#include "os.h"
#include "common/common.h"
#include "common/mopdef.h"
#include "common/nmadef.h"
#include "common/get.h"
#include "common/put.h"
#include "common/print.h"
#include "common/pf.h"
#include "common/cmp.h"
#include "common/dl.h"
#include "common/rc.h"
#include "common/file.h"
extern int DebugFlag;
struct dllist dllist[MAXDL];
void
mopProcessInfo(u_char *pkt, int *idx, u_short moplen, struct dllist *dl_rpr,
int trans)
{
u_short itype, tmps;
u_char ilen, tmpc, device;
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:
*idx = *idx + 3;
break;
case MOP_K_INFO_MFCT:
case MOP_K_INFO_RTM:
case MOP_K_INFO_CSZ:
case MOP_K_INFO_RSZ:
mopGetShort(pkt, idx);
break;
case MOP_K_INFO_CNU:
case MOP_K_INFO_HWA:
*idx = *idx + 6;
break;
case MOP_K_INFO_TIME:
*idx = *idx + 10;
break;
case MOP_K_INFO_SOFD:
device = mopGetChar(pkt, idx);
break;
case MOP_K_INFO_SFID:
tmpc = mopGetChar(pkt, idx);
*idx = *idx + tmpc;
break;
case MOP_K_INFO_PRTY:
case MOP_K_INFO_DLTY:
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) ||
(device == NMA_C_SOFD_DS2) ||
(device == NMA_C_SOFD_DP2) ||
(device == NMA_C_SOFD_DS3)) &&
((itype > 101) && (itype < 107))) {
switch (itype) {
case 102:
case 103:
case 105:
case 106:
*idx = *idx + ilen;
break;
case 104:
mopGetShort(pkt, idx);
break;
}
} else
*idx = *idx + ilen;
}
itype = mopGetShort(pkt, idx);
}
}
void
mopSendASV(u_char *dst, u_char *src, struct if_info *ii, int trans)
{
u_char pkt[200];
int idx;
idx = 0;
mopPutHeader(pkt, &idx, dst, src, MOP_K_PROTO_DL, trans);
mopPutChar(pkt, &idx, MOP_K_CODE_ASV);
mopPutLength(pkt, trans, idx);
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)
warnx("pfWrite() error");
}
void
mopStartLoad(u_char *dst, 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;
slot = -1;
for (i = 0; i < MAXDL && slot == -1; i++)
if (dllist[i].status != DL_STATUS_FREE)
if (mopCmpEAddr(dllist[i].eaddr, dst) == 0)
slot = i;
for (i = 0; slot == -1 && i < MAXDL; i++)
if (dllist[i].status == DL_STATUS_FREE) {
slot = i;
bcopy(dst, dllist[i].eaddr, 6);
}
if (slot == -1)
return;
dllist[slot] = *dl_rpr;
dllist[slot].status = DL_STATUS_READ_IMGHDR;
GetFileInfo(&dllist[slot], 0);
dllist[slot].nloadaddr = dllist[slot].loadaddr;
dllist[slot].lseek = lseek(dllist[slot].ldfd, 0L, SEEK_CUR);
dllist[slot].a_lseek = 0;
dllist[slot].count = 0;
if ((dllist[slot].dl_bsz >= 1492) || (dllist[slot].dl_bsz == 0))
dllist[slot].dl_bsz = 1492;
if (dllist[slot].dl_bsz == 1030)
dllist[slot].dl_bsz = 1000;
if (trans == TRANS_8023)
dllist[slot].dl_bsz = dllist[slot].dl_bsz - 8;
idx = 0;
mopPutHeader(pkt, &idx, dst, src, MOP_K_PROTO_DL, trans);
mopPutChar(pkt, &idx, mopcode);
mopPutChar(pkt, &idx, dllist[slot].count);
mopPutLong(pkt, &idx, dllist[slot].loadaddr);
len = mopFileRead(&dllist[slot], &pkt[idx]);
dllist[slot].nloadaddr = dllist[slot].loadaddr + len;
idx = idx + len;
mopPutLength(pkt, trans, idx);
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(dllist[slot].ii->fd, pkt, idx, trans) != idx)
if (DebugFlag)
warnx("pfWrite() error");
dllist[slot].status = DL_STATUS_SENT_MLD;
}
void
mopNextLoad(u_char *dst, u_char *src, u_char new_count, int trans)
{
int len;
int i, slot;
u_char pkt[BUFSIZE];
int idx, pidx;
char line[100],hname[17],*p;
slot = -1;
for (i = 0; i < MAXDL && slot == -1; i++)
if (dllist[i].status != DL_STATUS_FREE) {
if (mopCmpEAddr(dst, dllist[i].eaddr) == 0)
slot = i;
}
if (slot == -1)
return;
if (new_count == ((dllist[slot].count+1) % 256)) {
dllist[slot].loadaddr = dllist[slot].nloadaddr;
dllist[slot].count = new_count;
} else
return;
if (dllist[slot].status == DL_STATUS_SENT_PLT) {
close(dllist[slot].ldfd);
dllist[slot].ldfd = 0;
dllist[slot].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;
}
dllist[slot].lseek = lseek(dllist[slot].ldfd, 0L, SEEK_CUR);
if (dllist[slot].dl_bsz >= 1492)
dllist[slot].dl_bsz = 1492;
idx = 0;
mopPutHeader(pkt, &idx, dst, src, MOP_K_PROTO_DL, trans);
pidx = idx;
mopPutChar(pkt, &idx, MOP_K_CODE_MLD);
mopPutChar(pkt, &idx, dllist[slot].count);
mopPutLong(pkt, &idx, dllist[slot].loadaddr);
len = mopFileRead(&dllist[slot], &pkt[idx]);
if (len > 0) {
dllist[slot].nloadaddr = dllist[slot].loadaddr + len;
idx = idx + len;
mopPutLength(pkt, trans, idx);
} else {
if (len == 0) {
i = gethostname(hname, sizeof(hname));
p = strchr(hname, '.');
if (p != NULL)
*p = 0;
idx = pidx;
mopPutChar(pkt, &idx, MOP_K_CODE_PLT);
mopPutChar(pkt, &idx, dllist[slot].count);
mopPutChar(pkt, &idx, MOP_K_PLTP_HSN);
mopPutChar(pkt, &idx, (int)strlen(hname));
mopPutMulti(pkt, &idx, (u_char *)hname, (int)strlen(hname));
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, dllist[slot].xferaddr);
mopPutLength(pkt, trans, idx);
dllist[slot].status = DL_STATUS_SENT_PLT;
} else {
dllist[slot].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(dllist[slot].ii->fd, pkt, idx, trans) != idx)
if (DebugFlag)
warnx("pfWrite() error");
}
void
mopProcessDL(FILE *fd, struct if_info *ii, u_char *pkt, int *idx, u_char *dst,
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;
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:
mopGetChar(pkt, idx);
tmpc = mopGetChar(pkt, idx);
if ((tmpc != MOP_K_RPR_FORMAT) &&
(tmpc != MOP_K_RPR_FORMAT_V3)) {
fprintf(stderr, "mopd: Unknown RPR Format (%d) from ",
tmpc);
mopPrintHWA(stderr, src);
fprintf(stderr, "\n");
}
mopGetChar(pkt, idx);
tmpc = mopGetChar(pkt, idx);
if (tmpc > sizeof(pfile) - 1)
return;
for (i = 0; i < tmpc; i++) {
pfile[i] = mopGetChar(pkt, idx);
pfile[i+1] = '\0';
}
if (tmpc == 0) {
snprintf((char *)pfile, sizeof pfile,
"%02x%02x%02x%02x%02x%02x%c",
src[0], src[1], src[2], src[3], src[4], src[5], 0);
}
mopGetChar(pkt, idx);
dl_rpr = &dl;
bzero(dl_rpr, sizeof(*dl_rpr));
dl_rpr->ii = ii;
bcopy(src, dl_rpr->eaddr, 6);
mopProcessInfo(pkt, idx, moplen, dl_rpr, trans);
snprintf(filename, sizeof(filename), "%s.SYS", pfile);
if ((mopCmpEAddr(dst, dl_mcst) == 0)) {
if ((nfd = open(filename, O_RDONLY)) != -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);
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);
mopGetChar(pkt, idx);
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, u_char *pkt, int *idx, u_char dst,
u_char *src, int trans, u_short len)
{
u_char tmpc;
u_short tmps, 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);
if ((DebugFlag >= DEBUG_INFO))
fprintf(stderr, "Reserved : %02x\n", tmpc);
tmps = mopGetShort(pkt, idx);
if ((DebugFlag >= DEBUG_INFO))
fprintf(stderr, "Receipt Nbr : %04x\n", tmps);
dl_rpr = &dl;
bzero(dl_rpr, sizeof(*dl_rpr));
dl_rpr->ii = ii;
bcopy(src, dl_rpr->eaddr, 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;
}
}