2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
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
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.
21 * Internet, ethernet, port, and protocol string to address
22 * and address to string conversion routines
27 static const char rcsid[] =
28 "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.83 2001/09/17 21:57:50 fenner Exp $ (LBL)";
35 #include <sys/types.h>
36 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #ifdef HAVE_NETINET_IF_ETHER_H
45 #include <netinet/if_ether.h>
48 #include <arpa/inet.h>
53 #include <pcap-namedb.h>
60 #include "interface.h"
61 #include "addrtoname.h"
63 #include "setsignal.h"
66 static RETSIGTYPE nohostname(int);
69 * hash tables for whatever-to-name translations
72 #define HASHNAMESIZE 4096
80 struct hnamemem hnametable[HASHNAMESIZE];
81 struct hnamemem tporttable[HASHNAMESIZE];
82 struct hnamemem uporttable[HASHNAMESIZE];
83 struct hnamemem eprototable[HASHNAMESIZE];
84 struct hnamemem dnaddrtable[HASHNAMESIZE];
85 struct hnamemem llcsaptable[HASHNAMESIZE];
91 struct h6namemem *nxt;
94 struct h6namemem h6nametable[HASHNAMESIZE];
102 u_char *e_nsap; /* used only for nsaptable[] */
103 #define e_bs e_nsap /* for bytestringtable */
104 struct enamemem *e_nxt;
107 struct enamemem enametable[HASHNAMESIZE];
108 struct enamemem nsaptable[HASHNAMESIZE];
109 struct enamemem bytestringtable[HASHNAMESIZE];
115 struct protoidmem *p_nxt;
118 struct protoidmem protoidtable[HASHNAMESIZE];
121 * A faster replacement for inet_ntoa().
124 intoa(u_int32_t addr)
129 static char buf[sizeof(".xxx.xxx.xxx.xxx")];
132 cp = &buf[sizeof buf];
138 *--cp = byte % 10 + '0';
141 *--cp = byte % 10 + '0';
153 static u_int32_t f_netmask;
154 static u_int32_t f_localnet;
155 static u_int32_t netmask;
158 * "getname" is written in this atrocious way to make sure we don't
159 * wait forever while trying to get hostnames from yp.
166 nohostname(int signo)
168 longjmp(getname_env, 1);
172 * Return a name for the IP address pointed to by ap. This address
173 * is assumed to be in network byte order.
176 getname(const u_char *ap)
178 register struct hostent *hp;
180 static struct hnamemem *p; /* static for longjmp() */
182 memcpy(&addr, ap, sizeof(addr));
183 p = &hnametable[addr & (HASHNAMESIZE-1)];
184 for (; p->nxt; p = p->nxt) {
189 p->nxt = newhnamemem();
192 * Only print names when:
193 * (1) -n was not given.
194 * (2) Address is foreign and -f was given. (If -f was not
195 * give, f_netmask and f_local are 0 and the test
197 * (3) -a was given or the host portion is not all ones
198 * nor all zeros (i.e. not a network or broadcast address)
201 (addr & f_netmask) == f_localnet &&
203 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) {
204 if (!setjmp(getname_env)) {
205 (void)setsignal(SIGALRM, nohostname);
207 hp = gethostbyaddr((char *)&addr, 4, AF_INET);
212 p->name = strdup(hp->h_name);
214 /* Remove domain qualifications */
215 dotp = strchr(p->name, '.');
223 p->name = strdup(intoa(addr));
229 * Return a name for the IP6 address pointed to by ap. This address
230 * is assumed to be in network byte order.
233 getname6(const u_char *ap)
235 register struct hostent *hp;
236 struct in6_addr addr;
237 static struct h6namemem *p; /* static for longjmp() */
238 register const char *cp;
239 char ntop_buf[INET6_ADDRSTRLEN];
241 memcpy(&addr, ap, sizeof(addr));
242 p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
243 for (; p->nxt; p = p->nxt) {
244 if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
248 p->nxt = newh6namemem();
251 * Only print names when:
252 * (1) -n was not given.
253 * (2) Address is foreign and -f was given. (If -f was not
254 * give, f_netmask and f_local are 0 and the test
256 * (3) -a was given or the host portion is not all ones
257 * nor all zeros (i.e. not a network or broadcast address)
262 (addr & f_netmask) == f_localnet &&
264 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))
267 if (!setjmp(getname_env)) {
268 (void)setsignal(SIGALRM, nohostname);
270 hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
275 p->name = strdup(hp->h_name);
277 /* Remove domain qualifications */
278 dotp = strchr(p->name, '.');
286 cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
287 p->name = strdup(cp);
292 static char hex[] = "0123456789abcdef";
295 /* Find the hash node that corresponds the ether address 'ep' */
297 static inline struct enamemem *
298 lookup_emem(const u_char *ep)
300 register u_int i, j, k;
303 k = (ep[0] << 8) | ep[1];
304 j = (ep[2] << 8) | ep[3];
305 i = (ep[4] << 8) | ep[5];
307 tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
309 if (tp->e_addr0 == i &&
318 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
319 if (tp->e_nxt == NULL)
320 error("lookup_emem: calloc");
326 * Find the hash node that corresponds to the bytestring 'bs'
330 static inline struct enamemem *
331 lookup_bytestring(register const u_char *bs, const unsigned int nlen)
334 register u_int i, j, k;
337 k = (bs[0] << 8) | bs[1];
338 j = (bs[2] << 8) | bs[3];
339 i = (bs[4] << 8) | bs[5];
340 } else if (nlen >= 4) {
341 k = (bs[0] << 8) | bs[1];
342 j = (bs[2] << 8) | bs[3];
347 tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
349 if (tp->e_addr0 == i &&
352 memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0)
361 tp->e_bs = (u_char *) calloc(1, nlen + 1);
362 memcpy(tp->e_bs, bs, nlen);
363 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
364 if (tp->e_nxt == NULL)
365 error("lookup_bytestring: calloc");
370 /* Find the hash node that corresponds the NSAP 'nsap' */
372 static inline struct enamemem *
373 lookup_nsap(register const u_char *nsap)
375 register u_int i, j, k;
376 unsigned int nlen = *nsap;
378 const u_char *ensap = nsap + nlen - 6;
381 k = (ensap[0] << 8) | ensap[1];
382 j = (ensap[2] << 8) | ensap[3];
383 i = (ensap[4] << 8) | ensap[5];
388 tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
390 if (tp->e_addr0 == i &&
393 tp->e_nsap[0] == nlen &&
394 memcmp((const char *)&(nsap[1]),
395 (char *)&(tp->e_nsap[1]), nlen) == 0)
402 tp->e_nsap = (u_char *)malloc(nlen + 1);
403 if (tp->e_nsap == NULL)
404 error("lookup_nsap: malloc");
405 memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1);
406 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
407 if (tp->e_nxt == NULL)
408 error("lookup_nsap: calloc");
413 /* Find the hash node that corresponds the protoid 'pi'. */
415 static inline struct protoidmem *
416 lookup_protoid(const u_char *pi)
419 struct protoidmem *tp;
421 /* 5 octets won't be aligned */
422 i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
423 j = (pi[3] << 8) + pi[4];
424 /* XXX should be endian-insensitive, but do big-endian testing XXX */
426 tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
428 if (tp->p_oui == i && tp->p_proto == j)
434 tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
435 if (tp->p_nxt == NULL)
436 error("lookup_protoid: calloc");
442 etheraddr_string(register const u_char *ep)
446 register struct enamemem *tp;
447 char buf[sizeof("00:00:00:00:00:00")];
449 tp = lookup_emem(ep);
452 #ifdef USE_ETHER_NTOHOST
455 if (ether_ntohost(buf, (const struct ether_addr *)ep) == 0) {
456 tp->e_name = strdup(buf);
462 if ((j = *ep >> 4) != 0)
464 *cp++ = hex[*ep++ & 0xf];
465 for (i = 5; (int)--i >= 0;) {
467 if ((j = *ep >> 4) != 0)
469 *cp++ = hex[*ep++ & 0xf];
472 tp->e_name = strdup(buf);
477 linkaddr_string(const u_char *ep, const unsigned int len)
481 register struct enamemem *tp;
483 if (len == 6) /* XXX not totally correct... */
484 return etheraddr_string(ep);
486 tp = lookup_bytestring(ep, len);
490 tp->e_name = cp = (char *)malloc(len*3);
491 if (tp->e_name == NULL)
492 error("linkaddr_string: malloc");
493 if ((j = *ep >> 4) != 0)
495 *cp++ = hex[*ep++ & 0xf];
496 for (i = len-1; i > 0 ; --i) {
498 if ((j = *ep >> 4) != 0)
500 *cp++ = hex[*ep++ & 0xf];
507 etherproto_string(u_short port)
510 register struct hnamemem *tp;
511 register u_int32_t i = port;
512 char buf[sizeof("0000")];
514 for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
519 tp->nxt = newhnamemem();
523 *cp++ = hex[port >> 12 & 0xf];
524 *cp++ = hex[port >> 8 & 0xf];
525 *cp++ = hex[port >> 4 & 0xf];
526 *cp++ = hex[port & 0xf];
528 tp->name = strdup(buf);
533 protoid_string(register const u_char *pi)
537 register struct protoidmem *tp;
538 char buf[sizeof("00:00:00:00:00")];
540 tp = lookup_protoid(pi);
545 if ((j = *pi >> 4) != 0)
547 *cp++ = hex[*pi++ & 0xf];
548 for (i = 4; (int)--i >= 0;) {
550 if ((j = *pi >> 4) != 0)
552 *cp++ = hex[*pi++ & 0xf];
555 tp->p_name = strdup(buf);
560 llcsap_string(u_char sap)
562 register struct hnamemem *tp;
563 register u_int32_t i = sap;
564 char buf[sizeof("sap 00")];
566 for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
571 tp->nxt = newhnamemem();
573 snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff);
574 tp->name = strdup(buf);
579 isonsap_string(const u_char *nsap)
581 register u_int i, nlen = nsap[0];
583 register struct enamemem *tp;
585 tp = lookup_nsap(nsap);
589 tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1));
591 error("isonsap_string: malloc");
594 for (i = 0; i < nlen; i++) {
595 *cp++ = hex[*nsap >> 4];
596 *cp++ = hex[*nsap++ & 0xf];
597 if (((i & 1) == 0) && (i + 1 < nlen))
605 tcpport_string(u_short port)
607 register struct hnamemem *tp;
608 register u_int32_t i = port;
609 char buf[sizeof("00000")];
611 for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
616 tp->nxt = newhnamemem();
618 (void)snprintf(buf, sizeof(buf), "%u", i);
619 tp->name = strdup(buf);
624 udpport_string(register u_short port)
626 register struct hnamemem *tp;
627 register u_int32_t i = port;
628 char buf[sizeof("00000")];
630 for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
635 tp->nxt = newhnamemem();
637 (void)snprintf(buf, sizeof(buf), "%u", i);
638 tp->name = strdup(buf);
646 register struct hnamemem *table;
648 char buf[sizeof("0000000000")];
650 while ((sv = getservent()) != NULL) {
651 int port = ntohs(sv->s_port);
652 i = port & (HASHNAMESIZE-1);
653 if (strcmp(sv->s_proto, "tcp") == 0)
654 table = &tporttable[i];
655 else if (strcmp(sv->s_proto, "udp") == 0)
656 table = &uporttable[i];
663 (void)snprintf(buf, sizeof(buf), "%d", port);
664 table->name = strdup(buf);
666 table->name = strdup(sv->s_name);
668 table->nxt = newhnamemem();
673 /*XXX from libbpfc.a */
674 extern struct eproto {
680 init_eprotoarray(void)
683 register struct hnamemem *table;
685 for (i = 0; eproto_db[i].s; i++) {
686 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
687 table = &eprototable[j];
690 table->name = eproto_db[i].s;
691 table->addr = ntohs(eproto_db[i].p);
692 table->nxt = newhnamemem();
696 static struct protoidlist {
697 const u_char protoid[5];
700 {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" },
701 {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" },
702 {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" },
703 {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" },
704 {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" },
705 {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
709 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
713 init_protoidarray(void)
716 register struct protoidmem *tp;
717 struct protoidlist *pl;
723 for (i = 0; eproto_db[i].s; i++) {
724 u_short etype = htons(eproto_db[i].p);
726 memcpy((char *)&protoid[3], (char *)&etype, 2);
727 tp = lookup_protoid(protoid);
728 tp->p_name = strdup(eproto_db[i].s);
730 /* Hardwire some SNAP proto ID names */
731 for (pl = protoidlist; pl->name != NULL; ++pl) {
732 tp = lookup_protoid(pl->protoid);
733 /* Don't override existing name */
734 if (tp->p_name != NULL)
737 tp->p_name = pl->name;
741 static struct etherlist {
742 const u_char addr[6];
745 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
746 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
750 * Initialize the ethers hash table. We take two different approaches
751 * depending on whether or not the system provides the ethers name
752 * service. If it does, we just wire in a few names at startup,
753 * and etheraddr_string() fills in the table on demand. If it doesn't,
754 * then we suck in the entire /etc/ethers file at startup. The idea
755 * is that parsing the local file will be fast, but spinning through
756 * all the ethers entries via NIS & next_etherent might be very slow.
758 * XXX pcap_next_etherent doesn't belong in the pcap interface, but
759 * since the pcap module already does name-to-address translation,
760 * it's already does most of the work for the ethernet address-to-name
761 * translation, so we just pcap_next_etherent as a convenience.
764 init_etherarray(void)
766 register struct etherlist *el;
767 register struct enamemem *tp;
768 #ifdef USE_ETHER_NTOHOST
771 register struct pcap_etherent *ep;
774 /* Suck in entire ethers file */
775 fp = fopen(PCAP_ETHERS_FILE, "r");
777 while ((ep = pcap_next_etherent(fp)) != NULL) {
778 tp = lookup_emem(ep->addr);
779 tp->e_name = strdup(ep->name);
785 /* Hardwire some ethernet names */
786 for (el = etherlist; el->name != NULL; ++el) {
787 tp = lookup_emem(el->addr);
788 /* Don't override existing name */
789 if (tp->e_name != NULL)
792 #ifdef USE_ETHER_NTOHOST
793 /* Use yp/nis version of name if available */
794 if (ether_ntohost(name, (const struct ether_addr *)el->addr) == 0) {
795 tp->e_name = strdup(name);
799 tp->e_name = el->name;
803 static struct tok llcsap_db[] = {
804 { LLCSAP_NULL, "null" },
805 { LLCSAP_8021B_I, "802.1b-gsap" },
806 { LLCSAP_8021B_G, "802.1b-isap" },
807 { LLCSAP_IP, "ip-sap" },
808 { LLCSAP_PROWAYNM, "proway-nm" },
809 { LLCSAP_8021D, "802.1d" },
810 { LLCSAP_RS511, "eia-rs511" },
811 { LLCSAP_ISO8208, "x.25/llc2" },
812 { LLCSAP_PROWAY, "proway" },
813 { LLCSAP_SNAP, "snap" },
814 { LLCSAP_IPX, "IPX" },
815 { LLCSAP_NETBEUI, "netbeui" },
816 { LLCSAP_ISONS, "iso-clns" },
817 { LLCSAP_GLOBAL, "global" },
822 init_llcsaparray(void)
825 register struct hnamemem *table;
827 for (i = 0; llcsap_db[i].s != NULL; i++) {
828 table = &llcsaptable[llcsap_db[i].v];
831 table->name = llcsap_db[i].s;
832 table->addr = llcsap_db[i].v;
833 table->nxt = newhnamemem();
838 * Initialize the address to name translation machinery. We map all
839 * non-local IP addresses to numeric addresses if fflag is true (i.e.,
840 * to prevent blocking on the nameserver). localnet is the IP address
841 * of the local network. mask is its subnet mask.
844 init_addrtoname(u_int32_t localnet, u_int32_t mask)
848 f_localnet = localnet;
853 * Simplest way to suppress names.
865 dnaddr_string(u_short dnaddr)
867 register struct hnamemem *tp;
869 for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
871 if (tp->addr == dnaddr)
875 tp->nxt = newhnamemem();
877 tp->name = dnnum_string(dnaddr);
879 tp->name = dnname_string(dnaddr);
884 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
888 register struct hnamemem *p;
889 static struct hnamemem *ptr = NULL;
890 static u_int num = 0;
894 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
896 error("newhnamemem: calloc");
904 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
908 register struct h6namemem *p;
909 static struct h6namemem *ptr = NULL;
910 static u_int num = 0;
914 ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
916 error("newh6namemem: calloc");