xref: /openbsd-src/usr.sbin/tcpdump/addrtoname.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: addrtoname.c,v 1.39 2018/12/20 03:39:29 dlg Exp $	*/
2 
3 /*
4  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
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  *  Internet, ethernet, port, and protocol string to address
24  *  and address to string conversion routines
25  */
26 
27 #include <sys/socket.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 
31 struct mbuf;
32 struct rtentry;
33 #include <net/if.h>
34 
35 #include <netinet/in.h>
36 #include <netinet/if_ether.h>
37 #include <netinet/ip6.h>
38 
39 #include <arpa/inet.h>
40 
41 #include <ctype.h>
42 #include <inttypes.h>
43 #include <netdb.h>
44 #include <pcap.h>
45 #include <pcap-namedb.h>
46 #include <signal.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <stdlib.h>
50 #include <unistd.h>
51 #include <limits.h>
52 
53 #include "interface.h"
54 #include "addrtoname.h"
55 #include "llc.h"
56 #include "privsep.h"
57 #include "savestr.h"
58 
59 /*
60  * hash tables for whatever-to-name translations
61  */
62 
63 #define HASHNAMESIZE 4096
64 
65 struct hnamemem {
66 	u_int32_t addr;
67 	char *name;
68 	struct hnamemem *nxt;
69 };
70 
71 struct hnamemem hnametable[HASHNAMESIZE];
72 struct hnamemem tporttable[HASHNAMESIZE];
73 struct hnamemem uporttable[HASHNAMESIZE];
74 struct hnamemem eprototable[HASHNAMESIZE];
75 struct hnamemem dnaddrtable[HASHNAMESIZE];
76 struct hnamemem llcsaptable[HASHNAMESIZE];
77 
78 struct h6namemem {
79 	struct in6_addr addr;
80 	char *name;
81 	struct h6namemem *nxt;
82 };
83 
84 struct h6namemem h6nametable[HASHNAMESIZE];
85 
86 struct enamemem {
87 	u_short e_addr0;
88 	u_short e_addr1;
89 	u_short e_addr2;
90 	char *e_name;
91 	u_char *e_nsap;			/* used only for nsaptable[] */
92 #define e_bs e_nsap			/* for bytestringtable */
93 	struct enamemem *e_nxt;
94 };
95 
96 struct enamemem enametable[HASHNAMESIZE];
97 struct enamemem nsaptable[HASHNAMESIZE];
98 struct enamemem bytestringtable[HASHNAMESIZE];
99 static char *ipprototable[256];
100 
101 struct protoidmem {
102 	u_int32_t p_oui;
103 	u_short p_proto;
104 	char *p_name;
105 	struct protoidmem *p_nxt;
106 };
107 
108 struct protoidmem protoidtable[HASHNAMESIZE];
109 
110 /*
111  * A faster replacement for inet_ntoa().
112  */
113 char *
114 intoa(u_int32_t addr)
115 {
116 	char *cp;
117 	u_int byte;
118 	int n;
119 	static char buf[sizeof(".xxx.xxx.xxx.xxx")];
120 
121 	NTOHL(addr);
122 	cp = &buf[sizeof buf];
123 	*--cp = '\0';
124 
125 	n = 4;
126 	do {
127 		byte = addr & 0xff;
128 		*--cp = byte % 10 + '0';
129 		byte /= 10;
130 		if (byte > 0) {
131 			*--cp = byte % 10 + '0';
132 			byte /= 10;
133 			if (byte > 0)
134 				*--cp = byte + '0';
135 		}
136 		*--cp = '.';
137 		addr >>= 8;
138 	} while (--n > 0);
139 
140 	return cp + 1;
141 }
142 
143 static u_int32_t f_netmask;
144 static u_int32_t f_localnet;
145 static u_int32_t netmask;
146 
147 /*
148  * Return a name for the IP address pointed to by ap.  This address
149  * is assumed to be in network byte order.
150  */
151 char *
152 getname(const u_char *ap)
153 {
154 	char host[HOST_NAME_MAX+1];
155 	u_int32_t addr;
156 	struct hnamemem *p;
157 
158 	/*
159 	 * Extract 32 bits in network order, dealing with alignment.
160 	 */
161 	switch ((intptr_t)ap & (sizeof(u_int32_t)-1)) {
162 
163 	case 0:
164 		addr = *(u_int32_t *)ap;
165 		break;
166 
167 	case 2:
168 #if BYTE_ORDER == BIG_ENDIAN
169 		addr = ((u_int32_t)*(u_short *)ap << 16) |
170 			(u_int32_t)*(u_short *)(ap + 2);
171 #else
172 		addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) |
173 			(u_int32_t)*(u_short *)ap;
174 #endif
175 		break;
176 
177 	default:
178 #if BYTE_ORDER == BIG_ENDIAN
179 		addr = ((u_int32_t)ap[0] << 24) |
180 			((u_int32_t)ap[1] << 16) |
181 			((u_int32_t)ap[2] << 8) |
182 			(u_int32_t)ap[3];
183 #else
184 		addr = ((u_int32_t)ap[3] << 24) |
185 			((u_int32_t)ap[2] << 16) |
186 			((u_int32_t)ap[1] << 8) |
187 			(u_int32_t)ap[0];
188 #endif
189 		break;
190 	}
191 
192 	p = &hnametable[addr & (HASHNAMESIZE-1)];
193 	for (; p->nxt; p = p->nxt) {
194 		if (p->addr == addr)
195 			return (p->name);
196 	}
197 	p->addr = addr;
198 	p->nxt = newhnamemem();
199 
200 	/*
201 	 * Only print names when:
202 	 *	(1) -n was not given
203 	 *      (2) Address is foreign and -f was given. (If -f was not
204 	 *	    give, f_netmask and f_local are 0 and the test
205 	 *	    evaluates to true)
206 	 *      (3) -a was given or the host portion is not all ones
207 	 *          nor all zeros (i.e. not a network or broadcast address)
208 	 */
209 	if (!nflag &&
210 	    (addr & f_netmask) == f_localnet &&
211 	    (aflag ||
212 	    !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) {
213 		size_t n = priv_gethostbyaddr((char *)&addr, sizeof(addr),
214 		    AF_INET, host, sizeof(host));
215 		if (n > 0) {
216 			char *dotp;
217 
218 			p->name = savestr(host);
219 			if (Nflag) {
220 				/* Remove domain qualifications */
221 				dotp = strchr(p->name, '.');
222 				if (dotp)
223 					*dotp = '\0';
224 			}
225 			return (p->name);
226 		}
227 	}
228 	p->name = savestr(intoa(addr));
229 	return (p->name);
230 }
231 
232 /*
233  * Return a name for the IP6 address pointed to by ap.  This address
234  * is assumed to be in network byte order.
235  */
236 char *
237 getname6(const u_char *ap)
238 {
239 	char host[HOST_NAME_MAX+1];
240 	struct in6_addr addr;
241 	struct h6namemem *p;
242 	char *cp;
243 	char ntop_buf[INET6_ADDRSTRLEN];
244 
245 	memcpy(&addr, ap, sizeof(addr));
246 	p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
247 	for (; p->nxt; p = p->nxt) {
248 		if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
249 			return (p->name);
250 	}
251 	p->addr = addr;
252 	p->nxt = newh6namemem();
253 
254 	/*
255 	 * Only print names when:
256 	 *	(1) -n was not given
257 	 *      (2) Address is foreign and -f was given. (If -f was not
258 	 *	    give, f_netmask and f_local are 0 and the test
259 	 *	    evaluates to true)
260 	 *      (3) -a was given or the host portion is not all ones
261 	 *          nor all zeros (i.e. not a network or broadcast address)
262 	 */
263 	if (!nflag
264 #if 0
265 	&&
266 	    (addr & f_netmask) == f_localnet &&
267 	    (aflag ||
268 	    !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))
269 #endif
270 	    ) {
271 		size_t n = priv_gethostbyaddr((char *)&addr, sizeof(addr),
272 		    AF_INET6, host, sizeof(host));
273 		if (n > 0) {
274 			char *dotp;
275 
276 			p->name = savestr(host);
277 			if (Nflag) {
278 				/* Remove domain qualifications */
279 				dotp = strchr(p->name, '.');
280 				if (dotp)
281 					*dotp = '\0';
282 			}
283 			return (p->name);
284 		}
285 	}
286 	cp = (char *)inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
287 	p->name = savestr(cp);
288 	return (p->name);
289 }
290 
291 static char hex[] = "0123456789abcdef";
292 
293 
294 /* Find the hash node that corresponds the ether address 'ep' */
295 
296 static inline struct enamemem *
297 lookup_emem(const u_char *ep)
298 {
299 	u_int i, j, k;
300 	struct enamemem *tp;
301 
302 	k = (ep[0] << 8) | ep[1];
303 	j = (ep[2] << 8) | ep[3];
304 	i = (ep[4] << 8) | ep[5];
305 
306 	tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
307 	while (tp->e_nxt)
308 		if (tp->e_addr0 == i &&
309 		    tp->e_addr1 == j &&
310 		    tp->e_addr2 == k)
311 			return tp;
312 		else
313 			tp = tp->e_nxt;
314 	tp->e_addr0 = i;
315 	tp->e_addr1 = j;
316 	tp->e_addr2 = k;
317 	tp->e_nxt = calloc(1, sizeof(*tp));
318 	if (tp->e_nxt == NULL)
319 		error("lookup_emem: calloc");
320 
321 	return tp;
322 }
323 
324 /*
325  * Find the hash node that corresponds to the bytestring 'bs'
326  * with length 'nlen'
327  */
328 
329 static inline struct enamemem *
330 lookup_bytestring(const u_char *bs, const int nlen)
331 {
332 	struct enamemem *tp;
333 	u_int i, j, k;
334 
335 	if (nlen >= 6) {
336 		k = (bs[0] << 8) | bs[1];
337 		j = (bs[2] << 8) | bs[3];
338 		i = (bs[4] << 8) | bs[5];
339 	} else if (nlen >= 4) {
340 		k = (bs[0] << 8) | bs[1];
341 		j = (bs[2] << 8) | bs[3];
342 		i = 0;
343 	} else
344 		i = j = k = 0;
345 
346 	tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
347 	while (tp->e_nxt)
348 		if (tp->e_addr0 == i &&
349 		    tp->e_addr1 == j &&
350 		    tp->e_addr2 == k &&
351 		    bcmp((char *)bs, (char *)(tp->e_bs), nlen) == 0)
352 			return tp;
353 		else
354 			tp = tp->e_nxt;
355 
356 	tp->e_addr0 = i;
357 	tp->e_addr1 = j;
358 	tp->e_addr2 = k;
359 
360 	tp->e_bs = calloc(1, nlen + 1);
361 	if (tp->e_bs == NULL)
362 		error("lookup_bytestring: calloc");
363 	bcopy(bs, tp->e_bs, nlen);
364 	tp->e_nxt = calloc(1, sizeof(*tp));
365 	if (tp->e_nxt == NULL)
366 		error("lookup_bytestring: calloc");
367 
368 	return tp;
369 }
370 
371 /* Find the hash node that corresponds the NSAP 'nsap' */
372 
373 static inline struct enamemem *
374 lookup_nsap(const u_char *nsap)
375 {
376 	u_int i, j, k;
377 	int nlen = *nsap;
378 	struct enamemem *tp;
379 	const u_char *ensap = nsap + nlen - 6;
380 
381 	if (nlen > 6) {
382 		k = (ensap[0] << 8) | ensap[1];
383 		j = (ensap[2] << 8) | ensap[3];
384 		i = (ensap[4] << 8) | ensap[5];
385 	}
386 	else
387 		i = j = k = 0;
388 
389 	tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
390 	while (tp->e_nxt)
391 		if (tp->e_addr0 == i &&
392 		    tp->e_addr1 == j &&
393 		    tp->e_addr2 == k &&
394 		    tp->e_nsap[0] == nlen &&
395 		    memcmp((char *)&(nsap[1]),
396 			(char *)&(tp->e_nsap[1]), nlen) == 0)
397 			return tp;
398 		else
399 			tp = tp->e_nxt;
400 	tp->e_addr0 = i;
401 	tp->e_addr1 = j;
402 	tp->e_addr2 = k;
403 	tp->e_nsap = malloc(nlen + 1);
404 	if (tp->e_nsap == NULL)
405 		error("lookup_nsap: malloc");
406 	memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1);
407 	tp->e_nxt = calloc(1, sizeof(*tp));
408 	if (tp->e_nxt == NULL)
409 		error("lookup_nsap: calloc");
410 
411 	return tp;
412 }
413 
414 /* Find the hash node that corresponds the protoid 'pi'. */
415 
416 static inline struct protoidmem *
417 lookup_protoid(const u_char *pi)
418 {
419 	u_int i, j;
420 	struct protoidmem *tp;
421 
422 	/* 5 octets won't be aligned */
423 	i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
424 	j =   (pi[3] << 8) + pi[4];
425 	/* XXX should be endian-insensitive, but do big-endian testing  XXX */
426 
427 	tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
428 	while (tp->p_nxt)
429 		if (tp->p_oui == i && tp->p_proto == j)
430 			return tp;
431 		else
432 			tp = tp->p_nxt;
433 	tp->p_oui = i;
434 	tp->p_proto = j;
435 	tp->p_nxt = calloc(1, sizeof(*tp));
436 	if (tp->p_nxt == NULL)
437 		error("lookup_protoid: calloc");
438 
439 	return tp;
440 }
441 
442 char *
443 etheraddr_string(const u_char *ep)
444 {
445 	struct enamemem *tp;
446 	struct ether_addr e;
447 
448 	tp = lookup_emem(ep);
449 	if (tp->e_name)
450 		return (tp->e_name);
451 #ifdef HAVE_ETHER_NTOHOST
452 	if (!nflag) {
453 		char buf[HOST_NAME_MAX+1 + 1];
454 		if (priv_ether_ntohost(buf, sizeof(buf),
455 		    (struct ether_addr *)ep) > 0) {
456 			tp->e_name = savestr(buf);
457 			return (tp->e_name);
458 		}
459 	}
460 #endif
461 	memcpy(e.ether_addr_octet, ep, sizeof(e.ether_addr_octet));
462 	tp->e_name = savestr(ether_ntoa(&e));
463 	return (tp->e_name);
464 }
465 
466 char *
467 linkaddr_string(const u_char *ep, const int len)
468 {
469 	u_int i, j;
470 	char *cp;
471 	struct enamemem *tp;
472 
473 	if (len == 6)	/* XXX not totally correct... */
474 		return etheraddr_string(ep);
475 
476 	tp = lookup_bytestring(ep, len);
477 	if (tp->e_name)
478 		return (tp->e_name);
479 
480 	tp->e_name = cp = reallocarray(NULL, len, 3);
481 	if (tp->e_name == NULL)
482 		error("linkaddr_string: malloc");
483 	if ((j = *ep >> 4) != 0)
484 		*cp++ = hex[j];
485 	*cp++ = hex[*ep++ & 0xf];
486 	for (i = len-1; i > 0 ; --i) {
487 		*cp++ = ':';
488 		if ((j = *ep >> 4) != 0)
489 			*cp++ = hex[j];
490 		*cp++ = hex[*ep++ & 0xf];
491 	}
492 	*cp = '\0';
493 	return (tp->e_name);
494 }
495 
496 char *
497 etherproto_string(u_short port)
498 {
499 	char *cp;
500 	struct hnamemem *tp;
501 	u_int32_t i = port;
502 	char buf[sizeof("0000")];
503 
504 	for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
505 		if (tp->addr == i)
506 			return (tp->name);
507 
508 	tp->addr = i;
509 	tp->nxt = newhnamemem();
510 
511 	cp = buf;
512 	NTOHS(port);
513 	*cp++ = hex[port >> 12 & 0xf];
514 	*cp++ = hex[port >> 8 & 0xf];
515 	*cp++ = hex[port >> 4 & 0xf];
516 	*cp++ = hex[port & 0xf];
517 	*cp++ = '\0';
518 	tp->name = savestr(buf);
519 	return (tp->name);
520 }
521 
522 char *
523 protoid_string(const u_char *pi)
524 {
525 	u_int i, j;
526 	char *cp;
527 	struct protoidmem *tp;
528 	char buf[sizeof("00:00:00:00:00")];
529 
530 	tp = lookup_protoid(pi);
531 	if (tp->p_name)
532 		return tp->p_name;
533 
534 	cp = buf;
535 	if ((j = *pi >> 4) != 0)
536 		*cp++ = hex[j];
537 	*cp++ = hex[*pi++ & 0xf];
538 	for (i = 4; (int)--i >= 0;) {
539 		*cp++ = ':';
540 		if ((j = *pi >> 4) != 0)
541 			*cp++ = hex[j];
542 		*cp++ = hex[*pi++ & 0xf];
543 	}
544 	*cp = '\0';
545 	tp->p_name = savestr(buf);
546 	return (tp->p_name);
547 }
548 
549 char *
550 llcsap_string(u_char sap)
551 {
552 	struct hnamemem *tp;
553 	u_int32_t i = sap;
554 	char buf[sizeof("sap 00")];
555 
556 	for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
557 		if (tp->addr == i)
558 			return (tp->name);
559 
560 	tp->addr = i;
561 	tp->nxt = newhnamemem();
562 
563 	snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff);
564 	tp->name = savestr(buf);
565 	return (tp->name);
566 }
567 
568 char *
569 isonsap_string(const u_char *nsap)
570 {
571 	u_int i, nlen = nsap[0];
572 	char *cp;
573 	struct enamemem *tp;
574 
575 	tp = lookup_nsap(nsap);
576 	if (tp->e_name)
577 		return tp->e_name;
578 
579 	tp->e_name = cp = malloc(nlen * 2 + 2);
580 	if (cp == NULL)
581 		error("isonsap_string: malloc");
582 
583 	nsap++;
584 	*cp++ = '/';
585 	for (i = nlen; (int)--i >= 0;) {
586 		*cp++ = hex[*nsap >> 4];
587 		*cp++ = hex[*nsap++ & 0xf];
588 	}
589 	*cp = '\0';
590 	return (tp->e_name);
591 }
592 
593 char *
594 tcpport_string(u_short port)
595 {
596 	struct hnamemem *tp;
597 	u_int32_t i = port;
598 	char buf[sizeof("00000")];
599 
600 	for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
601 		if (tp->addr == i)
602 			return (tp->name);
603 
604 	tp->addr = i;
605 	tp->nxt = newhnamemem();
606 
607 	(void)snprintf(buf, sizeof(buf), "%u", i);
608 	tp->name = savestr(buf);
609 	return (tp->name);
610 }
611 
612 char *
613 udpport_string(u_short port)
614 {
615 	struct hnamemem *tp;
616 	u_int32_t i = port;
617 	char buf[sizeof("00000")];
618 
619 	for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
620 		if (tp->addr == i)
621 			return (tp->name);
622 
623 	tp->addr = i;
624 	tp->nxt = newhnamemem();
625 
626 	(void)snprintf(buf, sizeof(buf), "%u", i);
627 	tp->name = savestr(buf);
628 	return (tp->name);
629 }
630 
631 char *
632 ipproto_string(u_int proto)
633 {
634 	return ipprototable[proto & 0xff];
635 }
636 
637 static void
638 init_servarray(void)
639 {
640 	struct hnamemem *table;
641 	int i, port;
642 	char buf[sizeof("0000000000")];
643 	char service[BUFSIZ];
644 	char protocol[BUFSIZ];
645 
646 	priv_getserventries();
647 	while (priv_getserventry(service, sizeof(service), &port, protocol,
648 	    sizeof(protocol)) != 0) {
649 		port = ntohs(port);
650 		i = port & (HASHNAMESIZE-1);
651 		if (strcmp(protocol, "tcp") == 0)
652 			table = &tporttable[i];
653 		else if (strcmp(protocol, "udp") == 0)
654 			table = &uporttable[i];
655 		else
656 			continue;
657 
658 		while (table->name)
659 			table = table->nxt;
660 		if (nflag) {
661 			(void)snprintf(buf, sizeof(buf), "%d", port);
662 			table->name = savestr(buf);
663 		} else
664 			table->name = savestr(service);
665 		table->addr = port;
666 		table->nxt = newhnamemem();
667 	}
668 }
669 
670 static void
671 init_ipprotoarray(void)
672 {
673 	int i;
674 	char buf[sizeof("000")];
675 	char prot[BUFSIZ];
676 
677 	if (!nflag) {
678 		priv_getprotoentries();
679 		while (priv_getprotoentry(prot, sizeof(prot), &i) != 0)
680 			ipprototable[i & 0xff] = savestr(prot);
681 	}
682 	for (i = 0; i < 256; i++)
683 		if (ipprototable[i] == NULL) {
684 			(void)snprintf(buf, sizeof(buf), "%d", i);
685 			ipprototable[i] = savestr(buf);
686 		}
687 }
688 
689 /* XXX from libpcap */
690 extern const struct eproto {
691 	char *s;
692 	u_short p;
693 } * const eproto_db;
694 
695 static void
696 init_eprotoarray(void)
697 {
698 	int i;
699 	struct hnamemem *table;
700 
701 	for (i = 0; eproto_db[i].s; i++) {
702 		int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
703 		table = &eprototable[j];
704 		while (table->name)
705 			table = table->nxt;
706 		table->name = eproto_db[i].s;
707 		table->addr = ntohs(eproto_db[i].p);
708 		table->nxt = newhnamemem();
709 	}
710 }
711 
712 /*
713  * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
714  * types.
715  */
716 static void
717 init_protoidarray(void)
718 {
719 	int i;
720 	struct protoidmem *tp;
721 	u_char protoid[5];
722 
723 	protoid[0] = 0;
724 	protoid[1] = 0;
725 	protoid[2] = 0;
726 	for (i = 0; eproto_db[i].s; i++) {
727 		u_short etype = htons(eproto_db[i].p);
728 
729 		memcpy((char *)&protoid[3], (char *)&etype, 2);
730 		tp = lookup_protoid(protoid);
731 		tp->p_name = savestr(eproto_db[i].s);
732 	}
733 }
734 
735 static struct etherlist {
736 	u_char addr[6];
737 	char *name;
738 } etherlist[] = {
739 	{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
740 	{{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }, "LLDP_Multicast" },
741 	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
742 };
743 
744 /*
745  * Initialize the ethers hash table.  We take two different approaches
746  * depending on whether or not the system provides the ethers name
747  * service.  If it does, we just wire in a few names at startup,
748  * and etheraddr_string() fills in the table on demand.  If it doesn't,
749  * then we suck in the entire /etc/ethers file at startup.  The idea
750  * is that parsing the local file will be fast, but spinning through
751  * all the ethers entries via NIS & next_etherent might be very slow.
752  *
753  * XXX pcap_next_etherent doesn't belong in the pcap interface, but
754  * since the pcap module already does name-to-address translation,
755  * it's already does most of the work for the ethernet address-to-name
756  * translation, so we just pcap_next_etherent as a convenience.
757  */
758 static void
759 init_etherarray(void)
760 {
761 	struct etherlist *el;
762 	struct enamemem *tp;
763 #ifdef HAVE_ETHER_NTOHOST
764 	char name[HOST_NAME_MAX+1 + 1];
765 #else
766 	struct pcap_etherent *ep;
767 	FILE *fp;
768 
769 	/* Suck in entire ethers file */
770 	fp = fopen(PCAP_ETHERS_FILE, "r");
771 	if (fp != NULL) {
772 		while ((ep = pcap_next_etherent(fp)) != NULL) {
773 			tp = lookup_emem(ep->addr);
774 			tp->e_name = savestr(ep->name);
775 		}
776 		(void)fclose(fp);
777 	}
778 #endif
779 
780 	/* Hardwire some ethernet names */
781 	for (el = etherlist; el->name != NULL; ++el) {
782 		tp = lookup_emem(el->addr);
783 		/* Don't override existing name */
784 		if (tp->e_name != NULL)
785 			continue;
786 
787 #ifdef HAVE_ETHER_NTOHOST
788                 /* Use yp/nis version of name if available */
789                 if (priv_ether_ntohost(name, sizeof(name),
790 		    (struct ether_addr *)el->addr) > 0) {
791                         tp->e_name = savestr(name);
792 			continue;
793 		}
794 #endif
795 		tp->e_name = el->name;
796 	}
797 }
798 
799 static struct tok llcsap_db[] = {
800 	{ LLCSAP_NULL,		"null" },
801 	{ LLCSAP_8021B_I,	"802.1b-gsap" },
802 	{ LLCSAP_8021B_G,	"802.1b-isap" },
803 	{ LLCSAP_IP,		"ip-sap" },
804 	{ LLCSAP_PROWAYNM,	"proway-nm" },
805 	{ LLCSAP_8021D,		"802.1d" },
806 	{ LLCSAP_RS511,		"eia-rs511" },
807 	{ LLCSAP_ISO8208,	"x.25/llc2" },
808 	{ LLCSAP_PROWAY,	"proway" },
809 	{ LLCSAP_ISONS,		"iso-clns" },
810 	{ LLCSAP_GLOBAL,	"global" },
811 	{ 0,			NULL }
812 };
813 
814 static void
815 init_llcsaparray(void)
816 {
817 	int i;
818 	struct hnamemem *table;
819 
820 	for (i = 0; llcsap_db[i].s != NULL; i++) {
821 		table = &llcsaptable[llcsap_db[i].v];
822 		while (table->name)
823 			table = table->nxt;
824 		table->name = llcsap_db[i].s;
825 		table->addr = llcsap_db[i].v;
826 		table->nxt = newhnamemem();
827 	}
828 }
829 
830 /*
831  * Initialize the address to name translation machinery.  We map all
832  * non-local IP addresses to numeric addresses if fflag is true (i.e.,
833  * to prevent blocking on the nameserver).  localnet is the IP address
834  * of the local network.  mask is its subnet mask.
835  */
836 void
837 init_addrtoname(u_int32_t localnet, u_int32_t mask)
838 {
839 	netmask = mask;
840 	if (fflag) {
841 		f_localnet = localnet;
842 		f_netmask = mask;
843 	}
844 
845 	init_servarray();
846 	init_ipprotoarray();
847 
848 	if (nflag)
849 		/*
850 		 * Simplest way to suppress names.
851 		 */
852 		return;
853 
854 	init_etherarray();
855 	init_eprotoarray();
856 	init_llcsaparray();
857 	init_protoidarray();
858 }
859 
860 char *
861 dnaddr_string(u_short dnaddr)
862 {
863 	struct hnamemem *tp;
864 
865 	for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
866 	     tp = tp->nxt)
867 		if (tp->addr == dnaddr)
868 			return (tp->name);
869 
870 	tp->addr = dnaddr;
871 	tp->nxt = newhnamemem();
872 	if (nflag)
873 		tp->name = dnnum_string(dnaddr);
874 	else
875 		tp->name = dnname_string(dnaddr);
876 
877 	return(tp->name);
878 }
879 
880 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
881 struct hnamemem *
882 newhnamemem(void)
883 {
884 	struct hnamemem *p;
885 	static struct hnamemem *ptr = NULL;
886 	static u_int num = 0;
887 
888 	if (num  <= 0) {
889 		num = 64;
890 		ptr = calloc(num, sizeof (*ptr));
891 		if (ptr == NULL)
892 			error("newhnamemem: calloc");
893 	}
894 	--num;
895 	p = ptr++;
896 	return (p);
897 }
898 
899 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
900 struct h6namemem *
901 newh6namemem(void)
902 {
903 	struct h6namemem *p;
904 	static struct h6namemem *ptr = NULL;
905 	static u_int num = 0;
906 
907 	if (num  <= 0) {
908 		num = 64;
909 		ptr = calloc(num, sizeof (*ptr));
910 		if (ptr == NULL)
911 			error("newh6namemem: calloc");
912 	}
913 	--num;
914 	p = ptr++;
915 	return (p);
916 }
917