summaryrefslogtreecommitdiffstats
path: root/usr.sbin/tcpdump/tcpdump/addrtoname.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/tcpdump/tcpdump/addrtoname.c')
-rw-r--r--usr.sbin/tcpdump/tcpdump/addrtoname.c486
1 files changed, 365 insertions, 121 deletions
diff --git a/usr.sbin/tcpdump/tcpdump/addrtoname.c b/usr.sbin/tcpdump/tcpdump/addrtoname.c
index 5c70865..11a1098 100644
--- a/usr.sbin/tcpdump/tcpdump/addrtoname.c
+++ b/usr.sbin/tcpdump/tcpdump/addrtoname.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1988, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@@ -23,25 +23,41 @@
*/
#ifndef lint
static char rcsid[] =
- "@(#) $Header: addrtoname.c,v 1.14 92/05/25 14:29:07 mccanne Exp $ (LBL)";
+ "@(#) $Header: addrtoname.c,v 1.37 94/06/16 00:42:28 mccanne Exp $ (LBL)";
#endif
-#include <stdio.h>
-#include <strings.h>
-#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/time.h>
+
#include <net/if.h>
-#include <netdb.h>
+
#include <netinet/in.h>
#include <netinet/if_ether.h>
+
#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <pcap.h>
+#include <pcap-namedb.h>
#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
#include "interface.h"
#include "addrtoname.h"
-#include "nametoaddr.h"
-#include "etherent.h"
+#include "llc.h"
+
+static SIGRET nohostname(int);
+#ifdef ETHER_SERVICE
+struct ether_addr;
+extern int ether_ntohost(char *, struct ether_addr *);
+#endif
/*
* hash tables for whatever-to-name translations
@@ -50,7 +66,7 @@ static char rcsid[] =
#define HASHNAMESIZE 4096
struct hnamemem {
- u_long addr;
+ u_int32 addr;
char *name;
struct hnamemem *nxt;
};
@@ -59,24 +75,35 @@ struct hnamemem hnametable[HASHNAMESIZE];
struct hnamemem tporttable[HASHNAMESIZE];
struct hnamemem uporttable[HASHNAMESIZE];
struct hnamemem eprototable[HASHNAMESIZE];
+struct hnamemem dnaddrtable[HASHNAMESIZE];
+struct hnamemem llcsaptable[HASHNAMESIZE];
struct enamemem {
u_short e_addr0;
u_short e_addr1;
u_short e_addr2;
char *e_name;
+ u_char *e_nsap; /* used only for nsaptable[] */
struct enamemem *e_nxt;
};
struct enamemem enametable[HASHNAMESIZE];
+struct enamemem nsaptable[HASHNAMESIZE];
+struct protoidmem {
+ u_long p_oui;
+ u_short p_proto;
+ char *p_name;
+ struct protoidmem *p_nxt;
+};
+
+struct protoidmem protoidtable[HASHNAMESIZE];
/*
* A faster replacement for inet_ntoa().
*/
char *
-intoa(addr)
- u_long addr;
+intoa(u_int32 addr)
{
register char *cp;
register u_int byte;
@@ -105,9 +132,9 @@ intoa(addr)
return cp + 1;
}
-static u_long f_netmask;
-static u_long f_localnet;
-static u_long netmask;
+static u_int32 f_netmask;
+static u_int32 f_localnet;
+static u_int32 netmask;
/*
* "getname" is written in this atrocious way to make sure we don't
@@ -117,8 +144,8 @@ static u_long netmask;
jmp_buf getname_env;
-static void
-nohostname()
+static SIGRET
+nohostname(int signo)
{
longjmp(getname_env, 1);
}
@@ -128,16 +155,15 @@ nohostname()
* is assumed to be in network byte order.
*/
char *
-getname(ap)
- u_char *ap;
+getname(const u_char *ap)
{
- register struct hnamemem *p;
register struct hostent *hp;
register char *cp;
- u_long addr;
+ u_int32 addr;
+ static struct hnamemem *p; /* static for longjmp() */
#ifndef TCPDUMP_ALIGN
- addr = *(u_long *)ap;
+ addr = *(const u_int32 *)ap;
#else
/*
* Deal with alignment.
@@ -145,35 +171,35 @@ getname(ap)
switch ((int)ap & 3) {
case 0:
- addr = *(u_long *)ap;
+ addr = *(u_int32 *)ap;
break;
case 2:
#if BYTE_ORDER == LITTLE_ENDIAN
- addr = ((u_long)*(u_short *)(ap + 2) << 16) |
- (u_long)*(u_short *)ap;
+ addr = ((u_int32)*(u_short *)(ap + 2) << 16) |
+ (u_int32)*(u_short *)ap;
#else
- addr = ((u_long)*(u_short *)ap << 16) |
- (u_long)*(u_short *)(ap + 2);
+ addr = ((u_int32)*(u_short *)ap << 16) |
+ (u_int32)*(u_short *)(ap + 2);
#endif
break;
default:
#if BYTE_ORDER == LITTLE_ENDIAN
- addr = ((u_long)ap[0] << 24) |
- ((u_long)ap[1] << 16) |
- ((u_long)ap[2] << 8) |
- (u_long)ap[3];
+ addr = ((u_int32)ap[0] << 24) |
+ ((u_int32)ap[1] << 16) |
+ ((u_int32)ap[2] << 8) |
+ (u_int32)ap[3];
#else
- addr = ((u_long)ap[3] << 24) |
- ((u_long)ap[2] << 16) |
- ((u_long)ap[1] << 8) |
- (u_long)ap[0];
+ addr = ((u_int32)ap[3] << 24) |
+ ((u_int32)ap[2] << 16) |
+ ((u_int32)ap[1] << 8) |
+ (u_int32)ap[0];
#endif
break;
}
#endif
- p = &hnametable[addr & (HASHNAMESIZE-1)];
+ p = &hnametable[addr & (HASHNAMESIZE-1)];
for (; p->nxt; p = p->nxt) {
if (p->addr == addr)
return (p->name);
@@ -183,8 +209,8 @@ getname(ap)
/*
* Only print names when:
- * (1) -n was not given.
- * (2) Address is foreign and -f was given. If -f was not
+ * (1) -n was not given.
+ * (2) Address is foreign and -f was given. If -f was not
* present, f_netmask and f_local are 0 and the second
* test will succeed.
* (3) The host portion is not 0 (i.e., a network address).
@@ -198,14 +224,12 @@ getname(ap)
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
(void)alarm(0);
if (hp) {
- char *index();
- char *dotp;
- u_int len = strlen(hp->h_name) + 1;
- p->name = (char *)malloc(len);
- (void)strcpy(p->name, hp->h_name);
+ char *dotp;
+
+ p->name = savestr(hp->h_name);
if (Nflag) {
/* Remove domain qualifications */
- dotp = index(p->name, '.');
+ dotp = strchr(p->name, '.');
if (dotp)
*dotp = 0;
}
@@ -214,8 +238,7 @@ getname(ap)
}
}
cp = intoa(addr);
- p->name = (char *)malloc((unsigned)(strlen(cp) + 1));
- (void)strcpy(p->name, cp);
+ p->name = savestr(cp);
return (p->name);
}
@@ -225,8 +248,7 @@ static char hex[] = "0123456789abcdef";
/* Find the hash node that corresponds the ether address 'ep'. */
static inline struct enamemem *
-lookup_emem(ep)
- u_char *ep;
+lookup_emem(const u_char *ep)
{
register u_int i, j, k;
struct enamemem *tp;
@@ -251,9 +273,73 @@ lookup_emem(ep)
return tp;
}
+/* Find the hash node that corresponds the NSAP 'nsap'. */
+
+static inline struct enamemem *
+lookup_nsap(register const u_char *nsap)
+{
+ register u_int i, j, k;
+ int nlen = *nsap;
+ struct enamemem *tp;
+ const u_char *ensap = nsap + nlen - 6;
+
+ if (nlen > 6) {
+ k = (ensap[0] << 8) | ensap[1];
+ j = (ensap[2] << 8) | ensap[3];
+ i = (ensap[4] << 8) | ensap[5];
+ }
+ else
+ i = j = k = 0;
+
+ tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->e_nxt)
+ if (tp->e_addr0 == i &&
+ tp->e_addr1 == j &&
+ tp->e_addr2 == k &&
+ tp->e_nsap[0] == nlen &&
+ bcmp((char *)&(nsap[1]),
+ (char *)&(tp->e_nsap[1]), nlen) == 0)
+ return tp;
+ else
+ tp = tp->e_nxt;
+ tp->e_addr0 = i;
+ tp->e_addr1 = j;
+ tp->e_addr2 = k;
+ tp->e_nsap = (u_char *) calloc(1, nlen + 1);
+ bcopy(nsap, tp->e_nsap, nlen + 1);
+ tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+
+ return tp;
+}
+
+/* Find the hash node that corresponds the protoid 'pi'. */
+
+static inline struct protoidmem *
+lookup_protoid(const u_char *pi)
+{
+ register u_int i, j;
+ struct protoidmem *tp;
+
+ /* 5 octets won't be aligned */
+ i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
+ j = (pi[3] << 8) + pi[4];
+ /* XXX should be endian-insensitive, but do big-endian testing XXX */
+
+ tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->p_nxt)
+ if (tp->p_oui == i && tp->p_proto == j)
+ return tp;
+ else
+ tp = tp->p_nxt;
+ tp->p_oui = i;
+ tp->p_proto = j;
+ tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
+
+ return tp;
+}
+
char *
-etheraddr_string(ep)
- register u_char *ep;
+etheraddr_string(register const u_char *ep)
{
register u_int i, j;
register char *cp;
@@ -261,25 +347,24 @@ etheraddr_string(ep)
tp = lookup_emem(ep);
if (tp->e_name)
- return tp->e_name;
-
+ return (tp->e_name);
#ifdef ETHER_SERVICE
if (!nflag) {
- cp = ETHER_ntohost(ep);
- if (cp) {
- tp->e_name = cp;
- return cp;
+ char buf[128];
+ if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) {
+ tp->e_name = savestr(buf);
+ return (buf);
}
}
-#endif
+#endif
tp->e_name = cp = (char *)malloc(sizeof("00:00:00:00:00:00"));
- if (j = *ep >> 4)
+ if ((j = *ep >> 4) != 0)
*cp++ = hex[j];
*cp++ = hex[*ep++ & 0xf];
for (i = 5; (int)--i >= 0;) {
*cp++ = ':';
- if (j = *ep >> 4)
+ if ((j = *ep >> 4) != 0)
*cp++ = hex[j];
*cp++ = hex[*ep++ & 0xf];
}
@@ -288,8 +373,7 @@ etheraddr_string(ep)
}
char *
-etherproto_string(port)
- u_short port;
+etherproto_string(u_short port)
{
register char *cp;
register struct hnamemem *tp;
@@ -313,11 +397,82 @@ etherproto_string(port)
}
char *
-tcpport_string(port)
- u_short port;
+protoid_string(register const u_char *pi)
+{
+ register u_int i, j;
+ register char *cp;
+ register struct protoidmem *tp;
+
+ tp = lookup_protoid(pi);
+ if (tp->p_name)
+ return tp->p_name;
+
+ tp->p_name = cp = (char *)malloc(sizeof("00:00:00:00:00"));
+
+ if ((j = *pi >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*pi++ & 0xf];
+ for (i = 4; (int)--i >= 0;) {
+ *cp++ = ':';
+ if ((j = *pi >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*pi++ & 0xf];
+ }
+ *cp = '\0';
+ return (tp->p_name);
+}
+
+char *
+llcsap_string(u_char sap)
+{
+ register char *cp;
+ register struct hnamemem *tp;
+ register u_long i = sap;
+
+ for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->name = cp = (char *)malloc(sizeof("sap 00"));
+ tp->addr = i;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof (*tp));
+
+ (void)strcpy(cp, "sap ");
+ cp += strlen(cp);
+ *cp++ = hex[sap >> 4 & 0xf];
+ *cp++ = hex[sap & 0xf];
+ *cp++ = '\0';
+ return (tp->name);
+}
+
+char *
+isonsap_string(const u_char *nsap)
+{
+ register u_int i, nlen = nsap[0];
+ register char *cp;
+ register struct enamemem *tp;
+
+ tp = lookup_nsap(nsap);
+ if (tp->e_name)
+ return tp->e_name;
+
+ tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
+
+ nsap++;
+ *cp++ = '/';
+ for (i = nlen; (int)--i >= 0;) {
+ *cp++ = hex[*nsap >> 4];
+ *cp++ = hex[*nsap++ & 0xf];
+ }
+ *cp = '\0';
+ return (tp->e_name);
+}
+
+char *
+tcpport_string(u_short port)
{
register struct hnamemem *tp;
- register int i = port;
+ register u_long i = port;
for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
if (tp->addr == i)
@@ -332,11 +487,10 @@ tcpport_string(port)
}
char *
-udpport_string(port)
- register u_short port;
+udpport_string(register u_short port)
{
register struct hnamemem *tp;
- register int i = port;
+ register u_long i = port;
for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
if (tp->addr == i)
@@ -352,15 +506,15 @@ udpport_string(port)
}
static void
-init_servarray()
+init_servarray(void)
{
struct servent *sv;
register struct hnamemem *table;
register int i;
- while (sv = getservent()) {
- NTOHS(sv->s_port);
- i = sv->s_port & (HASHNAMESIZE-1);
+ while ((sv = getservent()) != NULL) {
+ int port = ntohs(sv->s_port);
+ i = port & (HASHNAMESIZE-1);
if (strcmp(sv->s_proto, "tcp") == 0)
table = &tporttable[i];
else if (strcmp(sv->s_proto, "udp") == 0)
@@ -373,45 +527,24 @@ init_servarray()
if (nflag) {
char buf[32];
- (void)sprintf(buf, "%d", sv->s_port);
- table->name = (char *)malloc((unsigned)strlen(buf)+1);
- (void)strcpy(table->name, buf);
- } else {
- table->name =
- (char *)malloc((unsigned)strlen(sv->s_name)+1);
- (void)strcpy(table->name, sv->s_name);
- }
- table->addr = sv->s_port;
+ (void)sprintf(buf, "%d", port);
+ table->name = savestr(buf);
+ } else
+ table->name = savestr(sv->s_name);
+ table->addr = port;
table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
}
endservent();
}
-#include "etherproto.h"
-
-/* Static data base of ether protocol types. */
-struct eproto eproto_db[] = {
- { "pup", ETHERTYPE_PUP },
- { "xns", ETHERTYPE_NS },
- { "ip", ETHERTYPE_IP },
- { "arp", ETHERTYPE_ARP },
- { "rarp", ETHERTYPE_REVARP },
- { "sprite", ETHERTYPE_SPRITE },
- { "mopdl", ETHERTYPE_MOPDL },
- { "moprc", ETHERTYPE_MOPRC },
- { "decnet", ETHERTYPE_DN },
- { "lat", ETHERTYPE_LAT },
- { "lanbridge", ETHERTYPE_LANBRIDGE },
- { "vexp", ETHERTYPE_VEXP },
- { "vprod", ETHERTYPE_VPROD },
- { "atalk", ETHERTYPE_ATALK },
- { "atalkarp", ETHERTYPE_AARP },
- { "loopback", ETHERTYPE_LOOPBACK },
- { (char *)0, 0 }
-};
+/*XXX from libbpfc.a */
+extern struct eproto {
+ char *s;
+ u_short p;
+} eproto_db[];
static void
-init_eprotoarray()
+init_eprotoarray(void)
{
register int i;
register struct hnamemem *table;
@@ -427,26 +560,118 @@ init_eprotoarray()
}
}
+/*
+ * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
+ * types.
+ */
static void
-init_etherarray()
+init_protoidarray(void)
{
-#ifndef ETHER_SERVICE
- FILE *fp;
- struct etherent *ep;
- struct enamemem *tp;
+ register int i;
+ register struct protoidmem *tp;
+ u_char protoid[5];
- fp = fopen(ETHERS_FILE, "r");
- if (fp == 0)
- /* No data base; will have to settle for
- numeric addresses. */
- return;
+ protoid[0] = 0;
+ protoid[1] = 0;
+ protoid[2] = 0;
+ for (i = 0; eproto_db[i].s; i++) {
+ u_short etype = htons(eproto_db[i].p);
+ bcopy((char *)&etype, (char *)&protoid[3], 2);
+ tp = lookup_protoid(protoid);
+ tp->p_name = savestr(eproto_db[i].s);
+ }
+}
- while (ep = next_etherent(fp)) {
- tp = lookup_emem(ep->addr);
- tp->e_name = (char *)malloc((unsigned)strlen(ep->name)+1);
- strcpy(tp->e_name, ep->name);
+static struct etherlist {
+ u_char addr[6];
+ char *name;
+} etherlist[] = {
+ {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
+ {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
+};
+
+/*
+ * Initialize the ethers hash table. We take two different approaches
+ * depending on whether or not the system provides the ethers name
+ * service. If it does, we just wire in a few names at startup,
+ * and etheraddr_string() fills in the table on demand. If it doesn't,
+ * then we suck in the entire /etc/ethers file at startup. The idea
+ * is that parsing the local file will be fast, but spinning through
+ * all the ethers entries via NIS & next_etherent might be very slow.
+ *
+ * XXX pcap_next_etherent doesn't belong in the pcap interface, but
+ * since the pcap module already does name-to-address translation,
+ * it's already does most of the work for the ethernet address-to-name
+ * translation, so we just pcap_next_etherent as a convenience.
+ */
+static void
+init_etherarray(void)
+{
+ register struct etherlist *el;
+ register struct enamemem *tp;
+#ifndef ETHER_SERVICE
+ register struct pcap_etherent *ep;
+ register FILE *fp;
+
+ /* Suck in entire ethers file */
+ fp = fopen(PCAP_ETHERS_FILE, "r");
+ if (fp != NULL) {
+ while ((ep = pcap_next_etherent(fp)) != NULL) {
+ tp = lookup_emem(ep->addr);
+ tp->e_name = savestr(ep->name);
+ }
+ (void)fclose(fp);
}
#endif
+
+ /* Hardwire some ethernet names */
+ for (el = etherlist; el->name != NULL; ++el) {
+#ifdef ETHER_SERVICE
+ /* Use yp/nis version of name if available */
+ char wrk[256];
+ if (ether_ntohost(wrk, (struct ether_addr *)el->addr) == 0) {
+ tp = lookup_emem(el->addr);
+ tp->e_name = savestr(wrk);
+ }
+#else
+ /* install if not already present */
+ tp = lookup_emem(el->addr);
+ if (tp->e_name == NULL)
+ tp->e_name = el->name;
+#endif
+
+ }
+}
+
+static struct token llcsap_db[] = {
+ { LLCSAP_NULL, "null" },
+ { LLCSAP_8021B_I, "802.1b-gsap" },
+ { LLCSAP_8021B_G, "802.1b-isap" },
+ { LLCSAP_IP, "ip-sap" },
+ { LLCSAP_PROWAYNM, "proway-nm" },
+ { LLCSAP_8021D, "802.1d" },
+ { LLCSAP_RS511, "eia-rs511" },
+ { LLCSAP_ISO8208, "x.25/llc2" },
+ { LLCSAP_PROWAY, "proway" },
+ { LLCSAP_ISONS, "iso-clns" },
+ { LLCSAP_GLOBAL, "global" },
+ { 0, NULL }
+};
+
+static void
+init_llcsaparray(void)
+{
+ register int i;
+ register struct hnamemem *table;
+
+ for (i = 0; llcsap_db[i].s != NULL; i++) {
+ table = &llcsaptable[llcsap_db[i].v];
+ while (table->name)
+ table = table->nxt;
+ table->name = llcsap_db[i].s;
+ table->addr = llcsap_db[i].v;
+ table->nxt = (struct hnamemem *)calloc(1, sizeof(*table));
+ }
}
/*
@@ -456,10 +681,7 @@ init_etherarray()
* of the local network. mask is its subnet mask.
*/
void
-init_addrtoname(fflag, localnet, mask)
- int fflag;
- u_long localnet;
- u_long mask;
+init_addrtoname(int fflag, u_int32 localnet, u_int32 mask)
{
netmask = mask;
if (fflag) {
@@ -475,4 +697,26 @@ init_addrtoname(fflag, localnet, mask)
init_etherarray();
init_servarray();
init_eprotoarray();
+ init_llcsaparray();
+ init_protoidarray();
+}
+
+char *
+dnaddr_string(u_short dnaddr)
+{
+ register struct hnamemem *tp;
+
+ for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
+ tp = tp->nxt)
+ if (tp->addr == dnaddr)
+ return (tp->name);
+
+ tp->addr = dnaddr;
+ tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
+ if (nflag)
+ tp->name = dnnum_string(dnaddr);
+ else
+ tp->name = dnname_string(dnaddr);
+
+ return(tp->name);
}
OpenPOWER on IntegriCloud