1
0
Files
2022-09-29 17:59:04 +03:00

131 lines
2.5 KiB
C

/*
* Copyright 1989 Silicon Graphics, Inc. All rights reserved.
*
* MAC module.
*/
#include <bstring.h>
#include <sys/types.h>
#include <netinet/in.h> /* for ntohs() */
#include "index.h"
#include "protodefs.h"
#include "strings.h"
#include "protocols/mac.h"
char macname[] = "mac";
/*
* MAC field identifiers and descriptors.
*/
enum macfid {
TRT,
BCN,
PAD
};
static ProtoField macfields[] = {
PFI_UINT("claimtrt", "Claim Token Rotation Time",TRT, u_long, PV_TERSE),
PFI_UINT("beacon", "Beacon Type", BCN, u_char, PV_TERSE),
PFI_BYTE("pad", "Reserved", PAD, 3, PV_VERBOSE+1),
};
#define MACFID(pf) ((enum macfid) (pf)->pf_id)
#define MACFIELD(fid) macfields[(int) fid]
/*
* MAC protocol interface.
*/
#define mac_setopt pr_stub_setopt
#define mac_embed pr_stub_embed
#define mac_resolve pr_stub_resolve
#define mac_match pr_stub_match
DefineLeafProtocol(mac, macname, "Medium Access Control", PRID_MAC,
DS_BIG_ENDIAN, sizeof(MAC));
static int
mac_init()
{
if (!pr_register(&mac_proto, macfields, lengthof(macfields), 0))
return 0;
return pr_nest(&mac_proto, PRID_FDDI, PRID_MAC, 0, 0);
}
static ExprType
mac_compile(ProtoField *pf, Expr *mex, Expr *tex, ProtoCompiler *pc)
{
enum macfid fid;
fid = MACFID(pf);
switch (fid) {
case BCN:
case TRT: {
long mask;
if (!pc_intmask(pc, mex, &mask))
return ET_ERROR;
if (tex->ex_op != EXOP_NUMBER) {
pc_badop(pc, tex);
return ET_ERROR;
}
if (!pc_intfield(pc, pf, mask, tex->ex_val,
sizeof(u_long))) {
return ET_COMPLEX;
}
break;
}
}
return ET_SIMPLE;
}
/* ARGSUSED */
static int
mac_fetch(ProtoField *pf, DataStream *ds, ProtoStack *ps, Expr *rex)
{
MAC *m;
m = (MAC *)ds_inline(ds, sizeof(*m), sizeof(u_long));
if (m == 0)
return 0;
switch (MACFID(pf)) {
case PAD:
return 0;
case TRT:
rex->ex_val = ntohl(m->clm);
rex->ex_op = EXOP_NUMBER;
break;
case BCN:
rex->ex_val = m->bcn.bcn_type;
rex->ex_op = EXOP_NUMBER;
break;
default:
return(0);
}
return 1;
}
static void
mac_decode(DataStream *ds, ProtoStack *ps, PacketView *pv)
{
MAC *m;
m = (MAC *)ds_inline(ds, sizeof(*m), sizeof(u_long));
if (m == 0)
return;
switch (PS_TOP(ps, struct fddiframe)->ff_fc & 0x0F) {
case MAC_SUBFC_CLM:
pv_showfield(pv, &MACFIELD(TRT), m, "%d", m->clm);
break;
case MAC_SUBFC_BEACON:
pv_showfield(pv, &MACFIELD(BCN), &m->bcn.bcn_type,
"%#02x", m->bcn.bcn_type);
pv_showfield(pv, &MACFIELD(PAD), m->bcn.bcn_pad,
"0x%02x%02x%02x",
m->bcn.bcn_pad[0], m->bcn.bcn_pad[1],
m->bcn.bcn_pad[2]);
break;
}
}