|
|
1.1 ! root 1: /* if_en.c 6.1 83/07/29 */ ! 2: ! 3: #include "en.h" ! 4: ! 5: /* ! 6: * Xerox prototype (3 Mb) Ethernet interface driver. ! 7: */ ! 8: #include "../machine/pte.h" ! 9: ! 10: #include "../h/param.h" ! 11: #include "../h/systm.h" ! 12: #include "../h/mbuf.h" ! 13: #include "../h/buf.h" ! 14: #include "../h/protosw.h" ! 15: #include "../h/socket.h" ! 16: #include "../h/vmmac.h" ! 17: #include "../h/errno.h" ! 18: #include "../h/ioctl.h" ! 19: ! 20: #include "../net/if.h" ! 21: #include "../net/netisr.h" ! 22: #include "../net/route.h" ! 23: #include "../netinet/in.h" ! 24: #include "../netinet/in_systm.h" ! 25: #include "../netinet/ip.h" ! 26: #include "../netinet/ip_var.h" ! 27: #include "../netpup/pup.h" ! 28: #include "../netpup/ether.h" ! 29: ! 30: #include "../vax/cpu.h" ! 31: #include "../vax/mtpr.h" ! 32: #include "../vaxif/if_en.h" ! 33: #include "../vaxif/if_enreg.h" ! 34: #include "../vaxif/if_uba.h" ! 35: #include "../vaxuba/ubareg.h" ! 36: #include "../vaxuba/ubavar.h" ! 37: ! 38: #define ENMTU (1024+512) ! 39: #define ENMRU (1024+512+16) /* 16 is enough to receive trailer */ ! 40: ! 41: int enprobe(), enattach(), enrint(), enxint(), encollide(); ! 42: struct uba_device *eninfo[NEN]; ! 43: u_short enstd[] = { 0 }; ! 44: struct uba_driver endriver = ! 45: { enprobe, 0, enattach, 0, enstd, "en", eninfo }; ! 46: #define ENUNIT(x) minor(x) ! 47: ! 48: int eninit(),enoutput(),enreset(),enioctl(); ! 49: ! 50: #ifdef notdef ! 51: /* ! 52: * If you need to byte swap IP's in the system, define ! 53: * this and do a SIOCSIFFLAGS at boot time. ! 54: */ ! 55: #define ENF_SWABIPS 0x100 ! 56: #endif ! 57: ! 58: /* ! 59: * Ethernet software status per interface. ! 60: * ! 61: * Each interface is referenced by a network interface structure, ! 62: * es_if, which the routing code uses to locate the interface. ! 63: * This structure contains the output queue for the interface, its address, ... ! 64: * We also have, for each interface, a UBA interface structure, which ! 65: * contains information about the UNIBUS resources held by the interface: ! 66: * map registers, buffered data paths, etc. Information is cached in this ! 67: * structure for use by the if_uba.c routines in running the interface ! 68: * efficiently. ! 69: */ ! 70: struct en_softc { ! 71: struct ifnet es_if; /* network-visible interface */ ! 72: struct ifuba es_ifuba; /* UNIBUS resources */ ! 73: short es_delay; /* current output delay */ ! 74: short es_mask; /* mask for current output delay */ ! 75: short es_lastx; /* host last transmitted to */ ! 76: short es_oactive; /* is output active? */ ! 77: short es_olen; /* length of last output */ ! 78: } en_softc[NEN]; ! 79: ! 80: /* ! 81: * Do output DMA to determine interface presence and ! 82: * interrupt vector. DMA is too short to disturb other hosts. ! 83: */ ! 84: enprobe(reg) ! 85: caddr_t reg; ! 86: { ! 87: register int br, cvec; /* r11, r10 value-result */ ! 88: register struct endevice *addr = (struct endevice *)reg; ! 89: ! 90: #ifdef lint ! 91: br = 0; cvec = br; br = cvec; ! 92: enrint(0); enxint(0); encollide(0); ! 93: #endif ! 94: addr->en_istat = 0; ! 95: addr->en_owc = -1; ! 96: addr->en_oba = 0; ! 97: addr->en_ostat = EN_IEN|EN_GO; ! 98: DELAY(100000); ! 99: addr->en_ostat = 0; ! 100: return (1); ! 101: } ! 102: ! 103: /* ! 104: * Interface exists: make available by filling in network interface ! 105: * record. System will initialize the interface when it is ready ! 106: * to accept packets. ! 107: */ ! 108: enattach(ui) ! 109: struct uba_device *ui; ! 110: { ! 111: register struct en_softc *es = &en_softc[ui->ui_unit]; ! 112: ! 113: es->es_if.if_unit = ui->ui_unit; ! 114: es->es_if.if_name = "en"; ! 115: es->es_if.if_mtu = ENMTU; ! 116: es->es_if.if_init = eninit; ! 117: es->es_if.if_output = enoutput; ! 118: es->es_if.if_ioctl = enioctl; ! 119: es->es_if.if_reset = enreset; ! 120: es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16 | UBA_CANTWAIT; ! 121: #if defined(VAX750) ! 122: /* don't chew up 750 bdp's */ ! 123: if (cpu == VAX_750 && ui->ui_unit > 0) ! 124: es->es_ifuba.ifu_flags &= ~UBA_NEEDBDP; ! 125: #endif ! 126: if_attach(&es->es_if); ! 127: } ! 128: ! 129: /* ! 130: * Reset of interface after UNIBUS reset. ! 131: * If interface is on specified uba, reset its state. ! 132: */ ! 133: enreset(unit, uban) ! 134: int unit, uban; ! 135: { ! 136: register struct uba_device *ui; ! 137: ! 138: if (unit >= NEN || (ui = eninfo[unit]) == 0 || ui->ui_alive == 0 || ! 139: ui->ui_ubanum != uban) ! 140: return; ! 141: printf(" en%d", unit); ! 142: eninit(unit); ! 143: } ! 144: ! 145: /* ! 146: * Initialization of interface; clear recorded pending ! 147: * operations, and reinitialize UNIBUS usage. ! 148: */ ! 149: eninit(unit) ! 150: int unit; ! 151: { ! 152: register struct en_softc *es = &en_softc[unit]; ! 153: register struct uba_device *ui = eninfo[unit]; ! 154: register struct endevice *addr; ! 155: struct sockaddr_in *sin = (struct sockaddr_in *)&es->es_if.if_addr; ! 156: int s; ! 157: ! 158: if (in_netof(sin->sin_addr) == 0) ! 159: return; ! 160: if (if_ubainit(&es->es_ifuba, ui->ui_ubanum, ! 161: sizeof (struct en_header), (int)btoc(ENMRU)) == 0) { ! 162: printf("en%d: can't initialize\n", unit); ! 163: es->es_if.if_flags &= ~IFF_UP; ! 164: return; ! 165: } ! 166: addr = (struct endevice *)ui->ui_addr; ! 167: addr->en_istat = addr->en_ostat = 0; ! 168: ! 169: /* ! 170: * Hang a receive and start any ! 171: * pending writes by faking a transmit complete. ! 172: */ ! 173: s = splimp(); ! 174: addr->en_iba = es->es_ifuba.ifu_r.ifrw_info; ! 175: addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1; ! 176: addr->en_istat = EN_IEN|EN_GO; ! 177: es->es_oactive = 1; ! 178: es->es_if.if_flags |= IFF_UP|IFF_RUNNING; ! 179: enxint(unit); ! 180: splx(s); ! 181: if_rtinit(&es->es_if, RTF_UP); ! 182: } ! 183: ! 184: int enalldelay = 0; ! 185: int enlastdel = 50; ! 186: int enlastmask = (~0) << 5; ! 187: ! 188: /* ! 189: * Start or restart output on interface. ! 190: * If interface is already active, then this is a retransmit ! 191: * after a collision, and just restuff registers and delay. ! 192: * If interface is not already active, get another datagram ! 193: * to send off of the interface queue, and map it to the interface ! 194: * before starting the output. ! 195: */ ! 196: enstart(dev) ! 197: dev_t dev; ! 198: { ! 199: int unit = ENUNIT(dev); ! 200: struct uba_device *ui = eninfo[unit]; ! 201: register struct en_softc *es = &en_softc[unit]; ! 202: register struct endevice *addr; ! 203: struct mbuf *m; ! 204: int dest; ! 205: ! 206: if (es->es_oactive) ! 207: goto restart; ! 208: ! 209: /* ! 210: * Not already active: dequeue another request ! 211: * and map it to the UNIBUS. If no more requests, ! 212: * just return. ! 213: */ ! 214: IF_DEQUEUE(&es->es_if.if_snd, m); ! 215: if (m == 0) { ! 216: es->es_oactive = 0; ! 217: return; ! 218: } ! 219: dest = mtod(m, struct en_header *)->en_dhost; ! 220: es->es_olen = if_wubaput(&es->es_ifuba, m); ! 221: #ifdef ENF_SWABIPS ! 222: /* ! 223: * The Xerox interface does word at a time DMA, so ! 224: * someone must do byte swapping of user data if high ! 225: * and low ender machines are to communicate. It doesn't ! 226: * belong here, but certain people depend on it, so... ! 227: * ! 228: * Should swab everybody, but this is a kludge anyway. ! 229: */ ! 230: if (es->es_if.if_flags & ENF_SWABIPS) { ! 231: register struct en_header *en; ! 232: ! 233: en = (struct en_header *)es->es_ifuba.ifu_w.ifrw_addr; ! 234: if (en->en_type == ENTYPE_IP) ! 235: enswab((caddr_t)(en + 1), (caddr_t)(en + 1), ! 236: es->es_olen - sizeof (struct en_header) + 1); ! 237: } ! 238: #endif ! 239: ! 240: /* ! 241: * Ethernet cannot take back-to-back packets (no ! 242: * buffering in interface. To help avoid overrunning ! 243: * receivers, enforce a small delay (about 1ms) in interface: ! 244: * * between all packets when enalldelay ! 245: * * whenever last packet was broadcast ! 246: * * whenever this packet is to same host as last packet ! 247: */ ! 248: if (enalldelay || es->es_lastx == 0 || es->es_lastx == dest) { ! 249: es->es_delay = enlastdel; ! 250: es->es_mask = enlastmask; ! 251: } ! 252: es->es_lastx = dest; ! 253: ! 254: restart: ! 255: /* ! 256: * Have request mapped to UNIBUS for transmission. ! 257: * Purge any stale data from this BDP, and start the otput. ! 258: */ ! 259: if (es->es_ifuba.ifu_flags & UBA_NEEDBDP) ! 260: UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_w.ifrw_bdp); ! 261: addr = (struct endevice *)ui->ui_addr; ! 262: addr->en_oba = (int)es->es_ifuba.ifu_w.ifrw_info; ! 263: addr->en_odelay = es->es_delay; ! 264: addr->en_owc = -((es->es_olen + 1) >> 1); ! 265: addr->en_ostat = EN_IEN|EN_GO; ! 266: es->es_oactive = 1; ! 267: } ! 268: ! 269: /* ! 270: * Ethernet interface transmitter interrupt. ! 271: * Start another output if more data to send. ! 272: */ ! 273: enxint(unit) ! 274: int unit; ! 275: { ! 276: register struct uba_device *ui = eninfo[unit]; ! 277: register struct en_softc *es = &en_softc[unit]; ! 278: register struct endevice *addr = (struct endevice *)ui->ui_addr; ! 279: ! 280: if (es->es_oactive == 0) ! 281: return; ! 282: if (es->es_mask && (addr->en_ostat&EN_OERROR)) { ! 283: es->es_if.if_oerrors++; ! 284: endocoll(unit); ! 285: return; ! 286: } ! 287: es->es_if.if_opackets++; ! 288: es->es_oactive = 0; ! 289: es->es_delay = 0; ! 290: es->es_mask = ~0; ! 291: if (es->es_ifuba.ifu_xtofree) { ! 292: m_freem(es->es_ifuba.ifu_xtofree); ! 293: es->es_ifuba.ifu_xtofree = 0; ! 294: } ! 295: if (es->es_if.if_snd.ifq_head == 0) { ! 296: es->es_lastx = 256; /* putatively illegal */ ! 297: return; ! 298: } ! 299: enstart(unit); ! 300: } ! 301: ! 302: /* ! 303: * Collision on ethernet interface. Do exponential ! 304: * backoff, and retransmit. If have backed off all ! 305: * the way print warning diagnostic, and drop packet. ! 306: */ ! 307: encollide(unit) ! 308: int unit; ! 309: { ! 310: struct en_softc *es = &en_softc[unit]; ! 311: ! 312: es->es_if.if_collisions++; ! 313: if (es->es_oactive == 0) ! 314: return; ! 315: endocoll(unit); ! 316: } ! 317: ! 318: endocoll(unit) ! 319: int unit; ! 320: { ! 321: register struct en_softc *es = &en_softc[unit]; ! 322: ! 323: /* ! 324: * Es_mask is a 16 bit number with n low zero bits, with ! 325: * n the number of backoffs. When es_mask is 0 we have ! 326: * backed off 16 times, and give up. ! 327: */ ! 328: if (es->es_mask == 0) { ! 329: printf("en%d: send error\n", unit); ! 330: enxint(unit); ! 331: return; ! 332: } ! 333: /* ! 334: * Another backoff. Restart with delay based on n low bits ! 335: * of the interval timer. ! 336: */ ! 337: es->es_mask <<= 1; ! 338: es->es_delay = mfpr(ICR) &~ es->es_mask; ! 339: enstart(unit); ! 340: } ! 341: ! 342: #ifdef notdef ! 343: struct sockproto enproto = { AF_ETHERLINK }; ! 344: struct sockaddr_en endst = { AF_ETHERLINK }; ! 345: struct sockaddr_en ensrc = { AF_ETHERLINK }; ! 346: #endif ! 347: /* ! 348: * Ethernet interface receiver interrupt. ! 349: * If input error just drop packet. ! 350: * Otherwise purge input buffered data path and examine ! 351: * packet to determine type. If can't determine length ! 352: * from type, then have to drop packet. Othewise decapsulate ! 353: * packet based on type and pass to type specific higher-level ! 354: * input routine. ! 355: */ ! 356: enrint(unit) ! 357: int unit; ! 358: { ! 359: register struct en_softc *es = &en_softc[unit]; ! 360: struct endevice *addr = (struct endevice *)eninfo[unit]->ui_addr; ! 361: register struct en_header *en; ! 362: struct mbuf *m; ! 363: int len; short resid; ! 364: register struct ifqueue *inq; ! 365: int off; ! 366: ! 367: es->es_if.if_ipackets++; ! 368: ! 369: /* ! 370: * Purge BDP; drop if input error indicated. ! 371: */ ! 372: if (es->es_ifuba.ifu_flags & UBA_NEEDBDP) ! 373: UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp); ! 374: if (addr->en_istat&EN_IERROR) { ! 375: es->es_if.if_ierrors++; ! 376: goto setup; ! 377: } ! 378: ! 379: /* ! 380: * Calculate input data length. ! 381: * Get pointer to ethernet header (in input buffer). ! 382: * Deal with trailer protocol: if type is PUP trailer ! 383: * get true type from first 16-bit word past data. ! 384: * Remember that type was trailer by setting off. ! 385: */ ! 386: resid = addr->en_iwc; ! 387: if (resid) ! 388: resid |= 0176000; ! 389: len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1; ! 390: len -= sizeof (struct en_header); ! 391: if (len > ENMRU) ! 392: goto setup; /* sanity */ ! 393: en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr); ! 394: en->en_type = ntohs(en->en_type); ! 395: #define endataaddr(en, off, type) ((type)(((caddr_t)((en)+1)+(off)))) ! 396: if (en->en_type >= ENTYPE_TRAIL && ! 397: en->en_type < ENTYPE_TRAIL+ENTYPE_NTRAILER) { ! 398: off = (en->en_type - ENTYPE_TRAIL) * 512; ! 399: if (off > ENMTU) ! 400: goto setup; /* sanity */ ! 401: en->en_type = ntohs(*endataaddr(en, off, u_short *)); ! 402: resid = ntohs(*(endataaddr(en, off+2, u_short *))); ! 403: if (off + resid > len) ! 404: goto setup; /* sanity */ ! 405: len = off + resid; ! 406: } else ! 407: off = 0; ! 408: if (len == 0) ! 409: goto setup; ! 410: #ifdef ENF_SWABIPS ! 411: if (es->es_if.if_flags & ENF_SWABIPS && en->en_type == ENTYPE_IP) ! 412: enswab((caddr_t)(en + 1), (caddr_t)(en + 1), len); ! 413: #endif ! 414: /* ! 415: * Pull packet off interface. Off is nonzero if packet ! 416: * has trailing header; if_rubaget will then force this header ! 417: * information to be at the front, but we still have to drop ! 418: * the type and length which are at the front of any trailer data. ! 419: */ ! 420: m = if_rubaget(&es->es_ifuba, len, off); ! 421: if (m == 0) ! 422: goto setup; ! 423: if (off) { ! 424: m->m_off += 2 * sizeof (u_short); ! 425: m->m_len -= 2 * sizeof (u_short); ! 426: } ! 427: switch (en->en_type) { ! 428: ! 429: #ifdef INET ! 430: case ENTYPE_IP: ! 431: schednetisr(NETISR_IP); ! 432: inq = &ipintrq; ! 433: break; ! 434: #endif ! 435: #ifdef PUP ! 436: case ENTYPE_PUP: ! 437: rpup_input(m); ! 438: goto setup; ! 439: #endif ! 440: default: ! 441: #ifdef notdef ! 442: enproto.sp_protocol = en->en_type; ! 443: endst.sen_host = en->en_dhost; ! 444: endst.sen_net = ensrc.sen_net = es->es_if.if_net; ! 445: ensrc.sen_host = en->en_shost; ! 446: raw_input(m, &enproto, ! 447: (struct sockaddr *)&ensrc, (struct sockaddr *)&endst); ! 448: #else ! 449: m_freem(m); ! 450: #endif ! 451: goto setup; ! 452: } ! 453: ! 454: if (IF_QFULL(inq)) { ! 455: IF_DROP(inq); ! 456: m_freem(m); ! 457: } else ! 458: IF_ENQUEUE(inq, m); ! 459: ! 460: setup: ! 461: /* ! 462: * Reset for next packet. ! 463: */ ! 464: addr->en_iba = es->es_ifuba.ifu_r.ifrw_info; ! 465: addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1; ! 466: addr->en_istat = EN_IEN|EN_GO; ! 467: } ! 468: ! 469: /* ! 470: * Ethernet output routine. ! 471: * Encapsulate a packet of type family for the local net. ! 472: * Use trailer local net encapsulation if enough data in first ! 473: * packet leaves a multiple of 512 bytes of data in remainder. ! 474: */ ! 475: enoutput(ifp, m0, dst) ! 476: struct ifnet *ifp; ! 477: struct mbuf *m0; ! 478: struct sockaddr *dst; ! 479: { ! 480: int type, dest, s, error; ! 481: register struct mbuf *m = m0; ! 482: register struct en_header *en; ! 483: register int off; ! 484: ! 485: switch (dst->sa_family) { ! 486: ! 487: #ifdef INET ! 488: case AF_INET: ! 489: dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr; ! 490: if (in_lnaof(*((struct in_addr *)&dest)) >= 0x100) { ! 491: error = EPERM; /* ??? */ ! 492: goto bad; ! 493: } ! 494: dest = (dest >> 24) & 0xff; ! 495: off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; ! 496: /* need per host negotiation */ ! 497: if ((ifp->if_flags & IFF_NOTRAILERS) == 0) ! 498: if (off > 0 && (off & 0x1ff) == 0 && ! 499: m->m_off >= MMINOFF + 2 * sizeof (u_short)) { ! 500: type = ENTYPE_TRAIL + (off>>9); ! 501: m->m_off -= 2 * sizeof (u_short); ! 502: m->m_len += 2 * sizeof (u_short); ! 503: *mtod(m, u_short *) = htons((u_short)ENTYPE_IP); ! 504: *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len); ! 505: goto gottrailertype; ! 506: } ! 507: type = ENTYPE_IP; ! 508: off = 0; ! 509: goto gottype; ! 510: #endif ! 511: #ifdef PUP ! 512: case AF_PUP: ! 513: dest = ((struct sockaddr_pup *)dst)->spup_host; ! 514: type = ENTYPE_PUP; ! 515: off = 0; ! 516: goto gottype; ! 517: #endif ! 518: ! 519: #ifdef notdef ! 520: case AF_ETHERLINK: ! 521: goto gotheader; ! 522: #endif ! 523: ! 524: default: ! 525: printf("en%d: can't handle af%d\n", ifp->if_unit, ! 526: dst->sa_family); ! 527: error = EAFNOSUPPORT; ! 528: goto bad; ! 529: } ! 530: ! 531: gottrailertype: ! 532: /* ! 533: * Packet to be sent as trailer: move first packet ! 534: * (control information) to end of chain. ! 535: */ ! 536: while (m->m_next) ! 537: m = m->m_next; ! 538: m->m_next = m0; ! 539: m = m0->m_next; ! 540: m0->m_next = 0; ! 541: m0 = m; ! 542: ! 543: gottype: ! 544: /* ! 545: * Add local net header. If no space in first mbuf, ! 546: * allocate another. ! 547: */ ! 548: if (m->m_off > MMAXOFF || ! 549: MMINOFF + sizeof (struct en_header) > m->m_off) { ! 550: m = m_get(M_DONTWAIT, MT_HEADER); ! 551: if (m == 0) { ! 552: error = ENOBUFS; ! 553: goto bad; ! 554: } ! 555: m->m_next = m0; ! 556: m->m_off = MMINOFF; ! 557: m->m_len = sizeof (struct en_header); ! 558: } else { ! 559: m->m_off -= sizeof (struct en_header); ! 560: m->m_len += sizeof (struct en_header); ! 561: } ! 562: en = mtod(m, struct en_header *); ! 563: en->en_shost = ifp->if_host[0]; ! 564: en->en_dhost = dest; ! 565: en->en_type = htons((u_short)type); ! 566: ! 567: gotheader: ! 568: /* ! 569: * Queue message on interface, and start output if interface ! 570: * not yet active. ! 571: */ ! 572: s = splimp(); ! 573: if (IF_QFULL(&ifp->if_snd)) { ! 574: IF_DROP(&ifp->if_snd); ! 575: error = ENOBUFS; ! 576: goto qfull; ! 577: } ! 578: IF_ENQUEUE(&ifp->if_snd, m); ! 579: if (en_softc[ifp->if_unit].es_oactive == 0) ! 580: enstart(ifp->if_unit); ! 581: splx(s); ! 582: return (0); ! 583: qfull: ! 584: m0 = m; ! 585: splx(s); ! 586: bad: ! 587: m_freem(m0); ! 588: return (error); ! 589: } ! 590: ! 591: /* ! 592: * Process an ioctl request. ! 593: */ ! 594: enioctl(ifp, cmd, data) ! 595: register struct ifnet *ifp; ! 596: int cmd; ! 597: caddr_t data; ! 598: { ! 599: struct ifreq *ifr = (struct ifreq *)data; ! 600: int s = splimp(), error = 0; ! 601: ! 602: switch (cmd) { ! 603: ! 604: case SIOCSIFADDR: ! 605: if (ifp->if_flags & IFF_RUNNING) ! 606: if_rtinit(ifp, -1); /* delete previous route */ ! 607: ensetaddr(ifp, (struct sockaddr_in *)&ifr->ifr_addr); ! 608: if (ifp->if_flags & IFF_RUNNING) ! 609: if_rtinit(ifp, RTF_UP); ! 610: else ! 611: eninit(ifp->if_unit); ! 612: break; ! 613: ! 614: default: ! 615: error = EINVAL; ! 616: } ! 617: splx(s); ! 618: return (error); ! 619: } ! 620: ! 621: ensetaddr(ifp, sin) ! 622: register struct ifnet *ifp; ! 623: register struct sockaddr_in *sin; ! 624: { ! 625: struct endevice *enaddr; ! 626: ! 627: ifp->if_net = in_netof(sin->sin_addr); ! 628: enaddr = (struct endevice *)eninfo[ifp->if_unit]->ui_addr; ! 629: ifp->if_host[0] = (~enaddr->en_addr) & 0xff; ! 630: sin = (struct sockaddr_in *)&ifp->if_addr; ! 631: sin->sin_family = AF_INET; ! 632: sin->sin_addr = if_makeaddr(ifp->if_net, ifp->if_host[0]); ! 633: sin = (struct sockaddr_in *)&ifp->if_broadaddr; ! 634: sin->sin_family = AF_INET; ! 635: sin->sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); ! 636: ifp->if_flags |= IFF_BROADCAST; ! 637: } ! 638: ! 639: #ifdef ENF_SWABIPS ! 640: /* ! 641: * Swab bytes ! 642: * Jeffrey Mogul, Stanford ! 643: */ ! 644: enswab(from, to, n) ! 645: register caddr_t *from, *to; ! 646: register int n; ! 647: { ! 648: register unsigned long temp; ! 649: ! 650: n >>= 1; n++; ! 651: #define STEP temp = *from++,*to++ = *from++,*to++ = temp ! 652: /* round to multiple of 8 */ ! 653: while ((--n) & 07) ! 654: STEP; ! 655: n >>= 3; ! 656: while (--n >= 0) { ! 657: STEP; STEP; STEP; STEP; ! 658: STEP; STEP; STEP; STEP; ! 659: } ! 660: } ! 661: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.