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

📄 _bgp.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (C) 1999 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-bgp.c,v 1.9.2.2 2000/01/25 18:32:53 itojun Exp $";
#endif

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

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

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

struct bgp {
       u_int8_t  bgp_marker[16];
       u_int16_t bgp_len;
       u_int8_t  bgp_type;
     };

#define BGP_SIZE          19  /* unaligned */

#define BGP_OPEN          1
#define BGP_UPDATE        2
#define BGP_NOTIFICATION  3
#define BGP_KEEPALIVE     4

struct bgp_open {
       u_int8_t  bgpo_marker[16];
       u_int16_t bgpo_len;
       u_int8_t  bgpo_type;
       u_int8_t  bgpo_version;
       u_int16_t bgpo_myas;
       u_int16_t bgpo_holdtime;
       u_int32_t bgpo_id;
       u_int8_t  bgpo_optlen;
       /* options should follow */
     };

struct bgp_opt {
       u_int8_t bgpopt_type;
       u_int8_t bgpopt_len;
       /* variable length */
     };

struct bgp_notification {
       u_int8_t  bgpn_marker[16];
       u_int16_t bgpn_len;
       u_int8_t  bgpn_type;
       u_int8_t  bgpn_major;
       u_int8_t  bgpn_minor;
       /* data should follow */
     };

struct bgp_attr {
       u_int8_t bgpa_flags;
       u_int8_t bgpa_type;
       union {
         u_int8_t len;
         u_int16_t elen;
     } bgpa_len;
   };
#define bgp_attr_len(p)  (((p)->bgpa_flags & 0x10) ? \
                          ntohs((p)->bgpa_len.elen) : (p)->bgpa_len.len)
#define bgp_attr_off(p)  (((p)->bgpa_flags & 0x10) ? 4 : 3)

#define BGPTYPE_ORIGIN             1
#define BGPTYPE_AS_PATH            2
#define BGPTYPE_NEXT_HOP           3
#define BGPTYPE_MULTI_EXIT_DISC    4
#define BGPTYPE_LOCAL_PREF         5
#define BGPTYPE_ATOMIC_AGGREGATE   6
#define BGPTYPE_AGGREGATOR         7
#define BGPTYPE_COMMUNITIES        8   /* RFC1997 */
#define BGPTYPE_ORIGINATOR_ID      9   /* RFC1998 */
#define BGPTYPE_CLUSTER_LIST       10  /* RFC1998 */
#define BGPTYPE_DPA                11  /* work in progress */
#define BGPTYPE_ADVERTISERS        12  /* RFC1863 */
#define BGPTYPE_RCID_PATH          13  /* RFC1863 */
#define BGPTYPE_MP_REACH_NLRI      14  /* RFC2283 */
#define BGPTYPE_MP_UNREACH_NLRI    15  /* RFC2283 */


static const char *bgptype[] = {
             NULL, "OPEN", "UPDATE", "NOTIFICATION", "KEEPALIVE",
           };

#define bgp_type(x) num_or_str(bgptype, DIM(bgptype), (x))

static const char *bgpopt_type[] = {
             NULL, "Authentication Information",
           };

#define bgp_opttype(x) \
        num_or_str(bgpopt_type, DIM(bgpopt_type), (x))

static const char *bgpnotify_major[] = {
             NULL,
             "Message Header Error",
             "OPEN Message Error",
             "UPDATE Message Error",
             "Hold Timer Expired",
             "Finite State Machine Error",
             "Cease",
           };

#define bgp_notify_major(x) \
        num_or_str (bgpnotify_major, DIM(bgpnotify_major), (x))

static const char *bgpnotify_minor_1[] = {
             NULL,
             "Connection Not Synchronized",
             "Bad Message Length",
             "Bad Message Type",
           };

static const char *bgpnotify_minor_2[] = {
             NULL,
             "Unsupported Version Number",
             "Bad Peer AS",
             "Bad BGP Identifier",
             "Unsupported Optional Parameter",
             "Authentication Failure",
             "Unacceptable Hold Time",
           };

static const char *bgpnotify_minor_3[] = {
             NULL,
             "Malformed Attribute List",
             "Unrecognized Well-known Attribute",
             "Missing Well-known Attribute",
             "Attribute Flags Error",
             "Attribute Length Error",
             "Invalid ORIGIN Attribute",
             "AS Routing Loop",
             "Invalid NEXT_HOP Attribute",
             "Optional Attribute Error",
             "Invalid Network Field",
             "Malformed AS_PATH",
           };

static const char **bgpnotify_minor[] = {
             NULL, bgpnotify_minor_1, bgpnotify_minor_2, bgpnotify_minor_3,
           };

static const int bgpnotify_minor_siz[] = {
             0,
             DIM (bgpnotify_minor_1),
             DIM (bgpnotify_minor_2),
             DIM (bgpnotify_minor_3),
           };

static const char *bgpattr_origin[] = {
             "IGP", "EGP", "INCOMPLETE",
           };

#define bgp_attr_origin(x) \
        num_or_str(bgpattr_origin, DIM(bgpattr_origin), (x))

static const char *bgpattr_type[] = {
             NULL,
             "ORIGIN",
             "AS_PATH",
             "NEXT_HOP",
             "MULTI_EXIT_DISC",
             "LOCAL_PREF",
             "ATOMIC_AGGREGATE",
             "AGGREGATOR",
             "COMMUNITIES",
             "ORIGINATOR_ID",
             "CLUSTER_LIST",
             "DPA",
             "ADVERTISERS",
             "RCID_PATH",
             "MP_REACH_NLRI",
             "MP_UNREACH_NLRI",
           };

