home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / addrtoname.c next >
C/C++ Source or Header  |  1997-04-13  |  23KB  |  771 lines

  1. /*
  2.  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
  3.  *      The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  *  Internet, ethernet, port, and protocol string to address
  22.  *  and address to string conversion routines
  23.  */
  24. #ifndef lint
  25. static char rcsid[] =
  26.     "@(#) $Header: addrtoname.c,v 1.49 96/07/02 00:19:35 leres Exp $ (LBL)";
  27. #endif
  28.  
  29. #include <sys/types.h>
  30. #include <sys/socket.h>
  31. #include <sys/time.h>
  32.  
  33. #if __STDC__
  34. struct mbuf;
  35. struct rtentry;
  36. #endif
  37. #include <net/if.h>
  38.  
  39. #include <netinet/in.h>
  40. #include <netinet/if_ether.h>
  41.  
  42. #include <arpa/inet.h>
  43.  
  44. #include <ctype.h>
  45. #include <netdb.h>
  46. #include <pcap.h>
  47. #include <pcap-namedb.h>
  48. #include <signal.h>
  49. #include <stdio.h>
  50. #include <string.h>
  51. #include <stdlib.h>
  52. #include <unistd.h>
  53.  
  54. #include "interface.h"
  55. #include "addrtoname.h"
  56. #include "llc.h"
  57.  
  58. /* Forwards */
  59. static RETSIGTYPE nohostname(int);
  60.  
  61. /*
  62.  * hash tables for whatever-to-name translations
  63.  */
  64.  
  65. #define HASHNAMESIZE 4096
  66.  
  67. struct hnamemem {
  68.         u_int32_t addr;
  69.         char *name;
  70.         struct hnamemem *nxt;
  71. };
  72.  
  73. struct hnamemem hnametable[HASHNAMESIZE];
  74. struct hnamemem tporttable[HASHNAMESIZE];
  75. struct hnamemem uporttable[HASHNAMESIZE];
  76. struct hnamemem eprototable[HASHNAMESIZE];
  77. struct hnamemem dnaddrtable[HASHNAMESIZE];
  78. struct hnamemem llcsaptable[HASHNAMESIZE];
  79.  
  80. struct enamemem {
  81.         u_short e_addr0;
  82.         u_short e_addr1;
  83.         u_short e_addr2;
  84.         char *e_name;
  85.         u_char *e_nsap;                 /* used only for nsaptable[] */
  86.         struct enamemem *e_nxt;
  87. };
  88.  
  89. struct enamemem enametable[HASHNAMESIZE];
  90. struct enamemem nsaptable[HASHNAMESIZE];
  91.  
  92. struct protoidmem {
  93.         u_int32_t p_oui;
  94.         u_short p_proto;
  95.         char *p_name;
  96.         struct protoidmem *p_nxt;
  97. };
  98.  
  99. struct protoidmem protoidtable[HASHNAMESIZE];
  100.  
  101. #ifdef __EMX__
  102. char *
  103. intoa(u_int32_t addr)
  104. {
  105.   static char result[16];
  106.   unsigned char *t;
  107.  
  108.   t = (unsigned char *)&addr;
  109.   sprintf (result, "%d.%d.%d.%d",
  110.            t[2] & 0xff, t[3] & 0xff, t[0] & 0xff, t[1] & 0xff);
  111.   return result;
  112. }
  113. #else
  114. /*
  115.  * A faster replacement for inet_ntoa().
  116.  */
  117. char *
  118. intoa(u_int32_t addr)
  119. {
  120.         register char *cp;
  121.         register u_int byte;
  122.         register int n;
  123.         static char buf[sizeof(".xxx.xxx.xxx.xxx")];
  124.  
  125.         NTOHL(addr);
  126.         cp = &buf[sizeof buf];
  127.         *--cp = '\0';
  128.  
  129.         n = 4;
  130.         do {
  131.                 byte = addr & 0xff;
  132.                 *--cp = byte % 10 + '0';
  133.                 byte /= 10;
  134.                 if (byte > 0) {
  135.                         *--cp = byte % 10 + '0';
  136.                         byte /= 10;
  137.                         if (byte > 0)
  138.                                 *--cp = byte + '0';
  139.                 }
  140.                 *--cp = '.';
  141.                 addr >>= 8;
  142.         } while (--n > 0);
  143.  
  144.         return cp + 1;
  145. }
  146. #endif
  147.  
  148. static u_int32_t f_netmask;
  149. static u_int32_t f_localnet;
  150. static u_int32_t netmask;
  151.  
  152. /*
  153.  * "getname" is written in this atrocious way to make sure we don't
  154.  * wait forever while trying to get hostnames from yp.
  155.  */
  156. #include <setjmp.h>
  157.  
  158. jmp_buf getname_env;
  159.  
  160. static RETSIGTYPE
  161. nohostname(int signo)
  162. {
  163.         longjmp(getname_env, 1);
  164. }
  165.  
  166. /*
  167.  * Return a name for the IP address pointed to by ap.  This address
  168.  * is assumed to be in network byte order.
  169.  */
  170. char *
  171. getname(const u_char *ap)
  172. {
  173.         register struct hostent *hp;
  174.         u_int32_t addr;
  175.         static struct hnamemem *p;              /* static for longjmp() */
  176.  
  177. #ifndef LBL_ALIGN
  178.         addr = *(const u_int32_t *)ap;
  179. #else
  180.         /*
  181.          * Deal with alignment.
  182.          */
  183.         switch ((long)ap & 3) {
  184.  
  185.         case 0:
  186.                 addr = *(u_int32_t *)ap;
  187.                 break;
  188.  
  189.         case 2:
  190. #if BYTE_ORDER == LITTLE_ENDIAN
  191.                 addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) |
  192.                         (u_int32_t)*(u_short *)ap;
  193. #else
  194.                 addr = ((u_int32_t)*(u_short *)ap << 16) |
  195.                         (u_int32_t)*(u_short *)(ap + 2);
  196. #endif
  197.                 break;
  198.  
  199.         default:
  200. #if BYTE_ORDER == LITTLE_ENDIAN
  201.                 addr = ((u_int32_t)ap[3] << 24) |
  202.                         ((u_int32_t)ap[2] << 16) |
  203.                         ((u_int32_t)ap[1] << 8) |
  204.                         (u_int32_t)ap[0];
  205. #else
  206.                 addr = ((u_int32_t)ap[0] << 24) |
  207.                         ((u_int32_t)ap[1] << 16) |
  208.                         ((u_int32_t)ap[2] << 8) |
  209.                         (u_int32_t)ap[3];
  210. #endif
  211.                 break;
  212.         }
  213. #endif
  214.         p = &hnametable[addr & (HASHNAMESIZE-1)];
  215.         for (; p->nxt; p = p->nxt) {
  216.                 if (p->addr == addr)
  217.                         return (p->name);
  218.         }
  219.         p->addr = addr;
  220.         p->nxt = newhnamemem();
  221.  
  222.         /*
  223.          * Only print names when:
  224.          *      (1) -n was not given.
  225.          *      (2) Address is foreign and -f was given.  If -f was not
  226.          *          present, f_netmask and f_local are 0 and the second
  227.          *          test will succeed.
  228.          *      (3) The host portion is not 0 (i.e., a network address).
  229.          *      (4) The host portion is not broadcast.
  230.          */
  231.         if (!nflag && (addr & f_netmask) == f_localnet
  232.             && (addr &~ netmask) != 0 && (addr | netmask) != 0xffffffff) {
  233.                 if (!setjmp(getname_env)) {
  234.                         (void)signal(SIGALRM, nohostname);
  235.                         (void)alarm(20);
  236.                         hp = gethostbyaddr((char *)&addr, 4, AF_INET);
  237.                         (void)alarm(0);
  238.                         if (hp) {
  239.                                 char *dotp;
  240.  
  241.                                 p->name = savestr(hp->h_name);
  242.                                 if (Nflag) {
  243.                                         /* Remove domain qualifications */
  244.                                         dotp = strchr(p->name, '.');
  245.                                         if (dotp)
  246.                                                 *dotp = '\0';
  247.                                 }
  248.                                 return (p->name);
  249.                         }
  250.                 }
  251.         }
  252.         p->name = savestr(intoa(addr));
  253.         return (p->name);
  254. }
  255.  
  256. static char hex[] = "0123456789abcdef";
  257.  
  258.  
  259. /* Find the hash node that corresponds the ether address 'ep' */
  260.  
  261. static inline struct enamemem *
  262. lookup_emem(const u_char *ep)
  263. {
  264.         register u_int i, j, k;
  265.         struct enamemem *tp;
  266.  
  267.         k = (ep[0] << 8) | ep[1];
  268.         j = (ep[2] << 8) | ep[3];
  269.         i = (ep[4] << 8) | ep[5];
  270.  
  271.         tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
  272.         while (tp->e_nxt)
  273.                 if (tp->e_addr0 == i &&
  274.                     tp->e_addr1 == j &&
  275.                     tp->e_addr2 == k)
  276.                         return tp;
  277.                 else
  278.                         tp = tp->e_nxt;
  279.         tp->e_addr0 = i;
  280.         tp->e_addr1 = j;
  281.         tp->e_addr2 = k;
  282.         tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
  283.         if (tp->e_nxt == NULL)
  284.                 error("lookup_emem: calloc");
  285.  
  286.         return tp;
  287. }
  288.  
  289. /* Find the hash node that corresponds the NSAP 'nsap' */
  290.  
  291. static inline struct enamemem *
  292. lookup_nsap(register const u_char *nsap)
  293. {
  294.         register u_int i, j, k;
  295.         int nlen = *nsap;
  296.         struct enamemem *tp;
  297.         const u_char *ensap = nsap + nlen - 6;
  298.  
  299.         if (nlen > 6) {
  300.                 k = (ensap[0] << 8) | ensap[1];
  301.                 j = (ensap[2] << 8) | ensap[3];
  302.                 i = (ensap[4] << 8) | ensap[5];
  303.         }
  304.         else
  305.                 i = j = k = 0;
  306.  
  307.         tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
  308.         while (tp->e_nxt)
  309.                 if (tp->e_addr0 == i &&
  310.                     tp->e_addr1 == j &&
  311.                     tp->e_addr2 == k &&
  312.                     tp->e_nsap[0] == nlen &&
  313.                     memcmp((char *)&(nsap[1]),
  314.                         (char *)&(tp->e_nsap[1]), nlen) == 0)
  315.                         return tp;
  316.                 else
  317.                         tp = tp->e_nxt;
  318.         tp->e_addr0 = i;
  319.         tp->e_addr1 = j;
  320.         tp->e_addr2 = k;
  321.         tp->e_nsap = (u_char *)malloc(nlen + 1);
  322.         if (tp->e_nsap == NULL)
  323.                 error("lookup_nsap: malloc");
  324.         memcpy(tp->e_nsap, nsap, nlen + 1);
  325.         tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
  326.         if (tp->e_nxt == NULL)
  327.                 error("lookup_nsap: calloc");
  328.  
  329.         return tp;
  330. }
  331.  
  332. /* Find the hash node that corresponds the protoid 'pi'. */
  333.  
  334. static inline struct protoidmem *
  335. lookup_protoid(const u_char *pi)
  336. {
  337.         register u_int i, j;
  338.         struct protoidmem *tp;
  339.  
  340.         /* 5 octets won't be aligned */
  341.         i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
  342.         j =   (pi[3] << 8) + pi[4];
  343.         /* XXX should be endian-insensitive, but do big-endian testing  XXX */
  344.  
  345.         tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
  346.         while (tp->p_nxt)
  347.                 if (tp->p_oui == i && tp->p_proto == j)
  348.                         return tp;
  349.                 else
  350.                         tp = tp->p_nxt;
  351.         tp->p_oui = i;
  352.         tp->p_proto = j;
  353.         tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
  354.         if (tp->p_nxt == NULL)
  355.                 error("lookup_protoid: calloc");
  356.  
  357.         return tp;
  358. }
  359.  
  360. char *
  361. etheraddr_string(register const u_char *ep)
  362. {
  363.         register u_int i, j;
  364.         register char *cp;
  365.         register struct enamemem *tp;
  366.         char buf[sizeof("00:00:00:00:00:00")];
  367.  
  368.         tp = lookup_emem(ep);
  369.         if (tp->e_name)
  370.                 return (tp->e_name);
  371. #ifdef HAVE_ETHER_NTOHOST
  372.         if (!nflag) {
  373.                 char buf[128];
  374.                 if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) {
  375.                         tp->e_name = savestr(buf);
  376.                         return (tp->e_name);
  377.                 }
  378.         }
  379. #endif
  380.         cp = buf;
  381.         if ((j = *ep >> 4) != 0)
  382.                 *cp++ = hex[j];
  383.         *cp++ = hex[*ep++ & 0xf];
  384.         for (i = 5; (int)--i >= 0;) {
  385.                 *cp++ = ':';
  386.                 if ((j = *ep >> 4) != 0)
  387.                         *cp++ = hex[j];
  388.                 *cp++ = hex[*ep++ & 0xf];
  389.         }
  390.         *cp = '\0';
  391.         tp->e_name = savestr(buf);
  392.         return (tp->e_name);
  393. }
  394.  
  395. char *
  396. etherproto_string(u_short port)
  397. {
  398.         register char *cp;
  399.         register struct hnamemem *tp;
  400.         register u_int32_t i = port;
  401.         char buf[sizeof("0000")];
  402.  
  403.         for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  404.                 if (tp->addr == i)
  405.                         return (tp->name);
  406.  
  407.         tp->addr = i;
  408.         tp->nxt = newhnamemem();
  409.  
  410.         cp = buf;
  411.         NTOHS(port);
  412.         *cp++ = hex[port >> 12 & 0xf];
  413.         *cp++ = hex[port >> 8 & 0xf];
  414.         *cp++ = hex[port >> 4 & 0xf];
  415.         *cp++ = hex[port & 0xf];
  416.         *cp++ = '\0';
  417.         tp->name = savestr(buf);
  418.         return (tp->name);
  419. }
  420.  
  421. char *
  422. protoid_string(register const u_char *pi)
  423. {
  424.         register u_int i, j;
  425.         register char *cp;
  426.         register struct protoidmem *tp;
  427.         char buf[sizeof("00:00:00:00:00")];
  428.  
  429.         tp = lookup_protoid(pi);
  430.         if (tp->p_name)
  431.                 return tp->p_name;
  432.  
  433.         cp = buf;
  434.         if ((j = *pi >> 4) != 0)
  435.                 *cp++ = hex[j];
  436.         *cp++ = hex[*pi++ & 0xf];
  437.         for (i = 4; (int)--i >= 0;) {
  438.                 *cp++ = ':';
  439.                 if ((j = *pi >> 4) != 0)
  440.                         *cp++ = hex[j];
  441.                 *cp++ = hex[*pi++ & 0xf];
  442.         }
  443.         *cp = '\0';
  444.         tp->p_name = savestr(buf);
  445.         return (tp->p_name);
  446. }
  447.  
  448. char *
  449. llcsap_string(u_char sap)
  450. {
  451.         register char *cp;
  452.         register struct hnamemem *tp;
  453.         register u_int32_t i = sap;
  454.         char buf[sizeof("sap 00")];
  455.  
  456.         for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  457.                 if (tp->addr == i)
  458.                         return (tp->name);
  459.  
  460.         tp->addr = i;
  461.         tp->nxt = newhnamemem();
  462.  
  463.         cp = buf;
  464.         (void)strcpy(cp, "sap ");
  465.         cp += strlen(cp);
  466.         *cp++ = hex[sap >> 4 & 0xf];
  467.         *cp++ = hex[sap & 0xf];
  468.         *cp++ = '\0';
  469.         tp->name = savestr(buf);
  470.         return (tp->name);
  471. }
  472.  
  473. char *
  474. isonsap_string(const u_char *nsap)
  475. {
  476.         register u_int i, nlen = nsap[0];
  477.         register char *cp;
  478.         register struct enamemem *tp;
  479.  
  480.         tp = lookup_nsap(nsap);
  481.         if (tp->e_name)
  482.                 return tp->e_name;
  483.  
  484.         tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
  485.         if (cp == NULL)
  486.                 error("isonsap_string: malloc");
  487.  
  488.         nsap++;
  489.         *cp++ = '/';
  490.         for (i = nlen; (int)--i >= 0;) {
  491.                 *cp++ = hex[*nsap >> 4];
  492.                 *cp++ = hex[*nsap++ & 0xf];
  493.         }
  494.         *cp = '\0';
  495.         return (tp->e_name);
  496. }
  497.  
  498. char *
  499. tcpport_string(u_short port)
  500. {
  501.         register struct hnamemem *tp;
  502.         register u_int32_t i = port;
  503.         char buf[sizeof("00000")];
  504.  
  505.         for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  506.                 if (tp->addr == i)
  507.                         return (tp->name);
  508.  
  509.         tp->addr = i;
  510.         tp->nxt = newhnamemem();
  511.  
  512.         (void)sprintf(buf, "%u", i);
  513.         tp->name = savestr(buf);
  514.         return (tp->name);
  515. }
  516.  
  517. char *
  518. udpport_string(register u_short port)
  519. {
  520.         register struct hnamemem *tp;
  521.         register u_int32_t i = port;
  522.         char buf[sizeof("00000")];
  523.  
  524.         for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
  525.                 if (tp->addr == i)
  526.                         return (tp->name);
  527.  
  528.         tp->addr = i;
  529.         tp->nxt = newhnamemem();
  530.  
  531.         (void)sprintf(buf, "%u", i);
  532.         tp->name = savestr(buf);
  533.         return (tp->name);
  534. }
  535.  
  536. static void
  537. init_servarray(void)
  538. {
  539.         struct servent *sv;
  540.         register struct hnamemem *table;
  541.         register int i;
  542.         char buf[sizeof("0000000000")];
  543.  
  544.         while ((sv = getservent()) != NULL) {
  545.                 int port = ntohs(sv->s_port);
  546.                 i = port & (HASHNAMESIZE-1);
  547.                 if (strcmp(sv->s_proto, "tcp") == 0)
  548.                         table = &tporttable[i];
  549.                 else if (strcmp(sv->s_proto, "udp") == 0)
  550.                         table = &uporttable[i];
  551.                 else
  552.                         continue;
  553.  
  554.                 while (table->name)
  555.                         table = table->nxt;
  556.                 if (nflag) {
  557.                         (void)sprintf(buf, "%d", port);
  558.                         table->name = savestr(buf);
  559.                 } else
  560.                         table->name = savestr(sv->s_name);
  561.                 table->addr = port;
  562.                 table->nxt = newhnamemem();
  563.         }
  564.         endservent();
  565. }
  566.  
  567. /*XXX from libbpfc.a */
  568. extern struct eproto {
  569.         char *s;
  570.         u_short p;
  571. } eproto_db[];
  572.  
  573. static void
  574. init_eprotoarray(void)
  575. {
  576.         register int i;
  577.         register struct hnamemem *table;
  578.  
  579.         for (i = 0; eproto_db[i].s; i++) {
  580.                 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
  581.                 table = &eprototable[j];
  582.                 while (table->name)
  583.                         table = table->nxt;
  584.                 table->name = eproto_db[i].s;
  585.                 table->addr = ntohs(eproto_db[i].p);
  586.                 table->nxt = newhnamemem();
  587.         }
  588. }
  589.  
  590. /*
  591.  * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
  592.  * types.
  593.  */
  594. static void
  595. init_protoidarray(void)
  596. {
  597.         register int i;
  598.         register struct protoidmem *tp;
  599.         u_char protoid[5];
  600.  
  601.         protoid[0] = 0;
  602.         protoid[1] = 0;
  603.         protoid[2] = 0;
  604.         for (i = 0; eproto_db[i].s; i++) {
  605.                 u_short etype = htons(eproto_db[i].p);
  606.  
  607.                 memcpy((char *)&protoid[3], (char *)&etype, 2);
  608.                 tp = lookup_protoid(protoid);
  609.                 tp->p_name = savestr(eproto_db[i].s);
  610.         }
  611. }
  612.  
  613. static struct etherlist {
  614.         u_char addr[6];
  615.         char *name;
  616. } etherlist[] = {
  617.         {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
  618.         {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
  619. };
  620.  
  621. /*
  622.  * Initialize the ethers hash table.  We take two different approaches
  623.  * depending on whether or not the system provides the ethers name
  624.  * service.  If it does, we just wire in a few names at startup,
  625.  * and etheraddr_string() fills in the table on demand.  If it doesn't,
  626.  * then we suck in the entire /etc/ethers file at startup.  The idea
  627.  * is that parsing the local file will be fast, but spinning through
  628.  * all the ethers entries via NIS & next_etherent might be very slow.
  629.  *
  630.  * XXX pcap_next_etherent doesn't belong in the pcap interface, but
  631.  * since the pcap module already does name-to-address translation,
  632.  * it's already does most of the work for the ethernet address-to-name
  633.  * translation, so we just pcap_next_etherent as a convenience.
  634.  */
  635. static void
  636. init_etherarray(void)
  637. {
  638.         register struct etherlist *el;
  639.         register struct enamemem *tp;
  640. #ifdef HAVE_ETHER_NTOHOST
  641.         char name[256];
  642. #else
  643.         register struct pcap_etherent *ep;
  644.         register FILE *fp;
  645.  
  646.         /* Suck in entire ethers file */
  647.         fp = fopen(PCAP_ETHERS_FILE, "r");
  648.         if (fp != NULL) {
  649.                 while ((ep = pcap_next_etherent(fp)) != NULL) {
  650.                         tp = lookup_emem(ep->addr);
  651.                         tp->e_name = savestr(ep->name);
  652.                 }
  653.                 (void)fclose(fp);
  654.         }
  655. #endif
  656.  
  657.         /* Hardwire some ethernet names */
  658.         for (el = etherlist; el->name != NULL; ++el) {
  659.                 tp = lookup_emem(el->addr);
  660.                 /* Don't override existing name */
  661.                 if (tp->e_name != NULL)
  662.                         continue;
  663.  
  664. #ifdef HAVE_ETHER_NTOHOST
  665.                 /* Use yp/nis version of name if available */
  666.                 if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) {
  667.                         tp->e_name = savestr(name);
  668.                         continue;
  669.                 }
  670. #endif
  671.                 tp->e_name = el->name;
  672.         }
  673. }
  674.  
  675. static struct tok llcsap_db[] = {
  676.         { LLCSAP_NULL,          "null" },
  677.         { LLCSAP_8021B_I,       "802.1b-gsap" },
  678.         { LLCSAP_8021B_G,       "802.1b-isap" },
  679.         { LLCSAP_IP,            "ip-sap" },
  680.         { LLCSAP_PROWAYNM,      "proway-nm" },
  681.         { LLCSAP_8021D,         "802.1d" },
  682.         { LLCSAP_RS511,         "eia-rs511" },
  683.         { LLCSAP_ISO8208,       "x.25/llc2" },
  684.         { LLCSAP_PROWAY,        "proway" },
  685.         { LLCSAP_ISONS,         "iso-clns" },
  686.         { LLCSAP_GLOBAL,        "global" },
  687.         { 0,                    NULL }
  688. };
  689.  
  690. static void
  691. init_llcsaparray(void)
  692. {
  693.         register int i;
  694.         register struct hnamemem *table;
  695.  
  696.         for (i = 0; llcsap_db[i].s != NULL; i++) {
  697.                 table = &llcsaptable[llcsap_db[i].v];
  698.                 while (table->name)
  699.                         table = table->nxt;
  700.                 table->name = llcsap_db[i].s;
  701.                 table->addr = llcsap_db[i].v;
  702.                 table->nxt = newhnamemem();
  703.         }
  704. }
  705.  
  706. /*
  707.  * Initialize the address to name translation machinery.  We map all
  708.  * non-local IP addresses to numeric addresses if fflag is true (i.e.,
  709.  * to prevent blocking on the nameserver).  localnet is the IP address
  710.  * of the local network.  mask is its subnet mask.
  711.  */
  712. void
  713. init_addrtoname(int fflag, u_int32_t localnet, u_int32_t mask)
  714. {
  715.         netmask = mask;
  716.         if (fflag) {
  717.                 f_localnet = localnet;
  718.                 f_netmask = mask;
  719.         }
  720.         if (nflag)
  721.                 /*
  722.                  * Simplest way to suppress names.
  723.                  */
  724.                 return;
  725.  
  726.         init_etherarray();
  727.         init_servarray();
  728.         init_eprotoarray();
  729.         init_llcsaparray();
  730.         init_protoidarray();
  731. }
  732.  
  733. char *
  734. dnaddr_string(u_short dnaddr)
  735. {
  736.         register struct hnamemem *tp;
  737.  
  738.         for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
  739.              tp = tp->nxt)
  740.                 if (tp->addr == dnaddr)
  741.                         return (tp->name);
  742.  
  743.         tp->addr = dnaddr;
  744.         tp->nxt = newhnamemem();
  745.         if (nflag)
  746.                 tp->name = dnnum_string(dnaddr);
  747.         else
  748.                 tp->name = dnname_string(dnaddr);
  749.  
  750.         return(tp->name);
  751. }
  752.  
  753. /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
  754. struct hnamemem *
  755. newhnamemem()
  756. {
  757.         register struct hnamemem *p;
  758.         static struct hnamemem *ptr = NULL;
  759.         static u_int num = 0;
  760.  
  761.         if (num  <= 0) {
  762.                 num = 64;
  763.                 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
  764.                 if (ptr == NULL)
  765.                         error("newhnamemem: calloc");
  766.         }
  767.         --num;
  768.         p = ptr++;
  769.         return (p);
  770. }
  771.