X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/b42fd30f1dcd7943335215d97c4b3a80f88e28be..ffa1470e5c7ff0e50028d085a481dc797b0b51ed:/addrtoname.c diff --git a/addrtoname.c b/addrtoname.c index 982a3c31..8399472b 100644 --- a/addrtoname.c +++ b/addrtoname.c @@ -22,43 +22,55 @@ * and address to string conversion routines */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.86 2001-11-25 01:48:46 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.108.2.8 2006-02-27 07:27:16 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include -#include -#include +#include -struct mbuf; -struct rtentry; -#include - -#include +#ifdef USE_ETHER_NTOHOST #ifdef HAVE_NETINET_IF_ETHER_H +struct mbuf; /* Squelch compiler warnings on some platforms for */ +struct rtentry; /* declarations in */ +#include /* for "struct ifnet" in "struct arpcom" on Solaris */ #include +#endif /* HAVE_NETINET_IF_ETHER_H */ +#ifdef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST +#include +#endif /* NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */ + +#if !defined(HAVE_DECL_ETHER_NTOHOST) || !HAVE_DECL_ETHER_NTOHOST +#ifndef HAVE_STRUCT_ETHER_ADDR +struct ether_addr { + unsigned char ether_addr_octet[6]; +}; +#endif +extern int ether_ntohost(char *, const struct ether_addr *); #endif -#include +#endif /* USE_ETHER_NTOHOST */ -#include -#include #include #include #include #include #include #include -#include #include "interface.h" #include "addrtoname.h" #include "llc.h" #include "setsignal.h" +#include "extract.h" +#include "oui.h" + +#ifndef ETHER_ADDR_LEN +#include "ether.h" +#endif /* * hash tables for whatever-to-name translations @@ -67,6 +79,7 @@ struct rtentry; */ #define HASHNAMESIZE 4096 +#define BUFSIZE 128 struct hnamemem { u_int32_t addr; @@ -79,9 +92,48 @@ struct hnamemem tporttable[HASHNAMESIZE]; struct hnamemem uporttable[HASHNAMESIZE]; struct hnamemem eprototable[HASHNAMESIZE]; struct hnamemem dnaddrtable[HASHNAMESIZE]; -struct hnamemem llcsaptable[HASHNAMESIZE]; struct hnamemem ipxsaptable[HASHNAMESIZE]; +#if defined(INET6) && defined(WIN32) +/* + * fake gethostbyaddr for Win2k/XP + * gethostbyaddr() returns incorrect value when AF_INET6 is passed + * to 3rd argument. + * + * h_name in struct hostent is only valid. + */ +static struct hostent * +win32_gethostbyaddr(const char *addr, int len, int type) +{ + static struct hostent host; + static char hostbuf[NI_MAXHOST]; + char hname[NI_MAXHOST]; + struct sockaddr_in6 addr6; + + host.h_name = hostbuf; + switch (type) { + case AF_INET: + return gethostbyaddr(addr, len, type); + break; + case AF_INET6: + memset(&addr6, 0, sizeof(addr6)); + addr6.sin6_family = AF_INET6; + memcpy(&addr6.sin6_addr, addr, len); + if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6), + hname, sizeof(hname), NULL, 0, 0)) { + return NULL; + } else { + strcpy(host.h_name, hname); + return &host; + } + break; + default: + return NULL; + } +} +#define gethostbyaddr win32_gethostbyaddr +#endif /* INET6 & WIN32 */ + #ifdef INET6 struct h6namemem { struct in6_addr addr; @@ -127,7 +179,7 @@ intoa(u_int32_t addr) static char buf[sizeof(".xxx.xxx.xxx.xxx")]; NTOHL(addr); - cp = &buf[sizeof buf]; + cp = buf + sizeof(buf); *--cp = '\0'; n = 4; @@ -150,11 +202,25 @@ intoa(u_int32_t addr) static u_int32_t f_netmask; static u_int32_t f_localnet; -static u_int32_t netmask; /* * Return a name for the IP address pointed to by ap. This address * is assumed to be in network byte order. + * + * NOTE: ap is *NOT* necessarily part of the packet data (not even if + * this is being called with the "ipaddr_string()" macro), so you + * *CANNOT* use the TCHECK{2}/TTEST{2} macros on it. Furthermore, + * even in cases where it *is* part of the packet data, the caller + * would still have to check for a null return value, even if it's + * just printing the return value with "%s" - not all versions of + * printf print "(null)" with "%s" and a null pointer, some of them + * don't check for a null pointer and crash in that case. + * + * The callers of this routine should, before handing this routine + * a pointer to packet data, be sure that the data is present in + * the packet buffer. They should probably do those checks anyway, + * as other data at that layer might not be IP addresses, and it + * also needs to check whether they're present in the packet buffer. */ const char * getname(const u_char *ap) @@ -173,18 +239,14 @@ getname(const u_char *ap) p->nxt = newhnamemem(); /* - * Only print names when: - * (1) -n was not given. + * Print names unless: + * (1) -n was given. * (2) Address is foreign and -f was given. (If -f was not - * give, f_netmask and f_local are 0 and the test + * given, f_netmask and f_localnet are 0 and the test * evaluates to true) - * (3) -a was given or the host portion is not all ones - * nor all zeros (i.e. not a network or broadcast address) */ if (!nflag && - (addr & f_netmask) == f_localnet && - (aflag || - !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) { + (addr & f_netmask) == f_localnet) { hp = gethostbyaddr((char *)&addr, 4, AF_INET); if (hp) { char *dotp; @@ -227,22 +289,9 @@ getname6(const u_char *ap) p->nxt = newh6namemem(); /* - * Only print names when: - * (1) -n was not given. - * (2) Address is foreign and -f was given. (If -f was not - * give, f_netmask and f_local are 0 and the test - * evaluates to true) - * (3) -a was given or the host portion is not all ones - * nor all zeros (i.e. not a network or broadcast address) + * Do not print names if -n was given. */ - if (!nflag -#if 0 - && - (addr & f_netmask) == f_localnet && - (aflag || - !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff)) -#endif - ) { + if (!nflag) { hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); if (hp) { char *dotp; @@ -297,7 +346,7 @@ lookup_emem(const u_char *ep) } /* - * Find the hash node that corresponds to the bytestring 'bs' + * Find the hash node that corresponds to the bytestring 'bs' * with length 'nlen' */ @@ -415,34 +464,46 @@ lookup_protoid(const u_char *pi) const char * etheraddr_string(register const u_char *ep) { - register u_int i, j; + register int i; register char *cp; register struct enamemem *tp; - char buf[sizeof("00:00:00:00:00:00")]; + int oui; + char buf[BUFSIZE]; tp = lookup_emem(ep); if (tp->e_name) return (tp->e_name); #ifdef USE_ETHER_NTOHOST if (!nflag) { - char buf[128]; - if (ether_ntohost(buf, (const struct ether_addr *)ep) == 0) { - tp->e_name = strdup(buf); + char buf2[BUFSIZE]; + + /* + * We don't cast it to "const struct ether_addr *" + * because some systems fail to declare the second + * argument as a "const" pointer, even though they + * don't modify what it points to. + */ + if (ether_ntohost(buf2, (struct ether_addr *)ep) == 0) { + tp->e_name = strdup(buf2); return (tp->e_name); } } #endif cp = buf; - if ((j = *ep >> 4) != 0) - *cp++ = hex[j]; + oui = EXTRACT_24BITS(ep); + *cp++ = hex[*ep >> 4 ]; *cp++ = hex[*ep++ & 0xf]; - for (i = 5; (int)--i >= 0;) { + for (i = 5; --i >= 0;) { *cp++ = ':'; - if ((j = *ep >> 4) != 0) - *cp++ = hex[j]; + *cp++ = hex[*ep >> 4 ]; *cp++ = hex[*ep++ & 0xf]; } - *cp = '\0'; + + if (!nflag) { + snprintf(cp, BUFSIZE - (2 + 5*3), " (oui %s)", + tok2str(oui_values, "Unknown", oui)); + } else + *cp = '\0'; tp->e_name = strdup(buf); return (tp->e_name); } @@ -450,13 +511,13 @@ etheraddr_string(register const u_char *ep) const char * linkaddr_string(const u_char *ep, const unsigned int len) { - register u_int i, j; + register u_int i; register char *cp; register struct enamemem *tp; if (len == 6) /* XXX not totally correct... */ return etheraddr_string(ep); - + tp = lookup_bytestring(ep, len); if (tp->e_name) return (tp->e_name); @@ -464,13 +525,11 @@ linkaddr_string(const u_char *ep, const unsigned int len) tp->e_name = cp = (char *)malloc(len*3); if (tp->e_name == NULL) error("linkaddr_string: malloc"); - if ((j = *ep >> 4) != 0) - *cp++ = hex[j]; + *cp++ = hex[*ep >> 4]; *cp++ = hex[*ep++ & 0xf]; for (i = len-1; i > 0 ; --i) { *cp++ = ':'; - if ((j = *ep >> 4) != 0) - *cp++ = hex[j]; + *cp++ = hex[*ep >> 4]; *cp++ = hex[*ep++ & 0xf]; } *cp = '\0'; @@ -530,45 +589,32 @@ protoid_string(register const u_char *pi) return (tp->p_name); } +#define ISONSAP_MAX_LENGTH 20 const char * -llcsap_string(u_char sap) +isonsap_string(const u_char *nsap, register u_int nsap_length) { - register struct hnamemem *tp; - register u_int32_t i = sap; - char buf[sizeof("sap 00")]; - - for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) - if (tp->addr == i) - return (tp->name); - - tp->addr = i; - tp->nxt = newhnamemem(); - - snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff); - tp->name = strdup(buf); - return (tp->name); -} - -const char * -isonsap_string(const u_char *nsap) -{ - register u_int i, nlen = nsap[0]; + register u_int nsap_idx; register char *cp; register struct enamemem *tp; + if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH) + return ("isonsap_string: illegal length"); + tp = lookup_nsap(nsap); if (tp->e_name) return tp->e_name; - tp->e_name = cp = (char *)malloc(nlen * 2 + 2); + tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")); if (cp == NULL) error("isonsap_string: malloc"); - nsap++; - *cp++ = '/'; - for (i = nlen; (int)--i >= 0;) { + for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { *cp++ = hex[*nsap >> 4]; *cp++ = hex[*nsap++ & 0xf]; + if (((nsap_idx & 1) == 0) && + (nsap_idx + 1 < nsap_length)) { + *cp++ = '.'; + } } *cp = '\0'; return (tp->e_name); @@ -669,9 +715,14 @@ init_servarray(void) endservent(); } -/*XXX from libbpfc.a */ -extern struct eproto { - char *s; +/* in libpcap.a (nametoaddr.c) */ +#if defined(WIN32) && !defined(USE_STATIC_LIBPCAP) +__declspec(dllimport) +#else +extern +#endif +const struct eproto { + const char *s; u_short p; } eproto_db[]; @@ -789,9 +840,16 @@ init_etherarray(void) continue; #ifdef USE_ETHER_NTOHOST - /* Use yp/nis version of name if available */ - if (ether_ntohost(name, (const struct ether_addr *)el->addr) == 0) { - tp->e_name = strdup(name); + /* + * Use YP/NIS version of name if available. + * + * We don't cast it to "const struct ether_addr *" + * because some systems don't modify the Ethernet + * address but fail to declare the second argument + * as a "const" pointer. + */ + if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { + tp->e_name = strdup(name); continue; } #endif @@ -799,40 +857,6 @@ init_etherarray(void) } } -static struct tok llcsap_db[] = { - { LLCSAP_NULL, "null" }, - { LLCSAP_8021B_I, "802.1b-gsap" }, - { LLCSAP_8021B_G, "802.1b-isap" }, - { LLCSAP_IP, "ip-sap" }, - { LLCSAP_PROWAYNM, "proway-nm" }, - { LLCSAP_8021D, "802.1d" }, - { LLCSAP_RS511, "eia-rs511" }, - { LLCSAP_ISO8208, "x.25/llc2" }, - { LLCSAP_PROWAY, "proway" }, - { LLCSAP_SNAP, "snap" }, - { LLCSAP_IPX, "IPX" }, - { LLCSAP_NETBEUI, "netbeui" }, - { LLCSAP_ISONS, "iso-clns" }, - { LLCSAP_GLOBAL, "global" }, - { 0, NULL } -}; - -static void -init_llcsaparray(void) -{ - register int i; - register struct hnamemem *table; - - for (i = 0; llcsap_db[i].s != NULL; i++) { - table = &llcsaptable[llcsap_db[i].v]; - while (table->name) - table = table->nxt; - table->name = llcsap_db[i].s; - table->addr = llcsap_db[i].v; - table->nxt = newhnamemem(); - } -} - static struct tok ipxsap_db[] = { { 0x0000, "Unknown" }, { 0x0001, "User" }, @@ -1076,7 +1100,6 @@ init_ipxsaparray(void) void init_addrtoname(u_int32_t localnet, u_int32_t mask) { - netmask = mask; if (fflag) { f_localnet = localnet; f_netmask = mask; @@ -1090,7 +1113,6 @@ init_addrtoname(u_int32_t localnet, u_int32_t mask) init_etherarray(); init_servarray(); init_eprotoarray(); - init_llcsaparray(); init_protoidarray(); init_ipxsaparray(); }