#define bgp_attr_type(x) \
        num_or_str(bgpattr_type, DIM(bgpattr_type), (x))

/* Subsequent address family identifier, RFC2283 section 7
 */
static const char *bgpattr_nlri_safi[] = {
             "Reserved", "Unicast",
             "Multicast", "Unicast+Multicast",
           };

#define bgp_attr_nlri_safi(x) \
        num_or_str(bgpattr_nlri_safi, DIM(bgpattr_nlri_safi), (x))

/* well-known community
 */
#define BGP_COMMUNITY_NO_EXPORT           0xffffff01
#define BGP_COMMUNITY_NO_ADVERT           0xffffff02
#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03

/* RFC1700 address family numbers
 */
#define AFNUM_INET      1
#define AFNUM_INET6     2
#define AFNUM_NSAP      3
#define AFNUM_HDLC      4
#define AFNUM_BBN1822   5
#define AFNUM_802       6
#define AFNUM_E163      7
#define AFNUM_E164      8
#define AFNUM_F69       9
#define AFNUM_X121      10
#define AFNUM_IPX       11
#define AFNUM_ATALK     12
#define AFNUM_DECNET    13
#define AFNUM_BANYAN    14
#define AFNUM_E164NSAP  15

static const char *afnumber[] = {
             "Reserved", "IPv4", "IPv6", "NSAP", "HDLC",
             "BBN 1822", "802", "E.163", "E.164", "F.69",
             "X.121", "IPX", "Appletalk", "Decnet IV", "Banyan Vines",
             "E.164 with NSAP subaddress",
           };

#define af_name(x) (((x) == 65535) ? afnumber[0] : \
                    num_or_str(afnumber, DIM(afnumber), (x)))


static const char *num_or_str (const char **table, size_t siz, int value)
{
  static char buf[20];

  if (value < 0 || siz <= value || table[value] == NULL)
  {
    sprintf (buf, "#%d", value);
    return buf;
  }
  return table[value];
}

static const char *bgp_notify_minor (int major, int minor)
{
  static const char **table;
  static char         buf[20];
  int    siz;
  const  char *p;

  if (0 <= major &&
      major < DIM(bgpnotify_minor) && bgpnotify_minor[major])
  {
    table = bgpnotify_minor[major];
    siz = bgpnotify_minor_siz[major];
    if (0 <= minor && minor < siz && table[minor])
         p = table[minor];
    else p = NULL;
  }
  else
    p = NULL;

  if (p == NULL)
  {
    sprintf (buf, "#%d", minor);
    return buf;
  }
  return p;
}

static int decode_prefix4 (const u_char *pd, char *buf, int buflen)
{
  struct in_addr addr;
  int    plen = pd[0];

  if (plen < 0 || 32 < plen)
    return -1;

  memset (&addr, 0, sizeof(addr));
  memcpy (&addr, &pd[1], (plen + 7) / 8);
  if (plen % 8)
    ((u_char *)&addr)[(plen + 7) / 8 - 1] &= ((0xff00 >> (plen % 8)) & 0xff);

  sprintf (buf, "%s/%d", ipaddr_string(&addr), plen);
  return 1 + (plen + 7) / 8;
}

#ifdef USE_INET6
static int decode_prefix6 (const u_char * pd, char *buf, int buflen)
{
  struct in6_addr addr;
  int    plen = pd[0];

  if (plen < 0 || 128 < plen)
     return -1;

  memset (&addr, 0, sizeof(addr));
  memcpy (&addr, &pd[1], (plen + 7) / 8);
  if (plen % 8)
    addr.s6_addr[(plen+7)/8-1] &= ((0xff00 >> (plen % 8)) & 0xff);

  sprintf (buf, "%s/%d", ip6addr_string(&addr), plen);
  return 1 + (plen + 7) / 8;
}
#endif

static void bgp_attr_print (const struct bgp_attr *attr, const u_char *dat, int len)
{
  u_int16_t af;
  u_int8_t  safi, snpa;
  int       i, tlen;
  int       advance = 0;
  const     u_char *p = dat;
  char      buf[256];

  switch (attr->bgpa_type)
  {
    case BGPTYPE_ORIGIN:
         if (len != 1)
              PUTS (" invalid len");
         else PRINTF (" %s", bgp_attr_origin (p[0]));
         break;

    case BGPTYPE_AS_PATH:
         if (len % 2)
         {
           PUTS (" invalid len");
           break;
         }
         while (p < dat + len)
         {
           /*
            * under RFC1965, p[0] means:
            * 1: AS_SET 2: AS_SEQUENCE
            * 3: AS_CONFED_SET 4: AS_CONFED_SEQUENCE
            */
           PUTCHAR (' ');
           if (p[0] == 3 || p[0] == 4)
              PUTS ("confed");
           PRINTF ("%s", (p[0] & 1) ? "{" : "");
           for (i = 0; i < p[1]; i += 2)
              PRINTF ("%s%u", i == 0 ? "" : " ",
                      ntohs (*(u_int16_t*) &p[2+i]));

           PUTCHAR ((p[0] & 1) ? '}' : '\0');

⌨️ 快捷键说明

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