/*
* 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 <config.h>
#endif
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_MBUF_H
#include <sys/mbuf.h>
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#ifdef HAVE_NET_SLIP_H
#include <net/slip.h>
#include <net/slcompress.h>
#endif
#include <pcap.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1