/* * Copyright (c) 1993-1997 JSC Rinet, Novosibirsk, Russia * * Redistribution and use in source forms, with and without modification, * are permitted provided that this entire comment appears intact. * Redistribution in binary form may occur without any restrictions. * * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND. */ /* interfaces.h -- network interface data-link level routines */ #ifdef HAVE_CONFIG_H #include #endif #include #include #ifdef HAVE_SYS_MBUF_H #include #endif #include #include #include #ifdef HAVE_NET_SLIP_H #include #include #endif #include #include "trafshow.h" u_char *snapend; /* Link-level header length */ #ifndef ETHER_HDRLEN #define ETHER_HDRLEN sizeof(struct ether_header) #endif #ifndef SLIP_HDRLEN #ifdef SLC_BPFHDR #define SLIP_HDRLEN SLC_BPFHDR /* if _BSDI_VERSION >= 199510 */ #else #define SLIP_HDRLEN 16 /* bpf slip header length */ #endif #endif #ifndef PPP_HDRLEN #ifdef SLC_BPFHDR #define PPP_HDRLEN SLC_BPFHDR /* if _BSDI_VERSION >= 199510 */ #else #define PPP_HDRLEN 4 /* sizeof(struct ppp_header) */ #endif #endif #ifdef DLT_C_HDLC #ifndef CHDLC_HDRLEN #define CHDLC_HDRLEN 4 /* sizeof(struct cisco_hdr) */ #endif #endif #ifndef NULL_HDRLEN #define NULL_HDRLEN 4 /* loopback header length */ #endif /* * This is the interface depended routines for ethernet, slip, ppp and lo. * 'p' is the points to the packet, * 'length' is the length of the packet, * 'caplen' is the number of bytes actually captured. */ void if_ether(user, h, p) char *user; struct pcap_pkthdr *h; register u_char *p; { u_int caplen = h->caplen; u_int length = h->len; if (caplen < ETHER_HDRLEN) return; snapend = p + caplen; if (eflag || ntohs(((struct ether_header *)p)->ether_type) == ETHERTYPE_IP) display(p, p + ETHER_HDRLEN, length - ETHER_HDRLEN); } void if_slip(user, h, p) char *user; struct pcap_pkthdr *h; register u_char *p; { u_int caplen = h->caplen; u_int length = h->len; if (caplen < SLIP_HDRLEN) return; snapend = p + caplen; display(NULL, p + SLIP_HDRLEN, length - SLIP_HDRLEN); } void if_ppp(user, h, p) char *user; struct pcap_pkthdr *h; register u_char *p; { u_int caplen = h->caplen; u_int length = h->len; register hdrlen = 0; u_short type; u_char *packetp; if (caplen < PPP_HDRLEN) return; packetp = p; snapend = p + caplen; #ifdef SLC_BPFHDRLEN p += SLC_BPFHDRLEN; /* pointer to link level header */ #endif /* PPP address and PPP control fields may be present (-acfc) */ if (p[0] == 0xff && p[1] == 0x03) { p += 2; hdrlen += 2; } /* Retrive the protocol type */ if (*p & 01) { /* Compressed protocol field (pfc) */ type = *p++; hdrlen++; } else { /* Un-compressed protocol field (-pfc) */ type = ntohs(*(u_short *)p); p += 2; hdrlen += 2; } if (type == 0x21) { /* IP protocol */ #ifdef SLC_BPFHDR p = packetp + SLC_BPFHDR; /* skip bpf pseudo header */ hdrlen = SLC_BPFHDR; #endif display(NULL, p, length - hdrlen); } } #ifdef DLT_C_HDLC void if_chdlc(user, h, p) char *user; struct pcap_pkthdr *h; register u_char *p; { u_int caplen = h->caplen; u_int length = h->len; if (caplen < CHDLC_HDRLEN) return; snapend = p + caplen; if (ntohs(*(u_short *)(p + 2)) == 0x0800) /* IP protocol */ display(NULL, p + CHDLC_HDRLEN, length - CHDLC_HDRLEN); } #endif #ifdef DLT_RAW void if_rawip(user, h, p) char *user; struct pcap_pkthdr *h; register u_char *p; { u_int caplen = h->caplen; u_int length = h->len; snapend = p + caplen; display(NULL, p, length); } #endif void if_null(user, h, p) char *user; struct pcap_pkthdr *h; register u_char *p; { u_int caplen = h->caplen; u_int length = h->len; u_int family; memcpy(&family, p, sizeof(family)); snapend = p + caplen; if (family == AF_INET) display(NULL, p + NULL_HDRLEN, length - NULL_HDRLEN); } /* * hardware depended funtions table. */ static struct if_func { void (*f)(); int type; } if_funcs[] = { { if_ether, DLT_EN10MB }, /* Ethernet */ #ifdef DLT_IEEE802 { if_ether, DLT_IEEE802 }, /* IEEE 802 */ #endif { if_slip, DLT_SLIP }, /* SLIP */ #ifdef DLT_SLIP_BSDOS { if_slip, DLT_SLIP_BSDOS }, /* libpcap stupid fake */ #endif { if_ppp, DLT_PPP }, /* PPP */ #ifdef DLT_PPP_BSDOS { if_ppp, DLT_PPP_BSDOS }, /* libpcap stupid fake */ #endif #ifdef DLT_C_HDLC { if_chdlc, DLT_C_HDLC }, /* Cisco HDLC */ #endif #ifdef DLT_RAW { if_rawip, DLT_RAW }, /* raw IP */ #endif { if_null, DLT_NULL }, /* loopback */ { NULL, 0 }, }; /* * Assign data link type to interface function. */ pcap_handler lookup_if(type) int type; { struct if_func *p; for (p = if_funcs; p->f != NULL; ++p) if (type == p->type) return p->f; error(0, "unknown data link type 0x%x", type); /* NOTREACHED */ return 0; }