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

📄 _decnet.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
 *      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.
 */

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

#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>

#include "decnet.h"
#include "extract.h"
#include "interfac.h"
#include "a2name.h"


static void print_decnet_ctlmsg (const union routehdr *, u_int);
static void print_t_info (int);
static void print_l1_routes (const char *, u_int);
static void print_l2_routes (const char *, u_int);
static void print_i_info (int);
static void print_elist (const char *, u_int);
static void print_nsp (const u_char *, u_int);
static void print_reason (int);

#ifdef PRINT_DECNET_DETAILS
static void pdata (u_char *dp, int maxlen)
{
  char c;
  int  x = maxlen;

  while (x-- > 0)
  {
    c = *dp++;
    if (isprint (c))
         PUTCHAR (c);
    else PRINTF ("\\%o", c & 0xFF);
  }
}
#endif

void decnet_print (const u_char * ap, u_int length, u_int caplen)
{
  static union routehdr rhcopy;
  union  routehdr *rhp = &rhcopy;
  int    mflags;
  int    dst, src, hops;
  u_int  rhlen, nsplen, pktlen;
  const  u_char *nspp;

  if (length < sizeof(struct shorthdr))
  {
    PUTS ("[|decnet]");
    return;
  }

  pktlen = EXTRACT_LE_16BITS (ap);

  rhlen = min (length, caplen);
  rhlen = min (rhlen, sizeof(*rhp));
  memcpy (rhp, &ap[sizeof(short)], rhlen);

  mflags = EXTRACT_LE_8BITS (rhp->rh_short.sh_flags);

  if (mflags & RMF_PAD)
  {
    /* pad bytes of some sort in front of message */
    u_int padlen = mflags & RMF_PADMASK;

    if (vflag)
       PRINTF ("[pad:%d] ", padlen);
    ap += padlen;
    length -= padlen;
    caplen -= padlen;
    rhlen = min (length, caplen);
    rhlen = min (rhlen, sizeof(*rhp));
    memcpy (rhp,&ap[sizeof(short)],rhlen);

    mflags = EXTRACT_LE_8BITS (rhp->rh_short.sh_flags);
  }

  if (mflags & RMF_FVER)
  {
    PUTS ("future-version-decnet");
    default_print (ap, length);
    return;
  }

  /* is it a control message? */
  if (mflags & RMF_CTLMSG)
  {
    print_decnet_ctlmsg (rhp, min (length, caplen));
    return;
  }

  switch (mflags & RMF_MASK)
  {
    case RMF_LONG:
         dst  = EXTRACT_LE_16BITS (rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
         src  = EXTRACT_LE_16BITS (rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
         hops = EXTRACT_LE_8BITS (rhp->rh_long.lg_visits);
         nspp = &ap[sizeof(short) + sizeof(struct longhdr)];
         nsplen = min ((length - sizeof(struct longhdr)),
                       (caplen - sizeof(struct longhdr)));
         break;
    case RMF_SHORT:
         dst  = EXTRACT_LE_16BITS (rhp->rh_short.sh_dst);
         src  = EXTRACT_LE_16BITS (rhp->rh_short.sh_src);
         hops = (EXTRACT_LE_8BITS (rhp->rh_short.sh_visits) & VIS_MASK) + 1;
         nspp = &ap[sizeof(short) + sizeof(struct shorthdr)];
         nsplen = min ((length - sizeof(struct shorthdr)),
                       (caplen - sizeof(struct shorthdr)));
         break;
    default:
         PUTS ("unknown message flags under mask");
         default_print ((u_char *) ap, length);
         return;
  }

  PRINTF ("%s > %s %d ", dnaddr_string(src), dnaddr_string(dst), pktlen);
  if (vflag)
  {
    if (mflags & RMF_RQR)
       PUTS ("RQR ");
    if (mflags & RMF_RTS)
       PUTS ("RTS ");
    if (mflags & RMF_IE)
       PUTS ("IE ");
    PRINTF ("%d hops ", hops);
  }

  print_nsp (nspp, nsplen);
}

static void print_decnet_ctlmsg (const union routehdr *rhp, u_int length)
{
  int               mflags = EXTRACT_LE_8BITS (rhp->rh_short.sh_flags);
  union controlmsg *cmp    = (union controlmsg *) rhp;
  int               src, dst, info, blksize, eco, ueco, hello, other, vers;
  etheraddr         srcea, rtea;
  int               priority;
  char             *rhpx = (char *) rhp;

  switch (mflags & RMF_CTLMASK)
  {
    case RMF_INIT:
         PUTS ("init ");
         src     = EXTRACT_LE_16BITS (cmp->cm_init.in_src);
         info    = EXTRACT_LE_8BITS  (cmp->cm_init.in_info);
         blksize = EXTRACT_LE_16BITS (cmp->cm_init.in_blksize);
         vers    = EXTRACT_LE_8BITS  (cmp->cm_init.in_vers);
         eco     = EXTRACT_LE_8BITS  (cmp->cm_init.in_eco);
         ueco    = EXTRACT_LE_8BITS  (cmp->cm_init.in_ueco);
         hello   = EXTRACT_LE_16BITS (cmp->cm_init.in_hello);
         print_t_info (info);
         PRINTF ("src %sblksize %d vers %d eco %d ueco %d hello %d",
                  dnaddr_string (src), blksize, vers, eco, ueco, hello);
         break;

    case RMF_VER:
         PUTS ("verification ");
         src   = EXTRACT_LE_16BITS (cmp->cm_ver.ve_src);
         other = EXTRACT_LE_8BITS  (cmp->cm_ver.ve_fcnval);
         PRINTF ("src %s fcnval %o", dnaddr_string (src), other);
         break;

    case RMF_TEST:
         PUTS ("test ");
         src   = EXTRACT_LE_16BITS (cmp->cm_test.te_src);
         other = EXTRACT_LE_8BITS  (cmp->cm_test.te_data);
         PRINTF ("src %s data %o", dnaddr_string (src), other);
         break;

    case RMF_L1ROUT:
         PUTS ("lev-1-routing ");
         src = EXTRACT_LE_16BITS (cmp->cm_l1rou.r1_src);
         PRINTF ("src %s ", dnaddr_string (src));
         print_l1_routes (&rhpx[sizeof(struct l1rout)],
                          length - sizeof(struct l1rout));
         break;

    case RMF_L2ROUT:
         PUTS ("lev-2-routing ");
         src = EXTRACT_LE_16BITS (cmp->cm_l2rout.r2_src);
         PRINTF ("src %s ", dnaddr_string (src));
         print_l2_routes (&rhpx[sizeof(struct l2rout)],
                          length - sizeof(struct l2rout));
         break;

    case RMF_RHELLO:
         PUTS ("router-hello ");
         vers = EXTRACT_LE_8BITS (cmp->cm_rhello.rh_vers);
         eco  = EXTRACT_LE_8BITS (cmp->cm_rhello.rh_eco);
         ueco = EXTRACT_LE_8BITS (cmp->cm_rhello.rh_ueco);
         memcpy (&srcea, &cmp->cm_rhello.rh_src, sizeof(srcea));
         src  = EXTRACT_LE_16BITS (srcea.dne_remote.dne_nodeaddr);
         info = EXTRACT_LE_8BITS  (cmp->cm_rhello.rh_info);
         blksize  = EXTRACT_LE_16BITS (cmp->cm_rhello.rh_blksize);
         priority = EXTRACT_LE_8BITS  (cmp->cm_rhello.rh_priority);
         hello    = EXTRACT_LE_16BITS (cmp->cm_rhello.rh_hello);
         print_i_info (info);
         PRINTF ("vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
                  vers, eco, ueco, dnaddr_string(src),
                  blksize, priority, hello);
         print_elist (&rhpx[sizeof(struct rhellomsg)],
                      length - sizeof(struct rhellomsg));
         break;

    case RMF_EHELLO:
         PUTS ("endnode-hello ");
         vers = EXTRACT_LE_8BITS (cmp->cm_ehello.eh_vers);
         eco  = EXTRACT_LE_8BITS (cmp->cm_ehello.eh_eco);
         ueco = EXTRACT_LE_8BITS (cmp->cm_ehello.eh_ueco);
         memcpy (&srcea, &cmp->cm_ehello.eh_src, sizeof(srcea));
         src     = EXTRACT_LE_16BITS (srcea.dne_remote.dne_nodeaddr);
         info    = EXTRACT_LE_8BITS  (cmp->cm_ehello.eh_info);
         blksize = EXTRACT_LE_16BITS (cmp->cm_ehello.eh_blksize);
         /*seed */
         memcpy (&rtea, &cmp->cm_ehello.eh_router, sizeof(rtea));
         dst   = EXTRACT_LE_16BITS (rtea.dne_remote.dne_nodeaddr);
         hello = EXTRACT_LE_16BITS (cmp->cm_ehello.eh_hello);
         other = EXTRACT_LE_8BITS (cmp->cm_ehello.eh_data);
         print_i_info (info);
         PRINTF ("vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
                 vers, eco, ueco, dnaddr_string (src),
                 blksize, dnaddr_string (dst), hello, other);
         break;

    default:
         PUTS ("unknown control message");
         default_print ((u_char *) rhp, length);
         break;
  }
}

static void print_t_info (int info)
{
  int ntype = info & 3;

  switch (ntype)
  {
    case 0:
         PUTS ("reserved-ntype? ");
         break;
    case TI_L2ROUT:
         PUTS ("l2rout ");
         break;
    case TI_L1ROUT:
         PUTS ("l1rout ");
         break;
    case TI_ENDNODE:
         PUTS ("endnode ");
         break;
  }
  if (info & TI_VERIF)
     PUTS ("verif ");
  if (info & TI_BLOCK)
     PUTS ("blo ");
}

static void print_l1_routes (const char *rp, u_int len)
{
  int count;
  int id;
  int info;

  /* The last short is a checksum */
  while (len > (3 * sizeof(short)))
  {
    count = EXTRACT_LE_16BITS (rp);
    if (count > 1024)
       return;                   /* seems to be bogus from here on */
    rp += sizeof(short);
    len -= sizeof(short);

    id = EXTRACT_LE_16BITS (rp);
    rp += sizeof(short);
    len -= sizeof(short);

    info = EXTRACT_LE_16BITS (rp);
    rp += sizeof(short);
    len -= sizeof(short);

    PRINTF ("{ids %d-%d cost %d hops %d} ", id, id + count,
            RI_COST (info), RI_HOPS (info));
  }
}

static void print_l2_routes (const char *rp, u_int len)
{
  int count;
  int area;
  int info;

  /* The last short is a checksum */
  while (len > (3 * sizeof(short)))
  {
    count = EXTRACT_LE_16BITS (rp);
    if (count > 1024)
       return;                   /* seems to be bogus from here on */
    rp += sizeof(short);
    len -= sizeof(short);

    area = EXTRACT_LE_16BITS (rp);
    rp += sizeof(short);
    len -= sizeof(short);

    info = EXTRACT_LE_16BITS (rp);
    rp += sizeof(short);
    len -= sizeof(short);

    PRINTF ("{areas %d-%d cost %d hops %d} ", area, area + count,
            RI_COST (info), RI_HOPS (info));
  }
}

static void print_i_info (int info)
{
  int ntype = info & II_TYPEMASK;

  switch (ntype)
  {
    case 0:
         PUTS ("reserved-ntype? ");
         break;
    case II_L2ROUT:
         PUTS ("l2rout ");
         break;
    case II_L1ROUT:
         PUTS ("l1rout ");
         break;
    case II_ENDNODE:
         PUTS ("endnode ");
         break;
  }
  if (info & II_VERIF)
     PUTS ("verif ");
  if (info & II_NOMCAST)
     PUTS ("nomcast ");
  if (info & II_BLOCK)
     PUTS ("blo ");
}

static void print_elist (const char *elp, u_int len)
{
  ARGSUSED (elp);
  ARGSUSED (len);

  /* Not enough examples available for me to debug this */
}

static void print_nsp (const u_char * nspp, u_int nsplen)
{
  const struct nsphdr *nsphp = (struct nsphdr *) nspp;
  int   dst, src, flags;

  flags = EXTRACT_LE_8BITS  (nsphp->nh_flags);
  dst   = EXTRACT_LE_16BITS (nsphp->nh_dst);
  src   = EXTRACT_LE_16BITS (nsphp->nh_src);

  switch (flags & NSP_TYPEMASK)
  {
    case MFT_DATA:
         switch (flags & NSP_SUBMASK)
         {
           case MFS_BOM:
           case MFS_MOM:

⌨️ 快捷键说明

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