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

📄 _ospf6.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 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.
 *
 * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
 */

#if 0
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.2 1999/11/21 09:36:58 fenner Exp $ (LBL)";
#endif

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>

#include "interfac.h"
#include "a2name.h"
#include "ospf6.h"

#ifdef USE_INET6

struct bits {
       u_int32_t   bit;
       const char *str;
     };

static const struct bits ospf6_option_bits[] = {
  { OSPF6_OPTION_V6, "V6" },
  { OSPF6_OPTION_E,  "E"  },
  { OSPF6_OPTION_MC, "MC" },
  { OSPF6_OPTION_N,  "N"  },
  { OSPF6_OPTION_R,  "R"  },
  { OSPF6_OPTION_DC, "DC" },
  { 0,               NULL }
};

static const struct bits ospf6_rla_flag_bits[] = {
  { RLA_FLAG_B, "B"  },
  { RLA_FLAG_E, "E"  },
  { RLA_FLAG_V, "V"  },
  { RLA_FLAG_W, "W"  },
  { 0,          NULL }
};

static struct tok type2str[] = {
  { OSPF_TYPE_UMD,  "umd"    },
  { OSPF_TYPE_HELLO,"hello"  },
  { OSPF_TYPE_DB,   "dd"     },
  { OSPF_TYPE_LSR,  "ls_req" },
  { OSPF_TYPE_LSU,  "ls_upd" },
  { OSPF_TYPE_LSA,  "ls_ack" },
  { 0,              NULL     }
};

static char tstr[] = " [|ospf]";

/* Forwards */
static void ospf6_print_seqage (u_int32_t, time_t);
static void ospf6_print_bits   (const struct bits *, u_char);
static int  ospf6_print_lshdr  (const struct lsa_hdr *);
static int  ospf6_print_lsa    (const struct lsa *);
static int  ospf6_decode_v3    (const struct ospf6hdr *, const u_char *);
static void ospf6_print_ls_type(u_int, const rtrid_t *, const rtrid_t *, const char *);

static void ospf6_print_seqage (u_int32_t seq, time_t us)
{
  time_t sec  = us % 60;
  time_t mins = (us / 60) % 60;
  time_t hour = us / 3600;

  PRINTF (" S %X age ", seq);
  if (hour)
       PRINTF ("%lu:%02lu:%02lu", (u_int32_t)hour, (u_int32_t)mins, (u_int32_t)sec);
  else if (mins)
       PRINTF ("%lu:%02lu", (u_int32_t)mins, (u_int32_t)sec);
  else PRINTF ("%lu", (u_int32_t) sec);
}


static void ospf6_print_bits (const struct bits *bp, u_char options)
{
  char sep = ' ';

  do
  {
    if (options & bp->bit)
    {
      PRINTF ("%c%s", sep, bp->str);
      sep = '/';
    }
  }
  while ((++bp)->bit);
}

static void ospf6_print_ls_type (u_int          ls_type,
                                 const rtrid_t *ls_stateid,
                                 const rtrid_t *ls_router,
                                 const char    *fmt)
{
  char *scope;

  switch (ls_type & LS_SCOPE_MASK)
  {
    case LS_SCOPE_LINKLOCAL:
         scope = "linklocal-";
         break;
    case LS_SCOPE_AREA:
         scope = "area-";
         break;
    case LS_SCOPE_AS:
         scope = "AS-";
         break;
    default:
         scope = "";
         break;
  }

  switch (ls_type & LS_TYPE_MASK)
  {
    case LS_TYPE_ROUTER:
         PRINTF (" %srtr %s", scope, ipaddr_string (ls_router));
         break;

    case LS_TYPE_NETWORK:
         PRINTF (" %snet dr %s if %s", scope,
                 ipaddr_string (ls_router), ipaddr_string (ls_stateid));
         break;

    case LS_TYPE_INTER_AP:
         PRINTF (" %sinter-area-prefix %s abr %s", scope,
                 ipaddr_string (ls_stateid), ipaddr_string (ls_router));
         break;

    case LS_TYPE_INTER_AR:
         PRINTF (" %sinter-area-router %s rtr %s", scope,
                 ipaddr_string (ls_router), ipaddr_string (ls_stateid));
         break;

    case LS_TYPE_ASE:
         PRINTF (" %sase %s asbr %s", scope,
                 ipaddr_string (ls_stateid), ipaddr_string (ls_router));
         break;

    case LS_TYPE_GROUP:
         PRINTF (" %sgroup %s rtr %s", scope,
                 ipaddr_string (ls_stateid), ipaddr_string (ls_router));
         break;

    case LS_TYPE_TYPE7:
         PRINTF (" %stype7 %s rtr %s", scope,
                 ipaddr_string (ls_stateid), ipaddr_string (ls_router));
         break;

    case LS_TYPE_LINK:
         PRINTF (" %slink %s rtr %s", scope,
                 ipaddr_string (ls_stateid), ipaddr_string (ls_router));
         break;

    case LS_TYPE_INTRA_AP:
         PRINTF (" %sintra-area-prefix %s rtr %s", scope,
                 ipaddr_string (ls_stateid), ipaddr_string (ls_router));
         break;

    default:
         PRINTF (" %s", scope);
         PRINTF (fmt, ls_type);
         break;
  }
}

static int ospf6_print_lshdr (const struct lsa_hdr *lshp)
{
  TCHECK (lshp->ls_type);
  PUTS (" {");                /* } (ctags) */

  TCHECK (lshp->ls_seq);
  ospf6_print_seqage (ntohl (lshp->ls_seq), ntohs (lshp->ls_age));
  ospf6_print_ls_type (ntohs (lshp->ls_type), &lshp->ls_stateid,
                       &lshp->ls_router, "ls_type %d");
  return (0);
trunc:
  return (1);
}

static int ospf6_print_lsaprefix (const struct lsa_prefix *lsapp)
{
  struct in6_addr prefix;
  int    k;

  TCHECK (*lsapp);
  k = (lsapp->lsa_p_len + 31) / 32;
  if (k * 4 > sizeof(struct in6_addr))
  {
    PRINTF ("??prefixlen %d??", lsapp->lsa_p_len);
    goto trunc;
  }
  memset (&prefix, 0, sizeof(prefix));
  memcpy (&prefix, lsapp->lsa_p_prefix, k * 4);
  PRINTF (" %s/%d", ip6addr_string (&prefix), lsapp->lsa_p_len);
  if (lsapp->lsa_p_opt)
     PRINTF ("(opt=%x)", lsapp->lsa_p_opt);
  return (sizeof(*lsapp) - 4 + k * 4);

trunc:
  return -1;
}


/*
 * Print a single link state advertisement.  If truncated return 1, else 0.
 */
static int ospf6_print_lsa (const struct lsa *lsap)
{
  const struct rlalink *rlp;
  const u_char         *ls_end;
#if 0
  const struct tos_metric *tosp;
  const struct aslametric *almp;
  const struct mcla       *mcp;
  const u_int32_t         *lp;
#endif
  const rtrid_t *ap;
  const struct llsa *llsap;
  const struct lsa_prefix *lsapp;
  int   j, k;

  if (ospf6_print_lshdr (&lsap->ls_hdr))
     return (1);

  TCHECK (lsap->ls_hdr.ls_length);
  ls_end = (u_char *) lsap + ntohs (lsap->ls_hdr.ls_length);
  switch (ntohs (lsap->ls_hdr.ls_type))
  {
    case LS_TYPE_ROUTER | LS_SCOPE_AREA:
         TCHECK (lsap->lsa_un.un_rla.rla_flags);
         ospf6_print_bits (ospf6_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags);
         TCHECK (lsap->lsa_un.un_rla.rla_options);
         ospf6_print_bits (ospf6_option_bits, ntohl (lsap->lsa_un.un_rla.rla_options));

         TCHECK (lsap->lsa_un.un_rla.rla_link);
         rlp = lsap->lsa_un.un_rla.rla_link;
         while (rlp + sizeof(*rlp) <= (struct rlalink *) ls_end)
         {
           TCHECK (*rlp);
           PUTS (" {");        /* } (ctags) */
           switch (rlp->link_type)
           {
             case RLA_TYPE_VIRTUAL:
                  PUTS (" virt");
                  /* Fall through */

             case RLA_TYPE_ROUTER:
                  PRINTF (" nbrid %s nbrif %s if %s",
                          ipaddr_string (&rlp->link_nrtid),
                          ipaddr_string (&rlp->link_nifid),
                          ipaddr_string (&rlp->link_ifid));
                  break;

             case RLA_TYPE_TRANSIT:
                  PRINTF (" dr %s drif %s if %s",
                          ipaddr_string (&rlp->link_nrtid),
                          ipaddr_string (&rlp->link_nifid),
                          ipaddr_string (&rlp->link_ifid));
                  break;

             default:
                  /* { (ctags) */
                  PRINTF (" ??RouterLinksType 0x%02x?? }", rlp->link_type);
                  return (0);
           }
           PRINTF (" metric %d", ntohs (rlp->link_metric));
           /* { (ctags) */
           PUTS (" }");
           rlp++;
         }
         break;

    case LS_TYPE_NETWORK | LS_SCOPE_AREA:
         TCHECK (lsap->lsa_un.un_nla.nla_options);
         ospf6_print_bits (ospf6_option_bits,
                           ntohl (lsap->lsa_un.un_nla.nla_options));
         PUTS (" rtrs");
         ap = lsap->lsa_un.un_nla.nla_router;
         while ((u_char *) ap < ls_end)
         {
           TCHECK (*ap);
           PRINTF (" %s", ipaddr_string (ap));
           ++ap;
         }
         break;

    case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
         TCHECK (lsap->lsa_un.un_inter_ap.inter_ap_metric);
         PRINTF (" metric %lu",
                 ntohl (lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);
         lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix;
         while (lsapp + sizeof(lsapp) <= (struct lsa_prefix *) ls_end)
         {
           k = ospf6_print_lsaprefix (lsapp);
           if (k < 0)

⌨️ 快捷键说明

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