aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Fenner <fenner@FreeBSD.org>2003-01-26 01:16:33 +0000
committerBill Fenner <fenner@FreeBSD.org>2003-01-26 01:16:33 +0000
commit09f33d614ae3d492253b1503d824296e3b77695e (patch)
tree48f10250dfd696b7848cb83c2db083a4d66ddcef
parent0a94d38f0590468c79627c0140ef494c66616ae6 (diff)
downloadsrc-09f33d614ae3d492253b1503d824296e3b77695e.tar.gz
src-09f33d614ae3d492253b1503d824296e3b77695e.zip
Commit tcpdump.org's multi-DLT support to vendor branch.
Notes
Notes: svn path=/vendor/libpcap/dist/; revision=109839
-rw-r--r--contrib/libpcap/VERSION2
-rw-r--r--contrib/libpcap/gencode.c7
-rw-r--r--contrib/libpcap/pcap-bpf.c51
-rw-r--r--contrib/libpcap/pcap-int.h2
-rw-r--r--contrib/libpcap/pcap.330
-rw-r--r--contrib/libpcap/pcap.c20
-rw-r--r--contrib/libpcap/pcap.h2
7 files changed, 113 insertions, 1 deletions
diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION
index eb49d7c7fdcb..e2e9c1595263 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 498539d8e354..f3e8e4798dc0 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 0d97d41e61c1..6d74af7c7dfd 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 82f7beff4e21..0f7c3237f2f7 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 8aaeb4ea8314..2ef8026bbe95 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 6b82453ddb8e..719c14c88fde 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 accd6ab3c6bd..8468a47d8f40 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 *);