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