14edb46e9SPaul Traina /* 2699fc314SBill Fenner * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 204edb46e9SPaul Traina * 214edb46e9SPaul Traina * Internet, ethernet, port, and protocol string to address 224edb46e9SPaul Traina * and address to string conversion routines 23a88113a8SBill Fenner * 24a88113a8SBill Fenner * $FreeBSD$ 254edb46e9SPaul Traina */ 264edb46e9SPaul Traina #ifndef lint 272ebf6c05SBill Fenner static const char rcsid[] = 28a88113a8SBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.64 1999/11/21 09:36:44 fenner Exp $ (LBL)"; 29a88113a8SBill Fenner #endif 30a88113a8SBill Fenner 31a88113a8SBill Fenner #ifdef HAVE_CONFIG_H 32a88113a8SBill Fenner #include "config.h" 334edb46e9SPaul Traina #endif 344edb46e9SPaul Traina 354edb46e9SPaul Traina #include <sys/types.h> 364edb46e9SPaul Traina #include <sys/socket.h> 374edb46e9SPaul Traina #include <sys/time.h> 384edb46e9SPaul Traina 394edb46e9SPaul Traina #if __STDC__ 404edb46e9SPaul Traina struct mbuf; 414edb46e9SPaul Traina struct rtentry; 424edb46e9SPaul Traina #endif 434edb46e9SPaul Traina #include <net/if.h> 444edb46e9SPaul Traina 454edb46e9SPaul Traina #include <netinet/in.h> 46ee3e7633SGarrett Wollman #include <net/ethernet.h> 474edb46e9SPaul Traina 48a88113a8SBill Fenner #ifdef INET6 49bb1ba417SBill Fenner #include <netinet/ip6.h> 50a88113a8SBill Fenner #endif 51a88113a8SBill Fenner 524edb46e9SPaul Traina #include <arpa/inet.h> 534edb46e9SPaul Traina 544edb46e9SPaul Traina #include <ctype.h> 554edb46e9SPaul Traina #include <netdb.h> 564edb46e9SPaul Traina #include <pcap.h> 574edb46e9SPaul Traina #include <pcap-namedb.h> 58699fc314SBill Fenner #ifdef HAVE_MALLOC_H 59699fc314SBill Fenner #include <malloc.h> 60699fc314SBill Fenner #endif 61699fc314SBill Fenner #ifdef HAVE_MEMORY_H 62699fc314SBill Fenner #include <memory.h> 63699fc314SBill Fenner #endif 644edb46e9SPaul Traina #include <signal.h> 654edb46e9SPaul Traina #include <stdio.h> 664edb46e9SPaul Traina #include <string.h> 674edb46e9SPaul Traina #include <stdlib.h> 684edb46e9SPaul Traina #include <unistd.h> 694edb46e9SPaul Traina 704edb46e9SPaul Traina #include "interface.h" 714edb46e9SPaul Traina #include "addrtoname.h" 724edb46e9SPaul Traina #include "llc.h" 73699fc314SBill Fenner #include "savestr.h" 74699fc314SBill Fenner #include "setsignal.h" 754edb46e9SPaul Traina 764edb46e9SPaul Traina /* Forwards */ 774edb46e9SPaul Traina static RETSIGTYPE nohostname(int); 784edb46e9SPaul Traina 794edb46e9SPaul Traina /* 804edb46e9SPaul Traina * hash tables for whatever-to-name translations 814edb46e9SPaul Traina */ 824edb46e9SPaul Traina 834edb46e9SPaul Traina #define HASHNAMESIZE 4096 844edb46e9SPaul Traina 854edb46e9SPaul Traina struct hnamemem { 864edb46e9SPaul Traina u_int32_t addr; 874edb46e9SPaul Traina char *name; 884edb46e9SPaul Traina struct hnamemem *nxt; 894edb46e9SPaul Traina }; 904edb46e9SPaul Traina 914edb46e9SPaul Traina struct hnamemem hnametable[HASHNAMESIZE]; 924edb46e9SPaul Traina struct hnamemem tporttable[HASHNAMESIZE]; 934edb46e9SPaul Traina struct hnamemem uporttable[HASHNAMESIZE]; 944edb46e9SPaul Traina struct hnamemem eprototable[HASHNAMESIZE]; 954edb46e9SPaul Traina struct hnamemem dnaddrtable[HASHNAMESIZE]; 964edb46e9SPaul Traina struct hnamemem llcsaptable[HASHNAMESIZE]; 974edb46e9SPaul Traina 98a88113a8SBill Fenner #ifdef INET6 99a88113a8SBill Fenner struct h6namemem { 100a88113a8SBill Fenner struct in6_addr addr; 101a88113a8SBill Fenner char *name; 102a88113a8SBill Fenner struct h6namemem *nxt; 103a88113a8SBill Fenner }; 104a88113a8SBill Fenner 105a88113a8SBill Fenner struct h6namemem h6nametable[HASHNAMESIZE]; 106a88113a8SBill Fenner #endif /* INET6 */ 107a88113a8SBill Fenner 1084edb46e9SPaul Traina struct enamemem { 1094edb46e9SPaul Traina u_short e_addr0; 1104edb46e9SPaul Traina u_short e_addr1; 1114edb46e9SPaul Traina u_short e_addr2; 1124edb46e9SPaul Traina char *e_name; 1134edb46e9SPaul Traina u_char *e_nsap; /* used only for nsaptable[] */ 1144edb46e9SPaul Traina struct enamemem *e_nxt; 1154edb46e9SPaul Traina }; 1164edb46e9SPaul Traina 1174edb46e9SPaul Traina struct enamemem enametable[HASHNAMESIZE]; 1184edb46e9SPaul Traina struct enamemem nsaptable[HASHNAMESIZE]; 1194edb46e9SPaul Traina 1204edb46e9SPaul Traina struct protoidmem { 1214edb46e9SPaul Traina u_int32_t p_oui; 1224edb46e9SPaul Traina u_short p_proto; 1234edb46e9SPaul Traina char *p_name; 1244edb46e9SPaul Traina struct protoidmem *p_nxt; 1254edb46e9SPaul Traina }; 1264edb46e9SPaul Traina 1274edb46e9SPaul Traina struct protoidmem protoidtable[HASHNAMESIZE]; 1284edb46e9SPaul Traina 1294edb46e9SPaul Traina /* 1304edb46e9SPaul Traina * A faster replacement for inet_ntoa(). 1314edb46e9SPaul Traina */ 1324edb46e9SPaul Traina char * 1334edb46e9SPaul Traina intoa(u_int32_t addr) 1344edb46e9SPaul Traina { 1354edb46e9SPaul Traina register char *cp; 1364edb46e9SPaul Traina register u_int byte; 1374edb46e9SPaul Traina register int n; 1384edb46e9SPaul Traina static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 1394edb46e9SPaul Traina 1404edb46e9SPaul Traina NTOHL(addr); 1414edb46e9SPaul Traina cp = &buf[sizeof buf]; 1424edb46e9SPaul Traina *--cp = '\0'; 1434edb46e9SPaul Traina 1444edb46e9SPaul Traina n = 4; 1454edb46e9SPaul Traina do { 1464edb46e9SPaul Traina byte = addr & 0xff; 1474edb46e9SPaul Traina *--cp = byte % 10 + '0'; 1484edb46e9SPaul Traina byte /= 10; 1494edb46e9SPaul Traina if (byte > 0) { 1504edb46e9SPaul Traina *--cp = byte % 10 + '0'; 1514edb46e9SPaul Traina byte /= 10; 1524edb46e9SPaul Traina if (byte > 0) 1534edb46e9SPaul Traina *--cp = byte + '0'; 1544edb46e9SPaul Traina } 1554edb46e9SPaul Traina *--cp = '.'; 1564edb46e9SPaul Traina addr >>= 8; 1574edb46e9SPaul Traina } while (--n > 0); 1584edb46e9SPaul Traina 1594edb46e9SPaul Traina return cp + 1; 1604edb46e9SPaul Traina } 1614edb46e9SPaul Traina 1624edb46e9SPaul Traina static u_int32_t f_netmask; 1634edb46e9SPaul Traina static u_int32_t f_localnet; 1644edb46e9SPaul Traina static u_int32_t netmask; 1654edb46e9SPaul Traina 1664edb46e9SPaul Traina /* 1674edb46e9SPaul Traina * "getname" is written in this atrocious way to make sure we don't 1684edb46e9SPaul Traina * wait forever while trying to get hostnames from yp. 1694edb46e9SPaul Traina */ 1704edb46e9SPaul Traina #include <setjmp.h> 1714edb46e9SPaul Traina 1724edb46e9SPaul Traina jmp_buf getname_env; 1734edb46e9SPaul Traina 1744edb46e9SPaul Traina static RETSIGTYPE 1754edb46e9SPaul Traina nohostname(int signo) 1764edb46e9SPaul Traina { 1774edb46e9SPaul Traina longjmp(getname_env, 1); 1784edb46e9SPaul Traina } 1794edb46e9SPaul Traina 1804edb46e9SPaul Traina /* 1814edb46e9SPaul Traina * Return a name for the IP address pointed to by ap. This address 1824edb46e9SPaul Traina * is assumed to be in network byte order. 1834edb46e9SPaul Traina */ 1844edb46e9SPaul Traina char * 1854edb46e9SPaul Traina getname(const u_char *ap) 1864edb46e9SPaul Traina { 1874edb46e9SPaul Traina register struct hostent *hp; 1884edb46e9SPaul Traina u_int32_t addr; 1894edb46e9SPaul Traina static struct hnamemem *p; /* static for longjmp() */ 1904edb46e9SPaul Traina 1914edb46e9SPaul Traina #ifndef LBL_ALIGN 1924edb46e9SPaul Traina addr = *(const u_int32_t *)ap; 1934edb46e9SPaul Traina #else 194a88113a8SBill Fenner memcpy(&addr, ap, sizeof(addr)); 1954edb46e9SPaul Traina #endif 1964edb46e9SPaul Traina p = &hnametable[addr & (HASHNAMESIZE-1)]; 1974edb46e9SPaul Traina for (; p->nxt; p = p->nxt) { 1984edb46e9SPaul Traina if (p->addr == addr) 1994edb46e9SPaul Traina return (p->name); 2004edb46e9SPaul Traina } 2014edb46e9SPaul Traina p->addr = addr; 2024edb46e9SPaul Traina p->nxt = newhnamemem(); 2034edb46e9SPaul Traina 2044edb46e9SPaul Traina /* 2054edb46e9SPaul Traina * Only print names when: 2064edb46e9SPaul Traina * (1) -n was not given. 207699fc314SBill Fenner * (2) Address is foreign and -f was given. (If -f was not 208699fc314SBill Fenner * give, f_netmask and f_local are 0 and the test 209699fc314SBill Fenner * evaluates to true) 210699fc314SBill Fenner * (3) -a was given or the host portion is not all ones 211699fc314SBill Fenner * nor all zeros (i.e. not a network or broadcast address) 2124edb46e9SPaul Traina */ 213699fc314SBill Fenner if (!nflag && 214699fc314SBill Fenner (addr & f_netmask) == f_localnet && 215699fc314SBill Fenner (aflag || 216699fc314SBill Fenner !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) { 2174edb46e9SPaul Traina if (!setjmp(getname_env)) { 218699fc314SBill Fenner (void)setsignal(SIGALRM, nohostname); 2194edb46e9SPaul Traina (void)alarm(20); 2204edb46e9SPaul Traina hp = gethostbyaddr((char *)&addr, 4, AF_INET); 2214edb46e9SPaul Traina (void)alarm(0); 2224edb46e9SPaul Traina if (hp) { 2234edb46e9SPaul Traina char *dotp; 2244edb46e9SPaul Traina 2254edb46e9SPaul Traina p->name = savestr(hp->h_name); 2264edb46e9SPaul Traina if (Nflag) { 2274edb46e9SPaul Traina /* Remove domain qualifications */ 2284edb46e9SPaul Traina dotp = strchr(p->name, '.'); 2294edb46e9SPaul Traina if (dotp) 2304edb46e9SPaul Traina *dotp = '\0'; 2314edb46e9SPaul Traina } 2324edb46e9SPaul Traina return (p->name); 2334edb46e9SPaul Traina } 2344edb46e9SPaul Traina } 2354edb46e9SPaul Traina } 2364edb46e9SPaul Traina p->name = savestr(intoa(addr)); 2374edb46e9SPaul Traina return (p->name); 2384edb46e9SPaul Traina } 2394edb46e9SPaul Traina 240a88113a8SBill Fenner #ifdef INET6 241a88113a8SBill Fenner /* 242a88113a8SBill Fenner * Return a name for the IP6 address pointed to by ap. This address 243a88113a8SBill Fenner * is assumed to be in network byte order. 244a88113a8SBill Fenner */ 245a88113a8SBill Fenner char * 246a88113a8SBill Fenner getname6(const u_char *ap) 247a88113a8SBill Fenner { 248a88113a8SBill Fenner register struct hostent *hp; 249a88113a8SBill Fenner struct in6_addr addr; 250a88113a8SBill Fenner static struct h6namemem *p; /* static for longjmp() */ 251a88113a8SBill Fenner register char *cp; 252a88113a8SBill Fenner char ntop_buf[INET6_ADDRSTRLEN]; 253a88113a8SBill Fenner 254a88113a8SBill Fenner memcpy(&addr, ap, sizeof(addr)); 255a88113a8SBill Fenner p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)]; 256a88113a8SBill Fenner for (; p->nxt; p = p->nxt) { 257a88113a8SBill Fenner if (memcmp(&p->addr, &addr, sizeof(addr)) == 0) 258a88113a8SBill Fenner return (p->name); 259a88113a8SBill Fenner } 260a88113a8SBill Fenner p->addr = addr; 261a88113a8SBill Fenner p->nxt = newh6namemem(); 262a88113a8SBill Fenner 263a88113a8SBill Fenner /* 264a88113a8SBill Fenner * Only print names when: 265a88113a8SBill Fenner * (1) -n was not given. 266a88113a8SBill Fenner * (2) Address is foreign and -f was given. (If -f was not 267a88113a8SBill Fenner * give, f_netmask and f_local are 0 and the test 268a88113a8SBill Fenner * evaluates to true) 269a88113a8SBill Fenner * (3) -a was given or the host portion is not all ones 270a88113a8SBill Fenner * nor all zeros (i.e. not a network or broadcast address) 271a88113a8SBill Fenner */ 272a88113a8SBill Fenner if (!nflag 273a88113a8SBill Fenner #if 0 274a88113a8SBill Fenner && 275a88113a8SBill Fenner (addr & f_netmask) == f_localnet && 276a88113a8SBill Fenner (aflag || 277a88113a8SBill Fenner !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff)) 278a88113a8SBill Fenner #endif 279a88113a8SBill Fenner ) { 280a88113a8SBill Fenner if (!setjmp(getname_env)) { 281a88113a8SBill Fenner (void)setsignal(SIGALRM, nohostname); 282a88113a8SBill Fenner (void)alarm(20); 283a88113a8SBill Fenner hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); 284a88113a8SBill Fenner (void)alarm(0); 285a88113a8SBill Fenner if (hp) { 286a88113a8SBill Fenner char *dotp; 287a88113a8SBill Fenner 288a88113a8SBill Fenner p->name = savestr(hp->h_name); 289a88113a8SBill Fenner if (Nflag) { 290a88113a8SBill Fenner /* Remove domain qualifications */ 291a88113a8SBill Fenner dotp = strchr(p->name, '.'); 292a88113a8SBill Fenner if (dotp) 293a88113a8SBill Fenner *dotp = '\0'; 294a88113a8SBill Fenner } 295a88113a8SBill Fenner return (p->name); 296a88113a8SBill Fenner } 297a88113a8SBill Fenner } 298a88113a8SBill Fenner } 299a88113a8SBill Fenner cp = (char *)inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)); 300a88113a8SBill Fenner p->name = savestr(cp); 301a88113a8SBill Fenner return (p->name); 302a88113a8SBill Fenner } 303a88113a8SBill Fenner #endif /* INET6 */ 304a88113a8SBill Fenner 3054edb46e9SPaul Traina static char hex[] = "0123456789abcdef"; 3064edb46e9SPaul Traina 3074edb46e9SPaul Traina 3084edb46e9SPaul Traina /* Find the hash node that corresponds the ether address 'ep' */ 3094edb46e9SPaul Traina 3104edb46e9SPaul Traina static inline struct enamemem * 3114edb46e9SPaul Traina lookup_emem(const u_char *ep) 3124edb46e9SPaul Traina { 3134edb46e9SPaul Traina register u_int i, j, k; 3144edb46e9SPaul Traina struct enamemem *tp; 3154edb46e9SPaul Traina 3164edb46e9SPaul Traina k = (ep[0] << 8) | ep[1]; 3174edb46e9SPaul Traina j = (ep[2] << 8) | ep[3]; 3184edb46e9SPaul Traina i = (ep[4] << 8) | ep[5]; 3194edb46e9SPaul Traina 3204edb46e9SPaul Traina tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; 3214edb46e9SPaul Traina while (tp->e_nxt) 3224edb46e9SPaul Traina if (tp->e_addr0 == i && 3234edb46e9SPaul Traina tp->e_addr1 == j && 3244edb46e9SPaul Traina tp->e_addr2 == k) 3254edb46e9SPaul Traina return tp; 3264edb46e9SPaul Traina else 3274edb46e9SPaul Traina tp = tp->e_nxt; 3284edb46e9SPaul Traina tp->e_addr0 = i; 3294edb46e9SPaul Traina tp->e_addr1 = j; 3304edb46e9SPaul Traina tp->e_addr2 = k; 3314edb46e9SPaul Traina tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 3324edb46e9SPaul Traina if (tp->e_nxt == NULL) 3334edb46e9SPaul Traina error("lookup_emem: calloc"); 3344edb46e9SPaul Traina 3354edb46e9SPaul Traina return tp; 3364edb46e9SPaul Traina } 3374edb46e9SPaul Traina 3384edb46e9SPaul Traina /* Find the hash node that corresponds the NSAP 'nsap' */ 3394edb46e9SPaul Traina 3404edb46e9SPaul Traina static inline struct enamemem * 3414edb46e9SPaul Traina lookup_nsap(register const u_char *nsap) 3424edb46e9SPaul Traina { 3434edb46e9SPaul Traina register u_int i, j, k; 3444edb46e9SPaul Traina int nlen = *nsap; 3454edb46e9SPaul Traina struct enamemem *tp; 3464edb46e9SPaul Traina const u_char *ensap = nsap + nlen - 6; 3474edb46e9SPaul Traina 3484edb46e9SPaul Traina if (nlen > 6) { 3494edb46e9SPaul Traina k = (ensap[0] << 8) | ensap[1]; 3504edb46e9SPaul Traina j = (ensap[2] << 8) | ensap[3]; 3514edb46e9SPaul Traina i = (ensap[4] << 8) | ensap[5]; 3524edb46e9SPaul Traina } 3534edb46e9SPaul Traina else 3544edb46e9SPaul Traina i = j = k = 0; 3554edb46e9SPaul Traina 3564edb46e9SPaul Traina tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; 3574edb46e9SPaul Traina while (tp->e_nxt) 3584edb46e9SPaul Traina if (tp->e_addr0 == i && 3594edb46e9SPaul Traina tp->e_addr1 == j && 3604edb46e9SPaul Traina tp->e_addr2 == k && 3614edb46e9SPaul Traina tp->e_nsap[0] == nlen && 3624edb46e9SPaul Traina memcmp((char *)&(nsap[1]), 3634edb46e9SPaul Traina (char *)&(tp->e_nsap[1]), nlen) == 0) 3644edb46e9SPaul Traina return tp; 3654edb46e9SPaul Traina else 3664edb46e9SPaul Traina tp = tp->e_nxt; 3674edb46e9SPaul Traina tp->e_addr0 = i; 3684edb46e9SPaul Traina tp->e_addr1 = j; 3694edb46e9SPaul Traina tp->e_addr2 = k; 3704edb46e9SPaul Traina tp->e_nsap = (u_char *)malloc(nlen + 1); 3714edb46e9SPaul Traina if (tp->e_nsap == NULL) 3724edb46e9SPaul Traina error("lookup_nsap: malloc"); 373699fc314SBill Fenner memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1); 3744edb46e9SPaul Traina tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 3754edb46e9SPaul Traina if (tp->e_nxt == NULL) 3764edb46e9SPaul Traina error("lookup_nsap: calloc"); 3774edb46e9SPaul Traina 3784edb46e9SPaul Traina return tp; 3794edb46e9SPaul Traina } 3804edb46e9SPaul Traina 3814edb46e9SPaul Traina /* Find the hash node that corresponds the protoid 'pi'. */ 3824edb46e9SPaul Traina 3834edb46e9SPaul Traina static inline struct protoidmem * 3844edb46e9SPaul Traina lookup_protoid(const u_char *pi) 3854edb46e9SPaul Traina { 3864edb46e9SPaul Traina register u_int i, j; 3874edb46e9SPaul Traina struct protoidmem *tp; 3884edb46e9SPaul Traina 3894edb46e9SPaul Traina /* 5 octets won't be aligned */ 3904edb46e9SPaul Traina i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 3914edb46e9SPaul Traina j = (pi[3] << 8) + pi[4]; 3924edb46e9SPaul Traina /* XXX should be endian-insensitive, but do big-endian testing XXX */ 3934edb46e9SPaul Traina 3944edb46e9SPaul Traina tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 3954edb46e9SPaul Traina while (tp->p_nxt) 3964edb46e9SPaul Traina if (tp->p_oui == i && tp->p_proto == j) 3974edb46e9SPaul Traina return tp; 3984edb46e9SPaul Traina else 3994edb46e9SPaul Traina tp = tp->p_nxt; 4004edb46e9SPaul Traina tp->p_oui = i; 4014edb46e9SPaul Traina tp->p_proto = j; 4024edb46e9SPaul Traina tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 4034edb46e9SPaul Traina if (tp->p_nxt == NULL) 4044edb46e9SPaul Traina error("lookup_protoid: calloc"); 4054edb46e9SPaul Traina 4064edb46e9SPaul Traina return tp; 4074edb46e9SPaul Traina } 4084edb46e9SPaul Traina 4094edb46e9SPaul Traina char * 4104edb46e9SPaul Traina etheraddr_string(register const u_char *ep) 4114edb46e9SPaul Traina { 4124edb46e9SPaul Traina register u_int i, j; 4134edb46e9SPaul Traina register char *cp; 4144edb46e9SPaul Traina register struct enamemem *tp; 4154edb46e9SPaul Traina char buf[sizeof("00:00:00:00:00:00")]; 4164edb46e9SPaul Traina 4174edb46e9SPaul Traina tp = lookup_emem(ep); 4184edb46e9SPaul Traina if (tp->e_name) 4194edb46e9SPaul Traina return (tp->e_name); 4204edb46e9SPaul Traina #ifdef HAVE_ETHER_NTOHOST 4214edb46e9SPaul Traina if (!nflag) { 4224edb46e9SPaul Traina char buf[128]; 4234edb46e9SPaul Traina if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { 4244edb46e9SPaul Traina tp->e_name = savestr(buf); 4254edb46e9SPaul Traina return (tp->e_name); 4264edb46e9SPaul Traina } 4274edb46e9SPaul Traina } 4284edb46e9SPaul Traina #endif 4294edb46e9SPaul Traina cp = buf; 4304edb46e9SPaul Traina if ((j = *ep >> 4) != 0) 4314edb46e9SPaul Traina *cp++ = hex[j]; 4324edb46e9SPaul Traina *cp++ = hex[*ep++ & 0xf]; 4334edb46e9SPaul Traina for (i = 5; (int)--i >= 0;) { 4344edb46e9SPaul Traina *cp++ = ':'; 4354edb46e9SPaul Traina if ((j = *ep >> 4) != 0) 4364edb46e9SPaul Traina *cp++ = hex[j]; 4374edb46e9SPaul Traina *cp++ = hex[*ep++ & 0xf]; 4384edb46e9SPaul Traina } 4394edb46e9SPaul Traina *cp = '\0'; 4404edb46e9SPaul Traina tp->e_name = savestr(buf); 4414edb46e9SPaul Traina return (tp->e_name); 4424edb46e9SPaul Traina } 4434edb46e9SPaul Traina 4444edb46e9SPaul Traina char * 4454edb46e9SPaul Traina etherproto_string(u_short port) 4464edb46e9SPaul Traina { 4474edb46e9SPaul Traina register char *cp; 4484edb46e9SPaul Traina register struct hnamemem *tp; 4494edb46e9SPaul Traina register u_int32_t i = port; 4504edb46e9SPaul Traina char buf[sizeof("0000")]; 4514edb46e9SPaul Traina 4524edb46e9SPaul Traina for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 4534edb46e9SPaul Traina if (tp->addr == i) 4544edb46e9SPaul Traina return (tp->name); 4554edb46e9SPaul Traina 4564edb46e9SPaul Traina tp->addr = i; 4574edb46e9SPaul Traina tp->nxt = newhnamemem(); 4584edb46e9SPaul Traina 4594edb46e9SPaul Traina cp = buf; 4604edb46e9SPaul Traina NTOHS(port); 4614edb46e9SPaul Traina *cp++ = hex[port >> 12 & 0xf]; 4624edb46e9SPaul Traina *cp++ = hex[port >> 8 & 0xf]; 4634edb46e9SPaul Traina *cp++ = hex[port >> 4 & 0xf]; 4644edb46e9SPaul Traina *cp++ = hex[port & 0xf]; 4654edb46e9SPaul Traina *cp++ = '\0'; 4664edb46e9SPaul Traina tp->name = savestr(buf); 4674edb46e9SPaul Traina return (tp->name); 4684edb46e9SPaul Traina } 4694edb46e9SPaul Traina 4704edb46e9SPaul Traina char * 4714edb46e9SPaul Traina protoid_string(register const u_char *pi) 4724edb46e9SPaul Traina { 4734edb46e9SPaul Traina register u_int i, j; 4744edb46e9SPaul Traina register char *cp; 4754edb46e9SPaul Traina register struct protoidmem *tp; 4764edb46e9SPaul Traina char buf[sizeof("00:00:00:00:00")]; 4774edb46e9SPaul Traina 4784edb46e9SPaul Traina tp = lookup_protoid(pi); 4794edb46e9SPaul Traina if (tp->p_name) 4804edb46e9SPaul Traina return tp->p_name; 4814edb46e9SPaul Traina 4824edb46e9SPaul Traina cp = buf; 4834edb46e9SPaul Traina if ((j = *pi >> 4) != 0) 4844edb46e9SPaul Traina *cp++ = hex[j]; 4854edb46e9SPaul Traina *cp++ = hex[*pi++ & 0xf]; 4864edb46e9SPaul Traina for (i = 4; (int)--i >= 0;) { 4874edb46e9SPaul Traina *cp++ = ':'; 4884edb46e9SPaul Traina if ((j = *pi >> 4) != 0) 4894edb46e9SPaul Traina *cp++ = hex[j]; 4904edb46e9SPaul Traina *cp++ = hex[*pi++ & 0xf]; 4914edb46e9SPaul Traina } 4924edb46e9SPaul Traina *cp = '\0'; 4934edb46e9SPaul Traina tp->p_name = savestr(buf); 4944edb46e9SPaul Traina return (tp->p_name); 4954edb46e9SPaul Traina } 4964edb46e9SPaul Traina 4974edb46e9SPaul Traina char * 4984edb46e9SPaul Traina llcsap_string(u_char sap) 4994edb46e9SPaul Traina { 5004edb46e9SPaul Traina register char *cp; 5014edb46e9SPaul Traina register struct hnamemem *tp; 5024edb46e9SPaul Traina register u_int32_t i = sap; 5034edb46e9SPaul Traina char buf[sizeof("sap 00")]; 5044edb46e9SPaul Traina 5054edb46e9SPaul Traina for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 5064edb46e9SPaul Traina if (tp->addr == i) 5074edb46e9SPaul Traina return (tp->name); 5084edb46e9SPaul Traina 5094edb46e9SPaul Traina tp->addr = i; 5104edb46e9SPaul Traina tp->nxt = newhnamemem(); 5114edb46e9SPaul Traina 5124edb46e9SPaul Traina cp = buf; 5134edb46e9SPaul Traina (void)strcpy(cp, "sap "); 5144edb46e9SPaul Traina cp += strlen(cp); 5154edb46e9SPaul Traina *cp++ = hex[sap >> 4 & 0xf]; 5164edb46e9SPaul Traina *cp++ = hex[sap & 0xf]; 5174edb46e9SPaul Traina *cp++ = '\0'; 5184edb46e9SPaul Traina tp->name = savestr(buf); 5194edb46e9SPaul Traina return (tp->name); 5204edb46e9SPaul Traina } 5214edb46e9SPaul Traina 5224edb46e9SPaul Traina char * 5234edb46e9SPaul Traina isonsap_string(const u_char *nsap) 5244edb46e9SPaul Traina { 5254edb46e9SPaul Traina register u_int i, nlen = nsap[0]; 5264edb46e9SPaul Traina register char *cp; 5274edb46e9SPaul Traina register struct enamemem *tp; 5284edb46e9SPaul Traina 5294edb46e9SPaul Traina tp = lookup_nsap(nsap); 5304edb46e9SPaul Traina if (tp->e_name) 5314edb46e9SPaul Traina return tp->e_name; 5324edb46e9SPaul Traina 53301bd0dbcSPaul Traina tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1)); 5344edb46e9SPaul Traina if (cp == NULL) 5354edb46e9SPaul Traina error("isonsap_string: malloc"); 5364edb46e9SPaul Traina 5374edb46e9SPaul Traina nsap++; 53801bd0dbcSPaul Traina for (i = 0; i < nlen; i++) { 5394edb46e9SPaul Traina *cp++ = hex[*nsap >> 4]; 5404edb46e9SPaul Traina *cp++ = hex[*nsap++ & 0xf]; 54101bd0dbcSPaul Traina if (((i & 1) == 0) && (i + 1 < nlen)) 54201bd0dbcSPaul Traina *cp++ = '.'; 5434edb46e9SPaul Traina } 5444edb46e9SPaul Traina *cp = '\0'; 5454edb46e9SPaul Traina return (tp->e_name); 5464edb46e9SPaul Traina } 5474edb46e9SPaul Traina 5484edb46e9SPaul Traina char * 5494edb46e9SPaul Traina tcpport_string(u_short port) 5504edb46e9SPaul Traina { 5514edb46e9SPaul Traina register struct hnamemem *tp; 5524edb46e9SPaul Traina register u_int32_t i = port; 5534edb46e9SPaul Traina char buf[sizeof("00000")]; 5544edb46e9SPaul Traina 5554edb46e9SPaul Traina for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 5564edb46e9SPaul Traina if (tp->addr == i) 5574edb46e9SPaul Traina return (tp->name); 5584edb46e9SPaul Traina 5594edb46e9SPaul Traina tp->addr = i; 5604edb46e9SPaul Traina tp->nxt = newhnamemem(); 5614edb46e9SPaul Traina 5627524a079SKris Kennaway (void)snprintf(buf, sizeof(buf), "%u", i); 5634edb46e9SPaul Traina tp->name = savestr(buf); 5644edb46e9SPaul Traina return (tp->name); 5654edb46e9SPaul Traina } 5664edb46e9SPaul Traina 5674edb46e9SPaul Traina char * 5684edb46e9SPaul Traina udpport_string(register u_short port) 5694edb46e9SPaul Traina { 5704edb46e9SPaul Traina register struct hnamemem *tp; 5714edb46e9SPaul Traina register u_int32_t i = port; 5724edb46e9SPaul Traina char buf[sizeof("00000")]; 5734edb46e9SPaul Traina 5744edb46e9SPaul Traina for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 5754edb46e9SPaul Traina if (tp->addr == i) 5764edb46e9SPaul Traina return (tp->name); 5774edb46e9SPaul Traina 5784edb46e9SPaul Traina tp->addr = i; 5794edb46e9SPaul Traina tp->nxt = newhnamemem(); 5804edb46e9SPaul Traina 5817524a079SKris Kennaway (void)snprintf(buf, sizeof(buf), "%u", i); 5824edb46e9SPaul Traina tp->name = savestr(buf); 5834edb46e9SPaul Traina return (tp->name); 5844edb46e9SPaul Traina } 5854edb46e9SPaul Traina 5864edb46e9SPaul Traina static void 5874edb46e9SPaul Traina init_servarray(void) 5884edb46e9SPaul Traina { 5894edb46e9SPaul Traina struct servent *sv; 5904edb46e9SPaul Traina register struct hnamemem *table; 5914edb46e9SPaul Traina register int i; 5924edb46e9SPaul Traina char buf[sizeof("0000000000")]; 5934edb46e9SPaul Traina 5944edb46e9SPaul Traina while ((sv = getservent()) != NULL) { 5954edb46e9SPaul Traina int port = ntohs(sv->s_port); 5964edb46e9SPaul Traina i = port & (HASHNAMESIZE-1); 5974edb46e9SPaul Traina if (strcmp(sv->s_proto, "tcp") == 0) 5984edb46e9SPaul Traina table = &tporttable[i]; 5994edb46e9SPaul Traina else if (strcmp(sv->s_proto, "udp") == 0) 6004edb46e9SPaul Traina table = &uporttable[i]; 6014edb46e9SPaul Traina else 6024edb46e9SPaul Traina continue; 6034edb46e9SPaul Traina 6044edb46e9SPaul Traina while (table->name) 6054edb46e9SPaul Traina table = table->nxt; 6064edb46e9SPaul Traina if (nflag) { 6077524a079SKris Kennaway (void)snprintf(buf, sizeof(buf), "%d", port); 6084edb46e9SPaul Traina table->name = savestr(buf); 6094edb46e9SPaul Traina } else 6104edb46e9SPaul Traina table->name = savestr(sv->s_name); 6114edb46e9SPaul Traina table->addr = port; 6124edb46e9SPaul Traina table->nxt = newhnamemem(); 6134edb46e9SPaul Traina } 6144edb46e9SPaul Traina endservent(); 6154edb46e9SPaul Traina } 6164edb46e9SPaul Traina 6174edb46e9SPaul Traina /*XXX from libbpfc.a */ 6184edb46e9SPaul Traina extern struct eproto { 6194edb46e9SPaul Traina char *s; 6204edb46e9SPaul Traina u_short p; 6214edb46e9SPaul Traina } eproto_db[]; 6224edb46e9SPaul Traina 6234edb46e9SPaul Traina static void 6244edb46e9SPaul Traina init_eprotoarray(void) 6254edb46e9SPaul Traina { 6264edb46e9SPaul Traina register int i; 6274edb46e9SPaul Traina register struct hnamemem *table; 6284edb46e9SPaul Traina 6294edb46e9SPaul Traina for (i = 0; eproto_db[i].s; i++) { 6304edb46e9SPaul Traina int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); 6314edb46e9SPaul Traina table = &eprototable[j]; 6324edb46e9SPaul Traina while (table->name) 6334edb46e9SPaul Traina table = table->nxt; 6344edb46e9SPaul Traina table->name = eproto_db[i].s; 6354edb46e9SPaul Traina table->addr = ntohs(eproto_db[i].p); 6364edb46e9SPaul Traina table->nxt = newhnamemem(); 6374edb46e9SPaul Traina } 6384edb46e9SPaul Traina } 6394edb46e9SPaul Traina 6404edb46e9SPaul Traina /* 6414edb46e9SPaul Traina * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 6424edb46e9SPaul Traina * types. 6434edb46e9SPaul Traina */ 6444edb46e9SPaul Traina static void 6454edb46e9SPaul Traina init_protoidarray(void) 6464edb46e9SPaul Traina { 6474edb46e9SPaul Traina register int i; 6484edb46e9SPaul Traina register struct protoidmem *tp; 6494edb46e9SPaul Traina u_char protoid[5]; 6504edb46e9SPaul Traina 6514edb46e9SPaul Traina protoid[0] = 0; 6524edb46e9SPaul Traina protoid[1] = 0; 6534edb46e9SPaul Traina protoid[2] = 0; 6544edb46e9SPaul Traina for (i = 0; eproto_db[i].s; i++) { 6554edb46e9SPaul Traina u_short etype = htons(eproto_db[i].p); 6564edb46e9SPaul Traina 6574edb46e9SPaul Traina memcpy((char *)&protoid[3], (char *)&etype, 2); 6584edb46e9SPaul Traina tp = lookup_protoid(protoid); 6594edb46e9SPaul Traina tp->p_name = savestr(eproto_db[i].s); 6604edb46e9SPaul Traina } 6614edb46e9SPaul Traina } 6624edb46e9SPaul Traina 6634edb46e9SPaul Traina static struct etherlist { 6644edb46e9SPaul Traina u_char addr[6]; 6654edb46e9SPaul Traina char *name; 6664edb46e9SPaul Traina } etherlist[] = { 6674edb46e9SPaul Traina {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 6684edb46e9SPaul Traina {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 6694edb46e9SPaul Traina }; 6704edb46e9SPaul Traina 6714edb46e9SPaul Traina /* 6724edb46e9SPaul Traina * Initialize the ethers hash table. We take two different approaches 6734edb46e9SPaul Traina * depending on whether or not the system provides the ethers name 6744edb46e9SPaul Traina * service. If it does, we just wire in a few names at startup, 6754edb46e9SPaul Traina * and etheraddr_string() fills in the table on demand. If it doesn't, 6764edb46e9SPaul Traina * then we suck in the entire /etc/ethers file at startup. The idea 6774edb46e9SPaul Traina * is that parsing the local file will be fast, but spinning through 6784edb46e9SPaul Traina * all the ethers entries via NIS & next_etherent might be very slow. 6794edb46e9SPaul Traina * 6804edb46e9SPaul Traina * XXX pcap_next_etherent doesn't belong in the pcap interface, but 6814edb46e9SPaul Traina * since the pcap module already does name-to-address translation, 6824edb46e9SPaul Traina * it's already does most of the work for the ethernet address-to-name 6834edb46e9SPaul Traina * translation, so we just pcap_next_etherent as a convenience. 6844edb46e9SPaul Traina */ 6854edb46e9SPaul Traina static void 6864edb46e9SPaul Traina init_etherarray(void) 6874edb46e9SPaul Traina { 6884edb46e9SPaul Traina register struct etherlist *el; 6894edb46e9SPaul Traina register struct enamemem *tp; 6904edb46e9SPaul Traina #ifdef HAVE_ETHER_NTOHOST 6914edb46e9SPaul Traina char name[256]; 6924edb46e9SPaul Traina #else 6934edb46e9SPaul Traina register struct pcap_etherent *ep; 6944edb46e9SPaul Traina register FILE *fp; 6954edb46e9SPaul Traina 6964edb46e9SPaul Traina /* Suck in entire ethers file */ 6974edb46e9SPaul Traina fp = fopen(PCAP_ETHERS_FILE, "r"); 6984edb46e9SPaul Traina if (fp != NULL) { 6994edb46e9SPaul Traina while ((ep = pcap_next_etherent(fp)) != NULL) { 7004edb46e9SPaul Traina tp = lookup_emem(ep->addr); 7014edb46e9SPaul Traina tp->e_name = savestr(ep->name); 7024edb46e9SPaul Traina } 7034edb46e9SPaul Traina (void)fclose(fp); 7044edb46e9SPaul Traina } 7054edb46e9SPaul Traina #endif 7064edb46e9SPaul Traina 7074edb46e9SPaul Traina /* Hardwire some ethernet names */ 7084edb46e9SPaul Traina for (el = etherlist; el->name != NULL; ++el) { 7094edb46e9SPaul Traina tp = lookup_emem(el->addr); 7104edb46e9SPaul Traina /* Don't override existing name */ 7114edb46e9SPaul Traina if (tp->e_name != NULL) 7124edb46e9SPaul Traina continue; 7134edb46e9SPaul Traina 7144edb46e9SPaul Traina #ifdef HAVE_ETHER_NTOHOST 7154edb46e9SPaul Traina /* Use yp/nis version of name if available */ 7164edb46e9SPaul Traina if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { 7174edb46e9SPaul Traina tp->e_name = savestr(name); 7184edb46e9SPaul Traina continue; 7194edb46e9SPaul Traina } 7204edb46e9SPaul Traina #endif 7214edb46e9SPaul Traina tp->e_name = el->name; 7224edb46e9SPaul Traina } 7234edb46e9SPaul Traina } 7244edb46e9SPaul Traina 7254edb46e9SPaul Traina static struct tok llcsap_db[] = { 7264edb46e9SPaul Traina { LLCSAP_NULL, "null" }, 7274edb46e9SPaul Traina { LLCSAP_8021B_I, "802.1b-gsap" }, 7284edb46e9SPaul Traina { LLCSAP_8021B_G, "802.1b-isap" }, 7294edb46e9SPaul Traina { LLCSAP_IP, "ip-sap" }, 7304edb46e9SPaul Traina { LLCSAP_PROWAYNM, "proway-nm" }, 7314edb46e9SPaul Traina { LLCSAP_8021D, "802.1d" }, 7324edb46e9SPaul Traina { LLCSAP_RS511, "eia-rs511" }, 7334edb46e9SPaul Traina { LLCSAP_ISO8208, "x.25/llc2" }, 7344edb46e9SPaul Traina { LLCSAP_PROWAY, "proway" }, 7354edb46e9SPaul Traina { LLCSAP_ISONS, "iso-clns" }, 7364edb46e9SPaul Traina { LLCSAP_GLOBAL, "global" }, 7374edb46e9SPaul Traina { 0, NULL } 7384edb46e9SPaul Traina }; 7394edb46e9SPaul Traina 7404edb46e9SPaul Traina static void 7414edb46e9SPaul Traina init_llcsaparray(void) 7424edb46e9SPaul Traina { 7434edb46e9SPaul Traina register int i; 7444edb46e9SPaul Traina register struct hnamemem *table; 7454edb46e9SPaul Traina 7464edb46e9SPaul Traina for (i = 0; llcsap_db[i].s != NULL; i++) { 7474edb46e9SPaul Traina table = &llcsaptable[llcsap_db[i].v]; 7484edb46e9SPaul Traina while (table->name) 7494edb46e9SPaul Traina table = table->nxt; 7504edb46e9SPaul Traina table->name = llcsap_db[i].s; 7514edb46e9SPaul Traina table->addr = llcsap_db[i].v; 7524edb46e9SPaul Traina table->nxt = newhnamemem(); 7534edb46e9SPaul Traina } 7544edb46e9SPaul Traina } 7554edb46e9SPaul Traina 7564edb46e9SPaul Traina /* 7574edb46e9SPaul Traina * Initialize the address to name translation machinery. We map all 7584edb46e9SPaul Traina * non-local IP addresses to numeric addresses if fflag is true (i.e., 7594edb46e9SPaul Traina * to prevent blocking on the nameserver). localnet is the IP address 7604edb46e9SPaul Traina * of the local network. mask is its subnet mask. 7614edb46e9SPaul Traina */ 7624edb46e9SPaul Traina void 763699fc314SBill Fenner init_addrtoname(u_int32_t localnet, u_int32_t mask) 7644edb46e9SPaul Traina { 7654edb46e9SPaul Traina netmask = mask; 7664edb46e9SPaul Traina if (fflag) { 7674edb46e9SPaul Traina f_localnet = localnet; 7684edb46e9SPaul Traina f_netmask = mask; 7694edb46e9SPaul Traina } 7704edb46e9SPaul Traina if (nflag) 7714edb46e9SPaul Traina /* 7724edb46e9SPaul Traina * Simplest way to suppress names. 7734edb46e9SPaul Traina */ 7744edb46e9SPaul Traina return; 7754edb46e9SPaul Traina 7764edb46e9SPaul Traina init_etherarray(); 7774edb46e9SPaul Traina init_servarray(); 7784edb46e9SPaul Traina init_eprotoarray(); 7794edb46e9SPaul Traina init_llcsaparray(); 7804edb46e9SPaul Traina init_protoidarray(); 7814edb46e9SPaul Traina } 7824edb46e9SPaul Traina 7834edb46e9SPaul Traina char * 7844edb46e9SPaul Traina dnaddr_string(u_short dnaddr) 7854edb46e9SPaul Traina { 7864edb46e9SPaul Traina register struct hnamemem *tp; 7874edb46e9SPaul Traina 7884edb46e9SPaul Traina for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; 7894edb46e9SPaul Traina tp = tp->nxt) 7904edb46e9SPaul Traina if (tp->addr == dnaddr) 7914edb46e9SPaul Traina return (tp->name); 7924edb46e9SPaul Traina 7934edb46e9SPaul Traina tp->addr = dnaddr; 7944edb46e9SPaul Traina tp->nxt = newhnamemem(); 7954edb46e9SPaul Traina if (nflag) 7964edb46e9SPaul Traina tp->name = dnnum_string(dnaddr); 7974edb46e9SPaul Traina else 7984edb46e9SPaul Traina tp->name = dnname_string(dnaddr); 7994edb46e9SPaul Traina 8004edb46e9SPaul Traina return(tp->name); 8014edb46e9SPaul Traina } 8024edb46e9SPaul Traina 8034edb46e9SPaul Traina /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 8044edb46e9SPaul Traina struct hnamemem * 8052ebf6c05SBill Fenner newhnamemem(void) 8064edb46e9SPaul Traina { 8074edb46e9SPaul Traina register struct hnamemem *p; 8084edb46e9SPaul Traina static struct hnamemem *ptr = NULL; 8094edb46e9SPaul Traina static u_int num = 0; 8104edb46e9SPaul Traina 8114edb46e9SPaul Traina if (num <= 0) { 8124edb46e9SPaul Traina num = 64; 8134edb46e9SPaul Traina ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 8144edb46e9SPaul Traina if (ptr == NULL) 8154edb46e9SPaul Traina error("newhnamemem: calloc"); 8164edb46e9SPaul Traina } 8174edb46e9SPaul Traina --num; 8184edb46e9SPaul Traina p = ptr++; 8194edb46e9SPaul Traina return (p); 8204edb46e9SPaul Traina } 821a88113a8SBill Fenner 822a88113a8SBill Fenner #ifdef INET6 823a88113a8SBill Fenner /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ 824a88113a8SBill Fenner struct h6namemem * 825a88113a8SBill Fenner newh6namemem(void) 826a88113a8SBill Fenner { 827a88113a8SBill Fenner register struct h6namemem *p; 828a88113a8SBill Fenner static struct h6namemem *ptr = NULL; 829a88113a8SBill Fenner static u_int num = 0; 830a88113a8SBill Fenner 831a88113a8SBill Fenner if (num <= 0) { 832a88113a8SBill Fenner num = 64; 833a88113a8SBill Fenner ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); 834a88113a8SBill Fenner if (ptr == NULL) 835a88113a8SBill Fenner error("newh6namemem: calloc"); 836a88113a8SBill Fenner } 837a88113a8SBill Fenner --num; 838a88113a8SBill Fenner p = ptr++; 839a88113a8SBill Fenner return (p); 840a88113a8SBill Fenner } 841a88113a8SBill Fenner #endif /* INET6 */ 842