From: Matthew Dillon Date: Sat, 3 May 2014 15:46:52 +0000 (-0700) Subject: Import libpcap-1.4.0. X-Git-Tag: v3.9.0~87^2 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/0e38198382c0ede3efe287a7486e2b3333f4a609 Import libpcap-1.4.0. See CHANGES for the details. --- diff --git a/contrib/libpcap/CHANGES b/contrib/libpcap/CHANGES index 4f7fa355c7..0dcf957eca 100644 --- a/contrib/libpcap/CHANGES +++ b/contrib/libpcap/CHANGES @@ -1,3 +1,35 @@ +Monday March 18, 2013 guy@alum.mit.edu +Summary for 1.4.0 libpcap release + Add netfilter/nfqueue interface. + If we don't have support for IPv6 address resolution, support, + in filter expressions, what IPv6 stuff we can. + Checks added for malloc()/realloc()/etc. failures. + Fix pcap-config to include -lpthread if canusb support is + present + Try to fix "pcap_parse not defined" problems when --without-flex + and --without-bison are used when you have Flex and Bison + Fix some issues with the pcap_loop man page. + Fix pcap_getnonblock() and pcap_setnonblock() to fill in the + supplied error message buffer + Fix typo that, it appeared, would cause pcap-libdlpi.c not to + compile (perhaps systems with libdlpi also have BPF and use + that instead) + Catch attempts to call pcap_compile() on a non-activated pcap_t + Fix crash on Linux with CAN-USB support without usbfs + Fix addition of VLAN tags for Linux cooked captures + Check for both EOPNOTSUPP and EINVAL after SIOCETHTOOL ioctl, so + that the driver can report either one if it doesn't support + SIOCETHTOOL + Add DLT_INFINIBAND and DLT_SCTP + Describe "proto XXX" and "protochain XXX" in the pcap-filter man + page + Handle either directories, or symlinks to directories, that + correspond to interfaces in /sys/class/net + Fix handling of VLAN tag insertion to check, on Linux 3.x + kernels, for VLAN tag valid flag + Clean up some man pages + Support libnl3 as well as libnl1 and libnl2 on Linux + Friday March 30, 2012. mcr@sandelman.ca Summary for 1.3.0 libpcap release Handle DLT_PFSYNC in {FreeBSD, other *BSD+Mac OS X, other}. diff --git a/contrib/libpcap/README b/contrib/libpcap/README index a206474aa1..8cac0af1d2 100644 --- a/contrib/libpcap/README +++ b/contrib/libpcap/README @@ -13,8 +13,11 @@ Anonymous Git is available via: Version 1.x.y of LIBPCAP can be retrieved with the CVS tag "libpcap_1_{x}rel{y}": cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_1_{x}rel{y} libpcap -Please submit patches against the master copy to the libpcap project on -sourceforge.net. +Please submit patches by forking the branch on GitHub at + + http://github.com/mcr/libpcap/tree/master + +and issuing a pull request. formerly from Lawrence Berkeley National Laboratory Network Research Group @@ -91,15 +94,18 @@ a particular release of libpcap. Problems, bugs, questions, desirable enhancements, etc. should be sent to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support -requests, and feature requests may also be submitted on the SourceForge -site for libpcap at +requests, and feature requests may also be submitted on the GitHub issue +tracker for libpcap at - http://sourceforge.net/projects/libpcap/ + https://github.com/mcr/libpcap/issues Source code contributions, etc. should be sent to the email address -submitted as patches on the SourceForge site for libpcap. +above or submitted by forking the branch on GitHub at + + http://github.com/mcr/libpcap/tree/master + +and issuing a pull request. -Current versions can be found at www.tcpdump.org, or the SourceForge -site for libpcap. +Current versions can be found at www.tcpdump.org. - The TCPdump team diff --git a/contrib/libpcap/VERSION b/contrib/libpcap/VERSION index f0bb29e763..88c5fb891d 100644 --- a/contrib/libpcap/VERSION +++ b/contrib/libpcap/VERSION @@ -1 +1 @@ -1.3.0 +1.4.0 diff --git a/contrib/libpcap/bpf_image.c b/contrib/libpcap/bpf_image.c index e2f1a774a4..e6c0f62617 100644 --- a/contrib/libpcap/bpf_image.c +++ b/contrib/libpcap/bpf_image.c @@ -292,11 +292,14 @@ bpf_image(p, n) break; } (void)snprintf(operand, sizeof operand, fmt, v); - (void)snprintf(image, sizeof image, - (BPF_CLASS(p->code) == BPF_JMP && - BPF_OP(p->code) != BPF_JA) ? - "(%03d) %-8s %-16s jt %d\tjf %d" - : "(%03d) %-8s %s", - n, op, operand, n + 1 + p->jt, n + 1 + p->jf); + if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) { + (void)snprintf(image, sizeof image, + "(%03d) %-8s %-16s jt %d\tjf %d", + n, op, operand, n + 1 + p->jt, n + 1 + p->jf); + } else { + (void)snprintf(image, sizeof image, + "(%03d) %-8s %s", + n, op, operand); + } return image; } diff --git a/contrib/libpcap/fad-getad.c b/contrib/libpcap/fad-getad.c index 742ae1facb..f4d5869c2d 100644 --- a/contrib/libpcap/fad-getad.c +++ b/contrib/libpcap/fad-getad.c @@ -141,11 +141,9 @@ get_sa_len(struct sockaddr *addr) * Returns -1 on error, 0 otherwise. * The list, as returned through "alldevsp", may be null if no interfaces * were up and could be opened. - * - * This is the implementation used on platforms that have "getifaddrs()". */ int -pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) +pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) { pcap_if_t *devlist = NULL; struct ifaddrs *ifap, *ifa; @@ -273,15 +271,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) freeifaddrs(ifap); - if (ret != -1) { - /* - * We haven't had any errors yet; do any platform-specific - * operations to add devices. - */ - if (pcap_platform_finddevs(&devlist, errbuf) < 0) - ret = -1; - } - if (ret == -1) { /* * We had an error; free the list we've been constructing. diff --git a/contrib/libpcap/gencode.c b/contrib/libpcap/gencode.c index 532229aae6..cdb0d34e9f 100644 --- a/contrib/libpcap/gencode.c +++ b/contrib/libpcap/gencode.c @@ -107,6 +107,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 @@ -261,20 +273,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); @@ -425,6 +433,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; @@ -2832,11 +2849,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; @@ -3044,11 +3059,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 */ @@ -3072,10 +3086,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(); @@ -3197,11 +3209,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*/ @@ -3219,11 +3229,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, @@ -3275,13 +3283,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: /* @@ -3628,7 +3634,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) @@ -4506,13 +4512,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); @@ -4669,7 +4673,7 @@ gen_host6(addr, mask, proto, dir, type) } /* NOTREACHED */ } -#endif /*INET6*/ +#endif #ifndef INET6 static struct block * @@ -4761,26 +4765,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: @@ -4808,10 +4806,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 @@ -4873,7 +4869,6 @@ gen_proto_abbrev(proto) b1 = gen_linktype(ETHERTYPE_MOPRC); break; -#ifdef INET6 case Q_IPV6: b1 = gen_linktype(ETHERTYPE_IPV6); break; @@ -4884,17 +4879,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 @@ -4902,10 +4894,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: @@ -5038,7 +5028,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; @@ -5046,7 +5035,6 @@ gen_portatom6(off, v) { return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v); } -#endif/*INET6*/ struct block * gen_portop(port, proto, dir) @@ -5138,7 +5126,6 @@ gen_port(port, ip_proto, dir) return b1; } -#ifdef INET6 struct block * gen_portop6(port, proto, dir) int port, proto, dir; @@ -5211,7 +5198,6 @@ gen_port6(port, ip_proto, dir) gen_and(b0, b1); return b1; } -#endif /* INET6 */ /* gen_portrange code */ static struct block * @@ -5316,7 +5302,6 @@ gen_portrange(port1, port2, ip_proto, dir) return b1; } -#ifdef INET6 static struct block * gen_portrangeatom6(off, v1, v2) int off; @@ -5417,7 +5402,6 @@ gen_portrange6(port1, port2, ip_proto, dir) gen_and(b0, b1); return b1; } -#endif /* INET6 */ static int lookup_proto(name, proto) @@ -5552,7 +5536,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); @@ -5565,7 +5549,7 @@ gen_protochain(v, proto, dir) s[i]->s.k = 40; i++; break; -#endif + default: bpf_error("unsupported proto to gen_protochain"); /*NOTREACHED*/ @@ -5592,7 +5576,6 @@ gen_protochain(v, proto, dir) fix2 = i; i++; -#ifdef INET6 if (proto == Q_IPV6) { int v6start, v6end, v6advance, j; @@ -5674,9 +5657,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; @@ -5820,10 +5801,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) @@ -5831,14 +5810,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, @@ -5989,7 +5965,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 @@ -6010,7 +5985,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"); @@ -6267,13 +6241,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 && @@ -6317,13 +6287,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 @@ -6471,16 +6437,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) @@ -6497,16 +6459,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"); @@ -6796,9 +6754,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. @@ -6907,16 +6863,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); @@ -7468,13 +7420,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 */ diff --git a/contrib/libpcap/grammar.y b/contrib/libpcap/grammar.y index f2ba28b1e5..f92e90dd73 100644 --- a/contrib/libpcap/grammar.y +++ b/contrib/libpcap/grammar.y @@ -167,7 +167,7 @@ yyerror(const char *msg) /* NOTREACHED */ } -#ifndef YYBISON +#ifdef NEED_YYPARSE_WRAPPER int yyparse(void); int diff --git a/contrib/libpcap/nametoaddr.c b/contrib/libpcap/nametoaddr.c index 5835e4d1fd..c0e86f43ab 100644 --- a/contrib/libpcap/nametoaddr.c +++ b/contrib/libpcap/nametoaddr.c @@ -247,6 +247,7 @@ pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto) free(cpy); return 0; } + free(cpy); if (*proto != save_proto) *proto = PROTO_UNDEF; diff --git a/contrib/libpcap/optimize.c b/contrib/libpcap/optimize.c index 6bbda95632..dcb104ec2a 100644 --- a/contrib/libpcap/optimize.c +++ b/contrib/libpcap/optimize.c @@ -112,51 +112,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 @@ -232,8 +190,7 @@ static uset all_edge_sets; #endif static void -find_levels_r(b) - struct block *b; +find_levels_r(struct block *b) { int level; @@ -261,8 +218,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(); @@ -274,8 +230,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; @@ -305,8 +260,7 @@ find_dom(root) } static void -propedom(ep) - struct edge *ep; +propedom(struct edge *ep) { SET_INSERT(ep->edom, ep->id); if (ep->succ) { @@ -320,8 +274,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; @@ -350,8 +303,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; @@ -381,8 +333,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; @@ -427,8 +378,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; @@ -464,8 +414,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; @@ -526,8 +475,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; @@ -582,7 +530,7 @@ struct valnode *vnode_base; struct valnode *next_vnode; static void -init_val() +init_val(void) { curval = 0; next_vnode = vnode_base; @@ -592,9 +540,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; @@ -625,11 +571,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; @@ -638,9 +580,7 @@ vstore(s, valp, newval, alter) } 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; @@ -695,8 +635,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; @@ -704,8 +643,7 @@ this_op(s) } static void -opt_not(b) - struct block *b; +opt_not(struct block *b) { struct block *tmp = JT(b); @@ -714,8 +652,7 @@ opt_not(b) } static void -opt_peep(b) - struct block *b; +opt_peep(struct block *b) { struct slist *s; struct slist *next, *last; @@ -978,10 +915,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; @@ -1166,9 +1100,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; @@ -1192,8 +1124,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; @@ -1213,9 +1144,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; @@ -1319,8 +1248,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; @@ -1336,9 +1264,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; @@ -1390,8 +1316,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; @@ -1446,8 +1371,7 @@ opt_j(ep) static void -or_pullup(b) - struct block *b; +or_pullup(struct block *b) { int val, at_top; struct block *pull; @@ -1539,8 +1463,7 @@ or_pullup(b) } static void -and_pullup(b) - struct block *b; +and_pullup(struct block *b) { int val, at_top; struct block *pull; @@ -1631,9 +1554,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; @@ -1670,17 +1591,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; @@ -1701,8 +1619,7 @@ find_inedges(root) } static void -opt_root(b) - struct block **b; +opt_root(struct block **b) { struct slist *tmp, *s; @@ -1726,9 +1643,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 @@ -1758,8 +1673,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; @@ -1786,8 +1700,7 @@ bpf_optimize(rootp) } static void -make_marks(p) - struct block *p; +make_marks(struct block *p) { if (!isMarked(p)) { Mark(p); @@ -1803,8 +1716,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); @@ -1815,8 +1727,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) @@ -1835,8 +1746,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 && @@ -1847,8 +1757,7 @@ eq_blk(b0, b1) } static void -intern_blocks(root) - struct block *root; +intern_blocks(struct block *root) { struct block *p; int i, j; @@ -1891,7 +1800,7 @@ intern_blocks(root) } static void -opt_cleanup() +opt_cleanup(void) { free((void *)vnode_base); free((void *)vmap); @@ -1905,8 +1814,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; @@ -1921,8 +1829,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; @@ -1935,8 +1842,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; @@ -1971,8 +1877,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; @@ -1989,8 +1894,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; @@ -2088,8 +1992,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; @@ -2261,9 +2164,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; @@ -2333,8 +2234,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; diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c index 944445f54c..9e739dc6a4 100644 --- a/contrib/libpcap/pcap-bpf.c +++ b/contrib/libpcap/pcap-bpf.c @@ -122,14 +122,6 @@ 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 @@ -218,30 +210,21 @@ 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 + * Map each value to their corresponding negation 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. + * Indicate that we're switching to + * non-blocking mode. */ - p->md.timeout = p->md.timeout * -1 - 1; + p->md.timeout = ~p->md.timeout; } } 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; + p->md.timeout = ~p->md.timeout; } } return (0); @@ -407,19 +390,10 @@ pcap_ack_zbuf(pcap_t *p) #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); if (p == NULL) return (NULL); @@ -1701,7 +1675,7 @@ pcap_activate_bpf(pcap_t *p) pcap_strerror(errno)); goto bad; } - bzero(&bz, sizeof(bz)); + memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */ bz.bz_bufa = p->md.zbuf1; bz.bz_bufb = p->md.zbuf2; bz.bz_buflen = p->md.zbufsize; @@ -2283,15 +2257,6 @@ pcap_activate_bpf(pcap_t *p) 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); } diff --git a/contrib/libpcap/pcap-common.c b/contrib/libpcap/pcap-common.c index 31cf84defc..bd18c64acb 100644 --- a/contrib/libpcap/pcap-common.c +++ b/contrib/libpcap/pcap-common.c @@ -841,7 +841,7 @@ #define LINKTYPE_NETANALYZER_TRANSPARENT 241 /* - * IP-over-Infiniband, as specified by RFC 4391. + * IP-over-InfiniBand, as specified by RFC 4391. * * Requested by Petr Sumbera . */ @@ -883,7 +883,21 @@ */ #define LINKTYPE_PFSYNC 246 -#define LINKTYPE_MATCHING_MAX 246 /* highest value in the "matching" range */ +/* + * Raw InfiniBand packets, starting with the Local Routing Header. + * + * Requested by Oren Kladnitsky . + */ +#define LINKTYPE_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen . + */ +#define LINKTYPE_SCTP 248 + +#define LINKTYPE_MATCHING_MAX 248 /* highest value in the "matching" range */ static struct linktype_map { int dlt; diff --git a/contrib/libpcap/pcap-filter.manmisc.in b/contrib/libpcap/pcap-filter.manmisc.in index d7b4b0a5f0..6019a8097b 100644 --- a/contrib/libpcap/pcap-filter.manmisc.in +++ b/contrib/libpcap/pcap-filter.manmisc.in @@ -45,6 +45,7 @@ Primitives usually consist of an There are three different kinds of qualifier: .IP \fItype\fP +.I type qualifiers say what kind of thing the id name or number refers to. Possible types are .BR host , @@ -58,6 +59,7 @@ qualifier, .B host is assumed. .IP \fIdir\fP +.I dir qualifiers specify a particular transfer direction to and/or from .IR id . Possible directions are @@ -93,6 +95,7 @@ and .B outbound qualifiers can be used to specify a desired direction. .IP \fIproto\fP +.I proto qualifiers restrict the match to a particular protocol. Possible protos are: @@ -159,7 +162,7 @@ True if the IPv4/v6 destination field of the packet is \fIhost\fP, which may be either an address or a name. .IP "\fBsrc host \fIhost\fR" True if the IPv4/v6 source field of the packet is \fIhost\fP. -.IP "\fBhost \fIhost\fP +.IP "\fBhost \fIhost\fP" True if either the IPv4/v6 source or destination of the packet is \fIhost\fP. .IP Any of the above host expressions can be prepended with the keywords, @@ -177,17 +180,17 @@ which is equivalent to: .in -.5i If \fIhost\fR is a name with multiple IP addresses, each address will be checked for a match. -.IP "\fBether dst \fIehost\fP +.IP "\fBether dst \fIehost\fP" True if the Ethernet destination address is \fIehost\fP. \fIEhost\fP may be either a name from /etc/ethers or a number (see .IR ethers (3N) for numeric format). -.IP "\fBether src \fIehost\fP +.IP "\fBether src \fIehost\fP" True if the Ethernet source address is \fIehost\fP. -.IP "\fBether host \fIehost\fP +.IP "\fBether host \fIehost\fP" True if either the Ethernet source or destination address is \fIehost\fP. -.IP "\fBgateway\fP \fIhost\fP +.IP "\fBgateway\fP \fIhost\fP" True if the packet used \fIhost\fP as a gateway. I.e., the Ethernet source or destination address was \fIhost\fP but neither the IP source @@ -302,6 +305,18 @@ Note that this primitive does not chase the protocol header chain. .IP "\fBip6 proto \fIprotocol\fR" True if the packet is an IPv6 packet of protocol type \fIprotocol\fP. Note that this primitive does not chase the protocol header chain. +.IP "\fBproto \fIprotocol\fR" +True if the packet is an IPv4 or IPv6 packet of protocol type +\fIprotocol\fP. Note that this primitive does not chase the protocol +header chain. +.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR" +Abbreviations for: +.in +.5i +.nf +\fBproto \fIp\fR\fB +.fi +.in -.5i +where \fIp\fR is one of the above protocols. .IP "\fBip6 protochain \fIprotocol\fR" True if the packet is IPv6 packet, and contains protocol header with type \fIprotocol\fR @@ -321,6 +336,10 @@ cannot be optimized by the BPF optimizer code, so this can be somewhat slow. .IP "\fBip protochain \fIprotocol\fR" Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4. +.IP "\fBprotochain \fIprotocol\fR" +True if the packet is an IPv4 or IPv6 packet of protocol type +\fIprotocol\fP. Note that this primitive chases the protocol +header chain. .IP "\fBether broadcast\fR" True if the packet is an Ethernet broadcast packet. The \fIether\fP @@ -402,6 +421,25 @@ the filter checks for the IPX etype in an Ethernet frame, the IPX DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of IPX, and the IPX etype in a SNAP frame. .RE +.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP" +Abbreviations for: +.in +.5i +.nf +\fBether proto \fIp\fR +.fi +.in -.5i +where \fIp\fR is one of the above protocols. +.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR" +Abbreviations for: +.in +.5i +.nf +\fBether proto \fIp\fR +.fi +.in -.5i +where \fIp\fR is one of the above protocols. +Note that not all applications using +.BR pcap (3PCAP) +currently know how to parse these protocols. .IP "\fBdecnet src \fIhost\fR" True if the DECNET source address is .IR host , @@ -503,25 +541,6 @@ True if the fourth IEEE 802.11 address, if present, is .IR ehost . The fourth address field is only used for WDS (Wireless Distribution System) frames. -.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP" -Abbreviations for: -.in +.5i -.nf -\fBether proto \fIp\fR -.fi -.in -.5i -where \fIp\fR is one of the above protocols. -.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR" -Abbreviations for: -.in +.5i -.nf -\fBether proto \fIp\fR -.fi -.in -.5i -where \fIp\fR is one of the above protocols. -Note that not all applications using -.BR pcap (3) -currently know how to parse these protocols. .IP "\fBtype \fIwlan_type\fR" True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR. Valid \fIwlan_type\fRs are: @@ -652,14 +671,6 @@ For example: .fi .in -.5i filters IPv4 protocols encapsulated in PPPoE. -.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR" -Abbreviations for: -.in +.5i -.nf -\fBip proto \fIp\fR\fB or ip6 proto \fIp\fR -.fi -.in -.5i -where \fIp\fR is one of the above protocols. .IP "\fBiso proto \fIprotocol\fR" True if the packet is an OSI packet of protocol type \fIprotocol\fP. \fIProtocol\fP can be a number or one of the names @@ -674,11 +685,11 @@ Abbreviations for: where \fIp\fR is one of the above protocols. .IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR" Abbreviations for IS-IS PDU types. -.IP "\fBvpi\fP \fIn\fR +.IP "\fBvpi\fP \fIn\fR" True if the packet is an ATM packet, for SunATM on Solaris, with a virtual path identifier of .IR n . -.IP "\fBvci\fP \fIn\fR +.IP "\fBvci\fP \fIn\fR" True if the packet is an ATM packet, for SunATM on Solaris, with a virtual channel identifier of .IR n . @@ -918,27 +929,6 @@ icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply .RE .SH "SEE ALSO" pcap(3PCAP) -.SH AUTHORS -The original authors are: -.LP -Van Jacobson, -Craig Leres and -Steven McCanne, all of the -Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. -.LP -It is currently being maintained by tcpdump.org. -.LP -The current version of libpcap is available via http: -.LP -.RS -.I http://www.tcpdump.org/ -.RE -.LP -The original distribution is available via anonymous ftp: -.LP -.RS -.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z -.RE .SH BUGS Please send problems, bugs, questions, desirable enhancements, etc. to: .LP diff --git a/contrib/libpcap/pcap-int.h b/contrib/libpcap/pcap-int.h index 8444e62cee..b3ce82d6a6 100644 --- a/contrib/libpcap/pcap-int.h +++ b/contrib/libpcap/pcap-int.h @@ -144,6 +144,7 @@ struct pcap_md { char *mondevice; /* mac80211 monitor device we created */ u_char *mmapbuf; /* memory-mapped region pointer */ size_t mmapbuflen; /* size of region */ + int vlan_offset; /* offset at which to insert vlan tags; if -1, don't insert */ u_int tp_version; /* version of tpacket_hdr for mmaped ring */ u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */ u_char *oneshot_buffer; /* buffer for copy of packet */ @@ -374,12 +375,13 @@ struct pcap_timeval { * the old record header as well as files with the new record 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/mcr/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_sf_pkthdr { @@ -454,6 +456,18 @@ int pcap_getnonblock_fd(pcap_t *, char *); int pcap_setnonblock_fd(pcap_t *p, int, char *); #endif +/* + * Internal interfaces for "pcap_create()". + * + * "pcap_create_interface()" is the routine to do a pcap_create on + * a regular network interface. There are multiple implementations + * of this, one for each platform type (Linux, BPF, DLPI, etc.), + * with the one used chosen by the configure script. + * + * "pcap_create_common()" allocates and fills in a pcap_t, for use + * by pcap_create routines. + */ +pcap_t *pcap_create_interface(const char *, char *); pcap_t *pcap_create_common(const char *, char *); int pcap_do_addexit(pcap_t *); void pcap_add_to_pcaps_to_close(pcap_t *); @@ -465,12 +479,16 @@ int pcap_check_activated(pcap_t *); /* * Internal interfaces for "pcap_findalldevs()". * + * "pcap_findalldevs_interfaces()" finds interfaces using the + * "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.). + * * "pcap_platform_finddevs()" is a platform-dependent routine to - * add devices not found by the "standard" mechanisms (SIOCGIFCONF, - * "getifaddrs()", etc.. + * add devices not found by the "standard" mechanisms. * - * "pcap_add_if()" adds an interface to the list of interfaces. + * "pcap_add_if()" adds an interface to the list of interfaces, for + * use by various "find interfaces" routines. */ +int pcap_findalldevs_interfaces(pcap_if_t **, char *); int pcap_platform_finddevs(pcap_if_t **, char *); int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *, size_t, struct sockaddr *, size_t, struct sockaddr *, size_t, diff --git a/contrib/libpcap/pcap.c b/contrib/libpcap/pcap.c index cfdd83fec6..9ce43183c8 100644 --- a/contrib/libpcap/pcap.c +++ b/contrib/libpcap/pcap.c @@ -74,8 +74,35 @@ static const char rcsid[] _U_ = #include "pcap-int.h" #ifdef HAVE_DAG_API -#include -#include +#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 int @@ -232,6 +259,173 @@ 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 + { 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) { @@ -1023,7 +1217,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); } /* @@ -1041,7 +1246,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); } @@ -1055,7 +1260,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) @@ -1072,7 +1288,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); } @@ -1081,7 +1297,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); } @@ -1464,10 +1680,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)); diff --git a/contrib/libpcap/pcap/bpf.h b/contrib/libpcap/pcap/bpf.h index 8bcde7fe52..8576bbdbd0 100644 --- a/contrib/libpcap/pcap/bpf.h +++ b/contrib/libpcap/pcap/bpf.h @@ -1133,7 +1133,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 . */ @@ -1175,7 +1175,21 @@ 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 . + */ +#define DLT_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen . + */ +#define DLT_SCTP 248 + +#define DLT_MATCHING_MAX 248 /* highest value in the "matching" range */ /* * DLT and savefile link type values are split into a class and diff --git a/contrib/libpcap/pcap/pcap.h b/contrib/libpcap/pcap/pcap.h index a02b359961..7be36b1718 100644 --- a/contrib/libpcap/pcap/pcap.h +++ b/contrib/libpcap/pcap/pcap.h @@ -113,12 +113,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/mcr/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; @@ -370,8 +371,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 **); diff --git a/contrib/libpcap/pcap_breakloop.3pcap b/contrib/libpcap/pcap_breakloop.3pcap index 2372348be4..e437af8a8e 100644 --- a/contrib/libpcap/pcap_breakloop.3pcap +++ b/contrib/libpcap/pcap_breakloop.3pcap @@ -58,20 +58,15 @@ if the signal interrupted a call reading packets in a live capture, when your signal handler returns after calling pcap_breakloop(), the call will be restarted, and the loop will not terminate until more packets arrive and the call completes. +.ft R .PP +.ft B Note also that, in a multi-threaded application, if one thread is -blocked in -.BR pcap_dispatch() , -.BR pcap_loop() , -.BR pcap_next() , -or -.BR pcap_next_ex() , -a call to -.B pcap_breakloop() -in a different thread will not unblock that thread; you will need to use -whatever mechanism the OS provides for breaking a thread out of blocking -calls in order to unblock the thread, such as thread cancellation in -systems that support POSIX threads. +blocked in pcap_dispatch(), pcap_loop(), pcap_next(), or pcap_next_ex(), +a call to pcap_breakloop() in a different thread will not unblock that +thread; you will need to use whatever mechanism the OS provides for +breaking a thread out of blocking calls in order to unblock the thread, +such as thread cancellation in systems that support POSIX threads. .ft R .PP Note that diff --git a/contrib/libpcap/pcap_loop.3pcap b/contrib/libpcap/pcap_loop.3pcap index da3069310a..7e0b582bac 100644 --- a/contrib/libpcap/pcap_loop.3pcap +++ b/contrib/libpcap/pcap_loop.3pcap @@ -84,7 +84,7 @@ processed when reading a ``savefile''. \fIcnt\fP was 0 was undefined; different platforms and devices behaved differently, so code that must work with older versions of libpcap -should use \-1, nor 0, as the value of +should use \-1, not 0, as the value of \fIcnt\fP.) .ft R .PP @@ -119,8 +119,9 @@ them. .B pcap_loop() returns 0 if .I cnt -is exhausted, \-1 if an error occurs, or \-2 if the loop terminated due -to a call to +is exhausted or if, when reading from a ``savefile'', no more packets +are available. It returns \-1 if an error occurs or \-2 if the loop +terminated due to a call to .B pcap_breakloop() before any packets were processed. It does diff --git a/contrib/libpcap/pcap_offline_filter.3pcap b/contrib/libpcap/pcap_offline_filter.3pcap index 596c5e44c3..3f11022d5a 100644 --- a/contrib/libpcap/pcap_offline_filter.3pcap +++ b/contrib/libpcap/pcap_offline_filter.3pcap @@ -29,7 +29,7 @@ pcap_offline_filter \- check whether a filter matches a packet .ft .LP .ft B -int pcap_offline_filter(struct bpf_program *fp, +int pcap_offline_filter(const struct bpf_program *fp, .ti +8 const struct pcap_pkthdr *h, const u_char *pkt) .ft diff --git a/contrib/libpcap/scanner.l b/contrib/libpcap/scanner.l index 064e9c885f..10ffbcd567 100644 --- a/contrib/libpcap/scanner.l +++ b/contrib/libpcap/scanner.l @@ -206,20 +206,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;