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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user