1 /* 2 * Copyright (c) 1982, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 34 * $Id: if_ethersubr.c,v 1.33 1997/02/22 09:41:00 peter Exp $ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/protosw.h> 43 #include <sys/socket.h> 44 #include <sys/sockio.h> 45 #include <sys/errno.h> 46 #include <sys/syslog.h> 47 #include <sys/sysctl.h> 48 49 #include <net/if.h> 50 #include <net/netisr.h> 51 #include <net/route.h> 52 #include <net/if_llc.h> 53 #include <net/if_dl.h> 54 #include <net/if_types.h> 55 #include <net/ethernet.h> 56 57 #ifdef INET 58 #include <netinet/in.h> 59 #include <netinet/in_var.h> 60 #endif 61 #include <netinet/if_ether.h> 62 63 #ifdef IPX 64 #include <netipx/ipx.h> 65 #include <netipx/ipx_if.h> 66 #endif 67 68 #ifdef NS 69 #include <netns/ns.h> 70 #include <netns/ns_if.h> 71 ushort ns_nettype; 72 int ether_outputdebug = 0; 73 int ether_inputdebug = 0; 74 #endif 75 76 #ifdef ISO 77 #include <netiso/argo_debug.h> 78 #include <netiso/iso.h> 79 #include <netiso/iso_var.h> 80 #include <netiso/iso_snpac.h> 81 #endif 82 83 /*#ifdef LLC 84 #include <netccitt/dll.h> 85 #include <netccitt/llc_var.h> 86 #endif*/ 87 88 #if defined(LLC) && defined(CCITT) 89 extern struct ifqueue pkintrq; 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 100 extern u_char at_org_code[ 3 ]; 101 extern u_char aarp_org_code[ 3 ]; 102 #endif NETATALK 103 104 static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **, 105 struct sockaddr *)); 106 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 107 #define senderr(e) { error = (e); goto bad;} 108 109 /* 110 * Ethernet output routine. 111 * Encapsulate a packet of type family for the local net. 112 * Use trailer local net encapsulation if enough data in first 113 * packet leaves a multiple of 512 bytes of data in remainder. 114 * Assumes that ifp is actually pointer to arpcom structure. 115 */ 116 int 117 ether_output(ifp, m0, dst, rt0) 118 register struct ifnet *ifp; 119 struct mbuf *m0; 120 struct sockaddr *dst; 121 struct rtentry *rt0; 122 { 123 short type; 124 int s, error = 0; 125 u_char *cp, edst[6]; 126 register struct mbuf *m2, *m = m0; 127 register struct rtentry *rt; 128 struct mbuf *mcopy = (struct mbuf *)0; 129 register struct ether_header *eh; 130 int off, len = m->m_pkthdr.len; 131 struct arpcom *ac = (struct arpcom *)ifp; 132 register struct ifqueue *inq; 133 #ifdef NETATALK 134 struct at_ifaddr *aa; 135 #endif NETATALK 136 137 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 138 senderr(ENETDOWN); 139 rt = rt0; 140 if (rt) { 141 if ((rt->rt_flags & RTF_UP) == 0) { 142 rt0 = rt = rtalloc1(dst, 1, 0UL); 143 if (rt0) 144 rt->rt_refcnt--; 145 else 146 senderr(EHOSTUNREACH); 147 } 148 if (rt->rt_flags & RTF_GATEWAY) { 149 if (rt->rt_gwroute == 0) 150 goto lookup; 151 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 152 rtfree(rt); rt = rt0; 153 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 154 0UL); 155 if ((rt = rt->rt_gwroute) == 0) 156 senderr(EHOSTUNREACH); 157 } 158 } 159 if (rt->rt_flags & RTF_REJECT) 160 if (rt->rt_rmx.rmx_expire == 0 || 161 time.tv_sec < rt->rt_rmx.rmx_expire) 162 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 163 } 164 switch (dst->sa_family) { 165 166 #ifdef INET 167 case AF_INET: 168 if (!arpresolve(ac, rt, m, dst, edst, rt0)) 169 return (0); /* if not yet resolved */ 170 /* If broadcasting on a simplex interface, loopback a copy */ 171 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 172 mcopy = m_copy(m, 0, (int)M_COPYALL); 173 off = m->m_pkthdr.len - m->m_len; 174 type = htons(ETHERTYPE_IP); 175 break; 176 #endif 177 #ifdef IPX 178 case AF_IPX: 179 type = htons(ETHERTYPE_IPX); 180 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host), 181 (caddr_t)edst, sizeof (edst)); 182 if (!bcmp((caddr_t)edst, (caddr_t)&ipx_thishost, sizeof(edst))) 183 return (looutput(ifp, m, dst, rt)); 184 /* If broadcasting on a simplex interface, loopback a copy */ 185 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 186 mcopy = m_copy(m, 0, (int)M_COPYALL); 187 break; 188 #endif 189 #ifdef NETATALK 190 case AF_APPLETALK: 191 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) { 192 #ifdef NETATALKDEBUG 193 extern char *prsockaddr(struct sockaddr *); 194 printf("aarpresolv: failed for %s\n", prsockaddr(dst)); 195 #endif NETATALKDEBUG 196 return (0); 197 } 198 /* 199 * ifaddr is the first thing in at_ifaddr 200 */ 201 if ((aa = (struct at_ifaddr *)at_ifawithnet( 202 (struct sockaddr_at *)dst, &ifp->if_addrhead)) 203 == 0) 204 goto bad; 205 206 /* 207 * In the phase 2 case, we need to prepend an mbuf for the llc header. 208 * Since we must preserve the value of m, which is passed to us by 209 * value, we m_copy() the first mbuf, and use it for our llc header. 210 */ 211 if ( aa->aa_flags & AFA_PHASE2 ) { 212 struct llc llc; 213 214 M_PREPEND(m, sizeof(struct llc), M_WAIT); 215 len += sizeof(struct llc); 216 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 217 llc.llc_control = LLC_UI; 218 bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code)); 219 llc.llc_snap_ether_type = htons( ETHERTYPE_AT ); 220 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc)); 221 type = htons(m->m_pkthdr.len); 222 } else { 223 type = htons(ETHERTYPE_AT); 224 } 225 break; 226 #endif NETATALK 227 #ifdef NS 228 case AF_NS: 229 switch(ns_nettype){ 230 default: 231 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */ 232 type = 0x8137; 233 break; 234 case 0x0: /* Novell 802.3 */ 235 type = htons( m->m_pkthdr.len); 236 break; 237 case 0xe0e0: /* Novell 802.2 and Token-Ring */ 238 M_PREPEND(m, 3, M_WAIT); 239 type = htons( m->m_pkthdr.len); 240 cp = mtod(m, u_char *); 241 *cp++ = 0xE0; 242 *cp++ = 0xE0; 243 *cp++ = 0x03; 244 break; 245 } 246 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 247 (caddr_t)edst, sizeof (edst)); 248 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){ 249 m->m_pkthdr.rcvif = ifp; 250 schednetisr(NETISR_NS); 251 inq = &nsintrq; 252 s = splimp(); 253 if (IF_QFULL(inq)) { 254 IF_DROP(inq); 255 m_freem(m); 256 } else 257 IF_ENQUEUE(inq, m); 258 splx(s); 259 return (error); 260 } 261 if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){ 262 m2 = m_copy(m, 0, (int)M_COPYALL); 263 m2->m_pkthdr.rcvif = ifp; 264 schednetisr(NETISR_NS); 265 inq = &nsintrq; 266 s = splimp(); 267 if (IF_QFULL(inq)) { 268 IF_DROP(inq); 269 m_freem(m2); 270 } else 271 IF_ENQUEUE(inq, m2); 272 splx(s); 273 } 274 /* If broadcasting on a simplex interface, loopback a copy */ 275 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)){ 276 mcopy = m_copy(m, 0, (int)M_COPYALL); 277 } 278 break; 279 #endif /* NS */ 280 #ifdef ISO 281 case AF_ISO: { 282 int snpalen; 283 struct llc *l; 284 register struct sockaddr_dl *sdl; 285 286 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 287 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 288 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 289 } else if (error = 290 iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 291 (char *)edst, &snpalen)) 292 goto bad; /* Not Resolved */ 293 /* If broadcasting on a simplex interface, loopback a copy */ 294 if (*edst & 1) 295 m->m_flags |= (M_BCAST|M_MCAST); 296 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && 297 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 298 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 299 if (mcopy) { 300 eh = mtod(mcopy, struct ether_header *); 301 bcopy((caddr_t)edst, 302 (caddr_t)eh->ether_dhost, sizeof (edst)); 303 bcopy((caddr_t)ac->ac_enaddr, 304 (caddr_t)eh->ether_shost, sizeof (edst)); 305 } 306 } 307 M_PREPEND(m, 3, M_DONTWAIT); 308 if (m == NULL) 309 return (0); 310 type = htons(m->m_pkthdr.len); 311 l = mtod(m, struct llc *); 312 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 313 l->llc_control = LLC_UI; 314 len += 3; 315 IFDEBUG(D_ETHER) 316 int i; 317 printf("unoutput: sending pkt to: "); 318 for (i=0; i<6; i++) 319 printf("%x ", edst[i] & 0xff); 320 printf("\n"); 321 ENDDEBUG 322 } break; 323 #endif /* ISO */ 324 #ifdef LLC 325 /* case AF_NSAP: */ 326 case AF_CCITT: { 327 register struct sockaddr_dl *sdl = 328 (struct sockaddr_dl *) rt -> rt_gateway; 329 330 if (sdl && sdl->sdl_family == AF_LINK 331 && sdl->sdl_alen > 0) { 332 bcopy(LLADDR(sdl), (char *)edst, 333 sizeof(edst)); 334 } else goto bad; /* Not a link interface ? Funny ... */ 335 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) && 336 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 337 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 338 if (mcopy) { 339 eh = mtod(mcopy, struct ether_header *); 340 bcopy((caddr_t)edst, 341 (caddr_t)eh->ether_dhost, sizeof (edst)); 342 bcopy((caddr_t)ac->ac_enaddr, 343 (caddr_t)eh->ether_shost, sizeof (edst)); 344 } 345 } 346 type = htons(m->m_pkthdr.len); 347 #ifdef LLC_DEBUG 348 { 349 int i; 350 register struct llc *l = mtod(m, struct llc *); 351 352 printf("ether_output: sending LLC2 pkt to: "); 353 for (i=0; i<6; i++) 354 printf("%x ", edst[i] & 0xff); 355 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 356 type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff, 357 l->llc_control & 0xff); 358 359 } 360 #endif /* LLC_DEBUG */ 361 } break; 362 #endif /* LLC */ 363 364 case AF_UNSPEC: 365 eh = (struct ether_header *)dst->sa_data; 366 (void)memcpy(edst, eh->ether_dhost, sizeof (edst)); 367 type = eh->ether_type; 368 break; 369 370 default: 371 printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit, 372 dst->sa_family); 373 senderr(EAFNOSUPPORT); 374 } 375 376 377 if (mcopy) 378 (void) looutput(ifp, mcopy, dst, rt); 379 /* 380 * Add local net header. If no space in first mbuf, 381 * allocate another. 382 */ 383 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 384 if (m == 0) 385 senderr(ENOBUFS); 386 eh = mtod(m, struct ether_header *); 387 (void)memcpy(&eh->ether_type, &type, 388 sizeof(eh->ether_type)); 389 (void)memcpy(eh->ether_dhost, edst, sizeof (edst)); 390 (void)memcpy(eh->ether_shost, ac->ac_enaddr, 391 sizeof(eh->ether_shost)); 392 s = splimp(); 393 /* 394 * Queue message on interface, and start output if interface 395 * not yet active. 396 */ 397 if (IF_QFULL(&ifp->if_snd)) { 398 IF_DROP(&ifp->if_snd); 399 splx(s); 400 senderr(ENOBUFS); 401 } 402 IF_ENQUEUE(&ifp->if_snd, m); 403 if ((ifp->if_flags & IFF_OACTIVE) == 0) 404 (*ifp->if_start)(ifp); 405 splx(s); 406 ifp->if_obytes += len + sizeof (struct ether_header); 407 if (m->m_flags & M_MCAST) 408 ifp->if_omcasts++; 409 return (error); 410 411 bad: 412 if (m) 413 m_freem(m); 414 return (error); 415 } 416 417 /* 418 * Process a received Ethernet packet; 419 * the packet is in the mbuf chain m without 420 * the ether header, which is provided separately. 421 */ 422 void 423 ether_input(ifp, eh, m) 424 struct ifnet *ifp; 425 register struct ether_header *eh; 426 struct mbuf *m; 427 { 428 register struct ifqueue *inq; 429 u_short ether_type, *checksum; 430 int s; 431 #if defined (ISO) || defined (LLC) || defined(NETATALK) 432 register struct llc *l; 433 #endif 434 435 if ((ifp->if_flags & IFF_UP) == 0) { 436 m_freem(m); 437 return; 438 } 439 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh); 440 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 441 sizeof(etherbroadcastaddr)) == 0) 442 m->m_flags |= M_BCAST; 443 else if (eh->ether_dhost[0] & 1) 444 m->m_flags |= M_MCAST; 445 if (m->m_flags & (M_BCAST|M_MCAST)) 446 ifp->if_imcasts++; 447 448 ether_type = ntohs(eh->ether_type); 449 450 switch (ether_type) { 451 #ifdef INET 452 case ETHERTYPE_IP: 453 schednetisr(NETISR_IP); 454 inq = &ipintrq; 455 break; 456 457 case ETHERTYPE_ARP: 458 schednetisr(NETISR_ARP); 459 inq = &arpintrq; 460 break; 461 #endif 462 #ifdef IPX 463 case ETHERTYPE_IPX: 464 schednetisr(NETISR_IPX); 465 inq = &ipxintrq; 466 break; 467 #endif 468 #ifdef NS 469 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */ 470 schednetisr(NETISR_NS); 471 inq = &nsintrq; 472 break; 473 474 #endif /* NS */ 475 #ifdef NETATALK 476 case ETHERTYPE_AT: 477 schednetisr(NETISR_ATALK); 478 inq = &atintrq1; 479 break; 480 case ETHERTYPE_AARP: 481 /* probably this should be done with a NETISR as well */ 482 aarpinput((struct arpcom *)ifp, m); /* XXX */ 483 return; 484 #endif NETATALK 485 default: 486 #ifdef NS 487 checksum = mtod(m, ushort *); 488 /* Novell 802.3 */ 489 if ((ether_type <= ETHERMTU) && 490 ((*checksum == 0xffff) || (*checksum == 0xE0E0))){ 491 if(*checksum == 0xE0E0) { 492 m->m_pkthdr.len -= 3; 493 m->m_len -= 3; 494 m->m_data += 3; 495 } 496 schednetisr(NETISR_NS); 497 inq = &nsintrq; 498 break; 499 } 500 #endif /* NS */ 501 #if defined (ISO) || defined (LLC) || defined(NETATALK) 502 if (ether_type > ETHERMTU) 503 goto dropanyway; 504 l = mtod(m, struct llc *); 505 switch (l->llc_dsap) { 506 #ifdef NETATALK 507 case LLC_SNAP_LSAP: 508 switch (l->llc_control) { 509 case LLC_UI: 510 if (l->llc_ssap != LLC_SNAP_LSAP) 511 goto dropanyway; 512 513 if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code, 514 sizeof(at_org_code)) == 0 && 515 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) { 516 inq = &atintrq2; 517 m_adj( m, sizeof( struct llc )); 518 schednetisr(NETISR_ATALK); 519 break; 520 } 521 522 if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code, 523 sizeof(aarp_org_code)) == 0 && 524 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) { 525 m_adj( m, sizeof( struct llc )); 526 aarpinput((struct arpcom *)ifp, m); /* XXX */ 527 return; 528 } 529 530 default: 531 goto dropanyway; 532 } 533 break; 534 #endif NETATALK 535 #ifdef ISO 536 case LLC_ISO_LSAP: 537 switch (l->llc_control) { 538 case LLC_UI: 539 /* LLC_UI_P forbidden in class 1 service */ 540 if ((l->llc_dsap == LLC_ISO_LSAP) && 541 (l->llc_ssap == LLC_ISO_LSAP)) { 542 /* LSAP for ISO */ 543 if (m->m_pkthdr.len > ether_type) 544 m_adj(m, ether_type - m->m_pkthdr.len); 545 m->m_data += 3; /* XXX */ 546 m->m_len -= 3; /* XXX */ 547 m->m_pkthdr.len -= 3; /* XXX */ 548 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 549 if (m == 0) 550 return; 551 *mtod(m, struct ether_header *) = *eh; 552 IFDEBUG(D_ETHER) 553 printf("clnp packet"); 554 ENDDEBUG 555 schednetisr(NETISR_ISO); 556 inq = &clnlintrq; 557 break; 558 } 559 goto dropanyway; 560 561 case LLC_XID: 562 case LLC_XID_P: 563 if(m->m_len < 6) 564 goto dropanyway; 565 l->llc_window = 0; 566 l->llc_fid = 9; 567 l->llc_class = 1; 568 l->llc_dsap = l->llc_ssap = 0; 569 /* Fall through to */ 570 case LLC_TEST: 571 case LLC_TEST_P: 572 { 573 struct sockaddr sa; 574 register struct ether_header *eh2; 575 int i; 576 u_char c = l->llc_dsap; 577 578 l->llc_dsap = l->llc_ssap; 579 l->llc_ssap = c; 580 if (m->m_flags & (M_BCAST | M_MCAST)) 581 bcopy((caddr_t)ac->ac_enaddr, 582 (caddr_t)eh->ether_dhost, 6); 583 sa.sa_family = AF_UNSPEC; 584 sa.sa_len = sizeof(sa); 585 eh2 = (struct ether_header *)sa.sa_data; 586 for (i = 0; i < 6; i++) { 587 eh2->ether_shost[i] = c = eh->ether_dhost[i]; 588 eh2->ether_dhost[i] = 589 eh->ether_dhost[i] = eh->ether_shost[i]; 590 eh->ether_shost[i] = c; 591 } 592 ifp->if_output(ifp, m, &sa, NULL); 593 return; 594 } 595 default: 596 m_freem(m); 597 return; 598 } 599 break; 600 #endif /* ISO */ 601 #ifdef LLC 602 case LLC_X25_LSAP: 603 { 604 if (m->m_pkthdr.len > ether_type) 605 m_adj(m, ether_type - m->m_pkthdr.len); 606 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 607 if (m == 0) 608 return; 609 if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 610 eh->ether_dhost, LLC_X25_LSAP, 6, 611 mtod(m, struct sdl_hdr *))) 612 panic("ETHER cons addr failure"); 613 mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type; 614 #ifdef LLC_DEBUG 615 printf("llc packet\n"); 616 #endif /* LLC_DEBUG */ 617 schednetisr(NETISR_CCITT); 618 inq = &llcintrq; 619 break; 620 } 621 #endif /* LLC */ 622 dropanyway: 623 default: 624 m_freem(m); 625 return; 626 } 627 #else /* ISO || LLC || NETATALK */ 628 m_freem(m); 629 return; 630 #endif /* ISO || LLC || NETATALK */ 631 } 632 633 s = splimp(); 634 if (IF_QFULL(inq)) { 635 IF_DROP(inq); 636 m_freem(m); 637 } else 638 IF_ENQUEUE(inq, m); 639 splx(s); 640 } 641 642 /* 643 * Perform common duties while attaching to interface list 644 */ 645 void 646 ether_ifattach(ifp) 647 register struct ifnet *ifp; 648 { 649 register struct ifaddr *ifa; 650 register struct sockaddr_dl *sdl; 651 652 ifp->if_type = IFT_ETHER; 653 ifp->if_addrlen = 6; 654 ifp->if_hdrlen = 14; 655 ifp->if_mtu = ETHERMTU; 656 ifp->if_resolvemulti = ether_resolvemulti; 657 if (ifp->if_baudrate == 0) 658 ifp->if_baudrate = 10000000; 659 ifa = ifnet_addrs[ifp->if_index - 1]; 660 if (ifa == 0) { 661 printf("ether_ifattach: no lladdr!\n"); 662 return; 663 } 664 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 665 sdl->sdl_type = IFT_ETHER; 666 sdl->sdl_alen = ifp->if_addrlen; 667 bcopy(((struct arpcom *)ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen); 668 } 669 670 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); 671 672 int 673 ether_ioctl(struct ifnet *ifp, int command, caddr_t data) 674 { 675 struct ifaddr *ifa = (struct ifaddr *) data; 676 struct ifreq *ifr = (struct ifreq *) data; 677 int error = 0; 678 679 switch (command) { 680 case SIOCSIFADDR: 681 ifp->if_flags |= IFF_UP; 682 683 switch (ifa->ifa_addr->sa_family) { 684 #ifdef INET 685 case AF_INET: 686 ifp->if_init(ifp->if_softc); /* before arpwhohas */ 687 arp_ifinit((struct arpcom *)ifp, ifa); 688 break; 689 #endif 690 #ifdef IPX 691 /* 692 * XXX - This code is probably wrong 693 */ 694 case AF_IPX: 695 { 696 register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 697 struct arpcom *ac = (struct arpcom *) (ifp->if_softc); 698 699 if (ipx_nullhost(*ina)) 700 ina->x_host = 701 *(union ipx_host *) 702 ac->ac_enaddr; 703 else { 704 bcopy((caddr_t) ina->x_host.c_host, 705 (caddr_t) ac->ac_enaddr, 706 sizeof(ac->ac_enaddr)); 707 } 708 709 /* 710 * Set new address 711 */ 712 ifp->if_init(ifp->if_softc); 713 break; 714 } 715 #endif 716 #ifdef NS 717 /* 718 * XXX - This code is probably wrong 719 */ 720 case AF_NS: 721 { 722 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 723 struct arpcom *ac = (struct arpcom *) (ifp->if_softc); 724 725 if (ns_nullhost(*ina)) 726 ina->x_host = 727 *(union ns_host *) (ac->ac_enaddr); 728 else { 729 bcopy((caddr_t) ina->x_host.c_host, 730 (caddr_t) ac->ac_enaddr, 731 sizeof(ac->ac_enaddr)); 732 } 733 734 /* 735 * Set new address 736 */ 737 ifp->if_init(ifp->if_softc); 738 break; 739 } 740 #endif 741 default: 742 ifp->if_init(ifp->if_softc); 743 break; 744 } 745 break; 746 747 case SIOCGIFADDR: 748 { 749 struct sockaddr *sa; 750 751 sa = (struct sockaddr *) & ifr->ifr_data; 752 bcopy(((struct arpcom *)ifp->if_softc)->ac_enaddr, 753 (caddr_t) sa->sa_data, ETHER_ADDR_LEN); 754 } 755 break; 756 757 case SIOCSIFMTU: 758 /* 759 * Set the interface MTU. 760 */ 761 if (ifr->ifr_mtu > ETHERMTU) { 762 error = EINVAL; 763 } else { 764 ifp->if_mtu = ifr->ifr_mtu; 765 } 766 break; 767 } 768 return (error); 769 } 770 771 int 772 ether_resolvemulti(ifp, llsa, sa) 773 struct ifnet *ifp; 774 struct sockaddr **llsa; 775 struct sockaddr *sa; 776 { 777 struct sockaddr_dl *sdl; 778 struct sockaddr_in *sin; 779 u_char *e_addr; 780 781 switch(sa->sa_family) { 782 case AF_LINK: 783 sdl = (struct sockaddr_dl *)sa; 784 e_addr = LLADDR(sdl); 785 if ((e_addr[0] & 1) != 1) 786 return EADDRNOTAVAIL; 787 *llsa = 0; 788 return 0; 789 790 #ifdef INET 791 case AF_INET: 792 sin = (struct sockaddr_in *)sa; 793 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 794 return EADDRNOTAVAIL; 795 MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR, 796 M_WAITOK); 797 sdl->sdl_len = sizeof *sdl; 798 sdl->sdl_family = AF_LINK; 799 sdl->sdl_index = ifp->if_index; 800 sdl->sdl_type = IFT_ETHER; 801 sdl->sdl_nlen = 0; 802 sdl->sdl_alen = ETHER_ADDR_LEN; 803 sdl->sdl_slen = 0; 804 e_addr = LLADDR(sdl); 805 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr); 806 *llsa = (struct sockaddr *)sdl; 807 return 0; 808 #endif 809 810 default: 811 /* 812 * Well, the text isn't quite right, but it's the name 813 * that counts... 814 */ 815 return EAFNOSUPPORT; 816 } 817 } 818