aboutsummaryrefslogtreecommitdiffstats
path: root/pcap-bpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcap-bpf.c')
-rw-r--r--pcap-bpf.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/pcap-bpf.c b/pcap-bpf.c
index 60caac6..32a21c7 100644
--- a/pcap-bpf.c
+++ b/pcap-bpf.c
@@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.53 2002-10-08 07:18:08 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.54 2002-12-19 09:05:45 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -229,9 +229,16 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
int fd;
struct ifreq ifr;
struct bpf_version bv;
+#ifdef BIOCGDLTLIST
+ struct bpf_dltlist bdl;
+#endif
u_int v;
pcap_t *p;
+#ifdef BIOCGDLTLIST
+ bzero(&bdl, sizeof(bdl));
+#endif
+
p = (pcap_t *)malloc(sizeof(*p));
if (p == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
@@ -348,6 +355,37 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
#endif
p->linktype = v;
+#ifdef BIOCGDLTLIST
+ /*
+ * We know the default link type -- now determine all the DLTs
+ * this interface supports. If this fails with EINVAL, 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));
+ goto bad;
+ }
+
+ p->dlt_count = bdl.bfl_len;
+ p->dlt_list = bdl.bfl_list;
+ } else {
+ if (errno != EINVAL) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ goto bad;
+ }
+ }
+#endif
+
/* set timeout */
if (to_ms != 0) {
/*
@@ -446,6 +484,10 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
return (p);
bad:
(void)close(fd);
+#ifdef BIOCGDLTLIST
+ if (bdl.bfl_list != NULL)
+ free(bdl.bfl_list);
+#endif
free(p);
return (NULL);
}
@@ -477,3 +519,16 @@ pcap_setfilter(pcap_t *p, struct bpf_program *fp)
}
return (0);
}
+
+int
+pcap_set_datalink_platform(pcap_t *p, int dlt)
+{
+#ifdef BIOCSDLT
+ if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set DLT %d: %s", dlt, strerror(errno));
+ return (-1);
+ }
+#endif
+ return (0);
+}