From a7ead691803de7e0f099aeda9ca7e2be437ea8ff Mon Sep 17 00:00:00 2001
From: Jerome Duval <jerome.duval@gmail.com>
Date: Tue, 28 Apr 2015 18:39:03 +0000
Subject: Haiku patch


diff --git a/Makefile.in b/Makefile.in
index e71d973..9be5f3a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -63,6 +63,7 @@ PROG=libpcap
 
 # Standard CFLAGS
 FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
+CXXFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
 
 INSTALL = @INSTALL@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -79,7 +80,12 @@ YACC = @YACC@
 	@rm -f $@
 	$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
 
-PSRC =	pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
+ifeq (@V_PCAP@,haiku)
+PCAPSRC = pcap-@V_PCAP@.cpp
+else
+PCAPSRC = pcap-@V_PCAP@.c
+endif
+PSRC =	$(PCAPSRC) @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @NETFILTER_SRC@ @DBUS_SRC@
 FSRC =  @V_FINDALLDEVS@
 SSRC =  @SSRC@
 CSRC =	pcap.c inet.c fad-helpers.c gencode.c optimize.c nametoaddr.c \
@@ -92,7 +98,7 @@ SRC =	$(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC)
 
 # We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
 # hack the extra indirection
-OBJ =	$(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS)
+OBJ =	$(patsubst %.cpp,%.o,$(PSRC:.c=.o)) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS)
 PUBHDR = \
 	pcap.h \
 	pcap-bpf.h \
diff --git a/aclocal.m4 b/aclocal.m4
index 83f5761..5da7783 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -447,7 +447,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
 	    aix*)
 		    ;;
 
-	    freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*)
+	    freebsd*|netbsd*|openbsd*|dragonfly*|linux*|osf*|haiku*)
 	    	    #
 		    # Platforms where the linker is the GNU linker
 		    # or accepts command-line arguments like
@@ -1065,7 +1065,7 @@ AC_DEFUN(AC_LBL_LIBRARY_NET, [
 	AC_CHECK_LIB(socket, gethostbyname,
                      LIBS="-lsocket -lnsl $LIBS", , -lnsl)
     fi
-    AC_SEARCH_LIBS(socket, socket, ,
+    AC_SEARCH_LIBS(socket, socket network, ,
 	AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))
     # DLPI needs putmsg under HPUX so test for -lstr while we're at it
     AC_SEARCH_LIBS(putmsg, str)
diff --git a/configure.ac b/configure.ac
index da2f940..ccdf999 100644
--- a/configure.ac
+++ b/configure.ac
@@ -381,6 +381,8 @@ elif test -c /dev/enet ; then		# check again in case not readable
 	V_PCAP=enet
 elif test -c /dev/nit ; then		# check again in case not readable
 	V_PCAP=snit
+elif test -r /boot/system ; then
+	V_PCAP=haiku
 else
 	V_PCAP=null
 fi
@@ -1384,7 +1386,7 @@ irix*)
 	MAN_MISC_INFO=5
 	;;
 
-linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*)
+linux*|freebsd*|netbsd*|openbsd*|dragonfly*|kfreebsd*|gnu*|haiku*)
 	DYEXT="so"
 
 	#
