summaryrefslogtreecommitdiffstats
path: root/lib/libpcap/pcap.c
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2005-11-18 11:05:38 +0000
committerdjm <djm@openbsd.org>2005-11-18 11:05:38 +0000
commita878b8190bd951d272b5ce5df54b7a46fd7a9b0d (patch)
tree1a081693f9083731b7ed15ed3eeb9429e2dd5f01 /lib/libpcap/pcap.c
parentremove stray .Ed; (diff)
downloadwireguard-openbsd-a878b8190bd951d272b5ce5df54b7a46fd7a9b0d.tar.xz
wireguard-openbsd-a878b8190bd951d272b5ce5df54b7a46fd7a9b0d.zip
pull in the good bits of libpcap-0.9.4's API without the cross-platform
cruft. help from deraadt@, mpf@, jmc@; ok mpf@a nb. this will break tcpdump unless it updated too
Diffstat (limited to 'lib/libpcap/pcap.c')
-rw-r--r--lib/libpcap/pcap.c182
1 files changed, 181 insertions, 1 deletions
diff --git a/lib/libpcap/pcap.c b/lib/libpcap/pcap.c
index 3eab3051cef..30f58292718 100644
--- a/lib/libpcap/pcap.c
+++ b/lib/libpcap/pcap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap.c,v 1.8 2004/01/27 06:58:03 tedu Exp $ */
+/* $OpenBSD: pcap.c,v 1.9 2005/11/18 11:05:39 djm Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
@@ -39,6 +39,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
@@ -46,6 +48,8 @@
#include "pcap-int.h"
+static const char pcap_version_string[] = "OpenBSD libpcap";
+
int
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
@@ -107,6 +111,15 @@ pcap_next(pcap_t *p, struct pcap_pkthdr *h)
return (s.pkt);
}
+/*
+ * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
+ */
+void
+pcap_breakloop(pcap_t *p)
+{
+ p->break_loop = 1;
+}
+
int
pcap_datalink(pcap_t *p)
{
@@ -114,6 +127,109 @@ pcap_datalink(pcap_t *p)
}
int
+pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
+{
+ if (p->dlt_count == 0) {
+ /*
+ * We couldn't fetch the list of DLTs, which means
+ * this platform doesn't support changing the
+ * DLT for an interface. Return a list of DLTs
+ * containing only the DLT this device supports.
+ */
+ *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
+ if (*dlt_buffer == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ **dlt_buffer = p->linktype;
+ return (1);
+ } else {
+ *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);
+ }
+}
+
+struct dlt_choice {
+ const char *name;
+ const char *description;
+ int dlt;
+};
+
+static struct dlt_choice dlts[] = {
+#define DLT_CHOICE(code, description) { #code, description, code }
+DLT_CHOICE(DLT_NULL, "no link-layer encapsulation"),
+DLT_CHOICE(DLT_EN10MB, "Ethernet (10Mb)"),
+DLT_CHOICE(DLT_EN3MB, "Experimental Ethernet (3Mb)"),
+DLT_CHOICE(DLT_AX25, "Amateur Radio AX.25"),
+DLT_CHOICE(DLT_PRONET, "Proteon ProNET Token Ring"),
+DLT_CHOICE(DLT_CHAOS, "Chaos"),
+DLT_CHOICE(DLT_IEEE802, "IEEE 802 Networks"),
+DLT_CHOICE(DLT_ARCNET, "ARCNET"),
+DLT_CHOICE(DLT_SLIP, "Serial Line IP"),
+DLT_CHOICE(DLT_PPP, "Point-to-point Protocol"),
+DLT_CHOICE(DLT_FDDI, "FDDI"),
+DLT_CHOICE(DLT_ATM_RFC1483, "LLC/SNAP encapsulated atm"),
+DLT_CHOICE(DLT_LOOP, "loopback type (af header)"),
+DLT_CHOICE(DLT_ENC, "IPSEC enc type (af header, spi, flags)"),
+DLT_CHOICE(DLT_RAW, "raw IP"),
+DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS Serial Line IP"),
+DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS Point-to-point Protocol"),
+DLT_CHOICE(DLT_OLD_PFLOG, "Packet filter logging, old (XXX remove?)"),
+DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"),
+DLT_CHOICE(DLT_PPP_ETHER, "PPP over Ethernet; session only w/o ether header"),
+DLT_CHOICE(DLT_IEEE802_11, "IEEE 802.11 wireless"),
+DLT_CHOICE(DLT_PFLOG, "Packet filter logging, by pcap people"),
+DLT_CHOICE(DLT_IEEE802_11_RADIO, "IEEE 802.11 plus WLAN header"),
+#undef DLT_CHOICE
+ { NULL, NULL, -1}
+};
+
+int
+pcap_datalink_name_to_val(const char *name)
+{
+ int i;
+
+ for (i = 0; dlts[i].name != NULL; i++) {
+ /* Skip leading "DLT_" */
+ if (strcasecmp(dlts[i].name + 4, name) == 0)
+ return (dlts[i].dlt);
+ }
+ return (-1);
+}
+
+const char *
+pcap_datalink_val_to_name(int dlt)
+{
+ int i;
+
+ for (i = 0; dlts[i].name != NULL; i++) {
+ if (dlts[i].dlt == dlt)
+ return (dlts[i].name + 4); /* Skip leading "DLT_" */
+ }
+ return (NULL);
+}
+
+const char *
+pcap_datalink_val_to_description(int dlt)
+{
+ int i;
+
+ for (i = 0; dlts[i].name != NULL; i++) {
+ if (dlts[i].dlt == dlt)
+ return (dlts[i].description);
+ }
+ return (NULL);
+}
+
+int
pcap_snapshot(pcap_t *p)
{
return (p->snapshot);
@@ -161,6 +277,46 @@ pcap_geterr(pcap_t *p)
return (p->errbuf);
}
+int
+pcap_getnonblock(pcap_t *p, char *errbuf)
+{
+ int fdflags;
+
+ fdflags = fcntl(p->fd, F_GETFL, 0);
+ if (fdflags == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ if (fdflags & O_NONBLOCK)
+ return (1);
+ else
+ return (0);
+}
+
+int
+pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+{
+ int fdflags;
+
+ fdflags = fcntl(p->fd, F_GETFL, 0);
+ if (fdflags == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ if (nonblock)
+ fdflags |= O_NONBLOCK;
+ else
+ fdflags &= ~O_NONBLOCK;
+ if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ return (0);
+}
+
/*
* Not all systems have strerror().
*/
@@ -181,6 +337,21 @@ pcap_strerror(int errnum)
#endif
}
+pcap_t *
+pcap_open_dead(int linktype, int snaplen)
+{
+ pcap_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+ memset (p, 0, sizeof(*p));
+ p->snapshot = snaplen;
+ p->linktype = linktype;
+ p->fd = -1;
+ return p;
+}
+
void
pcap_close(pcap_t *p)
{
@@ -198,5 +369,14 @@ pcap_close(pcap_t *p)
free(p->md.device);
#endif
pcap_freecode(&p->fcode);
+ if (p->dlt_list != NULL)
+ free(p->dlt_list);
free(p);
}
+
+const char *
+pcap_lib_version(void)
+{
+ return (pcap_version_string);
+}
+