Home | History | Annotate | Line # | Download | only in mopd
      1 /*	$NetBSD: process.c,v 1.21 2016/06/08 01:11:49 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1993-95 Mats O Jansson.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "port.h"
     28 #ifndef lint
     29 __RCSID("$NetBSD: process.c,v 1.21 2016/06/08 01:11:49 christos Exp $");
     30 #endif
     31 
     32 #include "os.h"
     33 #include "cmp.h"
     34 #include "common.h"
     35 #include "dl.h"
     36 #include "file.h"
     37 #include "get.h"
     38 #include "mopdef.h"
     39 #include "nmadef.h"
     40 #include "pf.h"
     41 #include "print.h"
     42 #include "put.h"
     43 #include "rc.h"
     44 
     45 extern u_char	buf[];
     46 extern int	DebugFlag;
     47 extern char 	*MopdDir;
     48 
     49 struct dllist dllist[MAXDL];		/* dump/load list		*/
     50 
     51 void	mopNextLoad(const u_char *, const u_char *, u_char, int);
     52 void	mopProcessDL(FILE *, struct if_info *, const u_char *, int *,
     53 	    const u_char *, const u_char *, int, u_short);
     54 void	mopProcessRC(FILE *, struct if_info *, const u_char *, int *,
     55 	    const u_char *, const u_char *, int, u_short);
     56 void	mopProcessInfo(const u_char *, int *, u_short, struct dllist *, int);
     57 void	mopSendASV(const u_char *, const u_char *, struct if_info *, int);
     58 void	mopStartLoad(const u_char *, const u_char *, struct dllist *, int);
     59 
     60 void
     61 mopProcessInfo(const u_char *pkt, int *idx, u_short moplen, struct dllist *dl_rpr,
     62 	       int trans)
     63 {
     64         u_short itype,tmps;
     65 	u_char  ilen ,tmpc,device;
     66 	const u_char *ucp;
     67 
     68 	device = 0;
     69 
     70 	switch(trans) {
     71 	case TRANS_ETHER:
     72 		moplen = moplen + 16;
     73 		break;
     74 	case TRANS_8023:
     75 		moplen = moplen + 14;
     76 		break;
     77 	}
     78 
     79 	itype = mopGetShort(pkt,idx);
     80 
     81 	while (*idx < (int)(moplen)) {
     82 		ilen  = mopGetChar(pkt,idx);
     83 		switch (itype) {
     84 		case 0:
     85 			tmpc  = mopGetChar(pkt,idx);
     86 			*idx = *idx + tmpc;
     87 			break;
     88 		case MOP_K_INFO_VER:
     89 			(void)mopGetChar(pkt,idx);
     90 			(void)mopGetChar(pkt,idx);
     91 			(void)mopGetChar(pkt,idx);
     92 			break;
     93 		case MOP_K_INFO_MFCT:
     94 			tmps = mopGetShort(pkt,idx);
     95 			break;
     96 		case MOP_K_INFO_CNU:
     97 			ucp = pkt + *idx; *idx = *idx + 6;
     98 			break;
     99 		case MOP_K_INFO_RTM:
    100 			tmps = mopGetShort(pkt,idx);
    101 			break;
    102 		case MOP_K_INFO_CSZ:
    103 			tmps = mopGetShort(pkt,idx);
    104 			break;
    105 		case MOP_K_INFO_RSZ:
    106 			tmps = mopGetShort(pkt,idx);
    107 			break;
    108 		case MOP_K_INFO_HWA:
    109 			ucp = pkt + *idx; *idx = *idx + 6;
    110 			break;
    111 		case MOP_K_INFO_TIME:
    112 			ucp = pkt + *idx; *idx = *idx + 10;
    113 			break;
    114 		case MOP_K_INFO_SOFD:
    115 			device = mopGetChar(pkt,idx);
    116 			break;
    117 		case MOP_K_INFO_SFID:
    118 			tmpc = mopGetChar(pkt,idx);
    119 			ucp = pkt + *idx; *idx = *idx + tmpc;
    120 			break;
    121 		case MOP_K_INFO_PRTY:
    122 			tmpc = mopGetChar(pkt,idx);
    123 			break;
    124 		case MOP_K_INFO_DLTY:
    125 			tmpc = mopGetChar(pkt,idx);
    126 			break;
    127 		case MOP_K_INFO_DLBSZ:
    128 			tmps = mopGetShort(pkt,idx);
    129 			dl_rpr->dl_bsz = tmps;
    130 			break;
    131 		default:
    132 			if (((device = NMA_C_SOFD_LCS) ||   /* DECserver 100 */
    133 			     (device = NMA_C_SOFD_DS2) ||   /* DECserver 200 */
    134 			     (device = NMA_C_SOFD_DP2) ||   /* DECserver 250 */
    135 			     (device = NMA_C_SOFD_DS3)) &&  /* DECserver 300 */
    136 			    ((itype > 101) && (itype < 107)))
    137 			{
    138 				switch (itype) {
    139 				case 102:
    140 					ucp = pkt + *idx;
    141 					*idx = *idx + ilen;
    142 					break;
    143 				case 103:
    144 					ucp = pkt + *idx;
    145 					*idx = *idx + ilen;
    146 					break;
    147 				case 104:
    148 					tmps = mopGetShort(pkt,idx);
    149 					break;
    150 				case 105:
    151 					ucp = pkt + *idx;
    152 					*idx = *idx + ilen;
    153 					break;
    154 				case 106:
    155 					ucp = pkt + *idx;
    156 					*idx = *idx + ilen;
    157 					break;
    158 				};
    159 			} else {
    160 				ucp = pkt + *idx; *idx = *idx + ilen;
    161 			};
    162 		}
    163 		itype = mopGetShort(pkt,idx);
    164         }
    165 	__USE(ucp);
    166 }
    167 
    168 void
    169 mopSendASV(const u_char *dst, const u_char *src, struct if_info *ii, int trans)
    170 {
    171         u_char	 pkt[200];
    172 	int	 idx;
    173 	u_char	 mopcode = MOP_K_CODE_ASV;
    174 	u_short	 ptype = MOP_K_PROTO_DL;
    175 
    176 	idx = 0;
    177 	mopPutHeader(pkt, &idx, dst, src, ptype, trans);
    178 
    179 	mopPutChar(pkt,&idx,mopcode);
    180 
    181 	mopPutLength(pkt, trans, idx);
    182 	(void)mopGetLength(pkt, trans);
    183 
    184 	if (DebugFlag == DEBUG_ONELINE) {
    185 		mopPrintOneline(stdout, pkt, trans);
    186 	}
    187 
    188 	if (DebugFlag >= DEBUG_HEADER) {
    189 		mopPrintHeader(stdout, pkt, trans);
    190 		mopPrintMopHeader(stdout, pkt, trans);
    191 	}
    192 
    193 	if (DebugFlag >= DEBUG_INFO) {
    194 		mopDumpDL(stdout, pkt, trans);
    195 	}
    196 
    197 	if (pfWrite(ii->fd, pkt, idx, trans) != idx) {
    198 		if (DebugFlag) {
    199 			(void)fprintf(stderr, "error pfWrite()\n");
    200 		}
    201 	}
    202 }
    203 
    204 #define MAX_ETH_PAYLOAD 1492
    205 
    206 void
    207 mopStartLoad(const u_char *dst, const u_char *src, struct dllist *dl_rpr,
    208 	     int trans)
    209 {
    210 	int	 len;
    211 	int	 i, slot;
    212 	u_char	 pkt[BUFSIZE];
    213 	int	 idx;
    214 	u_char	 mopcode = MOP_K_CODE_MLD;
    215 	u_short	 ptype = MOP_K_PROTO_DL;
    216 	struct dllist *dle;
    217 
    218 	slot = -1;
    219 
    220 	/* Look if we have a non terminated load, if so, use its slot */
    221 
    222 	for (i = 0, dle = dllist; i < MAXDL; i++, dle++) {
    223 		if (dle->status != DL_STATUS_FREE) {
    224 			if (mopCmpEAddr(dle->eaddr, dst) == 0) {
    225 				slot = i;
    226 			}
    227 		}
    228 	}
    229 
    230 	/* If no slot yet, then find first free */
    231 
    232 	if (slot == -1) {
    233 		for (i = 0, dle = dllist; i < MAXDL; i++, dle++) {
    234 			if (dle->status == DL_STATUS_FREE) {
    235 				if (slot == -1) {
    236 					slot = i;
    237 					memmove((char *)dle->eaddr,
    238 					    (const char *)dst, 6);
    239 				}
    240 			}
    241 		}
    242 	}
    243 
    244 	/* If no slot yet, then return. No slot is free */
    245 
    246 	if (slot == -1)
    247 		return;
    248 
    249 	/* Ok, save info from RPR */
    250 
    251 	dllist[slot] = *dl_rpr;
    252 	dle = &dllist[slot];
    253 	dle->status = DL_STATUS_READ_IMGHDR;
    254 
    255 	/* Get Load and Transfer Address. */
    256 
    257 	GetFileInfo(dle);
    258 
    259 	dle->nloadaddr = dle->loadaddr;
    260 	dle->lseek     = lseek(dle->ldfd, 0L, SEEK_CUR);
    261 	dle->a_lseek   = 0;
    262 
    263 	dle->count     = 0;
    264 	if (dle->dl_bsz >= MAX_ETH_PAYLOAD || dle->dl_bsz == 0)
    265 		dle->dl_bsz = MAX_ETH_PAYLOAD;
    266 	if (dle->dl_bsz == 1030)	/* VS/uVAX 2000 needs this */
    267 		dle->dl_bsz = 1000;
    268 	if (dle->dl_bsz == 0)		/* Needed by "big" VAXen */
    269 		dle->dl_bsz = MAX_ETH_PAYLOAD;
    270 	if (trans == TRANS_8023)
    271 		dle->dl_bsz = dle->dl_bsz - 8;
    272 
    273 	idx = 0;
    274 	mopPutHeader(pkt, &idx, dst, src, ptype, trans);
    275 	mopPutChar (pkt, &idx, mopcode);
    276 
    277 	mopPutChar (pkt, &idx, dle->count);
    278 	mopPutLong (pkt, &idx, dle->loadaddr);
    279 
    280 	len = mopFileRead(dle, &pkt[idx]);
    281 
    282 	dle->nloadaddr = dle->loadaddr + len;
    283 	idx = idx + len;
    284 
    285 	mopPutLength(pkt, trans, idx);
    286 	(void)mopGetLength(pkt, trans);
    287 
    288 	if (DebugFlag == DEBUG_ONELINE) {
    289 		mopPrintOneline(stdout, pkt, trans);
    290 	}
    291 
    292 	if (DebugFlag >= DEBUG_HEADER) {
    293 		mopPrintHeader(stdout, pkt, trans);
    294 		mopPrintMopHeader(stdout, pkt, trans);
    295 	}
    296 
    297 	if (DebugFlag >= DEBUG_INFO) {
    298 		mopDumpDL(stdout, pkt, trans);
    299 	}
    300 
    301 	if (pfWrite(dle->ii->fd, pkt, idx, trans) != idx) {
    302 		if (DebugFlag) {
    303 			(void)fprintf(stderr, "error pfWrite()\n");
    304 		}
    305 	}
    306 
    307 	dle->status = DL_STATUS_SENT_MLD;
    308 }
    309 
    310 void
    311 mopNextLoad(const u_char *dst, const u_char *src, u_char new_count, int trans)
    312 {
    313 	int	 len;
    314 	int	 i, slot;
    315 	u_char	 pkt[BUFSIZE];
    316 	int	 idx, pindex;
    317 	char	 line[100];
    318 	u_short  ptype = MOP_K_PROTO_DL;
    319 	u_char	 mopcode;
    320 	struct dllist *dle;
    321 
    322 	slot = -1;
    323 
    324 	for (i = 0, dle = dllist; i < MAXDL; i++, dle++) {
    325 		if (dle->status != DL_STATUS_FREE) {
    326 			if (mopCmpEAddr(dst, dle->eaddr) == 0)
    327 				slot = i;
    328 		}
    329 	}
    330 
    331 	/* If no slot yet, then return. No slot is free */
    332 
    333 	if (slot == -1)
    334 		return;
    335 
    336 	dle = &dllist[slot];
    337 
    338 	if (new_count == ((dle->count+1) % 256)) {
    339 		dle->loadaddr = dllist[slot].nloadaddr;
    340 		dle->count    = new_count;
    341 	} else if (new_count != (dle->count % 256)) {
    342 		return;
    343 	}
    344 
    345 	if (dle->status == DL_STATUS_SENT_PLT) {
    346 		close(dle->ldfd);
    347 		dle->ldfd = -1;
    348 		dle->status = DL_STATUS_FREE;
    349 		snprintf(line, sizeof(line),
    350 			"%x:%x:%x:%x:%x:%x Load completed",
    351 			dst[0],dst[1],dst[2],dst[3],dst[4],dst[5]);
    352 		syslog(LOG_INFO, "%s", line);
    353 		return;
    354 	}
    355 
    356 	dle->lseek     = lseek(dle->ldfd, 0L, SEEK_CUR);
    357 
    358 	if (dle->dl_bsz >= MAX_ETH_PAYLOAD)
    359 		dle->dl_bsz = MAX_ETH_PAYLOAD;
    360 
    361 	idx = 0;
    362 	mopPutHeader(pkt, &idx, dst, src, ptype, trans);
    363 	mopcode = MOP_K_CODE_MLD;
    364 	pindex = idx;
    365 	mopPutChar (pkt,&idx, mopcode);
    366 	mopPutChar (pkt,&idx, dle->count);
    367 	mopPutLong (pkt,&idx, dle->loadaddr);
    368 
    369 	len = mopFileRead(dle, &pkt[idx]);
    370 
    371 	if (len > 0 ) {
    372 
    373 		dle->nloadaddr = dle->loadaddr + len;
    374 		idx = idx + len;
    375 
    376 		mopPutLength(pkt, trans, idx);
    377 		(void)mopGetLength(pkt, trans);
    378 
    379 	} else {
    380 		if (len == 0) {
    381 			idx = pindex;
    382 			mopcode = MOP_K_CODE_PLT;
    383 			mopPutChar (pkt, &idx, mopcode);
    384 			mopPutChar (pkt, &idx, dle->count);
    385 			mopPutChar (pkt, &idx, MOP_K_PLTP_HSN);
    386  			mopPutChar (pkt, &idx, 3);
    387 			mopPutMulti(pkt, &idx, "ipc", 3);
    388 			mopPutChar (pkt, &idx, MOP_K_PLTP_HSA);
    389 			mopPutChar (pkt, &idx, 6);
    390 			mopPutMulti(pkt, &idx, src, 6);
    391 			mopPutChar (pkt, &idx, MOP_K_PLTP_HST);
    392 			mopPutTime (pkt, &idx, 0);
    393 			mopPutChar (pkt, &idx, 0);
    394 			mopPutLong (pkt, &idx, dle->xferaddr);
    395 
    396 			mopPutLength(pkt, trans, idx);
    397 			(void)mopGetLength(pkt, trans);
    398 
    399 			dle->status = DL_STATUS_SENT_PLT;
    400 		} else {
    401 			dle->status = DL_STATUS_FREE;
    402 			return;
    403 		}
    404 	}
    405 
    406 	if (DebugFlag == DEBUG_ONELINE) {
    407 		mopPrintOneline(stdout, pkt, trans);
    408 	}
    409 
    410 	if (DebugFlag >= DEBUG_HEADER) {
    411 		mopPrintHeader(stdout, pkt, trans);
    412 		mopPrintMopHeader(stdout, pkt, trans);
    413 	}
    414 
    415 	if (DebugFlag >= DEBUG_INFO) {
    416 		mopDumpDL(stdout, pkt, trans);
    417 	}
    418 
    419 	if (pfWrite(dle->ii->fd, pkt, idx, trans) != idx) {
    420 		if (DebugFlag) {
    421 			(void)fprintf(stderr, "error pfWrite()\n");
    422 		}
    423 	}
    424 }
    425 
    426 void
    427 mopProcessDL(FILE *fd, struct if_info *ii, const u_char *pkt, int *idx,
    428 	     const u_char *dst, const u_char *src, int trans, u_short len)
    429 {
    430 	u_char  tmpc;
    431 	u_short moplen;
    432 	u_char  pfile[129], mopcode;
    433 	char    filename[FILENAME_MAX];
    434 	char    line[100];
    435 	int     i, nfd;
    436 	struct dllist dl, *dl_rpr;
    437 	u_char  load;
    438 
    439 	if (DebugFlag == DEBUG_ONELINE) {
    440 		mopPrintOneline(stdout, pkt, trans);
    441 	}
    442 
    443 	if (DebugFlag >= DEBUG_HEADER) {
    444 		mopPrintHeader(stdout, pkt, trans);
    445 		mopPrintMopHeader(stdout, pkt, trans);
    446 	}
    447 
    448 	if (DebugFlag >= DEBUG_INFO) {
    449 		mopDumpDL(stdout, pkt, trans);
    450 	}
    451 
    452 	moplen  = mopGetLength(pkt, trans);
    453 	mopcode = mopGetChar(pkt,idx);
    454 
    455 	switch (mopcode) {
    456 	case MOP_K_CODE_MLT:
    457 		break;
    458 	case MOP_K_CODE_DCM:
    459 		break;
    460 	case MOP_K_CODE_MLD:
    461 		break;
    462 	case MOP_K_CODE_ASV:
    463 		break;
    464 	case MOP_K_CODE_RMD:
    465 		break;
    466 	case MOP_K_CODE_RPR:
    467 
    468 		tmpc = mopGetChar(pkt,idx);		/* Device Type */
    469 
    470 		tmpc = mopGetChar(pkt,idx);		/* Format Version */
    471 		if ((tmpc != MOP_K_RPR_FORMAT) &&
    472 		    (tmpc != MOP_K_RPR_FORMAT_V3)) {
    473 			(void)fprintf(stderr,"mopd: Unknown RPR Format (%d) from ",tmpc);
    474 			mopPrintHWA(stderr,src);
    475 			(void)fprintf(stderr,"\n");
    476 		}
    477 
    478 		(void)mopGetChar(pkt,idx);	/* Program Type */
    479 
    480 		tmpc = mopGetChar(pkt,idx);		/* Software ID Len */
    481 		if (tmpc > sizeof(pfile) - 1)
    482 			return;
    483 		for (i = 0; i < tmpc; i++) {
    484 			pfile[i] = mopGetChar(pkt,idx);
    485 			pfile[i+1] = '\0';
    486 		}
    487 
    488 		if (tmpc == 0) {
    489 			/* In a normal implementation of a MOP Loader this */
    490 			/* would cause a question to NML (DECnet) if this  */
    491 			/* node is known and if so what image to load. But */
    492 			/* we don't have DECnet so we don't have anybody   */
    493 			/* to ask. My solution is to use the ethernet addr */
    494 			/* as filename. Implementing a database would be   */
    495 			/* overkill.					   */
    496 			snprintf(pfile, sizeof(pfile),
    497 			    "%02x%02x%02x%02x%02x%02x%c",
    498 			    src[0],src[1],src[2],src[3],src[4],src[5],0);
    499 		}
    500 
    501 		tmpc = mopGetChar(pkt,idx);		/* Processor */
    502 
    503 		dl_rpr = &dl;
    504 		memset(dl_rpr, 0, sizeof(*dl_rpr));
    505 		dl_rpr->ii = ii;
    506 		memmove((char *)(dl_rpr->eaddr), (const char *)src, 6);
    507 		mopProcessInfo(pkt,idx,moplen,dl_rpr,trans);
    508 
    509 		snprintf(filename, sizeof(filename), "%s/%s.SYS",
    510 		    MopdDir, pfile);
    511 		if ((mopCmpEAddr(dst,dl_mcst) == 0)) {
    512 			if ((nfd = open(filename, O_RDONLY, 0)) != -1) {
    513 				close(nfd);
    514 				mopSendASV(src, ii->eaddr, ii, trans);
    515 				snprintf(line, sizeof(line),
    516 					"%x:%x:%x:%x:%x:%x (%d) Do you have %s? (Yes)",
    517 					src[0],src[1],src[2],
    518 					src[3],src[4],src[5],trans,pfile);
    519 			} else {
    520 				snprintf(line, sizeof(line),
    521 					"%x:%x:%x:%x:%x:%x (%d) Do you have %s? (No)",
    522 					src[0],src[1],src[2],
    523 					src[3],src[4],src[5],trans,pfile);
    524 			}
    525 			syslog(LOG_INFO, "%s", line);
    526 		} else {
    527 			if ((mopCmpEAddr(dst,ii->eaddr) == 0)) {
    528 				dl_rpr->ldfd = open(filename, O_RDONLY, 0);
    529 				mopStartLoad(src, ii->eaddr, dl_rpr, trans);
    530 				snprintf(line, sizeof(line),
    531 					"%x:%x:%x:%x:%x:%x Send me %s",
    532 					src[0],src[1],src[2],
    533 					src[3],src[4],src[5],pfile);
    534 				syslog(LOG_INFO, "%s", line);
    535 			}
    536 		}
    537 
    538 		break;
    539 	case MOP_K_CODE_RML:
    540 
    541 		load = mopGetChar(pkt,idx);		/* Load Number	*/
    542 
    543 		tmpc = mopGetChar(pkt,idx);		/* Error	*/
    544 
    545 		if ((mopCmpEAddr(dst,ii->eaddr) == 0)) {
    546 			mopNextLoad(src, ii->eaddr, load, trans);
    547 		}
    548 
    549 		break;
    550 	case MOP_K_CODE_RDS:
    551 		break;
    552 	case MOP_K_CODE_MDD:
    553 		break;
    554 	case MOP_K_CODE_CCP:
    555 		break;
    556 	case MOP_K_CODE_PLT:
    557 		break;
    558 	default:
    559 		break;
    560 	}
    561 }
    562 
    563 void
    564 mopProcessRC(FILE *fd, struct if_info *ii, const u_char *pkt, int *idx,
    565 	     const u_char *dst, const u_char *src, int trans, u_short len)
    566 {
    567 	u_char	 tmpc;
    568 	u_short	 moplen = 0;
    569 	u_char   mopcode;
    570 	struct dllist dl,*dl_rpr;
    571 
    572 	if (DebugFlag == DEBUG_ONELINE) {
    573 		mopPrintOneline(stdout, pkt, trans);
    574 	}
    575 
    576 	if (DebugFlag >= DEBUG_HEADER) {
    577 		mopPrintHeader(stdout, pkt, trans);
    578 		mopPrintMopHeader(stdout, pkt, trans);
    579 	}
    580 
    581 	if (DebugFlag >= DEBUG_INFO) {
    582 		mopDumpRC(stdout, pkt, trans);
    583 	}
    584 
    585 	moplen  = mopGetLength(pkt, trans);
    586 	mopcode = mopGetChar(pkt,idx);
    587 
    588 	switch (mopcode) {
    589 	case MOP_K_CODE_RID:
    590 		break;
    591 	case MOP_K_CODE_BOT:
    592 		break;
    593 	case MOP_K_CODE_SID:
    594 
    595 		tmpc = mopGetChar(pkt,idx);		/* Reserved */
    596 
    597 		if ((DebugFlag >= DEBUG_INFO)) {
    598 			(void)fprintf(stderr, "Reserved     :   %02x\n",tmpc);
    599 		}
    600 
    601 		(void)mopGetShort(pkt,idx);		/* Receipt # */
    602 		if ((DebugFlag >= DEBUG_INFO)) {
    603 			(void)fprintf(stderr, "Receipt Nbr  : %04x\n",tmpc);
    604 		}
    605 
    606 		dl_rpr = &dl;
    607 		memset(dl_rpr, 0, sizeof(*dl_rpr));
    608 		dl_rpr->ii = ii;
    609 		memmove((char *)(dl_rpr->eaddr), (const char *)src, 6);
    610 		mopProcessInfo(pkt,idx,moplen,dl_rpr,trans);
    611 
    612 		break;
    613 	case MOP_K_CODE_RQC:
    614 		break;
    615 	case MOP_K_CODE_CNT:
    616 		break;
    617 	case MOP_K_CODE_RVC:
    618 		break;
    619 	case MOP_K_CODE_RLC:
    620 		break;
    621 	case MOP_K_CODE_CCP:
    622 		break;
    623 	case MOP_K_CODE_CRA:
    624 		break;
    625 	default:
    626 		break;
    627 	}
    628 }
    629 
    630