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