1190214Srpaulo#ifdef HAVE_CONFIG_H
2190214Srpaulo#include "config.h"
3190214Srpaulo#endif
4190214Srpaulo
5190214Srpaulo#include <stdlib.h>
6190214Srpaulo#include <sys/types.h>
7190214Srpaulo#include <sys/socket.h>
8190214Srpaulo#include <netinet/in.h>
9190214Srpaulo#include <arpa/inet.h>
10190214Srpaulo#include <netdb.h>
11190214Srpaulo
12190214Srpaulo#include <pcap.h>
13190214Srpaulo
14190214Srpaulostatic void ifprint(pcap_if_t *d);
15190214Srpaulostatic char *iptos(bpf_u_int32 in);
16190214Srpaulo
17190214Srpauloint main(int argc, char **argv)
18190214Srpaulo{
19190214Srpaulo  pcap_if_t *alldevs;
20190214Srpaulo  pcap_if_t *d;
21190214Srpaulo  char *s;
22190214Srpaulo  bpf_u_int32 net, mask;
23190214Srpaulo
24190214Srpaulo  char errbuf[PCAP_ERRBUF_SIZE+1];
25190214Srpaulo  if (pcap_findalldevs(&alldevs, errbuf) == -1)
26190214Srpaulo  {
27190214Srpaulo    fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
28190214Srpaulo    exit(1);
29190214Srpaulo  }
30190214Srpaulo  for(d=alldevs;d;d=d->next)
31190214Srpaulo  {
32190214Srpaulo    ifprint(d);
33190214Srpaulo  }
34190214Srpaulo
35190214Srpaulo  if ( (s = pcap_lookupdev(errbuf)) == NULL)
36190214Srpaulo  {
37190214Srpaulo    fprintf(stderr,"Error in pcap_lookupdev: %s\n",errbuf);
38190214Srpaulo  }
39190214Srpaulo  else
40190214Srpaulo  {
41190214Srpaulo    printf("Preferred device name: %s\n",s);
42190214Srpaulo  }
43190214Srpaulo
44190214Srpaulo  if (pcap_lookupnet(s, &net, &mask, errbuf) < 0)
45190214Srpaulo  {
46190214Srpaulo    fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
47190214Srpaulo  }
48190214Srpaulo  else
49190214Srpaulo  {
50190214Srpaulo    printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
51190214Srpaulo  }
52190214Srpaulo
53190214Srpaulo  exit(0);
54190214Srpaulo}
55190214Srpaulo
56190214Srpaulostatic void ifprint(pcap_if_t *d)
57190214Srpaulo{
58190214Srpaulo  pcap_addr_t *a;
59190214Srpaulo#ifdef INET6
60190214Srpaulo  char ntop_buf[INET6_ADDRSTRLEN];
61190214Srpaulo#endif
62190214Srpaulo
63190214Srpaulo  printf("%s\n",d->name);
64190214Srpaulo  if (d->description)
65190214Srpaulo    printf("\tDescription: %s\n",d->description);
66190214Srpaulo  printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
67190214Srpaulo
68190214Srpaulo  for(a=d->addresses;a;a=a->next) {
69190214Srpaulo    switch(a->addr->sa_family)
70190214Srpaulo    {
71190214Srpaulo      case AF_INET:
72190214Srpaulo        printf("\tAddress Family: AF_INET\n");
73190214Srpaulo        if (a->addr)
74190214Srpaulo          printf("\t\tAddress: %s\n",
75190214Srpaulo            inet_ntoa(((struct sockaddr_in *)(a->addr))->sin_addr));
76190214Srpaulo        if (a->netmask)
77190214Srpaulo          printf("\t\tNetmask: %s\n",
78190214Srpaulo            inet_ntoa(((struct sockaddr_in *)(a->netmask))->sin_addr));
79190214Srpaulo        if (a->broadaddr)
80190214Srpaulo          printf("\t\tBroadcast Address: %s\n",
81190214Srpaulo            inet_ntoa(((struct sockaddr_in *)(a->broadaddr))->sin_addr));
82190214Srpaulo        if (a->dstaddr)
83190214Srpaulo          printf("\t\tDestination Address: %s\n",
84190214Srpaulo            inet_ntoa(((struct sockaddr_in *)(a->dstaddr))->sin_addr));
85190214Srpaulo        break;
86190214Srpaulo#ifdef INET6
87190214Srpaulo      case AF_INET6:
88190214Srpaulo        printf("\tAddress Family: AF_INET6\n");
89190214Srpaulo        if (a->addr)
90190214Srpaulo          printf("\t\tAddress: %s\n",
91190214Srpaulo            inet_ntop(AF_INET6,
92190214Srpaulo               ((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
93190214Srpaulo               ntop_buf, sizeof ntop_buf));
94190214Srpaulo        if (a->netmask)
95190214Srpaulo          printf("\t\tNetmask: %s\n",
96190214Srpaulo            inet_ntop(AF_INET6,
97190214Srpaulo              ((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
98190214Srpaulo               ntop_buf, sizeof ntop_buf));
99190214Srpaulo        if (a->broadaddr)
100190214Srpaulo          printf("\t\tBroadcast Address: %s\n",
101190214Srpaulo            inet_ntop(AF_INET6,
102190214Srpaulo              ((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
103190214Srpaulo               ntop_buf, sizeof ntop_buf));
104190214Srpaulo        if (a->dstaddr)
105190214Srpaulo          printf("\t\tDestination Address: %s\n",
106190214Srpaulo            inet_ntop(AF_INET6,
107190214Srpaulo              ((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
108190214Srpaulo               ntop_buf, sizeof ntop_buf));
109190214Srpaulo        break;
110190214Srpaulo#endif
111190214Srpaulo      default:
112190214Srpaulo        printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
113190214Srpaulo        break;
114190214Srpaulo    }
115190214Srpaulo  }
116190214Srpaulo  printf("\n");
117190214Srpaulo}
118190214Srpaulo
119190214Srpaulo/* From tcptraceroute */
120190214Srpaulo#define IPTOSBUFFERS	12
121190214Srpaulostatic char *iptos(bpf_u_int32 in)
122190214Srpaulo{
123190214Srpaulo	static char output[IPTOSBUFFERS][3*4+3+1];
124190214Srpaulo	static short which;
125190214Srpaulo	u_char *p;
126190214Srpaulo
127190214Srpaulo	p = (u_char *)&in;
128190214Srpaulo	which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
129190214Srpaulo	sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
130190214Srpaulo	return output[which];
131190214Srpaulo}
132