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