#include #include #include #include #include #ifdef __FreeBSD__ #include #endif #ifndef SOLARIS #include #endif #include #include #include #include #include #include pcap_t *pd = NULL; static u_long localnet, netmask; #define SNAPSIZE 54 unsigned long last_t_sec = 0, n_packets = 0; struct fddi_header { unsigned char fc; /* Frame control */ unsigned char dest[6]; /* MAC addresses */ unsigned char source[6]; }; struct ether_header { unsigned char dest[6]; /* MAC addresses */ unsigned char source[6]; unsigned char type[2]; /* Length or protocol type */ }; struct llc { unsigned char lsap[2]; unsigned char ui; unsigned char orgcode[3]; unsigned char ethertype[2]; }; #define NET_SHORT(a) (a[0] << 8 | a[1]) void ether_callback(u_char *user, struct pcap_pkthdr *h, u_char *p) { struct ether_header *ethp; struct llc *llcp; unsigned int ethertype, lsap; int len, j; ethp = (struct ether_header *)p; ethertype = NET_SHORT(ethp->type); p += sizeof(struct ether_header); if (ethertype <= 1500) { /* 802.3 packet */ llcp = (struct llc *)p; lsap = NET_SHORT(llcp->lsap); ethertype = lsap == 0xAAAA ? /* SNAP packet */ NET_SHORT(llcp->ethertype) : 0; p += sizeof(struct llc); printf("%5u lsap=%04X type=%04X\n", h->len, lsap, ethertype); } else lsap = 0; /* Blue book packet */ if (h->ts.tv_sec != last_t_sec) { printf("----- %u packets\n", n_packets); last_t_sec = h->ts.tv_sec; n_packets = 1; } else ++n_packets; #ifdef XXYYZZ printf("%5u ", h->len); for (j = 0; j != 20; ++j) printf("%02x ",p[j]); printf("\n"); #endif } void fddi_callback(u_char *user, struct pcap_pkthdr *h, u_char *p) { struct fddi_header *fddihp; struct llc *llcp; unsigned int lsap; int len; fddihp = (struct fddi_header *)p; if ((fddihp->fc & 0xF0) == 0x50) { /* Async LLC frame */ p += sizeof(struct fddi_header); llcp = (struct llc *)p; lsap = NET_SHORT(llcp->lsap); if (lsap == 0xAAAA) { len = h->len; p += sizeof(struct llc); } printf("%5u lsap=%04X\n", h->len, lsap); } } pcap_handler callback; static pcap_t *init(char *device) { pcap_t *pd = NULL; char errbuf[PCAP_ERRBUF_SIZE]; int type; if (!device) if (!(device = pcap_lookupdev(errbuf))) { printf("pcap_lookupdevice(): %s\n",errbuf); return NULL; } if (pd = pcap_open_live(device, SNAPSIZE, 1, 250, errbuf)) { if ((pcap_lookupnet (device, &localnet, &netmask, errbuf)) < 0) { printf("pcap_lookupnet(%s): %s\n", device,errbuf); return NULL; } } else { printf("pcap_open_live(%s): %s\n", device,errbuf); return NULL; } setuid(getuid()); type = pcap_datalink(pd); if (type == DLT_EN10MB) callback = (pcap_handler)ether_callback; else if (type == DLT_FDDI) callback = (pcap_handler)fddi_callback; else { printf("pcap bad link type 0x%x!\n", type); pcap_close(pd); return NULL; } return pd; } int main(int argc, char *argv[]) { static char *device = "ec0"; #ifndef __FreeBSD__ int pf, width = ulimit(4, NULL); #else int pf, width; struct rlimit reslimit; #endif /* FreeBSD */ fd_set readmask; struct timeval wait; #ifdef __FreeBSD__ if (getrlimit(RLIMIT_NOFILE,&reslimit) != 0) return; width = reslimit.rlim_cur; #endif /* FreeBSD */ if ((pd = init(device)) == NULL) return; int pf, width = ulimit(4, NULL); fd_set readmask; struct timeval wait; if ((pd = init(device)) == NULL) return; wait.tv_sec = 1; wait.tv_usec = 0; pf = pd->fd; /* if (lfd >= 0) FD_SET (lfd, &readmask); */ FD_ZERO(&readmask); FD_SET(pf,&readmask); while (select(width, &readmask, NULL, NULL, &wait) >= 0) { if (FD_ISSET(pf, &readmask)) pcap_read(pd, -1, callback, (u_char *)NULL); /* if ((lfd >= 0) && FD_ISSET (lfd, &readmask)) check_client_status (lfd); */ /* if (lfd >= 0) FD_SET(lfd, &readmask); */ FD_SET(pf, &readmask); } pcap_close (pd); }