📄 addrtoname.c
字号:
/* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * 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 */#ifndef lintstatic const char rcsid[] = "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.69.2.1 2001/01/17 18:29:58 guy Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>
#ifndef WIN32
#include <sys/socket.h>#include <sys/time.h>#else
#include <winsock2.h>
#include "bittypes.h"
#ifdef HAVE_ADDRINFO
#include <ws2tcpip.h>
#include <tpipv6.h>
#else
/* in6_addr is already defined in ws2tcpip.h */
struct in6_addr {
u_char s6_addr[16]; /* IPv6 address */
};
#endif /* HAVE_ADDRINFO */
#define INET6_ADDRSTRLEN 46
#include "missing/bittypes.h"
#ifdef HAVE_ADDRINFO
/*
* only member h_name of struct hostent is valid.
*/
static struct hostent * w32gethostbyaddr(const char * addr, int len, int type)
{
static struct hostent host;
static char hostbuf[NI_MAXHOST];
char hname[NI_MAXHOST];
struct sockaddr_in6 addr6;
host.h_name = hostbuf;
switch (type) {
case AF_INET:
return gethostbyaddr(addr, len, type);
break;
case AF_INET6:
memset(&addr6, 0, sizeof(addr6));
addr6.sin6_family = AF_INET6;
memcpy(&addr6.sin6_addr, addr, len);
if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6),
hname, sizeof(hname),
NULL, 0,
0)) {
return NULL;
} else {
strcpy(host.h_name, hname);
return &host;
}
break;
default:
return NULL;
}
}
#endif /* HAVE_ADDRINFO */
#endif /* WIN32 */
struct mbuf;struct rtentry;#ifndef WIN32
#include <net/if.h>
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IF_ETHER_H#include <netinet/if_ether.h>#endif#ifndef WIN32
#include <arpa/inet.h>
#endif
#include <ctype.h>#include <netdb.h>#include <pcap.h>#include <pcap-namedb.h>#include <signal.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include "interface.h"#include "addrtoname.h"#include "llc.h"#include "savestr.h"#include "setsignal.h"/* Forwards */static RETSIGTYPE nohostname(int);/* * hash tables for whatever-to-name translations */#define HASHNAMESIZE 4096struct hnamemem { u_int32_t addr; char *name; struct hnamemem *nxt;};struct hnamemem hnametable[HASHNAMESIZE];struct hnamemem tporttable[HASHNAMESIZE];struct hnamemem uporttable[HASHNAMESIZE];struct hnamemem eprototable[HASHNAMESIZE];struct hnamemem dnaddrtable[HASHNAMESIZE];struct hnamemem llcsaptable[HASHNAMESIZE];#ifdef INET6struct h6namemem { struct in6_addr addr; char *name; struct h6namemem *nxt;};struct h6namemem h6nametable[HASHNAMESIZE];#endif /* INET6 */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_int32_t 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(u_int32_t addr){ register char *cp; register u_int byte; register 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_int32_t f_netmask;static u_int32_t f_localnet;static u_int32_t netmask;/* * "getname" is written in this atrocious way to make sure we don't * wait forever while trying to get hostnames from yp. */#include <setjmp.h>jmp_buf getname_env;static RETSIGTYPEnohostname(int signo){ longjmp(getname_env, 1);}/* * 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){ register struct hostent *hp; u_int32_t addr; static struct hnamemem *p; /* static for longjmp() */#ifndef LBL_ALIGN addr = *(const u_int32_t *)ap;#else memcpy(&addr, ap, sizeof(addr));#endif 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 * 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 && (addr & f_netmask) == f_localnet && (aflag || !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) { if (!setjmp(getname_env)) {#ifndef WIN32
(void)setsignal(SIGALRM, nohostname);
(void)alarm(20);
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
(void)alarm(0);
#else
// In Win32 there is no alarm
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
#endif
if (hp) { char *dotp; p->name = savestr(hp->h_name); if (Nflag) { /* Remove domain qualifications */ dotp = strchr(p->name, '.'); if (dotp) *dotp = '\0'; } return (p->name); } } } p->name = savestr(intoa(addr)); return (p->name);}#ifdef INET6/* * 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){ register struct hostent *hp; struct in6_addr addr; static struct h6namemem *p; /* static for longjmp() */ register char *cp; char ntop_buf[INET6_ADDRSTRLEN]; memcpy(&addr, ap, sizeof(addr)); p = &h6nametable[*(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 ) { if (!setjmp(getname_env)) {#ifndef WIN32
(void)setsignal(SIGALRM, nohostname);
(void)alarm(20);
hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
(void)alarm(0);
#else
// In Win32 there is no alarm
#ifdef __MINGW32__
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
#else
hp = w32gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
#endif /* __MINGW32__ */
#endif /* Win32 */
if (hp) { char *dotp; p->name = savestr(hp->h_name); if (Nflag) { /* Remove domain qualifications */ dotp = strchr(p->name, '.'); if (dotp) *dotp = '\0'; } return (p->name); } } } cp = (char *)inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)); p->name = savestr(cp); return (p->name);}#endif /* INET6 */static char hex[] = "0123456789abcdef";/* Find the hash node that corresponds the ether address 'ep' */static inline struct enamemem *lookup_emem(const u_char *ep){ register u_int i, j, k; struct enamemem *tp; k = (ep[0] << 8) | ep[1]; j = (ep[2] << 8) | ep[3]; 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; else tp = tp->e_nxt; tp->e_addr0 = i; tp->e_addr1 = j; tp->e_addr2 = k; tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) error("lookup_emem: calloc"); 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 && memcmp((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 *)malloc(nlen + 1); if (tp->e_nsap == NULL) error("lookup_nsap: malloc"); memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1); tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); if (tp->e_nxt == NULL) error("lookup_nsap: calloc"); 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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -