diff --git a/net-libs/libpcap/libpcap-1.7.3.recipe b/net-libs/libpcap/libpcap-1.7.3.recipe new file mode 100644 index 000000000..b45b50073 --- /dev/null +++ b/net-libs/libpcap/libpcap-1.7.3.recipe @@ -0,0 +1,82 @@ +SUMMARY="A system-independent interface for user-level packet capture" +HOMEPAGE="http://www.tcpdump.org" +COPYRIGHT="1996-2014, Daniel Stenberg, . All rights reserved." +LICENSE="BSD (3-clause)" +SRC_URI="http://www.tcpdump.org/release/libpcap-$portVersion.tar.gz" +CHECKSUM_SHA256="dd9f85213dc8e948068405b55dd20f8b32e3083e9e0e186f833bd0372e559e2f" +REVISION="1" +ARCHITECTURES="x86_gcc2 x86 x86_64 arm" +SECONDARY_ARCHITECTURES="x86_gcc2 x86" + +PATCHES="libpcap-$portVersion.patchset" + +PROVIDES=" + libpcap$secondaryArchSuffix = $portVersion + lib:libpcap$secondaryArchSuffix = $portVersion compat >= 1 + " + +REQUIRES=" + haiku$secondaryArchSuffix + " +BUILD_REQUIRES=" + haiku${secondaryArchSuffix}_devel + " +BUILD_PREREQUIRES=" + cmd:autoconf + cmd:gcc$secondaryArchSuffix + cmd:ld$secondaryArchSuffix + cmd:libtoolize + cmd:make + cmd:bison + cmd:flex + cmd:pkg_config$secondaryArchSuffix + " + +BUILD() +{ + autoreconf -fi + CFLAGS="-D_BSD_SOURCE" runConfigure ./configure \ + --enable-shared + make $jobArgs +} + +INSTALL() +{ + make install + + # prepare develop/lib + prepareInstalledDevelLibs libpcap + fixPkgconfig + + # devel package + packageEntries devel \ + $developDir \ + $binDir/pcap-config + +} + +TEST() +{ + make check +} + +DESCRIPTION=" +libpcap provides a portable \ +framework for low-level network monitoring. Applications include \ +network statistics collection, security monitoring, network debugging, \ +etc. Since almost every system vendor provides a different interface \ +for packet capture, and since we''ve developed several tools that \ +require this functionality, we''ve created this system-independent API \ +to ease in porting and to alleviate the need for several \ +system-dependent packet capture modules in each application." + +# ----- devel package ------------------------------------------------------- + +PROVIDES_devel=" + libpcap${secondaryArchSuffix}_devel = $portVersion + cmd:pcap_config$secondaryArchSuffix + devel:libpcap$secondaryArchSuffix = $portVersion compat >= 1 + " +REQUIRES_devel=" + libpcap$secondaryArchSuffix == $portVersion base + " diff --git a/net-libs/libpcap/patches/libpcap-1.7.3.patchset b/net-libs/libpcap/patches/libpcap-1.7.3.patchset new file mode 100644 index 000000000..54c84861d --- /dev/null +++ b/net-libs/libpcap/patches/libpcap-1.7.3.patchset @@ -0,0 +1,425 @@ +From bd45ddf62df401e0de9ae034b3b66306e52d0c86 Mon Sep 17 00:00:00 2001 +From: Jerome Duval +Date: Tue, 28 Apr 2015 18:39:03 +0000 +Subject: Haiku patch + + +diff --git a/Makefile.in b/Makefile.in +index f317973..a3d89ae 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@ +@@ -84,7 +85,7 @@ YACC = @V_YACC@ + @rm -f $@ + $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c + +-PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @CAN_SRC@ @NETFILTER_SRC@ @CANUSB_SRC@ @DBUS_SRC@ ++PSRC = pcap-@V_PCAP@.cpp @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @CAN_SRC@ @NETFILTER_SRC@ @CANUSB_SRC@ @DBUS_SRC@ + FSRC = fad-@V_FINDALLDEVS@.c + SSRC = @SSRC@ + CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \ +@@ -97,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 = $(PSRC:.cpp=.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 02502b2..56f1422 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1105,7 +1105,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.in b/configure.in +index be4b29e..7b80c0b 100644 +--- a/configure.in ++++ b/configure.in +@@ -347,6 +347,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 +diff --git a/pcap-haiku.cpp b/pcap-haiku.cpp +new file mode 100644 +index 0000000..9b2b598 +--- /dev/null ++++ b/pcap-haiku.cpp +@@ -0,0 +1,354 @@ ++/* ++ * 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 ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* ++ * 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 = 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; ++ prepare_request(request, handlep->device); ++ ++ if (ioctl(handle->fd, SIOCGIFSTATS, &request, sizeof(struct ifreq)) < 0) { ++ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "pcap_stats: %s", ++ strerror(errno)); ++ return -1; ++ } ++ ++ 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.source; ++ ++ 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(device, 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; ++} ++ ++ ++extern "C" int ++pcap_platform_finddevs(pcap_if_t** _allDevices, char* errorBuffer) ++{ ++ // 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 -1; ++ } ++ ++ // get a list of all interfaces ++ ++ ifconf config; ++ config.ifc_len = sizeof(config.ifc_value); ++ if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0) { ++ close(socket); ++ return -1; ++ } ++ ++ uint32 count = (uint32)config.ifc_value; ++ if (count == 0) { ++ snprintf(errorBuffer, PCAP_ERRBUF_SIZE, ++ "There are no interfaces defined!\n"); ++ close(socket); ++ return -1; ++ } ++ ++ void* buffer = malloc(count * sizeof(struct ifreq)); ++ if (buffer == NULL) { ++ snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "Out of memory.\n"); ++ close(socket); ++ return -1; ++ } ++ ++ config.ifc_len = count * sizeof(struct ifreq); ++ config.ifc_buf = buffer; ++ if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0) { ++ close(socket); ++ return -1; ++ } ++ ++ ifreq* interface = (ifreq*)buffer; ++ ++ for (uint32 i = 0; i < count; i++) { ++ int flags = 0; ++ ++ // get interface type ++ ++ int linkSocket = ::socket(AF_LINK, SOCK_DGRAM, 0); ++ if (linkSocket < 0) { ++ fprintf(stderr, "No link level: %s\n", strerror(errno)); ++ } else { ++ struct ifreq request; ++ if (!prepare_request(request, interface->ifr_name)) { ++ snprintf(errorBuffer, PCAP_ERRBUF_SIZE, ++ "Interface name \"%s\" is too long.", interface->ifr_name); ++ close(linkSocket); ++ close(socket); ++ return -1; ++ } ++ ++ if (ioctl(linkSocket, SIOCGIFADDR, &request, sizeof(struct ifreq)) ++ == 0) { ++ sockaddr_dl &link = *(sockaddr_dl*)&request.ifr_addr; ++ ++ if (link.sdl_type == IFT_LOOP) ++ flags = IFF_LOOPBACK; ++ } ++ close(linkSocket); ++ } ++ ++ pcap_add_if(_allDevices, interface->ifr_name, flags, NULL, errorBuffer); ++ ++ interface = (ifreq*)((uint8*)interface ++ + _SIZEOF_ADDR_IFREQ(interface[0])); ++ } ++ ++ free(buffer); ++ close(socket); ++ return 0; ++} +-- +1.8.3.4 +