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