findalldevstest.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #ifdef HAVE_CONFIG_H
  2. #include <config.h>
  3. #endif
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #ifdef _WIN32
  8. #include <winsock2.h>
  9. #include <ws2tcpip.h>
  10. #include <windows.h>
  11. #else
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <arpa/inet.h>
  15. #include <netdb.h>
  16. #include <unistd.h>
  17. #endif
  18. #include <pcap.h>
  19. #include "pcap/funcattrs.h"
  20. static int ifprint(pcap_if_t *d);
  21. static char *iptos(bpf_u_int32 in);
  22. #ifdef _WIN32
  23. #include "portability.h"
  24. /*
  25. * Generate a string for a Win32-specific error (i.e. an error generated when
  26. * calling a Win32 API).
  27. * For errors occurred during standard C calls, we still use pcap_strerror()
  28. */
  29. #define ERRBUF_SIZE 1024
  30. static const char *
  31. win32_strerror(DWORD error)
  32. {
  33. static char errbuf[ERRBUF_SIZE+1];
  34. size_t errlen;
  35. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
  36. ERRBUF_SIZE, NULL);
  37. /*
  38. * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
  39. * message. Get rid of it.
  40. */
  41. errlen = strlen(errbuf);
  42. if (errlen >= 2) {
  43. errbuf[errlen - 1] = '\0';
  44. errbuf[errlen - 2] = '\0';
  45. errlen -= 2;
  46. }
  47. return errbuf;
  48. }
  49. static char *
  50. getpass(const char *prompt)
  51. {
  52. HANDLE console_handle = GetStdHandle(STD_INPUT_HANDLE);
  53. DWORD console_mode, save_console_mode;
  54. static char password[128+1];
  55. char *p;
  56. fprintf(stderr, "%s", prompt);
  57. /*
  58. * Turn off echoing.
  59. */
  60. if (!GetConsoleMode(console_handle, &console_mode)) {
  61. fprintf(stderr, "Can't get console mode: %s\n",
  62. win32_strerror(GetLastError()));
  63. exit(1);
  64. }
  65. save_console_mode = console_mode;
  66. console_mode &= ~ENABLE_ECHO_INPUT;
  67. if (!SetConsoleMode(console_handle, console_mode)) {
  68. fprintf(stderr, "Can't set console mode: %s\n",
  69. win32_strerror(GetLastError()));
  70. exit(1);
  71. }
  72. if (fgets(password, sizeof password, stdin) == NULL) {
  73. fprintf(stderr, "\n");
  74. SetConsoleMode(console_handle, save_console_mode);
  75. exit(1);
  76. }
  77. fprintf(stderr, "\n");
  78. SetConsoleMode(console_handle, save_console_mode);
  79. p = strchr(password, '\n');
  80. if (p != NULL)
  81. *p = '\0';
  82. return password;
  83. }
  84. #endif
  85. int main(int argc, char **argv)
  86. {
  87. pcap_if_t *alldevs;
  88. pcap_if_t *d;
  89. bpf_u_int32 net, mask;
  90. int exit_status = 0;
  91. char errbuf[PCAP_ERRBUF_SIZE+1];
  92. #ifdef ENABLE_REMOTE
  93. struct pcap_rmtauth auth;
  94. char username[128+1];
  95. char *p;
  96. char *password;
  97. #endif
  98. #ifdef ENABLE_REMOTE
  99. if (argc >= 2)
  100. {
  101. if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
  102. {
  103. /*
  104. * OK, try it with a user name and password.
  105. */
  106. fprintf(stderr, "User name: ");
  107. if (fgets(username, sizeof username, stdin) == NULL)
  108. exit(1);
  109. p = strchr(username, '\n');
  110. if (p != NULL)
  111. *p = '\0';
  112. password = getpass("Password: ");
  113. auth.type = RPCAP_RMTAUTH_PWD;
  114. auth.username = username;
  115. auth.password = password;
  116. if (pcap_findalldevs_ex(argv[1], &auth, &alldevs, errbuf) == -1)
  117. {
  118. fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
  119. exit(1);
  120. }
  121. }
  122. }
  123. else
  124. #endif
  125. {
  126. if (pcap_findalldevs(&alldevs, errbuf) == -1)
  127. {
  128. fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
  129. exit(1);
  130. }
  131. }
  132. for(d=alldevs;d;d=d->next)
  133. {
  134. if (!ifprint(d))
  135. exit_status = 2;
  136. }
  137. if (alldevs != NULL)
  138. {
  139. if (pcap_lookupnet(alldevs->name, &net, &mask, errbuf) < 0)
  140. {
  141. fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
  142. exit_status = 2;
  143. }
  144. else
  145. {
  146. printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
  147. }
  148. }
  149. pcap_freealldevs(alldevs);
  150. exit(exit_status);
  151. }
  152. static int ifprint(pcap_if_t *d)
  153. {
  154. pcap_addr_t *a;
  155. char ipv4_buf[INET_ADDRSTRLEN];
  156. char ipv6_buf[INET6_ADDRSTRLEN];
  157. const char *sep;
  158. int status = 1; /* success */
  159. printf("%s\n",d->name);
  160. if (d->description)
  161. printf("\tDescription: %s\n",d->description);
  162. printf("\tFlags: ");
  163. sep = "";
  164. if (d->flags & PCAP_IF_UP) {
  165. printf("%sUP", sep);
  166. sep = ", ";
  167. }
  168. if (d->flags & PCAP_IF_RUNNING) {
  169. printf("%sRUNNING", sep);
  170. sep = ", ";
  171. }
  172. if (d->flags & PCAP_IF_LOOPBACK) {
  173. printf("%sLOOPBACK", sep);
  174. sep = ", ";
  175. }
  176. if (d->flags & PCAP_IF_WIRELESS) {
  177. printf("%sWIRELESS", sep);
  178. switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
  179. case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
  180. printf(" (association status unknown)");
  181. break;
  182. case PCAP_IF_CONNECTION_STATUS_CONNECTED:
  183. printf(" (associated)");
  184. break;
  185. case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
  186. printf(" (not associated)");
  187. break;
  188. case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
  189. break;
  190. }
  191. } else {
  192. switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
  193. case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
  194. printf(" (connection status unknown)");
  195. break;
  196. case PCAP_IF_CONNECTION_STATUS_CONNECTED:
  197. printf(" (connected)");
  198. break;
  199. case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
  200. printf(" (disconnected)");
  201. break;
  202. case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
  203. break;
  204. }
  205. }
  206. sep = ", ";
  207. printf("\n");
  208. for(a=d->addresses;a;a=a->next) {
  209. if (a->addr != NULL)
  210. switch(a->addr->sa_family) {
  211. case AF_INET:
  212. printf("\tAddress Family: AF_INET\n");
  213. if (a->addr)
  214. printf("\t\tAddress: %s\n",
  215. inet_ntop(AF_INET,
  216. &((struct sockaddr_in *)(a->addr))->sin_addr,
  217. ipv4_buf, sizeof ipv4_buf));
  218. if (a->netmask)
  219. printf("\t\tNetmask: %s\n",
  220. inet_ntop(AF_INET,
  221. &((struct sockaddr_in *)(a->netmask))->sin_addr,
  222. ipv4_buf, sizeof ipv4_buf));
  223. if (a->broadaddr)
  224. printf("\t\tBroadcast Address: %s\n",
  225. inet_ntop(AF_INET,
  226. &((struct sockaddr_in *)(a->broadaddr))->sin_addr,
  227. ipv4_buf, sizeof ipv4_buf));
  228. if (a->dstaddr)
  229. printf("\t\tDestination Address: %s\n",
  230. inet_ntop(AF_INET,
  231. &((struct sockaddr_in *)(a->dstaddr))->sin_addr,
  232. ipv4_buf, sizeof ipv4_buf));
  233. break;
  234. #ifdef INET6
  235. case AF_INET6:
  236. printf("\tAddress Family: AF_INET6\n");
  237. if (a->addr)
  238. printf("\t\tAddress: %s\n",
  239. inet_ntop(AF_INET6,
  240. ((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
  241. ipv6_buf, sizeof ipv6_buf));
  242. if (a->netmask)
  243. printf("\t\tNetmask: %s\n",
  244. inet_ntop(AF_INET6,
  245. ((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
  246. ipv6_buf, sizeof ipv6_buf));
  247. if (a->broadaddr)
  248. printf("\t\tBroadcast Address: %s\n",
  249. inet_ntop(AF_INET6,
  250. ((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
  251. ipv6_buf, sizeof ipv6_buf));
  252. if (a->dstaddr)
  253. printf("\t\tDestination Address: %s\n",
  254. inet_ntop(AF_INET6,
  255. ((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
  256. ipv6_buf, sizeof ipv6_buf));
  257. break;
  258. #endif
  259. default:
  260. printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
  261. break;
  262. }
  263. else
  264. {
  265. fprintf(stderr, "\tWarning: a->addr is NULL, skipping this address.\n");
  266. status = 0;
  267. }
  268. }
  269. printf("\n");
  270. return status;
  271. }
  272. /* From tcptraceroute */
  273. #define IPTOSBUFFERS 12
  274. static char *iptos(bpf_u_int32 in)
  275. {
  276. static char output[IPTOSBUFFERS][3*4+3+1];
  277. static short which;
  278. u_char *p;
  279. p = (u_char *)&in;
  280. which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
  281. sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
  282. return output[which];
  283. }