mirror of
https://github.com/dreamlayers/netbsd-mopd.git
synced 2026-02-02 23:01:03 +00:00
Ultrix 4.00 netload requires transfers to end with Memory Load with Transfer Address. The load address must be present, though image data doesn't have to be present.
670 lines
16 KiB
C
670 lines
16 KiB
C
/* $NetBSD: process.c,v 1.21 2016/06/08 01:11:49 christos Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1993-95 Mats O Jansson. 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.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
|
*/
|
|
|
|
#include "port.h"
|
|
#ifndef lint
|
|
__RCSID("$NetBSD: process.c,v 1.21 2016/06/08 01:11:49 christos Exp $");
|
|
#endif
|
|
|
|
#include "os.h"
|
|
#include "cmp.h"
|
|
#include "common.h"
|
|
#include "dl.h"
|
|
#include "file.h"
|
|
#include "get.h"
|
|
#include "mopdef.h"
|
|
#include "nmadef.h"
|
|
#include "pf.h"
|
|
#include "print.h"
|
|
#include "put.h"
|
|
#include "rc.h"
|
|
|
|
extern u_char buf[];
|
|
extern int DebugFlag;
|
|
extern char *MopdDir;
|
|
|
|
struct dllist dllist[MAXDL]; /* dump/load list */
|
|
|
|
void mopNextLoad(const u_char *, const u_char *, u_char, int);
|
|
void mopProcessDL(FILE *, struct if_info *, const u_char *, int *,
|
|
const u_char *, const u_char *, int, u_short);
|
|
void mopProcessRC(FILE *, struct if_info *, const u_char *, int *,
|
|
const u_char *, const u_char *, int, u_short);
|
|
void mopProcessInfo(const u_char *, int *, u_short, struct dllist *, int);
|
|
void mopSendASV(const u_char *, const u_char *, struct if_info *, int);
|
|
void mopStartLoad(const u_char *, const u_char *, struct dllist *, int);
|
|
|
|
void
|
|
mopProcessInfo(const u_char *pkt, int *idx, u_short moplen, struct dllist *dl_rpr,
|
|
int trans)
|
|
{
|
|
u_short itype,tmps;
|
|
u_char ilen ,tmpc,device;
|
|
const u_char *ucp;
|
|
|
|
device = 0;
|
|
|
|
switch(trans) {
|
|
case TRANS_ETHER:
|
|
moplen = moplen + 16;
|
|
break;
|
|
case TRANS_8023:
|
|
moplen = moplen + 14;
|
|
break;
|
|
}
|
|
|
|
itype = mopGetShort(pkt,idx);
|
|
|
|
while (*idx < (int)(moplen)) {
|
|
ilen = mopGetChar(pkt,idx);
|
|
switch (itype) {
|
|
case 0:
|
|
tmpc = mopGetChar(pkt,idx);
|
|
*idx = *idx + tmpc;
|
|
break;
|
|
case MOP_K_INFO_VER:
|
|
(void)mopGetChar(pkt,idx);
|
|
(void)mopGetChar(pkt,idx);
|
|
(void)mopGetChar(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_MFCT:
|
|
tmps = mopGetShort(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_CNU:
|
|
ucp = pkt + *idx; *idx = *idx + 6;
|
|
break;
|
|
case MOP_K_INFO_RTM:
|
|
tmps = mopGetShort(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_CSZ:
|
|
tmps = mopGetShort(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_RSZ:
|
|
tmps = mopGetShort(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_HWA:
|
|
ucp = pkt + *idx; *idx = *idx + 6;
|
|
break;
|
|
case MOP_K_INFO_TIME:
|
|
ucp = pkt + *idx; *idx = *idx + 10;
|
|
break;
|
|
case MOP_K_INFO_SOFD:
|
|
device = mopGetChar(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_SFID:
|
|
tmpc = mopGetChar(pkt,idx);
|
|
ucp = pkt + *idx; *idx = *idx + tmpc;
|
|
break;
|
|
case MOP_K_INFO_PRTY:
|
|
tmpc = mopGetChar(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_DLTY:
|
|
tmpc = mopGetChar(pkt,idx);
|
|
break;
|
|
case MOP_K_INFO_DLBSZ:
|
|
tmps = mopGetShort(pkt,idx);
|
|
dl_rpr->dl_bsz = tmps;
|
|
break;
|
|
default:
|
|
if (((device = NMA_C_SOFD_LCS) || /* DECserver 100 */
|
|
(device = NMA_C_SOFD_DS2) || /* DECserver 200 */
|
|
(device = NMA_C_SOFD_DP2) || /* DECserver 250 */
|
|
(device = NMA_C_SOFD_DS3)) && /* DECserver 300 */
|
|
((itype > 101) && (itype < 107)))
|
|
{
|
|
switch (itype) {
|
|
case 102:
|
|
ucp = pkt + *idx;
|
|
*idx = *idx + ilen;
|
|
break;
|
|
case 103:
|
|
ucp = pkt + *idx;
|
|
*idx = *idx + ilen;
|
|
break;
|
|
case 104:
|
|
tmps = mopGetShort(pkt,idx);
|
|
break;
|
|
case 105:
|
|
ucp = pkt + *idx;
|
|
*idx = *idx + ilen;
|
|
break;
|
|
case 106:
|
|
ucp = pkt + *idx;
|
|
*idx = *idx + ilen;
|
|
break;
|
|
};
|
|
} else {
|
|
ucp = pkt + *idx; *idx = *idx + ilen;
|
|
};
|
|
}
|
|
itype = mopGetShort(pkt,idx);
|
|
}
|
|
__USE(ucp);
|
|
}
|
|
|
|
void
|
|
mopSendASV(const u_char *dst, const u_char *src, struct if_info *ii, int trans)
|
|
{
|
|
u_char pkt[200];
|
|
int idx;
|
|
u_char mopcode = MOP_K_CODE_ASV;
|
|
u_short ptype = MOP_K_PROTO_DL;
|
|
|
|
idx = 0;
|
|
mopPutHeader(pkt, &idx, dst, src, ptype, trans);
|
|
|
|
mopPutChar(pkt,&idx,mopcode);
|
|
|
|
mopPutLength(pkt, trans, idx);
|
|
(void)mopGetLength(pkt, trans);
|
|
|
|
if (DebugFlag == DEBUG_ONELINE) {
|
|
mopPrintOneline(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_HEADER) {
|
|
mopPrintHeader(stdout, pkt, trans);
|
|
mopPrintMopHeader(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_INFO) {
|
|
mopDumpDL(stdout, pkt, trans);
|
|
}
|
|
|
|
if (pfWrite(ii->fd, pkt, idx, trans) != idx) {
|
|
if (DebugFlag) {
|
|
(void)fprintf(stderr, "error pfWrite()\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
#define MAX_ETH_PAYLOAD 1492
|
|
|
|
void
|
|
mopStartLoad(const u_char *dst, const u_char *src, struct dllist *dl_rpr,
|
|
int trans)
|
|
{
|
|
int len;
|
|
int i, slot;
|
|
u_char pkt[BUFSIZE];
|
|
int idx;
|
|
u_char mopcode = MOP_K_CODE_MLD;
|
|
u_short ptype = MOP_K_PROTO_DL;
|
|
struct dllist *dle;
|
|
|
|
slot = -1;
|
|
|
|
/* Look if we have a non terminated load, if so, use its slot */
|
|
|
|
for (i = 0, dle = dllist; i < MAXDL; i++, dle++) {
|
|
if (dle->status != DL_STATUS_FREE) {
|
|
if (mopCmpEAddr(dle->eaddr, dst) == 0) {
|
|
slot = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If no slot yet, then find first free */
|
|
|
|
if (slot == -1) {
|
|
for (i = 0, dle = dllist; i < MAXDL; i++, dle++) {
|
|
if (dle->status == DL_STATUS_FREE) {
|
|
if (slot == -1) {
|
|
slot = i;
|
|
memmove((char *)dle->eaddr,
|
|
(const char *)dst, 6);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If no slot yet, then return. No slot is free */
|
|
|
|
if (slot == -1)
|
|
return;
|
|
|
|
/* Ok, save info from RPR */
|
|
|
|
dllist[slot] = *dl_rpr;
|
|
dle = &dllist[slot];
|
|
dle->status = DL_STATUS_READ_IMGHDR;
|
|
|
|
/* Get Load and Transfer Address. */
|
|
|
|
GetFileInfo(dle);
|
|
|
|
dle->nloadaddr = dle->loadaddr;
|
|
dle->lseek = lseek(dle->ldfd, 0L, SEEK_CUR);
|
|
dle->a_lseek = 0;
|
|
|
|
dle->count = 0;
|
|
if (dle->dl_bsz >= MAX_ETH_PAYLOAD || dle->dl_bsz == 0)
|
|
dle->dl_bsz = MAX_ETH_PAYLOAD;
|
|
if (dle->dl_bsz == 1030) /* VS/uVAX 2000 needs this */
|
|
dle->dl_bsz = 1000;
|
|
if (dle->dl_bsz == 1422) /* Ultrix 4.00 netload on KA630-A.V1.3 */
|
|
dle->dl_bsz = 1000; /* This works, but actual limit unknown */
|
|
if (dle->dl_bsz == 0) /* Needed by "big" VAXen */
|
|
dle->dl_bsz = MAX_ETH_PAYLOAD;
|
|
if (trans == TRANS_8023)
|
|
dle->dl_bsz = dle->dl_bsz - 8;
|
|
|
|
idx = 0;
|
|
mopPutHeader(pkt, &idx, dst, src, ptype, trans);
|
|
mopPutChar (pkt, &idx, mopcode);
|
|
|
|
mopPutChar (pkt, &idx, dle->count);
|
|
mopPutLong (pkt, &idx, dle->loadaddr);
|
|
|
|
len = mopFileRead(dle, &pkt[idx]);
|
|
|
|
dle->nloadaddr = dle->loadaddr + len;
|
|
idx = idx + len;
|
|
|
|
mopPutLength(pkt, trans, idx);
|
|
(void)mopGetLength(pkt, trans);
|
|
|
|
if (DebugFlag == DEBUG_ONELINE) {
|
|
mopPrintOneline(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_HEADER) {
|
|
mopPrintHeader(stdout, pkt, trans);
|
|
mopPrintMopHeader(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_INFO) {
|
|
mopDumpDL(stdout, pkt, trans);
|
|
}
|
|
|
|
if (pfWrite(dle->ii->fd, pkt, idx, trans) != idx) {
|
|
if (DebugFlag) {
|
|
(void)fprintf(stderr, "error pfWrite()\n");
|
|
}
|
|
}
|
|
|
|
dle->status = DL_STATUS_SENT_MLD;
|
|
}
|
|
|
|
void
|
|
mopNextLoad(const u_char *dst, const u_char *src, u_char new_count, int trans)
|
|
{
|
|
int len;
|
|
int i, slot;
|
|
u_char pkt[BUFSIZE];
|
|
int idx, pindex;
|
|
char line[100];
|
|
u_short ptype = MOP_K_PROTO_DL;
|
|
u_char mopcode;
|
|
struct dllist *dle;
|
|
|
|
slot = -1;
|
|
|
|
for (i = 0, dle = dllist; i < MAXDL; i++, dle++) {
|
|
if (dle->status != DL_STATUS_FREE) {
|
|
if (mopCmpEAddr(dst, dle->eaddr) == 0)
|
|
slot = i;
|
|
}
|
|
}
|
|
|
|
/* If no slot yet, then return. No slot is free */
|
|
|
|
if (slot == -1)
|
|
return;
|
|
|
|
dle = &dllist[slot];
|
|
|
|
if (new_count == ((dle->count+1) % 256)) {
|
|
dle->loadaddr = dllist[slot].nloadaddr;
|
|
dle->count = new_count;
|
|
} else if (new_count != (dle->count % 256)) {
|
|
return;
|
|
}
|
|
|
|
if (dle->status == DL_STATUS_SENT_PLT) {
|
|
close(dle->ldfd);
|
|
dle->ldfd = -1;
|
|
dle->status = DL_STATUS_FREE;
|
|
snprintf(line, sizeof(line),
|
|
"%x:%x:%x:%x:%x:%x Load completed",
|
|
dst[0],dst[1],dst[2],dst[3],dst[4],dst[5]);
|
|
syslog(LOG_INFO, "%s", line);
|
|
return;
|
|
}
|
|
|
|
dle->lseek = lseek(dle->ldfd, 0L, SEEK_CUR);
|
|
|
|
if (dle->dl_bsz >= MAX_ETH_PAYLOAD)
|
|
dle->dl_bsz = MAX_ETH_PAYLOAD;
|
|
|
|
idx = 0;
|
|
mopPutHeader(pkt, &idx, dst, src, ptype, trans);
|
|
mopcode = MOP_K_CODE_MLD;
|
|
pindex = idx;
|
|
mopPutChar (pkt,&idx, mopcode);
|
|
mopPutChar (pkt,&idx, dle->count);
|
|
mopPutLong (pkt,&idx, dle->loadaddr);
|
|
|
|
len = mopFileRead(dle, &pkt[idx]);
|
|
|
|
if (len > 0 ) {
|
|
|
|
dle->nloadaddr = dle->loadaddr + len;
|
|
idx = idx + len;
|
|
|
|
mopPutLength(pkt, trans, idx);
|
|
(void)mopGetLength(pkt, trans);
|
|
|
|
} else {
|
|
if (len == 0) {
|
|
idx = pindex;
|
|
mopPutChar (pkt, &idx, dle->endcode);
|
|
mopPutChar (pkt, &idx, dle->count);
|
|
if (dle->endcode == MOP_K_CODE_PLT) {
|
|
mopPutChar (pkt, &idx, MOP_K_PLTP_HSN);
|
|
mopPutChar (pkt, &idx, 3);
|
|
mopPutMulti(pkt, &idx, "ipc", 3);
|
|
mopPutChar (pkt, &idx, MOP_K_PLTP_HSA);
|
|
mopPutChar (pkt, &idx, 6);
|
|
mopPutMulti(pkt, &idx, src, 6);
|
|
mopPutChar (pkt, &idx, MOP_K_PLTP_HST);
|
|
mopPutTime (pkt, &idx, 0);
|
|
mopPutChar (pkt, &idx, 0);
|
|
mopPutLong (pkt, &idx, dle->xferaddr);
|
|
} else if (dle->endcode == MOP_K_CODE_MLT) {
|
|
/* According to spec, load address could be omitted,
|
|
* but Ultrix 4.00 netload expects it to be there.
|
|
* It is irrelevant with no data, and only sent so
|
|
* the transfer address is at the expected location.
|
|
*/
|
|
mopPutLong (pkt, &idx, dle->nloadaddr);
|
|
/* Ultrix 4.00 kernel has high bit set, which causes crash */
|
|
mopPutLong (pkt, &idx, dle->xferaddr & ~0x80000000);
|
|
}
|
|
|
|
mopPutLength(pkt, trans, idx);
|
|
(void)mopGetLength(pkt, trans);
|
|
|
|
dle->status = DL_STATUS_SENT_PLT;
|
|
} else {
|
|
dle->status = DL_STATUS_FREE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (DebugFlag == DEBUG_ONELINE) {
|
|
mopPrintOneline(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_HEADER) {
|
|
mopPrintHeader(stdout, pkt, trans);
|
|
mopPrintMopHeader(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_INFO) {
|
|
mopDumpDL(stdout, pkt, trans);
|
|
}
|
|
|
|
if (pfWrite(dle->ii->fd, pkt, idx, trans) != idx) {
|
|
if (DebugFlag) {
|
|
(void)fprintf(stderr, "error pfWrite()\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
mopProcessDL(FILE *fd, struct if_info *ii, const u_char *pkt, int *idx,
|
|
const u_char *dst, const u_char *src, int trans, u_short len)
|
|
{
|
|
u_char tmpc;
|
|
u_short moplen;
|
|
u_char pfile[129], mopcode;
|
|
char filename[FILENAME_MAX];
|
|
char line[100];
|
|
int i, nfd;
|
|
struct dllist dl, *dl_rpr;
|
|
u_char load;
|
|
u_char pgtype;
|
|
|
|
if (DebugFlag == DEBUG_ONELINE) {
|
|
mopPrintOneline(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_HEADER) {
|
|
mopPrintHeader(stdout, pkt, trans);
|
|
mopPrintMopHeader(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_INFO) {
|
|
mopDumpDL(stdout, pkt, trans);
|
|
}
|
|
|
|
moplen = mopGetLength(pkt, trans);
|
|
mopcode = mopGetChar(pkt,idx);
|
|
|
|
switch (mopcode) {
|
|
case MOP_K_CODE_MLT:
|
|
break;
|
|
case MOP_K_CODE_DCM:
|
|
break;
|
|
case MOP_K_CODE_MLD:
|
|
break;
|
|
case MOP_K_CODE_ASV:
|
|
break;
|
|
case MOP_K_CODE_RMD:
|
|
break;
|
|
case MOP_K_CODE_RPR:
|
|
|
|
tmpc = mopGetChar(pkt,idx); /* Device Type */
|
|
|
|
tmpc = mopGetChar(pkt,idx); /* Format Version */
|
|
if ((tmpc != MOP_K_RPR_FORMAT) &&
|
|
(tmpc != MOP_K_RPR_FORMAT_V3)) {
|
|
(void)fprintf(stderr,"mopd: Unknown RPR Format (%d) from ",tmpc);
|
|
mopPrintHWA(stderr,src);
|
|
(void)fprintf(stderr,"\n");
|
|
}
|
|
|
|
pgtype = mopGetChar(pkt,idx); /* Program Type */
|
|
|
|
tmpc = mopGetChar(pkt,idx); /* Software ID Len */
|
|
|
|
dl_rpr = &dl;
|
|
memset(dl_rpr, 0, sizeof(*dl_rpr));
|
|
|
|
/* Ultrix 4.00 netload sends 0xff, but no string after it. */
|
|
if (tmpc == 0xff) {
|
|
tmpc = 0;
|
|
/* Required by Ultrix 4.00 netload, not accepted by KA630-A.V1.3 */
|
|
dl_rpr->endcode = MOP_K_CODE_MLT;
|
|
} else {
|
|
dl_rpr->endcode = MOP_K_CODE_PLT;
|
|
}
|
|
|
|
if (tmpc > sizeof(pfile) - 1)
|
|
return;
|
|
for (i = 0; i < tmpc; i++) {
|
|
pfile[i] = mopGetChar(pkt,idx);
|
|
pfile[i+1] = '\0';
|
|
}
|
|
|
|
|
|
if (tmpc == 0) {
|
|
/* In a normal implementation of a MOP Loader this */
|
|
/* would cause a question to NML (DECnet) if this */
|
|
/* node is known and if so what image to load. But */
|
|
/* we don't have DECnet so we don't have anybody */
|
|
/* to ask. My solution is to use the ethernet addr */
|
|
/* as filename. Implementing a database would be */
|
|
/* overkill. */
|
|
const char *suffix;
|
|
switch (pgtype) {
|
|
case MOP_K_PGTY_SECLDR:
|
|
suffix = ".2";
|
|
break;
|
|
case MOP_K_PGTY_TERLDR:
|
|
suffix = ".3";
|
|
break;
|
|
case MOP_K_PGTY_MGNTFL:
|
|
suffix = ".M";
|
|
case MOP_K_PGTY_OPRSYS:
|
|
default:
|
|
suffix = "";
|
|
break;
|
|
}
|
|
snprintf(pfile, sizeof(pfile),
|
|
"%02x%02x%02x%02x%02x%02x%s%c",
|
|
src[0],src[1],src[2],src[3],src[4],src[5],suffix,0);
|
|
}
|
|
|
|
tmpc = mopGetChar(pkt,idx); /* Processor */
|
|
|
|
dl_rpr->ii = ii;
|
|
memmove((char *)(dl_rpr->eaddr), (const char *)src, 6);
|
|
mopProcessInfo(pkt,idx,moplen,dl_rpr,trans);
|
|
|
|
snprintf(filename, sizeof(filename), "%s/%s.SYS",
|
|
MopdDir, pfile);
|
|
if ((mopCmpEAddr(dst,dl_mcst) == 0)) {
|
|
if ((nfd = open(filename, O_RDONLY, 0)) != -1) {
|
|
close(nfd);
|
|
mopSendASV(src, ii->eaddr, ii, trans);
|
|
snprintf(line, sizeof(line),
|
|
"%x:%x:%x:%x:%x:%x (%d) Do you have %s? (Yes)",
|
|
src[0],src[1],src[2],
|
|
src[3],src[4],src[5],trans,pfile);
|
|
} else {
|
|
snprintf(line, sizeof(line),
|
|
"%x:%x:%x:%x:%x:%x (%d) Do you have %s? (No)",
|
|
src[0],src[1],src[2],
|
|
src[3],src[4],src[5],trans,pfile);
|
|
}
|
|
syslog(LOG_INFO, "%s", line);
|
|
} else {
|
|
if ((mopCmpEAddr(dst,ii->eaddr) == 0)) {
|
|
dl_rpr->ldfd = open(filename, O_RDONLY, 0);
|
|
mopStartLoad(src, ii->eaddr, dl_rpr, trans);
|
|
snprintf(line, sizeof(line),
|
|
"%x:%x:%x:%x:%x:%x Send me %s",
|
|
src[0],src[1],src[2],
|
|
src[3],src[4],src[5],pfile);
|
|
syslog(LOG_INFO, "%s", line);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case MOP_K_CODE_RML:
|
|
|
|
load = mopGetChar(pkt,idx); /* Load Number */
|
|
|
|
tmpc = mopGetChar(pkt,idx); /* Error */
|
|
|
|
if ((mopCmpEAddr(dst,ii->eaddr) == 0)) {
|
|
mopNextLoad(src, ii->eaddr, load, trans);
|
|
}
|
|
|
|
break;
|
|
case MOP_K_CODE_RDS:
|
|
break;
|
|
case MOP_K_CODE_MDD:
|
|
break;
|
|
case MOP_K_CODE_CCP:
|
|
break;
|
|
case MOP_K_CODE_PLT:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
mopProcessRC(FILE *fd, struct if_info *ii, const u_char *pkt, int *idx,
|
|
const u_char *dst, const u_char *src, int trans, u_short len)
|
|
{
|
|
u_char tmpc;
|
|
u_short moplen = 0;
|
|
u_char mopcode;
|
|
struct dllist dl,*dl_rpr;
|
|
|
|
if (DebugFlag == DEBUG_ONELINE) {
|
|
mopPrintOneline(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_HEADER) {
|
|
mopPrintHeader(stdout, pkt, trans);
|
|
mopPrintMopHeader(stdout, pkt, trans);
|
|
}
|
|
|
|
if (DebugFlag >= DEBUG_INFO) {
|
|
mopDumpRC(stdout, pkt, trans);
|
|
}
|
|
|
|
moplen = mopGetLength(pkt, trans);
|
|
mopcode = mopGetChar(pkt,idx);
|
|
|
|
switch (mopcode) {
|
|
case MOP_K_CODE_RID:
|
|
break;
|
|
case MOP_K_CODE_BOT:
|
|
break;
|
|
case MOP_K_CODE_SID:
|
|
|
|
tmpc = mopGetChar(pkt,idx); /* Reserved */
|
|
|
|
if ((DebugFlag >= DEBUG_INFO)) {
|
|
(void)fprintf(stderr, "Reserved : %02x\n",tmpc);
|
|
}
|
|
|
|
(void)mopGetShort(pkt,idx); /* Receipt # */
|
|
if ((DebugFlag >= DEBUG_INFO)) {
|
|
(void)fprintf(stderr, "Receipt Nbr : %04x\n",tmpc);
|
|
}
|
|
|
|
dl_rpr = &dl;
|
|
memset(dl_rpr, 0, sizeof(*dl_rpr));
|
|
dl_rpr->ii = ii;
|
|
memmove((char *)(dl_rpr->eaddr), (const char *)src, 6);
|
|
mopProcessInfo(pkt,idx,moplen,dl_rpr,trans);
|
|
|
|
break;
|
|
case MOP_K_CODE_RQC:
|
|
break;
|
|
case MOP_K_CODE_CNT:
|
|
break;
|
|
case MOP_K_CODE_RVC:
|
|
break;
|
|
case MOP_K_CODE_RLC:
|
|
break;
|
|
case MOP_K_CODE_CCP:
|
|
break;
|
|
case MOP_K_CODE_CRA:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|