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