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