From 34111fdf72727e35d5c81dc576ce3f5a87c9ef84 Mon Sep 17 00:00:00 2001 From: fenner Date: Sun, 26 Jan 2003 01:16:33 +0000 Subject: Commit tcpdump.org's multi-DLT support to vendor branch. --- contrib/libpcap/VERSION | 2 +- contrib/libpcap/gencode.c | 7 +++++++ contrib/libpcap/pcap-bpf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ contrib/libpcap/pcap-int.h | 2 ++ contrib/libpcap/pcap.3 | 30 +++++++++++++++++++++++++++ contrib/libpcap/pcap.c | 20 ++++++++++++++++++ contrib/libpcap/pcap.h | 2 ++ 7 files changed, 113 insertions(+), 1 deletion(-) (limited to 'contrib/libpcap') diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION index eb49d7c..e2e9c15 100644 --- a/contrib/libpcap/VERSION +++ b/contrib/libpcap/VERSION @@ -1 +1 @@ -0.7 +0.7+multidlt diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c index 498539d..f3e8e47 100644 --- a/contrib/libpcap/gencode.c +++ b/contrib/libpcap/gencode.c @@ -564,6 +564,11 @@ init_linktype(type) off_nl = 6; /* XXX in reality, variable! */ return; + case DLT_IEEE802_11: + off_linktype = 30; /* XXX variable */ + off_nl = 32; + return; + case DLT_EN10MB: off_linktype = 12; off_nl = 14; @@ -659,6 +664,7 @@ init_linktype(type) off_nl = 22; return; +#ifdef notdef case DLT_IEEE802_11: /* * 802.11 doesn't really have a link-level type field. @@ -675,6 +681,7 @@ init_linktype(type) off_linktype = 24; off_nl = 30; return; +#endif case DLT_PRISM_HEADER: /* diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index 0d97d41..6d74af7 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -204,9 +204,12 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) int fd; struct ifreq ifr; struct bpf_version bv; + struct bpf_dltlist bdl; u_int v; pcap_t *p; + bzero(&bdl, sizeof(bdl)); + p = (pcap_t *)malloc(sizeof(*p)); if (p == NULL) { snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", @@ -323,6 +326,30 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) #endif p->linktype = v; + /* + * We know the default link type -- now determine any additional + * DLTs this interface supports. If this fails, it's not fatal; + * we just don't get to use the feature later. + */ + if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) == 0) { + bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len); + if (bdl.bfl_list == NULL) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", + pcap_strerror(errno)); + goto bad; + } + + if (ioctl(fd, BIOCGDLTLIST, (caddr_t) &bdl) < 0) { + (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, + "BIOCGDLTLIST: %s", pcap_strerror(errno)); + free(bdl.bfl_list); + goto bad; + } + + p->dlt_count = bdl.bfl_len; + p->dlt_list = bdl.bfl_list; + } + /* set timeout */ if (to_ms != 0) { struct timeval to; @@ -416,6 +443,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf) return (p); bad: (void)close(fd); + if (bdl.bfl_list != NULL) + free(bdl.bfl_list); free(p); return (NULL); } @@ -441,3 +470,25 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp) } return (0); } + +int +pcap_set_datalink(pcap_t *p, int dlt) +{ + int i; + + for (i = 0; i < p->dlt_count; i++) + if (p->dlt_list[i] == dlt) + break; + if (i >= p->dlt_count) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "No such DLT as %d", dlt); + return -1; + } + if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { + (void) snprintf(p->errbuf, sizeof(p->errbuf), + "Cannot set DLT %d: %s", dlt, strerror(errno)); + return -1; + } + p->linktype = dlt; + return 0; +} diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h index 82f7bef..0f7c323 100644 --- a/contrib/libpcap/pcap-int.h +++ b/contrib/libpcap/pcap-int.h @@ -104,6 +104,8 @@ struct pcap { struct bpf_program fcode; char errbuf[PCAP_ERRBUF_SIZE]; + int dlt_count; + int *dlt_list; }; /* diff --git a/contrib/libpcap/pcap.3 b/contrib/libpcap/pcap.3 index 8aaeb4e..2ef8026 100644 --- a/contrib/libpcap/pcap.3 +++ b/contrib/libpcap/pcap.3 @@ -82,6 +82,8 @@ u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h) .LP .ft B int pcap_datalink(pcap_t *p) +int pcap_list_datalinks(pcap_t *p, int **dlt_buf); +int pcap_set_datalink(pcap_t *p, int dlt); int pcap_snapshot(pcap_t *p) int pcap_is_swapped(pcap_t *p) int pcap_major_version(pcap_t *p) @@ -663,6 +665,34 @@ header or 4 for frames beginning with an 802.2 LLC header. Apple LocalTalk; the packet begins with an AppleTalk LLAP header .RE .PP +.B pcap_list_datalinks() +is used to get a list of the supported data link types of the interface +associated with the pcap descriptor. +.B pcap_list_datalinks() +allocates an array to hold the list and sets +.IR *dlt_buf . +The caller is responsible for freeing the array. +.B \-1 +is returned on failure; +otherwise, the number of data link types in the array is returned. +.PP +.B pcap_set_datalink() +is used to set the current data link type of the pcap descriptor +to the type specified by +.IR dlt . +.B \-1 +is returned on failure. +.PP +.B pcap_datalink_name_to_val() +translates a data link type name, which is a +.B DLT_ +name with the +.B DLT_ +removed, to the corresponding data link type value. The translation +is case-insensitive. +is used to set the current data link type of the pcap descriptor +NULL is returned on failure. +.PP .B pcap_snapshot() returns the snapshot length specified when .B pcap_open_live diff --git a/contrib/libpcap/pcap.c b/contrib/libpcap/pcap.c index 6b82453..719c14c 100644 --- a/contrib/libpcap/pcap.c +++ b/contrib/libpcap/pcap.c @@ -123,6 +123,24 @@ pcap_datalink(pcap_t *p) } int +pcap_list_datalinks(pcap_t *p, int **dlt_buffer) +{ + if (p->dlt_count <= 0) { + *dlt_buffer = NULL; + return -1; + } + *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer) * p->dlt_count); + if (*dlt_buffer == NULL) { + (void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", + pcap_strerror(errno)); + return -1; + } + (void)memcpy(*dlt_buffer, p->dlt_list, + sizeof(**dlt_buffer) * p->dlt_count); + return (p->dlt_count); +} + +int pcap_snapshot(pcap_t *p) { return (p->snapshot); @@ -281,6 +299,8 @@ pcap_close(pcap_t *p) free(p->sf.base); } else if (p->buffer != NULL) free(p->buffer); + if (p->dlt_list != NULL) + free(p->dlt_list); pcap_freecode(&p->fcode); free(p); diff --git a/contrib/libpcap/pcap.h b/contrib/libpcap/pcap.h index accd6ab..8468a47 100644 --- a/contrib/libpcap/pcap.h +++ b/contrib/libpcap/pcap.h @@ -181,6 +181,8 @@ int pcap_compile_nopcap(int, int, struct bpf_program *, char *, int, bpf_u_int32); void pcap_freecode(struct bpf_program *); int pcap_datalink(pcap_t *); +int pcap_list_datalinks(pcap_t *, int **); +int pcap_set_datalink(pcap_t *, int); int pcap_snapshot(pcap_t *); int pcap_is_swapped(pcap_t *); int pcap_major_version(pcap_t *); -- cgit v1.1