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