summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/libpcap/pcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/contrib/libpcap/pcap.c')
-rw-r--r--freebsd/contrib/libpcap/pcap.c407
1 files changed, 264 insertions, 143 deletions
diff --git a/freebsd/contrib/libpcap/pcap.c b/freebsd/contrib/libpcap/pcap.c
index 4cf53b22..8ddeaec6 100644
--- a/freebsd/contrib/libpcap/pcap.c
+++ b/freebsd/contrib/libpcap/pcap.c
@@ -141,7 +141,7 @@ BOOL WINAPI DllMain(
/*
* Start WinSock.
- * Exported in case some applications using WinPcap called it,
+ * Exported in case some applications using WinPcap/Npcap called it,
* even though it wasn't exported.
*/
int
@@ -188,76 +188,165 @@ pcap_wsockinit(void)
PCAP_API char pcap_version[];
PCAP_API_DEF char pcap_version[] = PACKAGE_VERSION;
-static int
-pcap_not_initialized(pcap_t *pcap)
+static void
+pcap_set_not_initialized_message(pcap_t *pcap)
{
if (pcap->activated) {
/* A module probably forgot to set the function pointer */
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
"This operation isn't properly handled by that device");
- return (PCAP_ERROR);
+ return;
}
/* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
(void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
"This handle hasn't been activated yet");
+}
+
+static int
+pcap_read_not_initialized(pcap_t *pcap, int cnt _U_, pcap_handler callback _U_,
+ u_char *user _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_inject_not_initialized(pcap_t *pcap, const void * buf _U_, size_t size _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setfilter_not_initialized(pcap_t *pcap, struct bpf_program *fp _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setdirection_not_initialized(pcap_t *pcap, pcap_direction_t d _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_set_datalink_not_initialized(pcap_t *pcap, int dlt _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_getnonblock_not_initialized(pcap_t *pcap)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_stats_not_initialized(pcap_t *pcap, struct pcap_stat *ps _U_)
+{
+ pcap_set_not_initialized_message(pcap);
/* this means 'not initialized' */
return (PCAP_ERROR_NOT_ACTIVATED);
}
#ifdef _WIN32
-static void *
-pcap_not_initialized_ptr(pcap_t *pcap)
+struct pcap_stat *
+pcap_stats_ex_not_initialized(pcap_t *pcap, int *pcap_stat_size _U_)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (NULL);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (NULL);
}
+static int
+pcap_setbuff_not_initialized(pcap_t *pcap, int dim _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setmode_not_initialized(pcap_t *pcap, int mode _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_setmintocopy_not_initialized(pcap_t *pcap, int size _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
static HANDLE
pcap_getevent_not_initialized(pcap_t *pcap)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (INVALID_HANDLE_VALUE);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (INVALID_HANDLE_VALUE);
}
+static int
+pcap_oid_get_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
+ void *data _U_, size_t *lenp _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_oid_set_request_not_initialized(pcap_t *pcap, bpf_u_int32 oid _U_,
+ const void *data _U_, size_t *lenp _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
static u_int
pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (0);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (0);
}
+static int
+pcap_setuserbuffer_not_initialized(pcap_t *pcap, int size _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_live_dump_not_initialized(pcap_t *pcap, char *filename _U_, int maxsize _U_,
+ int maxpacks _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+static int
+pcap_live_dump_ended_not_initialized(pcap_t *pcap, int sync _U_)
+{
+ pcap_set_not_initialized_message(pcap);
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
static PAirpcapHandle
pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
{
- if (pcap->activated) {
- /* A module probably forgot to set the function pointer */
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This operation isn't properly handled by that device");
- return (NULL);
- }
- (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
- "This handle hasn't been activated yet");
+ pcap_set_not_initialized_message(pcap);
return (NULL);
}
#endif
@@ -298,8 +387,17 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
if (p->tstamp_type_count == 0) {
/*
* We don't support multiple time stamp types.
+ * That means the only type we support is PCAP_TSTAMP_HOST;
+ * set up a list containing only that type.
*/
- *tstamp_typesp = NULL;
+ *tstamp_typesp = (int*)malloc(sizeof(**tstamp_typesp));
+ if (*tstamp_typesp == NULL) {
+ pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
+ errno, "malloc");
+ return (PCAP_ERROR);
+ }
+ **tstamp_typesp = PCAP_TSTAMP_HOST;
+ return (1);
} else {
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
p->tstamp_type_count);
@@ -310,8 +408,8 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
}
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
sizeof(**tstamp_typesp) * p->tstamp_type_count);
+ return (p->tstamp_type_count);
}
- return (p->tstamp_type_count);
}
/*
@@ -661,7 +759,7 @@ get_if_description(const char *name)
* Get the description for the interface.
*/
memset(&ifrdesc, 0, sizeof ifrdesc);
- strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
+ pcap_strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
#ifdef __FreeBSD__
@@ -712,7 +810,7 @@ get_if_description(const char *name)
}
#endif /* __FreeBSD__ */
close(s);
- if (description != NULL && strlen(description) == 0) {
+ if (description != NULL && description[0] == '\0') {
/*
* Description is empty, so discard it.
*/
@@ -743,20 +841,13 @@ get_if_description(const char *name)
* OK, it's a valid number that's not
* bigger than INT_MAX. Construct
* a description from it.
+ * (If that fails, we don't worry about
+ * it, we just return NULL.)
*/
- static const char descr_prefix[] = "USB bus number ";
- size_t descr_size;
-
- /*
- * Allow enough room for a 32-bit bus number.
- * sizeof (descr_prefix) includes the
- * terminating NUL.
- */
- descr_size = sizeof (descr_prefix) + 10;
- description = malloc(descr_size);
- if (description != NULL) {
- pcap_snprintf(description, descr_size,
- "%s%ld", descr_prefix, busnum);
+ if (pcap_asprintf(&description,
+ "USB bus number %ld", busnum) == -1) {
+ /* Failed. */
+ description = NULL;
}
}
}
@@ -1294,14 +1385,14 @@ pcap_lookupdev(char *errbuf)
* on the list, there aren't any non-loopback devices,
* so why not just supply it as the default device?
*/
- (void)strlcpy(errbuf, "no suitable device found",
+ (void)pcap_strlcpy(errbuf, "no suitable device found",
PCAP_ERRBUF_SIZE);
ret = NULL;
} else {
/*
* Return the name of the first device on the list.
*/
- (void)strlcpy(device, alldevs->name, sizeof(device));
+ (void)pcap_strlcpy(device, alldevs->name, sizeof(device));
ret = device;
}
@@ -1368,7 +1459,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
- (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
if (errno == EADDRNOTAVAIL) {
(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -1387,7 +1478,7 @@ pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp,
/* XXX Work around Linux kernel bug */
ifr.ifr_addr.sa_family = AF_INET;
#endif
- (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ (void)pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFNETMASK: %s", device);
@@ -1577,13 +1668,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
* the pathname.
*/
if (pcap_strcasecmp(scheme, "file") == 0) {
- *schemep = scheme;
*pathp = strdup(colonp + 3);
if (*pathp == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
+ free(scheme);
return (-1);
}
+ *schemep = scheme;
return (0);
}
@@ -1686,7 +1778,12 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
* Treat verything up to the closing square
* bracket as the IP-Literal; we don't worry
* about whether it's a valid IPv6address or
- * IPvFuture.
+ * IPvFuture (or an IPv4address, for that
+ * matter, just in case we get handed a
+ * URL with an IPv4 IP-Literal, of the sort
+ * that pcap_createsrcstr() used to generate,
+ * and that pcap_parsesrcstr(), in the original
+ * WinPcap code, accepted).
*/
bracketp = strchr(parsep, ']');
if (bracketp == NULL) {
@@ -1807,9 +1904,9 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
switch (type) {
case PCAP_SRC_FILE:
- strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
+ pcap_strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
if (name != NULL && *name != '\0') {
- strlcat(source, name, PCAP_BUF_SIZE);
+ pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0);
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -1818,7 +1915,7 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
}
case PCAP_SRC_IFREMOTE:
- strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+ pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
if (host != NULL && *host != '\0') {
if (strchr(host, ':') != NULL) {
/*
@@ -1826,18 +1923,18 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
* probably an IPv6 address, and needs to
* be included in square brackets.
*/
- strlcat(source, "[", PCAP_BUF_SIZE);
- strlcat(source, host, PCAP_BUF_SIZE);
- strlcat(source, "]", PCAP_BUF_SIZE);
+ pcap_strlcat(source, "[", PCAP_BUF_SIZE);
+ pcap_strlcat(source, host, PCAP_BUF_SIZE);
+ pcap_strlcat(source, "]", PCAP_BUF_SIZE);
} else
- strlcat(source, host, PCAP_BUF_SIZE);
+ pcap_strlcat(source, host, PCAP_BUF_SIZE);
if (port != NULL && *port != '\0') {
- strlcat(source, ":", PCAP_BUF_SIZE);
- strlcat(source, port, PCAP_BUF_SIZE);
+ pcap_strlcat(source, ":", PCAP_BUF_SIZE);
+ pcap_strlcat(source, port, PCAP_BUF_SIZE);
}
- strlcat(source, "/", PCAP_BUF_SIZE);
+ pcap_strlcat(source, "/", PCAP_BUF_SIZE);
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"The host name cannot be NULL.");
@@ -1845,15 +1942,15 @@ pcap_createsrcstr(char *source, int type, const char *host, const char *port,
}
if (name != NULL && *name != '\0')
- strlcat(source, name, PCAP_BUF_SIZE);
+ pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0);
case PCAP_SRC_IFLOCAL:
- strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+ pcap_strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
if (name != NULL && *name != '\0')
- strlcat(source, name, PCAP_BUF_SIZE);
+ pcap_strlcat(source, name, PCAP_BUF_SIZE);
return (0);
@@ -1892,7 +1989,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* Local device.
*/
if (name && tmppath)
- strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_IFLOCAL;
free(tmppath);
@@ -1914,12 +2011,12 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
pcap_snprintf(host, PCAP_BUF_SIZE, "%s@%s",
tmpuserinfo, tmphost);
else
- strlcpy(host, tmphost, PCAP_BUF_SIZE);
+ pcap_strlcpy(host, tmphost, PCAP_BUF_SIZE);
}
if (port && tmpport)
- strlcpy(port, tmpport, PCAP_BUF_SIZE);
+ pcap_strlcpy(port, tmpport, PCAP_BUF_SIZE);
if (name && tmppath)
- strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_IFREMOTE;
free(tmppath);
@@ -1935,7 +2032,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* file://
*/
if (name && tmppath)
- strlcpy(name, tmppath, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, tmppath, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_FILE;
free(tmppath);
@@ -1951,7 +2048,7 @@ pcap_parsesrcstr(const char *source, int *type, char *host, char *port,
* as a local device.
*/
if (name)
- strlcpy(name, source, PCAP_BUF_SIZE);
+ pcap_strlcpy(name, source, PCAP_BUF_SIZE);
if (type)
*type = PCAP_SRC_IFLOCAL;
free(tmppath);
@@ -1983,11 +2080,28 @@ pcap_create(const char *device, char *errbuf)
else {
#ifdef _WIN32
/*
- * If the string appears to be little-endian UCS-2/UTF-16,
- * convert it to ASCII.
+ * On Windows, for backwards compatibility reasons,
+ * pcap_lookupdev() returns a pointer to a sequence of
+ * pairs of UTF-16LE device names and local code page
+ * description strings.
+ *
+ * This means that if a program uses pcap_lookupdev()
+ * to get a default device, and hands that to an API
+ * that opens devices, we'll get handed a UTF-16LE
+ * string, not a string in the local code page.
*
- * XXX - to UTF-8 instead? Or report an error if any
- * character isn't ASCII?
+ * To work around that, we check whether the string
+ * looks as if it might be a UTF-16LE strinh and, if
+ * so, convert it back to the local code page's
+ * extended ASCII.
+ *
+ * XXX - you *cannot* reliably detect whether a
+ * string is UTF-16LE or not; "a" could either
+ * be a one-character ASCII string or the first
+ * character of a UTF-16LE string. This particular
+ * version of this heuristic dates back to WinPcap
+ * 4.1.1; PacketOpenAdapter() does uses the same
+ * heuristic, with the exact same vulnerability.
*/
if (device[0] != '\0' && device[1] == '\0') {
size_t length;
@@ -2079,25 +2193,25 @@ initialize_ops(pcap_t *p)
* an activated pcap_t to point to a routine that returns
* a "this isn't activated" error.
*/
- p->read_op = (read_op_t)pcap_not_initialized;
- p->inject_op = (inject_op_t)pcap_not_initialized;
- p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
- p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
- p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
- p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
- p->stats_op = (stats_op_t)pcap_not_initialized;
+ p->read_op = pcap_read_not_initialized;
+ p->inject_op = pcap_inject_not_initialized;
+ p->setfilter_op = pcap_setfilter_not_initialized;
+ p->setdirection_op = pcap_setdirection_not_initialized;
+ p->set_datalink_op = pcap_set_datalink_not_initialized;
+ p->getnonblock_op = pcap_getnonblock_not_initialized;
+ p->stats_op = pcap_stats_not_initialized;
#ifdef _WIN32
- p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
- p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
- p->setmode_op = (setmode_op_t)pcap_not_initialized;
- p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
+ p->stats_ex_op = pcap_stats_ex_not_initialized;
+ p->setbuff_op = pcap_setbuff_not_initialized;
+ p->setmode_op = pcap_setmode_not_initialized;
+ p->setmintocopy_op = pcap_setmintocopy_not_initialized;
p->getevent_op = pcap_getevent_not_initialized;
- p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized;
- p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized;
+ p->oid_get_request_op = pcap_oid_get_request_not_initialized;
+ p->oid_set_request_op = pcap_oid_set_request_not_initialized;
p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
- p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized;
- p->live_dump_op = (live_dump_op_t)pcap_not_initialized;
- p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized;
+ p->setuserbuffer_op = pcap_setuserbuffer_not_initialized;
+ p->live_dump_op = pcap_live_dump_not_initialized;
+ p->live_dump_ended_op = pcap_live_dump_ended_not_initialized;
p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
#endif
@@ -2126,14 +2240,23 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* plus a structure following it of size "size". The
* structure following it is a private data structure
* for the routines that handle this pcap_t.
+ *
+ * The structure following it must be aligned on
+ * the appropriate alignment boundary for this platform.
+ * We align on an 8-byte boundary as that's probably what
+ * at least some platforms do, even with 32-bit integers,
+ * and because we can't be sure that some values won't
+ * require 8-byte alignment even on platforms with 32-bit
+ * integers.
*/
- chunk = malloc(sizeof (pcap_t) + size);
+#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U)
+ chunk = malloc(PCAP_T_ALIGNED_SIZE + size);
if (chunk == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
return (NULL);
}
- memset(chunk, 0, sizeof (pcap_t) + size);
+ memset(chunk, 0, PCAP_T_ALIGNED_SIZE + size);
/*
* Get a pointer to the pcap_t at the beginning.
@@ -2158,7 +2281,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
* Set the pointer to the private data; that's the structure
* of size "size" following the pcap_t.
*/
- p->priv = (void *)(chunk + sizeof (pcap_t));
+ p->priv = (void *)(chunk + PCAP_T_ALIGNED_SIZE);
}
return (p);
@@ -2454,6 +2577,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
int srctype;
/*
+ * 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 (device == NULL)
+ device = "any";
+
+ /*
* Retrofit - we have to make older applications compatible with
* remote capture.
* So we're calling pcap_open_remote() from here; this is a very
@@ -2524,13 +2657,13 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *er
return (p);
fail:
if (status == PCAP_ERROR)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
- p->errbuf);
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %.*s", device,
+ PCAP_ERRBUF_SIZE - 3, p->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED ||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
- pcap_statustostr(status), p->errbuf);
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%.*s)", device,
+ pcap_statustostr(status), PCAP_ERRBUF_SIZE - 6, p->errbuf);
else
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
pcap_statustostr(status));
@@ -2843,7 +2976,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(FRELAY, "Frame Relay"),
DLT_CHOICE(LOOP, "OpenBSD loopback"),
DLT_CHOICE(ENC, "OpenBSD encapsulated IP"),
- DLT_CHOICE(LINUX_SLL, "Linux cooked"),
+ DLT_CHOICE(LINUX_SLL, "Linux cooked v1"),
DLT_CHOICE(LTALK, "Localtalk"),
DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
@@ -2877,7 +3010,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(GPF_T, "GPF-T"),
DLT_CHOICE(GPF_F, "GPF-F"),
DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"),
- DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
+ DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"),
DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"),
DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"),
@@ -2901,10 +3034,11 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(SITA, "SITA pseudo-header"),
DLT_CHOICE(ERF, "Endace ERF header"),
DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"),
- DLT_CHOICE(IPMB, "IPMB"),
+ DLT_CHOICE(IPMB_KONTRON, "IPMB with Kontron pseudo-header"),
DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"),
DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"),
+ DLT_CHOICE(IPMB_LINUX, "IPMB with Linux/Pigeon Point pseudo-header"),
DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
DLT_CHOICE(MPLS, "MPLS with label as link-layer header"),
DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"),
@@ -2961,6 +3095,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DOCSIS31_XRA31, "Excentis XRA-31 DOCSIS 3.1 RF sniffer frames"),
DLT_CHOICE(ETHERNET_MPACKET, "802.3br mPackets"),
DLT_CHOICE(DISPLAYPORT_AUX, "DisplayPort AUX channel monitoring data"),
+ DLT_CHOICE(LINUX_SLL2, "Linux cooked v2"),
DLT_CHOICE_SENTINEL
};
@@ -3000,6 +3135,21 @@ pcap_datalink_val_to_description(int dlt)
return (NULL);
}
+const char *
+pcap_datalink_val_to_description_or_dlt(int dlt)
+{
+ static char unkbuf[40];
+ const char *description;
+
+ description = pcap_datalink_val_to_description(dlt);
+ if (description != NULL) {
+ return description;
+ } else {
+ (void)pcap_snprintf(unkbuf, sizeof(unkbuf), "DLT %u", dlt);
+ return unkbuf;
+ }
+}
+
struct tstamp_type_choice {
const char *name;
const char *description;
@@ -3152,7 +3302,7 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
* We copy the error message to errbuf, so callers
* can find it in either place.
*/
- strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -3196,7 +3346,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
* We copy the error message to errbuf, so callers
* can find it in either place.
*/
- strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
@@ -3232,35 +3382,6 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock)
}
#endif
-#ifdef _WIN32
-/*
- * Generate a string for a Win32-specific error (i.e. an error generated when
- * calling a Win32 API).
- * For errors occurred during standard C calls, we still use pcap_strerror()
- */
-void
-pcap_win32_err_to_str(DWORD error, char *errbuf)
-{
- size_t errlen;
- char *p;
-
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
- PCAP_ERRBUF_SIZE, NULL);
-
- /*
- * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
- * message. Get rid of it.
- */
- errlen = strlen(errbuf);
- if (errlen >= 2) {
- errbuf[errlen - 1] = '\0';
- errbuf[errlen - 2] = '\0';
- }
- p = strchr(errbuf, '\0');
- pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
-}
-#endif
-
/*
* Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
*/
@@ -3332,7 +3453,7 @@ pcap_strerror(int errnum)
errno_t err = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
if (err != 0) /* err = 0 if successful */
- strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
return (errbuf);
#else
return (strerror(errnum));
@@ -3554,7 +3675,7 @@ pcap_do_addexit(pcap_t *p)
/*
* "atexit()" failed; let our caller know.
*/
- strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
+ pcap_strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
return (0);
}
did_atexit = 1;