X-Git-Url: https://git.tcpdump.org/libpcap/blobdiff_plain/08ef9a54d2613a53d847cc321c8ab3f9d43d15cf..cc3ca65d6519faf3a0e4609b5150757c14af36e9:/nametoaddr.c diff --git a/nametoaddr.c b/nametoaddr.c index 70b64ce5..71280b31 100644 --- a/nametoaddr.c +++ b/nametoaddr.c @@ -22,19 +22,45 @@ * These functions are not time critical. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.72 2003-12-24 08:27:04 itojun Exp $ (LBL)"; -#endif - #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef WIN32 +#ifdef DECNETLIB +#include +#include +#endif + +#ifdef _WIN32 #include -#else /* WIN32 */ +#ifdef INET6 +/* + * To quote the MSDN page for getaddrinfo() at + * + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx + * + * "Support for getaddrinfo on Windows 2000 and older versions + * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and + * later. To execute an application that uses this function on earlier + * versions of Windows, then you need to include the Ws2tcpip.h and + * Wspiapi.h files. When the Wspiapi.h include file is added, the + * getaddrinfo function is defined to the WspiapiGetAddrInfo inline + * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo + * function is implemented in such a way that if the Ws2_32.dll or the + * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology + * Preview for Windows 2000) does not include getaddrinfo, then a + * version of getaddrinfo is implemented inline based on code in the + * Wspiapi.h header file. This inline code will be used on older Windows + * platforms that do not natively support the getaddrinfo function." + * + * We use getaddrinfo(), so we include Wspiapi.h here. pcap-stdinc.h + * includes Ws2tcpip.h, so we don't need to include it ourselves. + */ +#include +#endif + +#else /* _WIN32 */ #include #include /* concession to AIX */ @@ -42,38 +68,39 @@ static const char rcsid[] _U_ = #include #include -#endif /* WIN32 */ +#endif /* _WIN32 */ +#ifndef _WIN32 +#ifdef HAVE_ETHER_HOSTTON /* - * XXX - why was this included even on UNIX? + * XXX - do we need any of this if doesn't declare + * ether_hostton()? */ -#ifdef __MINGW32__ -#include "IP6_misc.h" -#endif - -#ifndef WIN32 -#ifdef HAVE_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 */ +#endif /* _WIN32 */ #include #include #include -#include +#include #include #include "pcap-int.h" #include "gencode.h" -#include +#include +#include "nametoaddr.h" #ifdef HAVE_OS_PROTO_H #include "os-proto.h" @@ -124,7 +151,7 @@ pcap_nametoaddrinfo(const char *name) memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /*not really*/ - hints.ai_socktype = IPPROTO_TCP; /*not really*/ + hints.ai_protocol = IPPROTO_TCP; /*not really*/ error = getaddrinfo(name, NULL, &hints, &res); if (error) return NULL; @@ -140,7 +167,7 @@ pcap_nametoaddrinfo(const char *name) bpf_u_int32 pcap_nametonetaddr(const char *name) { -#ifndef WIN32 +#ifndef _WIN32 struct netent *np; if ((np = getnetbyname(name)) != NULL) @@ -150,6 +177,15 @@ pcap_nametonetaddr(const char *name) #else /* * There's no "getnetbyname()" on Windows. + * + * XXX - I guess we could use the BSD code to read + * C:\Windows\System32\drivers\etc/networks, assuming + * that's its home on all the versions of Windows + * we use, but that file probably just has the loopback + * network on 127/24 on 99 44/100% of Windows machines. + * + * (Heck, these days it probably just has that on 99 44/100% + * of *UN*X* machines.) */ return 0; #endif @@ -209,6 +245,52 @@ 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; + } + free(cpy); + + if (*proto != save_proto) + *proto = PROTO_UNDEF; + } else { + *port1 = p1; + *port2 = p2; + *proto = PROTO_UNDEF; + } + + return 1; +} + int pcap_nametoproto(const char *str) { @@ -224,12 +306,18 @@ pcap_nametoproto(const char *str) #include "ethertype.h" struct eproto { - char *s; + const char *s; u_short p; }; -/* Static data base of ether protocol types. */ -struct eproto eproto_db[] = { +/* + * Static data base of ether protocol types. + * tcpdump used to import this, and it's declared as an export on + * Debian, at least, so make it a public symbol, even though we + * don't officially export it by declaring it in a header file. + * (Programs *should* do this themselves, as tcpdump now does.) + */ +PCAP_API_DEF struct eproto eproto_db[] = { { "pup", ETHERTYPE_PUP }, { "xns", ETHERTYPE_NS }, { "ip", ETHERTYPE_IP }, @@ -268,6 +356,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) @@ -312,8 +424,8 @@ __pcap_atodn(const char *s, bpf_u_int32 *addr) u_int node, area; - if (sscanf((char *)s, "%d.%d", &area, &node) != 2) - bpf_error("malformed decnet address '%s'", s); + if (sscanf(s, "%d.%d", &area, &node) != 2) + return(0); *addr = (area << AREASHIFT) & AREAMASK; *addr |= (node & NODEMASK); @@ -322,7 +434,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 * @@ -332,9 +452,11 @@ pcap_ether_aton(const char *s) register u_int d; e = ep = (u_char *)malloc(6); + if (e == NULL) + return (NULL); while (*s) { - if (*s == ':') + if (*s == ':' || *s == '.' || *s == '-') s += 1; d = xdtoi(*s++); if (isxdigit((unsigned char)*s)) { @@ -381,18 +503,13 @@ pcap_ether_hostton(const char *name) } #else -/* - * XXX - perhaps this should, instead, be declared in "lbl/os-XXX.h" files, - * for those OS versions that don't declare it, rather than being declared - * here? That way, for example, we could declare it on FreeBSD 2.x (which - * doesn't declare it), but not on FreeBSD 3.x (which declares it like - * this) or FreeBSD 4.x (which declares it with its first argument as - * "const char *", so no matter how we declare it here, it'll fail to - * compile on one of 3.x or 4.x). - */ -#if !defined(sgi) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \ - !defined(_UNICOSMP) -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 */ @@ -403,7 +520,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); @@ -412,23 +529,20 @@ pcap_ether_hostton(const char *name) } #endif -u_short -__pcap_nametodnaddr(const char *name) +int +__pcap_nametodnaddr(const char *name, u_short *res) { #ifdef DECNETLIB struct nodeent *getnodebyname(); struct nodeent *nep; - unsigned short res; nep = getnodebyname(name); if (nep == ((struct nodeent *)0)) - bpf_error("unknown decnet host name '%s'\n", name); + return(0); - memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short)); - return(res); + memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short)); + return(1); #else - bpf_error("decnet name support not included, '%s' cannot be translated\n", - name); return(0); #endif }