⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 a2name.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -