diff --git a/CREDITS b/CREDITS index 3a9de31..3d83930 100644 --- a/CREDITS +++ b/CREDITS @@ -15,6 +15,7 @@ Additional people who have contributed patches: Albert Chin Andrew Brown Antti Kantee + Arien Vijn Arkadiusz Miskiewicz Armando L. Caro Jr. Assar Westerlund diff --git a/nametoaddr.c b/nametoaddr.c index 816331c..747fb19 100644 --- a/nametoaddr.c +++ b/nametoaddr.c @@ -23,38 +23,65 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.48.1.1 1999-10-07 23:46:40 mcr Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.82.2.1 2008-02-06 10:21:47 guy Exp $ (LBL)"; #endif +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include + +#else /* WIN32 */ + #include #include /* concession to AIX */ #include #include -#if __STDC__ -struct mbuf; -struct rtentry; +#include +#endif /* WIN32 */ + +/* + * XXX - why was this included even on UNIX? + */ +#ifdef __MINGW32__ +#include "IP6_misc.h" #endif -#include -#include +#ifndef WIN32 +#ifdef HAVE_ETHER_HOSTTON +/* + * XXX - do we need any of this if doesn't declare + * ether_hostton()? + */ +#ifdef HAVE_NETINET_IF_ETHER_H +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include /* for "struct ifnet" in "struct arpcom" on Solaris */ #include +#endif /* HAVE_NETINET_IF_ETHER_H */ +#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON +#include +#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */ +#endif /* HAVE_ETHER_HOSTTON */ #include +#include +#endif /* WIN32 */ #include #include #include -#include -#include +#include #include #include "pcap-int.h" #include "gencode.h" -#include +#include -#include "gnuc.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif @@ -94,6 +121,25 @@ pcap_nametoaddr(const char *name) return 0; } +#ifdef INET6 +struct addrinfo * +pcap_nametoaddrinfo(const char *name) +{ + struct addrinfo hints, *res; + int error; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; /*not really*/ + hints.ai_protocol = IPPROTO_TCP; /*not really*/ + error = getaddrinfo(name, NULL, &hints, &res); + if (error) + return NULL; + else + return res; +} +#endif /*INET6*/ + /* * Convert net name to internet address. * Return 0 upon failure. @@ -101,12 +147,19 @@ pcap_nametoaddr(const char *name) bpf_u_int32 pcap_nametonetaddr(const char *name) { +#ifndef WIN32 struct netent *np; if ((np = getnetbyname(name)) != NULL) return np->n_net; else return 0; +#else + /* + * There's no "getnetbyname()" on Windows. + */ + return 0; +#endif } /* @@ -118,38 +171,40 @@ int pcap_nametoport(const char *name, int *port, int *proto) { struct servent *sp; - char *other; + int tcp_port = -1; + int udp_port = -1; - sp = getservbyname(name, (char *)0); - if (sp != NULL) { - NTOHS(sp->s_port); - *port = sp->s_port; - *proto = pcap_nametoproto(sp->s_proto); - /* - * We need to check /etc/services for ambiguous entries. - * If we find the ambiguous entry, and it has the - * same port number, change the proto to PROTO_UNDEF - * so both TCP and UDP will be checked. - */ - if (*proto == IPPROTO_TCP) - other = "udp"; - else - other = "tcp"; - - sp = getservbyname(name, other); - if (sp != 0) { - NTOHS(sp->s_port); + /* + * We need to check /etc/services for ambiguous entries. + * If we find the ambiguous entry, and it has the + * same port number, change the proto to PROTO_UNDEF + * so both TCP and UDP will be checked. + */ + sp = getservbyname(name, "tcp"); + if (sp != NULL) tcp_port = ntohs(sp->s_port); + sp = getservbyname(name, "udp"); + if (sp != NULL) udp_port = ntohs(sp->s_port); + if (tcp_port >= 0) { + *port = tcp_port; + *proto = IPPROTO_TCP; + if (udp_port >= 0) { + if (udp_port == tcp_port) + *proto = PROTO_UNDEF; #ifdef notdef - if (*port != sp->s_port) + else /* Can't handle ambiguous names that refer to different port numbers. */ warning("ambiguous port %s in /etc/services", name); #endif - *proto = PROTO_UNDEF; } return 1; } + if (udp_port >= 0) { + *port = udp_port; + *proto = IPPROTO_UDP; + return 1; + } #if defined(ultrix) || defined(__osf__) /* Special hack in case NFS isn't in /etc/services */ if (strcmp(name, "nfs") == 0) { @@ -161,6 +216,51 @@ pcap_nametoport(const char *name, int *port, int *proto) return 0; } +/* + * Convert a string in the form PPP-PPP, where correspond to ports, to + * a starting and ending port in a port range. + * Return 0 on failure. + */ +int +pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto) +{ + u_int p1, p2; + char *off, *cpy; + int save_proto; + + if (sscanf(name, "%d-%d", &p1, &p2) != 2) { + if ((cpy = strdup(name)) == NULL) + return 0; + + if ((off = strchr(cpy, '-')) == NULL) { + free(cpy); + return 0; + } + + *off = '\0'; + + if (pcap_nametoport(cpy, port1, proto) == 0) { + free(cpy); + return 0; + } + save_proto = *proto; + + if (pcap_nametoport(off + 1, port2, proto) == 0) { + free(cpy); + return 0; + } + + if (*proto != save_proto) + *proto = PROTO_UNDEF; + } else { + *port1 = p1; + *port2 = p2; + *proto = PROTO_UNDEF; + } + + return 1; +} + int pcap_nametoproto(const char *str) { @@ -176,7 +276,7 @@ pcap_nametoproto(const char *str) #include "ethertype.h" struct eproto { - char *s; + const char *s; u_short p; }; @@ -185,6 +285,9 @@ struct eproto eproto_db[] = { { "pup", ETHERTYPE_PUP }, { "xns", ETHERTYPE_NS }, { "ip", ETHERTYPE_IP }, +#ifdef INET6 + { "ip6", ETHERTYPE_IPV6 }, +#endif { "arp", ETHERTYPE_ARP }, { "rarp", ETHERTYPE_REVARP }, { "sprite", ETHERTYPE_SPRITE }, @@ -217,6 +320,30 @@ pcap_nametoeproto(const char *s) return PROTO_UNDEF; } +#include "llc.h" + +/* Static data base of LLC values. */ +static struct eproto llc_db[] = { + { "iso", LLCSAP_ISONS }, + { "stp", LLCSAP_8021D }, + { "ipx", LLCSAP_IPX }, + { "netbeui", LLCSAP_NETBEUI }, + { (char *)0, 0 } +}; + +int +pcap_nametollc(const char *s) +{ + struct eproto *p = llc_db; + + while (p->s != 0) { + if (strcmp(p->s, s) == 0) + return p->p; + p += 1; + } + return PROTO_UNDEF; +} + /* Hex digit to integer. */ static inline int xdtoi(c) @@ -261,7 +388,7 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr) u_int node, area; - if (sscanf((char *)s, "%d.%d", &area, &node) != 2) + if (sscanf(s, "%d.%d", &area, &node) != 2) bpf_error("malformed decnet address '%s'", s); *addr = (area << AREASHIFT) & AREAMASK; @@ -271,7 +398,15 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr) } /* - * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new + * Convert 's', which can have the one of the forms: + * + * "xx:xx:xx:xx:xx:xx" + * "xx.xx.xx.xx.xx.xx" + * "xx-xx-xx-xx-xx-xx" + * "xxxx.xxxx.xxxx" + * "xxxxxxxxxxxx" + * + * (or various mixes of ':', '.', and '-') into a new * ethernet address. Assumes 's' is well formed. */ u_char * @@ -283,10 +418,10 @@ pcap_ether_aton(const char *s) e = ep = (u_char *)malloc(6); while (*s) { - if (*s == ':') + if (*s == ':' || *s == '.' || *s == '-') s += 1; d = xdtoi(*s++); - if (isxdigit(*s)) { + if (isxdigit((unsigned char)*s)) { d <<= 4; d |= xdtoi(*s++); } @@ -304,7 +439,7 @@ pcap_ether_hostton(const char *name) register struct pcap_etherent *ep; register u_char *ap; static FILE *fp = NULL; - static init = 0; + static int init = 0; if (!init) { fp = fopen(PCAP_ETHERS_FILE, "r"); @@ -315,7 +450,7 @@ pcap_ether_hostton(const char *name) return (NULL); else rewind(fp); - + while ((ep = pcap_next_etherent(fp)) != NULL) { if (strcmp(ep->name, name) == 0) { ap = (u_char *)malloc(6); @@ -330,8 +465,13 @@ pcap_ether_hostton(const char *name) } #else -#ifndef sgi -extern int ether_hostton(char *, struct ether_addr *); +#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON +#ifndef HAVE_STRUCT_ETHER_ADDR +struct ether_addr { + unsigned char ether_addr_octet[6]; +}; +#endif +extern int ether_hostton(const char *, struct ether_addr *); #endif /* Use the os supplied routines */ @@ -342,7 +482,7 @@ pcap_ether_hostton(const char *name) u_char a[6]; ap = NULL; - if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) { + if (ether_hostton(name, (struct ether_addr *)a) == 0) { ap = (u_char *)malloc(6); if (ap != NULL) memcpy((char *)ap, (char *)a, 6); @@ -368,5 +508,6 @@ __pcap_nametodnaddr(const char *name) #else bpf_error("decnet name support not included, '%s' cannot be translated\n", name); + return(0); #endif } diff --git a/scanner.l b/scanner.l index 1231eaa..3d1085a 100644 --- a/scanner.l +++ b/scanner.l @@ -22,7 +22,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110.2.1 2007-11-18 02:04:55 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.110.2.2 2008-02-06 10:21:47 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -79,6 +79,7 @@ extern YYSTYPE yylval; N ([0-9]+|(0X|0x)[0-9A-Fa-f]+) B ([0-9A-Fa-f][0-9A-Fa-f]?) +B2 ([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]) W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?) %a 18400 @@ -166,6 +167,10 @@ V6004 ::{N}\.{N}\.{N}\.{N} V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004}) +MAC ({B}:{B}:{B}:{B}:{B}:{B}|{B}\-{B}\-{B}\-{B}\-{B}\-{B}|{B}\.{B}\.{B}\.{B}\.{B}\.{B}|{B2}\.{B2}\.{B2}|{B2}{3}) + + + %% dst return DST; src return SRC; @@ -315,11 +320,11 @@ sls return SLS; ">>" return RSH; ${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1); return AID; } +{MAC} { yylval.e = pcap_ether_aton((char *)yytext); + return EID; } {N} { yylval.i = stoi((char *)yytext); return NUM; } ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) { yylval.s = sdup((char *)yytext); return HID; } -{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext); - return EID; } {V6} { #ifdef INET6 struct addrinfo hints, *res;