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