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