📄 a2name.c
字号:
/*
* This file has been slightly modified by NRL for use with IPv6+IPsec.
* Search for USE_INET6 and/or IPSEC to see the blocks where this happened.
* See the NRL Copyright notice for conditions on the modifications.
*/
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
* 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
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Internet, ethernet, port, and protocol string to address
* and address to string conversion routines
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <setjmp.h>
#include <signal.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ipv6.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pcap.h>
#include <pc-name.h>
#include "ethertyp.h"
#include "interfac.h"
#include "llc.h"
#include "a2name.h"
extern int snprintf (char *str, size_t count, const char *fmt, ...);
extern struct hostent *_w32_gethostbyaddr6 (const void *addr);
struct eproto {
char *s;
u_short p;
};
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;
};
/*
* hash tables for whatever-to-name translations. Must be 2^n
*/
#define HASHNAMESIZE 4096
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
static struct hnamemem hnametable [HASHNAMESIZE+1];
static struct h6namemem hname6table[HASHNAMESIZE+1];
static struct hnamemem tporttable [HASHNAMESIZE+1];
static struct hnamemem uporttable [HASHNAMESIZE+1];
static struct hnamemem eprototable[HASHNAMESIZE+1];
static struct hnamemem dnaddrtable[HASHNAMESIZE+1];
static struct hnamemem llcsaptable[HASHNAMESIZE+1];
extern struct eproto eproto_db[]; /* in pcap.lib (nametoad.c) */
struct enamemem enametable [HASHNAMESIZE+1];
struct enamemem nsaptable [HASHNAMESIZE+1];
struct protoidmem {
u_int p_oui;
u_short p_proto;
char *p_name;
struct protoidmem *p_nxt;
};
struct protoidmem protoidtable[HASHNAMESIZE];
char *ether_file = "ethers";
char *atalk_file = "atalk";
static char hex[] = "0123456789ABCDEF";
static struct hnamemem *ip4_append0 = NULL;
static struct h6namemem *ip6_append0 = NULL;
#ifdef __DJGPP__
static jmp_buf getname_env; /* jmp_buf for terminating getXbyY() */
#endif
/*
* A faster replacement for inet_ntoa().
*/
char *intoa (u_int addr)
{
char *cp;
u_int byte;
int n;
static char buf [sizeof(".xxx.xxx.xxx.xxx")];
NTOHL (addr);
cp = &buf[sizeof buf];
*--cp = '\0';
n = 4;
do
{
byte = addr & 0xff;
*--cp = byte % 10 + '0';
byte /= 10;
if (byte > 0)
{
*--cp = byte % 10 + '0';
byte /= 10;
if (byte > 0)
*--cp = byte + '0';
}
*--cp = '.';
addr >>= 8;
}
while (--n > 0);
return (cp + 1);
}
static u_int f_netmask;
static u_int f_localnet;
/*
* Return a name for the IP address pointed to by ap. This address
* is assumed to be in network byte order.
*/
char *getname (const u_char *ap)
{
u_long addr = *(const u_long*) ap;
static struct hnamemem *p; /* static for longjmp() */
p = &hnametable [addr & (HASHNAMESIZE-1)];
for (; p->nxt; p = p->nxt)
{
if (p->addr == addr)
return (p->name);
}
p->addr = addr;
p->nxt = newhnamemem();
/*
* Only print names when:
* (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).
* (4) The host portion is not broadcast.
*/
if (!nflag && (addr & f_netmask) == f_localnet &&
(aflag || !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff)))
{
struct hostent *hp = gethostbyaddr ((char*)&addr, sizeof(addr), AF_INET);
if (hp)
{
p->name = savestr (hp->h_name);
if (Hflag)
{
struct hnamemem *a = newhnamemem();
a->name = p->name;
a->addr = addr;
a->nxt = ip4_append0;
ip4_append0 = a;
}
else if (Nflag)
{
/* Remove domain qualifications
*/
char *dotp = strchr (p->name, '.');
if (dotp)
*dotp = '\0';
}
return (p->name);
}
}
p->name = savestr (intoa(addr));
return (p->name);
}
#ifdef USE_INET6
#ifdef __DJGPP__
static void nohostname (int signo)
{
ARGSUSED (signo);
longjmp (getname_env, 1);
}
#endif
/*
* Return a name for the IP6 address pointed to by ap. This address
* is assumed to be in network byte order.
*/
char *getname6 (const u_char *ap)
{
struct hostent *hp;
struct in6_addr addr;
static struct h6namemem *p; /* static for longjmp() */
char *cp, ntop_buf[INET6_ADDRSTRLEN];
memcpy (&addr, ap, sizeof(addr));
p = &hname6table [*(u_int16_t*) &addr.s6_addr[14] & (HASHNAMESIZE-1)];
for (; p->nxt; p = p->nxt)
{
if (memcmp (&p->addr, &addr, sizeof(addr)) == 0)
return (p->name);
}
p->addr = addr;
p->nxt = newh6namemem();
/*
* Only print names when:
* (1) -n was not given.
* (2) Address is foreign and -f was given. (If -f was not
* give, f_netmask and f_local are 0 and the test
* evaluates to true)
* (3) -a was given or the host portion is not all ones
* nor all zeros (i.e. not a network or broadcast address)
*/
if (!nflag
#if 0
&& (addr & f_netmask) == f_localnet
&& (aflag || !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))
#endif
)
{
#ifdef __DJGPP__
if (!setjmp (getname_env))
{
signal (SIGALRM, nohostname);
alarm (10);
hp = _w32_gethostbyaddr6 (&addr);
alarm (0);
#else
hp = _w32_gethostbyaddr6 (&addr);
#endif
if (hp)
{
p->name = savestr (hp->h_name);
if (Nflag)
{
/* Remove domain qualifications */
char *dotp = strchr (p->name, '.');
if (dotp)
*dotp = '\0';
}
p->nxt = ip6_append0;
ip6_append0 = p;
return (p->name);
}
#ifdef __DJGPP__
}
#endif
}
cp = (char*) inet_ntop (AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
p->name = savestr (cp);
return (p->name);
}
#endif
/*
* Find the hash node that corresponds the ether address 'ep'
*/
static struct enamemem *lookup_emem (const u_char * ep)
{
struct enamemem *tp;
u_int k = (ep[0] << 8) | ep[1];
u_int j = (ep[2] << 8) | ep[3];
u_int i = (ep[4] << 8) | ep[5];
tp = &enametable [(i ^ j) & (HASHNAMESIZE-1)];
while (tp->e_nxt)
{
if (tp->e_addr0 == i &&
tp->e_addr1 == j &&
tp->e_addr2 == k)
return (tp);
tp = tp->e_nxt;
}
tp->e_addr0 = i;
tp->e_addr1 = j;
tp->e_addr2 = k;
tp->e_nxt = calloc (1, sizeof(*tp));
if (!tp->e_nxt)
{
PERROR (("lookup_emem: calloc"));
/* not reached */
}
return (tp);
}
/*
* Find the hash node that corresponds the NSAP 'nsap'
*/
static struct enamemem *lookup_nsap (const u_char * nsap)
{
struct enamemem *tp;
u_int i, j, k;
int nlen = *nsap;
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 &&
!memcmp (&nsap[1], &tp->e_nsap[1], nlen))
return (tp);
tp = tp->e_nxt;
}
tp->e_addr0 = i;
tp->e_addr1 = j;
tp->e_addr2 = k;
tp->e_nsap = malloc (nlen + 1);
if (!tp->e_nsap)
{
PERROR (("lookup_nsap: malloc"));
/* not reached */
}
memcpy (tp->e_nsap, nsap, nlen + 1);
tp->e_nxt = calloc (1, sizeof(*tp));
if (!tp->e_nxt)
{
PERROR (("lookup_nsap: calloc"));
/* not reached */
}
return (tp);
}
/*
* Find the hash node that corresponds the protoid 'pi'.
*/
static struct protoidmem *lookup_protoid (const u_char * pi)
{
struct protoidmem *tp;
u_int i, j;
/* 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 */
tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
while (tp->p_nxt)
{
if (tp->p_oui == i && tp->p_proto == j)
return (tp);
tp = tp->p_nxt;
}
tp->p_oui = i;
tp->p_proto = j;
tp->p_nxt = calloc (1, sizeof(*tp));
if (!tp->p_nxt)
{
PERROR (("lookup_protoid: calloc"));
/* not reached */
}
return (tp);
}
char *etheraddr_string (const u_char *ep)
{
struct enamemem *tp;
char *cp, buf [sizeof("00:00:00:00:00:00")];
u_int i, j;
tp = lookup_emem (ep);
if (tp->e_name)
return (tp->e_name);
cp = buf;
if ((j = *ep >> 4) != 0)
*cp++ = hex[j];
*cp++ = hex[*ep++ & 0xf];
for (i = 5; (int) --i >= 0;)
{
*cp++ = ':';
if ((j = *ep >> 4) != 0)
*cp++ = hex[j];
*cp++ = hex[*ep++ & 0xf];
}
*cp = '\0';
tp->e_name = savestr (buf);
return (tp->e_name);
}
char *etherproto_string (u_short port)
{
struct hnamemem *tp;
char *cp, buf [sizeof("0000")];
u_int i = port;
for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
if (tp->addr == i)
return (tp->name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -