xref: /dflybsd-src/contrib/libpcap/nametoaddr.c (revision e75ef36f1332e115895388cede9dfd24ca1a806c)
11077d0bdSPeter Avalos /*
21077d0bdSPeter Avalos  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
31077d0bdSPeter Avalos  *	The Regents of the University of California.  All rights reserved.
41077d0bdSPeter Avalos  *
51077d0bdSPeter Avalos  * Redistribution and use in source and binary forms, with or without
61077d0bdSPeter Avalos  * modification, are permitted provided that: (1) source code distributions
71077d0bdSPeter Avalos  * retain the above copyright notice and this paragraph in its entirety, (2)
81077d0bdSPeter Avalos  * distributions including binary code include the above copyright notice and
91077d0bdSPeter Avalos  * this paragraph in its entirety in the documentation or other materials
101077d0bdSPeter Avalos  * provided with the distribution, and (3) all advertising materials mentioning
111077d0bdSPeter Avalos  * features or use of this software display the following acknowledgement:
121077d0bdSPeter Avalos  * ``This product includes software developed by the University of California,
131077d0bdSPeter Avalos  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
141077d0bdSPeter Avalos  * the University nor the names of its contributors may be used to endorse
151077d0bdSPeter Avalos  * or promote products derived from this software without specific prior
161077d0bdSPeter Avalos  * written permission.
171077d0bdSPeter Avalos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
181077d0bdSPeter Avalos  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
191077d0bdSPeter Avalos  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
201077d0bdSPeter Avalos  *
211077d0bdSPeter Avalos  * Name to id translation routines used by the scanner.
221077d0bdSPeter Avalos  * These functions are not time critical.
231077d0bdSPeter Avalos  */
241077d0bdSPeter Avalos 
251077d0bdSPeter Avalos #ifdef HAVE_CONFIG_H
263a289941SAaron LI #include <config.h>
271077d0bdSPeter Avalos #endif
281077d0bdSPeter Avalos 
29a85e14b0SPeter Avalos #ifdef DECNETLIB
30a85e14b0SPeter Avalos #include <sys/types.h>
31a85e14b0SPeter Avalos #include <netdnet/dnetdb.h>
32a85e14b0SPeter Avalos #endif
33a85e14b0SPeter Avalos 
3497a9217aSAntonio Huete Jimenez #ifdef _WIN32
353a289941SAaron LI   #include <winsock2.h>
363a289941SAaron LI   #include <ws2tcpip.h>
371077d0bdSPeter Avalos 
3897a9217aSAntonio Huete Jimenez   #ifdef INET6
3997a9217aSAntonio Huete Jimenez     /*
4097a9217aSAntonio Huete Jimenez      * To quote the MSDN page for getaddrinfo() at
4197a9217aSAntonio Huete Jimenez      *
4297a9217aSAntonio Huete Jimenez      *    https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
4397a9217aSAntonio Huete Jimenez      *
4497a9217aSAntonio Huete Jimenez      * "Support for getaddrinfo on Windows 2000 and older versions
4597a9217aSAntonio Huete Jimenez      * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
4697a9217aSAntonio Huete Jimenez      * later. To execute an application that uses this function on earlier
4797a9217aSAntonio Huete Jimenez      * versions of Windows, then you need to include the Ws2tcpip.h and
4897a9217aSAntonio Huete Jimenez      * Wspiapi.h files. When the Wspiapi.h include file is added, the
4997a9217aSAntonio Huete Jimenez      * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
5097a9217aSAntonio Huete Jimenez      * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
5197a9217aSAntonio Huete Jimenez      * function is implemented in such a way that if the Ws2_32.dll or the
5297a9217aSAntonio Huete Jimenez      * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
5397a9217aSAntonio Huete Jimenez      * Preview for Windows 2000) does not include getaddrinfo, then a
5497a9217aSAntonio Huete Jimenez      * version of getaddrinfo is implemented inline based on code in the
5597a9217aSAntonio Huete Jimenez      * Wspiapi.h header file. This inline code will be used on older Windows
5697a9217aSAntonio Huete Jimenez      * platforms that do not natively support the getaddrinfo function."
5797a9217aSAntonio Huete Jimenez      *
583a289941SAaron LI      * We use getaddrinfo(), so we include Wspiapi.h here.
5997a9217aSAntonio Huete Jimenez      */
603a289941SAaron LI     #include <wspiapi.h>
613a289941SAaron LI   #endif /* INET6 */
6297a9217aSAntonio Huete Jimenez #else /* _WIN32 */
631077d0bdSPeter Avalos   #include <sys/param.h>
643a289941SAaron LI   #include <sys/types.h>
651077d0bdSPeter Avalos   #include <sys/socket.h>
661077d0bdSPeter Avalos   #include <sys/time.h>
671077d0bdSPeter Avalos 
681077d0bdSPeter Avalos   #include <netinet/in.h>
691077d0bdSPeter Avalos 
701077d0bdSPeter Avalos   #ifdef HAVE_ETHER_HOSTTON
713a289941SAaron LI     #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
721077d0bdSPeter Avalos       /*
733a289941SAaron LI        * OK, just include <net/ethernet.h>.
741077d0bdSPeter Avalos        */
753a289941SAaron LI       #include <net/ethernet.h>
763a289941SAaron LI     #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
773a289941SAaron LI       /*
783a289941SAaron LI        * OK, just include <netinet/ether.h>
793a289941SAaron LI        */
801077d0bdSPeter Avalos       #include <netinet/ether.h>
813a289941SAaron LI     #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
823a289941SAaron LI       /*
833a289941SAaron LI        * OK, just include <sys/ethernet.h>
843a289941SAaron LI        */
853a289941SAaron LI       #include <sys/ethernet.h>
863a289941SAaron LI     #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
873a289941SAaron LI       /*
883a289941SAaron LI        * OK, just include <arpa/inet.h>
893a289941SAaron LI        */
903a289941SAaron LI       #include <arpa/inet.h>
913a289941SAaron LI     #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
923a289941SAaron LI       /*
933a289941SAaron LI        * OK, include <netinet/if_ether.h>, after all the other stuff we
943a289941SAaron LI        * need to include or define for its benefit.
953a289941SAaron LI        */
963a289941SAaron LI       #define NEED_NETINET_IF_ETHER_H
973a289941SAaron LI     #else
983a289941SAaron LI       /*
993a289941SAaron LI        * We'll have to declare it ourselves.
1003a289941SAaron LI        * If <netinet/if_ether.h> defines struct ether_addr, include
1013a289941SAaron LI        * it.  Otherwise, define it ourselves.
1023a289941SAaron LI        */
1033a289941SAaron LI       #ifdef HAVE_STRUCT_ETHER_ADDR
1043a289941SAaron LI         #define NEED_NETINET_IF_ETHER_H
1053a289941SAaron LI       #else /* HAVE_STRUCT_ETHER_ADDR */
1063a289941SAaron LI 	struct ether_addr {
1073a289941SAaron LI 		unsigned char ether_addr_octet[6];
1083a289941SAaron LI 	};
1093a289941SAaron LI       #endif /* HAVE_STRUCT_ETHER_ADDR */
1103a289941SAaron LI     #endif /* what declares ether_hostton() */
1113a289941SAaron LI 
1123a289941SAaron LI     #ifdef NEED_NETINET_IF_ETHER_H
1133a289941SAaron LI       #include <net/if.h>	/* Needed on some platforms */
1143a289941SAaron LI       #include <netinet/in.h>	/* Needed on some platforms */
1153a289941SAaron LI       #include <netinet/if_ether.h>
1163a289941SAaron LI     #endif /* NEED_NETINET_IF_ETHER_H */
1173a289941SAaron LI 
1183a289941SAaron LI     #ifndef HAVE_DECL_ETHER_HOSTTON
1193a289941SAaron LI       /*
1203a289941SAaron LI        * No header declares it, so declare it ourselves.
1213a289941SAaron LI        */
1223a289941SAaron LI       extern int ether_hostton(const char *, struct ether_addr *);
1233a289941SAaron LI     #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
1241077d0bdSPeter Avalos   #endif /* HAVE_ETHER_HOSTTON */
1253a289941SAaron LI 
1261077d0bdSPeter Avalos   #include <arpa/inet.h>
1271077d0bdSPeter Avalos   #include <netdb.h>
12897a9217aSAntonio Huete Jimenez #endif /* _WIN32 */
1291077d0bdSPeter Avalos 
1301077d0bdSPeter Avalos #include <errno.h>
1311077d0bdSPeter Avalos #include <stdlib.h>
1321077d0bdSPeter Avalos #include <string.h>
1331077d0bdSPeter Avalos #include <stdio.h>
1341077d0bdSPeter Avalos 
1351077d0bdSPeter Avalos #include "pcap-int.h"
1361077d0bdSPeter Avalos 
137*ea16f64eSAntonio Huete Jimenez #include "diag-control.h"
138*ea16f64eSAntonio Huete Jimenez 
1391077d0bdSPeter Avalos #include "gencode.h"
140de0d3203SPeter Avalos #include <pcap/namedb.h>
14197a9217aSAntonio Huete Jimenez #include "nametoaddr.h"
1421077d0bdSPeter Avalos 
1431077d0bdSPeter Avalos #ifdef HAVE_OS_PROTO_H
1441077d0bdSPeter Avalos #include "os-proto.h"
1451077d0bdSPeter Avalos #endif
1461077d0bdSPeter Avalos 
1471077d0bdSPeter Avalos #ifndef NTOHL
1481077d0bdSPeter Avalos #define NTOHL(x) (x) = ntohl(x)
1491077d0bdSPeter Avalos #define NTOHS(x) (x) = ntohs(x)
1501077d0bdSPeter Avalos #endif
1511077d0bdSPeter Avalos 
1521077d0bdSPeter Avalos /*
1531077d0bdSPeter Avalos  *  Convert host name to internet address.
1541077d0bdSPeter Avalos  *  Return 0 upon failure.
1553a289941SAaron LI  *  XXX - not thread-safe; don't use it inside libpcap.
1561077d0bdSPeter Avalos  */
1571077d0bdSPeter Avalos bpf_u_int32 **
pcap_nametoaddr(const char * name)1581077d0bdSPeter Avalos pcap_nametoaddr(const char *name)
1591077d0bdSPeter Avalos {
1601077d0bdSPeter Avalos #ifndef h_addr
1611077d0bdSPeter Avalos 	static bpf_u_int32 *hlist[2];
1621077d0bdSPeter Avalos #endif
1631077d0bdSPeter Avalos 	bpf_u_int32 **p;
1641077d0bdSPeter Avalos 	struct hostent *hp;
1651077d0bdSPeter Avalos 
166*ea16f64eSAntonio Huete Jimenez 	/*
167*ea16f64eSAntonio Huete Jimenez 	 * gethostbyname() is deprecated on Windows, perhaps because
168*ea16f64eSAntonio Huete Jimenez 	 * it's not thread-safe, or because it doesn't support IPv6,
169*ea16f64eSAntonio Huete Jimenez 	 * or both.
170*ea16f64eSAntonio Huete Jimenez 	 *
171*ea16f64eSAntonio Huete Jimenez 	 * We deprecate pcap_nametoaddr() on all platforms because
172*ea16f64eSAntonio Huete Jimenez 	 * it's not thread-safe; we supply it for backwards compatibility,
173*ea16f64eSAntonio Huete Jimenez 	 * so suppress the deprecation warning.  We could, I guess,
174*ea16f64eSAntonio Huete Jimenez 	 * use getaddrinfo() and construct the array ourselves, but
175*ea16f64eSAntonio Huete Jimenez 	 * that's probably not worth the effort, as that wouldn't make
176*ea16f64eSAntonio Huete Jimenez 	 * this thread-safe - we can't change the API to require that
177*ea16f64eSAntonio Huete Jimenez 	 * our caller free the address array, so we still have to reuse
178*ea16f64eSAntonio Huete Jimenez 	 * a local array.
179*ea16f64eSAntonio Huete Jimenez 	 */
180*ea16f64eSAntonio Huete Jimenez DIAG_OFF_DEPRECATION
1811077d0bdSPeter Avalos 	if ((hp = gethostbyname(name)) != NULL) {
182*ea16f64eSAntonio Huete Jimenez DIAG_ON_DEPRECATION
1831077d0bdSPeter Avalos #ifndef h_addr
1841077d0bdSPeter Avalos 		hlist[0] = (bpf_u_int32 *)hp->h_addr;
1851077d0bdSPeter Avalos 		NTOHL(hp->h_addr);
1861077d0bdSPeter Avalos 		return hlist;
1871077d0bdSPeter Avalos #else
1881077d0bdSPeter Avalos 		for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
1891077d0bdSPeter Avalos 			NTOHL(**p);
1901077d0bdSPeter Avalos 		return (bpf_u_int32 **)hp->h_addr_list;
1911077d0bdSPeter Avalos #endif
1921077d0bdSPeter Avalos 	}
1931077d0bdSPeter Avalos 	else
1941077d0bdSPeter Avalos 		return 0;
1951077d0bdSPeter Avalos }
1961077d0bdSPeter Avalos 
1971077d0bdSPeter Avalos struct addrinfo *
pcap_nametoaddrinfo(const char * name)1981077d0bdSPeter Avalos pcap_nametoaddrinfo(const char *name)
1991077d0bdSPeter Avalos {
2001077d0bdSPeter Avalos 	struct addrinfo hints, *res;
2011077d0bdSPeter Avalos 	int error;
2021077d0bdSPeter Avalos 
2031077d0bdSPeter Avalos 	memset(&hints, 0, sizeof(hints));
2041077d0bdSPeter Avalos 	hints.ai_family = PF_UNSPEC;
2051077d0bdSPeter Avalos 	hints.ai_socktype = SOCK_STREAM;	/*not really*/
2061077d0bdSPeter Avalos 	hints.ai_protocol = IPPROTO_TCP;	/*not really*/
2071077d0bdSPeter Avalos 	error = getaddrinfo(name, NULL, &hints, &res);
2081077d0bdSPeter Avalos 	if (error)
2091077d0bdSPeter Avalos 		return NULL;
2101077d0bdSPeter Avalos 	else
2111077d0bdSPeter Avalos 		return res;
2121077d0bdSPeter Avalos }
2131077d0bdSPeter Avalos 
2141077d0bdSPeter Avalos /*
2151077d0bdSPeter Avalos  *  Convert net name to internet address.
2161077d0bdSPeter Avalos  *  Return 0 upon failure.
2173a289941SAaron LI  *  XXX - not guaranteed to be thread-safe!  See below for platforms
2183a289941SAaron LI  *  on which it is thread-safe and on which it isn't.
2191077d0bdSPeter Avalos  */
220*ea16f64eSAntonio Huete Jimenez #if defined(_WIN32) || defined(__CYGWIN__)
2211077d0bdSPeter Avalos bpf_u_int32
pcap_nametonetaddr(const char * name _U_)222*ea16f64eSAntonio Huete Jimenez pcap_nametonetaddr(const char *name _U_)
2231077d0bdSPeter Avalos {
2241077d0bdSPeter Avalos 	/*
2251077d0bdSPeter Avalos 	 * There's no "getnetbyname()" on Windows.
22697a9217aSAntonio Huete Jimenez 	 *
22797a9217aSAntonio Huete Jimenez 	 * XXX - I guess we could use the BSD code to read
22897a9217aSAntonio Huete Jimenez 	 * C:\Windows\System32\drivers\etc/networks, assuming
22997a9217aSAntonio Huete Jimenez 	 * that's its home on all the versions of Windows
23097a9217aSAntonio Huete Jimenez 	 * we use, but that file probably just has the loopback
23197a9217aSAntonio Huete Jimenez 	 * network on 127/24 on 99 44/100% of Windows machines.
23297a9217aSAntonio Huete Jimenez 	 *
23397a9217aSAntonio Huete Jimenez 	 * (Heck, these days it probably just has that on 99 44/100%
23497a9217aSAntonio Huete Jimenez 	 * of *UN*X* machines.)
2351077d0bdSPeter Avalos 	 */
2361077d0bdSPeter Avalos 	return 0;
237*ea16f64eSAntonio Huete Jimenez }
238*ea16f64eSAntonio Huete Jimenez #else /* _WIN32 */
239*ea16f64eSAntonio Huete Jimenez bpf_u_int32
pcap_nametonetaddr(const char * name)240*ea16f64eSAntonio Huete Jimenez pcap_nametonetaddr(const char *name)
241*ea16f64eSAntonio Huete Jimenez {
2423a289941SAaron LI 	/*
2433a289941SAaron LI 	 * UN*X.
2443a289941SAaron LI 	 */
2453a289941SAaron LI 	struct netent *np;
2463a289941SAaron LI   #if defined(HAVE_LINUX_GETNETBYNAME_R)
2473a289941SAaron LI 	/*
2483a289941SAaron LI 	 * We have Linux's reentrant getnetbyname_r().
2493a289941SAaron LI 	 */
2503a289941SAaron LI 	struct netent result_buf;
2513a289941SAaron LI 	char buf[1024];	/* arbitrary size */
2523a289941SAaron LI 	int h_errnoval;
2533a289941SAaron LI 	int err;
2543a289941SAaron LI 
2553a289941SAaron LI 	/*
2563a289941SAaron LI 	 * Apparently, the man page at
2573a289941SAaron LI 	 *
2583a289941SAaron LI 	 *    http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html
2593a289941SAaron LI 	 *
2603a289941SAaron LI 	 * lies when it says
2613a289941SAaron LI 	 *
2623a289941SAaron LI 	 *    If the function call successfully obtains a network record,
2633a289941SAaron LI 	 *    then *result is set pointing to result_buf; otherwise, *result
2643a289941SAaron LI 	 *    is set to NULL.
2653a289941SAaron LI 	 *
2663a289941SAaron LI 	 * and, in fact, at least in some versions of GNU libc, it does
2673a289941SAaron LI 	 * *not* always get set if getnetbyname_r() succeeds.
2683a289941SAaron LI 	 */
2693a289941SAaron LI 	np = NULL;
2703a289941SAaron LI  	err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
2713a289941SAaron LI 	    &h_errnoval);
2723a289941SAaron LI 	if (err != 0) {
2733a289941SAaron LI 		/*
2743a289941SAaron LI 		 * XXX - dynamically allocate the buffer, and make it
2753a289941SAaron LI 		 * bigger if we get ERANGE back?
2763a289941SAaron LI 		 */
2773a289941SAaron LI 		return 0;
2783a289941SAaron LI 	}
2793a289941SAaron LI   #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
2803a289941SAaron LI 	/*
2813a289941SAaron LI 	 * We have Solaris's and IRIX's reentrant getnetbyname_r().
2823a289941SAaron LI 	 */
2833a289941SAaron LI 	struct netent result_buf;
2843a289941SAaron LI 	char buf[1024];	/* arbitrary size */
2853a289941SAaron LI 
2863a289941SAaron LI 	np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
2873a289941SAaron LI   #elif defined(HAVE_AIX_GETNETBYNAME_R)
2883a289941SAaron LI 	/*
2893a289941SAaron LI 	 * We have AIX's reentrant getnetbyname_r().
2903a289941SAaron LI 	 */
2913a289941SAaron LI 	struct netent result_buf;
2923a289941SAaron LI 	struct netent_data net_data;
2933a289941SAaron LI 
2943a289941SAaron LI 	if (getnetbyname_r(name, &result_buf, &net_data) == -1)
2953a289941SAaron LI 		np = NULL;
2963a289941SAaron LI 	else
2973a289941SAaron LI 		np = &result_buf;
2983a289941SAaron LI   #else
2993a289941SAaron LI  	/*
3003a289941SAaron LI  	 * We don't have any getnetbyname_r(); either we have a
3013a289941SAaron LI  	 * getnetbyname() that uses thread-specific data, in which
3023a289941SAaron LI  	 * case we're thread-safe (sufficiently recent FreeBSD,
3033a289941SAaron LI  	 * sufficiently recent Darwin-based OS, sufficiently recent
3043a289941SAaron LI  	 * HP-UX, sufficiently recent Tru64 UNIX), or we have the
3053a289941SAaron LI  	 * traditional getnetbyname() (everything else, including
3063a289941SAaron LI  	 * current NetBSD and OpenBSD), in which case we're not
3073a289941SAaron LI  	 * thread-safe.
3083a289941SAaron LI  	 */
3093a289941SAaron LI 	np = getnetbyname(name);
3101077d0bdSPeter Avalos   #endif
3113a289941SAaron LI 	if (np != NULL)
3123a289941SAaron LI 		return np->n_net;
3133a289941SAaron LI 	else
3143a289941SAaron LI 		return 0;
3151077d0bdSPeter Avalos }
316*ea16f64eSAntonio Huete Jimenez #endif /* _WIN32 */
3171077d0bdSPeter Avalos 
3181077d0bdSPeter Avalos /*
3191077d0bdSPeter Avalos  * Convert a port name to its port and protocol numbers.
3201077d0bdSPeter Avalos  * We assume only TCP or UDP.
3211077d0bdSPeter Avalos  * Return 0 upon failure.
3221077d0bdSPeter Avalos  */
3231077d0bdSPeter Avalos int
pcap_nametoport(const char * name,int * port,int * proto)3241077d0bdSPeter Avalos pcap_nametoport(const char *name, int *port, int *proto)
3251077d0bdSPeter Avalos {
3263a289941SAaron LI 	struct addrinfo hints, *res, *ai;
3273a289941SAaron LI 	int error;
3283a289941SAaron LI 	struct sockaddr_in *in4;
3293a289941SAaron LI #ifdef INET6
3303a289941SAaron LI 	struct sockaddr_in6 *in6;
3313a289941SAaron LI #endif
3321077d0bdSPeter Avalos 	int tcp_port = -1;
3331077d0bdSPeter Avalos 	int udp_port = -1;
3341077d0bdSPeter Avalos 
3351077d0bdSPeter Avalos 	/*
3363a289941SAaron LI 	 * We check for both TCP and UDP in case there are
3373a289941SAaron LI 	 * ambiguous entries.
3383a289941SAaron LI 	 */
3393a289941SAaron LI 	memset(&hints, 0, sizeof(hints));
3403a289941SAaron LI 	hints.ai_family = PF_UNSPEC;
3413a289941SAaron LI 	hints.ai_socktype = SOCK_STREAM;
3423a289941SAaron LI 	hints.ai_protocol = IPPROTO_TCP;
3433a289941SAaron LI 	error = getaddrinfo(NULL, name, &hints, &res);
3443a289941SAaron LI 	if (error != 0) {
3453a289941SAaron LI 		if (error != EAI_NONAME &&
3463a289941SAaron LI 		    error != EAI_SERVICE) {
3473a289941SAaron LI 			/*
3483a289941SAaron LI 			 * This is a real error, not just "there's
3493a289941SAaron LI 			 * no such service name".
3503a289941SAaron LI 			 * XXX - this doesn't return an error string.
3513a289941SAaron LI 			 */
3523a289941SAaron LI 			return 0;
3533a289941SAaron LI 		}
3543a289941SAaron LI 	} else {
3553a289941SAaron LI 		/*
3563a289941SAaron LI 		 * OK, we found it.  Did it find anything?
3573a289941SAaron LI 		 */
3583a289941SAaron LI 		for (ai = res; ai != NULL; ai = ai->ai_next) {
3593a289941SAaron LI 			/*
3603a289941SAaron LI 			 * Does it have an address?
3613a289941SAaron LI 			 */
3623a289941SAaron LI 			if (ai->ai_addr != NULL) {
3633a289941SAaron LI 				/*
3643a289941SAaron LI 				 * Yes.  Get a port number; we're done.
3653a289941SAaron LI 				 */
3663a289941SAaron LI 				if (ai->ai_addr->sa_family == AF_INET) {
3673a289941SAaron LI 					in4 = (struct sockaddr_in *)ai->ai_addr;
3683a289941SAaron LI 					tcp_port = ntohs(in4->sin_port);
3693a289941SAaron LI 					break;
3703a289941SAaron LI 				}
3713a289941SAaron LI #ifdef INET6
3723a289941SAaron LI 				if (ai->ai_addr->sa_family == AF_INET6) {
3733a289941SAaron LI 					in6 = (struct sockaddr_in6 *)ai->ai_addr;
3743a289941SAaron LI 					tcp_port = ntohs(in6->sin6_port);
3753a289941SAaron LI 					break;
3763a289941SAaron LI 				}
3773a289941SAaron LI #endif
3783a289941SAaron LI 			}
3793a289941SAaron LI 		}
3803a289941SAaron LI 		freeaddrinfo(res);
3813a289941SAaron LI 	}
3823a289941SAaron LI 
3833a289941SAaron LI 	memset(&hints, 0, sizeof(hints));
3843a289941SAaron LI 	hints.ai_family = PF_UNSPEC;
3853a289941SAaron LI 	hints.ai_socktype = SOCK_DGRAM;
3863a289941SAaron LI 	hints.ai_protocol = IPPROTO_UDP;
3873a289941SAaron LI 	error = getaddrinfo(NULL, name, &hints, &res);
3883a289941SAaron LI 	if (error != 0) {
3893a289941SAaron LI 		if (error != EAI_NONAME &&
3903a289941SAaron LI 		    error != EAI_SERVICE) {
3913a289941SAaron LI 			/*
3923a289941SAaron LI 			 * This is a real error, not just "there's
3933a289941SAaron LI 			 * no such service name".
3943a289941SAaron LI 			 * XXX - this doesn't return an error string.
3953a289941SAaron LI 			 */
3963a289941SAaron LI 			return 0;
3973a289941SAaron LI 		}
3983a289941SAaron LI 	} else {
3993a289941SAaron LI 		/*
4003a289941SAaron LI 		 * OK, we found it.  Did it find anything?
4013a289941SAaron LI 		 */
4023a289941SAaron LI 		for (ai = res; ai != NULL; ai = ai->ai_next) {
4033a289941SAaron LI 			/*
4043a289941SAaron LI 			 * Does it have an address?
4053a289941SAaron LI 			 */
4063a289941SAaron LI 			if (ai->ai_addr != NULL) {
4073a289941SAaron LI 				/*
4083a289941SAaron LI 				 * Yes.  Get a port number; we're done.
4093a289941SAaron LI 				 */
4103a289941SAaron LI 				if (ai->ai_addr->sa_family == AF_INET) {
4113a289941SAaron LI 					in4 = (struct sockaddr_in *)ai->ai_addr;
4123a289941SAaron LI 					udp_port = ntohs(in4->sin_port);
4133a289941SAaron LI 					break;
4143a289941SAaron LI 				}
4153a289941SAaron LI #ifdef INET6
4163a289941SAaron LI 				if (ai->ai_addr->sa_family == AF_INET6) {
4173a289941SAaron LI 					in6 = (struct sockaddr_in6 *)ai->ai_addr;
4183a289941SAaron LI 					udp_port = ntohs(in6->sin6_port);
4193a289941SAaron LI 					break;
4203a289941SAaron LI 				}
4213a289941SAaron LI #endif
4223a289941SAaron LI 			}
4233a289941SAaron LI 		}
4243a289941SAaron LI 		freeaddrinfo(res);
4253a289941SAaron LI 	}
4263a289941SAaron LI 
4273a289941SAaron LI 	/*
4281077d0bdSPeter Avalos 	 * We need to check /etc/services for ambiguous entries.
4293a289941SAaron LI 	 * If we find an ambiguous entry, and it has the
4301077d0bdSPeter Avalos 	 * same port number, change the proto to PROTO_UNDEF
4311077d0bdSPeter Avalos 	 * so both TCP and UDP will be checked.
4321077d0bdSPeter Avalos 	 */
4331077d0bdSPeter Avalos 	if (tcp_port >= 0) {
4341077d0bdSPeter Avalos 		*port = tcp_port;
4351077d0bdSPeter Avalos 		*proto = IPPROTO_TCP;
4361077d0bdSPeter Avalos 		if (udp_port >= 0) {
4371077d0bdSPeter Avalos 			if (udp_port == tcp_port)
4381077d0bdSPeter Avalos 				*proto = PROTO_UNDEF;
4391077d0bdSPeter Avalos #ifdef notdef
4401077d0bdSPeter Avalos 			else
4411077d0bdSPeter Avalos 				/* Can't handle ambiguous names that refer
4421077d0bdSPeter Avalos 				   to different port numbers. */
4431077d0bdSPeter Avalos 				warning("ambiguous port %s in /etc/services",
4441077d0bdSPeter Avalos 					name);
4451077d0bdSPeter Avalos #endif
4461077d0bdSPeter Avalos 		}
4471077d0bdSPeter Avalos 		return 1;
4481077d0bdSPeter Avalos 	}
4491077d0bdSPeter Avalos 	if (udp_port >= 0) {
4501077d0bdSPeter Avalos 		*port = udp_port;
4511077d0bdSPeter Avalos 		*proto = IPPROTO_UDP;
4521077d0bdSPeter Avalos 		return 1;
4531077d0bdSPeter Avalos 	}
4541077d0bdSPeter Avalos #if defined(ultrix) || defined(__osf__)
4551077d0bdSPeter Avalos 	/* Special hack in case NFS isn't in /etc/services */
4561077d0bdSPeter Avalos 	if (strcmp(name, "nfs") == 0) {
4571077d0bdSPeter Avalos 		*port = 2049;
4581077d0bdSPeter Avalos 		*proto = PROTO_UNDEF;
4591077d0bdSPeter Avalos 		return 1;
4601077d0bdSPeter Avalos 	}
4611077d0bdSPeter Avalos #endif
4621077d0bdSPeter Avalos 	return 0;
4631077d0bdSPeter Avalos }
4641077d0bdSPeter Avalos 
4651077d0bdSPeter Avalos /*
4661077d0bdSPeter Avalos  * Convert a string in the form PPP-PPP, where correspond to ports, to
4671077d0bdSPeter Avalos  * a starting and ending port in a port range.
4681077d0bdSPeter Avalos  * Return 0 on failure.
4691077d0bdSPeter Avalos  */
4701077d0bdSPeter Avalos int
pcap_nametoportrange(const char * name,int * port1,int * port2,int * proto)4711077d0bdSPeter Avalos pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
4721077d0bdSPeter Avalos {
4731077d0bdSPeter Avalos 	u_int p1, p2;
4741077d0bdSPeter Avalos 	char *off, *cpy;
4751077d0bdSPeter Avalos 	int save_proto;
4761077d0bdSPeter Avalos 
4771077d0bdSPeter Avalos 	if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
4781077d0bdSPeter Avalos 		if ((cpy = strdup(name)) == NULL)
4791077d0bdSPeter Avalos 			return 0;
4801077d0bdSPeter Avalos 
4811077d0bdSPeter Avalos 		if ((off = strchr(cpy, '-')) == NULL) {
4821077d0bdSPeter Avalos 			free(cpy);
4831077d0bdSPeter Avalos 			return 0;
4841077d0bdSPeter Avalos 		}
4851077d0bdSPeter Avalos 
4861077d0bdSPeter Avalos 		*off = '\0';
4871077d0bdSPeter Avalos 
4881077d0bdSPeter Avalos 		if (pcap_nametoport(cpy, port1, proto) == 0) {
4891077d0bdSPeter Avalos 			free(cpy);
4901077d0bdSPeter Avalos 			return 0;
4911077d0bdSPeter Avalos 		}
4921077d0bdSPeter Avalos 		save_proto = *proto;
4931077d0bdSPeter Avalos 
4941077d0bdSPeter Avalos 		if (pcap_nametoport(off + 1, port2, proto) == 0) {
4951077d0bdSPeter Avalos 			free(cpy);
4961077d0bdSPeter Avalos 			return 0;
4971077d0bdSPeter Avalos 		}
4980e381983SMatthew Dillon 		free(cpy);
4991077d0bdSPeter Avalos 
5001077d0bdSPeter Avalos 		if (*proto != save_proto)
5011077d0bdSPeter Avalos 			*proto = PROTO_UNDEF;
5021077d0bdSPeter Avalos 	} else {
5031077d0bdSPeter Avalos 		*port1 = p1;
5041077d0bdSPeter Avalos 		*port2 = p2;
5051077d0bdSPeter Avalos 		*proto = PROTO_UNDEF;
5061077d0bdSPeter Avalos 	}
5071077d0bdSPeter Avalos 
5081077d0bdSPeter Avalos 	return 1;
5091077d0bdSPeter Avalos }
5101077d0bdSPeter Avalos 
5113a289941SAaron LI /*
5123a289941SAaron LI  * XXX - not guaranteed to be thread-safe!  See below for platforms
5133a289941SAaron LI  * on which it is thread-safe and on which it isn't.
5143a289941SAaron LI  */
5151077d0bdSPeter Avalos int
pcap_nametoproto(const char * str)5161077d0bdSPeter Avalos pcap_nametoproto(const char *str)
5171077d0bdSPeter Avalos {
5181077d0bdSPeter Avalos 	struct protoent *p;
5193a289941SAaron LI   #if defined(HAVE_LINUX_GETNETBYNAME_R)
5203a289941SAaron LI 	/*
5213a289941SAaron LI 	 * We have Linux's reentrant getprotobyname_r().
5223a289941SAaron LI 	 */
5233a289941SAaron LI 	struct protoent result_buf;
5243a289941SAaron LI 	char buf[1024];	/* arbitrary size */
5253a289941SAaron LI 	int err;
5261077d0bdSPeter Avalos 
5273a289941SAaron LI 	err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
5283a289941SAaron LI 	if (err != 0) {
5293a289941SAaron LI 		/*
5303a289941SAaron LI 		 * XXX - dynamically allocate the buffer, and make it
5313a289941SAaron LI 		 * bigger if we get ERANGE back?
5323a289941SAaron LI 		 */
5333a289941SAaron LI 		return 0;
5343a289941SAaron LI 	}
5353a289941SAaron LI   #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
5363a289941SAaron LI 	/*
5373a289941SAaron LI 	 * We have Solaris's and IRIX's reentrant getprotobyname_r().
5383a289941SAaron LI 	 */
5393a289941SAaron LI 	struct protoent result_buf;
5403a289941SAaron LI 	char buf[1024];	/* arbitrary size */
5413a289941SAaron LI 
5423a289941SAaron LI 	p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
5433a289941SAaron LI   #elif defined(HAVE_AIX_GETNETBYNAME_R)
5443a289941SAaron LI 	/*
5453a289941SAaron LI 	 * We have AIX's reentrant getprotobyname_r().
5463a289941SAaron LI 	 */
5473a289941SAaron LI 	struct protoent result_buf;
5483a289941SAaron LI 	struct protoent_data proto_data;
5493a289941SAaron LI 
5503a289941SAaron LI 	if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
5513a289941SAaron LI 		p = NULL;
5523a289941SAaron LI 	else
5533a289941SAaron LI 		p = &result_buf;
5543a289941SAaron LI   #else
5553a289941SAaron LI  	/*
5563a289941SAaron LI  	 * We don't have any getprotobyname_r(); either we have a
5573a289941SAaron LI  	 * getprotobyname() that uses thread-specific data, in which
5583a289941SAaron LI  	 * case we're thread-safe (sufficiently recent FreeBSD,
5593a289941SAaron LI  	 * sufficiently recent Darwin-based OS, sufficiently recent
5603a289941SAaron LI  	 * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
5613a289941SAaron LI 	 * the traditional getprotobyname() (everything else, including
5623a289941SAaron LI  	 * current NetBSD and OpenBSD), in which case we're not
5633a289941SAaron LI  	 * thread-safe.
5643a289941SAaron LI  	 */
5651077d0bdSPeter Avalos 	p = getprotobyname(str);
5663a289941SAaron LI   #endif
5671077d0bdSPeter Avalos 	if (p != 0)
5681077d0bdSPeter Avalos 		return p->p_proto;
5691077d0bdSPeter Avalos 	else
5701077d0bdSPeter Avalos 		return PROTO_UNDEF;
5711077d0bdSPeter Avalos }
5721077d0bdSPeter Avalos 
5731077d0bdSPeter Avalos #include "ethertype.h"
5741077d0bdSPeter Avalos 
5751077d0bdSPeter Avalos struct eproto {
5761077d0bdSPeter Avalos 	const char *s;
5771077d0bdSPeter Avalos 	u_short p;
5781077d0bdSPeter Avalos };
5791077d0bdSPeter Avalos 
58097a9217aSAntonio Huete Jimenez /*
58197a9217aSAntonio Huete Jimenez  * Static data base of ether protocol types.
58297a9217aSAntonio Huete Jimenez  * tcpdump used to import this, and it's declared as an export on
58397a9217aSAntonio Huete Jimenez  * Debian, at least, so make it a public symbol, even though we
58497a9217aSAntonio Huete Jimenez  * don't officially export it by declaring it in a header file.
58597a9217aSAntonio Huete Jimenez  * (Programs *should* do this themselves, as tcpdump now does.)
5863a289941SAaron LI  *
5873a289941SAaron LI  * We declare it here, right before defining it, to squelch any
5883a289941SAaron LI  * warnings we might get from compilers about the lack of a
5893a289941SAaron LI  * declaration.
59097a9217aSAntonio Huete Jimenez  */
5913a289941SAaron LI PCAP_API struct eproto eproto_db[];
59297a9217aSAntonio Huete Jimenez PCAP_API_DEF struct eproto eproto_db[] = {
593*ea16f64eSAntonio Huete Jimenez 	{ "aarp", ETHERTYPE_AARP },
594*ea16f64eSAntonio Huete Jimenez 	{ "arp", ETHERTYPE_ARP },
595*ea16f64eSAntonio Huete Jimenez 	{ "atalk", ETHERTYPE_ATALK },
596*ea16f64eSAntonio Huete Jimenez 	{ "decnet", ETHERTYPE_DN },
5971077d0bdSPeter Avalos 	{ "ip", ETHERTYPE_IP },
5981077d0bdSPeter Avalos #ifdef INET6
5991077d0bdSPeter Avalos 	{ "ip6", ETHERTYPE_IPV6 },
6001077d0bdSPeter Avalos #endif
601*ea16f64eSAntonio Huete Jimenez 	{ "lat", ETHERTYPE_LAT },
602*ea16f64eSAntonio Huete Jimenez 	{ "loopback", ETHERTYPE_LOOPBACK },
6031077d0bdSPeter Avalos 	{ "mopdl", ETHERTYPE_MOPDL },
6041077d0bdSPeter Avalos 	{ "moprc", ETHERTYPE_MOPRC },
605*ea16f64eSAntonio Huete Jimenez 	{ "rarp", ETHERTYPE_REVARP },
6061077d0bdSPeter Avalos 	{ "sca", ETHERTYPE_SCA },
6071077d0bdSPeter Avalos 	{ (char *)0, 0 }
6081077d0bdSPeter Avalos };
6091077d0bdSPeter Avalos 
6101077d0bdSPeter Avalos int
pcap_nametoeproto(const char * s)6111077d0bdSPeter Avalos pcap_nametoeproto(const char *s)
6121077d0bdSPeter Avalos {
6131077d0bdSPeter Avalos 	struct eproto *p = eproto_db;
6141077d0bdSPeter Avalos 
6151077d0bdSPeter Avalos 	while (p->s != 0) {
6161077d0bdSPeter Avalos 		if (strcmp(p->s, s) == 0)
6171077d0bdSPeter Avalos 			return p->p;
6181077d0bdSPeter Avalos 		p += 1;
6191077d0bdSPeter Avalos 	}
6201077d0bdSPeter Avalos 	return PROTO_UNDEF;
6211077d0bdSPeter Avalos }
6221077d0bdSPeter Avalos 
6231077d0bdSPeter Avalos #include "llc.h"
6241077d0bdSPeter Avalos 
6251077d0bdSPeter Avalos /* Static data base of LLC values. */
6261077d0bdSPeter Avalos static struct eproto llc_db[] = {
6271077d0bdSPeter Avalos 	{ "iso", LLCSAP_ISONS },
6281077d0bdSPeter Avalos 	{ "stp", LLCSAP_8021D },
6291077d0bdSPeter Avalos 	{ "ipx", LLCSAP_IPX },
6301077d0bdSPeter Avalos 	{ "netbeui", LLCSAP_NETBEUI },
6311077d0bdSPeter Avalos 	{ (char *)0, 0 }
6321077d0bdSPeter Avalos };
6331077d0bdSPeter Avalos 
6341077d0bdSPeter Avalos int
pcap_nametollc(const char * s)6351077d0bdSPeter Avalos pcap_nametollc(const char *s)
6361077d0bdSPeter Avalos {
6371077d0bdSPeter Avalos 	struct eproto *p = llc_db;
6381077d0bdSPeter Avalos 
6391077d0bdSPeter Avalos 	while (p->s != 0) {
6401077d0bdSPeter Avalos 		if (strcmp(p->s, s) == 0)
6411077d0bdSPeter Avalos 			return p->p;
6421077d0bdSPeter Avalos 		p += 1;
6431077d0bdSPeter Avalos 	}
6441077d0bdSPeter Avalos 	return PROTO_UNDEF;
6451077d0bdSPeter Avalos }
6461077d0bdSPeter Avalos 
6473a289941SAaron LI /* Hex digit to 8-bit unsigned integer. */
6483a289941SAaron LI static inline u_char
xdtoi(u_char c)6493a289941SAaron LI xdtoi(u_char c)
6501077d0bdSPeter Avalos {
651*ea16f64eSAntonio Huete Jimenez 	if (c >= '0' && c <= '9')
6523a289941SAaron LI 		return (u_char)(c - '0');
653*ea16f64eSAntonio Huete Jimenez 	else if (c >= 'a' && c <= 'f')
6543a289941SAaron LI 		return (u_char)(c - 'a' + 10);
6551077d0bdSPeter Avalos 	else
6563a289941SAaron LI 		return (u_char)(c - 'A' + 10);
6571077d0bdSPeter Avalos }
6581077d0bdSPeter Avalos 
6591077d0bdSPeter Avalos int
__pcap_atoin(const char * s,bpf_u_int32 * addr)6601077d0bdSPeter Avalos __pcap_atoin(const char *s, bpf_u_int32 *addr)
6611077d0bdSPeter Avalos {
6621077d0bdSPeter Avalos 	u_int n;
6631077d0bdSPeter Avalos 	int len;
6641077d0bdSPeter Avalos 
6651077d0bdSPeter Avalos 	*addr = 0;
6661077d0bdSPeter Avalos 	len = 0;
6673a289941SAaron LI 	for (;;) {
6681077d0bdSPeter Avalos 		n = 0;
669*ea16f64eSAntonio Huete Jimenez 		while (*s && *s != '.') {
670*ea16f64eSAntonio Huete Jimenez 			if (n > 25) {
671*ea16f64eSAntonio Huete Jimenez 				/* The result will be > 255 */
672*ea16f64eSAntonio Huete Jimenez 				return -1;
673*ea16f64eSAntonio Huete Jimenez 			}
6741077d0bdSPeter Avalos 			n = n * 10 + *s++ - '0';
675*ea16f64eSAntonio Huete Jimenez 		}
676*ea16f64eSAntonio Huete Jimenez 		if (n > 255)
677*ea16f64eSAntonio Huete Jimenez 			return -1;
6781077d0bdSPeter Avalos 		*addr <<= 8;
6791077d0bdSPeter Avalos 		*addr |= n & 0xff;
6801077d0bdSPeter Avalos 		len += 8;
6811077d0bdSPeter Avalos 		if (*s == '\0')
6821077d0bdSPeter Avalos 			return len;
6831077d0bdSPeter Avalos 		++s;
6841077d0bdSPeter Avalos 	}
6851077d0bdSPeter Avalos 	/* NOTREACHED */
6861077d0bdSPeter Avalos }
6871077d0bdSPeter Avalos 
6881077d0bdSPeter Avalos int
__pcap_atodn(const char * s,bpf_u_int32 * addr)6891077d0bdSPeter Avalos __pcap_atodn(const char *s, bpf_u_int32 *addr)
6901077d0bdSPeter Avalos {
6911077d0bdSPeter Avalos #define AREASHIFT 10
6921077d0bdSPeter Avalos #define AREAMASK 0176000
6931077d0bdSPeter Avalos #define NODEMASK 01777
6941077d0bdSPeter Avalos 
6951077d0bdSPeter Avalos 	u_int node, area;
6961077d0bdSPeter Avalos 
6971077d0bdSPeter Avalos 	if (sscanf(s, "%d.%d", &area, &node) != 2)
69897a9217aSAntonio Huete Jimenez 		return(0);
6991077d0bdSPeter Avalos 
7001077d0bdSPeter Avalos 	*addr = (area << AREASHIFT) & AREAMASK;
7011077d0bdSPeter Avalos 	*addr |= (node & NODEMASK);
7021077d0bdSPeter Avalos 
7031077d0bdSPeter Avalos 	return(32);
7041077d0bdSPeter Avalos }
7051077d0bdSPeter Avalos 
7061077d0bdSPeter Avalos /*
707de0d3203SPeter Avalos  * Convert 's', which can have the one of the forms:
708de0d3203SPeter Avalos  *
709de0d3203SPeter Avalos  *	"xx:xx:xx:xx:xx:xx"
710de0d3203SPeter Avalos  *	"xx.xx.xx.xx.xx.xx"
711de0d3203SPeter Avalos  *	"xx-xx-xx-xx-xx-xx"
712de0d3203SPeter Avalos  *	"xxxx.xxxx.xxxx"
713de0d3203SPeter Avalos  *	"xxxxxxxxxxxx"
714de0d3203SPeter Avalos  *
715de0d3203SPeter Avalos  * (or various mixes of ':', '.', and '-') into a new
7161077d0bdSPeter Avalos  * ethernet address.  Assumes 's' is well formed.
7171077d0bdSPeter Avalos  */
7181077d0bdSPeter Avalos u_char *
pcap_ether_aton(const char * s)7191077d0bdSPeter Avalos pcap_ether_aton(const char *s)
7201077d0bdSPeter Avalos {
7211077d0bdSPeter Avalos 	register u_char *ep, *e;
7223a289941SAaron LI 	register u_char d;
7231077d0bdSPeter Avalos 
7241077d0bdSPeter Avalos 	e = ep = (u_char *)malloc(6);
72597a9217aSAntonio Huete Jimenez 	if (e == NULL)
72697a9217aSAntonio Huete Jimenez 		return (NULL);
7271077d0bdSPeter Avalos 
7281077d0bdSPeter Avalos 	while (*s) {
729de0d3203SPeter Avalos 		if (*s == ':' || *s == '.' || *s == '-')
7301077d0bdSPeter Avalos 			s += 1;
7311077d0bdSPeter Avalos 		d = xdtoi(*s++);
732*ea16f64eSAntonio Huete Jimenez 		if (PCAP_ISXDIGIT(*s)) {
7331077d0bdSPeter Avalos 			d <<= 4;
7341077d0bdSPeter Avalos 			d |= xdtoi(*s++);
7351077d0bdSPeter Avalos 		}
7361077d0bdSPeter Avalos 		*ep++ = d;
7371077d0bdSPeter Avalos 	}
7381077d0bdSPeter Avalos 
7391077d0bdSPeter Avalos 	return (e);
7401077d0bdSPeter Avalos }
7411077d0bdSPeter Avalos 
7421077d0bdSPeter Avalos #ifndef HAVE_ETHER_HOSTTON
7433a289941SAaron LI /*
7443a289941SAaron LI  * Roll our own.
7453a289941SAaron LI  * XXX - not thread-safe, because pcap_next_etherent() isn't thread-
7463a289941SAaron LI  * safe!  Needs a mutex or a thread-safe pcap_next_etherent().
7473a289941SAaron LI  */
7481077d0bdSPeter Avalos u_char *
pcap_ether_hostton(const char * name)7491077d0bdSPeter Avalos pcap_ether_hostton(const char *name)
7501077d0bdSPeter Avalos {
7511077d0bdSPeter Avalos 	register struct pcap_etherent *ep;
7521077d0bdSPeter Avalos 	register u_char *ap;
7531077d0bdSPeter Avalos 	static FILE *fp = NULL;
7541077d0bdSPeter Avalos 	static int init = 0;
7551077d0bdSPeter Avalos 
7561077d0bdSPeter Avalos 	if (!init) {
7571077d0bdSPeter Avalos 		fp = fopen(PCAP_ETHERS_FILE, "r");
7581077d0bdSPeter Avalos 		++init;
7591077d0bdSPeter Avalos 		if (fp == NULL)
7601077d0bdSPeter Avalos 			return (NULL);
7611077d0bdSPeter Avalos 	} else if (fp == NULL)
7621077d0bdSPeter Avalos 		return (NULL);
7631077d0bdSPeter Avalos 	else
7641077d0bdSPeter Avalos 		rewind(fp);
7651077d0bdSPeter Avalos 
7661077d0bdSPeter Avalos 	while ((ep = pcap_next_etherent(fp)) != NULL) {
7671077d0bdSPeter Avalos 		if (strcmp(ep->name, name) == 0) {
7681077d0bdSPeter Avalos 			ap = (u_char *)malloc(6);
7691077d0bdSPeter Avalos 			if (ap != NULL) {
7701077d0bdSPeter Avalos 				memcpy(ap, ep->addr, 6);
7711077d0bdSPeter Avalos 				return (ap);
7721077d0bdSPeter Avalos 			}
7731077d0bdSPeter Avalos 			break;
7741077d0bdSPeter Avalos 		}
7751077d0bdSPeter Avalos 	}
7761077d0bdSPeter Avalos 	return (NULL);
7771077d0bdSPeter Avalos }
7781077d0bdSPeter Avalos #else
7793a289941SAaron LI /*
7803a289941SAaron LI  * Use the OS-supplied routine.
7813a289941SAaron LI  * This *should* be thread-safe; the API doesn't have a static buffer.
7823a289941SAaron LI  */
7831077d0bdSPeter Avalos u_char *
pcap_ether_hostton(const char * name)7841077d0bdSPeter Avalos pcap_ether_hostton(const char *name)
7851077d0bdSPeter Avalos {
7861077d0bdSPeter Avalos 	register u_char *ap;
7871077d0bdSPeter Avalos 	u_char a[6];
7881077d0bdSPeter Avalos 
7891077d0bdSPeter Avalos 	ap = NULL;
7901077d0bdSPeter Avalos 	if (ether_hostton(name, (struct ether_addr *)a) == 0) {
7911077d0bdSPeter Avalos 		ap = (u_char *)malloc(6);
7921077d0bdSPeter Avalos 		if (ap != NULL)
7931077d0bdSPeter Avalos 			memcpy((char *)ap, (char *)a, 6);
7941077d0bdSPeter Avalos 	}
7951077d0bdSPeter Avalos 	return (ap);
7961077d0bdSPeter Avalos }
7971077d0bdSPeter Avalos #endif
7981077d0bdSPeter Avalos 
7993a289941SAaron LI /*
8003a289941SAaron LI  * XXX - not guaranteed to be thread-safe!
8013a289941SAaron LI  */
80297a9217aSAntonio Huete Jimenez int
8033a289941SAaron LI #ifdef	DECNETLIB
__pcap_nametodnaddr(const char * name,u_short * res)80497a9217aSAntonio Huete Jimenez __pcap_nametodnaddr(const char *name, u_short *res)
8051077d0bdSPeter Avalos {
8061077d0bdSPeter Avalos 	struct nodeent *getnodebyname();
8071077d0bdSPeter Avalos 	struct nodeent *nep;
8081077d0bdSPeter Avalos 
8091077d0bdSPeter Avalos 	nep = getnodebyname(name);
8101077d0bdSPeter Avalos 	if (nep == ((struct nodeent *)0))
81197a9217aSAntonio Huete Jimenez 		return(0);
8121077d0bdSPeter Avalos 
81397a9217aSAntonio Huete Jimenez 	memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
81497a9217aSAntonio Huete Jimenez 	return(1);
8151077d0bdSPeter Avalos #else
8163a289941SAaron LI __pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
8173a289941SAaron LI {
8181077d0bdSPeter Avalos 	return(0);
8191077d0bdSPeter Avalos #endif
8201077d0bdSPeter Avalos }
821