1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Upgrade libpcap to 1.10.4

This commit is contained in:
dmiller
2023-04-28 14:37:51 +00:00
parent 186bed85c8
commit 585832c41e
121 changed files with 13810 additions and 8968 deletions

View File

@@ -28,11 +28,6 @@
#include <pcap-types.h>
#include "pcap-int.h"
#include "extract.h"
#include "pcap/sll.h"
#include "pcap/usb.h"
#include "pcap/nflog.h"
#include "pcap/can_socketcan.h"
#include "pcap-common.h"
@@ -168,11 +163,20 @@
#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
/*
* These three types are reserved for future use.
* These two types are reserved for future use.
*/
#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
/*
* Used for NetBSD DLT_HDLC; from looking at the one driver in NetBSD
* that uses it, it's Cisco HDLC, so it's the same as DLT_C_HDLC/
* LINKTYPE_C_HDLC, but we define a separate value to avoid some
* compatibility issues with programs on NetBSD.
*
* All code should treat LINKTYPE_NETBSD_HDLC and LINKTYPE_C_HDLC the same.
*/
#define LINKTYPE_NETBSD_HDLC 112 /* NetBSD HDLC framing */
#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
@@ -405,7 +409,7 @@
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
* Every frame contains a 32bit A429 label.
* More documentation on Arinc 429 can be found at
* http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
* https://web.archive.org/web/20040616233302/https://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
*/
#define LINKTYPE_A429 184
@@ -956,13 +960,15 @@
/*
* Link-layer header type for upper-protocol layer PDU saves from wireshark.
*
* the actual contents are determined by two TAGs stored with each
* packet:
* EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the
* original packet.
* the actual contents are determined by two TAGs, one or more of
* which is stored with each packet:
*
* EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector
* that can make sense of the data stored.
* EXP_PDU_TAG_DISSECTOR_NAME the name of the Wireshark dissector
* that can make sense of the data stored.
*
* EXP_PDU_TAG_HEUR_DISSECTOR_NAME the name of the Wireshark heuristic
* dissector that can make sense of the
* data stored.
*/
#define LINKTYPE_WIRESHARK_UPPER_PDU 252
@@ -1234,10 +1240,11 @@ static struct linktype_map {
{ DLT_FR, LINKTYPE_FRELAY },
#endif
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_RAW, LINKTYPE_RAW },
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
{ DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
{ DLT_HDLC, LINKTYPE_NETBSD_HDLC },
/* BSD/OS Cisco HDLC */
{ DLT_C_HDLC, LINKTYPE_C_HDLC },
@@ -1391,286 +1398,3 @@ max_snaplen_for_dlt(int dlt)
return MAXIMUM_SNAPLEN;
}
}
/*
* DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
* LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
* with the CAN ID being in host byte order.
*
* When reading a DLT_LINUX_SLL capture file, we need to check for those
* packets and convert the CAN ID from the byte order of the host that
* wrote the file to this host's byte order.
*/
static void
swap_linux_sll_header(const struct pcap_pkthdr *hdr, u_char *buf)
{
u_int caplen = hdr->caplen;
u_int length = hdr->len;
struct sll_header *shdr = (struct sll_header *)buf;
uint16_t protocol;
pcap_can_socketcan_hdr *chdr;
if (caplen < (u_int) sizeof(struct sll_header) ||
length < (u_int) sizeof(struct sll_header)) {
/* Not enough data to have the protocol field */
return;
}
protocol = EXTRACT_BE_U_2(&shdr->sll_protocol);
if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
return;
/*
* SocketCAN packet; fix up the packet's header.
*/
chdr = (pcap_can_socketcan_hdr *)(buf + sizeof(struct sll_header));
if (caplen < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id) ||
length < (u_int) sizeof(struct sll_header) + sizeof(chdr->can_id)) {
/* Not enough data to have the CAN ID */
return;
}
chdr->can_id = SWAPLONG(chdr->can_id);
}
/*
* The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
* byte order when capturing (it's supplied directly from a
* memory-mapped buffer shared by the kernel).
*
* When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED capture file,
* we need to convert it from the byte order of the host that wrote
* the file to this host's byte order.
*/
static void
swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
int header_len_64_bytes)
{
pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
bpf_u_int32 offset = 0;
/*
* "offset" is the offset *past* the field we're swapping;
* we skip the field *before* checking to make sure
* the captured data length includes the entire field.
*/
/*
* The URB id is a totally opaque value; do we really need to
* convert it to the reading host's byte order???
*/
offset += 8; /* skip past id */
if (hdr->caplen < offset)
return;
uhdr->id = SWAPLL(uhdr->id);
offset += 4; /* skip past various 1-byte fields */
offset += 2; /* skip past bus_id */
if (hdr->caplen < offset)
return;
uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
offset += 2; /* skip past various 1-byte fields */
offset += 8; /* skip past ts_sec */
if (hdr->caplen < offset)
return;
uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
offset += 4; /* skip past ts_usec */
if (hdr->caplen < offset)
return;
uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
offset += 4; /* skip past status */
if (hdr->caplen < offset)
return;
uhdr->status = SWAPLONG(uhdr->status);
offset += 4; /* skip past urb_len */
if (hdr->caplen < offset)
return;
uhdr->urb_len = SWAPLONG(uhdr->urb_len);
offset += 4; /* skip past data_len */
if (hdr->caplen < offset)
return;
uhdr->data_len = SWAPLONG(uhdr->data_len);
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
offset += 4; /* skip past s.iso.error_count */
if (hdr->caplen < offset)
return;
uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
offset += 4; /* skip past s.iso.numdesc */
if (hdr->caplen < offset)
return;
uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
} else
offset += 8; /* skip USB setup header */
/*
* With the old header, there are no isochronous descriptors
* after the header.
*
* With the new header, the actual number of descriptors in
* the header is not s.iso.numdesc, it's ndesc - only the
* first N descriptors, for some value of N, are put into
* the header, and ndesc is set to the actual number copied.
* In addition, if s.iso.numdesc is negative, no descriptors
* are captured, and ndesc is set to 0.
*/
if (header_len_64_bytes) {
/*
* This is either the "version 1" header, with
* 16 bytes of additional fields at the end, or
* a "version 0" header from a memory-mapped
* capture, with 16 bytes of zeroed-out padding
* at the end. Byte swap them as if this were
* a "version 1" header.
*/
offset += 4; /* skip past interval */
if (hdr->caplen < offset)
return;
uhdr->interval = SWAPLONG(uhdr->interval);
offset += 4; /* skip past start_frame */
if (hdr->caplen < offset)
return;
uhdr->start_frame = SWAPLONG(uhdr->start_frame);
offset += 4; /* skip past xfer_flags */
if (hdr->caplen < offset)
return;
uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
offset += 4; /* skip past ndesc */
if (hdr->caplen < offset)
return;
uhdr->ndesc = SWAPLONG(uhdr->ndesc);
if (uhdr->transfer_type == URB_ISOCHRONOUS) {
/* swap the values in struct linux_usb_isodesc */
usb_isodesc *pisodesc;
uint32_t i;
pisodesc = (usb_isodesc *)(void *)(buf+offset);
for (i = 0; i < uhdr->ndesc; i++) {
offset += 4; /* skip past status */
if (hdr->caplen < offset)
return;
pisodesc->status = SWAPLONG(pisodesc->status);
offset += 4; /* skip past offset */
if (hdr->caplen < offset)
return;
pisodesc->offset = SWAPLONG(pisodesc->offset);
offset += 4; /* skip past len */
if (hdr->caplen < offset)
return;
pisodesc->len = SWAPLONG(pisodesc->len);
offset += 4; /* skip past padding */
pisodesc++;
}
}
}
}
/*
* The DLT_NFLOG "packets" have a mixture of big-endian and host-byte-order
* data. They begin with a fixed-length header with big-endian fields,
* followed by a set of TLVs, where the type and length are in host
* byte order but the values are either big-endian or are a raw byte
* sequence that's the same regardless of the host's byte order.
*
* When reading a DLT_NFLOG capture file, we need to convert the type
* and length values from the byte order of the host that wrote the
* file to the byte order of this host.
*/
static void
swap_nflog_header(const struct pcap_pkthdr *hdr, u_char *buf)
{
u_char *p = buf;
nflog_hdr_t *nfhdr = (nflog_hdr_t *)buf;
nflog_tlv_t *tlv;
u_int caplen = hdr->caplen;
u_int length = hdr->len;
uint16_t size;
if (caplen < (u_int) sizeof(nflog_hdr_t) ||
length < (u_int) sizeof(nflog_hdr_t)) {
/* Not enough data to have any TLVs. */
return;
}
if (nfhdr->nflog_version != 0) {
/* Unknown NFLOG version */
return;
}
length -= sizeof(nflog_hdr_t);
caplen -= sizeof(nflog_hdr_t);
p += sizeof(nflog_hdr_t);
while (caplen >= sizeof(nflog_tlv_t)) {
tlv = (nflog_tlv_t *) p;
/* Swap the type and length. */
tlv->tlv_type = SWAPSHORT(tlv->tlv_type);
tlv->tlv_length = SWAPSHORT(tlv->tlv_length);
/* Get the length of the TLV. */
size = tlv->tlv_length;
if (size % 4 != 0)
size += 4 - size % 4;
/* Is the TLV's length less than the minimum? */
if (size < sizeof(nflog_tlv_t)) {
/* Yes. Give up now. */
return;
}
/* Do we have enough data for the full TLV? */
if (caplen < size || length < size) {
/* No. */
return;
}
/* Skip over the TLV. */
length -= size;
caplen -= size;
p += size;
}
}
void
swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
{
/*
* Convert pseudo-headers from the byte order of
* the host on which the file was saved to our
* byte order, as necessary.
*/
switch (linktype) {
case DLT_LINUX_SLL:
swap_linux_sll_header(hdr, data);
break;
case DLT_USB_LINUX:
swap_linux_usb_header(hdr, data, 0);
break;
case DLT_USB_LINUX_MMAPPED:
swap_linux_usb_header(hdr, data, 1);
break;
case DLT_NFLOG:
swap_nflog_header(hdr, data);
break;
}
}