10f74e101Schristos /* 20f74e101Schristos * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 30f74e101Schristos * The Regents of the University of California. All rights reserved. 40f74e101Schristos * 50f74e101Schristos * Redistribution and use in source and binary forms, with or without 60f74e101Schristos * modification, are permitted provided that: (1) source code distributions 70f74e101Schristos * retain the above copyright notice and this paragraph in its entirety, (2) 80f74e101Schristos * distributions including binary code include the above copyright notice and 90f74e101Schristos * this paragraph in its entirety in the documentation or other materials 100f74e101Schristos * provided with the distribution, and (3) all advertising materials mentioning 110f74e101Schristos * features or use of this software display the following acknowledgement: 120f74e101Schristos * ``This product includes software developed by the University of California, 130f74e101Schristos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 140f74e101Schristos * the University nor the names of its contributors may be used to endorse 150f74e101Schristos * or promote products derived from this software without specific prior 160f74e101Schristos * written permission. 170f74e101Schristos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 180f74e101Schristos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 190f74e101Schristos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 200f74e101Schristos * 210f74e101Schristos * Internet, ethernet, port, and protocol string to address 220f74e101Schristos * and address to string conversion routines 230f74e101Schristos */ 2411b3aaa1Schristos #include <sys/cdefs.h> 250f74e101Schristos #ifndef lint 26*26ba0b50Schristos __RCSID("$NetBSD: addrtoname.c,v 1.13 2024/09/02 16:15:29 christos Exp $"); 270f74e101Schristos #endif 280f74e101Schristos 29c74ad251Schristos #include <config.h> 300f74e101Schristos 31c74ad251Schristos #ifdef HAVE_CASPER 32c74ad251Schristos #include <libcasper.h> 33c74ad251Schristos #include <casper/cap_dns.h> 34c74ad251Schristos #endif /* HAVE_CASPER */ 35c74ad251Schristos 36c74ad251Schristos #include "netdissect-stdinc.h" 370f74e101Schristos 380f74e101Schristos #ifdef USE_ETHER_NTOHOST 39c74ad251Schristos #if defined(NET_ETHERNET_H_DECLARES_ETHER_NTOHOST) 40c74ad251Schristos /* 41c74ad251Schristos * OK, just include <net/ethernet.h>. 42c74ad251Schristos */ 43c74ad251Schristos #include <net/ethernet.h> 44c74ad251Schristos #elif defined(NETINET_ETHER_H_DECLARES_ETHER_NTOHOST) 45c74ad251Schristos /* 46c74ad251Schristos * OK, just include <netinet/ether.h> 47c74ad251Schristos */ 480f74e101Schristos #include <netinet/ether.h> 49c74ad251Schristos #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_NTOHOST) 50c74ad251Schristos /* 51c74ad251Schristos * OK, just include <sys/ethernet.h> 52c74ad251Schristos */ 53c74ad251Schristos #include <sys/ethernet.h> 54c74ad251Schristos #elif defined(ARPA_INET_H_DECLARES_ETHER_NTOHOST) 55c74ad251Schristos /* 56c74ad251Schristos * OK, just include <arpa/inet.h> 57c74ad251Schristos */ 58c74ad251Schristos #include <arpa/inet.h> 59c74ad251Schristos #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_NTOHOST) 60c74ad251Schristos /* 61c74ad251Schristos * OK, include <netinet/if_ether.h>, after all the other stuff we 62c74ad251Schristos * need to include or define for its benefit. 63c74ad251Schristos */ 64c74ad251Schristos #define NEED_NETINET_IF_ETHER_H 65c74ad251Schristos #else 66c74ad251Schristos /* 67c74ad251Schristos * We'll have to declare it ourselves. 68c74ad251Schristos * If <netinet/if_ether.h> defines struct ether_addr, include 69c74ad251Schristos * it. Otherwise, define it ourselves. 70c74ad251Schristos */ 71c74ad251Schristos #ifdef HAVE_STRUCT_ETHER_ADDR 72c74ad251Schristos #define NEED_NETINET_IF_ETHER_H 73c74ad251Schristos #else /* HAVE_STRUCT_ETHER_ADDR */ 740f74e101Schristos struct ether_addr { 75c74ad251Schristos /* Beware FreeBSD calls this "octet". */ 76c74ad251Schristos unsigned char ether_addr_octet[MAC_ADDR_LEN]; 770f74e101Schristos }; 78c74ad251Schristos #endif /* HAVE_STRUCT_ETHER_ADDR */ 79c74ad251Schristos #endif /* what declares ether_ntohost() */ 800f74e101Schristos 81c74ad251Schristos #ifdef NEED_NETINET_IF_ETHER_H 82c74ad251Schristos /* 83c74ad251Schristos * Include diag-control.h before <net/if.h>, which too defines a macro 84c74ad251Schristos * named ND_UNREACHABLE. 85c74ad251Schristos */ 86c74ad251Schristos #include "diag-control.h" 87c74ad251Schristos #include <net/if.h> /* Needed on some platforms */ 88c74ad251Schristos #include <netinet/in.h> /* Needed on some platforms */ 89c74ad251Schristos #include <netinet/if_ether.h> 90c74ad251Schristos #endif /* NEED_NETINET_IF_ETHER_H */ 91c74ad251Schristos 92c74ad251Schristos #ifndef HAVE_DECL_ETHER_NTOHOST 93c74ad251Schristos /* 94c74ad251Schristos * No header declares it, so declare it ourselves. 95c74ad251Schristos */ 96c74ad251Schristos extern int ether_ntohost(char *, const struct ether_addr *); 97c74ad251Schristos #endif /* !defined(HAVE_DECL_ETHER_NTOHOST) */ 980f74e101Schristos #endif /* USE_ETHER_NTOHOST */ 990f74e101Schristos 1000f74e101Schristos #include <pcap.h> 1010f74e101Schristos #include <pcap-namedb.h> 102c74ad251Schristos #ifndef HAVE_GETSERVENT 103c74ad251Schristos #include <getservent.h> 104c74ad251Schristos #endif 1050f74e101Schristos #include <signal.h> 1060f74e101Schristos #include <stdio.h> 1070f74e101Schristos #include <string.h> 1080f74e101Schristos #include <stdlib.h> 1090f74e101Schristos 110fdccd7e4Schristos #include "netdissect.h" 1110f74e101Schristos #include "addrtoname.h" 112fdccd7e4Schristos #include "addrtostr.h" 113fdccd7e4Schristos #include "ethertype.h" 1140f74e101Schristos #include "llc.h" 1150f74e101Schristos #include "extract.h" 1160f74e101Schristos #include "oui.h" 1170f74e101Schristos 1180f74e101Schristos /* 1190f74e101Schristos * hash tables for whatever-to-name translations 1200f74e101Schristos * 121c74ad251Schristos * ndo_error() called on strdup(3) failure with S_ERR_ND_MEM_ALLOC status 1220f74e101Schristos */ 1230f74e101Schristos 1240f74e101Schristos #define HASHNAMESIZE 4096 1250f74e101Schristos 1260f74e101Schristos struct hnamemem { 127b3a00663Schristos uint32_t addr; 1280f74e101Schristos const char *name; 1290f74e101Schristos struct hnamemem *nxt; 1300f74e101Schristos }; 1310f74e101Schristos 1320f74e101Schristos static struct hnamemem hnametable[HASHNAMESIZE]; 1330f74e101Schristos static struct hnamemem tporttable[HASHNAMESIZE]; 1340f74e101Schristos static struct hnamemem uporttable[HASHNAMESIZE]; 1350f74e101Schristos static struct hnamemem eprototable[HASHNAMESIZE]; 1360f74e101Schristos static struct hnamemem dnaddrtable[HASHNAMESIZE]; 1370f74e101Schristos static struct hnamemem ipxsaptable[HASHNAMESIZE]; 1380f74e101Schristos 139fdccd7e4Schristos #ifdef _WIN32 1400f74e101Schristos /* 1410f74e101Schristos * fake gethostbyaddr for Win2k/XP 1420f74e101Schristos * gethostbyaddr() returns incorrect value when AF_INET6 is passed 1430f74e101Schristos * to 3rd argument. 1440f74e101Schristos * 1450f74e101Schristos * h_name in struct hostent is only valid. 1460f74e101Schristos */ 1470f74e101Schristos static struct hostent * 1480f74e101Schristos win32_gethostbyaddr(const char *addr, int len, int type) 1490f74e101Schristos { 1500f74e101Schristos static struct hostent host; 1510f74e101Schristos static char hostbuf[NI_MAXHOST]; 1520f74e101Schristos char hname[NI_MAXHOST]; 1530f74e101Schristos struct sockaddr_in6 addr6; 1540f74e101Schristos 1550f74e101Schristos host.h_name = hostbuf; 1560f74e101Schristos switch (type) { 1570f74e101Schristos case AF_INET: 1580f74e101Schristos return gethostbyaddr(addr, len, type); 1590f74e101Schristos break; 1600f74e101Schristos case AF_INET6: 1610f74e101Schristos memset(&addr6, 0, sizeof(addr6)); 1620f74e101Schristos addr6.sin6_family = AF_INET6; 1630f74e101Schristos memcpy(&addr6.sin6_addr, addr, len); 1640f74e101Schristos if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6), 1650f74e101Schristos hname, sizeof(hname), NULL, 0, 0)) { 1660f74e101Schristos return NULL; 1670f74e101Schristos } else { 168817e9a7eSchristos strlcpy(host.h_name, hname, NI_MAXHOST); 1690f74e101Schristos return &host; 1700f74e101Schristos } 1710f74e101Schristos break; 1720f74e101Schristos default: 1730f74e101Schristos return NULL; 1740f74e101Schristos } 1750f74e101Schristos } 1760f74e101Schristos #define gethostbyaddr win32_gethostbyaddr 177fdccd7e4Schristos #endif /* _WIN32 */ 1780f74e101Schristos 1790f74e101Schristos struct h6namemem { 180c74ad251Schristos nd_ipv6 addr; 1810f74e101Schristos char *name; 1820f74e101Schristos struct h6namemem *nxt; 1830f74e101Schristos }; 1840f74e101Schristos 1850f74e101Schristos static struct h6namemem h6nametable[HASHNAMESIZE]; 1860f74e101Schristos 1870f74e101Schristos struct enamemem { 1880f74e101Schristos u_short e_addr0; 1890f74e101Schristos u_short e_addr1; 1900f74e101Schristos u_short e_addr2; 1910f74e101Schristos const char *e_name; 1920f74e101Schristos u_char *e_nsap; /* used only for nsaptable[] */ 1930f74e101Schristos struct enamemem *e_nxt; 1940f74e101Schristos }; 1950f74e101Schristos 1960f74e101Schristos static struct enamemem enametable[HASHNAMESIZE]; 1970f74e101Schristos static struct enamemem nsaptable[HASHNAMESIZE]; 19872c96ff3Schristos 19972c96ff3Schristos struct bsnamemem { 20072c96ff3Schristos u_short bs_addr0; 20172c96ff3Schristos u_short bs_addr1; 20272c96ff3Schristos u_short bs_addr2; 20372c96ff3Schristos const char *bs_name; 20472c96ff3Schristos u_char *bs_bytes; 20572c96ff3Schristos unsigned int bs_nbytes; 20672c96ff3Schristos struct bsnamemem *bs_nxt; 20772c96ff3Schristos }; 20872c96ff3Schristos 20972c96ff3Schristos static struct bsnamemem bytestringtable[HASHNAMESIZE]; 2100f74e101Schristos 2110f74e101Schristos struct protoidmem { 212b3a00663Schristos uint32_t p_oui; 2130f74e101Schristos u_short p_proto; 2140f74e101Schristos const char *p_name; 2150f74e101Schristos struct protoidmem *p_nxt; 2160f74e101Schristos }; 2170f74e101Schristos 2180f74e101Schristos static struct protoidmem protoidtable[HASHNAMESIZE]; 2190f74e101Schristos 2200f74e101Schristos /* 2210f74e101Schristos * A faster replacement for inet_ntoa(). 2220f74e101Schristos */ 2230f74e101Schristos const char * 224b3a00663Schristos intoa(uint32_t addr) 2250f74e101Schristos { 226c74ad251Schristos char *cp; 227c74ad251Schristos u_int byte; 228c74ad251Schristos int n; 2290f74e101Schristos static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 2300f74e101Schristos 231c74ad251Schristos addr = ntohl(addr); 2320f74e101Schristos cp = buf + sizeof(buf); 2330f74e101Schristos *--cp = '\0'; 2340f74e101Schristos 2350f74e101Schristos n = 4; 2360f74e101Schristos do { 2370f74e101Schristos byte = addr & 0xff; 238c74ad251Schristos *--cp = (char)(byte % 10) + '0'; 2390f74e101Schristos byte /= 10; 2400f74e101Schristos if (byte > 0) { 241c74ad251Schristos *--cp = (char)(byte % 10) + '0'; 2420f74e101Schristos byte /= 10; 2430f74e101Schristos if (byte > 0) 244c74ad251Schristos *--cp = (char)byte + '0'; 2450f74e101Schristos } 2460f74e101Schristos *--cp = '.'; 2470f74e101Schristos addr >>= 8; 2480f74e101Schristos } while (--n > 0); 2490f74e101Schristos 2500f74e101Schristos return cp + 1; 2510f74e101Schristos } 2520f74e101Schristos 253b3a00663Schristos static uint32_t f_netmask; 254b3a00663Schristos static uint32_t f_localnet; 255c74ad251Schristos #ifdef HAVE_CASPER 256c74ad251Schristos cap_channel_t *capdns; 257c74ad251Schristos #endif 2580f74e101Schristos 2590f74e101Schristos /* 2600f74e101Schristos * Return a name for the IP address pointed to by ap. This address 2610f74e101Schristos * is assumed to be in network byte order. 2620f74e101Schristos * 263c74ad251Schristos * NOTE: ap is *NOT* necessarily part of the packet data, so you 264c74ad251Schristos * *CANNOT* use the ND_TCHECK_* or ND_TTEST_* macros on it. Furthermore, 2650f74e101Schristos * even in cases where it *is* part of the packet data, the caller 2660f74e101Schristos * would still have to check for a null return value, even if it's 2670f74e101Schristos * just printing the return value with "%s" - not all versions of 2680f74e101Schristos * printf print "(null)" with "%s" and a null pointer, some of them 2690f74e101Schristos * don't check for a null pointer and crash in that case. 2700f74e101Schristos * 2710f74e101Schristos * The callers of this routine should, before handing this routine 2720f74e101Schristos * a pointer to packet data, be sure that the data is present in 2730f74e101Schristos * the packet buffer. They should probably do those checks anyway, 2740f74e101Schristos * as other data at that layer might not be IP addresses, and it 2750f74e101Schristos * also needs to check whether they're present in the packet buffer. 2760f74e101Schristos */ 2770f74e101Schristos const char * 278c74ad251Schristos ipaddr_string(netdissect_options *ndo, const u_char *ap) 2790f74e101Schristos { 280c74ad251Schristos struct hostent *hp; 281b3a00663Schristos uint32_t addr; 282fdccd7e4Schristos struct hnamemem *p; 2830f74e101Schristos 2840f74e101Schristos memcpy(&addr, ap, sizeof(addr)); 2850f74e101Schristos p = &hnametable[addr & (HASHNAMESIZE-1)]; 2860f74e101Schristos for (; p->nxt; p = p->nxt) { 2870f74e101Schristos if (p->addr == addr) 2880f74e101Schristos return (p->name); 2890f74e101Schristos } 2900f74e101Schristos p->addr = addr; 291fdccd7e4Schristos p->nxt = newhnamemem(ndo); 2920f74e101Schristos 2930f74e101Schristos /* 2940f74e101Schristos * Print names unless: 2950f74e101Schristos * (1) -n was given. 2960f74e101Schristos * (2) Address is foreign and -f was given. (If -f was not 2970f74e101Schristos * given, f_netmask and f_localnet are 0 and the test 2980f74e101Schristos * evaluates to true) 2990f74e101Schristos */ 300b3a00663Schristos if (!ndo->ndo_nflag && 3010f74e101Schristos (addr & f_netmask) == f_localnet) { 302c74ad251Schristos #ifdef HAVE_CASPER 303c74ad251Schristos if (capdns != NULL) { 304c74ad251Schristos hp = cap_gethostbyaddr(capdns, (char *)&addr, 4, 305c74ad251Schristos AF_INET); 306c74ad251Schristos } else 307c74ad251Schristos #endif 3080f74e101Schristos hp = gethostbyaddr((char *)&addr, 4, AF_INET); 3090f74e101Schristos if (hp) { 3100f74e101Schristos char *dotp; 3110f74e101Schristos 3120f74e101Schristos p->name = strdup(hp->h_name); 313fdccd7e4Schristos if (p->name == NULL) 314c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 315c74ad251Schristos "%s: strdup(hp->h_name)", __func__); 316b3a00663Schristos if (ndo->ndo_Nflag) { 3170f74e101Schristos /* Remove domain qualifications */ 3180f74e101Schristos dotp = strchr(p->name, '.'); 3190f74e101Schristos if (dotp) 3200f74e101Schristos *dotp = '\0'; 3210f74e101Schristos } 3220f74e101Schristos return (p->name); 3230f74e101Schristos } 3240f74e101Schristos } 3250f74e101Schristos p->name = strdup(intoa(addr)); 326fdccd7e4Schristos if (p->name == NULL) 327c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 328c74ad251Schristos "%s: strdup(intoa(addr))", __func__); 3290f74e101Schristos return (p->name); 3300f74e101Schristos } 3310f74e101Schristos 3320f74e101Schristos /* 3330f74e101Schristos * Return a name for the IP6 address pointed to by ap. This address 3340f74e101Schristos * is assumed to be in network byte order. 3350f74e101Schristos */ 3360f74e101Schristos const char * 337c74ad251Schristos ip6addr_string(netdissect_options *ndo, const u_char *ap) 3380f74e101Schristos { 339c74ad251Schristos struct hostent *hp; 340870189d2Schristos union { 341c74ad251Schristos nd_ipv6 addr; 342870189d2Schristos struct for_hash_addr { 343870189d2Schristos char fill[14]; 344b3a00663Schristos uint16_t d; 345870189d2Schristos } addra; 346870189d2Schristos } addr; 347fdccd7e4Schristos struct h6namemem *p; 348c74ad251Schristos const char *cp; 3490f74e101Schristos char ntop_buf[INET6_ADDRSTRLEN]; 3500f74e101Schristos 3510f74e101Schristos memcpy(&addr, ap, sizeof(addr)); 352870189d2Schristos p = &h6nametable[addr.addra.d & (HASHNAMESIZE-1)]; 3530f74e101Schristos for (; p->nxt; p = p->nxt) { 3540f74e101Schristos if (memcmp(&p->addr, &addr, sizeof(addr)) == 0) 3550f74e101Schristos return (p->name); 3560f74e101Schristos } 357c74ad251Schristos memcpy(p->addr, addr.addr, sizeof(nd_ipv6)); 358fdccd7e4Schristos p->nxt = newh6namemem(ndo); 3590f74e101Schristos 3600f74e101Schristos /* 3610f74e101Schristos * Do not print names if -n was given. 3620f74e101Schristos */ 363b3a00663Schristos if (!ndo->ndo_nflag) { 364c74ad251Schristos #ifdef HAVE_CASPER 365c74ad251Schristos if (capdns != NULL) { 366c74ad251Schristos hp = cap_gethostbyaddr(capdns, (char *)&addr, 367c74ad251Schristos sizeof(addr), AF_INET6); 368c74ad251Schristos } else 369c74ad251Schristos #endif 370c74ad251Schristos hp = gethostbyaddr((char *)&addr, sizeof(addr), 371c74ad251Schristos AF_INET6); 3720f74e101Schristos if (hp) { 3730f74e101Schristos char *dotp; 3740f74e101Schristos 3750f74e101Schristos p->name = strdup(hp->h_name); 376fdccd7e4Schristos if (p->name == NULL) 377c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 378c74ad251Schristos "%s: strdup(hp->h_name)", __func__); 379b3a00663Schristos if (ndo->ndo_Nflag) { 3800f74e101Schristos /* Remove domain qualifications */ 3810f74e101Schristos dotp = strchr(p->name, '.'); 3820f74e101Schristos if (dotp) 3830f74e101Schristos *dotp = '\0'; 3840f74e101Schristos } 3850f74e101Schristos return (p->name); 3860f74e101Schristos } 3870f74e101Schristos } 388fdccd7e4Schristos cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf)); 3890f74e101Schristos p->name = strdup(cp); 390fdccd7e4Schristos if (p->name == NULL) 391c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 392c74ad251Schristos "%s: strdup(cp)", __func__); 3930f74e101Schristos return (p->name); 3940f74e101Schristos } 3950f74e101Schristos 396c74ad251Schristos static const char hex[16] = { 397c74ad251Schristos '0', '1', '2', '3', '4', '5', '6', '7', 398c74ad251Schristos '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 399c74ad251Schristos }; 4000f74e101Schristos 401c74ad251Schristos /* 402c74ad251Schristos * Convert an octet to two hex digits. 403c74ad251Schristos * 404c74ad251Schristos * Coverity appears either: 405c74ad251Schristos * 406c74ad251Schristos * not to believe the C standard when it asserts that a uint8_t is 407c74ad251Schristos * exactly 8 bits in size; 408c74ad251Schristos * 409c74ad251Schristos * not to believe that an unsigned type of exactly 8 bits has a value 410c74ad251Schristos * in the range of 0 to 255; 411c74ad251Schristos * 412c74ad251Schristos * not to believe that, for a range of unsigned values, if you shift 413c74ad251Schristos * one of those values right by 4 bits, the maximum result value is 414c74ad251Schristos * the maximum value shifted right by 4 bits, with no stray 1's shifted 415c74ad251Schristos * in; 416c74ad251Schristos * 417c74ad251Schristos * not to believe that 255 >> 4 is 15; 418c74ad251Schristos * 419c74ad251Schristos * so it gets upset that we're taking a "tainted" unsigned value, shifting 420c74ad251Schristos * it right 4 bits, and using it as an index into a 16-element array. 421c74ad251Schristos * 422c74ad251Schristos * So we do a stupid pointless masking of the result of the shift with 423c74ad251Schristos * 0xf, to hammer the point home to Coverity. 424c74ad251Schristos */ 425c74ad251Schristos static inline char * 426c74ad251Schristos octet_to_hex(char *cp, uint8_t octet) 427c74ad251Schristos { 428c74ad251Schristos *cp++ = hex[(octet >> 4) & 0xf]; 429c74ad251Schristos *cp++ = hex[(octet >> 0) & 0xf]; 430c74ad251Schristos return (cp); 431c74ad251Schristos } 4320f74e101Schristos 4330f74e101Schristos /* Find the hash node that corresponds the ether address 'ep' */ 4340f74e101Schristos 435c74ad251Schristos static struct enamemem * 436fdccd7e4Schristos lookup_emem(netdissect_options *ndo, const u_char *ep) 4370f74e101Schristos { 438c74ad251Schristos u_int i, j, k; 4390f74e101Schristos struct enamemem *tp; 4400f74e101Schristos 4410f74e101Schristos k = (ep[0] << 8) | ep[1]; 4420f74e101Schristos j = (ep[2] << 8) | ep[3]; 4430f74e101Schristos i = (ep[4] << 8) | ep[5]; 4440f74e101Schristos 4450f74e101Schristos tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; 4460f74e101Schristos while (tp->e_nxt) 4470f74e101Schristos if (tp->e_addr0 == i && 4480f74e101Schristos tp->e_addr1 == j && 4490f74e101Schristos tp->e_addr2 == k) 4500f74e101Schristos return tp; 4510f74e101Schristos else 4520f74e101Schristos tp = tp->e_nxt; 453c74ad251Schristos tp->e_addr0 = (u_short)i; 454c74ad251Schristos tp->e_addr1 = (u_short)j; 455c74ad251Schristos tp->e_addr2 = (u_short)k; 4560f74e101Schristos tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 4570f74e101Schristos if (tp->e_nxt == NULL) 458c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__); 4590f74e101Schristos 4600f74e101Schristos return tp; 4610f74e101Schristos } 4620f74e101Schristos 4630f74e101Schristos /* 4640f74e101Schristos * Find the hash node that corresponds to the bytestring 'bs' 4650f74e101Schristos * with length 'nlen' 4660f74e101Schristos */ 4670f74e101Schristos 468c74ad251Schristos static struct bsnamemem * 469c74ad251Schristos lookup_bytestring(netdissect_options *ndo, const u_char *bs, 470fdccd7e4Schristos const unsigned int nlen) 4710f74e101Schristos { 47272c96ff3Schristos struct bsnamemem *tp; 473c74ad251Schristos u_int i, j, k; 4740f74e101Schristos 4750f74e101Schristos if (nlen >= 6) { 4760f74e101Schristos k = (bs[0] << 8) | bs[1]; 4770f74e101Schristos j = (bs[2] << 8) | bs[3]; 4780f74e101Schristos i = (bs[4] << 8) | bs[5]; 4790f74e101Schristos } else if (nlen >= 4) { 4800f74e101Schristos k = (bs[0] << 8) | bs[1]; 4810f74e101Schristos j = (bs[2] << 8) | bs[3]; 4820f74e101Schristos i = 0; 4830f74e101Schristos } else 4840f74e101Schristos i = j = k = 0; 4850f74e101Schristos 4860f74e101Schristos tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)]; 48772c96ff3Schristos while (tp->bs_nxt) 48872c96ff3Schristos if (nlen == tp->bs_nbytes && 48972c96ff3Schristos tp->bs_addr0 == i && 49072c96ff3Schristos tp->bs_addr1 == j && 49172c96ff3Schristos tp->bs_addr2 == k && 49272c96ff3Schristos memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0) 4930f74e101Schristos return tp; 4940f74e101Schristos else 49572c96ff3Schristos tp = tp->bs_nxt; 4960f74e101Schristos 497c74ad251Schristos tp->bs_addr0 = (u_short)i; 498c74ad251Schristos tp->bs_addr1 = (u_short)j; 499c74ad251Schristos tp->bs_addr2 = (u_short)k; 5000f74e101Schristos 50172c96ff3Schristos tp->bs_bytes = (u_char *) calloc(1, nlen); 50272c96ff3Schristos if (tp->bs_bytes == NULL) 503c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 504c74ad251Schristos "%s: calloc", __func__); 505870189d2Schristos 50672c96ff3Schristos memcpy(tp->bs_bytes, bs, nlen); 50772c96ff3Schristos tp->bs_nbytes = nlen; 50872c96ff3Schristos tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp)); 50972c96ff3Schristos if (tp->bs_nxt == NULL) 510c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 511c74ad251Schristos "%s: calloc", __func__); 5120f74e101Schristos 5130f74e101Schristos return tp; 5140f74e101Schristos } 5150f74e101Schristos 5160f74e101Schristos /* Find the hash node that corresponds the NSAP 'nsap' */ 5170f74e101Schristos 518c74ad251Schristos static struct enamemem * 519c74ad251Schristos lookup_nsap(netdissect_options *ndo, const u_char *nsap, 520c74ad251Schristos u_int nsap_length) 5210f74e101Schristos { 522c74ad251Schristos u_int i, j, k; 5230f74e101Schristos struct enamemem *tp; 524dc860a36Sspz const u_char *ensap; 5250f74e101Schristos 526dc860a36Sspz if (nsap_length > 6) { 527dc860a36Sspz ensap = nsap + nsap_length - 6; 5280f74e101Schristos k = (ensap[0] << 8) | ensap[1]; 5290f74e101Schristos j = (ensap[2] << 8) | ensap[3]; 5300f74e101Schristos i = (ensap[4] << 8) | ensap[5]; 531*26ba0b50Schristos } else 5320f74e101Schristos i = j = k = 0; 5330f74e101Schristos 5340f74e101Schristos tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; 5350f74e101Schristos while (tp->e_nxt) 53672c96ff3Schristos if (nsap_length == tp->e_nsap[0] && 53772c96ff3Schristos tp->e_addr0 == i && 5380f74e101Schristos tp->e_addr1 == j && 5390f74e101Schristos tp->e_addr2 == k && 54072c96ff3Schristos memcmp((const char *)nsap, 541dc860a36Sspz (char *)&(tp->e_nsap[1]), nsap_length) == 0) 5420f74e101Schristos return tp; 5430f74e101Schristos else 5440f74e101Schristos tp = tp->e_nxt; 545c74ad251Schristos tp->e_addr0 = (u_short)i; 546c74ad251Schristos tp->e_addr1 = (u_short)j; 547c74ad251Schristos tp->e_addr2 = (u_short)k; 548dc860a36Sspz tp->e_nsap = (u_char *)malloc(nsap_length + 1); 5490f74e101Schristos if (tp->e_nsap == NULL) 550c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: malloc", __func__); 551dc860a36Sspz tp->e_nsap[0] = (u_char)nsap_length; /* guaranteed < ISONSAP_MAX_LENGTH */ 552dc860a36Sspz memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length); 5530f74e101Schristos tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 5540f74e101Schristos if (tp->e_nxt == NULL) 555c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__); 5560f74e101Schristos 5570f74e101Schristos return tp; 5580f74e101Schristos } 5590f74e101Schristos 5600f74e101Schristos /* Find the hash node that corresponds the protoid 'pi'. */ 5610f74e101Schristos 562c74ad251Schristos static struct protoidmem * 563fdccd7e4Schristos lookup_protoid(netdissect_options *ndo, const u_char *pi) 5640f74e101Schristos { 565c74ad251Schristos u_int i, j; 5660f74e101Schristos struct protoidmem *tp; 5670f74e101Schristos 5680f74e101Schristos /* 5 octets won't be aligned */ 5690f74e101Schristos i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 5700f74e101Schristos j = (pi[3] << 8) + pi[4]; 5710f74e101Schristos /* XXX should be endian-insensitive, but do big-endian testing XXX */ 5720f74e101Schristos 5730f74e101Schristos tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 5740f74e101Schristos while (tp->p_nxt) 5750f74e101Schristos if (tp->p_oui == i && tp->p_proto == j) 5760f74e101Schristos return tp; 5770f74e101Schristos else 5780f74e101Schristos tp = tp->p_nxt; 5790f74e101Schristos tp->p_oui = i; 580c74ad251Schristos tp->p_proto = (u_short)j; 5810f74e101Schristos tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 5820f74e101Schristos if (tp->p_nxt == NULL) 583c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__); 5840f74e101Schristos 5850f74e101Schristos return tp; 5860f74e101Schristos } 5870f74e101Schristos 5880f74e101Schristos const char * 589c74ad251Schristos etheraddr_string(netdissect_options *ndo, const uint8_t *ep) 5900f74e101Schristos { 591c74ad251Schristos int i; 592c74ad251Schristos char *cp; 593c74ad251Schristos struct enamemem *tp; 5940f74e101Schristos int oui; 5950f74e101Schristos char buf[BUFSIZE]; 5960f74e101Schristos 597fdccd7e4Schristos tp = lookup_emem(ndo, ep); 5980f74e101Schristos if (tp->e_name) 5990f74e101Schristos return (tp->e_name); 6000f74e101Schristos #ifdef USE_ETHER_NTOHOST 601b3a00663Schristos if (!ndo->ndo_nflag) { 6020f74e101Schristos char buf2[BUFSIZE]; 603c74ad251Schristos /* 604c74ad251Schristos * This is a non-const copy of ep for ether_ntohost(), which 605c74ad251Schristos * has its second argument non-const in OpenBSD. Also saves a 606c74ad251Schristos * type cast. 607c74ad251Schristos */ 608c74ad251Schristos struct ether_addr ea; 6090f74e101Schristos 610c74ad251Schristos memcpy (&ea, ep, MAC_ADDR_LEN); 611c74ad251Schristos if (ether_ntohost(buf2, &ea) == 0) { 6120f74e101Schristos tp->e_name = strdup(buf2); 613fdccd7e4Schristos if (tp->e_name == NULL) 614c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 615c74ad251Schristos "%s: strdup(buf2)", __func__); 6160f74e101Schristos return (tp->e_name); 6170f74e101Schristos } 6180f74e101Schristos } 6190f74e101Schristos #endif 6200f74e101Schristos cp = buf; 621c74ad251Schristos oui = EXTRACT_BE_U_3(ep); 622c74ad251Schristos cp = octet_to_hex(cp, *ep++); 6230f74e101Schristos for (i = 5; --i >= 0;) { 6240f74e101Schristos *cp++ = ':'; 625c74ad251Schristos cp = octet_to_hex(cp, *ep++); 6260f74e101Schristos } 6270f74e101Schristos 628b3a00663Schristos if (!ndo->ndo_nflag) { 6290f74e101Schristos snprintf(cp, BUFSIZE - (2 + 5*3), " (oui %s)", 6300f74e101Schristos tok2str(oui_values, "Unknown", oui)); 6310f74e101Schristos } else 6320f74e101Schristos *cp = '\0'; 6330f74e101Schristos tp->e_name = strdup(buf); 634fdccd7e4Schristos if (tp->e_name == NULL) 635c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 636c74ad251Schristos "%s: strdup(buf)", __func__); 6370f74e101Schristos return (tp->e_name); 6380f74e101Schristos } 6390f74e101Schristos 6400f74e101Schristos const char * 641c74ad251Schristos le64addr_string(netdissect_options *ndo, const uint8_t *ep) 6420e9868baSchristos { 6430e9868baSchristos const unsigned int len = 8; 644c74ad251Schristos u_int i; 645c74ad251Schristos char *cp; 646c74ad251Schristos struct bsnamemem *tp; 6470e9868baSchristos char buf[BUFSIZE]; 6480e9868baSchristos 649fdccd7e4Schristos tp = lookup_bytestring(ndo, ep, len); 65072c96ff3Schristos if (tp->bs_name) 65172c96ff3Schristos return (tp->bs_name); 6520e9868baSchristos 6530e9868baSchristos cp = buf; 6540e9868baSchristos for (i = len; i > 0 ; --i) { 655c74ad251Schristos cp = octet_to_hex(cp, *(ep + i - 1)); 6560e9868baSchristos *cp++ = ':'; 6570e9868baSchristos } 6580e9868baSchristos cp --; 6590e9868baSchristos 6600e9868baSchristos *cp = '\0'; 6610e9868baSchristos 66272c96ff3Schristos tp->bs_name = strdup(buf); 66372c96ff3Schristos if (tp->bs_name == NULL) 664c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 665c74ad251Schristos "%s: strdup(buf)", __func__); 6660e9868baSchristos 66772c96ff3Schristos return (tp->bs_name); 6680e9868baSchristos } 6690e9868baSchristos 6700e9868baSchristos const char * 671c74ad251Schristos linkaddr_string(netdissect_options *ndo, const uint8_t *ep, 672fdccd7e4Schristos const unsigned int type, const unsigned int len) 6730f74e101Schristos { 674c74ad251Schristos u_int i; 675c74ad251Schristos char *cp; 676c74ad251Schristos struct bsnamemem *tp; 6770f74e101Schristos 6780f74e101Schristos if (len == 0) 6790f74e101Schristos return ("<empty>"); 6800f74e101Schristos 681c74ad251Schristos if (type == LINKADDR_ETHER && len == MAC_ADDR_LEN) 682b3a00663Schristos return (etheraddr_string(ndo, ep)); 6830f74e101Schristos 6840f74e101Schristos if (type == LINKADDR_FRELAY) 685ba2ff121Schristos return (q922_string(ndo, ep, len)); 6860f74e101Schristos 687fdccd7e4Schristos tp = lookup_bytestring(ndo, ep, len); 68872c96ff3Schristos if (tp->bs_name) 68972c96ff3Schristos return (tp->bs_name); 6900f74e101Schristos 69172c96ff3Schristos tp->bs_name = cp = (char *)malloc(len*3); 69272c96ff3Schristos if (tp->bs_name == NULL) 693c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 694c74ad251Schristos "%s: malloc", __func__); 695c74ad251Schristos cp = octet_to_hex(cp, *ep++); 6960f74e101Schristos for (i = len-1; i > 0 ; --i) { 6970f74e101Schristos *cp++ = ':'; 698c74ad251Schristos cp = octet_to_hex(cp, *ep++); 6990f74e101Schristos } 7000f74e101Schristos *cp = '\0'; 70172c96ff3Schristos return (tp->bs_name); 7020f74e101Schristos } 7030f74e101Schristos 7040f74e101Schristos #define ISONSAP_MAX_LENGTH 20 7050f74e101Schristos const char * 706c74ad251Schristos isonsap_string(netdissect_options *ndo, const uint8_t *nsap, 707c74ad251Schristos u_int nsap_length) 7080f74e101Schristos { 709c74ad251Schristos u_int nsap_idx; 710c74ad251Schristos char *cp; 711c74ad251Schristos struct enamemem *tp; 7120f74e101Schristos 7130f74e101Schristos if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH) 7140f74e101Schristos return ("isonsap_string: illegal length"); 7150f74e101Schristos 716dc860a36Sspz tp = lookup_nsap(ndo, nsap, nsap_length); 7170f74e101Schristos if (tp->e_name) 7180f74e101Schristos return tp->e_name; 7190f74e101Schristos 7200f74e101Schristos tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")); 7210f74e101Schristos if (cp == NULL) 722c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 723c74ad251Schristos "%s: malloc", __func__); 7240f74e101Schristos 7250f74e101Schristos for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { 726c74ad251Schristos cp = octet_to_hex(cp, *nsap++); 7270f74e101Schristos if (((nsap_idx & 1) == 0) && 7280f74e101Schristos (nsap_idx + 1 < nsap_length)) { 7290f74e101Schristos *cp++ = '.'; 7300f74e101Schristos } 7310f74e101Schristos } 7320f74e101Schristos *cp = '\0'; 7330f74e101Schristos return (tp->e_name); 7340f74e101Schristos } 7350f74e101Schristos 7360f74e101Schristos const char * 737fdccd7e4Schristos tcpport_string(netdissect_options *ndo, u_short port) 7380f74e101Schristos { 739c74ad251Schristos struct hnamemem *tp; 740c74ad251Schristos uint32_t i = port; 7410f74e101Schristos char buf[sizeof("00000")]; 7420f74e101Schristos 7430f74e101Schristos for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 7440f74e101Schristos if (tp->addr == i) 7450f74e101Schristos return (tp->name); 7460f74e101Schristos 7470f74e101Schristos tp->addr = i; 748fdccd7e4Schristos tp->nxt = newhnamemem(ndo); 7490f74e101Schristos 7500f74e101Schristos (void)snprintf(buf, sizeof(buf), "%u", i); 7510f74e101Schristos tp->name = strdup(buf); 752fdccd7e4Schristos if (tp->name == NULL) 753c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 754c74ad251Schristos "%s: strdup(buf)", __func__); 7550f74e101Schristos return (tp->name); 7560f74e101Schristos } 7570f74e101Schristos 7580f74e101Schristos const char * 759c74ad251Schristos udpport_string(netdissect_options *ndo, u_short port) 7600f74e101Schristos { 761c74ad251Schristos struct hnamemem *tp; 762c74ad251Schristos uint32_t i = port; 7630f74e101Schristos char buf[sizeof("00000")]; 7640f74e101Schristos 7650f74e101Schristos for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 7660f74e101Schristos if (tp->addr == i) 7670f74e101Schristos return (tp->name); 7680f74e101Schristos 7690f74e101Schristos tp->addr = i; 770fdccd7e4Schristos tp->nxt = newhnamemem(ndo); 7710f74e101Schristos 7720f74e101Schristos (void)snprintf(buf, sizeof(buf), "%u", i); 7730f74e101Schristos tp->name = strdup(buf); 774fdccd7e4Schristos if (tp->name == NULL) 775c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 776c74ad251Schristos "%s: strdup(buf)", __func__); 7770f74e101Schristos return (tp->name); 7780f74e101Schristos } 7790f74e101Schristos 7800f74e101Schristos const char * 781fdccd7e4Schristos ipxsap_string(netdissect_options *ndo, u_short port) 7820f74e101Schristos { 783c74ad251Schristos char *cp; 784c74ad251Schristos struct hnamemem *tp; 785c74ad251Schristos uint32_t i = port; 7860f74e101Schristos char buf[sizeof("0000")]; 7870f74e101Schristos 7880f74e101Schristos for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 7890f74e101Schristos if (tp->addr == i) 7900f74e101Schristos return (tp->name); 7910f74e101Schristos 7920f74e101Schristos tp->addr = i; 793fdccd7e4Schristos tp->nxt = newhnamemem(ndo); 7940f74e101Schristos 7950f74e101Schristos cp = buf; 796c74ad251Schristos port = ntohs(port); 7970f74e101Schristos *cp++ = hex[port >> 12 & 0xf]; 7980f74e101Schristos *cp++ = hex[port >> 8 & 0xf]; 7990f74e101Schristos *cp++ = hex[port >> 4 & 0xf]; 8000f74e101Schristos *cp++ = hex[port & 0xf]; 8010f74e101Schristos *cp++ = '\0'; 8020f74e101Schristos tp->name = strdup(buf); 803fdccd7e4Schristos if (tp->name == NULL) 804c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 805c74ad251Schristos "%s: strdup(buf)", __func__); 8060f74e101Schristos return (tp->name); 8070f74e101Schristos } 8080f74e101Schristos 8090f74e101Schristos static void 810b3a00663Schristos init_servarray(netdissect_options *ndo) 8110f74e101Schristos { 8120f74e101Schristos struct servent *sv; 813c74ad251Schristos struct hnamemem *table; 814c74ad251Schristos int i; 8150f74e101Schristos char buf[sizeof("0000000000")]; 8160f74e101Schristos 8170f74e101Schristos while ((sv = getservent()) != NULL) { 8180f74e101Schristos int port = ntohs(sv->s_port); 8190f74e101Schristos i = port & (HASHNAMESIZE-1); 8200f74e101Schristos if (strcmp(sv->s_proto, "tcp") == 0) 8210f74e101Schristos table = &tporttable[i]; 8220f74e101Schristos else if (strcmp(sv->s_proto, "udp") == 0) 8230f74e101Schristos table = &uporttable[i]; 8240f74e101Schristos else 8250f74e101Schristos continue; 8260f74e101Schristos 8270f74e101Schristos while (table->name) 8280f74e101Schristos table = table->nxt; 829b3a00663Schristos if (ndo->ndo_nflag) { 8300f74e101Schristos (void)snprintf(buf, sizeof(buf), "%d", port); 8310f74e101Schristos table->name = strdup(buf); 8320f74e101Schristos } else 8330f74e101Schristos table->name = strdup(sv->s_name); 834fdccd7e4Schristos if (table->name == NULL) 835c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 836c74ad251Schristos "%s: strdup", __func__); 837fdccd7e4Schristos 8380f74e101Schristos table->addr = port; 839fdccd7e4Schristos table->nxt = newhnamemem(ndo); 8400f74e101Schristos } 8410f74e101Schristos endservent(); 8420f74e101Schristos } 8430f74e101Schristos 844fdccd7e4Schristos static const struct eproto { 8450f74e101Schristos const char *s; 8460f74e101Schristos u_short p; 847fdccd7e4Schristos } eproto_db[] = { 848c74ad251Schristos { "aarp", ETHERTYPE_AARP }, 849c74ad251Schristos { "arp", ETHERTYPE_ARP }, 850c74ad251Schristos { "atalk", ETHERTYPE_ATALK }, 851c74ad251Schristos { "decnet", ETHERTYPE_DN }, 852fdccd7e4Schristos { "ip", ETHERTYPE_IP }, 853fdccd7e4Schristos { "ip6", ETHERTYPE_IPV6 }, 854c74ad251Schristos { "lat", ETHERTYPE_LAT }, 855c74ad251Schristos { "loopback", ETHERTYPE_LOOPBACK }, 856fdccd7e4Schristos { "mopdl", ETHERTYPE_MOPDL }, 857fdccd7e4Schristos { "moprc", ETHERTYPE_MOPRC }, 858c74ad251Schristos { "rarp", ETHERTYPE_REVARP }, 859fdccd7e4Schristos { "sca", ETHERTYPE_SCA }, 860fdccd7e4Schristos { (char *)0, 0 } 861fdccd7e4Schristos }; 8620f74e101Schristos 8630f74e101Schristos static void 864fdccd7e4Schristos init_eprotoarray(netdissect_options *ndo) 8650f74e101Schristos { 866c74ad251Schristos int i; 867c74ad251Schristos struct hnamemem *table; 8680f74e101Schristos 8690f74e101Schristos for (i = 0; eproto_db[i].s; i++) { 8700f74e101Schristos int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1); 8710f74e101Schristos table = &eprototable[j]; 8720f74e101Schristos while (table->name) 8730f74e101Schristos table = table->nxt; 8740f74e101Schristos table->name = eproto_db[i].s; 8750f74e101Schristos table->addr = htons(eproto_db[i].p); 876fdccd7e4Schristos table->nxt = newhnamemem(ndo); 8770f74e101Schristos } 8780f74e101Schristos } 8790f74e101Schristos 8800f74e101Schristos static const struct protoidlist { 8810f74e101Schristos const u_char protoid[5]; 8820f74e101Schristos const char *name; 8830f74e101Schristos } protoidlist[] = { 8840f74e101Schristos {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" }, 8850f74e101Schristos {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" }, 8860f74e101Schristos {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" }, 8870f74e101Schristos {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" }, 8880f74e101Schristos {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" }, 8890f74e101Schristos {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 8900f74e101Schristos }; 8910f74e101Schristos 8920f74e101Schristos /* 8930f74e101Schristos * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 8940f74e101Schristos * types. 8950f74e101Schristos */ 8960f74e101Schristos static void 897fdccd7e4Schristos init_protoidarray(netdissect_options *ndo) 8980f74e101Schristos { 899c74ad251Schristos int i; 900c74ad251Schristos struct protoidmem *tp; 9010f74e101Schristos const struct protoidlist *pl; 9020f74e101Schristos u_char protoid[5]; 9030f74e101Schristos 9040f74e101Schristos protoid[0] = 0; 9050f74e101Schristos protoid[1] = 0; 9060f74e101Schristos protoid[2] = 0; 9070f74e101Schristos for (i = 0; eproto_db[i].s; i++) { 9080f74e101Schristos u_short etype = htons(eproto_db[i].p); 9090f74e101Schristos 9100f74e101Schristos memcpy((char *)&protoid[3], (char *)&etype, 2); 911fdccd7e4Schristos tp = lookup_protoid(ndo, protoid); 9120f74e101Schristos tp->p_name = strdup(eproto_db[i].s); 913fdccd7e4Schristos if (tp->p_name == NULL) 914c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 915c74ad251Schristos "%s: strdup(eproto_db[i].s)", __func__); 9160f74e101Schristos } 9170f74e101Schristos /* Hardwire some SNAP proto ID names */ 9180f74e101Schristos for (pl = protoidlist; pl->name != NULL; ++pl) { 919fdccd7e4Schristos tp = lookup_protoid(ndo, pl->protoid); 9200f74e101Schristos /* Don't override existing name */ 9210f74e101Schristos if (tp->p_name != NULL) 9220f74e101Schristos continue; 9230f74e101Schristos 9240f74e101Schristos tp->p_name = pl->name; 9250f74e101Schristos } 9260f74e101Schristos } 9270f74e101Schristos 9280f74e101Schristos static const struct etherlist { 929c74ad251Schristos const nd_mac_addr addr; 9300f74e101Schristos const char *name; 9310f74e101Schristos } etherlist[] = { 9320f74e101Schristos {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 9330f74e101Schristos {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 9340f74e101Schristos }; 9350f74e101Schristos 9360f74e101Schristos /* 9370f74e101Schristos * Initialize the ethers hash table. We take two different approaches 9380f74e101Schristos * depending on whether or not the system provides the ethers name 9390f74e101Schristos * service. If it does, we just wire in a few names at startup, 9400f74e101Schristos * and etheraddr_string() fills in the table on demand. If it doesn't, 9410f74e101Schristos * then we suck in the entire /etc/ethers file at startup. The idea 9420f74e101Schristos * is that parsing the local file will be fast, but spinning through 9430f74e101Schristos * all the ethers entries via NIS & next_etherent might be very slow. 9440f74e101Schristos * 9450f74e101Schristos * XXX pcap_next_etherent doesn't belong in the pcap interface, but 9460f74e101Schristos * since the pcap module already does name-to-address translation, 9470f74e101Schristos * it's already does most of the work for the ethernet address-to-name 9480f74e101Schristos * translation, so we just pcap_next_etherent as a convenience. 9490f74e101Schristos */ 9500f74e101Schristos static void 951fdccd7e4Schristos init_etherarray(netdissect_options *ndo) 9520f74e101Schristos { 953c74ad251Schristos const struct etherlist *el; 954c74ad251Schristos struct enamemem *tp; 9550f74e101Schristos #ifdef USE_ETHER_NTOHOST 9560f74e101Schristos char name[256]; 9570f74e101Schristos #else 958c74ad251Schristos struct pcap_etherent *ep; 959c74ad251Schristos FILE *fp; 9600f74e101Schristos 9610f74e101Schristos /* Suck in entire ethers file */ 9620f74e101Schristos fp = fopen(PCAP_ETHERS_FILE, "r"); 9630f74e101Schristos if (fp != NULL) { 9640f74e101Schristos while ((ep = pcap_next_etherent(fp)) != NULL) { 965fdccd7e4Schristos tp = lookup_emem(ndo, ep->addr); 9660f74e101Schristos tp->e_name = strdup(ep->name); 967fdccd7e4Schristos if (tp->e_name == NULL) 968c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 969c74ad251Schristos "%s: strdup(ep->addr)", __func__); 9700f74e101Schristos } 9710f74e101Schristos (void)fclose(fp); 9720f74e101Schristos } 9730f74e101Schristos #endif 9740f74e101Schristos 9750f74e101Schristos /* Hardwire some ethernet names */ 9760f74e101Schristos for (el = etherlist; el->name != NULL; ++el) { 977fdccd7e4Schristos tp = lookup_emem(ndo, el->addr); 9780f74e101Schristos /* Don't override existing name */ 9790f74e101Schristos if (tp->e_name != NULL) 9800f74e101Schristos continue; 9810f74e101Schristos 9820f74e101Schristos #ifdef USE_ETHER_NTOHOST 9830f74e101Schristos /* 9840f74e101Schristos * Use YP/NIS version of name if available. 9850f74e101Schristos */ 986c74ad251Schristos /* Same workaround as in etheraddr_string(). */ 987c74ad251Schristos struct ether_addr ea; 988c74ad251Schristos memcpy (&ea, el->addr, MAC_ADDR_LEN); 989c74ad251Schristos if (ether_ntohost(name, &ea) == 0) { 9900f74e101Schristos tp->e_name = strdup(name); 991fdccd7e4Schristos if (tp->e_name == NULL) 992c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 993c74ad251Schristos "%s: strdup(name)", __func__); 9940f74e101Schristos continue; 9950f74e101Schristos } 9960f74e101Schristos #endif 9970f74e101Schristos tp->e_name = el->name; 9980f74e101Schristos } 9990f74e101Schristos } 10000f74e101Schristos 1001c74ad251Schristos static const struct ipxsap_ent { 1002c74ad251Schristos uint16_t v; 1003c74ad251Schristos const char *s; 1004c74ad251Schristos } ipxsap_db[] = { 10050f74e101Schristos { 0x0000, "Unknown" }, 10060f74e101Schristos { 0x0001, "User" }, 10070f74e101Schristos { 0x0002, "User Group" }, 10080f74e101Schristos { 0x0003, "PrintQueue" }, 10090f74e101Schristos { 0x0004, "FileServer" }, 10100f74e101Schristos { 0x0005, "JobServer" }, 10110f74e101Schristos { 0x0006, "Gateway" }, 10120f74e101Schristos { 0x0007, "PrintServer" }, 10130f74e101Schristos { 0x0008, "ArchiveQueue" }, 10140f74e101Schristos { 0x0009, "ArchiveServer" }, 10150f74e101Schristos { 0x000a, "JobQueue" }, 10160f74e101Schristos { 0x000b, "Administration" }, 10170f74e101Schristos { 0x000F, "Novell TI-RPC" }, 10180f74e101Schristos { 0x0017, "Diagnostics" }, 10190f74e101Schristos { 0x0020, "NetBIOS" }, 10200f74e101Schristos { 0x0021, "NAS SNA Gateway" }, 10210f74e101Schristos { 0x0023, "NACS AsyncGateway" }, 10220f74e101Schristos { 0x0024, "RemoteBridge/RoutingService" }, 10230f74e101Schristos { 0x0026, "BridgeServer" }, 10240f74e101Schristos { 0x0027, "TCP/IP Gateway" }, 10250f74e101Schristos { 0x0028, "Point-to-point X.25 BridgeServer" }, 10260f74e101Schristos { 0x0029, "3270 Gateway" }, 10270f74e101Schristos { 0x002a, "CHI Corp" }, 10280f74e101Schristos { 0x002c, "PC Chalkboard" }, 10290f74e101Schristos { 0x002d, "TimeSynchServer" }, 10300f74e101Schristos { 0x002e, "ARCserve5.0/PalindromeBackup" }, 10310f74e101Schristos { 0x0045, "DI3270 Gateway" }, 10320f74e101Schristos { 0x0047, "AdvertisingPrintServer" }, 10330f74e101Schristos { 0x004a, "NetBlazerModems" }, 10340f74e101Schristos { 0x004b, "BtrieveVAP" }, 10350f74e101Schristos { 0x004c, "NetwareSQL" }, 10360f74e101Schristos { 0x004d, "XtreeNetwork" }, 10370f74e101Schristos { 0x0050, "BtrieveVAP4.11" }, 10380f74e101Schristos { 0x0052, "QuickLink" }, 10390f74e101Schristos { 0x0053, "PrintQueueUser" }, 10400f74e101Schristos { 0x0058, "Multipoint X.25 Router" }, 10410f74e101Schristos { 0x0060, "STLB/NLM" }, 10420f74e101Schristos { 0x0064, "ARCserve" }, 10430f74e101Schristos { 0x0066, "ARCserve3.0" }, 10440f74e101Schristos { 0x0072, "WAN CopyUtility" }, 10450f74e101Schristos { 0x007a, "TES-NetwareVMS" }, 10460f74e101Schristos { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" }, 10470f74e101Schristos { 0x0095, "DDA OBGYN" }, 10480f74e101Schristos { 0x0098, "NetwareAccessServer" }, 10490f74e101Schristos { 0x009a, "Netware for VMS II/NamedPipeServer" }, 10500f74e101Schristos { 0x009b, "NetwareAccessServer" }, 10510f74e101Schristos { 0x009e, "PortableNetwareServer/SunLinkNVT" }, 10520f74e101Schristos { 0x00a1, "PowerchuteAPC UPS" }, 10530f74e101Schristos { 0x00aa, "LAWserve" }, 10540f74e101Schristos { 0x00ac, "CompaqIDA StatusMonitor" }, 10550f74e101Schristos { 0x0100, "PIPE STAIL" }, 10560f74e101Schristos { 0x0102, "LAN ProtectBindery" }, 10570f74e101Schristos { 0x0103, "OracleDataBaseServer" }, 10580f74e101Schristos { 0x0107, "Netware386/RSPX RemoteConsole" }, 10590f74e101Schristos { 0x010f, "NovellSNA Gateway" }, 10600f74e101Schristos { 0x0111, "TestServer" }, 10610f74e101Schristos { 0x0112, "HP PrintServer" }, 10620f74e101Schristos { 0x0114, "CSA MUX" }, 10630f74e101Schristos { 0x0115, "CSA LCA" }, 10640f74e101Schristos { 0x0116, "CSA CM" }, 10650f74e101Schristos { 0x0117, "CSA SMA" }, 10660f74e101Schristos { 0x0118, "CSA DBA" }, 10670f74e101Schristos { 0x0119, "CSA NMA" }, 10680f74e101Schristos { 0x011a, "CSA SSA" }, 10690f74e101Schristos { 0x011b, "CSA STATUS" }, 10700f74e101Schristos { 0x011e, "CSA APPC" }, 10710f74e101Schristos { 0x0126, "SNA TEST SSA Profile" }, 10720f74e101Schristos { 0x012a, "CSA TRACE" }, 10730f74e101Schristos { 0x012b, "NetwareSAA" }, 10740f74e101Schristos { 0x012e, "IKARUS VirusScan" }, 10750f74e101Schristos { 0x0130, "CommunicationsExecutive" }, 10760f74e101Schristos { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" }, 10770f74e101Schristos { 0x0135, "NetwareNamingServicesProfile" }, 10780f74e101Schristos { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" }, 10790f74e101Schristos { 0x0141, "LAN SpoolServer" }, 10800f74e101Schristos { 0x0152, "IRMALAN Gateway" }, 10810f74e101Schristos { 0x0154, "NamedPipeServer" }, 10820f74e101Schristos { 0x0166, "NetWareManagement" }, 10830f74e101Schristos { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" }, 10840f74e101Schristos { 0x0173, "Compaq" }, 10850f74e101Schristos { 0x0174, "Compaq SNMP Agent" }, 10860f74e101Schristos { 0x0175, "Compaq" }, 10870f74e101Schristos { 0x0180, "XTreeServer/XTreeTools" }, 10880f74e101Schristos { 0x018A, "NASI ServicesBroadcastServer" }, 10890f74e101Schristos { 0x01b0, "GARP Gateway" }, 10900f74e101Schristos { 0x01b1, "Binfview" }, 10910f74e101Schristos { 0x01bf, "IntelLanDeskManager" }, 10920f74e101Schristos { 0x01ca, "AXTEC" }, 10930f74e101Schristos { 0x01cb, "ShivaNetModem/E" }, 10940f74e101Schristos { 0x01cc, "ShivaLanRover/E" }, 10950f74e101Schristos { 0x01cd, "ShivaLanRover/T" }, 10960f74e101Schristos { 0x01ce, "ShivaUniversal" }, 10970f74e101Schristos { 0x01d8, "CastelleFAXPressServer" }, 10980f74e101Schristos { 0x01da, "CastelleLANPressPrintServer" }, 10990f74e101Schristos { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" }, 11000f74e101Schristos { 0x01f0, "LEGATO" }, 11010f74e101Schristos { 0x01f5, "LEGATO" }, 11020f74e101Schristos { 0x0233, "NMS Agent/NetwareManagementAgent" }, 11030f74e101Schristos { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" }, 11040f74e101Schristos { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" }, 11050f74e101Schristos { 0x023a, "LANtern" }, 11060f74e101Schristos { 0x023c, "MAVERICK" }, 11070f74e101Schristos { 0x023f, "NovellSMDR" }, 11080f74e101Schristos { 0x024e, "NetwareConnect" }, 11090f74e101Schristos { 0x024f, "NASI ServerBroadcast Cisco" }, 11100f74e101Schristos { 0x026a, "NMS ServiceConsole" }, 11110f74e101Schristos { 0x026b, "TimeSynchronizationServer Netware 4.x" }, 11120f74e101Schristos { 0x0278, "DirectoryServer Netware 4.x" }, 11130f74e101Schristos { 0x027b, "NetwareManagementAgent" }, 11140f74e101Schristos { 0x0280, "Novell File and Printer Sharing Service for PC" }, 11150f74e101Schristos { 0x0304, "NovellSAA Gateway" }, 11160f74e101Schristos { 0x0308, "COM/VERMED" }, 11170f74e101Schristos { 0x030a, "GalacticommWorldgroupServer" }, 11180f74e101Schristos { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" }, 11190f74e101Schristos { 0x0320, "AttachmateGateway" }, 1120*26ba0b50Schristos { 0x0327, "MicrosoftDiagnostics" }, 11210f74e101Schristos { 0x0328, "WATCOM SQL Server" }, 11220f74e101Schristos { 0x0335, "MultiTechSystems MultisynchCommServer" }, 11230f74e101Schristos { 0x0343, "Xylogics RemoteAccessServer/LANModem" }, 11240f74e101Schristos { 0x0355, "ArcadaBackupExec" }, 11250f74e101Schristos { 0x0358, "MSLCD1" }, 11260f74e101Schristos { 0x0361, "NETINELO" }, 11270f74e101Schristos { 0x037e, "Powerchute UPS Monitoring" }, 11280f74e101Schristos { 0x037f, "ViruSafeNotify" }, 11290f74e101Schristos { 0x0386, "HP Bridge" }, 11300f74e101Schristos { 0x0387, "HP Hub" }, 11310f74e101Schristos { 0x0394, "NetWare SAA Gateway" }, 11320f74e101Schristos { 0x039b, "LotusNotes" }, 11330f74e101Schristos { 0x03b7, "CertusAntiVirus" }, 11340f74e101Schristos { 0x03c4, "ARCserve4.0" }, 11350f74e101Schristos { 0x03c7, "LANspool3.5" }, 11360f74e101Schristos { 0x03d7, "LexmarkPrinterServer" }, 11370f74e101Schristos { 0x03d8, "LexmarkXLE PrinterServer" }, 11380f74e101Schristos { 0x03dd, "BanyanENS NetwareClient" }, 11390f74e101Schristos { 0x03de, "GuptaSequelBaseServer/NetWareSQL" }, 11400f74e101Schristos { 0x03e1, "UnivelUnixware" }, 11410f74e101Schristos { 0x03e4, "UnivelUnixware" }, 11420f74e101Schristos { 0x03fc, "IntelNetport" }, 11430f74e101Schristos { 0x03fd, "PrintServerQueue" }, 11440f74e101Schristos { 0x040A, "ipnServer" }, 11450f74e101Schristos { 0x040D, "LVERRMAN" }, 11460f74e101Schristos { 0x040E, "LVLIC" }, 11470f74e101Schristos { 0x0414, "NET Silicon (DPI)/Kyocera" }, 11480f74e101Schristos { 0x0429, "SiteLockVirus" }, 11490f74e101Schristos { 0x0432, "UFHELPR???" }, 11500f74e101Schristos { 0x0433, "Synoptics281xAdvancedSNMPAgent" }, 11510f74e101Schristos { 0x0444, "MicrosoftNT SNA Server" }, 11520f74e101Schristos { 0x0448, "Oracle" }, 11530f74e101Schristos { 0x044c, "ARCserve5.01" }, 11540f74e101Schristos { 0x0457, "CanonGP55" }, 11550f74e101Schristos { 0x045a, "QMS Printers" }, 11560f74e101Schristos { 0x045b, "DellSCSI Array" }, 11570f74e101Schristos { 0x0491, "NetBlazerModems" }, 11580f74e101Schristos { 0x04ac, "OnTimeScheduler" }, 11590f74e101Schristos { 0x04b0, "CD-Net" }, 11600f74e101Schristos { 0x0513, "EmulexNQA" }, 11610f74e101Schristos { 0x0520, "SiteLockChecks" }, 11620f74e101Schristos { 0x0529, "SiteLockChecks" }, 11630f74e101Schristos { 0x052d, "CitrixOS2 AppServer" }, 11640f74e101Schristos { 0x0535, "Tektronix" }, 11650f74e101Schristos { 0x0536, "Milan" }, 11660f74e101Schristos { 0x055d, "Attachmate SNA gateway" }, 11670f74e101Schristos { 0x056b, "IBM8235 ModemServer" }, 11680f74e101Schristos { 0x056c, "ShivaLanRover/E PLUS" }, 11690f74e101Schristos { 0x056d, "ShivaLanRover/T PLUS" }, 11700f74e101Schristos { 0x0580, "McAfeeNetShield" }, 11710f74e101Schristos { 0x05B8, "NLM to workstation communication (Revelation Software)" }, 11720f74e101Schristos { 0x05BA, "CompatibleSystemsRouters" }, 11730f74e101Schristos { 0x05BE, "CheyenneHierarchicalStorageManager" }, 11740f74e101Schristos { 0x0606, "JCWatermarkImaging" }, 11750f74e101Schristos { 0x060c, "AXISNetworkPrinter" }, 11760f74e101Schristos { 0x0610, "AdaptecSCSIManagement" }, 11770f74e101Schristos { 0x0621, "IBM AntiVirus" }, 11780f74e101Schristos { 0x0640, "Windows95 RemoteRegistryService" }, 11790f74e101Schristos { 0x064e, "MicrosoftIIS" }, 11800f74e101Schristos { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" }, 11810f74e101Schristos { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" }, 11820f74e101Schristos { 0x076C, "Xerox" }, 11830f74e101Schristos { 0x079b, "ShivaLanRover/E 115" }, 11840f74e101Schristos { 0x079c, "ShivaLanRover/T 115" }, 11850f74e101Schristos { 0x07B4, "CubixWorldDesk" }, 11860f74e101Schristos { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" }, 11870f74e101Schristos { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" }, 11880f74e101Schristos { 0x0810, "ELAN License Server Demo" }, 11890f74e101Schristos { 0x0824, "ShivaLanRoverAccessSwitch/E" }, 11900f74e101Schristos { 0x086a, "ISSC Collector" }, 11910f74e101Schristos { 0x087f, "ISSC DAS AgentAIX" }, 11920f74e101Schristos { 0x0880, "Intel Netport PRO" }, 11930f74e101Schristos { 0x0881, "Intel Netport PRO" }, 11940f74e101Schristos { 0x0b29, "SiteLock" }, 11950f74e101Schristos { 0x0c29, "SiteLockApplications" }, 11960f74e101Schristos { 0x0c2c, "LicensingServer" }, 11970f74e101Schristos { 0x2101, "PerformanceTechnologyInstantInternet" }, 11980f74e101Schristos { 0x2380, "LAI SiteLock" }, 11990f74e101Schristos { 0x238c, "MeetingMaker" }, 12000f74e101Schristos { 0x4808, "SiteLockServer/SiteLockMetering" }, 12010f74e101Schristos { 0x5555, "SiteLockUser" }, 12020f74e101Schristos { 0x6312, "Tapeware" }, 12030f74e101Schristos { 0x6f00, "RabbitGateway" }, 12040f74e101Schristos { 0x7703, "MODEM" }, 12050f74e101Schristos { 0x8002, "NetPortPrinters" }, 12060f74e101Schristos { 0x8008, "WordPerfectNetworkVersion" }, 12070f74e101Schristos { 0x85BE, "Cisco EIGRP" }, 12080f74e101Schristos { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" }, 12090f74e101Schristos { 0x9000, "McAfeeNetShield" }, 12100f74e101Schristos { 0x9604, "CSA-NT_MON" }, 12110f74e101Schristos { 0xb6a8, "OceanIsleReachoutRemoteControl" }, 12120f74e101Schristos { 0xf11f, "SiteLockMetering" }, 12130f74e101Schristos { 0xf1ff, "SiteLock" }, 12140f74e101Schristos { 0xf503, "Microsoft SQL Server" }, 12150f74e101Schristos { 0xF905, "IBM TimeAndPlace" }, 12160f74e101Schristos { 0xfbfb, "TopCallIII FaxServer" }, 12170f74e101Schristos { 0xffff, "AnyService/Wildcard" }, 12180f74e101Schristos { 0, (char *)0 } 12190f74e101Schristos }; 12200f74e101Schristos 12210f74e101Schristos static void 1222fdccd7e4Schristos init_ipxsaparray(netdissect_options *ndo) 12230f74e101Schristos { 1224c74ad251Schristos int i; 1225c74ad251Schristos struct hnamemem *table; 12260f74e101Schristos 12270f74e101Schristos for (i = 0; ipxsap_db[i].s != NULL; i++) { 1228c74ad251Schristos u_int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1); 12290f74e101Schristos table = &ipxsaptable[j]; 12300f74e101Schristos while (table->name) 12310f74e101Schristos table = table->nxt; 12320f74e101Schristos table->name = ipxsap_db[i].s; 12330f74e101Schristos table->addr = htons(ipxsap_db[i].v); 1234fdccd7e4Schristos table->nxt = newhnamemem(ndo); 12350f74e101Schristos } 12360f74e101Schristos } 12370f74e101Schristos 12380f74e101Schristos /* 12390f74e101Schristos * Initialize the address to name translation machinery. We map all 1240b3a00663Schristos * non-local IP addresses to numeric addresses if ndo->ndo_fflag is true 1241b3a00663Schristos * (i.e., to prevent blocking on the nameserver). localnet is the IP address 12420f74e101Schristos * of the local network. mask is its subnet mask. 12430f74e101Schristos */ 12440f74e101Schristos void 1245b3a00663Schristos init_addrtoname(netdissect_options *ndo, uint32_t localnet, uint32_t mask) 12460f74e101Schristos { 1247b3a00663Schristos if (ndo->ndo_fflag) { 12480f74e101Schristos f_localnet = localnet; 12490f74e101Schristos f_netmask = mask; 12500f74e101Schristos } 1251b3a00663Schristos if (ndo->ndo_nflag) 12520f74e101Schristos /* 12530f74e101Schristos * Simplest way to suppress names. 12540f74e101Schristos */ 12550f74e101Schristos return; 12560f74e101Schristos 1257fdccd7e4Schristos init_etherarray(ndo); 1258b3a00663Schristos init_servarray(ndo); 1259fdccd7e4Schristos init_eprotoarray(ndo); 1260fdccd7e4Schristos init_protoidarray(ndo); 1261fdccd7e4Schristos init_ipxsaparray(ndo); 12620f74e101Schristos } 12630f74e101Schristos 12640f74e101Schristos const char * 1265b3a00663Schristos dnaddr_string(netdissect_options *ndo, u_short dnaddr) 12660f74e101Schristos { 1267c74ad251Schristos struct hnamemem *tp; 12680f74e101Schristos 1269dc860a36Sspz for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != NULL; 12700f74e101Schristos tp = tp->nxt) 12710f74e101Schristos if (tp->addr == dnaddr) 12720f74e101Schristos return (tp->name); 12730f74e101Schristos 12740f74e101Schristos tp->addr = dnaddr; 1275fdccd7e4Schristos tp->nxt = newhnamemem(ndo); 1276fdccd7e4Schristos tp->name = dnnum_string(ndo, dnaddr); 12770f74e101Schristos 12780f74e101Schristos return(tp->name); 12790f74e101Schristos } 12800f74e101Schristos 12810f74e101Schristos /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 12820f74e101Schristos struct hnamemem * 1283fdccd7e4Schristos newhnamemem(netdissect_options *ndo) 12840f74e101Schristos { 1285c74ad251Schristos struct hnamemem *p; 12860f74e101Schristos static struct hnamemem *ptr = NULL; 12870f74e101Schristos static u_int num = 0; 12880f74e101Schristos 1289c74ad251Schristos if (num == 0) { 12900f74e101Schristos num = 64; 12910f74e101Schristos ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 12920f74e101Schristos if (ptr == NULL) 1293c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 1294c74ad251Schristos "%s: calloc", __func__); 12950f74e101Schristos } 12960f74e101Schristos --num; 12970f74e101Schristos p = ptr++; 12980f74e101Schristos return (p); 12990f74e101Schristos } 13000f74e101Schristos 13010f74e101Schristos /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ 13020f74e101Schristos struct h6namemem * 1303fdccd7e4Schristos newh6namemem(netdissect_options *ndo) 13040f74e101Schristos { 1305c74ad251Schristos struct h6namemem *p; 13060f74e101Schristos static struct h6namemem *ptr = NULL; 13070f74e101Schristos static u_int num = 0; 13080f74e101Schristos 1309c74ad251Schristos if (num == 0) { 13100f74e101Schristos num = 64; 13110f74e101Schristos ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); 13120f74e101Schristos if (ptr == NULL) 1313c74ad251Schristos (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, 1314c74ad251Schristos "%s: calloc", __func__); 13150f74e101Schristos } 13160f74e101Schristos --num; 13170f74e101Schristos p = ptr++; 13180f74e101Schristos return (p); 13190f74e101Schristos } 1320ba2ff121Schristos 1321ba2ff121Schristos /* Represent TCI part of the 802.1Q 4-octet tag as text. */ 1322ba2ff121Schristos const char * 1323ba2ff121Schristos ieee8021q_tci_string(const uint16_t tci) 1324ba2ff121Schristos { 1325ba2ff121Schristos static char buf[128]; 1326ba2ff121Schristos snprintf(buf, sizeof(buf), "vlan %u, p %u%s", 1327ba2ff121Schristos tci & 0xfff, 1328ba2ff121Schristos tci >> 13, 1329ba2ff121Schristos (tci & 0x1000) ? ", DEI" : ""); 1330ba2ff121Schristos return buf; 1331ba2ff121Schristos } 1332