13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
23 #include "pcap/funcattrs.h"
25 static int ifprint(pcap_if_t
*d
);
26 static char *iptos(bpf_u_int32 in
);
29 #include "portability.h"
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()
36 #define ERRBUF_SIZE 1024
38 win32_strerror(DWORD error
)
40 static char errbuf
[ERRBUF_SIZE
+1];
43 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, error
, 0, errbuf
,
47 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
48 * message. Get rid of it.
50 errlen
= strlen(errbuf
);
52 errbuf
[errlen
- 1] = '\0';
53 errbuf
[errlen
- 2] = '\0';
60 getpass(const char *prompt
)
62 HANDLE console_handle
= GetStdHandle(STD_INPUT_HANDLE
);
63 DWORD console_mode
, save_console_mode
;
64 static char password
[128+1];
67 fprintf(stderr
, "%s", prompt
);
72 if (!GetConsoleMode(console_handle
, &console_mode
)) {
73 fprintf(stderr
, "Can't get console mode: %s\n",
74 win32_strerror(GetLastError()));
77 save_console_mode
= console_mode
;
78 console_mode
&= ~ENABLE_ECHO_INPUT
;
79 if (!SetConsoleMode(console_handle
, console_mode
)) {
80 fprintf(stderr
, "Can't set console mode: %s\n",
81 win32_strerror(GetLastError()));
84 if (fgets(password
, sizeof password
, stdin
) == NULL
) {
85 fprintf(stderr
, "\n");
86 SetConsoleMode(console_handle
, save_console_mode
);
89 fprintf(stderr
, "\n");
90 SetConsoleMode(console_handle
, save_console_mode
);
91 p
= strchr(password
, '\n');
99 int main(int argc
, char **argv
)
101 int main(int argc _U_
, char **argv _U_
)
106 bpf_u_int32 net
, mask
;
108 char errbuf
[PCAP_ERRBUF_SIZE
+1];
110 struct pcap_rmtauth auth
;
111 char username
[128+1];
119 if (pcap_findalldevs_ex(argv
[1], NULL
, &alldevs
, errbuf
) == -1)
122 * OK, try it with a user name and password.
124 fprintf(stderr
, "User name: ");
125 if (fgets(username
, sizeof username
, stdin
) == NULL
)
127 p
= strchr(username
, '\n');
130 password
= getpass("Password: ");
131 auth
.type
= RPCAP_RMTAUTH_PWD
;
132 auth
.username
= username
;
133 auth
.password
= password
;
134 if (pcap_findalldevs_ex(argv
[1], &auth
, &alldevs
, errbuf
) == -1)
136 fprintf(stderr
,"Error in pcap_findalldevs: %s\n",errbuf
);
144 if (pcap_findalldevs(&alldevs
, errbuf
) == -1)
146 fprintf(stderr
,"Error in pcap_findalldevs: %s\n",errbuf
);
150 for(d
=alldevs
;d
;d
=d
->next
)
158 if (pcap_lookupnet(alldevs
->name
, &net
, &mask
, errbuf
) < 0)
161 * XXX - this doesn't distinguish between "a real error
162 * occurred" and "this interface doesn't *have* an IPv4
163 * address". The latter shouldn't be treated as an error.
165 * We look for the interface name, followed by a colon and
166 * a space, and, if we find it,w e see if what follows it
167 * is "no IPv4 address assigned".
169 size_t devnamelen
= strlen(alldevs
->name
);
170 if (strncmp(errbuf
, alldevs
->name
, devnamelen
) == 0 &&
171 strncmp(errbuf
+ devnamelen
, ": ", 2) == 0 &&
172 strcmp(errbuf
+ devnamelen
+ 2, "no IPv4 address assigned") == 0)
173 printf("Preferred device is not on an IPv4 network\n");
175 fprintf(stderr
,"Error in pcap_lookupnet: %s\n",errbuf
);
181 printf("Preferred device is on network: %s/%s\n",iptos(net
), iptos(mask
));
185 pcap_freealldevs(alldevs
);
189 static int ifprint(pcap_if_t
*d
)
192 char ipv4_buf
[INET_ADDRSTRLEN
];
193 char ipv6_buf
[INET6_ADDRSTRLEN
];
195 int status
= 1; /* success */
197 printf("%s\n",d
->name
);
199 printf("\tDescription: %s\n",d
->description
);
202 if (d
->flags
& PCAP_IF_UP
) {
206 if (d
->flags
& PCAP_IF_RUNNING
) {
207 printf("%sRUNNING", sep
);
210 if (d
->flags
& PCAP_IF_LOOPBACK
) {
211 printf("%sLOOPBACK", sep
);
214 if (d
->flags
& PCAP_IF_WIRELESS
) {
215 printf("%sWIRELESS", sep
);
216 switch (d
->flags
& PCAP_IF_CONNECTION_STATUS
) {
218 case PCAP_IF_CONNECTION_STATUS_UNKNOWN
:
219 printf(" (association status unknown)");
222 case PCAP_IF_CONNECTION_STATUS_CONNECTED
:
223 printf(" (associated)");
226 case PCAP_IF_CONNECTION_STATUS_DISCONNECTED
:
227 printf(" (not associated)");
230 case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE
:
234 switch (d
->flags
& PCAP_IF_CONNECTION_STATUS
) {
236 case PCAP_IF_CONNECTION_STATUS_UNKNOWN
:
237 printf(" (connection status unknown)");
240 case PCAP_IF_CONNECTION_STATUS_CONNECTED
:
241 printf(" (connected)");
244 case PCAP_IF_CONNECTION_STATUS_DISCONNECTED
:
245 printf(" (disconnected)");
248 case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE
:
255 for(a
=d
->addresses
;a
;a
=a
->next
) {
257 switch(a
->addr
->sa_family
) {
259 printf("\tAddress Family: AF_INET\n");
261 printf("\t\tAddress: %s\n",
263 &((struct sockaddr_in
*)(a
->addr
))->sin_addr
,
264 ipv4_buf
, sizeof ipv4_buf
));
266 printf("\t\tNetmask: %s\n",
268 &((struct sockaddr_in
*)(a
->netmask
))->sin_addr
,
269 ipv4_buf
, sizeof ipv4_buf
));
271 printf("\t\tBroadcast Address: %s\n",
273 &((struct sockaddr_in
*)(a
->broadaddr
))->sin_addr
,
274 ipv4_buf
, sizeof ipv4_buf
));
276 printf("\t\tDestination Address: %s\n",
278 &((struct sockaddr_in
*)(a
->dstaddr
))->sin_addr
,
279 ipv4_buf
, sizeof ipv4_buf
));
283 printf("\tAddress Family: AF_INET6\n");
285 printf("\t\tAddress: %s\n",
287 ((struct sockaddr_in6
*)(a
->addr
))->sin6_addr
.s6_addr
,
288 ipv6_buf
, sizeof ipv6_buf
));
290 printf("\t\tNetmask: %s\n",
292 ((struct sockaddr_in6
*)(a
->netmask
))->sin6_addr
.s6_addr
,
293 ipv6_buf
, sizeof ipv6_buf
));
295 printf("\t\tBroadcast Address: %s\n",
297 ((struct sockaddr_in6
*)(a
->broadaddr
))->sin6_addr
.s6_addr
,
298 ipv6_buf
, sizeof ipv6_buf
));
300 printf("\t\tDestination Address: %s\n",
302 ((struct sockaddr_in6
*)(a
->dstaddr
))->sin6_addr
.s6_addr
,
303 ipv6_buf
, sizeof ipv6_buf
));
307 printf("\tAddress Family: Unknown (%d)\n", a
->addr
->sa_family
);
312 fprintf(stderr
, "\tWarning: a->addr is NULL, skipping this address.\n");
320 /* From tcptraceroute */
321 #define IPTOSBUFFERS 12
322 static char *iptos(bpf_u_int32 in
)
324 static char output
[IPTOSBUFFERS
][sizeof("255.255.255.255")];
329 which
= (which
+ 1 == IPTOSBUFFERS
? 0 : which
+ 1);
330 snprintf(output
[which
], sizeof(output
[which
]), "%d.%d.%d.%d", p
[0], p
[1], p
[2], p
[3]);
331 return output
[which
];