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