diff --git a/pcap-haiku.cpp b/pcap-haiku.cpp
new file mode 100644
index 0000000..983a7dc
--- /dev/null
+++ b/pcap-haiku.cpp
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *		Axel Dörfler, axeld@pinc-software.de
+ *		James Woodcock
+ */
+
+
+#include "config.h"
+#include "pcap-int.h"
+
+#include <OS.h>
+
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * Private data for capturing on Haiku sockets.
+ */
+struct pcap_haiku {
+	struct pcap_stat	stat;
+	char	*device;	/* device name */
+};
+
+
+bool
+prepare_request(struct ifreq& request, const char* name)
+{
+	if (strlen(name) >= IF_NAMESIZE)
+		return false;
+
+	strcpy(request.ifr_name, name);
+	return true;
+}
+
+
+static int
+pcap_read_haiku(pcap_t* handle, int maxPackets, pcap_handler callback,
+	u_char* userdata)
+{
+	// Receive a single packet
+
+	struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv;
+	u_char* buffer = (u_char*)handle->buffer + handle->offset;
+	struct sockaddr_dl from;
+	ssize_t bytesReceived;
+	do {
+		if (handle->break_loop) {
+			// Clear the break loop flag, and return -2 to indicate our
+			// reasoning
+			handle->break_loop = 0;
+			return -2;
+		}
+
+		socklen_t fromLength = sizeof(from);
+		bytesReceived = recvfrom(handle->fd, buffer, handle->bufsize, MSG_TRUNC,
+			(struct sockaddr*)&from, &fromLength);
+	} while (bytesReceived < 0 && errno == B_INTERRUPTED);
+
+	if (bytesReceived < 0) {
+		if (errno == B_WOULD_BLOCK) {
+			// there is no packet for us
+			return 0;
+		}
+
+		snprintf(handle->errbuf, sizeof(handle->errbuf),
+			"recvfrom: %s", strerror(errno));
+		return -1;
+	}
+
+	int32 captureLength = bytesReceived;
+	if (captureLength > handle->snapshot)
+		captureLength = handle->snapshot;
+
+/*
+	// run the packet filter
+	if (!handle->md.use_bpf && handle->fcode.bf_insns) {
+		if (bpf_filter(handle->fcode.bf_insns, buffer, bytesReceived,
+				captureLength) == 0) {
+			// packet got rejected
+			return 0;
+		}
+	}
+*/
+
+	// fill in pcap_header
+
+	pcap_pkthdr header;
+	header.caplen = captureLength;
+	header.len = bytesReceived;
+	header.ts.tv_usec = system_time() % 1000000;
+	header.ts.tv_sec = system_time() / 1000000;
+		// TODO: get timing from packet!!!
+
+	/* Call the user supplied callback function */
+	callback(userdata, &header, buffer);
+	return 1;
+}
+
+
+static int
+pcap_inject_haiku(pcap_t *handle, const void *buffer, size_t size)
+{
+	// we don't support injecting packets yet
+	// TODO: use the AF_LINK protocol (we need another socket for this) to
+	// inject the packets
+	strlcpy(handle->errbuf, "Sending packets isn't supported yet",
+		PCAP_ERRBUF_SIZE);
+	return -1;
+}
+
+
+static int
+pcap_setfilter_haiku(pcap_t *handle, struct bpf_program *filter)
+{
+	// Make our private copy of the filter
+	if (install_bpf_program(handle, filter) < 0) {
+		// install_bpf_program() filled in errbuf
+		return -1;
+	}
+
+	// we don't support kernel filters at all
+	//handle->md.use_bpf = 0;
+	return 0;
+}
+
+
+static int
+pcap_stats_haiku(pcap_t *handle, struct pcap_stat *stats)
+{
+	struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv;
+	ifreq request;
+	int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
+	if (socket < 0) {
+		return -1;
+	}
+	prepare_request(request, handlep->device);
+	if (ioctl(socket, SIOCGIFSTATS, &request, sizeof(struct ifreq)) < 0) {
+		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "pcap_stats: %s",
+			strerror(errno));
+		close(socket);
+		return -1;
+	}
+
+	close(socket);
+	handlep->stat.ps_recv += request.ifr_stats.receive.packets;
+	handlep->stat.ps_drop += request.ifr_stats.receive.dropped;
+	*stats = handlep->stat;
+	return 0;
+}
+
+
+static int
+pcap_activate_haiku(pcap_t *handle)
+{
+	struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv;
+
+	const char* device = handle->opt.device;
+
+	handle->read_op = pcap_read_haiku;
+	handle->setfilter_op = pcap_setfilter_haiku;
+	handle->inject_op = pcap_inject_haiku;
+	handle->stats_op = pcap_stats_haiku;
+
+	// use default hooks where possible
+	handle->getnonblock_op = pcap_getnonblock_fd;
+	handle->setnonblock_op = pcap_setnonblock_fd;
+	//handle->close_op = pcap_close_common;
+
+	handlep->device	= strdup(device);
+	if (handlep->device == NULL) {
+		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
+			 pcap_strerror(errno) );
+		return PCAP_ERROR;
+	}
+	
+	handle->bufsize = 65536;
+		// TODO: should be determined by interface MTU
+
+	// allocate buffer for monitoring the device
+	handle->buffer = (u_char*)malloc(handle->bufsize);
+	if (handle->buffer == NULL) {
+		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "buffer malloc: %s",
+			strerror(errno));
+		return PCAP_ERROR;
+	}
+
+	handle->offset = 0;
+	handle->linktype = DLT_EN10MB;
+		// TODO: check interface type!
+
+	return 0;
+}
+
+
+//	#pragma mark - pcap API
+
+
+extern "C" pcap_t *
+pcap_create_interface(const char *device, char *errorBuffer)
+{
+	// TODO: handle promiscous mode!
+
+	// we need a socket to talk to the networking stack
+	int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
+	if (socket < 0) {
+		snprintf(errorBuffer, PCAP_ERRBUF_SIZE,
+			"The networking stack doesn't seem to be available.\n");
+		return NULL;
+	}
+
+	struct ifreq request;
+	if (!prepare_request(request, device)) {
+		snprintf(errorBuffer, PCAP_ERRBUF_SIZE,
+			"Interface name \"%s\" is too long.", device);
+		close(socket);
+		return NULL;
+	}
+
+	// check if the interface exist
+	if (ioctl(socket, SIOCGIFINDEX, &request, sizeof(request)) < 0) {
+		snprintf(errorBuffer, PCAP_ERRBUF_SIZE,
+			"Interface \"%s\" does not exist.\n", device);
+		close(socket);
+		return NULL;
+	}
+
+	close(socket);
+		// no longer needed after this point
+
+	// get link level interface for this interface
+
+	socket = ::socket(AF_LINK, SOCK_DGRAM, 0);
+	if (socket < 0) {
+		snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "No link level: %s\n",
+			strerror(errno));
+		return NULL;
+	}
+
+	// start monitoring
+	if (ioctl(socket, SIOCSPACKETCAP, &request, sizeof(struct ifreq)) < 0) {
+		snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "Cannot start monitoring: %s\n",
+			strerror(errno));
+		close(socket);
+		return NULL;
+	}
+
+	pcap_t* handle = pcap_create_common(errorBuffer,
+		sizeof (struct pcap_haiku));
+	if (handle == NULL) {
+		snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "malloc: %s", strerror(errno));
+		close(socket);
+		return NULL;
+	}
+
+	handle->selectable_fd = socket;
+	handle->fd = socket;
+	
+	handle->activate_op = pcap_activate_haiku;
+	//handle->can_set_rfmon_op = pcap_can_set_rfmon_linux;
+
+	return handle;
+}
+
+static int
+canBeBound(const char *name)
+{
+	return 1;
+}
+
+extern "C" int
+pcap_platform_finddevs(pcap_if_t** _allDevices, char* errorBuffer)
+{
+	return pcap_findalldevs_interfaces(_allDevices, errorBuffer, canBeBound);
+}
-- 
2.26.0


