📄 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: addrtoname.c,v 1.61 97/06/15 13:20:18 leres Exp $ (LBL)";#endif#include <sys/types.h>#ifndef WIN32
#include <sys/time.h>
#include <sys/socket.h>
#else
#include <winsock.h>
#endif
#if __STDC__struct mbuf;struct rtentry;#endif
#ifndef WIN32
#include <net/if.h>
#include <netinet/in.h>
#endif
#include <netinet/if_ether.h>#ifndef WIN32
#include <arpa/inet.h>#endif
#include <ctype.h>#ifndef WIN32
#include <netdb.h>#else
#include <net/netdb.h>
#endif
#include <pcap.h>#include <pcap-namedb.h>#ifdef HAVE_MALLOC_H#include <malloc.h>#endif#ifdef HAVE_MEMORY_H#include <memory.h>#endif#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];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 /* * Extract 32 bits in network order, dealing with alignment. */ switch ((long)ap & 3) { case 0: addr = *(u_int32_t *)ap; break; case 2:#ifdef WORDS_BIGENDIAN addr = ((u_int32_t)*(u_short *)ap << 16) | (u_int32_t)*(u_short *)(ap + 2);#else addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) | (u_int32_t)*(u_short *)ap;#endif break; default:#ifdef WORDS_BIGENDIAN addr = ((u_int32_t)ap[0] << 24) | ((u_int32_t)ap[1] << 16) | ((u_int32_t)ap[2] << 8) | (u_int32_t)ap[3];#else addr = ((u_int32_t)ap[3] << 24) | ((u_int32_t)ap[2] << 16) | ((u_int32_t)ap[1] << 8) | (u_int32_t)ap[0];#endif break; }#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);}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]; 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)); if (tp->p_nxt == NULL) error("lookup_protoid: calloc"); return tp;}char *etheraddr_string(register const u_char *ep){ register u_int i, j; register char *cp; register struct enamemem *tp; char buf[sizeof("00:00:00:00:00:00")]; tp = lookup_emem(ep); if (tp->e_name) return (tp->e_name);#ifdef HAVE_ETHER_NTOHOST if (!nflag) { char buf[128]; if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { tp->e_name = savestr(buf); return (tp->e_name); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -