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

📄 _isakmp.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project 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 BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#if 0
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.8.2.1 2000/01/14 19:19:56 mcr Exp $ (LBL)";
#endif

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>

#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/ipv6.h>

#include <netdb.h>

#include "isakmp.h"
#include "ipsec_do.h"
#include "oakley.h"
#include "interfac.h"
#include "a2name.h"
#include "extract.h"            /* must come after interface.h */

#ifndef HAVE_SOCKADDR_STORAGE
#define sockaddr_storage sockaddr
#endif

static u_char *isakmp_sa_print    (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_p_print     (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_t_print     (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_ke_print    (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_id_print    (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_hash_print  (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_nonce_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_n_print     (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_d_print     (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_vid_print   (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_sub0_print  (u_char, struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_sub_print   (u_char, struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static char   *numstr (int);

#define MAXINITIATORS 20
int ninitiator = 0;

static struct {
       cookie_t                initiator;
       struct sockaddr_storage iaddr;
       struct sockaddr_storage raddr;
     } cookiecache [MAXINITIATORS];

/* protocol id
 */
static char *protoidstr[] = {
            NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
};

/* isakmp->np
 */
static char *npstr[] = {
            "none", "sa", "p", "t", "ke", "id", "cert", "cr",
            "hash", "sig", "nonce", "n", "d", "vid"
          };

/* isakmp->np
 */
static u_char *(*npfunc[]) (struct isakmp_gen*, u_char*,
                            u_int32_t, u_int32_t, u_int32_t) = {
                NULL,
                isakmp_sa_print,
                isakmp_p_print,
                isakmp_t_print,
                isakmp_ke_print,
                isakmp_id_print,
                NULL,
                NULL,
                isakmp_hash_print,
                NULL,
                isakmp_nonce_print,
                isakmp_n_print,
                isakmp_d_print,
                isakmp_vid_print
              };

/* isakmp->etype
 */
static char *etypestr[] = {
            "none", "base", "ident", "auth", "agg", "inf", NULL, NULL,
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
            "oakley-quick", "oakley-newgroup",
          };

#define STR_OR_ID(x, tab) (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? \
                           tab[(x)] : numstr(x))

#define PROTOIDSTR(x)  STR_OR_ID(x, protoidstr)
#define NPSTR(x)       STR_OR_ID(x, npstr)
#define ETYPESTR(x)    STR_OR_ID(x, etypestr)

#define NPFUNC(x) (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) ? \
                   npfunc[(x)] : NULL)

static int iszero (u_char * p, size_t l)
{
  while (l--)
  {
    if (*p++)
      return 0;
  }
  return 1;
}

/*
 * find cookie from initiator cache
 */
static int cookie_find (cookie_t * in)
{
  int i;

  for (i = 0; i < MAXINITIATORS; i++)
  {
    if (!memcmp (in, &cookiecache[i].initiator, sizeof(*in)))
       return i;
  }
  return -1;
}

/*
 * record initiator
 */
static void cookie_record (cookie_t * in, const u_char * bp2)
{
  struct ip          *ip;
  struct sockaddr_in *sin;
  int    i;

#ifdef USE_INET6
  struct ipv6hdr      *ip6;
  struct sockaddr_in6 *sin6;
#endif

  i = cookie_find (in);
  if (0 <= i)
  {
    ninitiator = (i + 1) % MAXINITIATORS;
    return;
  }

  ip = (struct ip *) bp2;
  switch (ip->ip_v)
  {
    case 4:
         memset (&cookiecache[ninitiator].iaddr, 0, sizeof(cookiecache[ninitiator].iaddr));
         memset (&cookiecache[ninitiator].raddr, 0, sizeof(cookiecache[ninitiator].raddr));

         sin = (struct sockaddr_in *) &cookiecache[ninitiator].iaddr;
         sin->sin_family = AF_INET;
         memcpy (&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
         sin = (struct sockaddr_in *) &cookiecache[ninitiator].raddr;
         sin->sin_family = AF_INET;
         memcpy (&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
         break;

#ifdef USE_INET6
    case 6:
         memset (&cookiecache[ninitiator].iaddr, 0, sizeof(cookiecache[ninitiator].iaddr));
         memset (&cookiecache[ninitiator].raddr, 0, sizeof(cookiecache[ninitiator].raddr));

         ip6 = (struct ipv6hdr *) bp2;
         sin6 = (struct sockaddr_in6 *) &cookiecache[ninitiator].iaddr;
         sin6->sin6_family = AF_INET6;
         memcpy (&sin6->sin6_addr, &ip6->ipv6_src, sizeof(ip6->ipv6_src));
         sin6 = (struct sockaddr_in6 *) &cookiecache[ninitiator].raddr;
         sin6->sin6_family = AF_INET6;
         memcpy (&sin6->sin6_addr, &ip6->ipv6_dst, sizeof(ip6->ipv6_dst));
         break;
#endif

    default:
         return;
  }
  memcpy (&cookiecache[ninitiator].initiator, in, sizeof(*in));
  ninitiator = (ninitiator + 1) % MAXINITIATORS;
}

#define cookie_isinitiator(x, y)   cookie_sidecheck((x), (y), 1)
#define cookie_isresponder(x, y)   cookie_sidecheck((x), (y), 0)

static int cookie_sidecheck (int i, const u_char *bp2, int initiator)
{
  struct sockaddr_storage ss;
  struct sockaddr        *sa;
  struct ip              *ip;
  struct sockaddr_in     *sin;

#ifdef USE_INET6
  struct ipv6hdr      *ip6;
  struct sockaddr_in6 *sin6;
#endif
  int salen;

  memset (&ss, 0, sizeof(ss));
  ip = (struct ip *) bp2;

  switch (ip->ip_v)
  {
    case 4:
         sin = (struct sockaddr_in *) &ss;
         sin->sin_family = AF_INET;
         memcpy (&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
         break;

#ifdef USE_INET6
    case 6:
         ip6  = (struct ipv6hdr*) bp2;
         sin6 = (struct sockaddr_in6*) &ss;
         sin6->sin6_family = AF_INET6;
         memcpy (&sin6->sin6_addr, &ip6->ipv6_src, sizeof(ip6->ipv6_src));
         break;
#endif

    default:
         return 0;
  }

  sa = (struct sockaddr *) &ss;
  if (initiator)
  {
    if (sa->sa_family != ((struct sockaddr*)&cookiecache[i].iaddr)->sa_family)
       return 0;

#ifdef USE_INET6
    if (sa->sa_family == AF_INET6)
         salen = sizeof(struct sockaddr_in6);
    else salen = sizeof(struct sockaddr);
#else
    salen = sizeof(struct sockaddr);
#endif
    if (!memcmp (&ss, &cookiecache[i].iaddr, salen))
       return 1;
  }
  else
  {
    if (sa->sa_family != ((struct sockaddr *) &cookiecache[i].raddr)->sa_family)
       return 0;

#ifdef USE_INET6
    if (sa->sa_family == AF_INET6)
         salen = sizeof(struct sockaddr_in6);
    else salen = sizeof(struct sockaddr);
#else
    salen = sizeof(struct sockaddr);
#endif
    if (!memcmp (&ss, &cookiecache[i].raddr, salen))
      return 1;
  }
  return 0;
}

static void rawprint (caddr_t loc, size_t len)
{
  u_char *p = (u_char*) loc;
  int    i;
  for (i = 0; i < len; i++)
      PRINTF ("%02x", p[i] & 0xff);
}

struct attrmap {
       char *type;
       int   nvalue;
       char *value[30];
     };

static u_char *isakmp_attrmap_print (u_char *p, u_char *ep,
                                     struct attrmap *map, size_t nmap)
{
  u_short  *q;
  int       totlen;
  u_int32_t t, v;

  q = (u_short *) p;
  if (p[0] & 0x80)
       totlen = 4;
  else totlen = 4 + ntohs (q[1]);

  if (ep < p + totlen)
  {
    PUTS ("[|attr]");
    return ep + 1;
  }

  PUTCHAR ('(');
  t = ntohs (q[0]) & 0x7fff;
  if (map && t < nmap && map[t].type)
       PRINTF ("type=%s ", map[t].type);
  else PRINTF ("type=#%d ", t);

  if (p[0] & 0x80)
  {
    PUTS ("value=");
    v = ntohs (q[1]);
    if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
         PUTS (map[t].value[v]);
    else rawprint ((caddr_t) & q[1], 2);
  }
  else
  {
    PRINTF ("len=%d value=", ntohs (q[1]));
    rawprint ((caddr_t) & p[4], ntohs (q[1]));
  }
  PUTCHAR (')');
  return p + totlen;
}

static u_char *isakmp_attr_print (u_char * p, u_char * ep)
{
  u_short  *q;
  int       totlen;
  u_int32_t t;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -