*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.71 2003-11-22 00:06:05 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.72 2003-12-18 23:32:31 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
close(p->fd);
}
+/*
+ * We include the OS's <net/bpf.h>, not our "pcap-bpf.h", so we probably
+ * don't get DLT_DOCSIS defined.
+ */
+#ifndef DLT_DOCSIS
+#define DLT_DOCSIS 143
+#endif
+
/*
* XXX - on AIX, IBM's tcpdump (and perhaps the incompatible-with-everybody-
* else's libpcap in AIX 5.1) appears to forcibly load the BPF driver
* 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);
+ u_int i;
+ int is_ethernet;
+
+ bdl.bfl_list = (u_int *) malloc(sizeof(u_int) * bdl.bfl_len + 1);
if (bdl.bfl_list == NULL) {
(void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
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;
}
+ /*
+ * OK, for real Ethernet devices, add DLT_DOCSIS to the
+ * list, so that an application can let you choose it,
+ * in case you're capturing DOCSIS traffic that a Cisco
+ * Cable Modem Termination System is putting out onto
+ * an Ethernet (it doesn't put an Ethernet header onto
+ * the wire, it puts raw DOCSIS frames out on the wire
+ * inside the low-level Ethernet framing).
+ *
+ * A "real Ethernet device" is defined here as a device
+ * that has a link-layer type of DLT_EN10MB and that has
+ * no alternate link-layer types; that's done to exclude
+ * 802.11 interfaces (which might or might not be the
+ * right thing to do, but I suspect it is - Ethernet <->
+ * 802.11 bridges would probably badly mishandle frames
+ * that don't have Ethernet headers).
+ */
+ if (p->linktype == DLT_EN10MB) {
+ is_ethernet = TRUE;
+ for (i = 0; i < bdl.bfl_len; i++) {
+ if (bdl.bfl_list != DLT_EN10MB) {
+ is_ethernet = FALSE;
+ break;
+ }
+ }
+ if (is_ethernet) {
+ /*
+ * We reserved one more slot at the end of
+ * the list.
+ */
+ bdl.bfl_list[bdl.bfl_len] = DLT_DOCSIS;
+ bdl.bfl_len++;
+ }
+ }
p->dlt_count = bdl.bfl_len;
p->dlt_list = bdl.bfl_list;
} else {
}
#endif
+ /*
+ * If this is an Ethernet device, and we don't have a DLT_ list,
+ * give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give
+ * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to
+ * do, but there's not much we can do about that without finding
+ * some other way of determining whether it's an Ethernet or 802.11
+ * device.)
+ */
+ if (p->linktype == DLT_EN10MB && p->dlt_count == 0) {
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
+ }
+
/* set timeout */
if (to_ms != 0) {
/*
return (p);
bad:
(void)close(fd);
-#ifdef BIOCGDLTLIST
- if (bdl.bfl_list != NULL)
- free(bdl.bfl_list);
-#endif
+ if (p->dlt_list != NULL)
+ free(p->dlt_list);
free(p);
return (NULL);
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.14 2003-11-21 10:19:33 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.15 2003-12-18 23:32:31 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
handle->snapshot = snaplen;
/*handle->md.timeout = to_ms; */
- if ((handle->linktype = dag_get_datalink(handle)) < 0) {
+ if (dag_get_datalink(handle) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_linktype %s: unknown linktype\n", device);
- goto fail;
+ goto fail;
}
handle->bufsize = 0;
if (new_pcap_dag(handle) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
- goto fail;
+ goto fail;
}
/*
free((char *)device);
}
if (handle != NULL) {
+ /*
+ * Get rid of any link-layer type list we allocated.
+ */
+ if (handle->dlt_list != NULL)
+ free(handle->dlt_list);
free(handle);
}
static int
dag_get_datalink(pcap_t *p)
{
- int linktype = -1;
-
/* Check the type through a dagapi call.
*/
switch(dag_linktype(p->fd)) {
record = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
if ((ntohl(record->rec.pos.hdlc) & 0xffff0000) == 0xff030000) {
- linktype = DLT_PPP_SERIAL;
+ p->linktype = DLT_PPP_SERIAL;
fprintf(stderr, "Set DAG linktype to %d (DLT_PPP_SERIAL)\n", linktype);
} else {
- linktype = DLT_CHDLC;
+ p->linktype = DLT_CHDLC;
fprintf(stderr, "Set DAG linktype to %d (DLT_CHDLC)\n", linktype);
}
break;
}
case TYPE_ETH:
- linktype = DLT_EN10MB;
+ p->linktype = DLT_EN10MB;
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ */
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
fprintf(stderr, "Set DAG linktype to %d (DLT_EN10MB)\n", linktype);
break;
case TYPE_ATM:
- linktype = DLT_ATM_RFC1483;
+ p->linktype = DLT_ATM_RFC1483;
fprintf(stderr, "Set DAG linktype to %d (DLT_ATM_RFC1483)\n", linktype);
break;
case TYPE_LEGACY:
- linktype = DLT_NULL;
+ p->linktype = DLT_NULL;
fprintf(stderr, "Set DAG linktype to %d (DLT_NULL)\n", linktype);
break;
default:
fprintf(stderr, "Unknown DAG linktype %d\n", dag_linktype(p->fd));
- break;
+ return -1;;
}
-
- return linktype;
+ return 0;
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.94 2003-11-21 10:19:34 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.95 2003-12-18 23:32:32 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
case DL_ETHER:
p->linktype = DLT_EN10MB;
p->offset = 2;
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ */
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
break;
case DL_FDDI:
bad:
if (p->fd >= 0)
close(p->fd);
+ /*
+ * Get rid of any link-layer type list we allocated.
+ */
+ if (p->dlt_list != NULL)
+ free(p->dlt_list);
free(p);
return (NULL);
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.102 2003-11-21 10:19:34 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.103 2003-12-18 23:32:32 guy Exp $ (LBL)";
#endif
/*
switch (arptype) {
case ARPHRD_ETHER:
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ *
+ * XXX - are there any sorts of "fake Ethernet" that have
+ * ARPHRD_ETHER but that *shouldn't offer DLT_DOCSIS as
+ * a Cisco CMTS won't put traffic onto it or get traffic
+ * bridged onto it? ISDN is handled in "live_open_new()",
+ * as we fall back on cooked mode there; are there any
+ * others?
+ */
+ handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (handle->dlt_list != NULL) {
+ handle->dlt_list[0] = DLT_EN10MB;
+ handle->dlt_list[1] = DLT_DOCSIS;
+ handle->dlt_count = 2;
+ }
+ /* FALLTHROUGH */
+
case ARPHRD_METRICOM:
case ARPHRD_LOOPBACK:
handle->linktype = DLT_EN10MB;
}
handle->md.cooked = 1;
+ /*
+ * Get rid of any link-layer type list
+ * we allocated - this only supports cooked
+ * capture.
+ */
+ if (handle->dlt_list != NULL) {
+ free(handle->dlt_list);
+ handle->dlt_list = NULL;
+ handle->dlt_count = 0;
+ }
+
if (handle->linktype == -1) {
/*
* Warn that we're falling back on
}
/* IrDA capture is not a real "cooked" capture,
* it's IrLAP frames, not IP packets. */
- if(handle->linktype != DLT_LINUX_IRDA)
+ if (handle->linktype != DLT_LINUX_IRDA)
handle->linktype = DLT_LINUX_SLL;
}
if (sock_fd != -1)
close(sock_fd);
- if (fatal_err)
+ if (fatal_err) {
+ /*
+ * Get rid of any link-layer type list we allocated.
+ */
+ if (handle->dlt_list != NULL)
+ free(handle->dlt_list);
return -2;
- else
+ } else
return 0;
#else
strncpy(ebuf,
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.53 2003-11-21 10:19:35 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.54 2003-12-18 23:32:32 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
*/
p->selectable_fd = p->fd;
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ */
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
+
p->read_op = pcap_read_nit;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.84 2003-11-22 00:32:25 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-pf.c,v 1.85 2003-12-18 23:32:33 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
case ENDT_10MB:
p->linktype = DLT_EN10MB;
p->offset = 2;
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ */
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
break;
case ENDT_FDDI:
bad:
if (p->fd >= 0)
close(p->fd);
+ /*
+ * Get rid of any link-layer type list we allocated.
+ */
+ if (p->dlt_list != NULL)
+ free(p->dlt_list);
free(p);
return (NULL);
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.69 2003-11-21 10:19:35 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.70 2003-12-18 23:32:33 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
*/
p->selectable_fd = p->fd;
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ */
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
+
p->read_op = pcap_read_snit;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.49 2003-11-21 10:19:35 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.50 2003-12-18 23:32:33 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
p->linktype = DLT_EN10MB;
p->offset = RAW_HDRPAD(sizeof(struct ether_header));
ll_hdrlen = sizeof(struct ether_header);
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ *
+ * XXX - are there any sorts of "fake Ethernet" that have
+ * Ethernet link-layer headers but that *shouldn't offer
+ * DLT_DOCSIS as a Cisco CMTS won't put traffic onto it
+ * or get traffic bridged onto it? "el" is for ATM LANE
+ * Ethernet devices, so that might be the case for them;
+ * the same applies for "qaa" classical IP devices. If
+ * "fa" devices are for FORE SPANS, that'd apply to them
+ * as well; what are "cip" devices - some other ATM
+ * Classical IP devices?
+ */
+ handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (handle->dlt_list != NULL) {
+ handle->dlt_list[0] = DLT_EN10MB;
+ handle->dlt_list[1] = DLT_DOCSIS;
+ handle->dlt_count = 2;
+ }
} else if (strncmp("ipg", device, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0) {
return (p);
bad:
(void)close(fd);
+ /*
+ * Get rid of any link-layer type list we allocated.
+ */
+ if (p->dlt_list != NULL)
+ free(p->dlt_list);
free(p);
return (NULL);
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.18 2003-11-30 02:31:04 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.19 2003-12-18 23:32:33 guy Exp $ (LBL)";
#endif
#include <pcap-int.h>
case NdisMedium802_3:
p->linktype = DLT_EN10MB;
+ /*
+ * This is (presumably) a real Ethernet capture; give it a
+ * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
+ * that an application can let you choose it, in case you're
+ * capturing DOCSIS traffic that a Cisco Cable Modem
+ * Termination System is putting out onto an Ethernet (it
+ * doesn't put an Ethernet header onto the wire, it puts raw
+ * DOCSIS frames out on the wire inside the low-level
+ * Ethernet framing).
+ */
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
break;
case NdisMediumFddi:
PacketCloseAdapter(p->adapter);
if (p->buffer != NULL)
free(p->buffer);
+ /*
+ * Get rid of any link-layer type list we allocated.
+ */
+ if (p->dlt_list != NULL)
+ free(p->dlt_list);
free(p);
return (NULL);
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.69 2003-11-21 10:19:36 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.70 2003-12-18 23:32:34 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
break;
if (i >= p->dlt_count)
goto unsupported;
+ if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB &&
+ dlt == DLT_DOCSIS) {
+ /*
+ * This is presumably an Ethernet device, as the first
+ * link-layer type it offers is DLT_EN10MB, and the only
+ * other type it offers is DLT_DOCSIS. That means that
+ * we can't tell the driver to supply DOCSIS link-layer
+ * headers - we're just pretending that's what we're
+ * getting, as, presumably, we're capturing on a dedicated
+ * link to a Cisco Cable Modem Termination System, and
+ * it's putting raw DOCSIS frames on the wire inside low-level
+ * Ethernet framing.
+ */
+ p->linktype = dlt;
+ return (0);
+ }
if (p->set_datalink_op(p, dlt) == -1)
return (-1);
p->linktype = dlt;
DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radio information header"),
DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
+ DLT_CHOICE(DLT_DOCSIS, "DOCSIS"),
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
DLT_CHOICE_SENTINEL
};