From 96ccd9be2fd19e5dc644463cbd81940cfa0b1612 Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Tue, 26 Feb 2019 20:07:07 +0100
Subject: libpcap: fix 32bit x86 build

Confusion around the definition of int32...

diff --git a/bpf/net/bpf_filter.c b/bpf/net/bpf_filter.c
index 01a1b64..3503839 100644
--- a/bpf/net/bpf_filter.c
+++ b/bpf/net/bpf_filter.c
@@ -81,7 +81,9 @@
 #include <stdlib.h>
 #endif
 
+#ifndef __HAIKU__
 #define int32 bpf_int32
+#endif
 #define u_int32 bpf_u_int32
 
 #ifndef LBL_ALIGN
diff --git a/pcap/bpf.h b/pcap/bpf.h
index 78ad890..fc05d7c 100644
--- a/pcap/bpf.h
+++ b/pcap/bpf.h
@@ -81,7 +81,7 @@ extern "C" {
 /* BSD style release date */
 #define BPF_RELEASE 199606
 
-#ifdef MSDOS /* must be 32-bit */
+#if defined(MSDOS) || (defined(__HAIKU__) && defined(__X86__)) /* must be 32-bit */
 typedef long          bpf_int32;
 typedef unsigned long bpf_u_int32;
 #else
-- 
2.26.0

