File: | src/usr.sbin/mopd/mopd/process.c |
Warning: | line 293, column 4 Value stored to 'i' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: process.c,v 1.25 2023/03/08 04:43:14 guenther 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 "os.h" |
28 | #include "common/common.h" |
29 | #include "common/mopdef.h" |
30 | #include "common/nmadef.h" |
31 | #include "common/get.h" |
32 | #include "common/put.h" |
33 | #include "common/print.h" |
34 | #include "common/pf.h" |
35 | #include "common/cmp.h" |
36 | #include "common/dl.h" |
37 | #include "common/rc.h" |
38 | #include "common/file.h" |
39 | |
40 | extern int DebugFlag; |
41 | |
42 | struct dllist dllist[MAXDL16]; /* dump/load list */ |
43 | |
44 | void |
45 | mopProcessInfo(u_char *pkt, int *idx, u_short moplen, struct dllist *dl_rpr, |
46 | int trans) |
47 | { |
48 | u_short itype, tmps; |
49 | u_char ilen, tmpc, device; |
50 | |
51 | device = 0; |
52 | |
53 | switch (trans) { |
54 | case TRANS_ETHER1: |
55 | moplen = moplen + 16; |
56 | break; |
57 | case TRANS_80232: |
58 | moplen = moplen + 14; |
59 | break; |
60 | } |
61 | |
62 | itype = mopGetShort(pkt, idx); |
63 | |
64 | while (*idx < (int)(moplen)) { |
65 | ilen = mopGetChar(pkt, idx); |
66 | switch (itype) { |
67 | case 0: |
68 | tmpc = mopGetChar(pkt, idx); |
69 | *idx = *idx + tmpc; |
70 | break; |
71 | case MOP_K_INFO_VER1: |
72 | *idx = *idx + 3; |
73 | break; |
74 | case MOP_K_INFO_MFCT2: |
75 | case MOP_K_INFO_RTM4: |
76 | case MOP_K_INFO_CSZ5: |
77 | case MOP_K_INFO_RSZ6: |
78 | mopGetShort(pkt, idx); |
79 | break; |
80 | case MOP_K_INFO_CNU3: |
81 | case MOP_K_INFO_HWA7: |
82 | *idx = *idx + 6; |
83 | break; |
84 | case MOP_K_INFO_TIME8: |
85 | *idx = *idx + 10; |
86 | break; |
87 | case MOP_K_INFO_SOFD100: |
88 | device = mopGetChar(pkt, idx); |
89 | break; |
90 | case MOP_K_INFO_SFID200: |
91 | tmpc = mopGetChar(pkt, idx); |
92 | *idx = *idx + tmpc; |
93 | break; |
94 | case MOP_K_INFO_PRTY300: |
95 | case MOP_K_INFO_DLTY400: |
96 | mopGetChar(pkt, idx); |
97 | break; |
98 | case MOP_K_INFO_DLBSZ401: |
99 | tmps = mopGetShort(pkt, idx); |
100 | dl_rpr->dl_bsz = tmps; |
101 | break; |
102 | default: |
103 | if (((device == NMA_C_SOFD_LCS17) || /* DECserver 100 */ |
104 | (device == NMA_C_SOFD_DS233) || /* DECserver 200 */ |
105 | (device == NMA_C_SOFD_DP272) || /* DECserver 250 */ |
106 | (device == NMA_C_SOFD_DS360)) && /* DECserver 300 */ |
107 | ((itype > 101) && (itype < 107))) { |
108 | switch (itype) { |
109 | case 102: |
110 | case 103: |
111 | case 105: |
112 | case 106: |
113 | *idx = *idx + ilen; |
114 | break; |
115 | case 104: |
116 | mopGetShort(pkt, idx); |
117 | break; |
118 | } |
119 | } else |
120 | *idx = *idx + ilen; |
121 | } |
122 | itype = mopGetShort(pkt, idx); |
123 | } |
124 | } |
125 | |
126 | void |
127 | mopSendASV(u_char *dst, u_char *src, struct if_info *ii, int trans) |
128 | { |
129 | u_char pkt[200]; |
130 | int idx; |
131 | |
132 | idx = 0; |
133 | mopPutHeader(pkt, &idx, dst, src, MOP_K_PROTO_DL0x6001, trans); |
134 | |
135 | mopPutChar(pkt, &idx, MOP_K_CODE_ASV3); |
136 | |
137 | mopPutLength(pkt, trans, idx); |
138 | |
139 | if (DebugFlag == DEBUG_ONELINE1) |
140 | mopPrintOneline(stdout(&__sF[1]), pkt, trans); |
141 | |
142 | if (DebugFlag >= DEBUG_HEADER2) { |
143 | mopPrintHeader(stdout(&__sF[1]), pkt, trans); |
144 | mopPrintMopHeader(stdout(&__sF[1]), pkt, trans); |
145 | } |
146 | |
147 | if (DebugFlag >= DEBUG_INFO3) |
148 | mopDumpDL(stdout(&__sF[1]), pkt, trans); |
149 | |
150 | if (pfWrite(ii->fd, pkt, idx, trans) != idx) |
151 | if (DebugFlag) |
152 | warnx("pfWrite() error"); |
153 | } |
154 | |
155 | void |
156 | mopStartLoad(u_char *dst, u_char *src, struct dllist *dl_rpr, int trans) |
157 | { |
158 | int len; |
159 | int i, slot; |
160 | u_char pkt[BUFSIZE1600]; |
161 | int idx; |
162 | u_char mopcode = MOP_K_CODE_MLD2; |
163 | |
164 | slot = -1; |
165 | |
166 | /* Look if we have a non terminated load, if so, use its slot */ |
167 | for (i = 0; i < MAXDL16 && slot == -1; i++) |
168 | if (dllist[i].status != DL_STATUS_FREE0) |
169 | if (mopCmpEAddr(dllist[i].eaddr, dst) == 0) |
170 | slot = i; |
171 | |
172 | /* If no slot yet, then find first free */ |
173 | for (i = 0; slot == -1 && i < MAXDL16; i++) |
174 | if (dllist[i].status == DL_STATUS_FREE0) { |
175 | slot = i; |
176 | bcopy(dst, dllist[i].eaddr, 6); |
177 | } |
178 | |
179 | /* If no slot yet, then return. No slot is free */ |
180 | if (slot == -1) |
181 | return; |
182 | |
183 | /* Ok, save info from RPR */ |
184 | dllist[slot] = *dl_rpr; |
185 | dllist[slot].status = DL_STATUS_READ_IMGHDR1; |
186 | |
187 | /* Get Load and Transfer Address. */ |
188 | GetFileInfo(&dllist[slot], 0); |
189 | |
190 | dllist[slot].nloadaddr = dllist[slot].loadaddr; |
191 | dllist[slot].lseek = lseek(dllist[slot].ldfd, 0L, SEEK_CUR1); |
192 | dllist[slot].a_lseek = 0; |
193 | |
194 | dllist[slot].count = 0; |
195 | if ((dllist[slot].dl_bsz >= 1492) || (dllist[slot].dl_bsz == 0)) |
196 | dllist[slot].dl_bsz = 1492; |
197 | if (dllist[slot].dl_bsz == 1030) /* VS/uVAX 2000 needs this */ |
198 | dllist[slot].dl_bsz = 1000; |
199 | if (trans == TRANS_80232) |
200 | dllist[slot].dl_bsz = dllist[slot].dl_bsz - 8; |
201 | |
202 | idx = 0; |
203 | mopPutHeader(pkt, &idx, dst, src, MOP_K_PROTO_DL0x6001, trans); |
204 | mopPutChar(pkt, &idx, mopcode); |
205 | |
206 | mopPutChar(pkt, &idx, dllist[slot].count); |
207 | mopPutLong(pkt, &idx, dllist[slot].loadaddr); |
208 | |
209 | len = mopFileRead(&dllist[slot], &pkt[idx]); |
210 | |
211 | dllist[slot].nloadaddr = dllist[slot].loadaddr + len; |
212 | idx = idx + len; |
213 | |
214 | mopPutLength(pkt, trans, idx); |
215 | |
216 | if (DebugFlag == DEBUG_ONELINE1) |
217 | mopPrintOneline(stdout(&__sF[1]), pkt, trans); |
218 | |
219 | if (DebugFlag >= DEBUG_HEADER2) { |
220 | mopPrintHeader(stdout(&__sF[1]), pkt, trans); |
221 | mopPrintMopHeader(stdout(&__sF[1]), pkt, trans); |
222 | } |
223 | |
224 | if (DebugFlag >= DEBUG_INFO3) |
225 | mopDumpDL(stdout(&__sF[1]), pkt, trans); |
226 | |
227 | if (pfWrite(dllist[slot].ii->fd, pkt, idx, trans) != idx) |
228 | if (DebugFlag) |
229 | warnx("pfWrite() error"); |
230 | |
231 | dllist[slot].status = DL_STATUS_SENT_MLD2; |
232 | } |
233 | |
234 | void |
235 | mopNextLoad(u_char *dst, u_char *src, u_char new_count, int trans) |
236 | { |
237 | int len; |
238 | int i, slot; |
239 | u_char pkt[BUFSIZE1600]; |
240 | int idx, pidx; |
241 | char line[100],hname[17],*p; |
242 | |
243 | slot = -1; |
244 | |
245 | for (i = 0; i < MAXDL16 && slot == -1; i++) |
246 | if (dllist[i].status != DL_STATUS_FREE0) { |
247 | if (mopCmpEAddr(dst, dllist[i].eaddr) == 0) |
248 | slot = i; |
249 | } |
250 | |
251 | /* If no slot yet, then return. No slot is free */ |
252 | if (slot == -1) |
253 | return; |
254 | |
255 | if (new_count == ((dllist[slot].count+1) % 256)) { |
256 | dllist[slot].loadaddr = dllist[slot].nloadaddr; |
257 | dllist[slot].count = new_count; |
258 | } else |
259 | return; |
260 | |
261 | if (dllist[slot].status == DL_STATUS_SENT_PLT3) { |
262 | close(dllist[slot].ldfd); |
263 | dllist[slot].ldfd = 0; |
264 | dllist[slot].status = DL_STATUS_FREE0; |
265 | snprintf(line, sizeof(line), |
266 | "%x:%x:%x:%x:%x:%x Load completed", |
267 | dst[0], dst[1], dst[2], dst[3], dst[4], dst[5]); |
268 | syslog(LOG_INFO6, "%s", line); |
269 | return; |
270 | } |
271 | |
272 | dllist[slot].lseek = lseek(dllist[slot].ldfd, 0L, SEEK_CUR1); |
273 | |
274 | if (dllist[slot].dl_bsz >= 1492) |
275 | dllist[slot].dl_bsz = 1492; |
276 | |
277 | idx = 0; |
278 | mopPutHeader(pkt, &idx, dst, src, MOP_K_PROTO_DL0x6001, trans); |
279 | pidx = idx; |
280 | mopPutChar(pkt, &idx, MOP_K_CODE_MLD2); |
281 | mopPutChar(pkt, &idx, dllist[slot].count); |
282 | mopPutLong(pkt, &idx, dllist[slot].loadaddr); |
283 | |
284 | len = mopFileRead(&dllist[slot], &pkt[idx]); |
285 | |
286 | if (len > 0) { |
287 | dllist[slot].nloadaddr = dllist[slot].loadaddr + len; |
288 | idx = idx + len; |
289 | |
290 | mopPutLength(pkt, trans, idx); |
291 | } else { |
292 | if (len == 0) { |
293 | i = gethostname(hname, sizeof(hname)); |
Value stored to 'i' is never read | |
294 | p = strchr(hname, '.'); |
295 | if (p != NULL((void *)0)) |
296 | *p = 0; |
297 | |
298 | idx = pidx; |
299 | mopPutChar(pkt, &idx, MOP_K_CODE_PLT20); |
300 | mopPutChar(pkt, &idx, dllist[slot].count); |
301 | mopPutChar(pkt, &idx, MOP_K_PLTP_HSN3); |
302 | mopPutChar(pkt, &idx, (int)strlen(hname)); |
303 | mopPutMulti(pkt, &idx, (u_char *)hname, (int)strlen(hname)); |
304 | mopPutChar(pkt, &idx, MOP_K_PLTP_HSA4); |
305 | mopPutChar(pkt, &idx, 6); |
306 | mopPutMulti(pkt, &idx, src, 6); |
307 | mopPutChar(pkt, &idx, MOP_K_PLTP_HST5); |
308 | mopPutTime(pkt, &idx, 0); |
309 | mopPutChar(pkt, &idx, 0); |
310 | mopPutLong(pkt, &idx, dllist[slot].xferaddr); |
311 | |
312 | mopPutLength(pkt, trans, idx); |
313 | |
314 | dllist[slot].status = DL_STATUS_SENT_PLT3; |
315 | } else { |
316 | dllist[slot].status = DL_STATUS_FREE0; |
317 | return; |
318 | } |
319 | } |
320 | |
321 | if (DebugFlag == DEBUG_ONELINE1) |
322 | mopPrintOneline(stdout(&__sF[1]), pkt, trans); |
323 | |
324 | if (DebugFlag >= DEBUG_HEADER2) { |
325 | mopPrintHeader(stdout(&__sF[1]), pkt, trans); |
326 | mopPrintMopHeader(stdout(&__sF[1]), pkt, trans); |
327 | } |
328 | |
329 | if (DebugFlag >= DEBUG_INFO3) |
330 | mopDumpDL(stdout(&__sF[1]), pkt, trans); |
331 | |
332 | if (pfWrite(dllist[slot].ii->fd, pkt, idx, trans) != idx) |
333 | if (DebugFlag) |
334 | warnx("pfWrite() error"); |
335 | } |
336 | |
337 | void |
338 | mopProcessDL(FILE *fd, struct if_info *ii, u_char *pkt, int *idx, u_char *dst, |
339 | u_char *src, int trans, u_short len) |
340 | { |
341 | u_char tmpc; |
342 | u_short moplen; |
343 | u_char pfile[129], mopcode; |
344 | char filename[FILENAME_MAX1024]; |
345 | char line[100]; |
346 | int i, nfd; |
347 | struct dllist dl, *dl_rpr; |
348 | u_char load; |
349 | |
350 | if (DebugFlag == DEBUG_ONELINE1) |
351 | mopPrintOneline(stdout(&__sF[1]), pkt, trans); |
352 | |
353 | if (DebugFlag >= DEBUG_HEADER2) { |
354 | mopPrintHeader(stdout(&__sF[1]), pkt, trans); |
355 | mopPrintMopHeader(stdout(&__sF[1]), pkt, trans); |
356 | } |
357 | |
358 | if (DebugFlag >= DEBUG_INFO3) |
359 | mopDumpDL(stdout(&__sF[1]), pkt, trans); |
360 | |
361 | moplen = mopGetLength(pkt, trans); |
362 | mopcode = mopGetChar(pkt, idx); |
363 | |
364 | switch (mopcode) { |
365 | case MOP_K_CODE_MLT0: |
366 | break; |
367 | case MOP_K_CODE_DCM1: |
368 | break; |
369 | case MOP_K_CODE_MLD2: |
370 | break; |
371 | case MOP_K_CODE_ASV3: |
372 | break; |
373 | case MOP_K_CODE_RMD4: |
374 | break; |
375 | case MOP_K_CODE_RPR8: |
376 | mopGetChar(pkt, idx); /* Device Type */ |
377 | tmpc = mopGetChar(pkt, idx); /* Format Version */ |
378 | if ((tmpc != MOP_K_RPR_FORMAT4) && |
379 | (tmpc != MOP_K_RPR_FORMAT_V31)) { |
380 | fprintf(stderr(&__sF[2]), "mopd: Unknown RPR Format (%d) from ", |
381 | tmpc); |
382 | mopPrintHWA(stderr(&__sF[2]), src); |
383 | fprintf(stderr(&__sF[2]), "\n"); |
384 | } |
385 | |
386 | mopGetChar(pkt, idx); /* Program Type */ |
387 | |
388 | tmpc = mopGetChar(pkt, idx); /* Software ID Len */ |
389 | if (tmpc > sizeof(pfile) - 1) |
390 | return; |
391 | for (i = 0; i < tmpc; i++) { |
392 | pfile[i] = mopGetChar(pkt, idx); |
393 | pfile[i+1] = '\0'; |
394 | } |
395 | |
396 | if (tmpc == 0) { |
397 | /* In a normal implementation of a MOP Loader this */ |
398 | /* would cause a question to NML (DECnet) if this */ |
399 | /* node is known and if so what image to load. But */ |
400 | /* we don't have DECnet so we don't have anybody */ |
401 | /* to ask. My solution is to use the ethernet addr */ |
402 | /* as filename. Implementing a database would be */ |
403 | /* overkill. */ |
404 | snprintf((char *)pfile, sizeof pfile, |
405 | "%02x%02x%02x%02x%02x%02x%c", |
406 | src[0], src[1], src[2], src[3], src[4], src[5], 0); |
407 | } |
408 | |
409 | mopGetChar(pkt, idx); /* Processor */ |
410 | |
411 | dl_rpr = &dl; |
412 | bzero(dl_rpr, sizeof(*dl_rpr)); |
413 | dl_rpr->ii = ii; |
414 | bcopy(src, dl_rpr->eaddr, 6); |
415 | mopProcessInfo(pkt, idx, moplen, dl_rpr, trans); |
416 | |
417 | snprintf(filename, sizeof(filename), "%s.SYS", pfile); |
418 | if ((mopCmpEAddr(dst, dl_mcst) == 0)) { |
419 | if ((nfd = open(filename, O_RDONLY0x0000)) != -1) { |
420 | close(nfd); |
421 | mopSendASV(src, ii->eaddr, ii, trans); |
422 | snprintf(line, sizeof(line), |
423 | "%x:%x:%x:%x:%x:%x (%d) Do you have %s? " |
424 | "(Yes)", src[0], src[1], src[2], src[3], |
425 | src[4], src[5], trans, pfile); |
426 | } else { |
427 | snprintf(line, sizeof(line), |
428 | "%x:%x:%x:%x:%x:%x (%d) Do you have %s? " |
429 | "(No)", src[0], src[1], src[2], src[3], |
430 | src[4], src[5], trans, pfile); |
431 | } |
432 | syslog(LOG_INFO6, "%s", line); |
433 | } else { |
434 | if ((mopCmpEAddr(dst, ii->eaddr) == 0)) { |
435 | dl_rpr->ldfd = open(filename, O_RDONLY0x0000); |
436 | mopStartLoad(src, ii->eaddr, dl_rpr, trans); |
437 | snprintf(line, sizeof(line), |
438 | "%x:%x:%x:%x:%x:%x Send me %s", |
439 | src[0], src[1], src[2], src[3], src[4], |
440 | src[5], pfile); |
441 | syslog(LOG_INFO6, "%s", line); |
442 | } |
443 | } |
444 | break; |
445 | case MOP_K_CODE_RML10: |
446 | load = mopGetChar(pkt, idx); /* Load Number */ |
447 | mopGetChar(pkt, idx); /* Error */ |
448 | if ((mopCmpEAddr(dst, ii->eaddr) == 0)) |
449 | mopNextLoad(src, ii->eaddr, load, trans); |
450 | break; |
451 | case MOP_K_CODE_RDS12: |
452 | break; |
453 | case MOP_K_CODE_MDD14: |
454 | break; |
455 | case MOP_K_CODE_CCP17: |
456 | break; |
457 | case MOP_K_CODE_PLT20: |
458 | break; |
459 | default: |
460 | break; |
461 | } |
462 | } |
463 | |
464 | void |
465 | mopProcessRC(FILE *fd, struct if_info *ii, u_char *pkt, int *idx, u_char dst, |
466 | u_char *src, int trans, u_short len) |
467 | { |
468 | u_char tmpc; |
469 | u_short tmps, moplen = 0; |
470 | u_char mopcode; |
471 | struct dllist dl, *dl_rpr; |
472 | |
473 | if (DebugFlag == DEBUG_ONELINE1) |
474 | mopPrintOneline(stdout(&__sF[1]), pkt, trans); |
475 | |
476 | if (DebugFlag >= DEBUG_HEADER2) { |
477 | mopPrintHeader(stdout(&__sF[1]), pkt, trans); |
478 | mopPrintMopHeader(stdout(&__sF[1]), pkt, trans); |
479 | } |
480 | |
481 | if (DebugFlag >= DEBUG_INFO3) |
482 | mopDumpRC(stdout(&__sF[1]), pkt, trans); |
483 | |
484 | moplen = mopGetLength(pkt, trans); |
485 | mopcode = mopGetChar(pkt, idx); |
486 | |
487 | switch (mopcode) { |
488 | case MOP_K_CODE_RID5: |
489 | break; |
490 | case MOP_K_CODE_BOT6: |
491 | break; |
492 | case MOP_K_CODE_SID7: |
493 | tmpc = mopGetChar(pkt, idx); /* Reserved */ |
494 | |
495 | if ((DebugFlag >= DEBUG_INFO3)) |
496 | fprintf(stderr(&__sF[2]), "Reserved : %02x\n", tmpc); |
497 | |
498 | tmps = mopGetShort(pkt, idx); /* Receipt # */ |
499 | if ((DebugFlag >= DEBUG_INFO3)) |
500 | fprintf(stderr(&__sF[2]), "Receipt Nbr : %04x\n", tmps); |
501 | |
502 | dl_rpr = &dl; |
503 | bzero(dl_rpr, sizeof(*dl_rpr)); |
504 | dl_rpr->ii = ii; |
505 | bcopy(src, dl_rpr->eaddr, 6); |
506 | mopProcessInfo(pkt, idx, moplen, dl_rpr, trans); |
507 | break; |
508 | case MOP_K_CODE_RQC9: |
509 | break; |
510 | case MOP_K_CODE_CNT11: |
511 | break; |
512 | case MOP_K_CODE_RVC13: |
513 | break; |
514 | case MOP_K_CODE_RLC15: |
515 | break; |
516 | case MOP_K_CODE_CCP17: |
517 | break; |
518 | case MOP_K_CODE_CRA19: |
519 | break; |
520 | default: |
521 | break; |
522 | } |
523 | } |