]> The Tcpdump Group git mirrors - libpcap/blob - testprogs/findalldevstest.c
6a221f2599f75e31c4c2a7910b6ec4b9df2d061d
[libpcap] / testprogs / 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 <winsock2.h>
10 #include <ws2tcpip.h>
11 #include <windows.h>
12 #else
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
16 #include <netdb.h>
17 #include <unistd.h>
18 #endif
19
20 #include <pcap.h>
21
22 #include "pcap/funcattrs.h"
23
24 static int ifprint(pcap_if_t *d);
25 static char *iptos(bpf_u_int32 in);
26
27 #ifdef _WIN32
28 #include "portability.h"
29
30 /*
31 * Generate a string for a Win32-specific error (i.e. an error generated when
32 * calling a Win32 API).
33 * For errors occurred during standard C calls, we still use pcap_strerror()
34 */
35 #define ERRBUF_SIZE 1024
36 static const char *
37 win32_strerror(DWORD error)
38 {
39 static char errbuf[ERRBUF_SIZE+1];
40 size_t errlen;
41
42 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
43 ERRBUF_SIZE, NULL);
44
45 /*
46 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
47 * message. Get rid of it.
48 */
49 errlen = strlen(errbuf);
50 if (errlen >= 2) {
51 errbuf[errlen - 1] = '\0';
52 errbuf[errlen - 2] = '\0';
53 errlen -= 2;
54 }
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 bpf_u_int32 net, mask;
102 int exit_status = 0;
103 char errbuf[PCAP_ERRBUF_SIZE+1];
104 #ifdef ENABLE_REMOTE
105 struct pcap_rmtauth auth;
106 char username[128+1];
107 char *p;
108 char *password;
109 #endif
110
111 #ifdef ENABLE_REMOTE
112 if (argc >= 2)
113 {
114 if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
115 {
116 /*
117 * OK, try it with a user name and password.
118 */
119 fprintf(stderr, "User name: ");
120 if (fgets(username, sizeof username, stdin) == NULL)
121 exit(1);
122 p = strchr(username, '\n');
123 if (p != NULL)
124 *p = '\0';
125 password = getpass("Password: ");
126 auth.type = RPCAP_RMTAUTH_PWD;
127 auth.username = username;
128 auth.password = password;
129 if (pcap_findalldevs_ex(argv[1], &auth, &alldevs, errbuf) == -1)
130 {
131 fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
132 exit(1);
133 }
134 }
135 }
136 else
137 #endif
138 {
139 if (pcap_findalldevs(&alldevs, errbuf) == -1)
140 {
141 fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
142 exit(1);
143 }
144 }
145 for(d=alldevs;d;d=d->next)
146 {
147 if (!ifprint(d))
148 exit_status = 2;
149 }
150
151 if (alldevs != NULL)
152 {
153 if (pcap_lookupnet(alldevs->name, &net, &mask, errbuf) < 0)
154 {
155 fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
156 exit_status = 2;
157 }
158 else
159 {
160 printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
161 }
162 }
163
164 pcap_freealldevs(alldevs);
165 exit(exit_status);
166 }
167
168 static int ifprint(pcap_if_t *d)
169 {
170 pcap_addr_t *a;
171 char ipv4_buf[INET_ADDRSTRLEN];
172 char ipv6_buf[INET6_ADDRSTRLEN];
173 const char *sep;
174 int status = 1; /* success */
175
176 printf("%s\n",d->name);
177 if (d->description)
178 printf("\tDescription: %s\n",d->description);
179 printf("\tFlags: ");
180 sep = "";
181 if (d->flags & PCAP_IF_UP) {
182 printf("%sUP", sep);
183 sep = ", ";
184 }
185 if (d->flags & PCAP_IF_RUNNING) {
186 printf("%sRUNNING", sep);
187 sep = ", ";
188 }
189 if (d->flags & PCAP_IF_LOOPBACK) {
190 printf("%sLOOPBACK", sep);
191 sep = ", ";
192 }
193 printf("\n");
194
195 for(a=d->addresses;a;a=a->next) {
196 if (a->addr != NULL)
197 switch(a->addr->sa_family) {
198 case AF_INET:
199 printf("\tAddress Family: AF_INET\n");
200 if (a->addr)
201 printf("\t\tAddress: %s\n",
202 inet_ntop(AF_INET,
203 &((struct sockaddr_in *)(a->addr))->sin_addr,
204 ipv4_buf, sizeof ipv4_buf));
205 if (a->netmask)
206 printf("\t\tNetmask: %s\n",
207 inet_ntop(AF_INET,
208 &((struct sockaddr_in *)(a->netmask))->sin_addr,
209 ipv4_buf, sizeof ipv4_buf));
210 if (a->broadaddr)
211 printf("\t\tBroadcast Address: %s\n",
212 inet_ntop(AF_INET,
213 &((struct sockaddr_in *)(a->broadaddr))->sin_addr,
214 ipv4_buf, sizeof ipv4_buf));
215 if (a->dstaddr)
216 printf("\t\tDestination Address: %s\n",
217 inet_ntop(AF_INET,
218 &((struct sockaddr_in *)(a->dstaddr))->sin_addr,
219 ipv4_buf, sizeof ipv4_buf));
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 ipv6_buf, sizeof ipv6_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 ipv6_buf, sizeof ipv6_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 ipv6_buf, sizeof ipv6_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 ipv6_buf, sizeof ipv6_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 }