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