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