1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-03 05:09:14 +00:00

Updated the included libpcap to 1.5.3

This commit is contained in:
jay
2014-06-06 10:43:17 +00:00
parent 5f27fb12a6
commit d8071c0352
98 changed files with 11651 additions and 7008 deletions

View File

@@ -122,26 +122,58 @@ static const char rcsid[] _U_ =
static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
/*
* Private data for reading pcap savefiles.
*/
typedef enum {
NOT_SWAPPED,
SWAPPED,
MAYBE_SWAPPED
} swapped_type_t;
typedef enum {
PASS_THROUGH,
SCALE_UP,
SCALE_DOWN
} tstamp_scale_type_t;
struct pcap_sf {
size_t hdrsize;
swapped_type_t lengths_swapped;
tstamp_scale_type_t scale_type;
};
/*
* Check whether this is a pcap savefile and, if it is, extract the
* relevant information from the header.
*/
int
pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
pcap_t *
pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
int *err)
{
struct pcap_file_header hdr;
size_t amt_read;
pcap_t *p;
int swapped = 0;
struct pcap_sf *ps;
/*
* Assume no read errors.
*/
*err = 0;
/*
* Check whether the first 4 bytes of the file are the magic
* number for a pcap savefile, or for a byte-swapped pcap
* savefile.
*/
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
magic != NSEC_TCPDUMP_MAGIC) {
magic = SWAPLONG(magic);
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC)
return (0); /* nope */
p->sf.swapped = 1;
if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
magic != NSEC_TCPDUMP_MAGIC)
return (NULL); /* nope */
swapped = 1;
}
/*
@@ -162,13 +194,14 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
(unsigned long)sizeof(hdr),
(unsigned long)amt_read);
}
return (-1);
*err = 1;
return (NULL);
}
/*
* If it's a byte-swapped capture file, byte-swap the header.
*/
if (p->sf.swapped) {
if (swapped) {
hdr.version_major = SWAPSHORT(hdr.version_major);
hdr.version_minor = SWAPSHORT(hdr.version_minor);
hdr.thiszone = SWAPLONG(hdr.thiszone);
@@ -180,16 +213,81 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
if (hdr.version_major < PCAP_VERSION_MAJOR) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"archaic pcap savefile format");
return (-1);
*err = 1;
return (NULL);
}
p->sf.version_major = hdr.version_major;
p->sf.version_minor = hdr.version_minor;
/*
* OK, this is a good pcap file.
* Allocate a pcap_t for it.
*/
p = pcap_open_offline_common(errbuf, sizeof (struct pcap_sf));
if (p == NULL) {
/* Allocation failed. */
*err = 1;
return (NULL);
}
p->swapped = swapped;
p->version_major = hdr.version_major;
p->version_minor = hdr.version_minor;
p->tzoff = hdr.thiszone;
p->snapshot = hdr.snaplen;
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
p->sf.next_packet_op = pcap_next_packet;
p->next_packet_op = pcap_next_packet;
ps = p->priv;
p->opt.tstamp_precision = precision;
/*
* Will we need to scale the timestamps to match what the
* user wants?
*/
switch (precision) {
case PCAP_TSTAMP_PRECISION_MICRO:
if (magic == NSEC_TCPDUMP_MAGIC) {
/*
* The file has nanoseconds, the user
* wants microseconds; scale the
* precision down.
*/
ps->scale_type = SCALE_DOWN;
} else {
/*
* The file has microseconds, the
* user wants microseconds; nothing to do.
*/
ps->scale_type = PASS_THROUGH;
}
break;
case PCAP_TSTAMP_PRECISION_NANO:
if (magic == NSEC_TCPDUMP_MAGIC) {
/*
* The file has nanoseconds, the
* user wants nanoseconds; nothing to do.
*/
ps->scale_type = PASS_THROUGH;
} else {
/*
* The file has microoseconds, the user
* wants nanoseconds; scale the
* precision up.
*/
ps->scale_type = SCALE_UP;
}
break;
default:
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"unknown time stamp resolution %u", precision);
free(p);
*err = 1;
return (NULL);
}
/*
* We interchanged the caplen and len fields at version 2.3,
@@ -205,19 +303,19 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
case 2:
if (hdr.version_minor < 3)
p->sf.lengths_swapped = SWAPPED;
ps->lengths_swapped = SWAPPED;
else if (hdr.version_minor == 3)
p->sf.lengths_swapped = MAYBE_SWAPPED;
ps->lengths_swapped = MAYBE_SWAPPED;
else
p->sf.lengths_swapped = NOT_SWAPPED;
ps->lengths_swapped = NOT_SWAPPED;
break;
case 543:
p->sf.lengths_swapped = SWAPPED;
ps->lengths_swapped = SWAPPED;
break;
default:
p->sf.lengths_swapped = NOT_SWAPPED;
ps->lengths_swapped = NOT_SWAPPED;
break;
}
@@ -239,7 +337,7 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
* data ourselves and read from that buffer in order to
* make that work.
*/
p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
if (p->linktype == DLT_EN10MB) {
/*
@@ -265,7 +363,7 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
p->snapshot += 14;
}
} else
p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
/*
* Allocate a buffer for the packet data.
@@ -280,10 +378,14 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
return (-1);
free(p);
*err = 1;
return (NULL);
}
return (1);
p->cleanup_op = sf_cleanup;
return (p);
}
/*
@@ -294,8 +396,9 @@ pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
static int
pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
{
struct pcap_sf *ps = p->priv;
struct pcap_sf_patched_pkthdr sf_hdr;
FILE *fp = p->sf.rfile;
FILE *fp = p->rfile;
size_t amt_read;
bpf_u_int32 t;
@@ -306,8 +409,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* unpatched libpcap we only read as many bytes as the regular
* header has.
*/
amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
if (amt_read != p->sf.hdrsize) {
amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
if (amt_read != ps->hdrsize) {
if (ferror(fp)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
@@ -317,7 +420,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
if (amt_read != 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %lu header bytes, only got %lu",
(unsigned long)p->sf.hdrsize,
(unsigned long)ps->hdrsize,
(unsigned long)amt_read);
return (-1);
}
@@ -326,7 +429,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
}
}
if (p->sf.swapped) {
if (p->swapped) {
/* these were written in opposite byte order */
hdr->caplen = SWAPLONG(sf_hdr.caplen);
hdr->len = SWAPLONG(sf_hdr.len);
@@ -338,8 +441,34 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
}
switch (ps->scale_type) {
case PASS_THROUGH:
/*
* Just pass the time stamp through.
*/
break;
case SCALE_UP:
/*
* File has microseconds, user wants nanoseconds; convert
* it.
*/
hdr->ts.tv_usec = hdr->ts.tv_usec * 1000;
break;
case SCALE_DOWN:
/*
* File has nanoseconds, user wants microseconds; convert
* it.
*/
hdr->ts.tv_usec = hdr->ts.tv_usec / 1000;
break;
}
/* Swap the caplen and len fields, if necessary. */
switch (p->sf.lengths_swapped) {
switch (ps->lengths_swapped) {
case NOT_SWAPPED:
break;
@@ -430,7 +559,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
}
*data = p->buffer;
if (p->sf.swapped) {
if (p->swapped) {
/*
* Convert pseudo-headers from the byte order of
* the host on which the file was saved to our
@@ -452,11 +581,11 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
}
static int
sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
sf_write_header(pcap_t *p, FILE *fp, int linktype, int thiszone, int snaplen)
{
struct pcap_file_header hdr;
hdr.magic = TCPDUMP_MAGIC;
hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
@@ -507,7 +636,7 @@ pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
else
setbuf(f, NULL);
#endif
if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
fname, pcap_strerror(errno));
if (f != stdout)