resolve conflicts.
This commit is contained in:
parent
7e05f63e56
commit
511f4361e2
222
external/bsd/libpcap/dist/gencode.c
vendored
222
external/bsd/libpcap/dist/gencode.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gencode.c,v 1.5 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: gencode.c,v 1.6 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*#define CHASE_CHAIN*/
|
||||
/*
|
||||
@ -87,7 +87,7 @@ static const char rcsid[] _U_ =
|
||||
#include "pcap/sll.h"
|
||||
#include "pcap/ipnet.h"
|
||||
#include "arcnet.h"
|
||||
#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
|
||||
#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/filter.h>
|
||||
@ -110,6 +110,18 @@ static const char rcsid[] _U_ =
|
||||
|
||||
#define ETHERMTU 1500
|
||||
|
||||
#ifndef IPPROTO_HOPOPTS
|
||||
#define IPPROTO_HOPOPTS 0
|
||||
#endif
|
||||
#ifndef IPPROTO_ROUTING
|
||||
#define IPPROTO_ROUTING 43
|
||||
#endif
|
||||
#ifndef IPPROTO_FRAGMENT
|
||||
#define IPPROTO_FRAGMENT 44
|
||||
#endif
|
||||
#ifndef IPPROTO_DSTOPTS
|
||||
#define IPPROTO_DSTOPTS 60
|
||||
#endif
|
||||
#ifndef IPPROTO_SCTP
|
||||
#define IPPROTO_SCTP 132
|
||||
#endif
|
||||
@ -132,9 +144,7 @@ static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
|
||||
#endif
|
||||
|
||||
/* XXX */
|
||||
#ifdef PCAP_FDDIPAD
|
||||
static int pcap_fddipad;
|
||||
#endif
|
||||
|
||||
/* VARARGS */
|
||||
void
|
||||
@ -264,20 +274,16 @@ static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
|
||||
static struct block *gen_ipfrag(void);
|
||||
static struct block *gen_portatom(int, bpf_int32);
|
||||
static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
|
||||
#ifdef INET6
|
||||
static struct block *gen_portatom6(int, bpf_int32);
|
||||
static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);
|
||||
#endif
|
||||
struct block *gen_portop(int, int, int);
|
||||
static struct block *gen_port(int, int, int);
|
||||
struct block *gen_portrangeop(int, int, int, int);
|
||||
static struct block *gen_portrange(int, int, int, int);
|
||||
#ifdef INET6
|
||||
struct block *gen_portop6(int, int, int);
|
||||
static struct block *gen_port6(int, int, int);
|
||||
struct block *gen_portrangeop6(int, int, int, int);
|
||||
static struct block *gen_portrange6(int, int, int, int);
|
||||
#endif
|
||||
static int lookup_proto(const char *, int);
|
||||
static struct block *gen_protochain(int, int, int);
|
||||
static struct block *gen_proto(int, int, int);
|
||||
@ -428,6 +434,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
||||
const char * volatile xbuf = buf;
|
||||
u_int len;
|
||||
|
||||
/*
|
||||
* If this pcap_t hasn't been activated, it doesn't have a
|
||||
* link-layer type, so we can't use it.
|
||||
*/
|
||||
if (!p->activated) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"not-yet-activated pcap_t passed to pcap_compile");
|
||||
return (-1);
|
||||
}
|
||||
no_optimize = 0;
|
||||
n_errors = 0;
|
||||
root = NULL;
|
||||
@ -862,6 +877,7 @@ static u_int off_proto;
|
||||
* These are offsets for the MTP2 fields.
|
||||
*/
|
||||
static u_int off_li;
|
||||
static u_int off_li_hsl;
|
||||
|
||||
/*
|
||||
* These are offsets for the MTP3 fields.
|
||||
@ -911,9 +927,7 @@ init_linktype(p)
|
||||
pcap_t *p;
|
||||
{
|
||||
linktype = pcap_datalink(p);
|
||||
#ifdef PCAP_FDDIPAD
|
||||
pcap_fddipad = p->fddipad;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assume it's not raw ATM with a pseudo-header, for now.
|
||||
@ -935,6 +949,7 @@ init_linktype(p)
|
||||
* And assume we're not doing SS7.
|
||||
*/
|
||||
off_li = -1;
|
||||
off_li_hsl = -1;
|
||||
off_sio = -1;
|
||||
off_opc = -1;
|
||||
off_dpc = -1;
|
||||
@ -1050,13 +1065,9 @@ init_linktype(p)
|
||||
* XXX - should we generate code to check for SNAP?
|
||||
*/
|
||||
off_linktype = 13;
|
||||
#ifdef PCAP_FDDIPAD
|
||||
off_linktype += pcap_fddipad;
|
||||
#endif
|
||||
off_macpl = 13; /* FDDI MAC header length */
|
||||
#ifdef PCAP_FDDIPAD
|
||||
off_macpl += pcap_fddipad;
|
||||
#endif
|
||||
off_nl = 8; /* 802.2+SNAP */
|
||||
off_nl_nosnap = 3; /* 802.2 */
|
||||
return;
|
||||
@ -1327,6 +1338,13 @@ init_linktype(p)
|
||||
off_nl_nosnap = -1; /* no 802.2 LLC */
|
||||
return;
|
||||
|
||||
case DLT_BACNET_MS_TP:
|
||||
off_linktype = -1;
|
||||
off_macpl = -1;
|
||||
off_nl = -1;
|
||||
off_nl_nosnap = -1;
|
||||
return;
|
||||
|
||||
case DLT_JUNIPER_SERVICES:
|
||||
off_linktype = 12;
|
||||
off_macpl = -1; /* L3 proto location dep. on cookie type */
|
||||
@ -1367,6 +1385,7 @@ init_linktype(p)
|
||||
|
||||
case DLT_MTP2:
|
||||
off_li = 2;
|
||||
off_li_hsl = 4;
|
||||
off_sio = 3;
|
||||
off_opc = 4;
|
||||
off_dpc = 4;
|
||||
@ -1379,6 +1398,7 @@ init_linktype(p)
|
||||
|
||||
case DLT_MTP2_WITH_PHDR:
|
||||
off_li = 6;
|
||||
off_li_hsl = 8;
|
||||
off_sio = 7;
|
||||
off_opc = 8;
|
||||
off_dpc = 8;
|
||||
@ -1391,6 +1411,7 @@ init_linktype(p)
|
||||
|
||||
case DLT_ERF:
|
||||
off_li = 22;
|
||||
off_li_hsl = 24;
|
||||
off_sio = 23;
|
||||
off_opc = 24;
|
||||
off_dpc = 24;
|
||||
@ -2835,11 +2856,9 @@ ethertype_to_ppptype(proto)
|
||||
proto = PPP_IP;
|
||||
break;
|
||||
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
proto = PPP_IPV6;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ETHERTYPE_DN:
|
||||
proto = PPP_DECNET;
|
||||
@ -3047,11 +3066,10 @@ gen_linktype(proto)
|
||||
case ETHERTYPE_IP:
|
||||
/* Check for a version number of 4. */
|
||||
return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);
|
||||
#ifdef INET6
|
||||
|
||||
case ETHERTYPE_IPV6:
|
||||
/* Check for a version number of 6. */
|
||||
return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return gen_false(); /* always false */
|
||||
@ -3075,10 +3093,8 @@ gen_linktype(proto)
|
||||
/*
|
||||
* Raw IPv6, so no type field.
|
||||
*/
|
||||
#ifdef INET6
|
||||
if (proto == ETHERTYPE_IPV6)
|
||||
return gen_true(); /* always true */
|
||||
#endif
|
||||
|
||||
/* Checking for something other than IPv6; always false */
|
||||
return gen_false();
|
||||
@ -3184,8 +3200,7 @@ gen_linktype(proto)
|
||||
* Then we run it through "htonl()", and
|
||||
* generate code to compare against the result.
|
||||
*/
|
||||
if (bpf_pcap->sf.rfile != NULL &&
|
||||
bpf_pcap->sf.swapped)
|
||||
if (bpf_pcap->rfile != NULL && bpf_pcap->swapped)
|
||||
proto = SWAPLONG(proto);
|
||||
proto = htonl(proto);
|
||||
}
|
||||
@ -3200,11 +3215,9 @@ gen_linktype(proto)
|
||||
if (proto == ETHERTYPE_IP)
|
||||
return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
|
||||
BPF_B, (bpf_int32)AF_INET));
|
||||
#ifdef INET6
|
||||
else if (proto == ETHERTYPE_IPV6)
|
||||
return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
|
||||
BPF_B, (bpf_int32)AF_INET6));
|
||||
#endif /* INET6 */
|
||||
else
|
||||
return gen_false();
|
||||
/*NOTREACHED*/
|
||||
@ -3222,11 +3235,9 @@ gen_linktype(proto)
|
||||
default:
|
||||
return gen_false();
|
||||
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
return (gen_cmp(OR_LINK, off_linktype, BPF_B,
|
||||
(bpf_int32)ARCTYPE_INET6));
|
||||
#endif /* INET6 */
|
||||
|
||||
case ETHERTYPE_IP:
|
||||
b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
|
||||
@ -3278,13 +3289,11 @@ gen_linktype(proto)
|
||||
*/
|
||||
return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);
|
||||
|
||||
#ifdef INET6
|
||||
case ETHERTYPE_IPV6:
|
||||
/*
|
||||
* Check for the special NLPID for IPv6.
|
||||
*/
|
||||
return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);
|
||||
#endif
|
||||
|
||||
case LLCSAP_ISONS:
|
||||
/*
|
||||
@ -3346,6 +3355,9 @@ gen_linktype(proto)
|
||||
*/
|
||||
return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
|
||||
|
||||
case DLT_BACNET_MS_TP:
|
||||
return gen_mcmp(OR_LINK, 0, BPF_W, 0x55FF0000, 0xffff0000);
|
||||
|
||||
case DLT_IPNET:
|
||||
return gen_ipnet_linktype(proto);
|
||||
|
||||
@ -3631,7 +3643,7 @@ gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
}
|
||||
#endif /*INET6*/
|
||||
#endif
|
||||
|
||||
static struct block *
|
||||
gen_ehostop(eaddr, dir)
|
||||
@ -3700,18 +3712,10 @@ gen_fhostop(eaddr, dir)
|
||||
|
||||
switch (dir) {
|
||||
case Q_SRC:
|
||||
#ifdef PCAP_FDDIPAD
|
||||
return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr);
|
||||
#else
|
||||
return gen_bcmp(OR_LINK, 6 + 1, 6, eaddr);
|
||||
#endif
|
||||
|
||||
case Q_DST:
|
||||
#ifdef PCAP_FDDIPAD
|
||||
return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr);
|
||||
#else
|
||||
return gen_bcmp(OR_LINK, 0 + 1, 6, eaddr);
|
||||
#endif
|
||||
|
||||
case Q_AND:
|
||||
b0 = gen_fhostop(eaddr, Q_SRC);
|
||||
@ -4509,13 +4513,11 @@ gen_host(addr, mask, proto, dir, type)
|
||||
case Q_MOPRC:
|
||||
bpf_error("MOPRC host filtering not implemented");
|
||||
|
||||
#ifdef INET6
|
||||
case Q_IPV6:
|
||||
bpf_error("'ip6' modifier applied to ip host");
|
||||
|
||||
case Q_ICMPV6:
|
||||
bpf_error("'icmp6' modifier applied to %s", typestr);
|
||||
#endif /* INET6 */
|
||||
|
||||
case Q_AH:
|
||||
bpf_error("'ah' modifier applied to %s", typestr);
|
||||
@ -4574,6 +4576,9 @@ gen_host6(addr, mask, proto, dir, type)
|
||||
case Q_DEFAULT:
|
||||
return gen_host6(addr, mask, Q_IPV6, dir, type);
|
||||
|
||||
case Q_LINK:
|
||||
bpf_error("link-layer modifier applied to ip6 %s", typestr);
|
||||
|
||||
case Q_IP:
|
||||
bpf_error("'ip' modifier applied to ip6 %s", typestr);
|
||||
|
||||
@ -4672,7 +4677,7 @@ gen_host6(addr, mask, proto, dir, type)
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif /*INET6*/
|
||||
#endif
|
||||
|
||||
#ifndef INET6
|
||||
static struct block *
|
||||
@ -4764,26 +4769,20 @@ gen_proto_abbrev(proto)
|
||||
|
||||
case Q_SCTP:
|
||||
b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT);
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Q_TCP:
|
||||
b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Q_UDP:
|
||||
b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Q_ICMP:
|
||||
@ -4811,10 +4810,8 @@ gen_proto_abbrev(proto)
|
||||
|
||||
case Q_PIM:
|
||||
b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifndef IPPROTO_VRRP
|
||||
@ -4876,7 +4873,6 @@ gen_proto_abbrev(proto)
|
||||
b1 = gen_linktype(ETHERTYPE_MOPRC);
|
||||
break;
|
||||
|
||||
#ifdef INET6
|
||||
case Q_IPV6:
|
||||
b1 = gen_linktype(ETHERTYPE_IPV6);
|
||||
break;
|
||||
@ -4887,17 +4883,14 @@ gen_proto_abbrev(proto)
|
||||
case Q_ICMPV6:
|
||||
b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
|
||||
#ifndef IPPROTO_AH
|
||||
#define IPPROTO_AH 51
|
||||
#endif
|
||||
case Q_AH:
|
||||
b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifndef IPPROTO_ESP
|
||||
@ -4905,10 +4898,8 @@ gen_proto_abbrev(proto)
|
||||
#endif
|
||||
case Q_ESP:
|
||||
b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
|
||||
gen_or(b0, b1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Q_ISO:
|
||||
@ -5041,7 +5032,6 @@ gen_portatom(off, v)
|
||||
return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
static struct block *
|
||||
gen_portatom6(off, v)
|
||||
int off;
|
||||
@ -5049,7 +5039,6 @@ gen_portatom6(off, v)
|
||||
{
|
||||
return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
|
||||
}
|
||||
#endif/*INET6*/
|
||||
|
||||
struct block *
|
||||
gen_portop(port, proto, dir)
|
||||
@ -5141,7 +5130,6 @@ gen_port(port, ip_proto, dir)
|
||||
return b1;
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
struct block *
|
||||
gen_portop6(port, proto, dir)
|
||||
int port, proto, dir;
|
||||
@ -5214,7 +5202,6 @@ gen_port6(port, ip_proto, dir)
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
/* gen_portrange code */
|
||||
static struct block *
|
||||
@ -5319,7 +5306,6 @@ gen_portrange(port1, port2, ip_proto, dir)
|
||||
return b1;
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
static struct block *
|
||||
gen_portrangeatom6(off, v1, v2)
|
||||
int off;
|
||||
@ -5420,7 +5406,6 @@ gen_portrange6(port1, port2, ip_proto, dir)
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
static int
|
||||
lookup_proto(name, proto)
|
||||
@ -5555,7 +5540,7 @@ gen_protochain(v, proto, dir)
|
||||
s[i]->s.k = off_macpl + off_nl;
|
||||
i++;
|
||||
break;
|
||||
#ifdef INET6
|
||||
|
||||
case Q_IPV6:
|
||||
b0 = gen_linktype(ETHERTYPE_IPV6);
|
||||
|
||||
@ -5568,7 +5553,7 @@ gen_protochain(v, proto, dir)
|
||||
s[i]->s.k = 40;
|
||||
i++;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
bpf_error("unsupported proto to gen_protochain");
|
||||
/*NOTREACHED*/
|
||||
@ -5595,7 +5580,6 @@ gen_protochain(v, proto, dir)
|
||||
fix2 = i;
|
||||
i++;
|
||||
|
||||
#ifdef INET6
|
||||
if (proto == Q_IPV6) {
|
||||
int v6start, v6end, v6advance, j;
|
||||
|
||||
@ -5677,9 +5661,7 @@ gen_protochain(v, proto, dir)
|
||||
/* fixup */
|
||||
for (j = v6start; j <= v6end; j++)
|
||||
s[j]->s.jt = s[v6advance];
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
/* nop */
|
||||
s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
|
||||
s[i]->s.k = 0;
|
||||
@ -5823,10 +5805,8 @@ gen_proto(v, proto, dir)
|
||||
int dir;
|
||||
{
|
||||
struct block *b0, *b1;
|
||||
#ifdef INET6
|
||||
#ifndef CHASE_CHAIN
|
||||
struct block *b2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (dir != Q_DEFAULT)
|
||||
@ -5834,14 +5814,11 @@ gen_proto(v, proto, dir)
|
||||
|
||||
switch (proto) {
|
||||
case Q_DEFAULT:
|
||||
#ifdef INET6
|
||||
b0 = gen_proto(v, Q_IP, dir);
|
||||
b1 = gen_proto(v, Q_IPV6, dir);
|
||||
gen_or(b0, b1);
|
||||
return b1;
|
||||
#else
|
||||
/*FALLTHROUGH*/
|
||||
#endif
|
||||
|
||||
case Q_IP:
|
||||
/*
|
||||
* For FDDI, RFC 1188 says that SNAP encapsulation is used,
|
||||
@ -5992,7 +5969,6 @@ gen_proto(v, proto, dir)
|
||||
bpf_error("'carp proto' is bogus");
|
||||
/* NOTREACHED */
|
||||
|
||||
#ifdef INET6
|
||||
case Q_IPV6:
|
||||
b0 = gen_linktype(ETHERTYPE_IPV6);
|
||||
#ifndef CHASE_CHAIN
|
||||
@ -6013,7 +5989,6 @@ gen_proto(v, proto, dir)
|
||||
|
||||
case Q_ICMPV6:
|
||||
bpf_error("'icmp6 proto' is bogus");
|
||||
#endif /* INET6 */
|
||||
|
||||
case Q_AH:
|
||||
bpf_error("'ah proto' is bogus");
|
||||
@ -6270,13 +6245,9 @@ gen_scode(name, q)
|
||||
bpf_error("illegal port number %d < 0", port);
|
||||
if (port > 65535)
|
||||
bpf_error("illegal port number %d > 65535", port);
|
||||
#ifndef INET6
|
||||
return gen_port(port, real_proto, dir);
|
||||
#else
|
||||
b = gen_port(port, real_proto, dir);
|
||||
gen_or(gen_port6(port, real_proto, dir), b);
|
||||
return b;
|
||||
#endif /* INET6 */
|
||||
|
||||
case Q_PORTRANGE:
|
||||
if (proto != Q_DEFAULT &&
|
||||
@ -6320,13 +6291,9 @@ gen_scode(name, q)
|
||||
if (port2 > 65535)
|
||||
bpf_error("illegal port number %d > 65535", port2);
|
||||
|
||||
#ifndef INET6
|
||||
return gen_portrange(port1, port2, real_proto, dir);
|
||||
#else
|
||||
b = gen_portrange(port1, port2, real_proto, dir);
|
||||
gen_or(gen_portrange6(port1, port2, real_proto, dir), b);
|
||||
return b;
|
||||
#endif /* INET6 */
|
||||
|
||||
case Q_GATEWAY:
|
||||
#ifndef INET6
|
||||
@ -6474,16 +6441,12 @@ gen_ncode(s, v, q)
|
||||
if (v > 65535)
|
||||
bpf_error("illegal port number %u > 65535", v);
|
||||
|
||||
#ifndef INET6
|
||||
return gen_port((int)v, proto, dir);
|
||||
#else
|
||||
{
|
||||
struct block *b;
|
||||
b = gen_port((int)v, proto, dir);
|
||||
gen_or(gen_port6((int)v, proto, dir), b);
|
||||
return b;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
case Q_PORTRANGE:
|
||||
if (proto == Q_UDP)
|
||||
@ -6500,16 +6463,12 @@ gen_ncode(s, v, q)
|
||||
if (v > 65535)
|
||||
bpf_error("illegal port number %u > 65535", v);
|
||||
|
||||
#ifndef INET6
|
||||
return gen_portrange((int)v, (int)v, proto, dir);
|
||||
#else
|
||||
{
|
||||
struct block *b;
|
||||
b = gen_portrange((int)v, (int)v, proto, dir);
|
||||
gen_or(gen_portrange6((int)v, (int)v, proto, dir), b);
|
||||
return b;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
case Q_GATEWAY:
|
||||
bpf_error("'gateway' requires a name");
|
||||
@ -6799,9 +6758,7 @@ gen_load(proto, inst, size)
|
||||
case Q_LAT:
|
||||
case Q_MOPRC:
|
||||
case Q_MOPDL:
|
||||
#ifdef INET6
|
||||
case Q_IPV6:
|
||||
#endif
|
||||
/*
|
||||
* The offset is relative to the beginning of
|
||||
* the network-layer header.
|
||||
@ -6910,16 +6867,12 @@ gen_load(proto, inst, size)
|
||||
gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
|
||||
if (inst->b)
|
||||
gen_and(inst->b, b);
|
||||
#ifdef INET6
|
||||
gen_and(gen_proto_abbrev(Q_IP), b);
|
||||
#endif
|
||||
inst->b = b;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case Q_ICMPV6:
|
||||
bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
|
||||
/*NOTREACHED*/
|
||||
#endif
|
||||
}
|
||||
inst->regno = regno;
|
||||
s = new_stmt(BPF_ST);
|
||||
@ -7471,13 +7424,11 @@ gen_multicast(proto)
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
|
||||
#ifdef INET6
|
||||
case Q_IPV6:
|
||||
b0 = gen_linktype(ETHERTYPE_IPV6);
|
||||
b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255);
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
|
||||
/* NOTREACHED */
|
||||
@ -7586,14 +7537,14 @@ gen_inbound(dir)
|
||||
* check it, otherwise give up as this link-layer type
|
||||
* has nothing in the packet data.
|
||||
*/
|
||||
#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
|
||||
#if defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
|
||||
/*
|
||||
* We infer that this is Linux with PF_PACKET support.
|
||||
* This is Linux with PF_PACKET support.
|
||||
* If this is a *live* capture, we can look at
|
||||
* special meta-data in the filter expression;
|
||||
* if it's a savefile, we can't.
|
||||
*/
|
||||
if (bpf_pcap->sf.rfile != NULL) {
|
||||
if (bpf_pcap->rfile != NULL) {
|
||||
/* We have a FILE *, so this is a savefile */
|
||||
bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
|
||||
linktype);
|
||||
@ -7607,12 +7558,12 @@ gen_inbound(dir)
|
||||
/* to filter on inbound traffic, invert the match */
|
||||
gen_not(b0);
|
||||
}
|
||||
#else /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
|
||||
#else /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
|
||||
bpf_error("inbound/outbound not supported on linktype %d",
|
||||
linktype);
|
||||
b0 = NULL;
|
||||
/* NOTREACHED */
|
||||
#endif /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
|
||||
#endif /* defined(linux) && defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
|
||||
}
|
||||
return (b0);
|
||||
}
|
||||
@ -8072,9 +8023,10 @@ gen_pppoed()
|
||||
}
|
||||
|
||||
struct block *
|
||||
gen_pppoes()
|
||||
gen_pppoes(sess_num)
|
||||
int sess_num;
|
||||
{
|
||||
struct block *b0;
|
||||
struct block *b0, *b1;
|
||||
|
||||
/*
|
||||
* Test against the PPPoE session link-layer type.
|
||||
@ -8114,6 +8066,14 @@ gen_pppoes()
|
||||
orig_nl = off_nl;
|
||||
is_pppoes = 1;
|
||||
|
||||
/* If a specific session is requested, check PPPoE session id */
|
||||
if (sess_num >= 0) {
|
||||
b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W,
|
||||
(bpf_int32)sess_num, 0x0000ffff);
|
||||
gen_and(b0, b1);
|
||||
b0 = b1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The "network-layer" protocol is PPPoE, which has a 6-byte
|
||||
* PPPoE header, followed by a PPP packet.
|
||||
@ -8303,6 +8263,7 @@ gen_atmtype_abbrev(type)
|
||||
* FISU, length is null
|
||||
* LSSU, length is 1 or 2
|
||||
* MSU, length is 3 or more
|
||||
* For MTP2_HSL, sequences are on 2 bytes, and length on 9 bits
|
||||
*/
|
||||
struct block *
|
||||
gen_mtp2type_abbrev(type)
|
||||
@ -8339,6 +8300,33 @@ gen_mtp2type_abbrev(type)
|
||||
b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
|
||||
break;
|
||||
|
||||
case MH_FISU:
|
||||
if ( (linktype != DLT_MTP2) &&
|
||||
(linktype != DLT_ERF) &&
|
||||
(linktype != DLT_MTP2_WITH_PHDR) )
|
||||
bpf_error("'hfisu' supported only on MTP2_HSL");
|
||||
/* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
|
||||
b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JEQ, 0, 0);
|
||||
break;
|
||||
|
||||
case MH_LSSU:
|
||||
if ( (linktype != DLT_MTP2) &&
|
||||
(linktype != DLT_ERF) &&
|
||||
(linktype != DLT_MTP2_WITH_PHDR) )
|
||||
bpf_error("'hlssu' supported only on MTP2_HSL");
|
||||
b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 1, 0x0100);
|
||||
b1 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0);
|
||||
gen_and(b1, b0);
|
||||
break;
|
||||
|
||||
case MH_MSU:
|
||||
if ( (linktype != DLT_MTP2) &&
|
||||
(linktype != DLT_ERF) &&
|
||||
(linktype != DLT_MTP2_WITH_PHDR) )
|
||||
bpf_error("'hmsu' supported only on MTP2_HSL");
|
||||
b0 = gen_ncmp(OR_PACKET, off_li_hsl, BPF_H, 0xff80, BPF_JGT, 0, 0x0100);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
@ -8354,9 +8342,17 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
|
||||
{
|
||||
struct block *b0;
|
||||
bpf_u_int32 val1 , val2 , val3;
|
||||
u_int newoff_sio=off_sio;
|
||||
u_int newoff_opc=off_opc;
|
||||
u_int newoff_dpc=off_dpc;
|
||||
u_int newoff_sls=off_sls;
|
||||
|
||||
switch (mtp3field) {
|
||||
|
||||
case MH_SIO:
|
||||
newoff_sio += 3; /* offset for MTP2_HSL */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case M_SIO:
|
||||
if (off_sio == (u_int)-1)
|
||||
bpf_error("'sio' supported only on SS7");
|
||||
@ -8364,10 +8360,12 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
|
||||
if(jvalue > 255)
|
||||
bpf_error("sio value %u too big; max value = 255",
|
||||
jvalue);
|
||||
b0 = gen_ncmp(OR_PACKET, off_sio, BPF_B, 0xffffffff,
|
||||
b0 = gen_ncmp(OR_PACKET, newoff_sio, BPF_B, 0xffffffff,
|
||||
(u_int)jtype, reverse, (u_int)jvalue);
|
||||
break;
|
||||
|
||||
case MH_OPC:
|
||||
newoff_opc+=3;
|
||||
case M_OPC:
|
||||
if (off_opc == (u_int)-1)
|
||||
bpf_error("'opc' supported only on SS7");
|
||||
@ -8384,10 +8382,14 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
|
||||
val3 = jvalue & 0x00000003;
|
||||
val3 = val3 <<22;
|
||||
jvalue = val1 + val2 + val3;
|
||||
b0 = gen_ncmp(OR_PACKET, off_opc, BPF_W, 0x00c0ff0f,
|
||||
b0 = gen_ncmp(OR_PACKET, newoff_opc, BPF_W, 0x00c0ff0f,
|
||||
(u_int)jtype, reverse, (u_int)jvalue);
|
||||
break;
|
||||
|
||||
case MH_DPC:
|
||||
newoff_dpc += 3;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case M_DPC:
|
||||
if (off_dpc == (u_int)-1)
|
||||
bpf_error("'dpc' supported only on SS7");
|
||||
@ -8402,10 +8404,12 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
|
||||
val2 = jvalue & 0x00003f00;
|
||||
val2 = val2 << 8;
|
||||
jvalue = val1 + val2;
|
||||
b0 = gen_ncmp(OR_PACKET, off_dpc, BPF_W, 0xff3f0000,
|
||||
b0 = gen_ncmp(OR_PACKET, newoff_dpc, BPF_W, 0xff3f0000,
|
||||
(u_int)jtype, reverse, (u_int)jvalue);
|
||||
break;
|
||||
|
||||
case MH_SLS:
|
||||
newoff_sls+=3;
|
||||
case M_SLS:
|
||||
if (off_sls == (u_int)-1)
|
||||
bpf_error("'sls' supported only on SS7");
|
||||
@ -8416,7 +8420,7 @@ gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
|
||||
/* the following instruction is made to convert jvalue
|
||||
* to the forme used to write sls in an ss7 message*/
|
||||
jvalue = jvalue << 4;
|
||||
b0 = gen_ncmp(OR_PACKET, off_sls, BPF_B, 0xf0,
|
||||
b0 = gen_ncmp(OR_PACKET, newoff_sls, BPF_B, 0xf0,
|
||||
(u_int)jtype,reverse, (u_int)jvalue);
|
||||
break;
|
||||
|
||||
|
25
external/bsd/libpcap/dist/grammar.y
vendored
25
external/bsd/libpcap/dist/grammar.y
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: grammar.y,v 1.3 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: grammar.y,v 1.4 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
%{
|
||||
/*
|
||||
@ -169,7 +169,7 @@ yyerror(const char *msg)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#ifndef YYBISON
|
||||
#ifdef NEED_YYPARSE_WRAPPER
|
||||
int yyparse(void);
|
||||
|
||||
int
|
||||
@ -296,8 +296,9 @@ pfaction_to_num(const char *action)
|
||||
%token OAM OAMF4 CONNECTMSG METACONNECT
|
||||
%token VPI VCI
|
||||
%token RADIO
|
||||
%token FISU LSSU MSU
|
||||
%token SIO OPC DPC SLS
|
||||
%token FISU LSSU MSU HFISU HLSSU HMSU
|
||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||
|
||||
|
||||
%type <s> ID
|
||||
%type <e> EID
|
||||
@ -508,7 +509,8 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
|
||||
| MPLS pnum { $$ = gen_mpls($2); }
|
||||
| MPLS { $$ = gen_mpls(-1); }
|
||||
| PPPOED { $$ = gen_pppoed(); }
|
||||
| PPPOES { $$ = gen_pppoes(); }
|
||||
| PPPOES pnum { $$ = gen_pppoes($2); }
|
||||
| PPPOES { $$ = gen_pppoes(-1); }
|
||||
| pfvar { $$ = $1; }
|
||||
| pqual p80211 { $$ = $2; }
|
||||
;
|
||||
@ -672,12 +674,19 @@ atmlistvalue: atmfieldvalue
|
||||
mtp2type: FISU { $$ = M_FISU; }
|
||||
| LSSU { $$ = M_LSSU; }
|
||||
| MSU { $$ = M_MSU; }
|
||||
| HFISU { $$ = MH_FISU; }
|
||||
| HLSSU { $$ = MH_LSSU; }
|
||||
| HMSU { $$ = MH_MSU; }
|
||||
;
|
||||
/* MTP3 field types quantifier */
|
||||
mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
|
||||
| OPC { $$.mtp3fieldtype = M_OPC; }
|
||||
| DPC { $$.mtp3fieldtype = M_DPC; }
|
||||
| SLS { $$.mtp3fieldtype = M_SLS; }
|
||||
| HSIO { $$.mtp3fieldtype = MH_SIO; }
|
||||
| HOPC { $$.mtp3fieldtype = MH_OPC; }
|
||||
| HDPC { $$.mtp3fieldtype = MH_DPC; }
|
||||
| HSLS { $$.mtp3fieldtype = MH_SLS; }
|
||||
;
|
||||
mtp3value: mtp3fieldvalue
|
||||
| relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
|
||||
@ -689,7 +698,11 @@ mtp3fieldvalue: NUM {
|
||||
if ($$.mtp3fieldtype == M_SIO ||
|
||||
$$.mtp3fieldtype == M_OPC ||
|
||||
$$.mtp3fieldtype == M_DPC ||
|
||||
$$.mtp3fieldtype == M_SLS )
|
||||
$$.mtp3fieldtype == M_SLS ||
|
||||
$$.mtp3fieldtype == MH_SIO ||
|
||||
$$.mtp3fieldtype == MH_OPC ||
|
||||
$$.mtp3fieldtype == MH_DPC ||
|
||||
$$.mtp3fieldtype == MH_SLS)
|
||||
$$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
|
||||
}
|
||||
;
|
||||
|
202
external/bsd/libpcap/dist/optimize.c
vendored
202
external/bsd/libpcap/dist/optimize.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: optimize.c,v 1.5 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: optimize.c,v 1.6 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
|
||||
@ -114,51 +114,9 @@ static int cur_mark;
|
||||
static void opt_init(struct block *);
|
||||
static void opt_cleanup(void);
|
||||
|
||||
static void make_marks(struct block *);
|
||||
static void mark_code(struct block *);
|
||||
|
||||
static void intern_blocks(struct block *);
|
||||
|
||||
static int eq_slist(struct slist *, struct slist *);
|
||||
|
||||
static void find_levels_r(struct block *);
|
||||
|
||||
static void find_levels(struct block *);
|
||||
static void find_dom(struct block *);
|
||||
static void propedom(struct edge *);
|
||||
static void find_edom(struct block *);
|
||||
static void find_closure(struct block *);
|
||||
static int atomuse(struct stmt *);
|
||||
static int atomdef(struct stmt *);
|
||||
static void compute_local_ud(struct block *);
|
||||
static void find_ud(struct block *);
|
||||
static void init_val(void);
|
||||
static int F(int, int, int);
|
||||
static inline void vstore(struct stmt *, int *, int, int);
|
||||
static void opt_blk(struct block *, int);
|
||||
static int use_conflict(struct block *, struct block *);
|
||||
static void opt_j(struct edge *);
|
||||
static void or_pullup(struct block *);
|
||||
static void and_pullup(struct block *);
|
||||
static void opt_blks(struct block *, int);
|
||||
static inline void link_inedge(struct edge *, struct block *);
|
||||
static void find_inedges(struct block *);
|
||||
static void opt_root(struct block **);
|
||||
static void opt_loop(struct block *, int);
|
||||
static void fold_op(struct stmt *, int, int);
|
||||
static inline struct slist *this_op(struct slist *);
|
||||
static void opt_not(struct block *);
|
||||
static void opt_peep(struct block *);
|
||||
static void opt_stmt(struct stmt *, int[], int);
|
||||
static void deadstmt(struct stmt *, struct stmt *[]);
|
||||
static void opt_deadstores(struct block *);
|
||||
static struct block *fold_edge(struct block *, struct edge *);
|
||||
static inline int eq_blk(struct block *, struct block *);
|
||||
static u_int slength(struct slist *);
|
||||
static int count_blocks(struct block *);
|
||||
static void number_blks_r(struct block *);
|
||||
static u_int count_stmts(struct block *);
|
||||
static int convert_code_r(struct block *);
|
||||
#ifdef BDEBUG
|
||||
static void opt_dump(struct block *);
|
||||
#endif
|
||||
@ -234,8 +192,7 @@ static uset all_edge_sets;
|
||||
#endif
|
||||
|
||||
static void
|
||||
find_levels_r(b)
|
||||
struct block *b;
|
||||
find_levels_r(struct block *b)
|
||||
{
|
||||
int level;
|
||||
|
||||
@ -263,8 +220,7 @@ find_levels_r(b)
|
||||
* with the 'link' field of the struct block.
|
||||
*/
|
||||
static void
|
||||
find_levels(root)
|
||||
struct block *root;
|
||||
find_levels(struct block *root)
|
||||
{
|
||||
memset((char *)levels, 0, n_blocks * sizeof(*levels));
|
||||
unMarkAll();
|
||||
@ -276,8 +232,7 @@ find_levels(root)
|
||||
* Assumes graph has been leveled.
|
||||
*/
|
||||
static void
|
||||
find_dom(root)
|
||||
struct block *root;
|
||||
find_dom(struct block *root)
|
||||
{
|
||||
int i;
|
||||
struct block *b;
|
||||
@ -307,8 +262,7 @@ find_dom(root)
|
||||
}
|
||||
|
||||
static void
|
||||
propedom(ep)
|
||||
struct edge *ep;
|
||||
propedom(struct edge *ep)
|
||||
{
|
||||
SET_INSERT(ep->edom, ep->id);
|
||||
if (ep->succ) {
|
||||
@ -322,8 +276,7 @@ propedom(ep)
|
||||
* Assumes graph has been leveled and predecessors established.
|
||||
*/
|
||||
static void
|
||||
find_edom(root)
|
||||
struct block *root;
|
||||
find_edom(struct block *root)
|
||||
{
|
||||
int i;
|
||||
uset x;
|
||||
@ -352,8 +305,7 @@ find_edom(root)
|
||||
* Assumes graph has been leveled.
|
||||
*/
|
||||
static void
|
||||
find_closure(root)
|
||||
struct block *root;
|
||||
find_closure(struct block *root)
|
||||
{
|
||||
int i;
|
||||
struct block *b;
|
||||
@ -383,8 +335,7 @@ find_closure(root)
|
||||
* The implementation should probably change to an array access.
|
||||
*/
|
||||
static int
|
||||
atomuse(s)
|
||||
struct stmt *s;
|
||||
atomuse(struct stmt *s)
|
||||
{
|
||||
register int c = s->code;
|
||||
|
||||
@ -429,8 +380,7 @@ atomuse(s)
|
||||
* The implementation should probably change to an array access.
|
||||
*/
|
||||
static int
|
||||
atomdef(s)
|
||||
struct stmt *s;
|
||||
atomdef(struct stmt *s)
|
||||
{
|
||||
if (s->code == NOP)
|
||||
return -1;
|
||||
@ -466,8 +416,7 @@ atomdef(s)
|
||||
* register by a predecessor block of this block.
|
||||
*/
|
||||
static void
|
||||
compute_local_ud(b)
|
||||
struct block *b;
|
||||
compute_local_ud(struct block *b)
|
||||
{
|
||||
struct slist *s;
|
||||
atomset def = 0, use = 0, kill = 0;
|
||||
@ -528,8 +477,7 @@ compute_local_ud(b)
|
||||
* Assume graph is already leveled.
|
||||
*/
|
||||
static void
|
||||
find_ud(root)
|
||||
struct block *root;
|
||||
find_ud(struct block *root)
|
||||
{
|
||||
int i, maxlevel;
|
||||
struct block *p;
|
||||
@ -584,7 +532,7 @@ struct valnode *vnode_base;
|
||||
struct valnode *next_vnode;
|
||||
|
||||
static void
|
||||
init_val()
|
||||
init_val(void)
|
||||
{
|
||||
curval = 0;
|
||||
next_vnode = vnode_base;
|
||||
@ -594,9 +542,7 @@ init_val()
|
||||
|
||||
/* Because we really don't have an IR, this stuff is a little messy. */
|
||||
static int
|
||||
F(code, v0, v1)
|
||||
int code;
|
||||
int v0, v1;
|
||||
F(int code, int v0, int v1)
|
||||
{
|
||||
u_int hash;
|
||||
int val;
|
||||
@ -627,11 +573,7 @@ F(code, v0, v1)
|
||||
}
|
||||
|
||||
static inline void
|
||||
vstore(s, valp, newval, alter)
|
||||
struct stmt *s;
|
||||
int *valp;
|
||||
int newval;
|
||||
int alter;
|
||||
vstore(struct stmt *s, int *valp, int newval, int alter)
|
||||
{
|
||||
if (alter && *valp == newval)
|
||||
s->code = NOP;
|
||||
@ -639,10 +581,12 @@ vstore(s, valp, newval, alter)
|
||||
*valp = newval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do constant-folding on binary operators.
|
||||
* (Unary operators are handled elsewhere.)
|
||||
*/
|
||||
static void
|
||||
fold_op(s, v0, v1)
|
||||
struct stmt *s;
|
||||
int v0, v1;
|
||||
fold_op(struct stmt *s, int v0, int v1)
|
||||
{
|
||||
bpf_u_int32 a, b;
|
||||
|
||||
@ -684,10 +628,6 @@ fold_op(s, v0, v1)
|
||||
a >>= b;
|
||||
break;
|
||||
|
||||
case BPF_NEG:
|
||||
a = -a;
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
@ -697,8 +637,7 @@ fold_op(s, v0, v1)
|
||||
}
|
||||
|
||||
static inline struct slist *
|
||||
this_op(s)
|
||||
struct slist *s;
|
||||
this_op(struct slist *s)
|
||||
{
|
||||
while (s != 0 && s->s.code == NOP)
|
||||
s = s->next;
|
||||
@ -706,8 +645,7 @@ this_op(s)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_not(b)
|
||||
struct block *b;
|
||||
opt_not(struct block *b)
|
||||
{
|
||||
struct block *tmp = JT(b);
|
||||
|
||||
@ -716,8 +654,7 @@ opt_not(b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_peep(b)
|
||||
struct block *b;
|
||||
opt_peep(struct block *b)
|
||||
{
|
||||
struct slist *s;
|
||||
struct slist *next, *last;
|
||||
@ -980,10 +917,7 @@ opt_peep(b)
|
||||
* evaluation and code transformations weren't folded together.
|
||||
*/
|
||||
static void
|
||||
opt_stmt(s, val, alter)
|
||||
struct stmt *s;
|
||||
int val[];
|
||||
int alter;
|
||||
opt_stmt(struct stmt *s, int val[], int alter)
|
||||
{
|
||||
int op;
|
||||
int v;
|
||||
@ -1168,9 +1102,7 @@ opt_stmt(s, val, alter)
|
||||
}
|
||||
|
||||
static void
|
||||
deadstmt(s, last)
|
||||
register struct stmt *s;
|
||||
register struct stmt *last[];
|
||||
deadstmt(register struct stmt *s, register struct stmt *last[])
|
||||
{
|
||||
register int atom;
|
||||
|
||||
@ -1194,8 +1126,7 @@ deadstmt(s, last)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_deadstores(b)
|
||||
register struct block *b;
|
||||
opt_deadstores(register struct block *b)
|
||||
{
|
||||
register struct slist *s;
|
||||
register int atom;
|
||||
@ -1215,9 +1146,7 @@ opt_deadstores(b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blk(b, do_stmts)
|
||||
struct block *b;
|
||||
int do_stmts;
|
||||
opt_blk(struct block *b, int do_stmts)
|
||||
{
|
||||
struct slist *s;
|
||||
struct edge *p;
|
||||
@ -1321,8 +1250,7 @@ opt_blk(b, do_stmts)
|
||||
* from 'b'.
|
||||
*/
|
||||
static int
|
||||
use_conflict(b, succ)
|
||||
struct block *b, *succ;
|
||||
use_conflict(struct block *b, struct block *succ)
|
||||
{
|
||||
int atom;
|
||||
atomset use = succ->out_use;
|
||||
@ -1338,9 +1266,7 @@ use_conflict(b, succ)
|
||||
}
|
||||
|
||||
static struct block *
|
||||
fold_edge(child, ep)
|
||||
struct block *child;
|
||||
struct edge *ep;
|
||||
fold_edge(struct block *child, struct edge *ep)
|
||||
{
|
||||
int sense;
|
||||
int aval0, aval1, oval0, oval1;
|
||||
@ -1392,8 +1318,7 @@ fold_edge(child, ep)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_j(ep)
|
||||
struct edge *ep;
|
||||
opt_j(struct edge *ep)
|
||||
{
|
||||
register int i, k;
|
||||
register struct block *target;
|
||||
@ -1448,8 +1373,7 @@ opt_j(ep)
|
||||
|
||||
|
||||
static void
|
||||
or_pullup(b)
|
||||
struct block *b;
|
||||
or_pullup(struct block *b)
|
||||
{
|
||||
int val, at_top;
|
||||
struct block *pull;
|
||||
@ -1541,8 +1465,7 @@ or_pullup(b)
|
||||
}
|
||||
|
||||
static void
|
||||
and_pullup(b)
|
||||
struct block *b;
|
||||
and_pullup(struct block *b)
|
||||
{
|
||||
int val, at_top;
|
||||
struct block *pull;
|
||||
@ -1633,9 +1556,7 @@ and_pullup(b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_blks(root, do_stmts)
|
||||
struct block *root;
|
||||
int do_stmts;
|
||||
opt_blks(struct block *root, int do_stmts)
|
||||
{
|
||||
int i, maxlevel;
|
||||
struct block *p;
|
||||
@ -1672,17 +1593,14 @@ opt_blks(root, do_stmts)
|
||||
}
|
||||
|
||||
static inline void
|
||||
link_inedge(parent, child)
|
||||
struct edge *parent;
|
||||
struct block *child;
|
||||
link_inedge(struct edge *parent, struct block *child)
|
||||
{
|
||||
parent->next = child->in_edges;
|
||||
child->in_edges = parent;
|
||||
}
|
||||
|
||||
static void
|
||||
find_inedges(root)
|
||||
struct block *root;
|
||||
find_inedges(struct block *root)
|
||||
{
|
||||
int i;
|
||||
struct block *b;
|
||||
@ -1703,8 +1621,7 @@ find_inedges(root)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_root(b)
|
||||
struct block **b;
|
||||
opt_root(struct block **b)
|
||||
{
|
||||
struct slist *tmp, *s;
|
||||
|
||||
@ -1728,9 +1645,7 @@ opt_root(b)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_loop(root, do_stmts)
|
||||
struct block *root;
|
||||
int do_stmts;
|
||||
opt_loop(struct block *root, int do_stmts)
|
||||
{
|
||||
|
||||
#ifdef BDEBUG
|
||||
@ -1760,8 +1675,7 @@ opt_loop(root, do_stmts)
|
||||
* Optimize the filter code in its dag representation.
|
||||
*/
|
||||
void
|
||||
bpf_optimize(rootp)
|
||||
struct block **rootp;
|
||||
bpf_optimize(struct block **rootp)
|
||||
{
|
||||
struct block *root;
|
||||
|
||||
@ -1788,8 +1702,7 @@ bpf_optimize(rootp)
|
||||
}
|
||||
|
||||
static void
|
||||
make_marks(p)
|
||||
struct block *p;
|
||||
make_marks(struct block *p)
|
||||
{
|
||||
if (!isMarked(p)) {
|
||||
Mark(p);
|
||||
@ -1805,8 +1718,7 @@ make_marks(p)
|
||||
* only for nodes that are alive.
|
||||
*/
|
||||
static void
|
||||
mark_code(p)
|
||||
struct block *p;
|
||||
mark_code(struct block *p)
|
||||
{
|
||||
cur_mark += 1;
|
||||
make_marks(p);
|
||||
@ -1817,8 +1729,7 @@ mark_code(p)
|
||||
* the accumulator.
|
||||
*/
|
||||
static int
|
||||
eq_slist(x, y)
|
||||
struct slist *x, *y;
|
||||
eq_slist(struct slist *x, struct slist *y)
|
||||
{
|
||||
while (1) {
|
||||
while (x && x->s.code == NOP)
|
||||
@ -1837,8 +1748,7 @@ eq_slist(x, y)
|
||||
}
|
||||
|
||||
static inline int
|
||||
eq_blk(b0, b1)
|
||||
struct block *b0, *b1;
|
||||
eq_blk(struct block *b0, struct block *b1)
|
||||
{
|
||||
if (b0->s.code == b1->s.code &&
|
||||
b0->s.k == b1->s.k &&
|
||||
@ -1849,8 +1759,7 @@ eq_blk(b0, b1)
|
||||
}
|
||||
|
||||
static void
|
||||
intern_blocks(root)
|
||||
struct block *root;
|
||||
intern_blocks(struct block *root)
|
||||
{
|
||||
struct block *p;
|
||||
int i, j;
|
||||
@ -1893,7 +1802,7 @@ intern_blocks(root)
|
||||
}
|
||||
|
||||
static void
|
||||
opt_cleanup()
|
||||
opt_cleanup(void)
|
||||
{
|
||||
free((void *)vnode_base);
|
||||
free((void *)vmap);
|
||||
@ -1907,8 +1816,7 @@ opt_cleanup()
|
||||
* Return the number of stmts in 's'.
|
||||
*/
|
||||
static u_int
|
||||
slength(s)
|
||||
struct slist *s;
|
||||
slength(struct slist *s)
|
||||
{
|
||||
u_int n = 0;
|
||||
|
||||
@ -1923,8 +1831,7 @@ slength(s)
|
||||
* All nodes should be initially unmarked.
|
||||
*/
|
||||
static int
|
||||
count_blocks(p)
|
||||
struct block *p;
|
||||
count_blocks(struct block *p)
|
||||
{
|
||||
if (p == 0 || isMarked(p))
|
||||
return 0;
|
||||
@ -1937,8 +1844,7 @@ count_blocks(p)
|
||||
* the basic blocks, and entering them into the 'blocks' array.`
|
||||
*/
|
||||
static void
|
||||
number_blks_r(p)
|
||||
struct block *p;
|
||||
number_blks_r(struct block *p)
|
||||
{
|
||||
int n;
|
||||
|
||||
@ -1973,8 +1879,7 @@ number_blks_r(p)
|
||||
* an extra long jump if the false branch requires it (p->longjf).
|
||||
*/
|
||||
static u_int
|
||||
count_stmts(p)
|
||||
struct block *p;
|
||||
count_stmts(struct block *p)
|
||||
{
|
||||
u_int n;
|
||||
|
||||
@ -1991,8 +1896,7 @@ count_stmts(p)
|
||||
* from the total number of blocks and/or statements.
|
||||
*/
|
||||
static void
|
||||
opt_init(root)
|
||||
struct block *root;
|
||||
opt_init(struct block *root)
|
||||
{
|
||||
bpf_u_int32 *p;
|
||||
int i, n, max_stmts;
|
||||
@ -2090,8 +1994,7 @@ int bids[1000];
|
||||
* properly.
|
||||
*/
|
||||
static int
|
||||
convert_code_r(p)
|
||||
struct block *p;
|
||||
convert_code_r(struct block *p)
|
||||
{
|
||||
struct bpf_insn *dst;
|
||||
struct slist *src;
|
||||
@ -2263,9 +2166,7 @@ filled:
|
||||
* done with the filter program. See the pcap man page.
|
||||
*/
|
||||
struct bpf_insn *
|
||||
icode_to_fcode(root, lenp)
|
||||
struct block *root;
|
||||
u_int *lenp;
|
||||
icode_to_fcode(struct block *root, u_int *lenp)
|
||||
{
|
||||
u_int n;
|
||||
struct bpf_insn *fp;
|
||||
@ -2335,8 +2236,7 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
|
||||
|
||||
#ifdef BDEBUG
|
||||
static void
|
||||
opt_dump(root)
|
||||
struct block *root;
|
||||
opt_dump(struct block *root)
|
||||
{
|
||||
struct bpf_program f;
|
||||
|
||||
|
339
external/bsd/libpcap/dist/pcap-bpf.c
vendored
339
external/bsd/libpcap/dist/pcap-bpf.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcap-bpf.c,v 1.3 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: pcap-bpf.c,v 1.4 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1998
|
||||
@ -127,18 +127,60 @@ static int bpf_load(char *errbuf);
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
#include "pcap-dag.h"
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef HAVE_SNF_API
|
||||
#include "pcap-snf.h"
|
||||
#endif /* HAVE_SNF_API */
|
||||
|
||||
#ifdef HAVE_OS_PROTO_H
|
||||
#include "os-proto.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Later versions of NetBSD stick padding in front of FDDI frames
|
||||
* to align the IP header on a 4-byte boundary.
|
||||
*/
|
||||
#if defined(__NetBSD__) && __NetBSD_Version__ > 106000000
|
||||
#define PCAP_FDDIPAD 3
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Private data for capturing on BPF devices.
|
||||
*/
|
||||
struct pcap_bpf {
|
||||
#ifdef PCAP_FDDIPAD
|
||||
int fddipad;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
/*
|
||||
* Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
|
||||
* alternative between these two actual mmap'd buffers as required.
|
||||
* As there is a header on the front size of the mmap'd buffer, only
|
||||
* some of the buffer is exposed to libpcap as a whole via bufsize;
|
||||
* zbufsize is the true size. zbuffer tracks the current zbuf
|
||||
* assocated with buffer so that it can be used to decide which the
|
||||
* next buffer to read will be.
|
||||
*/
|
||||
u_char *zbuf1, *zbuf2, *zbuffer;
|
||||
u_int zbufsize;
|
||||
u_int zerocopy;
|
||||
u_int interrupted;
|
||||
struct timespec firstsel;
|
||||
/*
|
||||
* If there's currently a buffer being actively processed, then it is
|
||||
* referenced here; 'buffer' is also pointed at it, but offset by the
|
||||
* size of the header.
|
||||
*/
|
||||
struct bpf_zbuf_header *bzh;
|
||||
int nonblock; /* true if in nonblocking mode */
|
||||
#endif /* HAVE_ZEROCOPY_BPF */
|
||||
|
||||
char *device; /* device name */
|
||||
int filtering_in_kernel; /* using kernel filter */
|
||||
int must_do_on_close; /* stuff we must do when we close */
|
||||
};
|
||||
|
||||
/*
|
||||
* Stuff to do when we close.
|
||||
*/
|
||||
#define MUST_CLEAR_RFMON 0x00000001 /* clear rfmon (monitor) mode */
|
||||
|
||||
#ifdef BIOCGDLTLIST
|
||||
# if (defined(HAVE_NET_IF_MEDIA_H) && defined(IFM_IEEE80211)) && !defined(__APPLE__)
|
||||
#define HAVE_BSD_IEEE80211
|
||||
@ -197,22 +239,17 @@ static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
|
||||
|
||||
/*
|
||||
* For zerocopy bpf, the setnonblock/getnonblock routines need to modify
|
||||
* p->md.timeout so we don't call select(2) if the pcap handle is in non-
|
||||
* blocking mode. We preserve the timeout supplied by pcap_open functions
|
||||
* to make sure it does not get clobbered if the pcap handle moves between
|
||||
* blocking and non-blocking mode.
|
||||
* pb->nonblock so we don't call select(2) if the pcap handle is in non-
|
||||
* blocking mode.
|
||||
*/
|
||||
static int
|
||||
pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
|
||||
{
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
if (p->md.zerocopy) {
|
||||
/*
|
||||
* Use a negative value for the timeout to represent that the
|
||||
* pcap handle is in non-blocking mode.
|
||||
*/
|
||||
return (p->md.timeout < 0);
|
||||
}
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
|
||||
if (pb->zerocopy)
|
||||
return (pb->nonblock);
|
||||
#endif
|
||||
return (pcap_getnonblock_fd(p, errbuf));
|
||||
}
|
||||
@ -221,34 +258,10 @@ static int
|
||||
pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
if (p->md.zerocopy) {
|
||||
/*
|
||||
* Map each value to the corresponding 2's complement, to
|
||||
* preserve the timeout value provided with pcap_set_timeout.
|
||||
* (from pcap-linux.c).
|
||||
*/
|
||||
if (nonblock) {
|
||||
if (p->md.timeout >= 0) {
|
||||
/*
|
||||
* Timeout is non-negative, so we're not
|
||||
* currently in non-blocking mode; set it
|
||||
* to the 2's complement, to make it
|
||||
* negative, as an indication that we're
|
||||
* in non-blocking mode.
|
||||
*/
|
||||
p->md.timeout = p->md.timeout * -1 - 1;
|
||||
}
|
||||
} else {
|
||||
if (p->md.timeout < 0) {
|
||||
/*
|
||||
* Timeout is negative, so we're currently
|
||||
* in blocking mode; reverse the previous
|
||||
* operation, to make the timeout non-negative
|
||||
* again.
|
||||
*/
|
||||
p->md.timeout = (p->md.timeout + 1) * -1;
|
||||
}
|
||||
}
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
|
||||
if (pb->zerocopy) {
|
||||
pb->nonblock = nonblock;
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
@ -268,25 +281,26 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
|
||||
static int
|
||||
pcap_next_zbuf_shm(pcap_t *p, int *cc)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
struct bpf_zbuf_header *bzh;
|
||||
|
||||
if (p->md.zbuffer == p->md.zbuf2 || p->md.zbuffer == NULL) {
|
||||
bzh = (struct bpf_zbuf_header *)p->md.zbuf1;
|
||||
if (pb->zbuffer == pb->zbuf2 || pb->zbuffer == NULL) {
|
||||
bzh = (struct bpf_zbuf_header *)pb->zbuf1;
|
||||
if (bzh->bzh_user_gen !=
|
||||
atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
|
||||
p->md.bzh = bzh;
|
||||
p->md.zbuffer = (u_char *)p->md.zbuf1;
|
||||
p->buffer = p->md.zbuffer + sizeof(*bzh);
|
||||
pb->bzh = bzh;
|
||||
pb->zbuffer = (u_char *)pb->zbuf1;
|
||||
p->buffer = pb->zbuffer + sizeof(*bzh);
|
||||
*cc = bzh->bzh_kernel_len;
|
||||
return (1);
|
||||
}
|
||||
} else if (p->md.zbuffer == p->md.zbuf1) {
|
||||
bzh = (struct bpf_zbuf_header *)p->md.zbuf2;
|
||||
} else if (pb->zbuffer == pb->zbuf1) {
|
||||
bzh = (struct bpf_zbuf_header *)pb->zbuf2;
|
||||
if (bzh->bzh_user_gen !=
|
||||
atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
|
||||
p->md.bzh = bzh;
|
||||
p->md.zbuffer = (u_char *)p->md.zbuf2;
|
||||
p->buffer = p->md.zbuffer + sizeof(*bzh);
|
||||
pb->bzh = bzh;
|
||||
pb->zbuffer = (u_char *)pb->zbuf2;
|
||||
p->buffer = pb->zbuffer + sizeof(*bzh);
|
||||
*cc = bzh->bzh_kernel_len;
|
||||
return (1);
|
||||
}
|
||||
@ -305,6 +319,7 @@ pcap_next_zbuf_shm(pcap_t *p, int *cc)
|
||||
static int
|
||||
pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
struct bpf_zbuf bz;
|
||||
struct timeval tv;
|
||||
struct timespec cur;
|
||||
@ -328,15 +343,15 @@ pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
* our timeout is less then or equal to zero, handle it like a
|
||||
* regular timeout.
|
||||
*/
|
||||
tmout = p->md.timeout;
|
||||
tmout = p->opt.timeout;
|
||||
if (tmout)
|
||||
(void) clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||
if (p->md.interrupted && p->md.timeout) {
|
||||
expire = TSTOMILLI(&p->md.firstsel) + p->md.timeout;
|
||||
if (pb->interrupted && p->opt.timeout) {
|
||||
expire = TSTOMILLI(&pb->firstsel) + p->opt.timeout;
|
||||
tmout = expire - TSTOMILLI(&cur);
|
||||
#undef TSTOMILLI
|
||||
if (tmout <= 0) {
|
||||
p->md.interrupted = 0;
|
||||
pb->interrupted = 0;
|
||||
data = pcap_next_zbuf_shm(p, cc);
|
||||
if (data)
|
||||
return (data);
|
||||
@ -353,7 +368,7 @@ pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
* the next timeout. Note that we only call select if the handle
|
||||
* is in blocking mode.
|
||||
*/
|
||||
if (p->md.timeout >= 0) {
|
||||
if (!pb->nonblock) {
|
||||
FD_ZERO(&r_set);
|
||||
FD_SET(p->fd, &r_set);
|
||||
if (tmout != 0) {
|
||||
@ -361,11 +376,11 @@ pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
tv.tv_usec = (tmout * 1000) % 1000000;
|
||||
}
|
||||
r = select(p->fd + 1, &r_set, NULL, NULL,
|
||||
p->md.timeout != 0 ? &tv : NULL);
|
||||
p->opt.timeout != 0 ? &tv : NULL);
|
||||
if (r < 0 && errno == EINTR) {
|
||||
if (!p->md.interrupted && p->md.timeout) {
|
||||
p->md.interrupted = 1;
|
||||
p->md.firstsel = cur;
|
||||
if (!pb->interrupted && p->opt.timeout) {
|
||||
pb->interrupted = 1;
|
||||
pb->firstsel = cur;
|
||||
}
|
||||
return (0);
|
||||
} else if (r < 0) {
|
||||
@ -374,7 +389,7 @@ pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
}
|
||||
p->md.interrupted = 0;
|
||||
pb->interrupted = 0;
|
||||
/*
|
||||
* Check again for data, which may exist now that we've either been
|
||||
* woken up as a result of data or timed out. Try the "there's data"
|
||||
@ -402,30 +417,22 @@ pcap_next_zbuf(pcap_t *p, int *cc)
|
||||
static int
|
||||
pcap_ack_zbuf(pcap_t *p)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
|
||||
atomic_store_rel_int(&p->md.bzh->bzh_user_gen,
|
||||
p->md.bzh->bzh_kernel_gen);
|
||||
p->md.bzh = NULL;
|
||||
atomic_store_rel_int(&pb->bzh->bzh_user_gen,
|
||||
pb->bzh->bzh_kernel_gen);
|
||||
pb->bzh = NULL;
|
||||
p->buffer = NULL;
|
||||
return (0);
|
||||
}
|
||||
#endif /* HAVE_ZEROCOPY_BPF */
|
||||
|
||||
pcap_t *
|
||||
pcap_create(const char *device, char *ebuf)
|
||||
pcap_create_interface(const char *device, char *ebuf)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
if (strstr(device, "dag"))
|
||||
return (dag_create(device, ebuf));
|
||||
#endif /* HAVE_DAG_API */
|
||||
#ifdef HAVE_SNF_API
|
||||
if (strstr(device, "snf"))
|
||||
return (snf_create(device, ebuf));
|
||||
#endif /* HAVE_SNF_API */
|
||||
|
||||
p = pcap_create_common(device, ebuf);
|
||||
p = pcap_create_common(device, ebuf, sizeof (struct pcap_bpf));
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
@ -821,6 +828,7 @@ pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
|
||||
static int
|
||||
pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
int cc;
|
||||
int n = 0;
|
||||
register u_char *bp, *ep;
|
||||
@ -856,7 +864,7 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
* buffer.
|
||||
*/
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
if (p->md.zerocopy) {
|
||||
if (pb->zerocopy) {
|
||||
if (p->buffer != NULL)
|
||||
pcap_ack_zbuf(p);
|
||||
i = pcap_next_zbuf(p, &cc);
|
||||
@ -1004,7 +1012,7 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
* skipping that padding.
|
||||
#endif
|
||||
*/
|
||||
if (p->md.use_bpf ||
|
||||
if (pb->filtering_in_kernel ||
|
||||
bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
|
||||
struct pcap_pkthdr pkthdr;
|
||||
|
||||
@ -1271,19 +1279,20 @@ bpf_load(char *errbuf)
|
||||
static void
|
||||
pcap_cleanup_bpf(pcap_t *p)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
#ifdef HAVE_BSD_IEEE80211
|
||||
int sock;
|
||||
struct ifmediareq req;
|
||||
struct ifreq ifr;
|
||||
#endif
|
||||
|
||||
if (p->md.must_do_on_close != 0) {
|
||||
if (pb->must_do_on_close != 0) {
|
||||
/*
|
||||
* There's something we have to do when closing this
|
||||
* pcap_t.
|
||||
*/
|
||||
#ifdef HAVE_BSD_IEEE80211
|
||||
if (p->md.must_do_on_close & MUST_CLEAR_RFMON) {
|
||||
if (pb->must_do_on_close & MUST_CLEAR_RFMON) {
|
||||
/*
|
||||
* We put the interface into rfmon mode;
|
||||
* take it out of rfmon mode.
|
||||
@ -1300,7 +1309,7 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
strerror(errno));
|
||||
} else {
|
||||
memset(&req, 0, sizeof(req));
|
||||
strncpy(req.ifm_name, p->md.device,
|
||||
strncpy(req.ifm_name, pb->device,
|
||||
sizeof(req.ifm_name));
|
||||
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
|
||||
fprintf(stderr,
|
||||
@ -1315,7 +1324,7 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
*/
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
(void)strncpy(ifr.ifr_name,
|
||||
p->md.device,
|
||||
pb->device,
|
||||
sizeof(ifr.ifr_name));
|
||||
ifr.ifr_media =
|
||||
req.ifm_current & ~IFM_IEEE80211_MONITOR;
|
||||
@ -1338,11 +1347,11 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
* have to take the interface out of some mode.
|
||||
*/
|
||||
pcap_remove_from_pcaps_to_close(p);
|
||||
p->md.must_do_on_close = 0;
|
||||
pb->must_do_on_close = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
if (p->md.zerocopy) {
|
||||
if (pb->zerocopy) {
|
||||
/*
|
||||
* Delete the mappings. Note that p->buffer gets
|
||||
* initialized to one of the mmapped regions in
|
||||
@ -1350,16 +1359,16 @@ pcap_cleanup_bpf(pcap_t *p)
|
||||
* null it out so that pcap_cleanup_live_common()
|
||||
* doesn't try to free it.
|
||||
*/
|
||||
if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL)
|
||||
(void) munmap(p->md.zbuf1, p->md.zbufsize);
|
||||
if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL)
|
||||
(void) munmap(p->md.zbuf2, p->md.zbufsize);
|
||||
if (pb->zbuf1 != MAP_FAILED && pb->zbuf1 != NULL)
|
||||
(void) munmap(pb->zbuf1, pb->zbufsize);
|
||||
if (pb->zbuf2 != MAP_FAILED && pb->zbuf2 != NULL)
|
||||
(void) munmap(pb->zbuf2, pb->zbufsize);
|
||||
p->buffer = NULL;
|
||||
}
|
||||
#endif
|
||||
if (p->md.device != NULL) {
|
||||
free(p->md.device);
|
||||
p->md.device = NULL;
|
||||
if (pb->device != NULL) {
|
||||
free(pb->device);
|
||||
pb->device = NULL;
|
||||
}
|
||||
pcap_cleanup_live_common(p);
|
||||
}
|
||||
@ -1474,6 +1483,7 @@ check_setif_failure(pcap_t *p, int error)
|
||||
static int
|
||||
pcap_activate_bpf(pcap_t *p)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
int status = 0;
|
||||
int fd;
|
||||
#ifdef LIFNAMSIZ
|
||||
@ -1555,8 +1565,8 @@ pcap_activate_bpf(pcap_t *p)
|
||||
}
|
||||
#endif
|
||||
|
||||
p->md.device = strdup(p->opt.source);
|
||||
if (p->md.device == NULL) {
|
||||
pb->device = strdup(p->opt.source);
|
||||
if (pb->device == NULL) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
|
||||
pcap_strerror(errno));
|
||||
status = PCAP_ERROR;
|
||||
@ -1664,7 +1674,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
/*
|
||||
* We have zerocopy BPF; use it.
|
||||
*/
|
||||
p->md.zerocopy = 1;
|
||||
pb->zerocopy = 1;
|
||||
|
||||
/*
|
||||
* How to pick a buffer size: first, query the maximum buffer
|
||||
@ -1694,22 +1704,22 @@ pcap_activate_bpf(pcap_t *p)
|
||||
#ifndef roundup
|
||||
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */
|
||||
#endif
|
||||
p->md.zbufsize = roundup(v, getpagesize());
|
||||
if (p->md.zbufsize > zbufmax)
|
||||
p->md.zbufsize = zbufmax;
|
||||
p->md.zbuf1 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
|
||||
pb->zbufsize = roundup(v, getpagesize());
|
||||
if (pb->zbufsize > zbufmax)
|
||||
pb->zbufsize = zbufmax;
|
||||
pb->zbuf1 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON, -1, 0);
|
||||
p->md.zbuf2 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
|
||||
pb->zbuf2 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON, -1, 0);
|
||||
if (p->md.zbuf1 == MAP_FAILED || p->md.zbuf2 == MAP_FAILED) {
|
||||
if (pb->zbuf1 == MAP_FAILED || pb->zbuf2 == MAP_FAILED) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s",
|
||||
pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
bzero(&bz, sizeof(bz));
|
||||
bz.bz_bufa = p->md.zbuf1;
|
||||
bz.bz_bufb = p->md.zbuf2;
|
||||
bz.bz_buflen = p->md.zbufsize;
|
||||
memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
|
||||
bz.bz_bufa = pb->zbuf1;
|
||||
bz.bz_bufb = pb->zbuf2;
|
||||
bz.bz_buflen = pb->zbufsize;
|
||||
if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s",
|
||||
pcap_strerror(errno));
|
||||
@ -1721,7 +1731,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
p->opt.source, pcap_strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
v = p->md.zbufsize - sizeof(struct bpf_zbuf_header);
|
||||
v = pb->zbufsize - sizeof(struct bpf_zbuf_header);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -2033,8 +2043,8 @@ pcap_activate_bpf(pcap_t *p)
|
||||
if (v == DLT_FDDI)
|
||||
p->fddipad = PCAP_FDDIPAD;
|
||||
else
|
||||
p->fddipad = 0;
|
||||
#endif
|
||||
p->fddipad = 0;
|
||||
p->linktype = v;
|
||||
|
||||
#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
|
||||
@ -2056,9 +2066,14 @@ pcap_activate_bpf(pcap_t *p)
|
||||
#endif
|
||||
/* set timeout */
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
if (p->md.timeout != 0 && !p->md.zerocopy) {
|
||||
/*
|
||||
* In zero-copy mode, we just use the timeout in select().
|
||||
* XXX - what if we're in non-blocking mode and the *application*
|
||||
* is using select() or poll() or kqueues or....?
|
||||
*/
|
||||
if (p->opt.timeout && !pb->zerocopy) {
|
||||
#else
|
||||
if (p->md.timeout) {
|
||||
if (p->opt.timeout) {
|
||||
#endif
|
||||
/*
|
||||
* XXX - is this seconds/nanoseconds in AIX?
|
||||
@ -2082,8 +2097,8 @@ pcap_activate_bpf(pcap_t *p)
|
||||
struct BPF_TIMEVAL bpf_to;
|
||||
|
||||
if (IOCPARM_LEN(BIOCSRTIMEOUT) != sizeof(struct timeval)) {
|
||||
bpf_to.tv_sec = p->md.timeout / 1000;
|
||||
bpf_to.tv_usec = (p->md.timeout * 1000) % 1000000;
|
||||
bpf_to.tv_sec = p->opt.timeout / 1000;
|
||||
bpf_to.tv_usec = (p->opt.timeout * 1000) % 1000000;
|
||||
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"BIOCSRTIMEOUT: %s", pcap_strerror(errno));
|
||||
@ -2092,8 +2107,8 @@ pcap_activate_bpf(pcap_t *p)
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
to.tv_sec = p->md.timeout / 1000;
|
||||
to.tv_usec = (p->md.timeout * 1000) % 1000000;
|
||||
to.tv_sec = p->opt.timeout / 1000;
|
||||
to.tv_usec = (p->opt.timeout * 1000) % 1000000;
|
||||
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"BIOCSRTIMEOUT: %s", pcap_strerror(errno));
|
||||
@ -2105,7 +2120,6 @@ pcap_activate_bpf(pcap_t *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _AIX
|
||||
#ifdef BIOCIMMEDIATE
|
||||
/*
|
||||
* Darren Reed notes that
|
||||
@ -2117,51 +2131,38 @@ pcap_activate_bpf(pcap_t *p)
|
||||
* is reducing things to only a few packets (i.e. one every
|
||||
* second or so).
|
||||
*
|
||||
* so we turn BIOCIMMEDIATE mode on if this is AIX.
|
||||
* so we always turn BIOCIMMEDIATE mode on if this is AIX.
|
||||
*
|
||||
* We don't turn it on for other platforms, as that means we
|
||||
* get woken up for every packet, which may not be what we want;
|
||||
* in the Winter 1993 USENIX paper on BPF, they say:
|
||||
* For other platforms, we don't turn immediate mode on by default,
|
||||
* as that would mean we get woken up for every packet, which
|
||||
* probably isn't what you want for a packet sniffer.
|
||||
*
|
||||
* Since a process might want to look at every packet on a
|
||||
* network and the time between packets can be only a few
|
||||
* microseconds, it is not possible to do a read system call
|
||||
* per packet and BPF must collect the data from several
|
||||
* packets and return it as a unit when the monitoring
|
||||
* application does a read.
|
||||
*
|
||||
* which I infer is the reason for the timeout - it means we
|
||||
* wait that amount of time, in the hopes that more packets
|
||||
* will arrive and we'll get them all with one read.
|
||||
*
|
||||
* Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
|
||||
* BSDs) causes the timeout to be ignored.
|
||||
*
|
||||
* On the other hand, some platforms (e.g., Linux) don't support
|
||||
* timeouts, they just hand stuff to you as soon as it arrives;
|
||||
* if that doesn't cause a problem on those platforms, it may
|
||||
* be OK to have BIOCIMMEDIATE mode on BSD as well.
|
||||
*
|
||||
* (Note, though, that applications may depend on the read
|
||||
* completing, even if no packets have arrived, when the timeout
|
||||
* expires, e.g. GUI applications that have to check for input
|
||||
* while waiting for packets to arrive; a non-zero timeout
|
||||
* prevents "select()" from working right on FreeBSD and
|
||||
* possibly other BSDs, as the timer doesn't start until a
|
||||
* "read()" is done, so the timer isn't in effect if the
|
||||
* application is blocked on a "select()", and the "select()"
|
||||
* doesn't get woken up for a BPF device until the buffer
|
||||
* fills up.)
|
||||
* We set immediate mode if the caller requested it by calling
|
||||
* pcap_set_immediate() before calling pcap_activate().
|
||||
*/
|
||||
v = 1;
|
||||
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
|
||||
pcap_strerror(errno));
|
||||
#ifndef _AIX
|
||||
if (p->opt.immediate) {
|
||||
#endif /* _AIX */
|
||||
v = 1;
|
||||
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"BIOCIMMEDIATE: %s", pcap_strerror(errno));
|
||||
status = PCAP_ERROR;
|
||||
goto bad;
|
||||
}
|
||||
#ifndef _AIX
|
||||
}
|
||||
#endif /* _AIX */
|
||||
#else /* BIOCIMMEDIATE */
|
||||
if (p->opt.immediate) {
|
||||
/*
|
||||
* We don't support immediate mode. Fail.
|
||||
*/
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Immediate mode not supported");
|
||||
status = PCAP_ERROR;
|
||||
goto bad;
|
||||
}
|
||||
#endif /* BIOCIMMEDIATE */
|
||||
#endif /* _AIX */
|
||||
#endif /* BIOCIMMEDIATE */
|
||||
|
||||
if (p->opt.promisc) {
|
||||
/* set promiscuous mode, just warn if it fails */
|
||||
@ -2180,7 +2181,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||
}
|
||||
p->bufsize = v;
|
||||
#ifdef HAVE_ZEROCOPY_BPF
|
||||
if (!p->md.zerocopy) {
|
||||
if (!pb->zerocopy) {
|
||||
#endif
|
||||
p->buffer = (u_char *)malloc(p->bufsize);
|
||||
if (p->buffer == NULL) {
|
||||
@ -2281,22 +2282,13 @@ pcap_activate_bpf(pcap_t *p)
|
||||
|
||||
return (status);
|
||||
bad:
|
||||
pcap_cleanup_bpf(p);
|
||||
pcap_cleanup_bpf(p);
|
||||
return (status);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
#ifdef HAVE_DAG_API
|
||||
if (dag_platform_finddevs(alldevsp, errbuf) < 0)
|
||||
return (-1);
|
||||
#endif /* HAVE_DAG_API */
|
||||
#ifdef HAVE_SNF_API
|
||||
if (snf_platform_finddevs(alldevsp, errbuf) < 0)
|
||||
return (-1);
|
||||
#endif /* HAVE_SNF_API */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -2304,6 +2296,7 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
static int
|
||||
monitor_mode(pcap_t *p, int set)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
int sock;
|
||||
struct ifmediareq req;
|
||||
int *media_list;
|
||||
@ -2441,7 +2434,7 @@ monitor_mode(pcap_t *p, int set)
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
|
||||
p->md.must_do_on_close |= MUST_CLEAR_RFMON;
|
||||
pb->must_do_on_close |= MUST_CLEAR_RFMON;
|
||||
|
||||
/*
|
||||
* Add this to the list of pcaps to close when we exit.
|
||||
@ -2618,6 +2611,8 @@ remove_802_11(pcap_t *p)
|
||||
static int
|
||||
pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
{
|
||||
struct pcap_bpf *pb = p->priv;
|
||||
|
||||
/*
|
||||
* Free any user-mode filter we might happen to have installed.
|
||||
*/
|
||||
@ -2630,7 +2625,7 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
/*
|
||||
* It worked.
|
||||
*/
|
||||
p->md.use_bpf = 1; /* filtering in the kernel */
|
||||
pb->filtering_in_kernel = 1; /* filtering in the kernel */
|
||||
|
||||
/*
|
||||
* Discard any previously-received packets, as they might
|
||||
@ -2670,7 +2665,7 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
|
||||
*/
|
||||
if (install_bpf_program(p, fp) < 0)
|
||||
return (-1);
|
||||
p->md.use_bpf = 0; /* filtering in userland */
|
||||
pb->filtering_in_kernel = 0; /* filtering in userland */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
46
external/bsd/libpcap/dist/pcap.3pcap.in
vendored
46
external/bsd/libpcap/dist/pcap.3pcap.in
vendored
@ -19,7 +19,7 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP 3PCAP "4 April 2008"
|
||||
.TH PCAP 3PCAP "1 July 2013"
|
||||
.SH NAME
|
||||
pcap \- Packet Capture library
|
||||
.SH SYNOPSIS
|
||||
@ -309,6 +309,19 @@ handle, call
|
||||
lists the values it returns and describes the packet formats that
|
||||
correspond to those values.
|
||||
.PP
|
||||
Do
|
||||
.B NOT
|
||||
assume that the packets for a given capture or ``savefile`` will have
|
||||
any given link-layer header type, such as
|
||||
.B DLT_EN10MB
|
||||
for Ethernet. For example, the "any" device on Linux will have a
|
||||
link-layer header type of
|
||||
.B DLT_LINUX_SLL
|
||||
even if all devices on the system at the time the "any" device is opened
|
||||
have some other data link type, such as
|
||||
.B DLT_EN10MB
|
||||
for Ethernet.
|
||||
.PP
|
||||
To obtain the
|
||||
.B "FILE\ *"
|
||||
corresponding to a
|
||||
@ -510,20 +523,13 @@ number of bytes available from the capture, if the length of the packet
|
||||
is larger than the maximum number of bytes to capture).
|
||||
.RE
|
||||
.PP
|
||||
.BR pcap_next_ex ()
|
||||
supplies that pointer through a pointer argument.
|
||||
.BR pcap_next ()
|
||||
is passed an argument that points to a
|
||||
.I struct pcap_pkthdr
|
||||
structure, and fills it in.
|
||||
.PP
|
||||
The callback is also supplied a
|
||||
.I const u_char
|
||||
pointer to the first
|
||||
.B caplen
|
||||
(as given in the
|
||||
.I struct pcap_pkthdr
|
||||
a pointer to which is passed to the callback routine)
|
||||
mentioned above)
|
||||
bytes of data from the packet. This won't necessarily be the entire
|
||||
packet; to capture the entire packet, you will have to provide a value
|
||||
for
|
||||
@ -534,10 +540,28 @@ that is sufficiently large to get all of the packet's data - a value of
|
||||
65535 should be sufficient on most if not all networks). When reading
|
||||
from a ``savefile'', the snapshot length specified when the capture was
|
||||
performed will limit the amount of packet data available.
|
||||
.PP
|
||||
.BR pcap_next ()
|
||||
returns that pointer;
|
||||
is passed an argument that points to a
|
||||
.I struct pcap_pkthdr
|
||||
structure, and fills it in with the time stamp and length values for the
|
||||
packet. It returns a
|
||||
.I const u_char
|
||||
to the first
|
||||
.B caplen
|
||||
bytes of the packet on success, and NULL on error.
|
||||
.PP
|
||||
.BR pcap_next_ex ()
|
||||
supplies that pointer through a pointer argument.
|
||||
is passed two pointer arguments, one of which points to a
|
||||
.IR struct pcap_pkthdr *
|
||||
and one of which points to a
|
||||
.IR "const u_char" *.
|
||||
It sets the first pointer to point to a
|
||||
.I struct pcap_pkthdr
|
||||
structure with the time stamp and length values for the packet, and sets
|
||||
the second pointer to point to the first
|
||||
.B caplen
|
||||
bytes of the packet.
|
||||
.PP
|
||||
To force the loop in
|
||||
.BR pcap_dispatch ()
|
||||
|
510
external/bsd/libpcap/dist/pcap.c
vendored
510
external/bsd/libpcap/dist/pcap.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcap.c,v 1.3 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: pcap.c,v 1.4 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
|
||||
@ -76,17 +76,56 @@ static const char rcsid[] _U_ =
|
||||
#include "pcap-int.h"
|
||||
|
||||
#ifdef HAVE_DAG_API
|
||||
#include <dagnew.h>
|
||||
#include <dagapi.h>
|
||||
#include "pcap-dag.h"
|
||||
#endif /* HAVE_DAG_API */
|
||||
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
#include "pcap-septel.h"
|
||||
#endif /* HAVE_SEPTEL_API */
|
||||
|
||||
#ifdef HAVE_SNF_API
|
||||
#include "pcap-snf.h"
|
||||
#endif /* HAVE_SNF_API */
|
||||
|
||||
#ifdef PCAP_SUPPORT_USB
|
||||
#include "pcap-usb-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_BT
|
||||
#include "pcap-bt-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_CAN
|
||||
#include "pcap-can-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_CANUSB
|
||||
#include "pcap-canusb-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_NETFILTER
|
||||
#include "pcap-netfilter-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_DBUS
|
||||
#include "pcap-dbus.h"
|
||||
#endif
|
||||
|
||||
int
|
||||
pcap_not_initialized(pcap_t *pcap)
|
||||
pcap_not_initialized(pcap_t *pcap _U_)
|
||||
{
|
||||
/* this means 'not initialized' */
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
Adapter *
|
||||
pcap_no_adapter(pcap_t *pcap _U_)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
|
||||
* a PCAP_ERROR value on an error.
|
||||
@ -161,7 +200,7 @@ pcap_free_tstamp_types(int *tstamp_type_list)
|
||||
* packet data cannot be guaranteed to be available after the callback
|
||||
* returns, so that a copy must be made.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt)
|
||||
{
|
||||
struct oneshot_userdata *sp = (struct oneshot_userdata *)user;
|
||||
@ -197,7 +236,7 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
|
||||
/* Saves a pointer to the packet headers */
|
||||
*pkt_header= &p->pcap_header;
|
||||
|
||||
if (p->sf.rfile != NULL) {
|
||||
if (p->rfile != NULL) {
|
||||
int status;
|
||||
|
||||
/* We are on an offline capture */
|
||||
@ -234,6 +273,176 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
|
||||
return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
|
||||
}
|
||||
|
||||
#if defined(DAG_ONLY)
|
||||
int
|
||||
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (dag_findalldevs(alldevsp, errbuf));
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create(const char *source, char *errbuf)
|
||||
{
|
||||
return (dag_create(source, errbuf));
|
||||
}
|
||||
#elif defined(SEPTEL_ONLY)
|
||||
int
|
||||
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (septel_findalldevs(alldevsp, errbuf));
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create(const char *source, char *errbuf)
|
||||
{
|
||||
return (septel_create(source, errbuf));
|
||||
}
|
||||
#elif defined(SNF_ONLY)
|
||||
int
|
||||
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
return (snf_findalldevs(alldevsp, errbuf));
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create(const char *source, char *errbuf)
|
||||
{
|
||||
return (snf_create(source, errbuf));
|
||||
}
|
||||
#else /* regular pcap */
|
||||
struct capture_source_type {
|
||||
int (*findalldevs_op)(pcap_if_t **, char *);
|
||||
pcap_t *(*create_op)(const char *, char *, int *);
|
||||
} capture_source_types[] = {
|
||||
#ifdef HAVE_DAG_API
|
||||
{ dag_findalldevs, dag_create },
|
||||
#endif
|
||||
#ifdef HAVE_SEPTEL_API
|
||||
{ septel_findalldevs, septel_create },
|
||||
#endif
|
||||
#ifdef HAVE_SNF_API
|
||||
{ snf_findalldevs, snf_create },
|
||||
#endif
|
||||
#ifdef PCAP_SUPPORT_BT
|
||||
{ bt_findalldevs, bt_create },
|
||||
#endif
|
||||
#if PCAP_SUPPORT_CANUSB
|
||||
{ canusb_findalldevs, canusb_create },
|
||||
#endif
|
||||
#ifdef PCAP_SUPPORT_CAN
|
||||
{ can_findalldevs, can_create },
|
||||
#endif
|
||||
#ifdef PCAP_SUPPORT_USB
|
||||
{ usb_findalldevs, usb_create },
|
||||
#endif
|
||||
#ifdef PCAP_SUPPORT_NETFILTER
|
||||
{ netfilter_findalldevs, netfilter_create },
|
||||
#endif
|
||||
#ifdef PCAP_SUPPORT_DBUS
|
||||
{ dbus_findalldevs, dbus_create },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* Get a list of all capture sources that are up and that we can open.
|
||||
* Returns -1 on error, 0 otherwise.
|
||||
* The list, as returned through "alldevsp", may be null if no interfaces
|
||||
* were up and could be opened.
|
||||
*/
|
||||
int
|
||||
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Get the list of regular interfaces first.
|
||||
*/
|
||||
if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
|
||||
return (-1); /* failure */
|
||||
|
||||
/*
|
||||
* Add any interfaces that need a platform-specific mechanism
|
||||
* to find.
|
||||
*/
|
||||
if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
|
||||
/*
|
||||
* We had an error; free the list we've been
|
||||
* constructing.
|
||||
*/
|
||||
if (*alldevsp != NULL) {
|
||||
pcap_freealldevs(*alldevsp);
|
||||
*alldevsp = NULL;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask each of the non-local-network-interface capture
|
||||
* source types what interfaces they have.
|
||||
*/
|
||||
for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) {
|
||||
if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
|
||||
/*
|
||||
* We had an error; free the list we've been
|
||||
* constructing.
|
||||
*/
|
||||
if (*alldevsp != NULL) {
|
||||
pcap_freealldevs(*alldevsp);
|
||||
*alldevsp = NULL;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create(const char *source, char *errbuf)
|
||||
{
|
||||
size_t i;
|
||||
int is_theirs;
|
||||
pcap_t *p;
|
||||
|
||||
/*
|
||||
* A null source 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";
|
||||
|
||||
/*
|
||||
* Try each of the non-local-network-interface capture
|
||||
* source types until we find one that works for this
|
||||
* device or run out of types.
|
||||
*/
|
||||
for (i = 0; capture_source_types[i].create_op != NULL; i++) {
|
||||
is_theirs = 0;
|
||||
p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
|
||||
if (is_theirs) {
|
||||
/*
|
||||
* The device name refers to a device of the
|
||||
* type in question; either it succeeded,
|
||||
* in which case p refers to a pcap_t to
|
||||
* later activate for the device, or it
|
||||
* failed, in which case p is null and we
|
||||
* should return that to report the failure
|
||||
* to create.
|
||||
*/
|
||||
return (p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, try it as a regular network interface.
|
||||
*/
|
||||
return (pcap_create_interface(source, errbuf));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
initialize_ops(pcap_t *p)
|
||||
{
|
||||
@ -254,6 +463,7 @@ initialize_ops(pcap_t *p)
|
||||
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->getadapter_op = pcap_no_adapter;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -264,30 +474,65 @@ initialize_ops(pcap_t *p)
|
||||
p->cleanup_op = pcap_cleanup_live_common;
|
||||
|
||||
/*
|
||||
* In most cases, the standard one-short callback can
|
||||
* In most cases, the standard one-shot callback can
|
||||
* be used for pcap_next()/pcap_next_ex().
|
||||
*/
|
||||
p->oneshot_callback = pcap_oneshot;
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_common(const char *source, char *ebuf)
|
||||
static pcap_t *
|
||||
pcap_alloc_pcap_t(char *ebuf, size_t size)
|
||||
{
|
||||
char *chunk;
|
||||
pcap_t *p;
|
||||
|
||||
p = malloc(sizeof(*p));
|
||||
if (p == NULL) {
|
||||
/*
|
||||
* Allocate a chunk of memory big enough for a pcap_t
|
||||
* 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.
|
||||
*/
|
||||
chunk = malloc(sizeof (pcap_t) + size);
|
||||
if (chunk == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
return (NULL);
|
||||
}
|
||||
memset(p, 0, sizeof(*p));
|
||||
memset(chunk, 0, sizeof (pcap_t) + size);
|
||||
|
||||
/*
|
||||
* Get a pointer to the pcap_t at the beginning.
|
||||
*/
|
||||
p = (pcap_t *)chunk;
|
||||
|
||||
#ifndef WIN32
|
||||
p->fd = -1; /* not opened yet */
|
||||
p->selectable_fd = -1;
|
||||
p->send_fd = -1;
|
||||
#endif
|
||||
|
||||
if (size == 0) {
|
||||
/* No private data was requested. */
|
||||
p->priv = NULL;
|
||||
} else {
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_create_common(const char *source, char *ebuf, size_t size)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_alloc_pcap_t(ebuf, size);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
p->opt.source = strdup(source);
|
||||
if (p->opt.source == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
@ -307,11 +552,14 @@ pcap_create_common(const char *source, char *ebuf)
|
||||
initialize_ops(p);
|
||||
|
||||
/* put in some defaults*/
|
||||
pcap_set_timeout(p, 0);
|
||||
pcap_set_snaplen(p, 65535); /* max packet size */
|
||||
pcap_set_snaplen(p, 65535); /* max packet size */
|
||||
p->opt.timeout = 0; /* no timeout specified */
|
||||
p->opt.buffer_size = 0; /* use the platform's default */
|
||||
p->opt.promisc = 0;
|
||||
p->opt.buffer_size = 0;
|
||||
p->opt.rfmon = 0;
|
||||
p->opt.immediate = 0;
|
||||
p->opt.tstamp_type = -1; /* default to not setting time stamp type */
|
||||
p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
|
||||
return (p);
|
||||
}
|
||||
|
||||
@ -358,7 +606,7 @@ pcap_set_timeout(pcap_t *p, int timeout_ms)
|
||||
{
|
||||
if (pcap_check_activated(p))
|
||||
return (PCAP_ERROR_ACTIVATED);
|
||||
p->md.timeout = timeout_ms;
|
||||
p->opt.timeout = timeout_ms;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -371,32 +619,44 @@ pcap_set_tstamp_type(pcap_t *p, int tstamp_type)
|
||||
return (PCAP_ERROR_ACTIVATED);
|
||||
|
||||
/*
|
||||
* If p->tstamp_type_count is 0, we don't support setting
|
||||
* the time stamp type at all.
|
||||
* If p->tstamp_type_count is 0, we only support PCAP_TSTAMP_HOST;
|
||||
* the default time stamp type is PCAP_TSTAMP_HOST.
|
||||
*/
|
||||
if (p->tstamp_type_count == 0)
|
||||
return (PCAP_ERROR_CANTSET_TSTAMP_TYPE);
|
||||
|
||||
/*
|
||||
* Check whether we claim to support this type of time stamp.
|
||||
*/
|
||||
for (i = 0; i < p->tstamp_type_count; i++) {
|
||||
if ((int)p->tstamp_type_list[i] == tstamp_type) {
|
||||
/*
|
||||
* Yes.
|
||||
*/
|
||||
if (p->tstamp_type_count == 0) {
|
||||
if (tstamp_type == PCAP_TSTAMP_HOST) {
|
||||
p->opt.tstamp_type = tstamp_type;
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Check whether we claim to support this type of time stamp.
|
||||
*/
|
||||
for (i = 0; i < p->tstamp_type_count; i++) {
|
||||
if (p->tstamp_type_list[i] == (u_int)tstamp_type) {
|
||||
/*
|
||||
* Yes.
|
||||
*/
|
||||
p->opt.tstamp_type = tstamp_type;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No. We support setting the time stamp type, but not to this
|
||||
* particular value.
|
||||
* We don't support this type of time stamp.
|
||||
*/
|
||||
return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_set_immediate_mode(pcap_t *p, int immediate)
|
||||
{
|
||||
if (pcap_check_activated(p))
|
||||
return (PCAP_ERROR_ACTIVATED);
|
||||
p->opt.immediate = immediate;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_set_buffer_size(pcap_t *p, int buffer_size)
|
||||
{
|
||||
@ -406,6 +666,54 @@ pcap_set_buffer_size(pcap_t *p, int buffer_size)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pcap_check_activated(p))
|
||||
return (PCAP_ERROR_ACTIVATED);
|
||||
|
||||
/*
|
||||
* If p->tstamp_precision_count is 0, we only support setting
|
||||
* the time stamp precision to microsecond precision; every
|
||||
* pcap module *MUST* support microsecond precision, even if
|
||||
* it does so by converting the native precision to
|
||||
* microseconds.
|
||||
*/
|
||||
if (p->tstamp_precision_count == 0) {
|
||||
if (tstamp_precision == PCAP_TSTAMP_PRECISION_MICRO) {
|
||||
p->opt.tstamp_precision = tstamp_precision;
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Check whether we claim to support this precision of
|
||||
* time stamp.
|
||||
*/
|
||||
for (i = 0; i < p->tstamp_precision_count; i++) {
|
||||
if (p->tstamp_precision_list[i] == (u_int)tstamp_precision) {
|
||||
/*
|
||||
* Yes.
|
||||
*/
|
||||
p->opt.tstamp_precision = tstamp_precision;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't support this time stamp precision.
|
||||
*/
|
||||
return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_get_tstamp_precision(pcap_t *p)
|
||||
{
|
||||
return (p->opt.tstamp_precision);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_activate(pcap_t *p)
|
||||
{
|
||||
@ -493,6 +801,27 @@ fail:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_open_offline_common(char *ebuf, size_t size)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_alloc_pcap_t(ebuf, size);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
|
||||
p->opt.source = strdup("(savefile)");
|
||||
if (p->opt.source == NULL) {
|
||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
|
||||
pcap_strerror(errno));
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
{
|
||||
@ -515,7 +844,7 @@ pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
register int n;
|
||||
|
||||
for (;;) {
|
||||
if (p->sf.rfile != NULL) {
|
||||
if (p->rfile != NULL) {
|
||||
/*
|
||||
* 0 means EOF, so don't loop if we get 0.
|
||||
*/
|
||||
@ -551,18 +880,24 @@ pcap_breakloop(pcap_t *p)
|
||||
int
|
||||
pcap_datalink(pcap_t *p)
|
||||
{
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
return (p->linktype);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_datalink_ext(pcap_t *p)
|
||||
{
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
return (p->linktype_ext);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
|
||||
{
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
if (p->dlt_count == 0) {
|
||||
/*
|
||||
* We couldn't fetch the list of DLTs, which means
|
||||
@ -574,7 +909,7 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
|
||||
if (*dlt_buffer == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
**dlt_buffer = p->linktype;
|
||||
return (1);
|
||||
@ -583,7 +918,7 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
|
||||
if (*dlt_buffer == NULL) {
|
||||
(void)snprintf(p->errbuf, sizeof(p->errbuf),
|
||||
"malloc: %s", pcap_strerror(errno));
|
||||
return (-1);
|
||||
return (PCAP_ERROR);
|
||||
}
|
||||
(void)memcpy(*dlt_buffer, p->dlt_list,
|
||||
sizeof(**dlt_buffer) * p->dlt_count);
|
||||
@ -811,6 +1146,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
|
||||
DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
|
||||
DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
|
||||
DLT_CHOICE(DLT_BACNET_MS_TP, "BACnet MS/TP"),
|
||||
DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
|
||||
DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
|
||||
DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
|
||||
@ -868,6 +1204,7 @@ static struct dlt_choice dlt_choices[] = {
|
||||
DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
|
||||
DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
|
||||
DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
|
||||
DLT_CHOICE(DLT_DBUS, "D-Bus"),
|
||||
DLT_CHOICE_SENTINEL
|
||||
};
|
||||
|
||||
@ -962,31 +1299,39 @@ pcap_tstamp_type_val_to_description(int tstamp_type)
|
||||
int
|
||||
pcap_snapshot(pcap_t *p)
|
||||
{
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
return (p->snapshot);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_is_swapped(pcap_t *p)
|
||||
{
|
||||
return (p->sf.swapped);
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
return (p->swapped);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_major_version(pcap_t *p)
|
||||
{
|
||||
return (p->sf.version_major);
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
return (p->version_major);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_minor_version(pcap_t *p)
|
||||
{
|
||||
return (p->sf.version_minor);
|
||||
if (!p->activated)
|
||||
return (PCAP_ERROR_NOT_ACTIVATED);
|
||||
return (p->version_minor);
|
||||
}
|
||||
|
||||
FILE *
|
||||
pcap_file(pcap_t *p)
|
||||
{
|
||||
return (p->sf.rfile);
|
||||
return (p->rfile);
|
||||
}
|
||||
|
||||
int
|
||||
@ -998,7 +1343,7 @@ pcap_fileno(pcap_t *p)
|
||||
if (p->adapter != NULL)
|
||||
return ((int)(DWORD)p->adapter->hFile);
|
||||
else
|
||||
return (-1);
|
||||
return (PCAP_ERROR);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1025,7 +1370,18 @@ pcap_geterr(pcap_t *p)
|
||||
int
|
||||
pcap_getnonblock(pcap_t *p, char *errbuf)
|
||||
{
|
||||
return (p->getnonblock_op(p, errbuf));
|
||||
int ret;
|
||||
|
||||
ret = p->getnonblock_op(p, errbuf);
|
||||
if (ret == -1) {
|
||||
/*
|
||||
* In case somebody depended on the bug wherein
|
||||
* the error message was put into p->errbuf
|
||||
* by pcap_getnonblock_fd().
|
||||
*/
|
||||
strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1043,7 +1399,7 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
|
||||
|
||||
fdflags = fcntl(p->fd, F_GETFL, 0);
|
||||
if (fdflags == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -1057,7 +1413,18 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
|
||||
int
|
||||
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
||||
{
|
||||
return (p->setnonblock_op(p, nonblock, errbuf));
|
||||
int ret;
|
||||
|
||||
ret = p->setnonblock_op(p, nonblock, errbuf);
|
||||
if (ret == -1) {
|
||||
/*
|
||||
* In case somebody depended on the bug wherein
|
||||
* the error message was put into p->errbuf
|
||||
* by pcap_setnonblock_fd().
|
||||
*/
|
||||
strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
@ -1074,7 +1441,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
|
||||
|
||||
fdflags = fcntl(p->fd, F_GETFL, 0);
|
||||
if (fdflags == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -1083,7 +1450,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
|
||||
else
|
||||
fdflags &= ~O_NONBLOCK;
|
||||
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
@ -1175,6 +1542,9 @@ pcap_statustostr(int errnum)
|
||||
|
||||
case PCAP_ERROR_PROMISC_PERM_DENIED:
|
||||
return ("You don't have permission to capture in promiscuous mode on that device");
|
||||
|
||||
case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP:
|
||||
return ("That device doesn't support that time stamp precision");
|
||||
}
|
||||
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
|
||||
return(ebuf);
|
||||
@ -1272,6 +1642,12 @@ pcap_setmintocopy(pcap_t *p, int size)
|
||||
return (p->setmintocopy_op(p, size));
|
||||
}
|
||||
|
||||
Adapter *
|
||||
pcap_get_adapter(pcap_t *p)
|
||||
{
|
||||
return (p->getadapter_op(p));
|
||||
}
|
||||
|
||||
static int
|
||||
pcap_setmintocopy_dead(pcap_t *p, int size)
|
||||
{
|
||||
@ -1339,7 +1715,7 @@ pcap_do_addexit(pcap_t *p)
|
||||
void
|
||||
pcap_add_to_pcaps_to_close(pcap_t *p)
|
||||
{
|
||||
p->md.next = pcaps_to_close;
|
||||
p->next = pcaps_to_close;
|
||||
pcaps_to_close = p;
|
||||
}
|
||||
|
||||
@ -1349,7 +1725,7 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
|
||||
pcap_t *pc, *prevpc;
|
||||
|
||||
for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
|
||||
prevpc = pc, pc = pc->md.next) {
|
||||
prevpc = pc, pc = pc->next) {
|
||||
if (pc == p) {
|
||||
/*
|
||||
* Found it. Remove it from the list.
|
||||
@ -1358,12 +1734,12 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
|
||||
/*
|
||||
* It was at the head of the list.
|
||||
*/
|
||||
pcaps_to_close = pc->md.next;
|
||||
pcaps_to_close = pc->next;
|
||||
} else {
|
||||
/*
|
||||
* It was in the middle of the list.
|
||||
*/
|
||||
prevpc->md.next = pc->md.next;
|
||||
prevpc->next = pc->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1387,6 +1763,11 @@ pcap_cleanup_live_common(pcap_t *p)
|
||||
p->tstamp_type_list = NULL;
|
||||
p->tstamp_type_count = 0;
|
||||
}
|
||||
if (p->tstamp_precision_list != NULL) {
|
||||
free(p->tstamp_precision_list);
|
||||
p->tstamp_precision_list = NULL;
|
||||
p->tstamp_precision_count = 0;
|
||||
}
|
||||
pcap_freecode(&p->fcode);
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
if (p->fd >= 0) {
|
||||
@ -1394,7 +1775,6 @@ pcap_cleanup_live_common(pcap_t *p)
|
||||
p->fd = -1;
|
||||
}
|
||||
p->selectable_fd = -1;
|
||||
p->send_fd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1405,16 +1785,26 @@ pcap_cleanup_dead(pcap_t *p _U_)
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_open_dead(int linktype, int snaplen)
|
||||
pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
switch (precision) {
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_MICRO:
|
||||
case PCAP_TSTAMP_PRECISION_NANO:
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
p = malloc(sizeof(*p));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
memset (p, 0, sizeof(*p));
|
||||
p->snapshot = snaplen;
|
||||
p->linktype = linktype;
|
||||
p->opt.tstamp_precision = precision;
|
||||
p->stats_op = pcap_stats_dead;
|
||||
#ifdef WIN32
|
||||
p->setbuff_op = pcap_setbuff_dead;
|
||||
@ -1426,6 +1816,13 @@ pcap_open_dead(int linktype, int snaplen)
|
||||
return (p);
|
||||
}
|
||||
|
||||
pcap_t *
|
||||
pcap_open_dead(int linktype, int snaplen)
|
||||
{
|
||||
return (pcap_open_dead_with_tstamp_precision(linktype, snaplen,
|
||||
PCAP_TSTAMP_PRECISION_MICRO));
|
||||
}
|
||||
|
||||
/*
|
||||
* API compatible with WinPcap's "send a packet" routine - returns -1
|
||||
* on error, 0 otherwise.
|
||||
@ -1466,10 +1863,10 @@ pcap_close(pcap_t *p)
|
||||
* the packet doesn't pass and non-zero if the packet does pass.
|
||||
*/
|
||||
int
|
||||
pcap_offline_filter(struct bpf_program *fp, const struct pcap_pkthdr *h,
|
||||
pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
|
||||
const u_char *pkt)
|
||||
{
|
||||
struct bpf_insn *fcode = fp->bf_insns;
|
||||
const struct bpf_insn *fcode = fp->bf_insns;
|
||||
|
||||
if (fcode != NULL)
|
||||
return (bpf_filter(fcode, pkt, h->len, h->caplen));
|
||||
@ -1531,6 +1928,8 @@ pcap_lib_version(void)
|
||||
strlen(pcap_version_string);
|
||||
full_pcap_version_string =
|
||||
malloc(full_pcap_version_string_len);
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
sprintf(full_pcap_version_string,
|
||||
pcap_version_string_fmt, wpcap_version_string,
|
||||
pcap_version_string);
|
||||
@ -1548,7 +1947,8 @@ pcap_lib_version(void)
|
||||
strlen(packet_version_string) +
|
||||
strlen(pcap_version_string);
|
||||
full_pcap_version_string = malloc(full_pcap_version_string_len);
|
||||
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
sprintf(full_pcap_version_string,
|
||||
pcap_version_string_packet_dll_fmt,
|
||||
wpcap_version_string, packet_version_string,
|
||||
@ -1577,6 +1977,8 @@ pcap_lib_version (void)
|
||||
sizeof dospfx + strlen(pcap_version_string);
|
||||
full_pcap_version_string =
|
||||
malloc(full_pcap_version_string_len);
|
||||
if (full_pcap_version_string == NULL)
|
||||
return (NULL);
|
||||
strcpy(full_pcap_version_string, dospfx);
|
||||
strcat(full_pcap_version_string, pcap_version_string);
|
||||
}
|
||||
|
55
external/bsd/libpcap/dist/pcap/bpf.h
vendored
55
external/bsd/libpcap/dist/pcap/bpf.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bpf.h,v 1.4 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: bpf.h,v 1.5 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||
@ -1138,7 +1138,7 @@ struct bpf_program {
|
||||
#define DLT_NETANALYZER_TRANSPARENT 241
|
||||
|
||||
/*
|
||||
* IP-over-Infiniband, as specified by RFC 4391.
|
||||
* IP-over-InfiniBand, as specified by RFC 4391.
|
||||
*
|
||||
* Requested by Petr Sumbera <petr.sumbera@oracle.com>.
|
||||
*/
|
||||
@ -1180,7 +1180,56 @@ struct bpf_program {
|
||||
#define DLT_PFSYNC 246
|
||||
#endif
|
||||
|
||||
#define DLT_MATCHING_MAX 246 /* highest value in the "matching" range */
|
||||
/*
|
||||
* Raw InfiniBand packets, starting with the Local Routing Header.
|
||||
*
|
||||
* Requested by Oren Kladnitsky <orenk@mellanox.com>.
|
||||
*/
|
||||
#define DLT_INFINIBAND 247
|
||||
|
||||
/*
|
||||
* SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
|
||||
*
|
||||
* Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
|
||||
*/
|
||||
#define DLT_SCTP 248
|
||||
|
||||
/*
|
||||
* USB packets, beginning with a USBPcap header.
|
||||
*
|
||||
* Requested by Tomasz Mon <desowin@gmail.com>
|
||||
*/
|
||||
#define DLT_USBPCAP 249
|
||||
|
||||
/*
|
||||
* Schweitzer Engineering Laboratories "RTAC" product serial-line
|
||||
* packets.
|
||||
*
|
||||
* Requested by Chris Bontje <chris_bontje@selinc.com>.
|
||||
*/
|
||||
#define DLT_RTAC_SERIAL 250
|
||||
|
||||
/*
|
||||
* Bluetooth Low Energy air interface link-layer packets.
|
||||
*
|
||||
* Requested by Mike Kershaw <dragorn@kismetwireless.net>.
|
||||
*/
|
||||
#define DLT_BLUETOOTH_LE_LL 251
|
||||
|
||||
/*
|
||||
* DLT 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.
|
||||
*
|
||||
* EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector
|
||||
* that can make sense of the data stored.
|
||||
*/
|
||||
#define DLT_WIRESHARK_UPPER_PDU 252
|
||||
|
||||
#define DLT_MATCHING_MAX 252 /* highest value in the "matching" range */
|
||||
|
||||
/*
|
||||
* DLT and savefile link type values are split into a class and
|
||||
|
36
external/bsd/libpcap/dist/pcap/pcap.h
vendored
36
external/bsd/libpcap/dist/pcap/pcap.h
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pcap.h,v 1.3 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: pcap.h,v 1.4 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||
/*
|
||||
@ -117,12 +117,13 @@ typedef struct pcap_addr pcap_addr_t;
|
||||
* the old file header as well as files with the new file header
|
||||
* (using the magic number to determine the header format).
|
||||
*
|
||||
* Then supply the changes as a patch at
|
||||
* Then supply the changes by forking the branch at
|
||||
*
|
||||
* http://sourceforge.net/projects/libpcap/
|
||||
* https://github.com/the-tcpdump-group/libpcap/issues
|
||||
*
|
||||
* so that future versions of libpcap and programs that use it (such as
|
||||
* tcpdump) will be able to read your new capture file format.
|
||||
* and issuing a pull request, so that future versions of libpcap and
|
||||
* programs that use it (such as tcpdump) will be able to read your new
|
||||
* capture file format.
|
||||
*/
|
||||
struct pcap_file_header {
|
||||
bpf_u_int32 magic;
|
||||
@ -257,6 +258,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
||||
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
|
||||
#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
|
||||
#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
|
||||
#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 /* the requested time stamp precision is not supported */
|
||||
|
||||
/*
|
||||
* Warning codes for the pcap API.
|
||||
@ -283,7 +285,10 @@ int pcap_can_set_rfmon(pcap_t *);
|
||||
int pcap_set_rfmon(pcap_t *, int);
|
||||
int pcap_set_timeout(pcap_t *, int);
|
||||
int pcap_set_tstamp_type(pcap_t *, int);
|
||||
int pcap_set_immediate_mode(pcap_t *, int);
|
||||
int pcap_set_buffer_size(pcap_t *, int);
|
||||
int pcap_set_tstamp_precision(pcap_t *, int);
|
||||
int pcap_get_tstamp_precision(pcap_t *);
|
||||
int pcap_activate(pcap_t *);
|
||||
|
||||
int pcap_list_tstamp_types(pcap_t *, int **);
|
||||
@ -336,18 +341,34 @@ const char *pcap_tstamp_type_val_to_description(int);
|
||||
#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */
|
||||
#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */
|
||||
|
||||
/*
|
||||
* Time stamp resolution types.
|
||||
* Not all systems and interfaces will necessarily support all of these
|
||||
* resolutions when doing live captures; all of them can be requested
|
||||
* when reading a savefile.
|
||||
*/
|
||||
#define PCAP_TSTAMP_PRECISION_MICRO 0 /* use timestamps with microsecond precision, default */
|
||||
#define PCAP_TSTAMP_PRECISION_NANO 1 /* use timestamps with nanosecond precision */
|
||||
|
||||
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||
pcap_t *pcap_open_dead(int, int);
|
||||
pcap_t *pcap_open_dead_with_tstamp_precision(int, int, u_int);
|
||||
pcap_t *pcap_open_offline_with_tstamp_precision(const char *, u_int, char *);
|
||||
pcap_t *pcap_open_offline(const char *, char *);
|
||||
#if defined(WIN32)
|
||||
pcap_t *pcap_hopen_offline_with_tstamp_precision(intptr_t, u_int, char *);
|
||||
pcap_t *pcap_hopen_offline(intptr_t, char *);
|
||||
#if !defined(LIBPCAP_EXPORTS)
|
||||
#define pcap_fopen_offline_with_tstamp_precision(f,p,b) \
|
||||
pcap_hopen_offline_with_tstamp_precision(_get_osfhandle(_fileno(f)), p, b)
|
||||
#define pcap_fopen_offline(f,b) \
|
||||
pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
|
||||
#else /*LIBPCAP_EXPORTS*/
|
||||
static pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *);
|
||||
static pcap_t *pcap_fopen_offline(FILE *, char *);
|
||||
#endif
|
||||
#else /*WIN32*/
|
||||
pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *);
|
||||
pcap_t *pcap_fopen_offline(FILE *, char *);
|
||||
#endif /*WIN32*/
|
||||
|
||||
@ -374,8 +395,8 @@ int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
|
||||
int pcap_compile_nopcap(int, int, struct bpf_program *,
|
||||
const char *, int, bpf_u_int32);
|
||||
void pcap_freecode(struct bpf_program *);
|
||||
int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
|
||||
const u_char *);
|
||||
int pcap_offline_filter(const struct bpf_program *,
|
||||
const struct pcap_pkthdr *, const u_char *);
|
||||
int pcap_datalink(pcap_t *);
|
||||
int pcap_datalink_ext(pcap_t *);
|
||||
int pcap_list_datalinks(pcap_t *, int **);
|
||||
@ -429,6 +450,7 @@ void bpf_dump(const struct bpf_program *, int);
|
||||
int pcap_setbuff(pcap_t *p, int dim);
|
||||
int pcap_setmode(pcap_t *p, int mode);
|
||||
int pcap_setmintocopy(pcap_t *p, int size);
|
||||
Adapter *pcap_get_adapter(pcap_t *p);
|
||||
|
||||
#ifdef WPCAP
|
||||
/* Include file with the wpcap-specific extensions */
|
||||
|
@ -19,9 +19,10 @@
|
||||
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.\"
|
||||
.TH PCAP_OPEN_OFFLINE 3PCAP "5 April 2008"
|
||||
.TH PCAP_OPEN_OFFLINE 3PCAP "1 July 2013"
|
||||
.SH NAME
|
||||
pcap_open_offline, pcap_fopen_offline \- open a saved capture file for reading
|
||||
pcap_open_offline, pcap_open_offline_with_tstamp_precision,
|
||||
pcap_fopen_offline, pcap_fopen_offline_with_tstamp_precision \- open a saved capture file for reading
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
.ft B
|
||||
@ -35,12 +36,18 @@ char errbuf[PCAP_ERRBUF_SIZE];
|
||||
.LP
|
||||
.ft B
|
||||
pcap_t *pcap_open_offline(const char *fname, char *errbuf);
|
||||
pcap_t *pcap_open_offline_with_tstamp_precision(const char *fname,
|
||||
u_int precision, char *errbuf);
|
||||
pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf);
|
||||
pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *fp,
|
||||
u_int precision, char *errbuf);
|
||||
.ft
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.B pcap_open_offline()
|
||||
is called to open a ``savefile'' for reading.
|
||||
and
|
||||
.B pcap_open_offline_with_tstamp_precision()
|
||||
are called to open a ``savefile'' for reading.
|
||||
.PP
|
||||
.I fname
|
||||
specifies the name of the file to open. The file can have the pcap file
|
||||
@ -55,15 +62,37 @@ be read.
|
||||
The name "-" in a synonym for
|
||||
.BR stdin .
|
||||
.PP
|
||||
.B pcap_open_offline_with_tstamp_precision()
|
||||
takes an additional
|
||||
.I precision
|
||||
argument specifying the time stamp precision desired;
|
||||
if
|
||||
.B PCAP_TSTAMP_PRECISION_MICRO
|
||||
is specified, packet time stamps will be supplied in seconds and
|
||||
microseconds,
|
||||
and if
|
||||
.B PCAP_TSTAMP_PRECISION_NANO
|
||||
is specified, packet time stamps will be supplied in seconds and
|
||||
nanoseconds. If the time stamps in the file do not have the same
|
||||
precision as the requested precision, they will be scaled up or down as
|
||||
necessary before being supplied.
|
||||
.PP
|
||||
Alternatively, you may call
|
||||
.B pcap_fopen_offline()
|
||||
or
|
||||
.B pcap_fopen_offline_with_tstamp_precision()
|
||||
to read dumped data from an existing open stream
|
||||
.IR fp .
|
||||
.B pcap_fopen_offline_with_tstamp_precision() takes an additional
|
||||
.I precision
|
||||
argument as described above.
|
||||
Note that on Windows, that stream should be opened in binary mode.
|
||||
.SH RETURN VALUE
|
||||
.B pcap_open_offline()
|
||||
.BR pcap_open_offline() ,
|
||||
.BR pcap_open_offline_with_tstamp_precision() ,
|
||||
.BR pcap_fopen_offline() ,
|
||||
and
|
||||
.B pcap_fopen_offline()
|
||||
.B pcap_fopen_offline_with_tstamp_precision()
|
||||
return a
|
||||
.I pcap_t *
|
||||
on success and
|
||||
|
29
external/bsd/libpcap/dist/scanner.l
vendored
29
external/bsd/libpcap/dist/scanner.l
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: scanner.l,v 1.4 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: scanner.l,v 1.5 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
%{
|
||||
/*
|
||||
@ -210,20 +210,8 @@ vrrp return VRRP;
|
||||
carp return CARP;
|
||||
radio return RADIO;
|
||||
|
||||
ip6 {
|
||||
#ifdef INET6
|
||||
return IPV6;
|
||||
#else
|
||||
bpf_error("%s not supported", yytext);
|
||||
#endif
|
||||
}
|
||||
icmp6 {
|
||||
#ifdef INET6
|
||||
return ICMPV6;
|
||||
#else
|
||||
bpf_error("%s not supported", yytext);
|
||||
#endif
|
||||
}
|
||||
ip6 return IPV6;
|
||||
icmp6 return ICMPV6;
|
||||
ah return AH;
|
||||
esp return ESP;
|
||||
|
||||
@ -327,10 +315,17 @@ fisu return FISU;
|
||||
lssu return LSSU;
|
||||
lsu return LSSU;
|
||||
msu return MSU;
|
||||
hfisu return HFISU;
|
||||
hlssu return HLSSU;
|
||||
hmsu return HMSU;
|
||||
sio return SIO;
|
||||
opc return OPC;
|
||||
dpc return DPC;
|
||||
sls return SLS;
|
||||
hsio return HSIO;
|
||||
hopc return HOPC;
|
||||
hdpc return HDPC;
|
||||
hsls return HSLS;
|
||||
|
||||
[ \r\n\t] ;
|
||||
[+\-*/:\[\]!<>()&|=] return yytext[0];
|
||||
@ -341,8 +336,12 @@ sls return SLS;
|
||||
"<<" return LSH;
|
||||
">>" return RSH;
|
||||
${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
|
||||
if (yylval.e == NULL)
|
||||
bpf_error("malloc");
|
||||
return AID; }
|
||||
{MAC} { yylval.e = pcap_ether_aton((char *)yytext);
|
||||
if (yylval.e == NULL)
|
||||
bpf_error("malloc");
|
||||
return EID; }
|
||||
{N} { yylval.i = stoi((char *)yytext); return NUM; }
|
||||
({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
|
||||
|
394
external/bsd/libpcap/dist/sf-pcap-ng.c
vendored
394
external/bsd/libpcap/dist/sf-pcap-ng.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sf-pcap-ng.c,v 1.3 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: sf-pcap-ng.c,v 1.4 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
@ -203,6 +203,29 @@ struct block_cursor {
|
||||
bpf_u_int32 block_type;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
PASS_THROUGH,
|
||||
SCALE_UP,
|
||||
SCALE_DOWN
|
||||
} tstamp_scale_type_t;
|
||||
|
||||
/*
|
||||
* Per-interface information.
|
||||
*/
|
||||
struct pcap_ng_if {
|
||||
u_int tsresol; /* time stamp resolution */
|
||||
u_int64_t tsoffset; /* time stamp offset */
|
||||
tstamp_scale_type_t scale_type; /* how to scale */
|
||||
};
|
||||
|
||||
struct pcap_ng_sf {
|
||||
u_int user_tsresol; /* time stamp resolution requested by the user */
|
||||
bpf_u_int32 ifcount; /* number of interfaces seen in this capture */
|
||||
bpf_u_int32 ifaces_size; /* size of arrary below */
|
||||
struct pcap_ng_if *ifaces; /* array of interface information */
|
||||
};
|
||||
|
||||
static void pcap_ng_cleanup(pcap_t *p);
|
||||
static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
|
||||
u_char **data);
|
||||
|
||||
@ -241,7 +264,7 @@ read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
if (status <= 0)
|
||||
return (status); /* error or EOF */
|
||||
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
bhdr.block_type = SWAPLONG(bhdr.block_type);
|
||||
bhdr.total_length = SWAPLONG(bhdr.total_length);
|
||||
}
|
||||
@ -348,7 +371,7 @@ get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
/*
|
||||
* Byte-swap it if necessary.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
opthdr->option_code = SWAPSHORT(opthdr->option_code);
|
||||
opthdr->option_length = SWAPSHORT((uint32_t)opthdr->option_length);
|
||||
}
|
||||
@ -483,7 +506,7 @@ process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
|
||||
}
|
||||
saw_tsoffset = 1;
|
||||
memcpy(tsoffset, optvalue, sizeof(*tsoffset));
|
||||
if (p->sf.swapped)
|
||||
if (p->swapped)
|
||||
*tsoffset = (uint64_t)SWAPLL(*tsoffset);
|
||||
break;
|
||||
|
||||
@ -496,22 +519,151 @@ done:
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
{
|
||||
struct pcap_ng_sf *ps;
|
||||
u_int tsresol;
|
||||
u_int64_t tsoffset;
|
||||
|
||||
ps = p->priv;
|
||||
|
||||
/*
|
||||
* Count this interface.
|
||||
*/
|
||||
ps->ifcount++;
|
||||
|
||||
/*
|
||||
* Grow the array of per-interface information as necessary.
|
||||
*/
|
||||
if (ps->ifcount > ps->ifaces_size) {
|
||||
/*
|
||||
* We need to grow the array.
|
||||
*/
|
||||
if (ps->ifaces == NULL) {
|
||||
/*
|
||||
* It's currently empty.
|
||||
*/
|
||||
ps->ifaces_size = 1;
|
||||
ps->ifaces = malloc(sizeof (struct pcap_ng_if));
|
||||
} else {
|
||||
/*
|
||||
* It's not currently empty; double its size.
|
||||
* (Perhaps overkill once we have a lot of interfaces.)
|
||||
*/
|
||||
ps->ifaces_size *= 2;
|
||||
ps->ifaces = realloc(ps->ifaces, ps->ifaces_size * sizeof (struct pcap_ng_if));
|
||||
}
|
||||
if (ps->ifaces == NULL) {
|
||||
/*
|
||||
* We ran out of memory.
|
||||
* Give up.
|
||||
*/
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"out of memory for per-interface information (%u interfaces)",
|
||||
ps->ifcount);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the default time stamp resolution and offset.
|
||||
*/
|
||||
tsresol = 1000000; /* microsecond resolution */
|
||||
tsoffset = 0; /* absolute timestamps */
|
||||
|
||||
/*
|
||||
* Now look for various time stamp options, so we know
|
||||
* how to interpret the time stamps for this interface.
|
||||
*/
|
||||
if (process_idb_options(p, cursor, &tsresol, &tsoffset, errbuf) == -1)
|
||||
return (0);
|
||||
|
||||
ps->ifaces[ps->ifcount - 1].tsresol = tsresol;
|
||||
ps->ifaces[ps->ifcount - 1].tsoffset = tsoffset;
|
||||
|
||||
/*
|
||||
* Determine whether we're scaling up or down or not
|
||||
* at all for this interface.
|
||||
*/
|
||||
switch (p->opt.tstamp_precision) {
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_MICRO:
|
||||
if (tsresol == 1000000) {
|
||||
/*
|
||||
* The resolution is 1 microsecond,
|
||||
* so we don't have to do scaling.
|
||||
*/
|
||||
ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH;
|
||||
} else if (tsresol > 1000000) {
|
||||
/*
|
||||
* The resolution is greater than
|
||||
* 1 microsecond, so we have to
|
||||
* scale the timestamps down.
|
||||
*/
|
||||
ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN;
|
||||
} else {
|
||||
/*
|
||||
* The resolution is less than 1
|
||||
* microsecond, so we have to scale
|
||||
* the timestamps up.
|
||||
*/
|
||||
ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP;
|
||||
}
|
||||
break;
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_NANO:
|
||||
if (tsresol == 1000000000) {
|
||||
/*
|
||||
* The resolution is 1 nanosecond,
|
||||
* so we don't have to do scaling.
|
||||
*/
|
||||
ps->ifaces[ps->ifcount - 1].scale_type = PASS_THROUGH;
|
||||
} else if (tsresol > 1000000000) {
|
||||
/*
|
||||
* The resolution is greater than
|
||||
* 1 nanosecond, so we have to
|
||||
* scale the timestamps down.
|
||||
*/
|
||||
ps->ifaces[ps->ifcount - 1].scale_type = SCALE_DOWN;
|
||||
} else {
|
||||
/*
|
||||
* The resolution is less than 1
|
||||
* nanosecond, so we have to scale
|
||||
* the timestamps up.
|
||||
*/
|
||||
ps->ifaces[ps->ifcount - 1].scale_type = SCALE_UP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether this is a pcap-ng savefile and, if it is, extract the
|
||||
* relevant information from the header.
|
||||
*/
|
||||
int
|
||||
pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
pcap_t *
|
||||
pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
int *err)
|
||||
{
|
||||
size_t amt_read;
|
||||
bpf_u_int32 total_length;
|
||||
bpf_u_int32 byte_order_magic;
|
||||
struct block_header *bhdrp;
|
||||
struct section_header_block *shbp;
|
||||
pcap_t *p;
|
||||
int swapped = 0;
|
||||
struct pcap_ng_sf *ps;
|
||||
int status;
|
||||
struct block_cursor cursor;
|
||||
struct interface_description_block *idbp;
|
||||
|
||||
/*
|
||||
* Assume no read errors.
|
||||
*/
|
||||
*err = 0;
|
||||
|
||||
/*
|
||||
* Check whether the first 4 bytes of the file are the block
|
||||
* type for a pcap-ng savefile.
|
||||
@ -526,7 +678,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
* this as possibly being a pcap-ng file transferred
|
||||
* between UN*X and Windows in text file format?
|
||||
*/
|
||||
return (0); /* nope */
|
||||
return (NULL); /* nope */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -546,14 +698,15 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"error reading dump file: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1); /* fail */
|
||||
*err = 1;
|
||||
return (NULL); /* fail */
|
||||
}
|
||||
|
||||
/*
|
||||
* Possibly a weird short text file, so just say
|
||||
* "not pcap-ng".
|
||||
*/
|
||||
return (0);
|
||||
return (NULL);
|
||||
}
|
||||
amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
|
||||
if (amt_read < sizeof(byte_order_magic)) {
|
||||
@ -561,14 +714,15 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"error reading dump file: %s",
|
||||
pcap_strerror(errno));
|
||||
return (-1); /* fail */
|
||||
*err = 1;
|
||||
return (NULL); /* fail */
|
||||
}
|
||||
|
||||
/*
|
||||
* Possibly a weird short text file, so just say
|
||||
* "not pcap-ng".
|
||||
*/
|
||||
return (0);
|
||||
return (NULL);
|
||||
}
|
||||
if (byte_order_magic != BYTE_ORDER_MAGIC) {
|
||||
byte_order_magic = SWAPLONG(byte_order_magic);
|
||||
@ -576,9 +730,9 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
/*
|
||||
* Not a pcap-ng file.
|
||||
*/
|
||||
return (0);
|
||||
return (NULL);
|
||||
}
|
||||
p->sf.swapped = 1;
|
||||
swapped = 1;
|
||||
total_length = SWAPLONG(total_length);
|
||||
}
|
||||
|
||||
@ -590,9 +744,46 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
"Section Header Block in pcap-ng dump file has a length of %u < %lu",
|
||||
total_length,
|
||||
(unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
|
||||
return (-1);
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, this is a good pcap-ng file.
|
||||
* Allocate a pcap_t for it.
|
||||
*/
|
||||
p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf));
|
||||
if (p == NULL) {
|
||||
/* Allocation failed. */
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
}
|
||||
p->swapped = swapped;
|
||||
ps = p->priv;
|
||||
|
||||
/*
|
||||
* What precision does the user want?
|
||||
*/
|
||||
switch (precision) {
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_MICRO:
|
||||
ps->user_tsresol = 1000000;
|
||||
break;
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_NANO:
|
||||
ps->user_tsresol = 1000000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"unknown time stamp resolution %u", precision);
|
||||
free(p);
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
p->opt.tstamp_precision = precision;
|
||||
|
||||
/*
|
||||
* Allocate a buffer into which to read blocks. We default to
|
||||
* the maximum of:
|
||||
@ -611,7 +802,9 @@ pcap_ng_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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -629,7 +822,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
1, errbuf) == -1)
|
||||
goto fail;
|
||||
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
/*
|
||||
* Byte-swap the fields we've read.
|
||||
*/
|
||||
@ -646,15 +839,13 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
shbp->major_version);
|
||||
goto fail;
|
||||
}
|
||||
p->sf.version_major = shbp->major_version;
|
||||
p->sf.version_minor = shbp->minor_version;
|
||||
p->version_major = shbp->major_version;
|
||||
p->version_minor = shbp->minor_version;
|
||||
|
||||
/*
|
||||
* Set the default time stamp resolution and offset.
|
||||
* Save the time stamp resolution the user requested.
|
||||
*/
|
||||
p->sf.tsresol = 1000000; /* microsecond resolution */
|
||||
p->sf.tsscale = 1; /* multiply by 1 to scale to microseconds */
|
||||
p->sf.tsoffset = 0; /* absolute timestamps */
|
||||
p->opt.tstamp_precision = precision;
|
||||
|
||||
/*
|
||||
* Now start looking for an Interface Description Block.
|
||||
@ -666,7 +857,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
status = read_block(fp, p, &cursor, errbuf);
|
||||
if (status == 0) {
|
||||
/* EOF - no IDB in this file */
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"the capture file has no Interface Description Blocks");
|
||||
goto fail;
|
||||
}
|
||||
@ -687,42 +878,16 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
/*
|
||||
* Byte-swap it if necessary.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
idbp->linktype = SWAPSHORT((uint16_t)idbp->linktype);
|
||||
idbp->snaplen = SWAPLONG(idbp->snaplen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Count this interface.
|
||||
* Try to add this interface.
|
||||
*/
|
||||
p->sf.ifcount++;
|
||||
|
||||
/*
|
||||
* Now look for various time stamp options, so
|
||||
* we know how to interpret the time stamps.
|
||||
*/
|
||||
if (process_idb_options(p, &cursor, &p->sf.tsresol,
|
||||
&p->sf.tsoffset, errbuf) == -1)
|
||||
if (!add_interface(p, &cursor, errbuf))
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Compute the scaling factor to convert the
|
||||
* sub-second part of the time stamp to
|
||||
* microseconds.
|
||||
*/
|
||||
if (p->sf.tsresol > 1000000) {
|
||||
/*
|
||||
* Higher than microsecond resolution;
|
||||
* scale down to microseconds.
|
||||
*/
|
||||
p->sf.tsscale = (p->sf.tsresol / 1000000);
|
||||
} else {
|
||||
/*
|
||||
* Lower than microsecond resolution;
|
||||
* scale up to microseconds.
|
||||
*/
|
||||
p->sf.tsscale = (1000000 / p->sf.tsresol);
|
||||
}
|
||||
goto done;
|
||||
|
||||
case BT_EPB:
|
||||
@ -733,7 +898,7 @@ pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
|
||||
* not valid, as we don't know what link-layer
|
||||
* encapsulation the packet has.
|
||||
*/
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
||||
"the capture file has a packet block before any Interface Description Blocks");
|
||||
goto fail;
|
||||
|
||||
@ -751,13 +916,26 @@ done:
|
||||
p->linktype = linktype_to_dlt(idbp->linktype);
|
||||
p->linktype_ext = 0;
|
||||
|
||||
p->sf.next_packet_op = pcap_ng_next_packet;
|
||||
p->next_packet_op = pcap_ng_next_packet;
|
||||
p->cleanup_op = pcap_ng_cleanup;
|
||||
|
||||
return (1);
|
||||
return (p);
|
||||
|
||||
fail:
|
||||
free(ps->ifaces);
|
||||
free(p->buffer);
|
||||
return (-1);
|
||||
free(p);
|
||||
*err = 1;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pcap_ng_cleanup(pcap_t *p)
|
||||
{
|
||||
struct pcap_ng_sf *ps = p->priv;
|
||||
|
||||
free(ps->ifaces);
|
||||
sf_cleanup(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -768,6 +946,7 @@ fail:
|
||||
static int
|
||||
pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
{
|
||||
struct pcap_ng_sf *ps = p->priv;
|
||||
struct block_cursor cursor;
|
||||
int status;
|
||||
struct enhanced_packet_block *epbp;
|
||||
@ -776,9 +955,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
bpf_u_int32 interface_id = 0xFFFFFFFF;
|
||||
struct interface_description_block *idbp;
|
||||
struct section_header_block *shbp;
|
||||
FILE *fp = p->sf.rfile;
|
||||
u_int tsresol;
|
||||
u_int64_t tsoffset;
|
||||
FILE *fp = p->rfile;
|
||||
u_int64_t t, sec, frac;
|
||||
|
||||
/*
|
||||
@ -810,7 +987,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
/*
|
||||
* Byte-swap it if necessary.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
/* these were written in opposite byte order */
|
||||
interface_id = SWAPLONG(epbp->interface_id);
|
||||
hdr->caplen = SWAPLONG(epbp->caplen);
|
||||
@ -845,7 +1022,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
/*
|
||||
* Byte-swap it if necessary.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
/* these were written in opposite byte order */
|
||||
hdr->len = SWAPLONG(spbp->len);
|
||||
} else
|
||||
@ -875,7 +1052,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
/*
|
||||
* Byte-swap it if necessary.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
/* these were written in opposite byte order */
|
||||
interface_id = SWAPSHORT((uint32_t)pbp->interface_id);
|
||||
hdr->caplen = SWAPLONG(pbp->caplen);
|
||||
@ -904,7 +1081,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
/*
|
||||
* Byte-swap it if necessary.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
idbp->linktype = SWAPSHORT((uint32_t)idbp->linktype);
|
||||
idbp->snaplen = SWAPLONG(idbp->snaplen);
|
||||
}
|
||||
@ -931,37 +1108,10 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
}
|
||||
|
||||
/*
|
||||
* Count this interface.
|
||||
* Try to add this interface.
|
||||
*/
|
||||
p->sf.ifcount++;
|
||||
|
||||
/*
|
||||
* Set the default time stamp resolution and offset.
|
||||
*/
|
||||
tsresol = 1000000; /* microsecond resolution */
|
||||
tsoffset = 0; /* absolute timestamps */
|
||||
|
||||
/*
|
||||
* Now look for various time stamp options, to
|
||||
* make sure they're the same.
|
||||
*
|
||||
* XXX - we could, in theory, handle multiple
|
||||
* different resolutions and offsets, but we
|
||||
* don't do so for now.
|
||||
*/
|
||||
if (process_idb_options(p, &cursor, &tsresol, &tsoffset,
|
||||
p->errbuf) == -1)
|
||||
if (!add_interface(p, &cursor, p->errbuf))
|
||||
return (-1);
|
||||
if (tsresol != p->sf.tsresol) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"an interface has a time stamp resolution different from the time stamp resolution of the first interface");
|
||||
return (-1);
|
||||
}
|
||||
if (tsoffset != p->sf.tsoffset) {
|
||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"an interface has a time stamp offset different from the time stamp offset of the first interface");
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_SHB:
|
||||
@ -979,7 +1129,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
* the same as that of the previous section.
|
||||
* We'll check for that later.
|
||||
*/
|
||||
if (p->sf.swapped) {
|
||||
if (p->swapped) {
|
||||
shbp->byte_order_magic =
|
||||
SWAPLONG(shbp->byte_order_magic);
|
||||
shbp->major_version =
|
||||
@ -1036,7 +1186,7 @@ pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
|
||||
* any IDBs, we'll fail when we see a packet
|
||||
* block.)
|
||||
*/
|
||||
p->sf.ifcount = 0;
|
||||
ps->ifcount = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1051,7 +1201,7 @@ found:
|
||||
/*
|
||||
* Is the interface ID an interface we know?
|
||||
*/
|
||||
if (interface_id >= p->sf.ifcount) {
|
||||
if (interface_id >= ps->ifcount) {
|
||||
/*
|
||||
* Yes. Fail.
|
||||
*/
|
||||
@ -1064,20 +1214,52 @@ found:
|
||||
/*
|
||||
* Convert the time stamp to a struct timeval.
|
||||
*/
|
||||
sec = t / p->sf.tsresol + p->sf.tsoffset;
|
||||
frac = t % p->sf.tsresol;
|
||||
if (p->sf.tsresol > 1000000) {
|
||||
sec = t / ps->ifaces[interface_id].tsresol + ps->ifaces[interface_id].tsoffset;
|
||||
frac = t % ps->ifaces[interface_id].tsresol;
|
||||
switch (ps->ifaces[interface_id].scale_type) {
|
||||
|
||||
case PASS_THROUGH:
|
||||
/*
|
||||
* Higher than microsecond resolution; scale down to
|
||||
* microseconds.
|
||||
* The interface resolution is what the user wants,
|
||||
* so we're done.
|
||||
*/
|
||||
frac /= p->sf.tsscale;
|
||||
} else {
|
||||
break;
|
||||
|
||||
case SCALE_UP:
|
||||
/*
|
||||
* Lower than microsecond resolution; scale up to
|
||||
* microseconds.
|
||||
* The interface resolution is less than what the user
|
||||
* wants; scale up to that resolution.
|
||||
*
|
||||
* XXX - if ps->ifaces[interface_id].tsresol is a power
|
||||
* of 10, we could just multiply by the quotient of
|
||||
* ps->ifaces[interface_id].tsresol and ps->user_tsresol,
|
||||
* as we know that's an integer. That runs less risk of
|
||||
* overflow.
|
||||
*
|
||||
* Is there something clever we could do if
|
||||
* ps->ifaces[interface_id].tsresol is a power of 2?
|
||||
*/
|
||||
frac *= p->sf.tsscale;
|
||||
frac *= ps->ifaces[interface_id].tsresol;
|
||||
frac /= ps->user_tsresol;
|
||||
break;
|
||||
|
||||
case SCALE_DOWN:
|
||||
/*
|
||||
* The interface resolution is greater than what the user
|
||||
* wants; scale down to that resolution.
|
||||
*
|
||||
* XXX - if ps->ifaces[interface_id].tsresol is a power
|
||||
* of 10, we could just divide by the quotient of
|
||||
* ps->user_tsresol and ps->ifaces[interface_id].tsresol,
|
||||
* as we know that's an integer. That runs less risk of
|
||||
* overflow.
|
||||
*
|
||||
* Is there something clever we could do if
|
||||
* ps->ifaces[interface_id].tsresol is a power of 2?
|
||||
*/
|
||||
frac *= ps->user_tsresol;
|
||||
frac /= ps->ifaces[interface_id].tsresol;
|
||||
break;
|
||||
}
|
||||
hdr->ts.tv_sec = sec;
|
||||
hdr->ts.tv_usec = (suseconds_t)frac;
|
||||
@ -1089,7 +1271,7 @@ found:
|
||||
if (*data == NULL)
|
||||
return (-1);
|
||||
|
||||
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
|
||||
|
193
external/bsd/libpcap/dist/sf-pcap.c
vendored
193
external/bsd/libpcap/dist/sf-pcap.c
vendored
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sf-pcap.c,v 1.3 2013/04/06 17:29:53 christos Exp $ */
|
||||
/* $NetBSD: sf-pcap.c,v 1.4 2013/12/31 17:08:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||
@ -124,26 +124,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -164,13 +196,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);
|
||||
@ -182,16 +215,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,
|
||||
@ -207,19 +305,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;
|
||||
}
|
||||
|
||||
@ -241,7 +339,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) {
|
||||
/*
|
||||
@ -267,7 +365,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.
|
||||
@ -282,10 +380,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -296,8 +398,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;
|
||||
|
||||
@ -308,8 +411,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",
|
||||
@ -319,7 +422,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);
|
||||
}
|
||||
@ -328,7 +431,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);
|
||||
@ -340,8 +443,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;
|
||||
@ -432,7 +561,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
|
||||
@ -454,11 +583,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;
|
||||
|
||||
@ -509,7 +638,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)
|
||||
|
29
external/bsd/libpcap/include/config.h
vendored
29
external/bsd/libpcap/include/config.h
vendored
@ -59,6 +59,15 @@
|
||||
/* if libnl exists and is version 2.x */
|
||||
/* #undef HAVE_LIBNL_2_x */
|
||||
|
||||
/* if libnl exists and is version 3.x */
|
||||
/* #undef HAVE_LIBNL_3_x */
|
||||
|
||||
/* libnl has NLE_FAILURE */
|
||||
/* #undef HAVE_LIBNL_NLE */
|
||||
|
||||
/* libnl has new-style socket api */
|
||||
/* #undef HAVE_LIBNL_SOCKETS */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
@ -212,6 +221,9 @@
|
||||
/* path for device for USB sniffing */
|
||||
/* #undef LINUX_USB_MON_DEV */
|
||||
|
||||
/* if we need a pcap_parse wrapper around yyparse */
|
||||
/* #undef NEED_YYPARSE_WRAPPER */
|
||||
|
||||
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
|
||||
/* #undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
|
||||
|
||||
@ -251,6 +263,9 @@
|
||||
/* target host supports canusb */
|
||||
/* #undef PCAP_SUPPORT_CANUSB */
|
||||
|
||||
/* support D-Bus sniffing */
|
||||
/* #undef PCAP_SUPPORT_DBUS */
|
||||
|
||||
/* target host supports netfilter sniffing */
|
||||
/* #undef PCAP_SUPPORT_NETFILTER */
|
||||
|
||||
@ -260,18 +275,23 @@
|
||||
/* include ACN support */
|
||||
/* #undef SITA */
|
||||
|
||||
/* if struct sockaddr_hci has hci_channel member */
|
||||
/* #undef SOCKADDR_HCI_HAS_HCI_CHANNEL */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Enable parser debugging */
|
||||
/* #undef YYDEBUG */
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* needed on HP-UX */
|
||||
/* #undef _HPUX_SOURCE */
|
||||
|
||||
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
|
||||
/* #undef _LARGEFILE_SOURCE */
|
||||
|
||||
@ -281,6 +301,9 @@
|
||||
/* define on AIX to get certain functions */
|
||||
/* #undef _SUN */
|
||||
|
||||
/* define if your compiler allows __attribute__((format)) without a warning */
|
||||
#define __ATTRIBUTE___FORMAT_OK 1
|
||||
|
||||
/* to handle Ultrix compilers that don't support const in prototypes */
|
||||
/* #undef const */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user