summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/pcap-snoop.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpcap/pcap-snoop.c')
-rw-r--r--contrib/libpcap/pcap-snoop.c80
1 files changed, 67 insertions, 13 deletions
diff --git a/contrib/libpcap/pcap-snoop.c b/contrib/libpcap/pcap-snoop.c
index 1260bd7..acbe548 100644
--- a/contrib/libpcap/pcap-snoop.c
+++ b/contrib/libpcap/pcap-snoop.c
@@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.45.2.5 2004/03/21 08:33:24 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.54 2004/10/19 07:06:14 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -63,8 +63,8 @@ pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
int cc;
register struct snoopheader *sh;
- register int datalen;
- register int caplen;
+ register u_int datalen;
+ register u_int caplen;
register u_char *cp;
again:
@@ -97,6 +97,16 @@ again:
}
sh = (struct snoopheader *)p->buffer;
datalen = sh->snoop_packetlen;
+
+ /*
+ * XXX - Sigh, snoop_packetlen is a 16 bit quantity. If we
+ * got a short length, but read a full sized snoop pakcet,
+ * assume we overflowed and add back the 64K...
+ */
+ if (cc == (p->snapshot + sizeof(struct snoopheader)) &&
+ (datalen < p->snapshot))
+ datalen += (64 * 1024);
+
caplen = (datalen < p->snapshot) ? datalen : p->snapshot;
cp = (u_char *)(sh + 1) + p->offset; /* XXX */
@@ -126,6 +136,24 @@ again:
}
static int
+pcap_inject_snoop(pcap_t *p, const void *buf, size_t size)
+{
+ int ret;
+
+ /*
+ * XXX - libnet overwrites the source address with what I
+ * presume is the interface's address; is that required?
+ */
+ ret = write(p->fd, buf, size);
+ if (ret == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ return (ret);
+}
+
+static int
pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
{
register struct rawstats *rs;
@@ -165,15 +193,6 @@ pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps)
return (0);
}
-static void
-pcap_close_snoop(pcap_t *p)
-{
- if (p->buffer != NULL)
- free(p->buffer);
- if (p->fd >= 0)
- close(p->fd);
-}
-
/* XXX can't disable promiscuous */
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
@@ -237,6 +256,35 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
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?
+ */
+ 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;
+ }
} else if (strncmp("ipg", device, 3) == 0 ||
strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */
strncmp("xpi", device, 3) == 0) {
@@ -329,16 +377,22 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
p->selectable_fd = p->fd;
p->read_op = pcap_read_snoop;
+ p->inject_op = pcap_inject_snoop;
p->setfilter_op = install_bpf_program; /* no kernel filtering */
p->set_datalink_op = NULL; /* can't change data link type */
p->getnonblock_op = pcap_getnonblock_fd;
p->setnonblock_op = pcap_setnonblock_fd;
p->stats_op = pcap_stats_snoop;
- p->close_op = pcap_close_snoop;
+ p->close_op = pcap_close_common;
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);
}
OpenPOWER on IntegriCloud