xref: /netbsd-src/usr.sbin/mopd/mopd/process.c (revision cdd21bd307854e72bdd5f364023525b60c7c4218)
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
mopProcessInfo(const u_char * pkt,int * idx,u_short moplen,struct dllist * dl_rpr,int trans)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
mopSendASV(const u_char * dst,const u_char * src,struct if_info * ii,int trans)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
mopStartLoad(const u_char * dst,const u_char * src,struct dllist * dl_rpr,int trans)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
mopNextLoad(const u_char * dst,const u_char * src,u_char new_count,int trans)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
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)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
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)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