1 /* $NetBSD: if_ethersubr.c,v 1.52 2000/02/01 22:52:05 thorpej Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * 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. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1982, 1989, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by the University of 47 * California, Berkeley and its contributors. 48 * 4. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 * @(#)if_ethersubr.c 8.2 (Berkeley) 4/4/96 65 */ 66 67 #include "opt_inet.h" 68 #include "opt_atalk.h" 69 #include "opt_ccitt.h" 70 #include "opt_llc.h" 71 #include "opt_iso.h" 72 #include "opt_ns.h" 73 #include "opt_gateway.h" 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/kernel.h> 78 #include <sys/malloc.h> 79 #include <sys/mbuf.h> 80 #include <sys/protosw.h> 81 #include <sys/socket.h> 82 #include <sys/ioctl.h> 83 #include <sys/errno.h> 84 #include <sys/syslog.h> 85 86 #include <machine/cpu.h> 87 88 #include <net/if.h> 89 #include <net/netisr.h> 90 #include <net/route.h> 91 #include <net/if_llc.h> 92 #include <net/if_dl.h> 93 #include <net/if_types.h> 94 95 #include <net/if_ether.h> 96 97 #include <netinet/in.h> 98 #ifdef INET 99 #include <netinet/in_var.h> 100 #endif 101 #include <netinet/if_inarp.h> 102 103 #ifdef INET6 104 #ifndef INET 105 #include <netinet/in.h> 106 #endif 107 #include <netinet6/in6_var.h> 108 #include <netinet6/nd6.h> 109 #include <netinet6/in6_ifattach.h> 110 #endif 111 112 #ifdef NS 113 #include <netns/ns.h> 114 #include <netns/ns_if.h> 115 #endif 116 117 #ifdef IPX 118 #include <netipx/ipx.h> 119 #include <netipx/ipx_if.h> 120 #endif 121 122 #ifdef ISO 123 #include <netiso/argo_debug.h> 124 #include <netiso/iso.h> 125 #include <netiso/iso_var.h> 126 #include <netiso/iso_snpac.h> 127 #endif 128 129 #ifdef LLC 130 #include <netccitt/dll.h> 131 #include <netccitt/llc_var.h> 132 #endif 133 134 #if defined(LLC) && defined(CCITT) 135 extern struct ifqueue pkintrq; 136 #endif 137 138 #ifdef NETATALK 139 #include <netatalk/at.h> 140 #include <netatalk/at_var.h> 141 #include <netatalk/at_extern.h> 142 143 #define llc_snap_org_code llc_un.type_snap.org_code 144 #define llc_snap_ether_type llc_un.type_snap.ether_type 145 146 extern u_char at_org_code[3]; 147 extern u_char aarp_org_code[3]; 148 #endif /* NETATALK */ 149 150 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 151 #define senderr(e) { error = (e); goto bad;} 152 153 #define SIN(x) ((struct sockaddr_in *)x) 154 155 static int ether_output __P((struct ifnet *, struct mbuf *, 156 struct sockaddr *, struct rtentry *)); 157 static void ether_input __P((struct ifnet *, struct mbuf *)); 158 159 /* 160 * Ethernet output routine. 161 * Encapsulate a packet of type family for the local net. 162 * Assumes that ifp is actually pointer to ethercom structure. 163 */ 164 static int 165 ether_output(ifp, m0, dst, rt0) 166 struct ifnet *ifp; 167 struct mbuf *m0; 168 struct sockaddr *dst; 169 struct rtentry *rt0; 170 { 171 u_int16_t etype = 0; 172 int s, error = 0, hdrcmplt = 0; 173 u_char esrc[6], edst[6]; 174 struct mbuf *m = m0; 175 struct rtentry *rt; 176 struct mbuf *mcopy = (struct mbuf *)0; 177 struct ether_header *eh; 178 #ifdef INET 179 struct arphdr *ah; 180 #endif /* INET */ 181 #ifdef NETATALK 182 struct at_ifaddr *aa; 183 #endif /* NETATALK */ 184 185 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 186 senderr(ENETDOWN); 187 ifp->if_lastchange = time; 188 if ((rt = rt0) != NULL) { 189 if ((rt->rt_flags & RTF_UP) == 0) { 190 if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) { 191 rt->rt_refcnt--; 192 if (rt->rt_ifp != ifp) 193 return (*rt->rt_ifp->if_output) 194 (ifp, m0, dst, rt); 195 } else 196 senderr(EHOSTUNREACH); 197 } 198 if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS) { 199 if (rt->rt_gwroute == 0) 200 goto lookup; 201 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 202 rtfree(rt); rt = rt0; 203 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1); 204 if ((rt = rt->rt_gwroute) == 0) 205 senderr(EHOSTUNREACH); 206 /* the "G" test below also prevents rt == rt0 */ 207 if ((rt->rt_flags & RTF_GATEWAY) || 208 (rt->rt_ifp != ifp)) { 209 rt->rt_refcnt--; 210 rt0->rt_gwroute = 0; 211 senderr(EHOSTUNREACH); 212 } 213 } 214 } 215 if (rt->rt_flags & RTF_REJECT) 216 if (rt->rt_rmx.rmx_expire == 0 || 217 time.tv_sec < rt->rt_rmx.rmx_expire) 218 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 219 } 220 switch (dst->sa_family) { 221 222 #ifdef INET 223 case AF_INET: 224 if (m->m_flags & M_BCAST) 225 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst, 226 sizeof(edst)); 227 228 else if (m->m_flags & M_MCAST) { 229 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, 230 (caddr_t)edst) 231 232 } else if (!arpresolve(ifp, rt, m, dst, edst)) 233 return (0); /* if not yet resolved */ 234 /* If broadcasting on a simplex interface, loopback a copy */ 235 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 236 mcopy = m_copy(m, 0, (int)M_COPYALL); 237 etype = htons(ETHERTYPE_IP); 238 break; 239 240 case AF_ARP: 241 ah = mtod(m, struct arphdr *); 242 if (m->m_flags & M_BCAST) 243 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst, 244 sizeof(edst)); 245 else 246 bcopy((caddr_t)ar_tha(ah), 247 (caddr_t)edst, sizeof(edst)); 248 249 ah->ar_hrd = htons(ARPHRD_ETHER); 250 251 switch(ntohs(ah->ar_op)) { 252 case ARPOP_REVREQUEST: 253 case ARPOP_REVREPLY: 254 etype = htons(ETHERTYPE_REVARP); 255 break; 256 257 case ARPOP_REQUEST: 258 case ARPOP_REPLY: 259 default: 260 etype = htons(ETHERTYPE_ARP); 261 } 262 263 break; 264 #endif 265 #ifdef INET6 266 case AF_INET6: 267 #ifdef OLDIP6OUTPUT 268 if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst)) 269 return(0); /* if not yet resolves */ 270 #else 271 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)){ 272 /* this must be impossible, so we bark */ 273 printf("nd6_storelladdr failed\n"); 274 return(0); 275 } 276 #endif /* OLDIP6OUTPUT */ 277 etype = htons(ETHERTYPE_IPV6); 278 break; 279 #endif 280 #ifdef NETATALK 281 case AF_APPLETALK: 282 if (!aarpresolve(ifp, m, (struct sockaddr_at *)dst, edst)) { 283 #ifdef NETATALKDEBUG 284 printf("aarpresolv failed\n"); 285 #endif /* NETATALKDEBUG */ 286 return (0); 287 } 288 /* 289 * ifaddr is the first thing in at_ifaddr 290 */ 291 aa = (struct at_ifaddr *) at_ifawithnet( 292 (struct sockaddr_at *)dst, ifp); 293 if (aa == NULL) 294 goto bad; 295 296 /* 297 * In the phase 2 case, we need to prepend an mbuf for the 298 * llc header. Since we must preserve the value of m, 299 * which is passed to us by value, we m_copy() the first 300 * mbuf, and use it for our llc header. 301 */ 302 if (aa->aa_flags & AFA_PHASE2) { 303 struct llc llc; 304 305 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT); 306 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 307 llc.llc_control = LLC_UI; 308 bcopy(at_org_code, llc.llc_snap_org_code, 309 sizeof(llc.llc_snap_org_code)); 310 llc.llc_snap_ether_type = htons(ETHERTYPE_ATALK); 311 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc)); 312 } else { 313 etype = htons(ETHERTYPE_ATALK); 314 } 315 break; 316 #endif /* NETATALK */ 317 #ifdef NS 318 case AF_NS: 319 etype = htons(ETHERTYPE_NS); 320 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 321 (caddr_t)edst, sizeof (edst)); 322 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))) 323 return (looutput(ifp, m, dst, rt)); 324 /* If broadcasting on a simplex interface, loopback a copy */ 325 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 326 mcopy = m_copy(m, 0, (int)M_COPYALL); 327 break; 328 #endif 329 #ifdef IPX 330 case AF_IPX: 331 etype = htons(ETHERTYPE_IPX); 332 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host), 333 (caddr_t)edst, sizeof (edst)); 334 /* If broadcasting on a simplex interface, loopback a copy */ 335 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 336 mcopy = m_copy(m, 0, (int)M_COPYALL); 337 break; 338 #endif 339 #ifdef ISO 340 case AF_ISO: { 341 int snpalen; 342 struct llc *l; 343 struct sockaddr_dl *sdl; 344 345 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 346 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 347 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 348 } else { 349 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 350 (char *)edst, &snpalen); 351 if (error) 352 goto bad; /* Not Resolved */ 353 } 354 /* If broadcasting on a simplex interface, loopback a copy */ 355 if (*edst & 1) 356 m->m_flags |= (M_BCAST|M_MCAST); 357 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && 358 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 359 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 360 if (mcopy) { 361 eh = mtod(mcopy, struct ether_header *); 362 bcopy((caddr_t)edst, 363 (caddr_t)eh->ether_dhost, sizeof (edst)); 364 bcopy(LLADDR(ifp->if_sadl), 365 (caddr_t)eh->ether_shost, sizeof (edst)); 366 } 367 } 368 M_PREPEND(m, 3, M_DONTWAIT); 369 if (m == NULL) 370 return (0); 371 l = mtod(m, struct llc *); 372 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 373 l->llc_control = LLC_UI; 374 #ifdef ARGO_DEBUG 375 if (argo_debug[D_ETHER]) { 376 int i; 377 printf("unoutput: sending pkt to: "); 378 for (i=0; i<6; i++) 379 printf("%x ", edst[i] & 0xff); 380 printf("\n"); 381 } 382 #endif 383 } break; 384 #endif /* ISO */ 385 #ifdef LLC 386 /* case AF_NSAP: */ 387 case AF_CCITT: { 388 struct sockaddr_dl *sdl = 389 (struct sockaddr_dl *) rt -> rt_gateway; 390 391 if (sdl && sdl->sdl_family == AF_LINK 392 && sdl->sdl_alen > 0) { 393 bcopy(LLADDR(sdl), (char *)edst, 394 sizeof(edst)); 395 } else goto bad; /* Not a link interface ? Funny ... */ 396 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) && 397 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 398 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 399 if (mcopy) { 400 eh = mtod(mcopy, struct ether_header *); 401 bcopy((caddr_t)edst, 402 (caddr_t)eh->ether_dhost, sizeof (edst)); 403 bcopy(LLADDR(ifp->if_sadl), 404 (caddr_t)eh->ether_shost, sizeof (edst)); 405 } 406 } 407 #ifdef LLC_DEBUG 408 { 409 int i; 410 struct llc *l = mtod(m, struct llc *); 411 412 printf("ether_output: sending LLC2 pkt to: "); 413 for (i=0; i<6; i++) 414 printf("%x ", edst[i] & 0xff); 415 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 416 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff, 417 l->llc_control & 0xff); 418 419 } 420 #endif /* LLC_DEBUG */ 421 } break; 422 #endif /* LLC */ 423 424 case pseudo_AF_HDRCMPLT: 425 hdrcmplt = 1; 426 eh = (struct ether_header *)dst->sa_data; 427 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc)); 428 /* FALLTHROUGH */ 429 430 case AF_UNSPEC: 431 eh = (struct ether_header *)dst->sa_data; 432 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 433 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */ 434 etype = eh->ether_type; 435 break; 436 437 default: 438 printf("%s: can't handle af%d\n", ifp->if_xname, 439 dst->sa_family); 440 senderr(EAFNOSUPPORT); 441 } 442 443 if (mcopy) 444 (void) looutput(ifp, mcopy, dst, rt); 445 446 /* If no ether type is set, this must be a 802.2 formatted packet. 447 */ 448 if (etype == 0) 449 etype = htons(m->m_pkthdr.len); 450 /* 451 * Add local net header. If no space in first mbuf, 452 * allocate another. 453 */ 454 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 455 if (m == 0) 456 senderr(ENOBUFS); 457 eh = mtod(m, struct ether_header *); 458 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, 459 sizeof(eh->ether_type)); 460 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 461 if (hdrcmplt) 462 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost, 463 sizeof(eh->ether_shost)); 464 else 465 bcopy(LLADDR(ifp->if_sadl), (caddr_t)eh->ether_shost, 466 sizeof(eh->ether_shost)); 467 s = splimp(); 468 /* 469 * Queue message on interface, and start output if interface 470 * not yet active. 471 */ 472 if (IF_QFULL(&ifp->if_snd)) { 473 IF_DROP(&ifp->if_snd); 474 splx(s); 475 senderr(ENOBUFS); 476 } 477 ifp->if_obytes += m->m_pkthdr.len; 478 IF_ENQUEUE(&ifp->if_snd, m); 479 if ((ifp->if_flags & IFF_OACTIVE) == 0) 480 (*ifp->if_start)(ifp); 481 splx(s); 482 if (m->m_flags & M_MCAST) 483 ifp->if_omcasts++; 484 return (error); 485 486 bad: 487 if (m) 488 m_freem(m); 489 return (error); 490 } 491 492 /* 493 * Process a received Ethernet packet; 494 * the packet is in the mbuf chain m with 495 * the ether header. 496 */ 497 static void 498 ether_input(ifp, m) 499 struct ifnet *ifp; 500 struct mbuf *m; 501 { 502 struct ifqueue *inq; 503 u_int16_t etype; 504 int s; 505 struct ether_header *eh; 506 #if defined (ISO) || defined (LLC) || defined(NETATALK) 507 struct llc *l; 508 #endif 509 510 if ((ifp->if_flags & IFF_UP) == 0) { 511 m_freem(m); 512 return; 513 } 514 515 eh = mtod(m, struct ether_header *); 516 517 ifp->if_lastchange = time; 518 ifp->if_ibytes += m->m_pkthdr.len; 519 if (eh->ether_dhost[0] & 1) { 520 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 521 sizeof(etherbroadcastaddr)) == 0) 522 m->m_flags |= M_BCAST; 523 else 524 m->m_flags |= M_MCAST; 525 } 526 if (m->m_flags & (M_BCAST|M_MCAST)) 527 ifp->if_imcasts++; 528 529 etype = ntohs(eh->ether_type); 530 531 /* Strip off the Ethernet header. */ 532 m_adj(m, sizeof(struct ether_header)); 533 534 /* If the CRC is still on the packet, trim it off. */ 535 if (m->m_flags & M_HASFCS) 536 m_adj(m, -ETHER_CRC_LEN); 537 538 switch (etype) { 539 #ifdef INET 540 case ETHERTYPE_IP: 541 #ifdef GATEWAY 542 if (ipflow_fastforward(m)) 543 return; 544 #endif 545 schednetisr(NETISR_IP); 546 inq = &ipintrq; 547 break; 548 549 case ETHERTYPE_ARP: 550 schednetisr(NETISR_ARP); 551 inq = &arpintrq; 552 break; 553 554 case ETHERTYPE_REVARP: 555 revarpinput(m); /* XXX queue? */ 556 return; 557 #endif 558 #ifdef INET6 559 case ETHERTYPE_IPV6: 560 schednetisr(NETISR_IPV6); 561 inq = &ip6intrq; 562 break; 563 #endif 564 #ifdef NS 565 case ETHERTYPE_NS: 566 schednetisr(NETISR_NS); 567 inq = &nsintrq; 568 break; 569 570 #endif 571 #ifdef IPX 572 case ETHERTYPE_IPX: 573 schednetisr(NETISR_IPX); 574 inq = &ipxintrq; 575 break; 576 #endif 577 #ifdef NETATALK 578 case ETHERTYPE_ATALK: 579 schednetisr(NETISR_ATALK); 580 inq = &atintrq1; 581 break; 582 case ETHERTYPE_AARP: 583 /* probably this should be done with a NETISR as well */ 584 aarpinput(ifp, m); /* XXX */ 585 return; 586 #endif /* NETATALK */ 587 default: 588 #if defined (ISO) || defined (LLC) || defined (NETATALK) 589 if (etype > ETHERMTU) 590 goto dropanyway; 591 l = mtod(m, struct llc *); 592 switch (l->llc_dsap) { 593 #ifdef NETATALK 594 case LLC_SNAP_LSAP: 595 switch (l->llc_control) { 596 case LLC_UI: 597 if (l->llc_ssap != LLC_SNAP_LSAP) { 598 goto dropanyway; 599 } 600 601 if (Bcmp(&(l->llc_snap_org_code)[0], 602 at_org_code, sizeof(at_org_code)) == 0 && 603 ntohs(l->llc_snap_ether_type) == 604 ETHERTYPE_ATALK) { 605 inq = &atintrq2; 606 m_adj(m, sizeof(struct llc)); 607 schednetisr(NETISR_ATALK); 608 break; 609 } 610 611 if (Bcmp(&(l->llc_snap_org_code)[0], 612 aarp_org_code, 613 sizeof(aarp_org_code)) == 0 && 614 ntohs(l->llc_snap_ether_type) == 615 ETHERTYPE_AARP) { 616 m_adj( m, sizeof(struct llc)); 617 aarpinput(ifp, m); /* XXX */ 618 return; 619 } 620 621 default: 622 goto dropanyway; 623 } 624 break; 625 #endif /* NETATALK */ 626 #ifdef ISO 627 case LLC_ISO_LSAP: 628 switch (l->llc_control) { 629 case LLC_UI: 630 /* LLC_UI_P forbidden in class 1 service */ 631 if ((l->llc_dsap == LLC_ISO_LSAP) && 632 (l->llc_ssap == LLC_ISO_LSAP)) { 633 /* LSAP for ISO */ 634 if (m->m_pkthdr.len > etype) 635 m_adj(m, etype - m->m_pkthdr.len); 636 m->m_data += 3; /* XXX */ 637 m->m_len -= 3; /* XXX */ 638 m->m_pkthdr.len -= 3; /* XXX */ 639 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 640 if (m == 0) 641 return; 642 *mtod(m, struct ether_header *) = *eh; 643 #ifdef ARGO_DEBUG 644 if (argo_debug[D_ETHER]) 645 printf("clnp packet"); 646 #endif 647 schednetisr(NETISR_ISO); 648 inq = &clnlintrq; 649 break; 650 } 651 goto dropanyway; 652 653 case LLC_XID: 654 case LLC_XID_P: 655 if(m->m_len < 6) 656 goto dropanyway; 657 l->llc_window = 0; 658 l->llc_fid = 9; 659 l->llc_class = 1; 660 l->llc_dsap = l->llc_ssap = 0; 661 /* Fall through to */ 662 case LLC_TEST: 663 case LLC_TEST_P: 664 { 665 struct sockaddr sa; 666 struct ether_header *eh2; 667 int i; 668 u_char c = l->llc_dsap; 669 670 l->llc_dsap = l->llc_ssap; 671 l->llc_ssap = c; 672 if (m->m_flags & (M_BCAST | M_MCAST)) 673 bcopy(LLADDR(ifp->if_sadl), 674 (caddr_t)eh->ether_dhost, 6); 675 sa.sa_family = AF_UNSPEC; 676 sa.sa_len = sizeof(sa); 677 eh2 = (struct ether_header *)sa.sa_data; 678 for (i = 0; i < 6; i++) { 679 eh2->ether_shost[i] = c = 680 eh->ether_dhost[i]; 681 eh2->ether_dhost[i] = 682 eh->ether_dhost[i] = 683 eh->ether_shost[i]; 684 eh->ether_shost[i] = c; 685 } 686 ifp->if_output(ifp, m, &sa, NULL); 687 return; 688 } 689 default: 690 m_freem(m); 691 return; 692 } 693 break; 694 #endif /* ISO */ 695 #ifdef LLC 696 case LLC_X25_LSAP: 697 { 698 if (m->m_pkthdr.len > etype) 699 m_adj(m, etype - m->m_pkthdr.len); 700 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 701 if (m == 0) 702 return; 703 if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 704 eh->ether_dhost, LLC_X25_LSAP, 6, 705 mtod(m, struct sdl_hdr *))) 706 panic("ETHER cons addr failure"); 707 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype; 708 #ifdef LLC_DEBUG 709 printf("llc packet\n"); 710 #endif /* LLC_DEBUG */ 711 schednetisr(NETISR_CCITT); 712 inq = &llcintrq; 713 break; 714 } 715 #endif /* LLC */ 716 dropanyway: 717 default: 718 m_freem(m); 719 return; 720 } 721 #else /* ISO || LLC || NETATALK*/ 722 m_freem(m); 723 return; 724 #endif /* ISO || LLC || NETATALK*/ 725 } 726 727 s = splimp(); 728 if (IF_QFULL(inq)) { 729 IF_DROP(inq); 730 m_freem(m); 731 } else 732 IF_ENQUEUE(inq, m); 733 splx(s); 734 } 735 736 /* 737 * Convert Ethernet address to printable (loggable) representation. 738 */ 739 static char digits[] = "0123456789abcdef"; 740 char * 741 ether_sprintf(ap) 742 const u_char *ap; 743 { 744 static char etherbuf[18]; 745 char *cp = etherbuf; 746 int i; 747 748 for (i = 0; i < 6; i++) { 749 *cp++ = digits[*ap >> 4]; 750 *cp++ = digits[*ap++ & 0xf]; 751 *cp++ = ':'; 752 } 753 *--cp = 0; 754 return (etherbuf); 755 } 756 757 /* 758 * Perform common duties while attaching to interface list 759 */ 760 void 761 ether_ifattach(ifp, lla) 762 struct ifnet *ifp; 763 const u_int8_t *lla; 764 { 765 struct sockaddr_dl *sdl; 766 767 ifp->if_type = IFT_ETHER; 768 ifp->if_addrlen = 6; 769 ifp->if_hdrlen = 14; 770 ifp->if_mtu = ETHERMTU; 771 ifp->if_output = ether_output; 772 ifp->if_input = ether_input; 773 if ((sdl = ifp->if_sadl) && 774 sdl->sdl_family == AF_LINK) { 775 sdl->sdl_type = IFT_ETHER; 776 sdl->sdl_alen = ifp->if_addrlen; 777 bcopy(lla, LLADDR(sdl), ifp->if_addrlen); 778 } 779 LIST_INIT(&((struct ethercom *)ifp)->ec_multiaddrs); 780 ifp->if_broadcastaddr = etherbroadcastaddr; 781 #ifdef INET6 782 in6_ifattach_getifid(ifp); 783 #endif 784 } 785 786 void 787 ether_ifdetach(ifp) 788 struct ifnet *ifp; 789 { 790 791 /* Nothing. */ 792 } 793 794 #ifdef INET 795 u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 796 u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 797 #endif 798 #ifdef INET6 799 u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 800 u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 801 #endif 802 /* 803 * Add an Ethernet multicast address or range of addresses to the list for a 804 * given interface. 805 */ 806 int 807 ether_addmulti(ifr, ec) 808 struct ifreq *ifr; 809 struct ethercom *ec; 810 { 811 struct ether_multi *enm; 812 #ifdef INET 813 struct sockaddr_in *sin; 814 #endif /* INET */ 815 #ifdef INET6 816 struct sockaddr_in6 *sin6; 817 #endif /* INET6 */ 818 u_char addrlo[6]; 819 u_char addrhi[6]; 820 int s = splimp(); 821 822 switch (ifr->ifr_addr.sa_family) { 823 824 case AF_UNSPEC: 825 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 826 bcopy(addrlo, addrhi, 6); 827 break; 828 829 #ifdef INET 830 case AF_INET: 831 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 832 if (sin->sin_addr.s_addr == INADDR_ANY) { 833 /* 834 * An IP address of INADDR_ANY means listen to all 835 * of the Ethernet multicast addresses used for IP. 836 * (This is for the sake of IP multicast routers.) 837 */ 838 bcopy(ether_ipmulticast_min, addrlo, 6); 839 bcopy(ether_ipmulticast_max, addrhi, 6); 840 } 841 else { 842 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 843 bcopy(addrlo, addrhi, 6); 844 } 845 break; 846 #endif 847 #ifdef INET6 848 case AF_INET6: 849 sin6 = (struct sockaddr_in6 *) 850 &(((struct in6_ifreq *)ifr)->ifr_addr); 851 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 852 /* 853 * An IP6 address of 0 means listen to all 854 * of the Ethernet multicast address used for IP6. 855 * (This is used for multicast routers.) 856 */ 857 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 858 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 859 #if 0 860 set_allmulti = 1; 861 #endif 862 } else { 863 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 864 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 865 } 866 break; 867 #endif 868 869 default: 870 splx(s); 871 return (EAFNOSUPPORT); 872 } 873 874 /* 875 * Verify that we have valid Ethernet multicast addresses. 876 */ 877 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 878 splx(s); 879 return (EINVAL); 880 } 881 /* 882 * See if the address range is already in the list. 883 */ 884 ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm); 885 if (enm != NULL) { 886 /* 887 * Found it; just increment the reference count. 888 */ 889 ++enm->enm_refcount; 890 splx(s); 891 return (0); 892 } 893 /* 894 * New address or range; malloc a new multicast record 895 * and link it into the interface's multicast list. 896 */ 897 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 898 if (enm == NULL) { 899 splx(s); 900 return (ENOBUFS); 901 } 902 bcopy(addrlo, enm->enm_addrlo, 6); 903 bcopy(addrhi, enm->enm_addrhi, 6); 904 enm->enm_ec = ec; 905 enm->enm_refcount = 1; 906 LIST_INSERT_HEAD(&ec->ec_multiaddrs, enm, enm_list); 907 ec->ec_multicnt++; 908 splx(s); 909 /* 910 * Return ENETRESET to inform the driver that the list has changed 911 * and its reception filter should be adjusted accordingly. 912 */ 913 return (ENETRESET); 914 } 915 916 /* 917 * Delete a multicast address record. 918 */ 919 int 920 ether_delmulti(ifr, ec) 921 struct ifreq *ifr; 922 struct ethercom *ec; 923 { 924 struct ether_multi *enm; 925 #ifdef INET 926 struct sockaddr_in *sin; 927 #endif /* INET */ 928 #ifdef INET6 929 struct sockaddr_in6 *sin6; 930 #endif /* INET6 */ 931 u_char addrlo[6]; 932 u_char addrhi[6]; 933 int s = splimp(); 934 935 switch (ifr->ifr_addr.sa_family) { 936 937 case AF_UNSPEC: 938 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 939 bcopy(addrlo, addrhi, 6); 940 break; 941 942 #ifdef INET 943 case AF_INET: 944 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 945 if (sin->sin_addr.s_addr == INADDR_ANY) { 946 /* 947 * An IP address of INADDR_ANY means stop listening 948 * to the range of Ethernet multicast addresses used 949 * for IP. 950 */ 951 bcopy(ether_ipmulticast_min, addrlo, 6); 952 bcopy(ether_ipmulticast_max, addrhi, 6); 953 } 954 else { 955 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 956 bcopy(addrlo, addrhi, 6); 957 } 958 break; 959 #endif 960 #ifdef INET6 961 case AF_INET6: 962 sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr); 963 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 964 /* 965 * An IP6 address of all 0 means stop listening 966 * to the range of Ethernet multicast addresses used 967 * for IP6 968 */ 969 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 970 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 971 } else { 972 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 973 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 974 } 975 break; 976 #endif 977 978 default: 979 splx(s); 980 return (EAFNOSUPPORT); 981 } 982 983 /* 984 * Look up the address in our list. 985 */ 986 ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm); 987 if (enm == NULL) { 988 splx(s); 989 return (ENXIO); 990 } 991 if (--enm->enm_refcount != 0) { 992 /* 993 * Still some claims to this record. 994 */ 995 splx(s); 996 return (0); 997 } 998 /* 999 * No remaining claims to this record; unlink and free it. 1000 */ 1001 LIST_REMOVE(enm, enm_list); 1002 free(enm, M_IFMADDR); 1003 ec->ec_multicnt--; 1004 splx(s); 1005 /* 1006 * Return ENETRESET to inform the driver that the list has changed 1007 * and its reception filter should be adjusted accordingly. 1008 */ 1009 return (ENETRESET); 1010 } 1011