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