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