check_struct_has_member("struct msghdr" msg_flags "ftmacros.h;sys/socket.h" HAVE_STRUCT_MSGHDR_MSG_FLAGS)
cmake_pop_check_state()
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C}
- pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c)
+ pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c)
endif(ENABLE_REMOTE)
###################################################################
pcap-libdlpi.c \
pcap-linux.c \
pcap-namedb.h \
- pcap-new.c \
pcap-netfilter-linux.c \
pcap-netfilter-linux.h \
pcap-netmap.c \
AC_DEFINE(ENABLE_REMOTE,,
[Define to 1 if remote packet capture is to be supported])
- REMOTE_C_SRC="$REMOTE_C_SRC pcap-new.c pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c"
+ REMOTE_C_SRC="$REMOTE_C_SRC pcap-rpcap.c rpcap-protocol.c sockutils.c sslutils.c"
BUILD_RPCAPD=build-rpcapd
INSTALL_RPCAPD=install-rpcapd
;;
+++ /dev/null
-/*
- * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * nor the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ftmacros.h"
-#include "diag-control.h"
-
-/*
- * sockutils.h may include <crtdbg.h> on Windows, and pcap-int.h will
- * include portability.h, and portability.h, on Windows, expects that
- * <crtdbg.h> has already been included, so include sockutils.h first.
- */
-#include "sockutils.h"
-#include "pcap-int.h" // for the details of the pcap_t structure
-#include "pcap-rpcap.h"
-#include "rpcap-protocol.h"
-#include <errno.h> // for the errno variable
-#include <stdlib.h> // for malloc(), free(), ...
-#include <string.h> // for strstr, etc
-
-#ifndef _WIN32
-#include <dirent.h> // for readdir
-#endif
-
-/* String identifier to be used in the pcap_findalldevs_ex() */
-#define PCAP_TEXT_SOURCE_FILE "File"
-#define PCAP_TEXT_SOURCE_FILE_LEN (sizeof PCAP_TEXT_SOURCE_FILE - 1)
-/* String identifier to be used in the pcap_findalldevs_ex() */
-#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
-#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof "Network adapter" - 1)
-
-/* String identifier to be used in the pcap_findalldevs_ex() */
-#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host"
-#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_LOCAL_HOST + 1)
-
-/****************************************************
- * *
- * Function bodies *
- * *
- ****************************************************/
-
-int pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
-{
- int type;
- char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
- size_t pathlen;
- size_t stringlen;
- pcap_t *fp;
- char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
- pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
- pcap_if_t *dev; /* Device we're adding to the pcap_if_t list */
-
- /* List starts out empty. */
- (*alldevs) = NULL;
- lastdev = NULL;
-
- if (strlen(source) > PCAP_BUF_SIZE)
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
- return -1;
- }
-
- /*
- * Determine the type of the source (file, local, remote)
- * There are some differences if pcap_findalldevs_ex() is called to list files and remote adapters.
- * In the first case, the name of the directory we have to look into must be present (therefore
- * the 'name' parameter of the pcap_parsesrcstr() is present).
- * In the second case, the name of the adapter is not required (we need just the host). So, we have
- * to use a first time this function to get the source type, and a second time to get the appropriate
- * info, which depends on the source type.
- */
- if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
- return -1;
-
- switch (type)
- {
- case PCAP_SRC_IFLOCAL:
- if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
- return -1;
-
- /* Initialize temporary string */
- tmpstring[PCAP_BUF_SIZE] = 0;
-
- /* The user wants to retrieve adapters from a local host */
- if (pcap_findalldevs(alldevs, errbuf) == -1)
- return -1;
-
- if (*alldevs == NULL)
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "No interfaces found! Make sure libpcap/Npcap is properly installed"
- " on the local machine.");
- return -1;
- }
-
- /* Scan all the interfaces and modify name and description */
- /* This is a trick in order to avoid the re-implementation of the pcap_findalldevs here */
- dev = *alldevs;
- while (dev)
- {
- char *localdesc, *desc;
-
- /* Create the new device identifier */
- if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1)
- return -1;
-
- /* Delete the old pointer */
- free(dev->name);
-
- /* Make a copy of the new device identifier */
- dev->name = strdup(tmpstring);
- if (dev->name == NULL)
- {
- pcap_fmt_errmsg_for_errno(errbuf,
- PCAP_ERRBUF_SIZE, errno,
- "malloc() failed");
- pcap_freealldevs(*alldevs);
- return -1;
- }
-
- /*
- * Create the description.
- */
- if ((dev->description == NULL) || (dev->description[0] == 0))
- localdesc = dev->name;
- else
- localdesc = dev->description;
- if (pcap_asprintf(&desc, "%s '%s' %s",
- PCAP_TEXT_SOURCE_ADAPTER, localdesc,
- PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
- {
- pcap_fmt_errmsg_for_errno(errbuf,
- PCAP_ERRBUF_SIZE, errno,
- "malloc() failed");
- pcap_freealldevs(*alldevs);
- return -1;
- }
-
- /* Now overwrite the description */
- free(dev->description);
- dev->description = desc;
-
- dev = dev->next;
- }
-
- return 0;
-
- case PCAP_SRC_FILE:
- {
-#ifdef _WIN32
- WIN32_FIND_DATA filedata;
- HANDLE filehandle;
-#else
- struct dirent *filedata;
- DIR *unixdir;
-#endif
-
- if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
- return -1;
-
- /* Check that the filename is correct */
- stringlen = strlen(name);
-
- /* The directory must end with '\' in Win32 and '/' in UNIX */
-#ifdef _WIN32
-#define ENDING_CHAR '\\'
-#else
-#define ENDING_CHAR '/'
-#endif
-
- if (name[stringlen - 1] != ENDING_CHAR)
- {
- name[stringlen] = ENDING_CHAR;
- name[stringlen + 1] = 0;
-
- stringlen++;
- }
-
- /* Save the path for future reference */
- snprintf(path, sizeof(path), "%s", name);
- pathlen = strlen(path);
-
-#ifdef _WIN32
- /* To perform directory listing, Win32 must have an 'asterisk' as ending char */
- if (name[stringlen - 1] != '*')
- {
- name[stringlen] = '*';
- name[stringlen + 1] = 0;
- }
-
- filehandle = FindFirstFile(name, &filedata);
-
- if (filehandle == INVALID_HANDLE_VALUE)
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path);
- return -1;
- }
-
-#else
- /* opening the folder */
- unixdir= opendir(path);
-
- /* get the first file into it */
- filedata= readdir(unixdir);
-
- if (filedata == NULL)
- {
- DIAG_OFF_FORMAT_TRUNCATION
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error when listing files: does folder '%s' exist?", path);
- DIAG_ON_FORMAT_TRUNCATION
- closedir(unixdir);
- return -1;
- }
-#endif
-
- /* Add all files we find to the list. */
- do
- {
-#ifdef _WIN32
- /* Skip the file if the pathname won't fit in the buffer */
- if (pathlen + strlen(filedata.cFileName) >= sizeof(filename))
- continue;
- snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
-#else
- if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
- continue;
- DIAG_OFF_FORMAT_TRUNCATION
- snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
- DIAG_ON_FORMAT_TRUNCATION
-#endif
-
- fp = pcap_open_offline(filename, errbuf);
-
- if (fp)
- {
- /* allocate the main structure */
- dev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
- if (dev == NULL)
- {
- pcap_fmt_errmsg_for_errno(errbuf,
- PCAP_ERRBUF_SIZE, errno,
- "malloc() failed");
- pcap_freealldevs(*alldevs);
-#ifdef _WIN32
- FindClose(filehandle);
-#else
- closedir(unixdir);
-#endif
- return -1;
- }
-
- /* Initialize the structure to 'zero' */
- memset(dev, 0, sizeof(pcap_if_t));
-
- /* Append it to the list. */
- if (lastdev == NULL)
- {
- /*
- * List is empty, so it's also
- * the first device.
- */
- *alldevs = dev;
- }
- else
- {
- /*
- * Append after the last device.
- */
- lastdev->next = dev;
- }
- /* It's now the last device. */
- lastdev = dev;
-
- /* Create the new source identifier */
- if (pcap_createsrcstr(tmpstring, PCAP_SRC_FILE, NULL, NULL, filename, errbuf) == -1)
- {
- pcap_freealldevs(*alldevs);
-#ifdef _WIN32
- FindClose(filehandle);
-#else
- closedir(unixdir);
-#endif
- return -1;
- }
-
- dev->name = strdup(tmpstring);
- if (dev->name == NULL)
- {
- pcap_fmt_errmsg_for_errno(errbuf,
- PCAP_ERRBUF_SIZE, errno,
- "malloc() failed");
- pcap_freealldevs(*alldevs);
-#ifdef _WIN32
- FindClose(filehandle);
-#else
- closedir(unixdir);
-#endif
- return -1;
- }
-
- /*
- * Create the description.
- */
- if (pcap_asprintf(&dev->description,
- "%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
- filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1)
- {
- pcap_fmt_errmsg_for_errno(errbuf,
- PCAP_ERRBUF_SIZE, errno,
- "malloc() failed");
- pcap_freealldevs(*alldevs);
-#ifdef _WIN32
- FindClose(filehandle);
-#else
- closedir(unixdir);
-#endif
- return -1;
- }
-
- pcap_close(fp);
- }
- }
-#ifdef _WIN32
- while (FindNextFile(filehandle, &filedata) != 0);
-#else
- while ( (filedata= readdir(unixdir)) != NULL);
-#endif
-
-
- /* Close the search handle. */
-#ifdef _WIN32
- FindClose(filehandle);
-#else
- closedir(unixdir);
-#endif
-
- return 0;
- }
-
- case PCAP_SRC_IFREMOTE:
- return pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf);
-
- default:
- pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
- return -1;
- }
-}
-
-pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
-{
- char name[PCAP_BUF_SIZE];
- int type;
- pcap_t *fp;
- int status;
-
- /*
- * A null device name is equivalent to the "any" device -
- * which might not be supported on this platform, but
- * this means that you'll get a "not supported" error
- * rather than, say, a crash when we try to dereference
- * the null pointer.
- */
- if (source == NULL)
- source = "any";
-
- if (strlen(source) > PCAP_BUF_SIZE)
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "The source string is too long. Cannot handle it correctly.");
- return NULL;
- }
-
- /*
- * Determine the type of the source (file, local, remote) and,
- * if it's file or local, the name of the file or capture device.
- */
- if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
- return NULL;
-
- switch (type)
- {
- case PCAP_SRC_FILE:
- return pcap_open_offline(name, errbuf);
-
- case PCAP_SRC_IFLOCAL:
- fp = pcap_create(name, errbuf);
- break;
-
- case PCAP_SRC_IFREMOTE:
- /*
- * Although we already have host, port and iface, we prefer
- * to pass only 'source' to pcap_open_rpcap(), so that it
- * has to call pcap_parsesrcstr() again.
- * This is less optimized, but much clearer.
- */
- return pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
-
- default:
- pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
- return NULL;
- }
-
- if (fp == NULL)
- return (NULL);
- status = pcap_set_snaplen(fp, snaplen);
- if (status < 0)
- goto fail;
- if (flags & PCAP_OPENFLAG_PROMISCUOUS)
- {
- status = pcap_set_promisc(fp, 1);
- if (status < 0)
- goto fail;
- }
- if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
- {
- status = pcap_set_immediate_mode(fp, 1);
- if (status < 0)
- goto fail;
- }
-#ifdef _WIN32
- /*
- * This flag is supported on Windows only.
- * XXX - is there a way to support it with
- * the capture mechanisms on UN*X? It's not
- * exactly a "set direction" operation; I
- * think it means "do not capture packets
- * injected with pcap_sendpacket() or
- * pcap_inject()".
- */
- /* disable loopback capture if requested */
- if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
- fp->opt.nocapture_local = 1;
-#endif /* _WIN32 */
- status = pcap_set_timeout(fp, read_timeout);
- if (status < 0)
- goto fail;
- status = pcap_activate(fp);
- if (status < 0)
- goto fail;
- return fp;
-
-fail:
- DIAG_OFF_FORMAT_TRUNCATION
- if (status == PCAP_ERROR)
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
- name, fp->errbuf);
- else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
- status == PCAP_ERROR_PERM_DENIED ||
- status == PCAP_ERROR_PROMISC_PERM_DENIED)
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)",
- name, pcap_statustostr(status), fp->errbuf);
- else
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
- name, pcap_statustostr(status));
- DIAG_ON_FORMAT_TRUNCATION
- pcap_close(fp);
- return NULL;
-}
-
-struct pcap_samp *pcap_setsampling(pcap_t *p)
-{
- return &p->rmt_samp;
-}
#include <config.h>
#endif
+/*
+ * Include this before including any system header files, as it
+ * may do some #defines that cause those headerss to declare
+ * more functions that it does by default.
+ */
+#include "ftmacros.h"
+
#include <pcap-types.h>
#ifndef _WIN32
#include <sys/param.h>
#include "pcap-airpcap.h"
#endif
+#ifdef ENABLE_REMOTE
+#include "pcap-rpcap.h"
+#endif
+
#ifdef _WIN32
/*
* To quote the WSAStartup() documentation:
#endif
) {
*netp = *maskp = 0;
- return 0;
+ return (0);
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
}
#endif /* !defined(_WIN32) */
-#ifdef ENABLE_REMOTE
-#include "pcap-rpcap.h"
-
/*
* Extract a substring from a string.
*/
{
return (pcap_parsesrcstr_ex(source, type, NULL, host, port, name, NULL, errbuf));
}
-#endif
pcap_t *
pcap_create(const char *device, char *errbuf)
pcap_debug = value;
}
#endif
+
+/*
+ * APIs.added in WinPcap for remote capture.
+ *
+ * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino, CACE Technologies
+ * nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _WIN32
+#include <dirent.h> // for readdir
+#endif
+
+/* String identifier to be used in the pcap_findalldevs_ex() */
+#define PCAP_TEXT_SOURCE_FILE "File"
+#define PCAP_TEXT_SOURCE_FILE_LEN (sizeof PCAP_TEXT_SOURCE_FILE - 1)
+/* String identifier to be used in the pcap_findalldevs_ex() */
+#define PCAP_TEXT_SOURCE_ADAPTER "Network adapter"
+#define PCAP_TEXT_SOURCE_ADAPTER_LEN (sizeof "Network adapter" - 1)
+
+/* String identifier to be used in the pcap_findalldevs_ex() */
+#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST "on local host"
+#define PCAP_TEXT_SOURCE_ON_LOCAL_HOST_LEN (sizeof PCAP_TEXT_SOURCE_ON_LOCAL_HOST + 1)
+
+/****************************************************
+ * *
+ * Function bodies *
+ * *
+ ****************************************************/
+
+#ifdef ENABLE_REMOTE
+ #define _USED_FOR_REMOTE
+#else
+ #define _USED_FOR_REMOTE _U_
+#endif
+
+int
+pcap_findalldevs_ex(const char *source, struct pcap_rmtauth *auth _USED_FOR_REMOTE,
+ pcap_if_t **alldevs, char *errbuf)
+{
+ int type;
+ char name[PCAP_BUF_SIZE], path[PCAP_BUF_SIZE], filename[PCAP_BUF_SIZE];
+ size_t pathlen;
+ size_t stringlen;
+ pcap_t *fp;
+ char tmpstring[PCAP_BUF_SIZE + 1]; /* Needed to convert names and descriptions from 'old' syntax to the 'new' one */
+ pcap_if_t *lastdev; /* Last device in the pcap_if_t list */
+ pcap_if_t *dev; /* Device we're adding to the pcap_if_t list */
+
+ /* List starts out empty. */
+ (*alldevs) = NULL;
+ lastdev = NULL;
+
+ if (strlen(source) > PCAP_BUF_SIZE) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "The source string is too long. Cannot handle it correctly.");
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Determine the type of the source (file, local, remote).
+ *
+ * There are some differences if pcap_findalldevs_ex() is called to
+ * list files and remote adapters.
+ *
+ * In the first case, the name of the directory we have to look into
+ * must be present (therefore the 'name' parameter of the
+ * pcap_parsesrcstr() is present).
+ *
+ * In the second case, the name of the adapter is not required
+ * (we need just the host). So, we have to use this function a
+ * first time to get the source type, and a second time to get
+ * the appropriate info, which depends on the source type.
+ */
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
+ return (PCAP_ERROR);
+
+ switch (type) {
+
+ case PCAP_SRC_IFLOCAL:
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, NULL, errbuf) == -1)
+ return (PCAP_ERROR);
+
+ /* Initialize temporary string */
+ tmpstring[PCAP_BUF_SIZE] = 0;
+
+ /* The user wants to retrieve adapters from a local host */
+ if (pcap_findalldevs(alldevs, errbuf) == -1)
+ return (PCAP_ERROR);
+
+ if (*alldevs == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "No interfaces found! Make sure libpcap/Npcap is properly installed"
+ " on the local machine.");
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Scan all the interfaces and modify name and description.
+ *
+ * This is a trick in order to avoid the re-implementation
+ * of pcap_findalldevs here.
+ */
+ dev = *alldevs;
+ while (dev) {
+ char *localdesc, *desc;
+
+ /* Create the new device identifier */
+ if (pcap_createsrcstr(tmpstring, PCAP_SRC_IFLOCAL, NULL, NULL, dev->name, errbuf) == -1)
+ return (PCAP_ERROR);
+
+ /* Delete the old pointer */
+ free(dev->name);
+
+ /* Make a copy of the new device identifier */
+ dev->name = strdup(tmpstring);
+ if (dev->name == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Create the description.
+ */
+ if ((dev->description == NULL) ||
+ (dev->description[0] == 0))
+ localdesc = dev->name;
+ else
+ localdesc = dev->description;
+ if (pcap_asprintf(&desc, "%s '%s' %s",
+ PCAP_TEXT_SOURCE_ADAPTER, localdesc,
+ PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1) {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
+ return (PCAP_ERROR);
+ }
+
+ /* Now overwrite the description */
+ free(dev->description);
+ dev->description = desc;
+
+ dev = dev->next;
+ }
+
+ return (0);
+
+ case PCAP_SRC_FILE:
+ {
+#ifdef _WIN32
+ WIN32_FIND_DATA filedata;
+ HANDLE filehandle;
+#else
+ struct dirent *filedata;
+ DIR *unixdir;
+#endif
+
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
+ return (PCAP_ERROR);
+
+ /* Check that the filename is correct */
+ stringlen = strlen(name);
+
+ /*
+ * The directory must end with '\' in Windows and
+ * '/' in UN*Xes.
+ */
+#ifdef _WIN32
+#define ENDING_CHAR '\\'
+#else
+#define ENDING_CHAR '/'
+#endif
+
+ if (name[stringlen - 1] != ENDING_CHAR) {
+ name[stringlen] = ENDING_CHAR;
+ name[stringlen + 1] = 0;
+
+ stringlen++;
+ }
+
+ /* Save the path for future reference */
+ snprintf(path, sizeof(path), "%s", name);
+ pathlen = strlen(path);
+
+#ifdef _WIN32
+ /*
+ * To perform directory listing, Windows must have an
+ * asterisk as the ending character.
+ */
+ if (name[stringlen - 1] != '*') {
+ name[stringlen] = '*';
+ name[stringlen + 1] = 0;
+ }
+
+ filehandle = FindFirstFile(name, &filedata);
+
+ if (filehandle == INVALID_HANDLE_VALUE) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Error when listing files: does folder '%s' exist?", path);
+ return (PCAP_ERROR);
+ }
+
+#else
+ /* opening the folder */
+ unixdir= opendir(path);
+
+ /* get the first file into it */
+ filedata= readdir(unixdir);
+
+ if (filedata == NULL) {
+ DIAG_OFF_FORMAT_TRUNCATION
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Error when listing files: does folder '%s' exist?", path);
+ DIAG_ON_FORMAT_TRUNCATION
+ closedir(unixdir);
+ return (PCAP_ERROR);
+ }
+#endif
+
+ /* Add all files we find to the list. */
+ do {
+#ifdef _WIN32
+ /* Skip the file if the pathname won't fit in the buffer */
+ if (pathlen + strlen(filedata.cFileName) >= sizeof(filename))
+ continue;
+ snprintf(filename, sizeof(filename), "%s%s", path, filedata.cFileName);
+#else
+ if (pathlen + strlen(filedata->d_name) >= sizeof(filename))
+ continue;
+ DIAG_OFF_FORMAT_TRUNCATION
+ snprintf(filename, sizeof(filename), "%s%s", path, filedata->d_name);
+ DIAG_ON_FORMAT_TRUNCATION
+#endif
+
+ fp = pcap_open_offline(filename, errbuf);
+
+ if (fp) {
+ /* allocate the main structure */
+ dev = (pcap_if_t *)malloc(sizeof(pcap_if_t));
+ if (dev == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
+#ifdef _WIN32
+ FindClose(filehandle);
+#else
+ closedir(unixdir);
+#endif
+ return (PCAP_ERROR);
+ }
+
+ /* Initialize the structure to 'zero' */
+ memset(dev, 0, sizeof(pcap_if_t));
+
+ /* Append it to the list. */
+ if (lastdev == NULL) {
+ /*
+ * List is empty, so it's also
+ * the first device.
+ */
+ *alldevs = dev;
+ } else {
+ /*
+ * Append after the last device.
+ */
+ lastdev->next = dev;
+ }
+ /* It's now the last device. */
+ lastdev = dev;
+
+ /* Create the new source identifier */
+ if (pcap_createsrcstr(tmpstring, PCAP_SRC_FILE,
+ NULL, NULL, filename, errbuf) == -1) {
+ pcap_freealldevs(*alldevs);
+#ifdef _WIN32
+ FindClose(filehandle);
+#else
+ closedir(unixdir);
+#endif
+ return (PCAP_ERROR);
+ }
+
+ dev->name = strdup(tmpstring);
+ if (dev->name == NULL) {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
+#ifdef _WIN32
+ FindClose(filehandle);
+#else
+ closedir(unixdir);
+#endif
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Create the description.
+ */
+ if (pcap_asprintf(&dev->description,
+ "%s '%s' %s", PCAP_TEXT_SOURCE_FILE,
+ filename, PCAP_TEXT_SOURCE_ON_LOCAL_HOST) == -1) {
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "malloc() failed");
+ pcap_freealldevs(*alldevs);
+#ifdef _WIN32
+ FindClose(filehandle);
+#else
+ closedir(unixdir);
+#endif
+ return (PCAP_ERROR);
+ }
+
+ pcap_close(fp);
+ }
+ }
+#ifdef _WIN32
+ while (FindNextFile(filehandle, &filedata) != 0);
+#else
+ while ( (filedata= readdir(unixdir)) != NULL);
+#endif
+
+
+ /* Close the search handle. */
+#ifdef _WIN32
+ FindClose(filehandle);
+#else
+ closedir(unixdir);
+#endif
+
+ return (0);
+ }
+
+ case PCAP_SRC_IFREMOTE:
+#ifdef ENABLE_REMOTE
+ return (pcap_findalldevs_ex_remote(source, auth, alldevs, errbuf));
+#else
+ pcap_strlcpy(errbuf, "Remote packte capture is not supported",
+ PCAP_ERRBUF_SIZE);
+ return (PCAP_ERROR);
+#endif
+
+ default:
+ pcap_strlcpy(errbuf, "Source type not supported", PCAP_ERRBUF_SIZE);
+ return (PCAP_ERROR);
+ }
+}
+
+pcap_t *
+pcap_open(const char *source, int snaplen, int flags, int read_timeout,
+ struct pcap_rmtauth *auth _USED_FOR_REMOTE, char *errbuf)
+{
+ char name[PCAP_BUF_SIZE];
+ int type;
+ pcap_t *fp;
+ int status;
+
+ /*
+ * A null device name is equivalent to the "any" device -
+ * which might not be supported on this platform, but
+ * this means that you'll get a "not supported" error
+ * rather than, say, a crash when we try to dereference
+ * the null pointer.
+ */
+ if (source == NULL)
+ source = "any";
+
+ if (strlen(source) > PCAP_BUF_SIZE) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "The source string is too long. Cannot handle it correctly.");
+ return (NULL);
+ }
+
+ /*
+ * Determine the type of the source (file, local, remote) and,
+ * if it's file or local, the name of the file or capture device.
+ */
+ if (pcap_parsesrcstr(source, &type, NULL, NULL, name, errbuf) == -1)
+ return (NULL);
+
+ switch (type) {
+ case PCAP_SRC_FILE:
+ return pcap_open_offline(name, errbuf);
+
+ case PCAP_SRC_IFLOCAL:
+ fp = pcap_create(name, errbuf);
+ break;
+
+ case PCAP_SRC_IFREMOTE:
+#ifdef ENABLE_REMOTE
+ /*
+ * Although we already have host, port and iface, we prefer
+ * to pass only 'source' to pcap_open_rpcap(), so that it
+ * has to call pcap_parsesrcstr() again.
+ * This is less optimized, but much clearer.
+ */
+ return (pcap_open_rpcap(source, snaplen, flags, read_timeout,
+ auth, errbuf));
+#else
+ pcap_strlcpy(errbuf, "Remote packte capture is not supported",
+ PCAP_ERRBUF_SIZE);
+ return (NULL);
+#endif
+
+ default:
+ pcap_strlcpy(errbuf, "Source type not supported",
+ PCAP_ERRBUF_SIZE);
+ return (NULL);
+ }
+
+ if (fp == NULL)
+ return (NULL);
+ status = pcap_set_snaplen(fp, snaplen);
+ if (status < 0)
+ goto fail;
+ if (flags & PCAP_OPENFLAG_PROMISCUOUS) {
+ status = pcap_set_promisc(fp, 1);
+ if (status < 0)
+ goto fail;
+ }
+ if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS) {
+ status = pcap_set_immediate_mode(fp, 1);
+ if (status < 0)
+ goto fail;
+ }
+#ifdef _WIN32
+ /*
+ * This flag is supported on Windows only.
+ * XXX - is there a way to support it with
+ * the capture mechanisms on UN*X? It's not
+ * exactly a "set direction" operation; I
+ * think it means "do not capture packets
+ * injected with pcap_sendpacket() or
+ * pcap_inject()".
+ */
+ /* disable loopback capture if requested */
+ if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
+ fp->opt.nocapture_local = 1;
+#endif /* _WIN32 */
+ status = pcap_set_timeout(fp, read_timeout);
+ if (status < 0)
+ goto fail;
+ status = pcap_activate(fp);
+ if (status < 0)
+ goto fail;
+ return fp;
+
+fail:
+ DIAG_OFF_FORMAT_TRUNCATION
+ if (status == PCAP_ERROR)
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ name, fp->errbuf);
+ else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
+ status == PCAP_ERROR_PERM_DENIED ||
+ status == PCAP_ERROR_PROMISC_PERM_DENIED)
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)",
+ name, pcap_statustostr(status), fp->errbuf);
+ else
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ name, pcap_statustostr(status));
+ DIAG_ON_FORMAT_TRUNCATION
+ pcap_close(fp);
+ return (NULL);
+}
+
+struct pcap_samp *
+pcap_setsampling(pcap_t *p _USED_FOR_REMOTE)
+{
+#ifdef ENABLE_REMOTE
+ return (&p->rmt_samp);
+#else
+ return (NULL);
+#endif
+}
#endif /* _WIN32/MSDOS/UN*X */
/*
- * Remote capture definitions.
- *
- * These routines are only present if libpcap has been configured to
- * include remote capture support.
+ * APIs.added in WinPcap for remote capture.
+ *
+ * They are present even if remote capture isn't enabled, as they
+ * also support local capture, and as their absence may complicate
+ * code build on macOS 14 with Xcode 15, as that platform supports
+ * "weakly linked symbols":
+ *
+ * https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
+ *
+ * which are symbols in dynamically-linked shared libraries, declare in
+ * such a fashion that if a program linked against a newer software
+ * development kit (SDK), and using a symbol present in the OS version
+ * for which that SDK is provided, is run on an older OS version that
+ * lacks that symbol, that symbol's value is a NULL pointer. This
+ * allows those programs to test for the presence of that symbol
+ * by checking whether it's non-null and, if it is, using the symbol,
+ * otherwise not using it.
+ *
+ * (This is a slightly more convenient alternative to the usual
+ * technique used on Windows - and also available, and sometimes
+ * used, on UN*Xes - of loading the library containing the symbol
+ * at run time with dlopen() on UN*Xes and LoadLibrary() on Windows,
+ * looking up the symbol with dlsym() on UN*Xes and GetProcAddress()
+ * on Windows, and using the symbol with the returned pointer if it's
+ * not null.)
*/
/*
}
#endif
-#ifdef ENABLE_REMOTE
int main(int argc, char **argv)
-#else
-int main(int argc _U_, char **argv _U_)
-#endif
{
pcap_if_t *alldevs;
pcap_if_t *d;
bpf_u_int32 net, mask;
int exit_status = 0;
char errbuf[PCAP_ERRBUF_SIZE+1];
-#ifdef ENABLE_REMOTE
struct pcap_rmtauth auth;
char username[128+1];
char *p;
char *password;
-#endif
-#ifdef ENABLE_REMOTE
if (argc >= 2)
{
if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
}
}
else
-#endif
{
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
{
register int op;
register char *cp, *device;
- int dorfmon, dopromisc, snaplen, useactivate, bufsize;
+ int dorfmon, dopromisc, snaplen, useactivate, useopen, bufsize;
char ebuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist;
pcap_t *pd;
snaplen = MAXIMUM_SNAPLEN;
bufsize = 0;
useactivate = 0;
+ useopen = 0;
if ((cp = strrchr(argv[0], '/')) != NULL)
program_name = cp + 1;
else
program_name = argv[0];
opterr = 0;
- while ((op = getopt(argc, argv, "i:Ips:aB:")) != -1) {
+ while ((op = getopt(argc, argv, "i:Iops:aB:")) != -1) {
switch (op) {
case 'i':
useactivate = 1; /* required for rfmon */
break;
+ case 'o':
+ useopen = 1;
+ break;
+
case 'p':
dopromisc = 1;
break;
pcap_statustostr(status), pcap_geterr(pd));
} else
printf("%s opened successfully\n", device);
+ } else if (useopen) {
+ *ebuf = '\0';
+ pd = pcap_open(device, 65535, PCAP_OPENFLAG_PROMISCUOUS,
+ 1000, NULL, ebuf);
+ if (pd == NULL)
+ error("%s", ebuf);
+ else if (*ebuf)
+ warning("%s", ebuf);
+ else
+ printf("%s opened successfully\n", device);
} else {
*ebuf = '\0';
pd = pcap_open_live(device, 65535, 0, 1000, ebuf);