Home | History | Annotate | Line # | Download | only in dist
      1 /*	$NetBSD: nametoaddr.c,v 1.8 2026/03/18 23:43:20 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that: (1) source code distributions
      9  * retain the above copyright notice and this paragraph in its entirety, (2)
     10  * distributions including binary code include the above copyright notice and
     11  * this paragraph in its entirety in the documentation or other materials
     12  * provided with the distribution, and (3) all advertising materials mentioning
     13  * features or use of this software display the following acknowledgement:
     14  * ``This product includes software developed by the University of California,
     15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
     16  * the University nor the names of its contributors may be used to endorse
     17  * or promote products derived from this software without specific prior
     18  * written permission.
     19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
     20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
     21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     22  *
     23  * Name to id translation routines used by the scanner.
     24  * These functions are not time critical.
     25  */
     26 
     27 #include <sys/cdefs.h>
     28 __RCSID("$NetBSD: nametoaddr.c,v 1.8 2026/03/18 23:43:20 christos Exp $");
     29 
     30 #include <config.h>
     31 
     32 #ifdef DECNETLIB
     33 #include <sys/types.h>
     34 #include <netdnet/dnetdb.h>
     35 #endif
     36 
     37 #ifdef _WIN32
     38   #include <winsock2.h>
     39   #include <ws2tcpip.h>
     40 #else /* _WIN32 */
     41   #include <sys/param.h>
     42   #include <sys/types.h>
     43   #include <sys/socket.h>
     44   #include <sys/time.h>
     45 
     46   #include <netinet/in.h>
     47 
     48   #ifdef HAVE_ETHER_HOSTTON
     49     #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
     50       /*
     51        * OK, just include <net/ethernet.h>.
     52        */
     53       #include <net/ethernet.h>
     54     #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
     55       /*
     56        * OK, just include <netinet/ether.h>
     57        */
     58       #include <netinet/ether.h>
     59     #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
     60       /*
     61        * OK, just include <sys/ethernet.h>
     62        */
     63       #include <sys/ethernet.h>
     64     #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
     65       /*
     66        * OK, just include <arpa/inet.h>
     67        */
     68       #include <arpa/inet.h>
     69     #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
     70       /*
     71        * OK, include <netinet/if_ether.h>, after all the other stuff we
     72        * need to include or define for its benefit.
     73        */
     74       #define NEED_NETINET_IF_ETHER_H
     75     #else
     76       /*
     77        * We'll have to declare it ourselves.
     78        * If <netinet/if_ether.h> defines struct ether_addr, include
     79        * it.  Otherwise, define it ourselves.
     80        */
     81       #ifdef HAVE_STRUCT_ETHER_ADDR
     82         #define NEED_NETINET_IF_ETHER_H
     83       #else /* HAVE_STRUCT_ETHER_ADDR */
     84 	struct ether_addr {
     85 		unsigned char ether_addr_octet[6];
     86 	};
     87       #endif /* HAVE_STRUCT_ETHER_ADDR */
     88     #endif /* what declares ether_hostton() */
     89 
     90     #ifdef NEED_NETINET_IF_ETHER_H
     91       #include <net/if.h>	/* Needed on some platforms */
     92       #include <netinet/in.h>	/* Needed on some platforms */
     93       #include <netinet/if_ether.h>
     94     #endif /* NEED_NETINET_IF_ETHER_H */
     95 
     96     #ifndef HAVE_DECL_ETHER_HOSTTON
     97       /*
     98        * No header declares it, so declare it ourselves.
     99        */
    100       extern int ether_hostton(const char *, struct ether_addr *);
    101     #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
    102   #endif /* HAVE_ETHER_HOSTTON */
    103 
    104   #include <arpa/inet.h>
    105   #include <netdb.h>
    106 #endif /* _WIN32 */
    107 
    108 #include <errno.h>
    109 #include <stdlib.h>
    110 #include <string.h>
    111 #include <stdio.h>
    112 
    113 #include "pcap-int.h"
    114 
    115 #include "diag-control.h"
    116 
    117 #include "gencode.h"
    118 #include <pcap/namedb.h>
    119 #include "nametoaddr.h"
    120 
    121 #include "thread-local.h"
    122 
    123 #ifdef HAVE_OS_PROTO_H
    124 #include "os-proto.h"
    125 #endif
    126 
    127 #ifndef NTOHL
    128 #define NTOHL(x) (x) = ntohl(x)
    129 #define NTOHS(x) (x) = ntohs(x)
    130 #endif
    131 
    132 /*
    133  *  Convert host name to internet address.
    134  *  Return 0 upon failure.
    135  *  XXX - not thread-safe; don't use it inside libpcap.
    136  */
    137 bpf_u_int32 **
    138 pcap_nametoaddr(const char *name)
    139 {
    140 #ifndef h_addr
    141 	static bpf_u_int32 *hlist[2];
    142 #endif
    143 	bpf_u_int32 **p;
    144 	struct hostent *hp;
    145 
    146 	/*
    147 	 * gethostbyname() is deprecated on Windows, perhaps because
    148 	 * it's not thread-safe, or because it doesn't support IPv6,
    149 	 * or both.
    150 	 *
    151 	 * We deprecate pcap_nametoaddr() on all platforms because
    152 	 * it's not thread-safe; we supply it for backwards compatibility,
    153 	 * so suppress the deprecation warning.  We could, I guess,
    154 	 * use getaddrinfo() and construct the array ourselves, but
    155 	 * that's probably not worth the effort, as that wouldn't make
    156 	 * this thread-safe - we can't change the API to require that
    157 	 * our caller free the address array, so we still have to reuse
    158 	 * a local array.
    159 	 */
    160 DIAG_OFF_DEPRECATION
    161 	if ((hp = gethostbyname(name)) != NULL) {
    162 DIAG_ON_DEPRECATION
    163 #ifndef h_addr
    164 		hlist[0] = (bpf_u_int32 *)hp->h_addr;
    165 		NTOHL(hp->h_addr);
    166 		return hlist;
    167 #else
    168 		for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
    169 			NTOHL(**p);
    170 		return (bpf_u_int32 **)hp->h_addr_list;
    171 #endif
    172 	}
    173 	else
    174 		return 0;
    175 }
    176 
    177 struct addrinfo *
    178 pcap_nametoaddrinfo(const char *name)
    179 {
    180 	struct addrinfo hints, *res;
    181 	int error;
    182 
    183 	memset(&hints, 0, sizeof(hints));
    184 	hints.ai_family = PF_UNSPEC;
    185 	hints.ai_socktype = SOCK_STREAM;	/*not really*/
    186 	hints.ai_protocol = IPPROTO_TCP;	/*not really*/
    187 	error = getaddrinfo(name, NULL, &hints, &res);
    188 	if (error)
    189 		return NULL;
    190 	else
    191 		return res;
    192 }
    193 
    194 /*
    195  *  Convert net name to internet address.
    196  *  Return 0 upon failure.
    197  *  XXX - not guaranteed to be thread-safe!  See below for platforms
    198  *  on which it is thread-safe and on which it isn't.
    199  */
    200 #if defined(_WIN32) || defined(__CYGWIN__)
    201 bpf_u_int32
    202 pcap_nametonetaddr(const char *name _U_)
    203 {
    204 	/*
    205 	 * There's no "getnetbyname()" on Windows.
    206 	 *
    207 	 * XXX - I guess we could use the BSD code to read
    208 	 * C:\Windows\System32\drivers\etc/networks, assuming
    209 	 * that's its home on all the versions of Windows
    210 	 * we use, but that file probably just has the loopback
    211 	 * network on 127/24 on 99 44/100% of Windows machines.
    212 	 *
    213 	 * (Heck, these days it probably just has that on 99 44/100%
    214 	 * of *UN*X* machines.)
    215 	 */
    216 	return 0;
    217 }
    218 #else /* _WIN32 */
    219 bpf_u_int32
    220 pcap_nametonetaddr(const char *name)
    221 {
    222 	/*
    223 	 * UN*X.
    224 	 */
    225 	struct netent *np;
    226   #if defined(HAVE_LINUX_GETNETBYNAME_R)
    227 	/*
    228 	 * We have Linux's reentrant getnetbyname_r().
    229 	 */
    230 	struct netent result_buf;
    231 	char buf[1024];	/* arbitrary size */
    232 	int h_errnoval;
    233 	int err;
    234 
    235 	/*
    236 	 * Apparently, the man page at
    237 	 *
    238 	 *    http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html
    239 	 *
    240 	 * lies when it says
    241 	 *
    242 	 *    If the function call successfully obtains a network record,
    243 	 *    then *result is set pointing to result_buf; otherwise, *result
    244 	 *    is set to NULL.
    245 	 *
    246 	 * and, in fact, at least in some versions of GNU libc, it does
    247 	 * *not* always get set if getnetbyname_r() succeeds.
    248 	 */
    249 	np = NULL;
    250 	err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
    251 	    &h_errnoval);
    252 	if (err != 0) {
    253 		/*
    254 		 * XXX - dynamically allocate the buffer, and make it
    255 		 * bigger if we get ERANGE back?
    256 		 */
    257 		return 0;
    258 	}
    259   #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
    260 	/*
    261 	 * We have Solaris's and IRIX's reentrant getnetbyname_r().
    262 	 */
    263 	struct netent result_buf;
    264 	char buf[1024];	/* arbitrary size */
    265 
    266 	np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
    267   #elif defined(HAVE_AIX_GETNETBYNAME_R)
    268 	/*
    269 	 * We have AIX's reentrant getnetbyname_r().
    270 	 */
    271 	struct netent result_buf;
    272 	struct netent_data net_data;
    273 
    274 	if (getnetbyname_r(name, &result_buf, &net_data) == -1)
    275 		np = NULL;
    276 	else
    277 		np = &result_buf;
    278   #else
    279 	/*
    280 	 * We don't have any getnetbyname_r(); either we have a
    281 	 * getnetbyname() that uses thread-specific data, in which
    282 	 * case we're thread-safe (sufficiently recent FreeBSD,
    283 	 * sufficiently recent Darwin-based OS, sufficiently recent
    284 	 * HP-UX, sufficiently recent Tru64 UNIX), or we have the
    285 	 * traditional getnetbyname() (everything else, including
    286 	 * current NetBSD and OpenBSD), in which case we're not
    287 	 * thread-safe.
    288 	 */
    289 	np = getnetbyname(name);
    290   #endif
    291 	if (np != NULL)
    292 		return np->n_net;
    293 	else
    294 		return 0;
    295 }
    296 #endif /* _WIN32 */
    297 
    298 /*
    299  * Convert a port name to its port and protocol numbers.
    300  * We assume only TCP or UDP.
    301  * Return 0 upon failure.
    302  */
    303 int
    304 pcap_nametoport(const char *name, int *port, int *proto)
    305 {
    306 	struct addrinfo hints, *res, *ai;
    307 	int error;
    308 	struct sockaddr_in *in4;
    309 #ifdef INET6
    310 	struct sockaddr_in6 *in6;
    311 #endif
    312 	int tcp_port = -1;
    313 	int udp_port = -1;
    314 
    315 	/*
    316 	 * We check for both TCP and UDP in case there are
    317 	 * ambiguous entries.
    318 	 */
    319 	memset(&hints, 0, sizeof(hints));
    320 	hints.ai_family = PF_UNSPEC;
    321 	hints.ai_socktype = SOCK_STREAM;
    322 	hints.ai_protocol = IPPROTO_TCP;
    323 	error = getaddrinfo(NULL, name, &hints, &res);
    324 	if (error != 0) {
    325 		if (error != EAI_NONAME &&
    326 		    error != EAI_SERVICE) {
    327 			/*
    328 			 * This is a real error, not just "there's
    329 			 * no such service name".
    330 			 * XXX - this doesn't return an error string.
    331 			 */
    332 			return 0;
    333 		}
    334 	} else {
    335 		/*
    336 		 * OK, we found it.  Did it find anything?
    337 		 */
    338 		for (ai = res; ai != NULL; ai = ai->ai_next) {
    339 			/*
    340 			 * Does it have an address?
    341 			 */
    342 			if (ai->ai_addr != NULL) {
    343 				/*
    344 				 * Yes.  Get a port number; we're done.
    345 				 */
    346 				if (ai->ai_addr->sa_family == AF_INET) {
    347 					in4 = (struct sockaddr_in *)ai->ai_addr;
    348 					tcp_port = ntohs(in4->sin_port);
    349 					break;
    350 				}
    351 #ifdef INET6
    352 				if (ai->ai_addr->sa_family == AF_INET6) {
    353 					in6 = (struct sockaddr_in6 *)ai->ai_addr;
    354 					tcp_port = ntohs(in6->sin6_port);
    355 					break;
    356 				}
    357 #endif
    358 			}
    359 		}
    360 		freeaddrinfo(res);
    361 	}
    362 
    363 	memset(&hints, 0, sizeof(hints));
    364 	hints.ai_family = PF_UNSPEC;
    365 	hints.ai_socktype = SOCK_DGRAM;
    366 	hints.ai_protocol = IPPROTO_UDP;
    367 	error = getaddrinfo(NULL, name, &hints, &res);
    368 	if (error != 0) {
    369 		if (error != EAI_NONAME &&
    370 		    error != EAI_SERVICE) {
    371 			/*
    372 			 * This is a real error, not just "there's
    373 			 * no such service name".
    374 			 * XXX - this doesn't return an error string.
    375 			 */
    376 			return 0;
    377 		}
    378 	} else {
    379 		/*
    380 		 * OK, we found it.  Did it find anything?
    381 		 */
    382 		for (ai = res; ai != NULL; ai = ai->ai_next) {
    383 			/*
    384 			 * Does it have an address?
    385 			 */
    386 			if (ai->ai_addr != NULL) {
    387 				/*
    388 				 * Yes.  Get a port number; we're done.
    389 				 */
    390 				if (ai->ai_addr->sa_family == AF_INET) {
    391 					in4 = (struct sockaddr_in *)ai->ai_addr;
    392 					udp_port = ntohs(in4->sin_port);
    393 					break;
    394 				}
    395 #ifdef INET6
    396 				if (ai->ai_addr->sa_family == AF_INET6) {
    397 					in6 = (struct sockaddr_in6 *)ai->ai_addr;
    398 					udp_port = ntohs(in6->sin6_port);
    399 					break;
    400 				}
    401 #endif
    402 			}
    403 		}
    404 		freeaddrinfo(res);
    405 	}
    406 
    407 	/*
    408 	 * We need to check /etc/services for ambiguous entries.
    409 	 * If we find an ambiguous entry, and it has the
    410 	 * same port number, change the proto to PROTO_UNDEF
    411 	 * so both TCP and UDP will be checked.
    412 	 */
    413 	if (tcp_port >= 0) {
    414 		*port = tcp_port;
    415 		*proto = IPPROTO_TCP;
    416 		if (udp_port >= 0) {
    417 			if (udp_port == tcp_port)
    418 				*proto = PROTO_UNDEF;
    419 #ifdef notdef
    420 			else
    421 				/* Can't handle ambiguous names that refer
    422 				   to different port numbers. */
    423 				warning("ambiguous port %s in /etc/services",
    424 					name);
    425 #endif
    426 		}
    427 		return 1;
    428 	}
    429 	if (udp_port >= 0) {
    430 		*port = udp_port;
    431 		*proto = IPPROTO_UDP;
    432 		return 1;
    433 	}
    434 #if defined(ultrix) || defined(__osf__)
    435 	/* Special hack in case NFS isn't in /etc/services */
    436 	if (strcmp(name, "nfs") == 0) {
    437 		*port = 2049;
    438 		*proto = PROTO_UNDEF;
    439 		return 1;
    440 	}
    441 #endif
    442 	return 0;
    443 }
    444 
    445 /*
    446  * Convert a string in the form PPP-PPP, where correspond to ports, to
    447  * a starting and ending port in a port range.
    448  * Return 0 on failure.
    449  */
    450 int
    451 pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
    452 {
    453 	char *off, *cpy;
    454 	int save_proto;
    455 
    456 	if ((cpy = strdup(name)) == NULL)
    457 		return 0;
    458 
    459 	if ((off = strchr(cpy, '-')) == NULL) {
    460 		free(cpy);
    461 		return 0;
    462 	}
    463 
    464 	*off = '\0';
    465 
    466 	if (pcap_nametoport(cpy, port1, proto) == 0) {
    467 		free(cpy);
    468 		return 0;
    469 	}
    470 	save_proto = *proto;
    471 
    472 	if (pcap_nametoport(off + 1, port2, proto) == 0) {
    473 		free(cpy);
    474 		return 0;
    475 	}
    476 	free(cpy);
    477 
    478 	if (*proto != save_proto)
    479 		*proto = PROTO_UNDEF;
    480 
    481 	return 1;
    482 }
    483 
    484 /*
    485  * XXX - not guaranteed to be thread-safe!  See below for platforms
    486  * on which it is thread-safe and on which it isn't.
    487  */
    488 int
    489 pcap_nametoproto(const char *str)
    490 {
    491 	struct protoent *p;
    492   #if defined(HAVE_LINUX_GETNETBYNAME_R)
    493 	/*
    494 	 * We have Linux's reentrant getprotobyname_r().
    495 	 */
    496 	struct protoent result_buf;
    497 	char buf[1024];	/* arbitrary size */
    498 	int err;
    499 
    500 	err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
    501 	if (err != 0) {
    502 		/*
    503 		 * XXX - dynamically allocate the buffer, and make it
    504 		 * bigger if we get ERANGE back?
    505 		 */
    506 		return 0;
    507 	}
    508   #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
    509 	/*
    510 	 * We have Solaris's and IRIX's reentrant getprotobyname_r().
    511 	 */
    512 	struct protoent result_buf;
    513 	char buf[1024];	/* arbitrary size */
    514 
    515 	p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
    516   #elif defined(HAVE_AIX_GETNETBYNAME_R)
    517 	/*
    518 	 * We have AIX's reentrant getprotobyname_r().
    519 	 */
    520 	struct protoent result_buf;
    521 	struct protoent_data proto_data;
    522 
    523 	if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
    524 		p = NULL;
    525 	else
    526 		p = &result_buf;
    527   #else
    528 	/*
    529 	 * We don't have any getprotobyname_r(); either we have a
    530 	 * getprotobyname() that uses thread-specific data, in which
    531 	 * case we're thread-safe (sufficiently recent FreeBSD,
    532 	 * sufficiently recent Darwin-based OS, sufficiently recent
    533 	 * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
    534 	 * the traditional getprotobyname() (everything else, including
    535 	 * current NetBSD and OpenBSD), in which case we're not
    536 	 * thread-safe.
    537 	 */
    538 	p = getprotobyname(str);
    539   #endif
    540 	if (p != 0)
    541 		return p->p_proto;
    542 	else
    543 		return PROTO_UNDEF;
    544 }
    545 
    546 #include "ethertype.h"
    547 
    548 struct eproto {
    549 	const char *s;
    550 	u_short p;
    551 };
    552 
    553 /*
    554  * Static data base of ether protocol types.
    555  * tcpdump used to import this, and it's declared as an export on
    556  * Debian, at least, so make it a public symbol, even though we
    557  * don't officially export it by declaring it in a header file.
    558  * (Programs *should* do this themselves, as tcpdump now does.)
    559  *
    560  * We declare it here, right before defining it, to squelch any
    561  * warnings we might get from compilers about the lack of a
    562  * declaration.
    563  */
    564 PCAP_API struct eproto eproto_db[];
    565 PCAP_API_DEF struct eproto eproto_db[] = {
    566 	{ "aarp", ETHERTYPE_AARP },
    567 	{ "arp", ETHERTYPE_ARP },
    568 	{ "atalk", ETHERTYPE_ATALK },
    569 	{ "decnet", ETHERTYPE_DN },
    570 	{ "ip", ETHERTYPE_IP },
    571 #ifdef INET6
    572 	{ "ip6", ETHERTYPE_IPV6 },
    573 #endif
    574 	{ "lat", ETHERTYPE_LAT },
    575 	{ "loopback", ETHERTYPE_LOOPBACK },
    576 	{ "mopdl", ETHERTYPE_MOPDL },
    577 	{ "moprc", ETHERTYPE_MOPRC },
    578 	{ "rarp", ETHERTYPE_REVARP },
    579 	{ "sca", ETHERTYPE_SCA },
    580 	{ (char *)0, 0 }
    581 };
    582 
    583 int
    584 pcap_nametoeproto(const char *s)
    585 {
    586 	struct eproto *p = eproto_db;
    587 
    588 	while (p->s != 0) {
    589 		if (strcmp(p->s, s) == 0)
    590 			return p->p;
    591 		p += 1;
    592 	}
    593 	return PROTO_UNDEF;
    594 }
    595 
    596 #include "llc.h"
    597 
    598 /* Static data base of LLC values. */
    599 static struct eproto llc_db[] = {
    600 	{ "iso", LLCSAP_ISONS },
    601 	{ "stp", LLCSAP_8021D },
    602 	{ "ipx", LLCSAP_IPX },
    603 	{ "netbeui", LLCSAP_NETBEUI },
    604 	{ (char *)0, 0 }
    605 };
    606 
    607 int
    608 pcap_nametollc(const char *s)
    609 {
    610 	struct eproto *p = llc_db;
    611 
    612 	while (p->s != 0) {
    613 		if (strcmp(p->s, s) == 0)
    614 			return p->p;
    615 		p += 1;
    616 	}
    617 	return PROTO_UNDEF;
    618 }
    619 
    620 /* Hex digit to 8-bit unsigned integer. */
    621 static inline u_char
    622 pcapint_xdtoi(u_char c)
    623 {
    624 	if (c >= '0' && c <= '9')
    625 		return (u_char)(c - '0');
    626 	else if (c >= 'a' && c <= 'f')
    627 		return (u_char)(c - 'a' + 10);
    628 	else
    629 		return (u_char)(c - 'A' + 10);
    630 }
    631 
    632 int
    633 __pcap_atoin(const char *s, bpf_u_int32 *addr)
    634 {
    635 	u_int n;
    636 	int len;
    637 
    638 	*addr = 0;
    639 	len = 0;
    640 	for (;;) {
    641 		n = 0;
    642 		while (*s && *s != '.') {
    643 			if (n > 25) {
    644 				/* The result will be > 255 */
    645 				return -1;
    646 			}
    647 			n = n * 10 + *s++ - '0';
    648 		}
    649 		if (n > 255)
    650 			return -1;
    651 		*addr <<= 8;
    652 		*addr |= n & 0xff;
    653 		len += 8;
    654 		if (*s == '\0')
    655 			return len;
    656 		++s;
    657 	}
    658 	/* NOTREACHED */
    659 }
    660 
    661 int
    662 __pcap_atodn(const char *s, bpf_u_int32 *addr)
    663 {
    664 #define AREASHIFT 10
    665 #define AREAMASK 0176000
    666 #define NODEMASK 01777
    667 
    668 	u_int node, area;
    669 
    670 	if (sscanf(s, "%d.%d", &area, &node) != 2)
    671 		return(0);
    672 
    673 	*addr = (area << AREASHIFT) & AREAMASK;
    674 	*addr |= (node & NODEMASK);
    675 
    676 	return(32);
    677 }
    678 
    679 /*
    680  * libpcap ARCnet address format is "^\$[0-9a-fA-F]{1,2}$" in regexp syntax.
    681  * Iff the given string is a well-formed ARCnet address, parse the string,
    682  * store the 8-bit unsigned value into the provided integer and return 1.
    683  * Otherwise return 0.
    684  *
    685  *  --> START -- $ --> DOLLAR -- [0-9a-fA-F] --> HEX1 -- \0 -->-+
    686  *        |              |                        |             |
    687  *       [.]            [.]                  [0-9a-fA-F]        |
    688  *        |              |                        |             |
    689  *        v              v                        v             v
    690  *    (invalid) <--------+-<---------------[.]-- HEX2 -- \0 -->-+--> (valid)
    691  */
    692 int
    693 pcapint_atoan(const char *s, uint8_t *addr)
    694 {
    695 	enum {
    696 		START,
    697 		DOLLAR,
    698 		HEX1,
    699 		HEX2,
    700 	} fsm_state = START;
    701 	uint8_t tmp = 0;
    702 
    703 	while (*s) {
    704 		switch (fsm_state) {
    705 		case START:
    706 			if (*s != '$')
    707 				goto invalid;
    708 			fsm_state = DOLLAR;
    709 			break;
    710 		case DOLLAR:
    711 			if (! PCAP_ISXDIGIT(*s))
    712 				goto invalid;
    713 			tmp = pcapint_xdtoi(*s);
    714 			fsm_state = HEX1;
    715 			break;
    716 		case HEX1:
    717 			if (! PCAP_ISXDIGIT(*s))
    718 				goto invalid;
    719 			tmp <<= 4;
    720 			tmp |= pcapint_xdtoi(*s);
    721 			fsm_state = HEX2;
    722 			break;
    723 		case HEX2:
    724 			goto invalid;
    725 		} // switch
    726 		s++;
    727 	} // while
    728 	if (fsm_state == HEX1 || fsm_state == HEX2) {
    729 		*addr = tmp;
    730 		return 1;
    731 	}
    732 
    733 invalid:
    734 	return 0;
    735 }
    736 
    737 // Man page: "xxxxxxxxxxxx", regexp: "^[0-9a-fA-F]{12}$".
    738 static u_char
    739 pcapint_atomac48_xxxxxxxxxxxx(const char *s, uint8_t *addr)
    740 {
    741 	if (strlen(s) == 12 &&
    742 	    PCAP_ISXDIGIT(s[0]) &&
    743 	    PCAP_ISXDIGIT(s[1]) &&
    744 	    PCAP_ISXDIGIT(s[2]) &&
    745 	    PCAP_ISXDIGIT(s[3]) &&
    746 	    PCAP_ISXDIGIT(s[4]) &&
    747 	    PCAP_ISXDIGIT(s[5]) &&
    748 	    PCAP_ISXDIGIT(s[6]) &&
    749 	    PCAP_ISXDIGIT(s[7]) &&
    750 	    PCAP_ISXDIGIT(s[8]) &&
    751 	    PCAP_ISXDIGIT(s[9]) &&
    752 	    PCAP_ISXDIGIT(s[10]) &&
    753 	    PCAP_ISXDIGIT(s[11])) {
    754 		addr[0] = pcapint_xdtoi(s[0]) << 4 | pcapint_xdtoi(s[1]);
    755 		addr[1] = pcapint_xdtoi(s[2]) << 4 | pcapint_xdtoi(s[3]);
    756 		addr[2] = pcapint_xdtoi(s[4]) << 4 | pcapint_xdtoi(s[5]);
    757 		addr[3] = pcapint_xdtoi(s[6]) << 4 | pcapint_xdtoi(s[7]);
    758 		addr[4] = pcapint_xdtoi(s[8]) << 4 | pcapint_xdtoi(s[9]);
    759 		addr[5] = pcapint_xdtoi(s[10]) << 4 | pcapint_xdtoi(s[11]);
    760 		return 1;
    761 	}
    762 	return 0;
    763 }
    764 
    765 // Man page: "xxxx.xxxx.xxxx", regexp: "^[0-9a-fA-F]{4}(\.[0-9a-fA-F]{4}){2}$".
    766 static u_char
    767 pcapint_atomac48_xxxx_3_times(const char *s, uint8_t *addr)
    768 {
    769 	const char sep = '.';
    770 	if (strlen(s) == 14 &&
    771 	    PCAP_ISXDIGIT(s[0]) &&
    772 	    PCAP_ISXDIGIT(s[1]) &&
    773 	    PCAP_ISXDIGIT(s[2]) &&
    774 	    PCAP_ISXDIGIT(s[3]) &&
    775 	    s[4] == sep &&
    776 	    PCAP_ISXDIGIT(s[5]) &&
    777 	    PCAP_ISXDIGIT(s[6]) &&
    778 	    PCAP_ISXDIGIT(s[7]) &&
    779 	    PCAP_ISXDIGIT(s[8]) &&
    780 	    s[9] == sep &&
    781 	    PCAP_ISXDIGIT(s[10]) &&
    782 	    PCAP_ISXDIGIT(s[11]) &&
    783 	    PCAP_ISXDIGIT(s[12]) &&
    784 	    PCAP_ISXDIGIT(s[13])) {
    785 		addr[0] = pcapint_xdtoi(s[0]) << 4 | pcapint_xdtoi(s[1]);
    786 		addr[1] = pcapint_xdtoi(s[2]) << 4 | pcapint_xdtoi(s[3]);
    787 		addr[2] = pcapint_xdtoi(s[5]) << 4 | pcapint_xdtoi(s[6]);
    788 		addr[3] = pcapint_xdtoi(s[7]) << 4 | pcapint_xdtoi(s[8]);
    789 		addr[4] = pcapint_xdtoi(s[10]) << 4 | pcapint_xdtoi(s[11]);
    790 		addr[5] = pcapint_xdtoi(s[12]) << 4 | pcapint_xdtoi(s[13]);
    791 		return 1;
    792 	}
    793 	return 0;
    794 }
    795 
    796 /*
    797  * Man page: "xx:xx:xx:xx:xx:xx", regexp: "^[0-9a-fA-F]{1,2}(:[0-9a-fA-F]{1,2}){5}$".
    798  * Man page: "xx-xx-xx-xx-xx-xx", regexp: "^[0-9a-fA-F]{1,2}(-[0-9a-fA-F]{1,2}){5}$".
    799  * Man page: "xx.xx.xx.xx.xx.xx", regexp: "^[0-9a-fA-F]{1,2}(\.[0-9a-fA-F]{1,2}){5}$".
    800  * (Any "xx" above can be "x", which is equivalent to "0x".)
    801  *
    802  * An equivalent (and parametrisable for EUI-64) FSM could be implemented using
    803  * a smaller graph, but that graph would be neither acyclic nor planar nor
    804  * trivial to verify.
    805  *
    806  *                |
    807  *    [.]         v
    808  * +<---------- START
    809  * |              |
    810  * |              | [0-9a-fA-F]
    811  * |  [.]         v
    812  * +<--------- BYTE0_X ----------+
    813  * |              |              |
    814  * |              | [0-9a-fA-F]  |
    815  * |  [.]         v              |
    816  * +<--------- BYTE0_XX          | [:\.-]
    817  * |              |              |
    818  * |              | [:\.-]       |
    819  * |  [.]         v              |
    820  * +<----- BYTE0_SEP_BYTE1 <-----+
    821  * |              |
    822  * |              | [0-9a-fA-F]
    823  * |  [.]         v
    824  * +<--------- BYTE1_X ----------+
    825  * |              |              |
    826  * |              | [0-9a-fA-F]  |
    827  * |  [.]         v              |
    828  * +<--------- BYTE1_XX          | <sep>
    829  * |              |              |
    830  * |              | <sep>        |
    831  * |  [.]         v              |
    832  * +<----- BYTE1_SEP_BYTE2 <-----+
    833  * |              |
    834  * |              | [0-9a-fA-F]
    835  * |  [.]         v
    836  * +<--------- BYTE2_X ----------+
    837  * |              |              |
    838  * |              | [0-9a-fA-F]  |
    839  * |  [.]         v              |
    840  * +<--------- BYTE2_XX          | <sep>
    841  * |              |              |
    842  * |              | <sep>        |
    843  * |  [.]         v              |
    844  * +<----- BYTE2_SEP_BYTE3 <-----+
    845  * |              |
    846  * |              | [0-9a-fA-F]
    847  * |  [.]         v
    848  * +<--------- BYTE3_X ----------+
    849  * |              |              |
    850  * |              | [0-9a-fA-F]  |
    851  * |  [.]         v              |
    852  * +<--------- BYTE3_XX          | <sep>
    853  * |              |              |
    854  * |              | <sep>        |
    855  * |  [.]         v              |
    856  * +<----- BYTE3_SEP_BYTE4 <-----+
    857  * |              |
    858  * |              | [0-9a-fA-F]
    859  * |  [.]         v
    860  * +<--------- BYTE4_X ----------+
    861  * |              |              |
    862  * |              | [0-9a-fA-F]  |
    863  * |  [.]         v              |
    864  * +<--------- BYTE4_XX          | <sep>
    865  * |              |              |
    866  * |              | <sep>        |
    867  * |  [.]         v              |
    868  * +<----- BYTE4_SEP_BYTE5 <-----+
    869  * |              |
    870  * |              | [0-9a-fA-F]
    871  * |  [.]         v
    872  * +<--------- BYTE5_X ----------+
    873  * |              |              |
    874  * |              | [0-9a-fA-F]  |
    875  * |  [.]         v              |
    876  * +<--------- BYTE5_XX          | \0
    877  * |              |              |
    878  * |              | \0           |
    879  * |              |              v
    880  * +--> (reject)  +---------> (accept)
    881  *
    882  */
    883 static u_char
    884 pcapint_atomac48_x_xx_6_times(const char *s, uint8_t *addr)
    885 {
    886 	enum {
    887 		START,
    888 		BYTE0_X,
    889 		BYTE0_XX,
    890 		BYTE0_SEP_BYTE1,
    891 		BYTE1_X,
    892 		BYTE1_XX,
    893 		BYTE1_SEP_BYTE2,
    894 		BYTE2_X,
    895 		BYTE2_XX,
    896 		BYTE2_SEP_BYTE3,
    897 		BYTE3_X,
    898 		BYTE3_XX,
    899 		BYTE3_SEP_BYTE4,
    900 		BYTE4_X,
    901 		BYTE4_XX,
    902 		BYTE4_SEP_BYTE5,
    903 		BYTE5_X,
    904 		BYTE5_XX,
    905 	} fsm_state = START;
    906 	uint8_t buf[6];
    907 	const char *seplist = ":.-";
    908 	char sep;
    909 
    910 	while (*s) {
    911 		switch (fsm_state) {
    912 		case START:
    913 			if (PCAP_ISXDIGIT(*s)) {
    914 				buf[0] = pcapint_xdtoi(*s);
    915 				fsm_state = BYTE0_X;
    916 				break;
    917 			}
    918 			goto reject;
    919 		case BYTE0_X:
    920 			if (strchr(seplist, *s)) {
    921 				sep = *s;
    922 				fsm_state = BYTE0_SEP_BYTE1;
    923 				break;
    924 			}
    925 			if (PCAP_ISXDIGIT(*s)) {
    926 				buf[0] = buf[0] << 4 | pcapint_xdtoi(*s);
    927 				fsm_state = BYTE0_XX;
    928 				break;
    929 			}
    930 			goto reject;
    931 		case BYTE0_XX:
    932 			if (strchr(seplist, *s)) {
    933 				sep = *s;
    934 				fsm_state = BYTE0_SEP_BYTE1;
    935 				break;
    936 			}
    937 			goto reject;
    938 		case BYTE0_SEP_BYTE1:
    939 			if (PCAP_ISXDIGIT(*s)) {
    940 				buf[1] = pcapint_xdtoi(*s);
    941 				fsm_state = BYTE1_X;
    942 				break;
    943 			}
    944 			goto reject;
    945 		case BYTE1_X:
    946 			if (*s == sep) {
    947 				fsm_state = BYTE1_SEP_BYTE2;
    948 				break;
    949 			}
    950 			if (PCAP_ISXDIGIT(*s)) {
    951 				buf[1] = buf[1] << 4 | pcapint_xdtoi(*s);
    952 				fsm_state = BYTE1_XX;
    953 				break;
    954 			}
    955 			goto reject;
    956 		case BYTE1_XX:
    957 			if (*s == sep) {
    958 				fsm_state = BYTE1_SEP_BYTE2;
    959 				break;
    960 			}
    961 			goto reject;
    962 		case BYTE1_SEP_BYTE2:
    963 			if (PCAP_ISXDIGIT(*s)) {
    964 				buf[2] = pcapint_xdtoi(*s);
    965 				fsm_state = BYTE2_X;
    966 				break;
    967 			}
    968 			goto reject;
    969 		case BYTE2_X:
    970 			if (*s == sep) {
    971 				fsm_state = BYTE2_SEP_BYTE3;
    972 				break;
    973 			}
    974 			if (PCAP_ISXDIGIT(*s)) {
    975 				buf[2] = buf[2] << 4 | pcapint_xdtoi(*s);
    976 				fsm_state = BYTE2_XX;
    977 				break;
    978 			}
    979 			goto reject;
    980 		case BYTE2_XX:
    981 			if (*s == sep) {
    982 				fsm_state = BYTE2_SEP_BYTE3;
    983 				break;
    984 			}
    985 			goto reject;
    986 		case BYTE2_SEP_BYTE3:
    987 			if (PCAP_ISXDIGIT(*s)) {
    988 				buf[3] = pcapint_xdtoi(*s);
    989 				fsm_state = BYTE3_X;
    990 				break;
    991 			}
    992 			goto reject;
    993 		case BYTE3_X:
    994 			if (*s == sep) {
    995 				fsm_state = BYTE3_SEP_BYTE4;
    996 				break;
    997 			}
    998 			if (PCAP_ISXDIGIT(*s)) {
    999 				buf[3] = buf[3] << 4 | pcapint_xdtoi(*s);
   1000 				fsm_state = BYTE3_XX;
   1001 				break;
   1002 			}
   1003 			goto reject;
   1004 		case BYTE3_XX:
   1005 			if (*s == sep) {
   1006 				fsm_state = BYTE3_SEP_BYTE4;
   1007 				break;
   1008 			}
   1009 			goto reject;
   1010 		case BYTE3_SEP_BYTE4:
   1011 			if (PCAP_ISXDIGIT(*s)) {
   1012 				buf[4] = pcapint_xdtoi(*s);
   1013 				fsm_state = BYTE4_X;
   1014 				break;
   1015 			}
   1016 			goto reject;
   1017 		case BYTE4_X:
   1018 			if (*s == sep) {
   1019 				fsm_state = BYTE4_SEP_BYTE5;
   1020 				break;
   1021 			}
   1022 			if (PCAP_ISXDIGIT(*s)) {
   1023 				buf[4] = buf[4] << 4 | pcapint_xdtoi(*s);
   1024 				fsm_state = BYTE4_XX;
   1025 				break;
   1026 			}
   1027 			goto reject;
   1028 		case BYTE4_XX:
   1029 			if (*s == sep) {
   1030 				fsm_state = BYTE4_SEP_BYTE5;
   1031 				break;
   1032 			}
   1033 			goto reject;
   1034 		case BYTE4_SEP_BYTE5:
   1035 			if (PCAP_ISXDIGIT(*s)) {
   1036 				buf[5] = pcapint_xdtoi(*s);
   1037 				fsm_state = BYTE5_X;
   1038 				break;
   1039 			}
   1040 			goto reject;
   1041 		case BYTE5_X:
   1042 			if (PCAP_ISXDIGIT(*s)) {
   1043 				buf[5] = buf[5] << 4 | pcapint_xdtoi(*s);
   1044 				fsm_state = BYTE5_XX;
   1045 				break;
   1046 			}
   1047 			goto reject;
   1048 		case BYTE5_XX:
   1049 			goto reject;
   1050 		} // switch
   1051 		s++;
   1052 	} // while
   1053 
   1054 	if (fsm_state == BYTE5_X || fsm_state == BYTE5_XX) {
   1055 		// accept
   1056 		memcpy(addr, buf, sizeof(buf));
   1057 		return 1;
   1058 	}
   1059 
   1060 reject:
   1061 	return 0;
   1062 }
   1063 
   1064 // The 'addr' argument must point to an array of at least 6 elements.
   1065 static int
   1066 pcapint_atomac48(const char *s, uint8_t *addr)
   1067 {
   1068 	return s && (
   1069 	    pcapint_atomac48_xxxxxxxxxxxx(s, addr) ||
   1070 	    pcapint_atomac48_xxxx_3_times(s, addr) ||
   1071 	    pcapint_atomac48_x_xx_6_times(s, addr)
   1072 	);
   1073 }
   1074 
   1075 /*
   1076  * If 's' is a MAC-48 address in one of the forms documented in pcap-filter(7)
   1077  * for "ether host", return a pointer to an allocated buffer with the binary
   1078  * value of the address.  Return NULL on any error.
   1079  */
   1080 u_char *
   1081 pcap_ether_aton(const char *s)
   1082 {
   1083 	uint8_t tmp[6];
   1084 	if (! pcapint_atomac48(s, tmp))
   1085 		return (NULL);
   1086 
   1087 	u_char *e = malloc(6);
   1088 	if (e == NULL)
   1089 		return (NULL);
   1090 	memcpy(e, tmp, sizeof(tmp));
   1091 	return (e);
   1092 }
   1093 
   1094 #ifndef HAVE_ETHER_HOSTTON
   1095 /*
   1096  * Roll our own.
   1097  *
   1098  * This should be thread-safe, as we define the static variables
   1099  * we use to be thread-local, and as pcap_next_etherent() does so
   1100  * as well.
   1101  */
   1102 u_char *
   1103 pcap_ether_hostton(const char *name)
   1104 {
   1105 	register struct pcap_etherent *ep;
   1106 	register u_char *ap;
   1107 	static thread_local FILE *fp = NULL;
   1108 	static thread_local int init = 0;
   1109 
   1110 	if (!init) {
   1111 		fp = fopen(PCAP_ETHERS_FILE, "r");
   1112 		++init;
   1113 		if (fp == NULL)
   1114 			return (NULL);
   1115 	} else if (fp == NULL)
   1116 		return (NULL);
   1117 	else
   1118 		rewind(fp);
   1119 
   1120 	while ((ep = pcap_next_etherent(fp)) != NULL) {
   1121 		if (strcmp(ep->name, name) == 0) {
   1122 			ap = (u_char *)malloc(6);
   1123 			if (ap != NULL) {
   1124 				memcpy(ap, ep->addr, 6);
   1125 				return (ap);
   1126 			}
   1127 			break;
   1128 		}
   1129 	}
   1130 	return (NULL);
   1131 }
   1132 #else
   1133 /*
   1134  * Use the OS-supplied routine.
   1135  * This *should* be thread-safe; the API doesn't have a static buffer.
   1136  */
   1137 u_char *
   1138 pcap_ether_hostton(const char *name)
   1139 {
   1140 	register u_char *ap;
   1141 	u_char a[6];
   1142 	char namebuf[1024];
   1143 
   1144 	/*
   1145 	 * In AIX 7.1 and 7.2: int ether_hostton(char *, struct ether_addr *);
   1146 	 */
   1147 	pcapint_strlcpy(namebuf, name, sizeof(namebuf));
   1148 	ap = NULL;
   1149 	if (ether_hostton(namebuf, (struct ether_addr *)a) == 0) {
   1150 		ap = (u_char *)malloc(6);
   1151 		if (ap != NULL)
   1152 			memcpy((char *)ap, (char *)a, 6);
   1153 	}
   1154 	return (ap);
   1155 }
   1156 #endif
   1157 
   1158 /*
   1159  * XXX - not guaranteed to be thread-safe!
   1160  */
   1161 int
   1162 #ifdef	DECNETLIB
   1163 __pcap_nametodnaddr(const char *name, u_short *res)
   1164 {
   1165 	struct nodeent *getnodebyname();
   1166 	struct nodeent *nep;
   1167 
   1168 	nep = getnodebyname(name);
   1169 	if (nep == ((struct nodeent *)0))
   1170 		return(0);
   1171 
   1172 	memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
   1173 	return(1);
   1174 #else
   1175 __pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
   1176 {
   1177 	return(0);
   1178 #endif
   1179 }
   1180