]>
The Tcpdump Group git mirrors - tcpdump/blob - addrtoname.c
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
25 static const char rcsid
[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.65 2000-01-17 06:24:23 itojun Exp $ (LBL)";
33 #include <sys/types.h>
34 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <netinet/if_ether.h>
47 #include <netinet6/ip6.h>
50 #include <arpa/inet.h>
55 #include <pcap-namedb.h>
68 #include "interface.h"
69 #include "addrtoname.h"
72 #include "setsignal.h"
75 static RETSIGTYPE
nohostname(int);
78 * hash tables for whatever-to-name translations
81 #define HASHNAMESIZE 4096
89 struct hnamemem hnametable
[HASHNAMESIZE
];
90 struct hnamemem tporttable
[HASHNAMESIZE
];
91 struct hnamemem uporttable
[HASHNAMESIZE
];
92 struct hnamemem eprototable
[HASHNAMESIZE
];
93 struct hnamemem dnaddrtable
[HASHNAMESIZE
];
94 struct hnamemem llcsaptable
[HASHNAMESIZE
];
100 struct h6namemem
*nxt
;
103 struct h6namemem h6nametable
[HASHNAMESIZE
];
111 u_char
*e_nsap
; /* used only for nsaptable[] */
112 struct enamemem
*e_nxt
;
115 struct enamemem enametable
[HASHNAMESIZE
];
116 struct enamemem nsaptable
[HASHNAMESIZE
];
122 struct protoidmem
*p_nxt
;
125 struct protoidmem protoidtable
[HASHNAMESIZE
];
128 * A faster replacement for inet_ntoa().
131 intoa(u_int32_t addr
)
136 static char buf
[sizeof(".xxx.xxx.xxx.xxx")];
139 cp
= &buf
[sizeof buf
];
145 *--cp
= byte
% 10 + '0';
148 *--cp
= byte
% 10 + '0';
160 static u_int32_t f_netmask
;
161 static u_int32_t f_localnet
;
162 static u_int32_t netmask
;
165 * "getname" is written in this atrocious way to make sure we don't
166 * wait forever while trying to get hostnames from yp.
173 nohostname(int signo
)
175 longjmp(getname_env
, 1);
179 * Return a name for the IP address pointed to by ap. This address
180 * is assumed to be in network byte order.
183 getname(const u_char
*ap
)
185 register struct hostent
*hp
;
187 static struct hnamemem
*p
; /* static for longjmp() */
190 addr
= *(const u_int32_t
*)ap
;
192 memcpy(&addr
, ap
, sizeof(addr
));
194 p
= &hnametable
[addr
& (HASHNAMESIZE
-1)];
195 for (; p
->nxt
; p
= p
->nxt
) {
200 p
->nxt
= newhnamemem();
203 * Only print names when:
204 * (1) -n was not given.
205 * (2) Address is foreign and -f was given. (If -f was not
206 * give, f_netmask and f_local are 0 and the test
208 * (3) -a was given or the host portion is not all ones
209 * nor all zeros (i.e. not a network or broadcast address)
212 (addr
& f_netmask
) == f_localnet
&&
214 !((addr
& ~netmask
) == 0 || (addr
| netmask
) == 0xffffffff))) {
215 if (!setjmp(getname_env
)) {
216 (void)setsignal(SIGALRM
, nohostname
);
218 hp
= gethostbyaddr((char *)&addr
, 4, AF_INET
);
223 p
->name
= savestr(hp
->h_name
);
225 /* Remove domain qualifications */
226 dotp
= strchr(p
->name
, '.');
234 p
->name
= savestr(intoa(addr
));
240 * Return a name for the IP6 address pointed to by ap. This address
241 * is assumed to be in network byte order.
244 getname6(const u_char
*ap
)
246 register struct hostent
*hp
;
247 struct in6_addr addr
;
248 static struct h6namemem
*p
; /* static for longjmp() */
250 char ntop_buf
[INET6_ADDRSTRLEN
];
252 memcpy(&addr
, ap
, sizeof(addr
));
253 p
= &h6nametable
[*(u_int16_t
*)&addr
.s6_addr
[14] & (HASHNAMESIZE
-1)];
254 for (; p
->nxt
; p
= p
->nxt
) {
255 if (memcmp(&p
->addr
, &addr
, sizeof(addr
)) == 0)
259 p
->nxt
= newh6namemem();
262 * Only print names when:
263 * (1) -n was not given.
264 * (2) Address is foreign and -f was given. (If -f was not
265 * give, f_netmask and f_local are 0 and the test
267 * (3) -a was given or the host portion is not all ones
268 * nor all zeros (i.e. not a network or broadcast address)
273 (addr
& f_netmask
) == f_localnet
&&
275 !((addr
& ~netmask
) == 0 || (addr
| netmask
) == 0xffffffff))
278 if (!setjmp(getname_env
)) {
279 (void)setsignal(SIGALRM
, nohostname
);
281 hp
= gethostbyaddr((char *)&addr
, sizeof(addr
), AF_INET6
);
286 p
->name
= savestr(hp
->h_name
);
288 /* Remove domain qualifications */
289 dotp
= strchr(p
->name
, '.');
297 cp
= (char *)inet_ntop(AF_INET6
, &addr
, ntop_buf
, sizeof(ntop_buf
));
298 p
->name
= savestr(cp
);
303 static char hex
[] = "0123456789abcdef";
306 /* Find the hash node that corresponds the ether address 'ep' */
308 static inline struct enamemem
*
309 lookup_emem(const u_char
*ep
)
311 register u_int i
, j
, k
;
314 k
= (ep
[0] << 8) | ep
[1];
315 j
= (ep
[2] << 8) | ep
[3];
316 i
= (ep
[4] << 8) | ep
[5];
318 tp
= &enametable
[(i
^ j
) & (HASHNAMESIZE
-1)];
320 if (tp
->e_addr0
== i
&&
329 tp
->e_nxt
= (struct enamemem
*)calloc(1, sizeof(*tp
));
330 if (tp
->e_nxt
== NULL
)
331 error("lookup_emem: calloc");
336 /* Find the hash node that corresponds the NSAP 'nsap' */
338 static inline struct enamemem
*
339 lookup_nsap(register const u_char
*nsap
)
341 register u_int i
, j
, k
;
344 const u_char
*ensap
= nsap
+ nlen
- 6;
347 k
= (ensap
[0] << 8) | ensap
[1];
348 j
= (ensap
[2] << 8) | ensap
[3];
349 i
= (ensap
[4] << 8) | ensap
[5];
354 tp
= &nsaptable
[(i
^ j
) & (HASHNAMESIZE
-1)];
356 if (tp
->e_addr0
== i
&&
359 tp
->e_nsap
[0] == nlen
&&
360 memcmp((char *)&(nsap
[1]),
361 (char *)&(tp
->e_nsap
[1]), nlen
) == 0)
368 tp
->e_nsap
= (u_char
*)malloc(nlen
+ 1);
369 if (tp
->e_nsap
== NULL
)
370 error("lookup_nsap: malloc");
371 memcpy((char *)tp
->e_nsap
, (char *)nsap
, nlen
+ 1);
372 tp
->e_nxt
= (struct enamemem
*)calloc(1, sizeof(*tp
));
373 if (tp
->e_nxt
== NULL
)
374 error("lookup_nsap: calloc");
379 /* Find the hash node that corresponds the protoid 'pi'. */
381 static inline struct protoidmem
*
382 lookup_protoid(const u_char
*pi
)
385 struct protoidmem
*tp
;
387 /* 5 octets won't be aligned */
388 i
= (((pi
[0] << 8) + pi
[1]) << 8) + pi
[2];
389 j
= (pi
[3] << 8) + pi
[4];
390 /* XXX should be endian-insensitive, but do big-endian testing XXX */
392 tp
= &protoidtable
[(i
^ j
) & (HASHNAMESIZE
-1)];
394 if (tp
->p_oui
== i
&& tp
->p_proto
== j
)
400 tp
->p_nxt
= (struct protoidmem
*)calloc(1, sizeof(*tp
));
401 if (tp
->p_nxt
== NULL
)
402 error("lookup_protoid: calloc");
408 etheraddr_string(register const u_char
*ep
)
412 register struct enamemem
*tp
;
413 char buf
[sizeof("00:00:00:00:00:00")];
415 tp
= lookup_emem(ep
);
418 #ifdef HAVE_ETHER_NTOHOST
421 if (ether_ntohost(buf
, (struct ether_addr
*)ep
) == 0) {
422 tp
->e_name
= savestr(buf
);
428 if ((j
= *ep
>> 4) != 0)
430 *cp
++ = hex
[*ep
++ & 0xf];
431 for (i
= 5; (int)--i
>= 0;) {
433 if ((j
= *ep
>> 4) != 0)
435 *cp
++ = hex
[*ep
++ & 0xf];
438 tp
->e_name
= savestr(buf
);
443 etherproto_string(u_short port
)
446 register struct hnamemem
*tp
;
447 register u_int32_t i
= port
;
448 char buf
[sizeof("0000")];
450 for (tp
= &eprototable
[i
& (HASHNAMESIZE
-1)]; tp
->nxt
; tp
= tp
->nxt
)
455 tp
->nxt
= newhnamemem();
459 *cp
++ = hex
[port
>> 12 & 0xf];
460 *cp
++ = hex
[port
>> 8 & 0xf];
461 *cp
++ = hex
[port
>> 4 & 0xf];
462 *cp
++ = hex
[port
& 0xf];
464 tp
->name
= savestr(buf
);
469 protoid_string(register const u_char
*pi
)
473 register struct protoidmem
*tp
;
474 char buf
[sizeof("00:00:00:00:00")];
476 tp
= lookup_protoid(pi
);
481 if ((j
= *pi
>> 4) != 0)
483 *cp
++ = hex
[*pi
++ & 0xf];
484 for (i
= 4; (int)--i
>= 0;) {
486 if ((j
= *pi
>> 4) != 0)
488 *cp
++ = hex
[*pi
++ & 0xf];
491 tp
->p_name
= savestr(buf
);
496 llcsap_string(u_char sap
)
499 register struct hnamemem
*tp
;
500 register u_int32_t i
= sap
;
501 char buf
[sizeof("sap 00")];
503 for (tp
= &llcsaptable
[i
& (HASHNAMESIZE
-1)]; tp
->nxt
; tp
= tp
->nxt
)
508 tp
->nxt
= newhnamemem();
511 (void)strcpy(cp
, "sap ");
513 *cp
++ = hex
[sap
>> 4 & 0xf];
514 *cp
++ = hex
[sap
& 0xf];
516 tp
->name
= savestr(buf
);
521 isonsap_string(const u_char
*nsap
)
523 register u_int i
, nlen
= nsap
[0];
525 register struct enamemem
*tp
;
527 tp
= lookup_nsap(nsap
);
531 tp
->e_name
= cp
= (char *)malloc(nlen
* 2 + 2);
533 error("isonsap_string: malloc");
537 for (i
= nlen
; (int)--i
>= 0;) {
538 *cp
++ = hex
[*nsap
>> 4];
539 *cp
++ = hex
[*nsap
++ & 0xf];
546 tcpport_string(u_short port
)
548 register struct hnamemem
*tp
;
549 register u_int32_t i
= port
;
550 char buf
[sizeof("00000")];
552 for (tp
= &tporttable
[i
& (HASHNAMESIZE
-1)]; tp
->nxt
; tp
= tp
->nxt
)
557 tp
->nxt
= newhnamemem();
559 (void)snprintf(buf
, sizeof(buf
), "%u", i
);
560 tp
->name
= savestr(buf
);
565 udpport_string(register u_short port
)
567 register struct hnamemem
*tp
;
568 register u_int32_t i
= port
;
569 char buf
[sizeof("00000")];
571 for (tp
= &uporttable
[i
& (HASHNAMESIZE
-1)]; tp
->nxt
; tp
= tp
->nxt
)
576 tp
->nxt
= newhnamemem();
578 (void)snprintf(buf
, sizeof(buf
), "%u", i
);
579 tp
->name
= savestr(buf
);
587 register struct hnamemem
*table
;
589 char buf
[sizeof("0000000000")];
591 while ((sv
= getservent()) != NULL
) {
592 int port
= ntohs(sv
->s_port
);
593 i
= port
& (HASHNAMESIZE
-1);
594 if (strcmp(sv
->s_proto
, "tcp") == 0)
595 table
= &tporttable
[i
];
596 else if (strcmp(sv
->s_proto
, "udp") == 0)
597 table
= &uporttable
[i
];
604 (void)snprintf(buf
, sizeof(buf
), "%d", port
);
605 table
->name
= savestr(buf
);
607 table
->name
= savestr(sv
->s_name
);
609 table
->nxt
= newhnamemem();
614 /*XXX from libbpfc.a */
615 extern struct eproto
{
621 init_eprotoarray(void)
624 register struct hnamemem
*table
;
626 for (i
= 0; eproto_db
[i
].s
; i
++) {
627 int j
= ntohs(eproto_db
[i
].p
) & (HASHNAMESIZE
-1);
628 table
= &eprototable
[j
];
631 table
->name
= eproto_db
[i
].s
;
632 table
->addr
= ntohs(eproto_db
[i
].p
);
633 table
->nxt
= newhnamemem();
638 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
642 init_protoidarray(void)
645 register struct protoidmem
*tp
;
651 for (i
= 0; eproto_db
[i
].s
; i
++) {
652 u_short etype
= htons(eproto_db
[i
].p
);
654 memcpy((char *)&protoid
[3], (char *)&etype
, 2);
655 tp
= lookup_protoid(protoid
);
656 tp
->p_name
= savestr(eproto_db
[i
].s
);
660 static struct etherlist
{
664 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
665 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL
}
669 * Initialize the ethers hash table. We take two different approaches
670 * depending on whether or not the system provides the ethers name
671 * service. If it does, we just wire in a few names at startup,
672 * and etheraddr_string() fills in the table on demand. If it doesn't,
673 * then we suck in the entire /etc/ethers file at startup. The idea
674 * is that parsing the local file will be fast, but spinning through
675 * all the ethers entries via NIS & next_etherent might be very slow.
677 * XXX pcap_next_etherent doesn't belong in the pcap interface, but
678 * since the pcap module already does name-to-address translation,
679 * it's already does most of the work for the ethernet address-to-name
680 * translation, so we just pcap_next_etherent as a convenience.
683 init_etherarray(void)
685 register struct etherlist
*el
;
686 register struct enamemem
*tp
;
687 #ifdef HAVE_ETHER_NTOHOST
690 register struct pcap_etherent
*ep
;
693 /* Suck in entire ethers file */
694 fp
= fopen(PCAP_ETHERS_FILE
, "r");
696 while ((ep
= pcap_next_etherent(fp
)) != NULL
) {
697 tp
= lookup_emem(ep
->addr
);
698 tp
->e_name
= savestr(ep
->name
);
704 /* Hardwire some ethernet names */
705 for (el
= etherlist
; el
->name
!= NULL
; ++el
) {
706 tp
= lookup_emem(el
->addr
);
707 /* Don't override existing name */
708 if (tp
->e_name
!= NULL
)
711 #ifdef HAVE_ETHER_NTOHOST
712 /* Use yp/nis version of name if available */
713 if (ether_ntohost(name
, (struct ether_addr
*)el
->addr
) == 0) {
714 tp
->e_name
= savestr(name
);
718 tp
->e_name
= el
->name
;
722 static struct tok llcsap_db
[] = {
723 { LLCSAP_NULL
, "null" },
724 { LLCSAP_8021B_I
, "802.1b-gsap" },
725 { LLCSAP_8021B_G
, "802.1b-isap" },
726 { LLCSAP_IP
, "ip-sap" },
727 { LLCSAP_PROWAYNM
, "proway-nm" },
728 { LLCSAP_8021D
, "802.1d" },
729 { LLCSAP_RS511
, "eia-rs511" },
730 { LLCSAP_ISO8208
, "x.25/llc2" },
731 { LLCSAP_PROWAY
, "proway" },
732 { LLCSAP_ISONS
, "iso-clns" },
733 { LLCSAP_GLOBAL
, "global" },
738 init_llcsaparray(void)
741 register struct hnamemem
*table
;
743 for (i
= 0; llcsap_db
[i
].s
!= NULL
; i
++) {
744 table
= &llcsaptable
[llcsap_db
[i
].v
];
747 table
->name
= llcsap_db
[i
].s
;
748 table
->addr
= llcsap_db
[i
].v
;
749 table
->nxt
= newhnamemem();
754 * Initialize the address to name translation machinery. We map all
755 * non-local IP addresses to numeric addresses if fflag is true (i.e.,
756 * to prevent blocking on the nameserver). localnet is the IP address
757 * of the local network. mask is its subnet mask.
760 init_addrtoname(u_int32_t localnet
, u_int32_t mask
)
764 f_localnet
= localnet
;
769 * Simplest way to suppress names.
781 dnaddr_string(u_short dnaddr
)
783 register struct hnamemem
*tp
;
785 for (tp
= &dnaddrtable
[dnaddr
& (HASHNAMESIZE
-1)]; tp
->nxt
!= 0;
787 if (tp
->addr
== dnaddr
)
791 tp
->nxt
= newhnamemem();
793 tp
->name
= dnnum_string(dnaddr
);
795 tp
->name
= dnname_string(dnaddr
);
800 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
804 register struct hnamemem
*p
;
805 static struct hnamemem
*ptr
= NULL
;
806 static u_int num
= 0;
810 ptr
= (struct hnamemem
*)calloc(num
, sizeof (*ptr
));
812 error("newhnamemem: calloc");
820 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
824 register struct h6namemem
*p
;
825 static struct h6namemem
*ptr
= NULL
;
826 static u_int num
= 0;
830 ptr
= (struct h6namemem
*)calloc(num
, sizeof (*ptr
));
832 error("newh6namemem: calloc");