📄 _decnet.c
字号:
/*
* 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 + -