1 /* $NetBSD: if_ethersubr.c,v 1.58 2000/06/17 20:57:20 matt 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 #endif 110 111 #ifdef NS 112 #include <netns/ns.h> 113 #include <netns/ns_if.h> 114 #endif 115 116 #ifdef IPX 117 #include <netipx/ipx.h> 118 #include <netipx/ipx_if.h> 119 #endif 120 121 #ifdef ISO 122 #include <netiso/argo_debug.h> 123 #include <netiso/iso.h> 124 #include <netiso/iso_var.h> 125 #include <netiso/iso_snpac.h> 126 #endif 127 128 #ifdef LLC 129 #include <netccitt/dll.h> 130 #include <netccitt/llc_var.h> 131 #endif 132 133 #if defined(LLC) && defined(CCITT) 134 extern struct ifqueue pkintrq; 135 #endif 136 137 #ifdef NETATALK 138 #include <netatalk/at.h> 139 #include <netatalk/at_var.h> 140 #include <netatalk/at_extern.h> 141 142 #define llc_snap_org_code llc_un.type_snap.org_code 143 #define llc_snap_ether_type llc_un.type_snap.ether_type 144 145 extern u_char at_org_code[3]; 146 extern u_char aarp_org_code[3]; 147 #endif /* NETATALK */ 148 149 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 150 #define senderr(e) { error = (e); goto bad;} 151 152 #define SIN(x) ((struct sockaddr_in *)x) 153 154 static int ether_output __P((struct ifnet *, struct mbuf *, 155 struct sockaddr *, struct rtentry *)); 156 static void ether_input __P((struct ifnet *, struct mbuf *)); 157 158 /* 159 * Ethernet output routine. 160 * Encapsulate a packet of type family for the local net. 161 * Assumes that ifp is actually pointer to ethercom structure. 162 */ 163 static int 164 ether_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, 165 struct rtentry *rt0) 166 { 167 u_int16_t etype = 0; 168 int s, error = 0, hdrcmplt = 0; 169 u_char esrc[6], edst[6]; 170 struct mbuf *m = m0; 171 struct rtentry *rt; 172 struct mbuf *mcopy = (struct mbuf *)0; 173 struct ether_header *eh; 174 #ifdef INET 175 struct arphdr *ah; 176 #endif /* INET */ 177 #ifdef NETATALK 178 struct at_ifaddr *aa; 179 #endif /* NETATALK */ 180 181 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 182 senderr(ENETDOWN); 183 ifp->if_lastchange = time; 184 if ((rt = rt0) != NULL) { 185 if ((rt->rt_flags & RTF_UP) == 0) { 186 if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) { 187 rt->rt_refcnt--; 188 if (rt->rt_ifp != ifp) 189 return (*rt->rt_ifp->if_output) 190 (ifp, m0, dst, rt); 191 } else 192 senderr(EHOSTUNREACH); 193 } 194 if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS) { 195 if (rt->rt_gwroute == 0) 196 goto lookup; 197 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 198 rtfree(rt); rt = rt0; 199 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1); 200 if ((rt = rt->rt_gwroute) == 0) 201 senderr(EHOSTUNREACH); 202 /* the "G" test below also prevents rt == rt0 */ 203 if ((rt->rt_flags & RTF_GATEWAY) || 204 (rt->rt_ifp != ifp)) { 205 rt->rt_refcnt--; 206 rt0->rt_gwroute = 0; 207 senderr(EHOSTUNREACH); 208 } 209 } 210 } 211 if (rt->rt_flags & RTF_REJECT) 212 if (rt->rt_rmx.rmx_expire == 0 || 213 time.tv_sec < rt->rt_rmx.rmx_expire) 214 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 215 } 216 switch (dst->sa_family) { 217 218 #ifdef INET 219 case AF_INET: 220 if (m->m_flags & M_BCAST) 221 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst, 222 sizeof(edst)); 223 224 else if (m->m_flags & M_MCAST) { 225 ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr, 226 (caddr_t)edst) 227 228 } else if (!arpresolve(ifp, rt, m, dst, edst)) 229 return (0); /* if not yet resolved */ 230 /* If broadcasting on a simplex interface, loopback a copy */ 231 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 232 mcopy = m_copy(m, 0, (int)M_COPYALL); 233 etype = htons(ETHERTYPE_IP); 234 break; 235 236 case AF_ARP: 237 ah = mtod(m, struct arphdr *); 238 if (m->m_flags & M_BCAST) 239 bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst, 240 sizeof(edst)); 241 else 242 bcopy((caddr_t)ar_tha(ah), 243 (caddr_t)edst, sizeof(edst)); 244 245 ah->ar_hrd = htons(ARPHRD_ETHER); 246 247 switch(ntohs(ah->ar_op)) { 248 case ARPOP_REVREQUEST: 249 case ARPOP_REVREPLY: 250 etype = htons(ETHERTYPE_REVARP); 251 break; 252 253 case ARPOP_REQUEST: 254 case ARPOP_REPLY: 255 default: 256 etype = htons(ETHERTYPE_ARP); 257 } 258 259 break; 260 #endif 261 #ifdef INET6 262 case AF_INET6: 263 #ifdef OLDIP6OUTPUT 264 if (!nd6_resolve(ifp, rt, m, dst, (u_char *)edst)) 265 return(0); /* if not yet resolves */ 266 #else 267 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)){ 268 /* this must be impossible, so we bark */ 269 printf("nd6_storelladdr failed\n"); 270 return(0); 271 } 272 #endif /* OLDIP6OUTPUT */ 273 etype = htons(ETHERTYPE_IPV6); 274 break; 275 #endif 276 #ifdef NETATALK 277 case AF_APPLETALK: 278 if (!aarpresolve(ifp, m, (struct sockaddr_at *)dst, edst)) { 279 #ifdef NETATALKDEBUG 280 printf("aarpresolv failed\n"); 281 #endif /* NETATALKDEBUG */ 282 return (0); 283 } 284 /* 285 * ifaddr is the first thing in at_ifaddr 286 */ 287 aa = (struct at_ifaddr *) at_ifawithnet( 288 (struct sockaddr_at *)dst, ifp); 289 if (aa == NULL) 290 goto bad; 291 292 /* 293 * In the phase 2 case, we need to prepend an mbuf for the 294 * llc header. Since we must preserve the value of m, 295 * which is passed to us by value, we m_copy() the first 296 * mbuf, and use it for our llc header. 297 */ 298 if (aa->aa_flags & AFA_PHASE2) { 299 struct llc llc; 300 301 M_PREPEND(m, sizeof(struct llc), M_DONTWAIT); 302 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 303 llc.llc_control = LLC_UI; 304 bcopy(at_org_code, llc.llc_snap_org_code, 305 sizeof(llc.llc_snap_org_code)); 306 llc.llc_snap_ether_type = htons(ETHERTYPE_ATALK); 307 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc)); 308 } else { 309 etype = htons(ETHERTYPE_ATALK); 310 } 311 break; 312 #endif /* NETATALK */ 313 #ifdef NS 314 case AF_NS: 315 etype = htons(ETHERTYPE_NS); 316 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 317 (caddr_t)edst, sizeof (edst)); 318 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))) 319 return (looutput(ifp, m, dst, rt)); 320 /* If broadcasting on a simplex interface, loopback a copy */ 321 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 322 mcopy = m_copy(m, 0, (int)M_COPYALL); 323 break; 324 #endif 325 #ifdef IPX 326 case AF_IPX: 327 etype = htons(ETHERTYPE_IPX); 328 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host), 329 (caddr_t)edst, sizeof (edst)); 330 /* If broadcasting on a simplex interface, loopback a copy */ 331 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 332 mcopy = m_copy(m, 0, (int)M_COPYALL); 333 break; 334 #endif 335 #ifdef ISO 336 case AF_ISO: { 337 int snpalen; 338 struct llc *l; 339 struct sockaddr_dl *sdl; 340 341 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 342 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 343 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 344 } else { 345 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 346 (char *)edst, &snpalen); 347 if (error) 348 goto bad; /* Not Resolved */ 349 } 350 /* If broadcasting on a simplex interface, loopback a copy */ 351 if (*edst & 1) 352 m->m_flags |= (M_BCAST|M_MCAST); 353 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && 354 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 355 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 356 if (mcopy) { 357 eh = mtod(mcopy, struct ether_header *); 358 bcopy((caddr_t)edst, 359 (caddr_t)eh->ether_dhost, sizeof (edst)); 360 bcopy(LLADDR(ifp->if_sadl), 361 (caddr_t)eh->ether_shost, sizeof (edst)); 362 } 363 } 364 M_PREPEND(m, 3, M_DONTWAIT); 365 if (m == NULL) 366 return (0); 367 l = mtod(m, struct llc *); 368 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 369 l->llc_control = LLC_UI; 370 #ifdef ARGO_DEBUG 371 if (argo_debug[D_ETHER]) { 372 int i; 373 printf("unoutput: sending pkt to: "); 374 for (i=0; i<6; i++) 375 printf("%x ", edst[i] & 0xff); 376 printf("\n"); 377 } 378 #endif 379 } break; 380 #endif /* ISO */ 381 #ifdef LLC 382 /* case AF_NSAP: */ 383 case AF_CCITT: { 384 struct sockaddr_dl *sdl = 385 (struct sockaddr_dl *) rt -> rt_gateway; 386 387 if (sdl && sdl->sdl_family == AF_LINK 388 && sdl->sdl_alen > 0) { 389 bcopy(LLADDR(sdl), (char *)edst, 390 sizeof(edst)); 391 } else goto bad; /* Not a link interface ? Funny ... */ 392 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) && 393 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 394 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 395 if (mcopy) { 396 eh = mtod(mcopy, struct ether_header *); 397 bcopy((caddr_t)edst, 398 (caddr_t)eh->ether_dhost, sizeof (edst)); 399 bcopy(LLADDR(ifp->if_sadl), 400 (caddr_t)eh->ether_shost, sizeof (edst)); 401 } 402 } 403 #ifdef LLC_DEBUG 404 { 405 int i; 406 struct llc *l = mtod(m, struct llc *); 407 408 printf("ether_output: sending LLC2 pkt to: "); 409 for (i=0; i<6; i++) 410 printf("%x ", edst[i] & 0xff); 411 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 412 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff, 413 l->llc_control & 0xff); 414 415 } 416 #endif /* LLC_DEBUG */ 417 } break; 418 #endif /* LLC */ 419 420 case pseudo_AF_HDRCMPLT: 421 hdrcmplt = 1; 422 eh = (struct ether_header *)dst->sa_data; 423 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc)); 424 /* FALLTHROUGH */ 425 426 case AF_UNSPEC: 427 eh = (struct ether_header *)dst->sa_data; 428 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 429 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */ 430 etype = eh->ether_type; 431 break; 432 433 default: 434 printf("%s: can't handle af%d\n", ifp->if_xname, 435 dst->sa_family); 436 senderr(EAFNOSUPPORT); 437 } 438 439 if (mcopy) 440 (void) looutput(ifp, mcopy, dst, rt); 441 442 /* If no ether type is set, this must be a 802.2 formatted packet. 443 */ 444 if (etype == 0) 445 etype = htons(m->m_pkthdr.len); 446 /* 447 * Add local net header. If no space in first mbuf, 448 * allocate another. 449 */ 450 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 451 if (m == 0) 452 senderr(ENOBUFS); 453 eh = mtod(m, struct ether_header *); 454 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, 455 sizeof(eh->ether_type)); 456 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 457 if (hdrcmplt) 458 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost, 459 sizeof(eh->ether_shost)); 460 else 461 bcopy(LLADDR(ifp->if_sadl), (caddr_t)eh->ether_shost, 462 sizeof(eh->ether_shost)); 463 s = splimp(); 464 /* 465 * Queue message on interface, and start output if interface 466 * not yet active. 467 */ 468 if (IF_QFULL(&ifp->if_snd)) { 469 IF_DROP(&ifp->if_snd); 470 splx(s); 471 senderr(ENOBUFS); 472 } 473 ifp->if_obytes += m->m_pkthdr.len; 474 if (m->m_flags & M_MCAST) 475 ifp->if_omcasts++; 476 IF_ENQUEUE(&ifp->if_snd, m); 477 if ((ifp->if_flags & IFF_OACTIVE) == 0) 478 (*ifp->if_start)(ifp); 479 splx(s); 480 return (error); 481 482 bad: 483 if (m) 484 m_freem(m); 485 return (error); 486 } 487 488 /* 489 * Process a received Ethernet packet; 490 * the packet is in the mbuf chain m with 491 * the ether header. 492 */ 493 static void 494 ether_input(struct ifnet *ifp, struct mbuf *m) 495 { 496 struct ifqueue *inq; 497 u_int16_t etype; 498 int s; 499 struct ether_header *eh; 500 #if defined (ISO) || defined (LLC) || defined(NETATALK) 501 struct llc *l; 502 #endif 503 504 if ((ifp->if_flags & IFF_UP) == 0) { 505 m_freem(m); 506 return; 507 } 508 509 eh = mtod(m, struct ether_header *); 510 511 ifp->if_lastchange = time; 512 ifp->if_ibytes += m->m_pkthdr.len; 513 if (eh->ether_dhost[0] & 1) { 514 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 515 sizeof(etherbroadcastaddr)) == 0) 516 m->m_flags |= M_BCAST; 517 else 518 m->m_flags |= M_MCAST; 519 } 520 if (m->m_flags & (M_BCAST|M_MCAST)) 521 ifp->if_imcasts++; 522 523 etype = ntohs(eh->ether_type); 524 525 /* Strip off the Ethernet header. */ 526 m_adj(m, sizeof(struct ether_header)); 527 528 /* If the CRC is still on the packet, trim it off. */ 529 if (m->m_flags & M_HASFCS) 530 m_adj(m, -ETHER_CRC_LEN); 531 532 switch (etype) { 533 #ifdef INET 534 case ETHERTYPE_IP: 535 #ifdef GATEWAY 536 if (ipflow_fastforward(m)) 537 return; 538 #endif 539 schednetisr(NETISR_IP); 540 inq = &ipintrq; 541 break; 542 543 case ETHERTYPE_ARP: 544 schednetisr(NETISR_ARP); 545 inq = &arpintrq; 546 break; 547 548 case ETHERTYPE_REVARP: 549 revarpinput(m); /* XXX queue? */ 550 return; 551 #endif 552 #ifdef INET6 553 case ETHERTYPE_IPV6: 554 schednetisr(NETISR_IPV6); 555 inq = &ip6intrq; 556 break; 557 #endif 558 #ifdef NS 559 case ETHERTYPE_NS: 560 schednetisr(NETISR_NS); 561 inq = &nsintrq; 562 break; 563 564 #endif 565 #ifdef IPX 566 case ETHERTYPE_IPX: 567 schednetisr(NETISR_IPX); 568 inq = &ipxintrq; 569 break; 570 #endif 571 #ifdef NETATALK 572 case ETHERTYPE_ATALK: 573 schednetisr(NETISR_ATALK); 574 inq = &atintrq1; 575 break; 576 case ETHERTYPE_AARP: 577 /* probably this should be done with a NETISR as well */ 578 aarpinput(ifp, m); /* XXX */ 579 return; 580 #endif /* NETATALK */ 581 default: 582 #if defined (ISO) || defined (LLC) || defined (NETATALK) 583 if (etype > ETHERMTU) 584 goto dropanyway; 585 l = mtod(m, struct llc *); 586 switch (l->llc_dsap) { 587 #ifdef NETATALK 588 case LLC_SNAP_LSAP: 589 switch (l->llc_control) { 590 case LLC_UI: 591 if (l->llc_ssap != LLC_SNAP_LSAP) { 592 goto dropanyway; 593 } 594 595 if (Bcmp(&(l->llc_snap_org_code)[0], 596 at_org_code, sizeof(at_org_code)) == 0 && 597 ntohs(l->llc_snap_ether_type) == 598 ETHERTYPE_ATALK) { 599 inq = &atintrq2; 600 m_adj(m, sizeof(struct llc)); 601 schednetisr(NETISR_ATALK); 602 break; 603 } 604 605 if (Bcmp(&(l->llc_snap_org_code)[0], 606 aarp_org_code, 607 sizeof(aarp_org_code)) == 0 && 608 ntohs(l->llc_snap_ether_type) == 609 ETHERTYPE_AARP) { 610 m_adj( m, sizeof(struct llc)); 611 aarpinput(ifp, m); /* XXX */ 612 return; 613 } 614 615 default: 616 goto dropanyway; 617 } 618 break; 619 #endif /* NETATALK */ 620 #ifdef ISO 621 case LLC_ISO_LSAP: 622 switch (l->llc_control) { 623 case LLC_UI: 624 /* LLC_UI_P forbidden in class 1 service */ 625 if ((l->llc_dsap == LLC_ISO_LSAP) && 626 (l->llc_ssap == LLC_ISO_LSAP)) { 627 /* LSAP for ISO */ 628 if (m->m_pkthdr.len > etype) 629 m_adj(m, etype - m->m_pkthdr.len); 630 m->m_data += 3; /* XXX */ 631 m->m_len -= 3; /* XXX */ 632 m->m_pkthdr.len -= 3; /* XXX */ 633 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 634 if (m == 0) 635 return; 636 *mtod(m, struct ether_header *) = *eh; 637 #ifdef ARGO_DEBUG 638 if (argo_debug[D_ETHER]) 639 printf("clnp packet"); 640 #endif 641 schednetisr(NETISR_ISO); 642 inq = &clnlintrq; 643 break; 644 } 645 goto dropanyway; 646 647 case LLC_XID: 648 case LLC_XID_P: 649 if(m->m_len < 6) 650 goto dropanyway; 651 l->llc_window = 0; 652 l->llc_fid = 9; 653 l->llc_class = 1; 654 l->llc_dsap = l->llc_ssap = 0; 655 /* Fall through to */ 656 case LLC_TEST: 657 case LLC_TEST_P: 658 { 659 struct sockaddr sa; 660 struct ether_header *eh2; 661 int i; 662 u_char c = l->llc_dsap; 663 664 l->llc_dsap = l->llc_ssap; 665 l->llc_ssap = c; 666 if (m->m_flags & (M_BCAST | M_MCAST)) 667 bcopy(LLADDR(ifp->if_sadl), 668 (caddr_t)eh->ether_dhost, 6); 669 sa.sa_family = AF_UNSPEC; 670 sa.sa_len = sizeof(sa); 671 eh2 = (struct ether_header *)sa.sa_data; 672 for (i = 0; i < 6; i++) { 673 eh2->ether_shost[i] = c = 674 eh->ether_dhost[i]; 675 eh2->ether_dhost[i] = 676 eh->ether_dhost[i] = 677 eh->ether_shost[i]; 678 eh->ether_shost[i] = c; 679 } 680 ifp->if_output(ifp, m, &sa, NULL); 681 return; 682 } 683 default: 684 m_freem(m); 685 return; 686 } 687 break; 688 #endif /* ISO */ 689 #ifdef LLC 690 case LLC_X25_LSAP: 691 { 692 if (m->m_pkthdr.len > etype) 693 m_adj(m, etype - m->m_pkthdr.len); 694 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 695 if (m == 0) 696 return; 697 if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 698 eh->ether_dhost, LLC_X25_LSAP, 6, 699 mtod(m, struct sdl_hdr *))) 700 panic("ETHER cons addr failure"); 701 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype; 702 #ifdef LLC_DEBUG 703 printf("llc packet\n"); 704 #endif /* LLC_DEBUG */ 705 schednetisr(NETISR_CCITT); 706 inq = &llcintrq; 707 break; 708 } 709 #endif /* LLC */ 710 dropanyway: 711 default: 712 m_freem(m); 713 return; 714 } 715 #else /* ISO || LLC || NETATALK*/ 716 m_freem(m); 717 return; 718 #endif /* ISO || LLC || NETATALK*/ 719 } 720 721 s = splimp(); 722 if (IF_QFULL(inq)) { 723 IF_DROP(inq); 724 m_freem(m); 725 } else 726 IF_ENQUEUE(inq, m); 727 splx(s); 728 } 729 730 /* 731 * Convert Ethernet address to printable (loggable) representation. 732 */ 733 static char digits[] = "0123456789abcdef"; 734 char * 735 ether_sprintf(const u_char *ap) 736 { 737 static char etherbuf[18]; 738 char *cp = etherbuf; 739 int i; 740 741 for (i = 0; i < 6; i++) { 742 *cp++ = digits[*ap >> 4]; 743 *cp++ = digits[*ap++ & 0xf]; 744 *cp++ = ':'; 745 } 746 *--cp = 0; 747 return (etherbuf); 748 } 749 750 /* 751 * Perform common duties while attaching to interface list 752 */ 753 void 754 ether_ifattach(struct ifnet *ifp, const u_int8_t *lla) 755 { 756 struct sockaddr_dl *sdl; 757 758 ifp->if_type = IFT_ETHER; 759 ifp->if_addrlen = 6; 760 ifp->if_hdrlen = 14; 761 ifp->if_mtu = ETHERMTU; 762 ifp->if_output = ether_output; 763 ifp->if_input = ether_input; 764 if (ifp->if_baudrate == 0) 765 ifp->if_baudrate = IF_Mbps(10); /* just a default */ 766 if ((sdl = ifp->if_sadl) && 767 sdl->sdl_family == AF_LINK) { 768 sdl->sdl_type = IFT_ETHER; 769 sdl->sdl_alen = ifp->if_addrlen; 770 bcopy(lla, LLADDR(sdl), ifp->if_addrlen); 771 } 772 LIST_INIT(&((struct ethercom *)ifp)->ec_multiaddrs); 773 ifp->if_broadcastaddr = etherbroadcastaddr; 774 } 775 776 void 777 ether_ifdetach(struct ifnet *ifp) 778 { 779 780 /* Nothing. */ 781 } 782 783 #if 0 784 /* 785 * This is for reference. We have a table-driven version 786 * of the little-endian crc32 generator, which is faster 787 * than the double-loop. 788 */ 789 u_int32_t 790 ether_crc32_le(const u_int8_t *buf, size_t len) 791 { 792 u_int32_t c, crc, carry; 793 size_t i, j; 794 795 crc = 0xffffffffU; /* initial value */ 796 797 for (i = 0; i < len; i++) { 798 c = buf[i]; 799 for (j = 0; j < 8; j++) { 800 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); 801 crc >>= 1; 802 c >>= 1; 803 if (carry) 804 crc = (crc ^ ETHER_CRC_POLY_LE); 805 } 806 } 807 808 return (crc); 809 } 810 #else 811 u_int32_t 812 ether_crc32_le(const u_int8_t *buf, size_t len) 813 { 814 static const u_int32_t crctab[] = { 815 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 816 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 817 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 818 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 819 }; 820 u_int32_t crc; 821 int i; 822 823 crc = 0xffffffffU; /* initial value */ 824 825 for (i = 0; i < len; i++) { 826 crc ^= buf[i]; 827 crc = (crc >> 4) ^ crctab[crc & 0xf]; 828 crc = (crc >> 4) ^ crctab[crc & 0xf]; 829 } 830 831 return (crc); 832 } 833 #endif 834 835 u_int32_t 836 ether_crc32_be(const u_int8_t *buf, size_t len) 837 { 838 u_int32_t c, crc, carry; 839 size_t i, j; 840 841 crc = 0xffffffffU; /* initial value */ 842 843 for (i = 0; i < len; i++) { 844 c = buf[i]; 845 for (j = 0; j < 8; j++) { 846 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); 847 crc <<= 1; 848 c >>= 1; 849 if (carry) 850 crc = (crc ^ ETHER_CRC_POLY_BE) | carry; 851 } 852 } 853 854 return (crc); 855 } 856 857 #ifdef INET 858 u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 859 u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 860 #endif 861 #ifdef INET6 862 u_char ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 863 u_char ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 864 #endif 865 /* 866 * Add an Ethernet multicast address or range of addresses to the list for a 867 * given interface. 868 */ 869 int 870 ether_addmulti(struct ifreq *ifr, struct ethercom *ec) 871 { 872 struct ether_multi *enm; 873 #ifdef INET 874 struct sockaddr_in *sin; 875 #endif /* INET */ 876 #ifdef INET6 877 struct sockaddr_in6 *sin6; 878 #endif /* INET6 */ 879 u_char addrlo[6]; 880 u_char addrhi[6]; 881 int s = splimp(); 882 883 switch (ifr->ifr_addr.sa_family) { 884 885 case AF_UNSPEC: 886 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 887 bcopy(addrlo, addrhi, 6); 888 break; 889 890 #ifdef INET 891 case AF_INET: 892 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 893 if (sin->sin_addr.s_addr == INADDR_ANY) { 894 /* 895 * An IP address of INADDR_ANY means listen to all 896 * of the Ethernet multicast addresses used for IP. 897 * (This is for the sake of IP multicast routers.) 898 */ 899 bcopy(ether_ipmulticast_min, addrlo, 6); 900 bcopy(ether_ipmulticast_max, addrhi, 6); 901 } 902 else { 903 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 904 bcopy(addrlo, addrhi, 6); 905 } 906 break; 907 #endif 908 #ifdef INET6 909 case AF_INET6: 910 sin6 = (struct sockaddr_in6 *) 911 &(((struct in6_ifreq *)ifr)->ifr_addr); 912 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 913 /* 914 * An IP6 address of 0 means listen to all 915 * of the Ethernet multicast address used for IP6. 916 * (This is used for multicast routers.) 917 */ 918 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 919 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 920 #if 0 921 set_allmulti = 1; 922 #endif 923 } else { 924 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 925 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 926 } 927 break; 928 #endif 929 930 default: 931 splx(s); 932 return (EAFNOSUPPORT); 933 } 934 935 /* 936 * Verify that we have valid Ethernet multicast addresses. 937 */ 938 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 939 splx(s); 940 return (EINVAL); 941 } 942 /* 943 * See if the address range is already in the list. 944 */ 945 ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm); 946 if (enm != NULL) { 947 /* 948 * Found it; just increment the reference count. 949 */ 950 ++enm->enm_refcount; 951 splx(s); 952 return (0); 953 } 954 /* 955 * New address or range; malloc a new multicast record 956 * and link it into the interface's multicast list. 957 */ 958 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 959 if (enm == NULL) { 960 splx(s); 961 return (ENOBUFS); 962 } 963 bcopy(addrlo, enm->enm_addrlo, 6); 964 bcopy(addrhi, enm->enm_addrhi, 6); 965 enm->enm_ec = ec; 966 enm->enm_refcount = 1; 967 LIST_INSERT_HEAD(&ec->ec_multiaddrs, enm, enm_list); 968 ec->ec_multicnt++; 969 splx(s); 970 /* 971 * Return ENETRESET to inform the driver that the list has changed 972 * and its reception filter should be adjusted accordingly. 973 */ 974 return (ENETRESET); 975 } 976 977 /* 978 * Delete a multicast address record. 979 */ 980 int 981 ether_delmulti(struct ifreq *ifr, struct ethercom *ec) 982 { 983 struct ether_multi *enm; 984 #ifdef INET 985 struct sockaddr_in *sin; 986 #endif /* INET */ 987 #ifdef INET6 988 struct sockaddr_in6 *sin6; 989 #endif /* INET6 */ 990 u_char addrlo[6]; 991 u_char addrhi[6]; 992 int s = splimp(); 993 994 switch (ifr->ifr_addr.sa_family) { 995 996 case AF_UNSPEC: 997 bcopy(ifr->ifr_addr.sa_data, addrlo, 6); 998 bcopy(addrlo, addrhi, 6); 999 break; 1000 1001 #ifdef INET 1002 case AF_INET: 1003 sin = (struct sockaddr_in *)&(ifr->ifr_addr); 1004 if (sin->sin_addr.s_addr == INADDR_ANY) { 1005 /* 1006 * An IP address of INADDR_ANY means stop listening 1007 * to the range of Ethernet multicast addresses used 1008 * for IP. 1009 */ 1010 bcopy(ether_ipmulticast_min, addrlo, 6); 1011 bcopy(ether_ipmulticast_max, addrhi, 6); 1012 } 1013 else { 1014 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 1015 bcopy(addrlo, addrhi, 6); 1016 } 1017 break; 1018 #endif 1019 #ifdef INET6 1020 case AF_INET6: 1021 sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr); 1022 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1023 /* 1024 * An IP6 address of all 0 means stop listening 1025 * to the range of Ethernet multicast addresses used 1026 * for IP6 1027 */ 1028 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 1029 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 1030 } else { 1031 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 1032 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1033 } 1034 break; 1035 #endif 1036 1037 default: 1038 splx(s); 1039 return (EAFNOSUPPORT); 1040 } 1041 1042 /* 1043 * Look up the address in our list. 1044 */ 1045 ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm); 1046 if (enm == NULL) { 1047 splx(s); 1048 return (ENXIO); 1049 } 1050 if (--enm->enm_refcount != 0) { 1051 /* 1052 * Still some claims to this record. 1053 */ 1054 splx(s); 1055 return (0); 1056 } 1057 /* 1058 * No remaining claims to this record; unlink and free it. 1059 */ 1060 LIST_REMOVE(enm, enm_list); 1061 free(enm, M_IFMADDR); 1062 ec->ec_multicnt--; 1063 splx(s); 1064 /* 1065 * Return ENETRESET to inform the driver that the list has changed 1066 * and its reception filter should be adjusted accordingly. 1067 */ 1068 return (ENETRESET); 1069 } 1070