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