1
0
Files
irix-657m-src/irix/cmd/netman/lib/protocols/hello.c
2022-09-29 17:59:04 +03:00

193 lines
5.2 KiB
C

/*
* Copyright 1989 Silicon Graphics, Inc. All rights reserved.
*
* Snoop on Distributed Computer Network (DCN) HELLO routing protocol.
* An older version of HELLO is defined in RFC 891.
*/
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "enum.h"
#include "protodefs.h"
#include "protocols/hello.h"
#include "protocols/ip.h"
char helloname[] = "hello";
/*
* Datastream macros.
*/
#define S_ALIGN sizeof(u_short) /* short word alignment */
#define ds_inline_hellohdr(ds) \
(struct hellohdr *) ds_inline(ds, sizeof(struct hellohdr), S_ALIGN)
#define ds_inline_type0pair(ds) \
(struct type0pair *) ds_inline(ds, sizeof(struct type0pair), S_ALIGN)
#define ds_inline_type1pair(ds) \
(struct type1pair *) ds_inline(ds, sizeof(struct type1pair), S_ALIGN)
/*
* Hello field identifiers and descriptors.
*/
enum hellofid {
CHECKSUM, DATE, TIME, TIMESTAMP, COUNT, TYPE,
DST, DELAY, OFFSET, D0_DELAY, D0_OFFSET
};
#define HPFI_UINT(name, title, id, type, off, level) \
PFI(name, title, id, DS_ZERO_EXTEND, sizeof(type), off, EXOP_NUMBER, \
level)
static ProtoField hellofields[] = {
/* hello header */
PFI_UINT("checksum", "Checksum", CHECKSUM, u_short, PV_VERBOSE),
PFI_UINT("date", "Date", DATE, u_short, PV_TERSE),
PFI_UINT("time", "Time", TIME, u_long, PV_DEFAULT),
PFI_UINT("timestamp", "Timestamp", TIMESTAMP,u_short, PV_DEFAULT),
PFI_UINT("count", "Count", COUNT, u_char, PV_TERSE),
PFI_UINT("type", "Type", TYPE, u_char, PV_TERSE),
/* hello data (routing table entries) */
PFI_UINT("dst", "Destination", DST, u_long, PV_DEFAULT),
PFI_UINT("delay", "Delay", DELAY, u_short, PV_DEFAULT),
PFI_UINT("offset", "Offset", OFFSET, u_short, PV_DEFAULT),
HPFI_UINT("d0_delay", "Type 0 Delay", D0_DELAY, u_short,12,PV_DEFAULT),
HPFI_UINT("d0_offset", "Type 0 Offset", D0_OFFSET,u_short,14,PV_DEFAULT),
};
#define HELLOFID(pf) ((enum hellofid) (pf)->pf_id)
#define HELLOFIELD(fid) hellofields[(int) fid]
static ProtoMacro hellonicknames[] = {
PMI("HELLO", helloname),
};
/*
* HELLO protocol interface.
*/
#define hello_compile pr_stub_compile
#define hello_embed pr_stub_embed
#define hello_match pr_stub_match
#define hello_resolve pr_stub_resolve
#define hello_setopt pr_stub_setopt
DefineLeafProtocol(hello, helloname, "DCN HELLO Routing Protocol", PRID_HELLO,
DS_BIG_ENDIAN, HELLO_HDRSIZE);
static int
hello_init()
{
if (!pr_register(&hello_proto, hellofields, lengthof(hellofields), 3))
return 0;
if (!pr_nest(&hello_proto, PRID_IP, IPPROTO_HELLO, hellonicknames,
lengthof(hellonicknames))) {
return 0;
}
return 1;
} /* hello_init() */
static int
hello_fetch(ProtoField *pf, DataStream *ds, ProtoStack *ps, Expr *rex)
{
struct hellohdr *hi;
if (pf->pf_id > (int) TYPE) { /* should not fetch data fields */
return 0;
}
hi = ds_inline_hellohdr(ds);
if (hi == 0) { /* fetch what you can */
return ds_field(ds, pf, HELLO_HDRSIZE, rex);
}
rex->ex_op = EXOP_NUMBER;
switch (HELLOFID(pf)) {
case CHECKSUM:
rex->ex_val = ntohs(hi->h_cksum);
break;
case DATE:
rex->ex_val = ntohs(hi->h_date);
break;
case TIME:
rex->ex_val = ntohl(hi->h_time);
break;
case TIMESTAMP:
rex->ex_val = ntohs(hi->h_tstp);
break;
case COUNT:
rex->ex_val = hi->h_count;
break;
case TYPE:
rex->ex_val = hi->h_type;
break;
default:
return 0;
}
return 1;
} /* hello_fetch() */
static void
hello_decode(DataStream *ds, ProtoStack *ps, PacketView *pv)
{
struct hellohdr *hi;
hi = ds_inline_hellohdr(ds);
if ( hi == 0 )
return;
pv_showfield(pv, &HELLOFIELD(CHECKSUM), &hi->h_cksum,
"%#-04x", ntohs(hi->h_cksum));
pv_showfield(pv, &HELLOFIELD(DATE), &hi->h_date,
"%#-04x (sync: %1d, yr:%4d, day:%2d, mo:%2d)",
ntohs(hi->h_date),
(ntohs(hi->h_date)>>15 & 0x01), /* ck valid */
(ntohs(hi->h_date) & 037) + 1972, /* year */
(ntohs(hi->h_date)>>5 & 037), /* day */
(ntohs(hi->h_date)>>10 & 037) ); /* month */
pv_showfield(pv, &HELLOFIELD(TIME), &hi->h_time,
"%-10d (%-12.12s)", ntohl(hi->h_time),
ip_timestamp(ntohl(hi->h_time)));
pv_showfield(pv, &HELLOFIELD(TIMESTAMP), &hi->h_tstp,
"%-5d", ntohs(hi->h_tstp));
pv_showfield(pv, &HELLOFIELD(COUNT), &hi->h_count,
"%-3d", hi->h_count);
pv_showfield(pv, &HELLOFIELD(TYPE), &hi->h_type,
"%-1d", hi->h_type);
switch (hi->h_type) {
case 1: {
struct type1pair *n;
while ((n = ds_inline_type1pair(ds)) != 0) {
n->d1_dst = ntohl(n->d1_dst);
n->d1_delay= ntohs(n->d1_delay);
n->d1_offset= ntohs(n->d1_offset);
pv_break(pv);
pv_showfield(pv, &HELLOFIELD(DST), &n->d1_dst,
"%-15.15s", inet_ntoa(n->d1_dst));
pv_showfield(pv, &HELLOFIELD(DELAY), &n->d1_delay,
"%-5d", n->d1_delay);
pv_showfield(pv, &HELLOFIELD(OFFSET), &n->d1_offset,
"%-5d", n->d1_offset);
}
break;
} /* case of type 1 pair */
case 0: {
struct type0pair *n;
while ((n = ds_inline_type0pair(ds)) != 0) {
n->d0_delay= ntohs(n->d0_delay);
n->d0_offset= ntohs(n->d0_offset);
pv_break(pv);
pv_showfield(pv, &HELLOFIELD(D0_DELAY), &n->d0_delay,
"%-5d", n->d0_delay);
pv_showfield(pv, &HELLOFIELD(D0_OFFSET), &n->d0_offset,
"%-5d", n->d0_offset);
}
} /* case of type 0 pair */
}
} /* hello_decode() */