common.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "common.h"
  17. #include <android/api-level.h>
  18. #include <arpa/inet.h>
  19. #include <assert.h>
  20. #include <ctype.h>
  21. #include <errno.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <iostream>
  25. namespace {
  26. bool strEqual(const char *a, const char *b) {
  27. return strcmp(a, b) == 0;
  28. }
  29. // Allow specifying network handles in decimal and hexadecimal.
  30. bool parseNetworkHandle(const char *arg, net_handle_t *nethandle) {
  31. if (arg == nullptr || !isdigit(arg[0]) || nethandle == nullptr) {
  32. return false;
  33. }
  34. net_handle_t nh;
  35. char *end = nullptr;
  36. nh = strtoull(arg, &end, 0);
  37. if (end != nullptr && *end == '\0') {
  38. *nethandle = nh;
  39. return true;
  40. }
  41. return false;
  42. }
  43. } // namespace
  44. void printUsage(const char *progname) {
  45. std::cerr << "Usage: " << progname
  46. << " [--nethandle <nethandle>]"
  47. << " [--mode explicit|process]"
  48. << " [--family unspec|ipv4|ipv6]"
  49. << " <argument>"
  50. << std::endl;
  51. std::cerr << std::endl;
  52. std::cerr << "Learn nethandle values from 'dumpsys connectivity --short' "
  53. << "or 'dumpsys connectivity --diag'"
  54. << std::endl;
  55. }
  56. Arguments::~Arguments() {}
  57. bool Arguments::parseArguments(int argc, const char* argv[]) {
  58. if (argc < 1 || argv == nullptr) { return false; }
  59. for (int i = 1; i < argc; i++) {
  60. if (strEqual(argv[i], "--nethandle")) {
  61. i++;
  62. if (argc == i) break;
  63. if (!parseNetworkHandle(argv[i], &nethandle)) {
  64. std::cerr << "Failed to parse nethandle: '" << argv[i] << "'"
  65. << std::endl;
  66. break;
  67. }
  68. } else if (strEqual(argv[i], "--family")) {
  69. i++;
  70. if (argc == i) break;
  71. if (strEqual(argv[i], "unspec")) {
  72. family = AF_UNSPEC;
  73. } else if (strEqual(argv[i], "ipv4")) {
  74. family = AF_INET;
  75. } else if (strEqual(argv[i], "ipv6")) {
  76. family = AF_INET6;
  77. } else {
  78. break;
  79. }
  80. } else if (strEqual(argv[i], "--mode")) {
  81. i++;
  82. if (argc == i) break;
  83. if (strEqual(argv[i], "explicit")) {
  84. api_mode = ApiMode::EXPLICIT;
  85. } else if (strEqual(argv[i], "process")) {
  86. api_mode = ApiMode::PROCESS;
  87. } else {
  88. break;
  89. }
  90. } else if (arg1 == nullptr) {
  91. arg1 = argv[i];
  92. } else {
  93. arg1 = nullptr;
  94. break;
  95. }
  96. }
  97. if (arg1 != nullptr) {
  98. return true;
  99. }
  100. printUsage(argv[0]);
  101. return false;
  102. }
  103. std::string inetSockaddrToString(const sockaddr* sa) {
  104. const bool is_ipv6 = (sa->sa_family == AF_INET6);
  105. char host[INET6_ADDRSTRLEN];
  106. char port[sizeof("65535")];
  107. getnameinfo(sa, is_ipv6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in),
  108. host, sizeof(host),
  109. port, sizeof(port),
  110. NI_NUMERICHOST | NI_NUMERICSERV);
  111. if (port[0] == '0' || port[0] == '\0') {
  112. return std::string(host);
  113. }
  114. return (is_ipv6 ? "[" : "") + std::string(host) + (is_ipv6 ? "]:" : ":") + std::string(port);
  115. }