|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1995, 1996 ! 24: * Matt Thomas <[email protected]>. All rights reserved. ! 25: * Copyright (c) 1982, 1989, 1993 ! 26: * The Regents of the University of California. All rights reserved. ! 27: * ! 28: * Redistribution and use in source and binary forms, with or without ! 29: * modification, are permitted provided that the following conditions ! 30: * are met: ! 31: * 1. Redistributions of source code must retain the above copyright ! 32: * notice, this list of conditions and the following disclaimer. ! 33: * 2. Redistributions in binary form must reproduce the above copyright ! 34: * notice, this list of conditions and the following disclaimer in the ! 35: * documentation and/or other materials provided with the distribution. ! 36: * 3. All advertising materials mentioning features or use of this software ! 37: * must display the following acknowledgement: ! 38: * This product includes software developed by the University of ! 39: * California, Berkeley and its contributors. ! 40: * 4. Neither the name of the University nor the names of its contributors ! 41: * may be used to endorse or promote products derived from this software ! 42: * without specific prior written permission. ! 43: * ! 44: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 45: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 46: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 47: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 48: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 49: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 50: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 51: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 52: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 53: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 54: * SUCH DAMAGE. ! 55: * ! 56: * from: if_ethersubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp ! 57: */ ! 58: ! 59: #include "opt_atalk.h" ! 60: #include "opt_inet.h" ! 61: #include "opt_ipx.h" ! 62: ! 63: #include <sys/param.h> ! 64: #include <sys/systm.h> ! 65: #include <sys/mbuf.h> ! 66: #include <sys/socket.h> ! 67: ! 68: #include <net/if.h> ! 69: #include <net/netisr.h> ! 70: #include <net/route.h> ! 71: #include <net/if_llc.h> ! 72: #include <net/if_dl.h> ! 73: #include <net/if_types.h> ! 74: ! 75: #if INET ! 76: #include <netinet/in.h> ! 77: #include <netinet/in_var.h> ! 78: #include <netinet/if_ether.h> ! 79: #endif ! 80: #if defined(__FreeBSD__) ! 81: #include <netinet/if_fddi.h> ! 82: #else ! 83: #include <net/if_fddi.h> ! 84: #endif ! 85: ! 86: #if IPX ! 87: #include <netipx/ipx.h> ! 88: #include <netipx/ipx_if.h> ! 89: #endif ! 90: ! 91: #if NS ! 92: #include <netns/ns.h> ! 93: #include <netns/ns_if.h> ! 94: #endif ! 95: ! 96: #if DECNET ! 97: #include <netdnet/dn.h> ! 98: #endif ! 99: ! 100: #if ISO ! 101: #include <netiso/argo_debug.h> ! 102: #include <netiso/iso.h> ! 103: #include <netiso/iso_var.h> ! 104: #include <netiso/iso_snpac.h> ! 105: #endif ! 106: ! 107: #if LLC ! 108: #include <netccitt/dll.h> ! 109: #include <netccitt/llc_var.h> ! 110: #endif ! 111: ! 112: ! 113: #if LLC && CCITT ! 114: extern struct ifqueue pkintrq; ! 115: #endif ! 116: ! 117: #include "bpfilter.h" ! 118: ! 119: #define senderr(e) { error = (e); goto bad;} ! 120: ! 121: /* ! 122: * This really should be defined in if_llc.h but in case it isn't. ! 123: */ ! 124: #ifndef llc_snap ! 125: #define llc_snap llc_un.type_snap ! 126: #endif ! 127: ! 128: #if defined(__bsdi__) || defined(__NetBSD__) ! 129: #define RTALLOC1(a, b) rtalloc1(a, b) ! 130: #define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e) ! 131: #elif defined(__FreeBSD__) ! 132: #define RTALLOC1(a, b) rtalloc1(a, b, 0UL) ! 133: #define ARPRESOLVE(a, b, c, d, e, f) arpresolve(a, b, c, d, e, f) ! 134: #endif ! 135: /* ! 136: * FDDI output routine. ! 137: * Encapsulate a packet of type family for the local net. ! 138: * Use trailer local net encapsulation if enough data in first ! 139: * packet leaves a multiple of 512 bytes of data in remainder. ! 140: * Assumes that ifp is actually pointer to arpcom structure. ! 141: */ ! 142: int ! 143: fddi_output(ifp, m0, dst, rt0) ! 144: register struct ifnet *ifp; ! 145: struct mbuf *m0; ! 146: struct sockaddr *dst; ! 147: struct rtentry *rt0; ! 148: { ! 149: u_int16_t type; ! 150: int s, loop_copy = 0, error = 0; ! 151: u_char edst[6]; ! 152: register struct mbuf *m = m0; ! 153: register struct rtentry *rt; ! 154: register struct fddi_header *fh; ! 155: struct arpcom *ac = (struct arpcom *)ifp; ! 156: ! 157: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) ! 158: senderr(ENETDOWN); ! 159: getmicrotime(&ifp->if_lastchange); ! 160: #if !defined(__bsdi__) || _BSDI_VERSION >= 199401 ! 161: if (rt = rt0) { ! 162: if ((rt->rt_flags & RTF_UP) == 0) { ! 163: if (rt0 = rt = RTALLOC1(dst, 1)) ! 164: rt->rt_refcnt--; ! 165: else ! 166: senderr(EHOSTUNREACH); ! 167: } ! 168: if (rt->rt_flags & RTF_GATEWAY) { ! 169: if (rt->rt_gwroute == 0) ! 170: goto lookup; ! 171: if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { ! 172: rtfree(rt); rt = rt0; ! 173: lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 1); ! 174: if ((rt = rt->rt_gwroute) == 0) ! 175: senderr(EHOSTUNREACH); ! 176: } ! 177: } ! 178: if (rt->rt_flags & RTF_REJECT) ! 179: if (rt->rt_rmx.rmx_expire == 0 || ! 180: time_second < rt->rt_rmx.rmx_expire) ! 181: senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); ! 182: } ! 183: #endif ! 184: switch (dst->sa_family) { ! 185: ! 186: #if INET ! 187: case AF_INET: { ! 188: #if !defined(__bsdi__) || _BSDI_VERSION >= 199401 ! 189: if (!ARPRESOLVE(ac, rt, m, dst, edst, rt0)) ! 190: return (0); /* if not yet resolved */ ! 191: #else ! 192: int usetrailers; ! 193: if (!arpresolve(ac, m, &((struct sockaddr_in *)dst)->sin_addr, edst, &usetrailers)) ! 194: return (0); /* if not yet resolved */ ! 195: #endif ! 196: type = htons(ETHERTYPE_IP); ! 197: break; ! 198: } ! 199: #endif ! 200: #if IPX ! 201: case AF_IPX: ! 202: type = htons(ETHERTYPE_IPX); ! 203: bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host), ! 204: (caddr_t)edst, sizeof (edst)); ! 205: break; ! 206: #endif ! 207: ! 208: #if NS ! 209: case AF_NS: ! 210: type = htons(ETHERTYPE_NS); ! 211: bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), ! 212: (caddr_t)edst, sizeof (edst)); ! 213: break; ! 214: #endif ! 215: #if ISO ! 216: case AF_ISO: { ! 217: int snpalen; ! 218: struct llc *l; ! 219: register struct sockaddr_dl *sdl; ! 220: ! 221: if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && ! 222: sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { ! 223: bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); ! 224: } else if (error = ! 225: iso_snparesolve(ifp, (struct sockaddr_iso *)dst, ! 226: (char *)edst, &snpalen)) ! 227: goto bad; /* Not Resolved */ ! 228: /* If broadcasting on a simplex interface, loopback a copy */ ! 229: if (*edst & 1) ! 230: m->m_flags |= (M_BCAST|M_MCAST); ! 231: M_PREPEND(m, 3, M_DONTWAIT); ! 232: if (m == NULL) ! 233: return (0); ! 234: type = 0; ! 235: l = mtod(m, struct llc *); ! 236: l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; ! 237: l->llc_control = LLC_UI; ! 238: IFDEBUG(D_ETHER) ! 239: int i; ! 240: printf("unoutput: sending pkt to: "); ! 241: for (i=0; i<6; i++) ! 242: printf("%x ", edst[i] & 0xff); ! 243: printf("\n"); ! 244: ENDDEBUG ! 245: } break; ! 246: #endif /* ISO */ ! 247: #if LLC ! 248: /* case AF_NSAP: */ ! 249: case AF_CCITT: { ! 250: register struct sockaddr_dl *sdl = ! 251: (struct sockaddr_dl *) rt -> rt_gateway; ! 252: ! 253: if (sdl && sdl->sdl_family != AF_LINK && sdl->sdl_alen <= 0) ! 254: goto bad; /* Not a link interface ? Funny ... */ ! 255: bcopy(LLADDR(sdl), (char *)edst, sizeof(edst)); ! 256: if (*edst & 1) ! 257: loop_copy = 1; ! 258: type = 0; ! 259: #if LLC_DEBUG ! 260: { ! 261: int i; ! 262: register struct llc *l = mtod(m, struct llc *); ! 263: ! 264: printf("fddi_output: sending LLC2 pkt to: "); ! 265: for (i=0; i<6; i++) ! 266: printf("%x ", edst[i] & 0xff); ! 267: printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", ! 268: type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff, ! 269: l->llc_control & 0xff); ! 270: ! 271: } ! 272: #endif /* LLC_DEBUG */ ! 273: } break; ! 274: #endif /* LLC */ ! 275: ! 276: case AF_UNSPEC: ! 277: { ! 278: struct ether_header *eh; ! 279: loop_copy = -1; ! 280: eh = (struct ether_header *)dst->sa_data; ! 281: (void)memcpy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); ! 282: if (*edst & 1) ! 283: m->m_flags |= (M_BCAST|M_MCAST); ! 284: type = eh->ether_type; ! 285: break; ! 286: } ! 287: ! 288: #if NBPFILTER > 0 ! 289: case AF_IMPLINK: ! 290: { ! 291: fh = mtod(m, struct fddi_header *); ! 292: error = EPROTONOSUPPORT; ! 293: switch (fh->fddi_fc & (FDDIFC_C|FDDIFC_L|FDDIFC_F)) { ! 294: case FDDIFC_LLC_ASYNC: { ! 295: /* legal priorities are 0 through 7 */ ! 296: if ((fh->fddi_fc & FDDIFC_Z) > 7) ! 297: goto bad; ! 298: break; ! 299: } ! 300: case FDDIFC_LLC_SYNC: { ! 301: /* FDDIFC_Z bits reserved, must be zero */ ! 302: if (fh->fddi_fc & FDDIFC_Z) ! 303: goto bad; ! 304: break; ! 305: } ! 306: case FDDIFC_SMT: { ! 307: /* FDDIFC_Z bits must be non zero */ ! 308: if ((fh->fddi_fc & FDDIFC_Z) == 0) ! 309: goto bad; ! 310: break; ! 311: } ! 312: default: { ! 313: /* anything else is too dangerous */ ! 314: goto bad; ! 315: } ! 316: } ! 317: error = 0; ! 318: if (fh->fddi_dhost[0] & 1) ! 319: m->m_flags |= (M_BCAST|M_MCAST); ! 320: goto queue_it; ! 321: } ! 322: #endif ! 323: default: ! 324: printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit, ! 325: dst->sa_family); ! 326: senderr(EAFNOSUPPORT); ! 327: } ! 328: ! 329: if (type != 0) { ! 330: register struct llc *l; ! 331: M_PREPEND(m, sizeof (struct llc), M_DONTWAIT); ! 332: if (m == 0) ! 333: senderr(ENOBUFS); ! 334: l = mtod(m, struct llc *); ! 335: l->llc_control = LLC_UI; ! 336: l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP; ! 337: l->llc_snap.org_code[0] = l->llc_snap.org_code[1] = l->llc_snap.org_code[2] = 0; ! 338: (void)memcpy((caddr_t) &l->llc_snap.ether_type, (caddr_t) &type, ! 339: sizeof(u_int16_t)); ! 340: } ! 341: ! 342: /* ! 343: * Add local net header. If no space in first mbuf, ! 344: * allocate another. ! 345: */ ! 346: M_PREPEND(m, sizeof (struct fddi_header), M_DONTWAIT); ! 347: if (m == 0) ! 348: senderr(ENOBUFS); ! 349: fh = mtod(m, struct fddi_header *); ! 350: fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4; ! 351: (void)memcpy((caddr_t)fh->fddi_dhost, (caddr_t)edst, sizeof (edst)); ! 352: queue_it: ! 353: (void)memcpy((caddr_t)fh->fddi_shost, (caddr_t)ac->ac_enaddr, ! 354: sizeof(fh->fddi_shost)); ! 355: ! 356: /* ! 357: * If a simplex interface, and the packet is being sent to our ! 358: * Ethernet address or a broadcast address, loopback a copy. ! 359: * XXX To make a simplex device behave exactly like a duplex ! 360: * device, we should copy in the case of sending to our own ! 361: * ethernet address (thus letting the original actually appear ! 362: * on the wire). However, we don't do that here for security ! 363: * reasons and compatibility with the original behavior. ! 364: */ ! 365: if ((ifp->if_flags & IFF_SIMPLEX) && ! 366: (loop_copy != -1)) { ! 367: if ((m->m_flags & M_BCAST) || loop_copy) { ! 368: struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); ! 369: ! 370: (void) if_simloop(ifp, ! 371: n, dst, sizeof(struct fddi_header)); ! 372: } else if (bcmp(fh->fddi_dhost, ! 373: fh->fddi_shost, sizeof(fh->fddi_shost)) == 0) { ! 374: (void) if_simloop(ifp, ! 375: m, dst, sizeof(struct fddi_header)); ! 376: return(0); /* XXX */ ! 377: } ! 378: } ! 379: ! 380: s = splimp(); ! 381: /* ! 382: * Queue message on interface, and start output if interface ! 383: * not yet active. ! 384: */ ! 385: if (IF_QFULL(&ifp->if_snd)) { ! 386: IF_DROP(&ifp->if_snd); ! 387: splx(s); ! 388: senderr(ENOBUFS); ! 389: } ! 390: ifp->if_obytes += m->m_pkthdr.len; ! 391: IF_ENQUEUE(&ifp->if_snd, m); ! 392: if ((ifp->if_flags & IFF_OACTIVE) == 0) ! 393: (*ifp->if_start)(ifp); ! 394: splx(s); ! 395: if (m->m_flags & M_MCAST) ! 396: ifp->if_omcasts++; ! 397: return (error); ! 398: ! 399: bad: ! 400: if (m) ! 401: m_freem(m); ! 402: return (error); ! 403: } ! 404: ! 405: /* ! 406: * Process a received FDDI packet; ! 407: * the packet is in the mbuf chain m without ! 408: * the fddi header, which is provided separately. ! 409: */ ! 410: void ! 411: fddi_input(ifp, fh, m) ! 412: struct ifnet *ifp; ! 413: register struct fddi_header *fh; ! 414: struct mbuf *m; ! 415: { ! 416: register struct ifqueue *inq; ! 417: register struct llc *l; ! 418: int s; ! 419: ! 420: if ((ifp->if_flags & IFF_UP) == 0) { ! 421: m_freem(m); ! 422: return; ! 423: } ! 424: getmicrotime(&ifp->if_lastchange); ! 425: ifp->if_ibytes += m->m_pkthdr.len + sizeof (*fh); ! 426: if (fh->fddi_dhost[0] & 1) { ! 427: if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost, ! 428: sizeof(fddibroadcastaddr)) == 0) ! 429: m->m_flags |= M_BCAST; ! 430: else ! 431: m->m_flags |= M_MCAST; ! 432: ifp->if_imcasts++; ! 433: } else if ((ifp->if_flags & IFF_PROMISC) ! 434: && bcmp(((struct arpcom *)ifp)->ac_enaddr, (caddr_t)fh->fddi_dhost, ! 435: sizeof(fh->fddi_dhost)) != 0) { ! 436: m_freem(m); ! 437: return; ! 438: } ! 439: ! 440: #ifdef M_LINK0 ! 441: /* ! 442: * If this has a LLC priority of 0, then mark it so upper ! 443: * layers have a hint that it really came via a FDDI/Ethernet ! 444: * bridge. ! 445: */ ! 446: if ((fh->fddi_fc & FDDIFC_LLC_PRIO7) == FDDIFC_LLC_PRIO0) ! 447: m->m_flags |= M_LINK0; ! 448: #endif ! 449: ! 450: l = mtod(m, struct llc *); ! 451: switch (l->llc_dsap) { ! 452: #if defined(INET) || NS || IPX || defined(NETATALK) ! 453: case LLC_SNAP_LSAP: ! 454: { ! 455: u_int16_t type; ! 456: if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP) ! 457: goto dropanyway; ! 458: ! 459: if (l->llc_snap.org_code[0] != 0 || l->llc_snap.org_code[1] != 0|| l->llc_snap.org_code[2] != 0) ! 460: goto dropanyway; ! 461: type = ntohs(l->llc_snap.ether_type); ! 462: m_adj(m, 8); ! 463: switch (type) { ! 464: #if INET ! 465: case ETHERTYPE_IP: ! 466: if (ipflow_fastforward(m)) ! 467: return; ! 468: schednetisr(NETISR_IP); ! 469: inq = &ipintrq; ! 470: break; ! 471: ! 472: case ETHERTYPE_ARP: ! 473: #if !defined(__bsdi__) || _BSDI_VERSION >= 199401 ! 474: schednetisr(NETISR_ARP); ! 475: inq = &arpintrq; ! 476: break; ! 477: #else ! 478: arpinput((struct arpcom *)ifp, m); ! 479: return; ! 480: #endif ! 481: #endif ! 482: #if IPX ! 483: case ETHERTYPE_IPX: ! 484: schednetisr(NETISR_IPX); ! 485: inq = &ipxintrq; ! 486: break; ! 487: #endif ! 488: #if NS ! 489: case ETHERTYPE_NS: ! 490: schednetisr(NETISR_NS); ! 491: inq = &nsintrq; ! 492: break; ! 493: #endif ! 494: #if DECNET ! 495: case ETHERTYPE_DECNET: ! 496: schednetisr(NETISR_DECNET); ! 497: inq = &decnetintrq; ! 498: break; ! 499: #endif ! 500: ! 501: default: ! 502: /* printf("fddi_input: unknown protocol 0x%x\n", type); */ ! 503: ifp->if_noproto++; ! 504: goto dropanyway; ! 505: } ! 506: break; ! 507: } ! 508: #endif /* INET || NS */ ! 509: #if ISO ! 510: case LLC_ISO_LSAP: ! 511: switch (l->llc_control) { ! 512: case LLC_UI: ! 513: /* LLC_UI_P forbidden in class 1 service */ ! 514: if ((l->llc_dsap == LLC_ISO_LSAP) && ! 515: (l->llc_ssap == LLC_ISO_LSAP)) { ! 516: /* LSAP for ISO */ ! 517: m->m_data += 3; /* XXX */ ! 518: m->m_len -= 3; /* XXX */ ! 519: m->m_pkthdr.len -= 3; /* XXX */ ! 520: M_PREPEND(m, sizeof *fh, M_DONTWAIT); ! 521: if (m == 0) ! 522: return; ! 523: *mtod(m, struct fddi_header *) = *fh; ! 524: IFDEBUG(D_ETHER) ! 525: printf("clnp packet"); ! 526: ENDDEBUG ! 527: schednetisr(NETISR_ISO); ! 528: inq = &clnlintrq; ! 529: break; ! 530: } ! 531: goto dropanyway; ! 532: ! 533: case LLC_XID: ! 534: case LLC_XID_P: ! 535: if(m->m_len < 6) ! 536: goto dropanyway; ! 537: l->llc_window = 0; ! 538: l->llc_fid = 9; ! 539: l->llc_class = 1; ! 540: l->llc_dsap = l->llc_ssap = 0; ! 541: /* Fall through to */ ! 542: case LLC_TEST: ! 543: case LLC_TEST_P: ! 544: { ! 545: struct sockaddr sa; ! 546: register struct ether_header *eh; ! 547: struct arpcom *ac = (struct arpcom *) ifp; ! 548: int i; ! 549: u_char c = l->llc_dsap; ! 550: ! 551: l->llc_dsap = l->llc_ssap; ! 552: l->llc_ssap = c; ! 553: if (m->m_flags & (M_BCAST | M_MCAST)) ! 554: bcopy((caddr_t)ac->ac_enaddr, ! 555: (caddr_t)eh->ether_dhost, 6); ! 556: sa.sa_family = AF_UNSPEC; ! 557: sa.sa_len = sizeof(sa); ! 558: eh = (struct ether_header *)sa.sa_data; ! 559: for (i = 0; i < 6; i++) { ! 560: eh->ether_shost[i] = fh->fddi_dhost[i]; ! 561: eh->ether_dhost[i] = fh->fddi_shost[i]; ! 562: } ! 563: eh->ether_type = 0; ! 564: ifp->if_output(ifp, m, &sa, NULL); ! 565: return; ! 566: } ! 567: default: ! 568: m_freem(m); ! 569: return; ! 570: } ! 571: break; ! 572: #endif /* ISO */ ! 573: #if LLC ! 574: case LLC_X25_LSAP: ! 575: { ! 576: M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); ! 577: if (m == 0) ! 578: return; ! 579: if ( !sdl_sethdrif(ifp, fh->fddi_shost, LLC_X25_LSAP, ! 580: fh->fddi_dhost, LLC_X25_LSAP, 6, ! 581: mtod(m, struct sdl_hdr *))) ! 582: panic("ETHER cons addr failure"); ! 583: mtod(m, struct sdl_hdr *)->sdlhdr_len = m->m_pkthdr.len - sizeof(struct sdl_hdr); ! 584: #if LLC_DEBUG ! 585: printf("llc packet\n"); ! 586: #endif /* LLC_DEBUG */ ! 587: schednetisr(NETISR_CCITT); ! 588: inq = &llcintrq; ! 589: break; ! 590: } ! 591: #endif /* LLC */ ! 592: ! 593: default: ! 594: /* printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap); */ ! 595: ifp->if_noproto++; ! 596: dropanyway: ! 597: m_freem(m); ! 598: return; ! 599: } ! 600: ! 601: s = splimp(); ! 602: if (IF_QFULL(inq)) { ! 603: IF_DROP(inq); ! 604: m_freem(m); ! 605: } else ! 606: IF_ENQUEUE(inq, m); ! 607: splx(s); ! 608: } ! 609: /* ! 610: * Perform common duties while attaching to interface list ! 611: */ ! 612: #ifdef __NetBSD__ ! 613: #define ifa_next ifa_list.tqe_next ! 614: #endif ! 615: ! 616: void ! 617: fddi_ifattach(ifp) ! 618: register struct ifnet *ifp; ! 619: { ! 620: register struct ifaddr *ifa; ! 621: register struct sockaddr_dl *sdl; ! 622: ! 623: ifp->if_type = IFT_FDDI; ! 624: ifp->if_addrlen = 6; ! 625: ifp->if_hdrlen = 21; ! 626: ifp->if_mtu = FDDIMTU; ! 627: ifp->if_baudrate = 100000000; ! 628: #if IFF_NOTRAILERS ! 629: ifp->if_flags |= IFF_NOTRAILERS; ! 630: #endif ! 631: #if defined(__FreeBSD__) ! 632: ifa = ifnet_addrs[ifp->if_index - 1]; ! 633: sdl = (struct sockaddr_dl *)ifa->ifa_addr; ! 634: sdl->sdl_type = IFT_FDDI; ! 635: sdl->sdl_alen = ifp->if_addrlen; ! 636: bcopy(((struct arpcom *)ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen); ! 637: #elif defined(__NetBSD__) ! 638: LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs); ! 639: for (ifa = ifp->if_addrlist.tqh_first; ifa != NULL; ifa = ifa->ifa_list.tqe_next) ! 640: #else ! 641: for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next) ! 642: #endif ! 643: #if !defined(__FreeBSD__) ! 644: if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && ! 645: sdl->sdl_family == AF_LINK) { ! 646: sdl->sdl_type = IFT_FDDI; ! 647: sdl->sdl_alen = ifp->if_addrlen; ! 648: bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr, ! 649: LLADDR(sdl), ifp->if_addrlen); ! 650: break; ! 651: } ! 652: #endif ! 653: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.