libpcap  1.10.1
About: libpcap is a packet filter library used by tools like tcpdump.
  Fossies Dox: libpcap-1.10.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

findalldevstest.c
Go to the documentation of this file.
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 "varattrs.h"
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 
43  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
44  ERRBUF_SIZE, NULL);
45 
46  /*
47  * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
48  * message. Get rid of it.
49  */
50  errlen = strlen(errbuf);
51  if (errlen >= 2) {
52  errbuf[errlen - 1] = '\0';
53  errbuf[errlen - 2] = '\0';
54  errlen -= 2;
55  }
56  return errbuf;
57 }
58 
59 static char *
60 getpass(const char *prompt)
61 {
62  HANDLE console_handle = GetStdHandle(STD_INPUT_HANDLE);
63  DWORD console_mode, save_console_mode;
64  static char password[128+1];
65  char *p;
66 
67  fprintf(stderr, "%s", prompt);
68 
69  /*
70  * Turn off echoing.
71  */
72  if (!GetConsoleMode(console_handle, &console_mode)) {
73  fprintf(stderr, "Can't get console mode: %s\n",
74  win32_strerror(GetLastError()));
75  exit(1);
76  }
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()));
82  exit(1);
83  }
84  if (fgets(password, sizeof password, stdin) == NULL) {
85  fprintf(stderr, "\n");
86  SetConsoleMode(console_handle, save_console_mode);
87  exit(1);
88  }
89  fprintf(stderr, "\n");
90  SetConsoleMode(console_handle, save_console_mode);
91  p = strchr(password, '\n');
92  if (p != NULL)
93  *p = '\0';
94  return password;
95 }
96 #endif
97 
98 #ifdef ENABLE_REMOTE
99 int main(int argc, char **argv)
100 #else
101 int main(int argc _U_, char **argv _U_)
102 #endif
103 {
104  pcap_if_t *alldevs;
105  pcap_if_t *d;
106  bpf_u_int32 net, mask;
107  int exit_status = 0;
108  char errbuf[PCAP_ERRBUF_SIZE+1];
109 #ifdef ENABLE_REMOTE
110  struct pcap_rmtauth auth;
111  char username[128+1];
112  char *p;
113  char *password;
114 #endif
115 
116 #ifdef ENABLE_REMOTE
117  if (argc >= 2)
118  {
119  if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
120  {
121  /*
122  * OK, try it with a user name and password.
123  */
124  fprintf(stderr, "User name: ");
125  if (fgets(username, sizeof username, stdin) == NULL)
126  exit(1);
127  p = strchr(username, '\n');
128  if (p != NULL)
129  *p = '\0';
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)
135  {
136  fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
137  exit(1);
138  }
139  }
140  }
141  else
142 #endif
143  {
144  if (pcap_findalldevs(&alldevs, errbuf) == -1)
145  {
146  fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
147  exit(1);
148  }
149  }
150  for(d=alldevs;d;d=d->next)
151  {
152  if (!ifprint(d))
153  exit_status = 2;
154  }
155 
156  if (alldevs != NULL)
157  {
158  if (pcap_lookupnet(alldevs->name, &net, &mask, errbuf) < 0)
159  {
160  /*
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.
164  *
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".
168  */
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");
174  else {
175  fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
176  exit_status = 2;
177  }
178  }
179  else
180  {
181  printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
182  }
183  }
184 
185  pcap_freealldevs(alldevs);
186  exit(exit_status);
187 }
188 
189 static int ifprint(pcap_if_t *d)
190 {
191  pcap_addr_t *a;
192  char ipv4_buf[INET_ADDRSTRLEN];
193  char ipv6_buf[INET6_ADDRSTRLEN];
194  const char *sep;
195  int status = 1; /* success */
196 
197  printf("%s\n",d->name);
198  if (d->description)
199  printf("\tDescription: %s\n",d->description);
200  printf("\tFlags: ");
201  sep = "";
202  if (d->flags & PCAP_IF_UP) {
203  printf("%sUP", sep);
204  sep = ", ";
205  }
206  if (d->flags & PCAP_IF_RUNNING) {
207  printf("%sRUNNING", sep);
208  sep = ", ";
209  }
210  if (d->flags & PCAP_IF_LOOPBACK) {
211  printf("%sLOOPBACK", sep);
212  sep = ", ";
213  }
214  if (d->flags & PCAP_IF_WIRELESS) {
215  printf("%sWIRELESS", sep);
216  switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
217 
219  printf(" (association status unknown)");
220  break;
221 
223  printf(" (associated)");
224  break;
225 
227  printf(" (not associated)");
228  break;
229 
231  break;
232  }
233  } else {
234  switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
235 
237  printf(" (connection status unknown)");
238  break;
239 
241  printf(" (connected)");
242  break;
243 
245  printf(" (disconnected)");
246  break;
247 
249  break;
250  }
251  }
252  sep = ", ";
253  printf("\n");
254 
255  for(a=d->addresses;a;a=a->next) {
256  if (a->addr != NULL)
257  switch(a->addr->sa_family) {
258  case AF_INET:
259  printf("\tAddress Family: AF_INET\n");
260  if (a->addr)
261  printf("\t\tAddress: %s\n",
262  inet_ntop(AF_INET,
263  &((struct sockaddr_in *)(a->addr))->sin_addr,
264  ipv4_buf, sizeof ipv4_buf));
265  if (a->netmask)
266  printf("\t\tNetmask: %s\n",
267  inet_ntop(AF_INET,
268  &((struct sockaddr_in *)(a->netmask))->sin_addr,
269  ipv4_buf, sizeof ipv4_buf));
270  if (a->broadaddr)
271  printf("\t\tBroadcast Address: %s\n",
272  inet_ntop(AF_INET,
273  &((struct sockaddr_in *)(a->broadaddr))->sin_addr,
274  ipv4_buf, sizeof ipv4_buf));
275  if (a->dstaddr)
276  printf("\t\tDestination Address: %s\n",
277  inet_ntop(AF_INET,
278  &((struct sockaddr_in *)(a->dstaddr))->sin_addr,
279  ipv4_buf, sizeof ipv4_buf));
280  break;
281 #ifdef INET6
282  case AF_INET6:
283  printf("\tAddress Family: AF_INET6\n");
284  if (a->addr)
285  printf("\t\tAddress: %s\n",
286  inet_ntop(AF_INET6,
287  ((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
288  ipv6_buf, sizeof ipv6_buf));
289  if (a->netmask)
290  printf("\t\tNetmask: %s\n",
291  inet_ntop(AF_INET6,
292  ((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
293  ipv6_buf, sizeof ipv6_buf));
294  if (a->broadaddr)
295  printf("\t\tBroadcast Address: %s\n",
296  inet_ntop(AF_INET6,
297  ((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
298  ipv6_buf, sizeof ipv6_buf));
299  if (a->dstaddr)
300  printf("\t\tDestination Address: %s\n",
301  inet_ntop(AF_INET6,
302  ((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
303  ipv6_buf, sizeof ipv6_buf));
304  break;
305 #endif
306  default:
307  printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
308  break;
309  }
310  else
311  {
312  fprintf(stderr, "\tWarning: a->addr is NULL, skipping this address.\n");
313  status = 0;
314  }
315  }
316  printf("\n");
317  return status;
318 }
319 
320 /* From tcptraceroute */
321 #define IPTOSBUFFERS 12
322 static char *iptos(bpf_u_int32 in)
323 {
324  static char output[IPTOSBUFFERS][sizeof("255.255.255.255")];
325  static short which;
326  u_char *p;
327 
328  p = (u_char *)&in;
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];
332 }
u_int bpf_u_int32
Definition: bpf.h:98
static void error(const char *,...)
int main(int argc, char **argv)
#define IPTOSBUFFERS
static char * iptos(bpf_u_int32 in)
static int ifprint(pcap_if_t *d)
int snprintf(char *, size_t, const char *,...)
char * getpass(char *)
int printf(const char *,...)
int pcap_lookupnet(const char *device, bpf_u_int32 *localnet, bpf_u_int32 *netmask, char *errbuf)
Definition: pcap-dos.c:518
#define _U_
Definition: pcap-dos.h:93
unsigned long DWORD
Definition: pcap-dos.h:18
int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
Definition: pcap-new.c:74
#define PCAP_IF_CONNECTION_STATUS
Definition: pcap.h:313
#define PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE
Definition: pcap.h:317
#define PCAP_IF_LOOPBACK
Definition: pcap.h:309
#define PCAP_IF_CONNECTION_STATUS_CONNECTED
Definition: pcap.h:315
#define PCAP_IF_RUNNING
Definition: pcap.h:311
#define PCAP_IF_UP
Definition: pcap.h:310
#define PCAP_IF_WIRELESS
Definition: pcap.h:312
#define RPCAP_RMTAUTH_PWD
Definition: pcap.h:1021
#define PCAP_IF_CONNECTION_STATUS_UNKNOWN
Definition: pcap.h:314
#define PCAP_ERRBUF_SIZE
Definition: pcap.h:152
#define PCAP_IF_CONNECTION_STATUS_DISCONNECTED
Definition: pcap.h:316
void pcap_freealldevs(pcap_if_t *alldevs)
Definition: pcap.c:1431
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
Definition: pcap.c:711
struct pcap_addr * next
Definition: pcap.h:323
struct sockaddr * addr
Definition: pcap.h:324
struct sockaddr * netmask
Definition: pcap.h:325
struct sockaddr * dstaddr
Definition: pcap.h:327
struct sockaddr * broadaddr
Definition: pcap.h:326
Definition: pcap.h:301
char * name
Definition: pcap.h:303
bpf_u_int32 flags
Definition: pcap.h:306
struct pcap_if * next
Definition: pcap.h:302
char * description
Definition: pcap.h:304
struct pcap_addr * addresses
Definition: pcap.h:305
char * password
Definition: pcap.h:1062
char * username
Definition: pcap.h:1054
int type
Definition: pcap.h:1046