1 /* $OpenBSD: if_ethersubr.c,v 1.66 2002/09/11 05:38:47 itojun Exp $ */ 2 /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1982, 1989, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by the University of 48 * California, Berkeley and its contributors. 49 * 4. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 66 */ 67 68 /* 69 %%% portions-copyright-nrl-95 70 Portions of this software are Copyright 1995-1998 by Randall Atkinson, 71 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights 72 Reserved. All rights under this copyright have been assigned to the US 73 Naval Research Laboratory (NRL). The NRL Copyright Notice and License 74 Agreement Version 1.1 (January 17, 1995) applies to these portions of the 75 software. 76 You should have received a copy of the license with this software. If you 77 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. 78 */ 79 80 #include "bpfilter.h" 81 82 #include <sys/param.h> 83 #include <sys/systm.h> 84 #include <sys/kernel.h> 85 #include <sys/malloc.h> 86 #include <sys/mbuf.h> 87 #include <sys/protosw.h> 88 #include <sys/socket.h> 89 #include <sys/ioctl.h> 90 #include <sys/errno.h> 91 #include <sys/syslog.h> 92 #include <sys/timeout.h> 93 94 #include <machine/cpu.h> 95 96 #include <net/if.h> 97 #include <net/netisr.h> 98 #include <net/route.h> 99 #include <net/if_llc.h> 100 #include <net/if_dl.h> 101 #include <net/if_types.h> 102 103 #include <netinet/in.h> 104 #ifdef INET 105 #include <netinet/in_var.h> 106 #endif 107 #include <netinet/if_ether.h> 108 #include <netinet/ip_ipsp.h> 109 110 #if NBPFILTER > 0 111 #include <net/bpf.h> 112 #endif 113 114 #include "bridge.h" 115 #if NBRIDGE > 0 116 #include <net/if_bridge.h> 117 #endif 118 119 #include "vlan.h" 120 #if NVLAN > 0 121 #include <net/if_vlan_var.h> 122 #endif /* NVLAN > 0 */ 123 124 #ifdef INET6 125 #ifndef INET 126 #include <netinet/in.h> 127 #endif 128 #include <netinet6/in6_var.h> 129 #include <netinet6/nd6.h> 130 #endif 131 132 #ifdef NS 133 #include <netns/ns.h> 134 #include <netns/ns_if.h> 135 #endif 136 137 #ifdef IPX 138 #include <netipx/ipx.h> 139 #include <netipx/ipx_if.h> 140 #endif 141 142 #ifdef ISO 143 #include <netiso/argo_debug.h> 144 #include <netiso/iso.h> 145 #include <netiso/iso_var.h> 146 #include <netiso/iso_snpac.h> 147 #endif 148 149 #include <netccitt/x25.h> 150 #include <netccitt/pk.h> 151 #include <netccitt/pk_extern.h> 152 #include <netccitt/dll.h> 153 #include <netccitt/llc_var.h> 154 155 #ifdef NETATALK 156 #include <netatalk/at.h> 157 #include <netatalk/at_var.h> 158 #include <netatalk/at_extern.h> 159 160 extern u_char at_org_code[ 3 ]; 161 extern u_char aarp_org_code[ 3 ]; 162 #endif /* NETATALK */ 163 164 #if defined(CCITT) 165 #include <sys/socketvar.h> 166 #endif 167 168 u_char etherbroadcastaddr[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 169 #define senderr(e) { error = (e); goto bad;} 170 171 172 int 173 ether_ioctl(ifp, arp, cmd, data) 174 register struct ifnet *ifp; 175 struct arpcom *arp; 176 u_long cmd; 177 caddr_t data; 178 { 179 struct ifaddr *ifa = (struct ifaddr *)data; 180 int error = 0; 181 182 switch (cmd) { 183 184 #if defined(CCITT) 185 case SIOCSIFCONF_X25: 186 ifp->if_flags |= IFF_UP; 187 ifa->ifa_rtrequest = cons_rtrequest; 188 error = x25_llcglue(PRC_IFUP, ifa->ifa_addr); 189 break; 190 #endif /* CCITT */ 191 case SIOCSIFADDR: 192 switch (ifa->ifa_addr->sa_family) { 193 #ifdef IPX 194 case AF_IPX: 195 { 196 struct ipx_addr *ina = &IA_SIPX(ifa)->sipx_addr; 197 198 if (ipx_nullhost(*ina)) 199 ina->ipx_host = 200 *(union ipx_host *)(arp->ac_enaddr); 201 else 202 bcopy(ina->ipx_host.c_host, 203 arp->ac_enaddr, sizeof(arp->ac_enaddr)); 204 break; 205 } 206 #endif /* IPX */ 207 #ifdef NETATALK 208 case AF_APPLETALK: 209 /* Nothing to do. */ 210 break; 211 #endif /* NETATALK */ 212 #ifdef NS 213 /* XXX - This code is probably wrong. */ 214 case AF_NS: 215 { 216 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 217 218 if (ns_nullhost(*ina)) 219 ina->x_host = 220 *(union ns_host *)(arp->ac_enaddr); 221 else 222 bcopy(ina->x_host.c_host, 223 arp->ac_enaddr, sizeof(arp->ac_enaddr)); 224 break; 225 } 226 #endif /* NS */ 227 } 228 break; 229 default: 230 break; 231 } 232 233 return error; 234 } 235 236 /* 237 * Ethernet output routine. 238 * Encapsulate a packet of type family for the local net. 239 * Assumes that ifp is actually pointer to arpcom structure. 240 */ 241 int 242 ether_output(ifp, m0, dst, rt0) 243 register struct ifnet *ifp; 244 struct mbuf *m0; 245 struct sockaddr *dst; 246 struct rtentry *rt0; 247 { 248 u_int16_t etype; 249 int s, len, error = 0, hdrcmplt = 0; 250 u_char edst[ETHER_ADDR_LEN], esrc[ETHER_ADDR_LEN]; 251 register struct mbuf *m = m0; 252 register struct rtentry *rt; 253 struct mbuf *mcopy = (struct mbuf *)0; 254 register struct ether_header *eh; 255 struct arpcom *ac = (struct arpcom *)ifp; 256 short mflags; 257 ALTQ_DECL(struct altq_pktattr pktattr;) 258 259 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 260 senderr(ENETDOWN); 261 if ((rt = rt0) != NULL) { 262 if ((rt->rt_flags & RTF_UP) == 0) { 263 if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) 264 rt->rt_refcnt--; 265 else 266 senderr(EHOSTUNREACH); 267 } 268 if (rt->rt_flags & RTF_GATEWAY) { 269 if (rt->rt_gwroute == 0) 270 goto lookup; 271 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 272 rtfree(rt); rt = rt0; 273 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1); 274 if ((rt = rt->rt_gwroute) == 0) 275 senderr(EHOSTUNREACH); 276 } 277 } 278 if (rt->rt_flags & RTF_REJECT) 279 if (rt->rt_rmx.rmx_expire == 0 || 280 time.tv_sec < rt->rt_rmx.rmx_expire) 281 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 282 } 283 284 /* 285 * if the queueing discipline needs packet classification, 286 * do it before prepending link headers. 287 */ 288 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr); 289 290 switch (dst->sa_family) { 291 292 #ifdef INET 293 case AF_INET: 294 if (!arpresolve(ac, rt, m, dst, edst)) 295 return (0); /* if not yet resolved */ 296 /* If broadcasting on a simplex interface, loopback a copy */ 297 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 298 mcopy = m_copy(m, 0, (int)M_COPYALL); 299 etype = htons(ETHERTYPE_IP); 300 break; 301 #endif 302 #ifdef INET6 303 case AF_INET6: 304 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)) 305 return (0); /* it must be impossible, but... */ 306 etype = htons(ETHERTYPE_IPV6); 307 break; 308 #endif 309 #ifdef NS 310 case AF_NS: 311 etype = htons(ETHERTYPE_NS); 312 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 313 (caddr_t)edst, sizeof (edst)); 314 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))) 315 return (looutput(ifp, m, dst, rt)); 316 /* If broadcasting on a simplex interface, loopback a copy */ 317 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 318 mcopy = m_copy(m, 0, (int)M_COPYALL); 319 break; 320 #endif 321 #ifdef IPX 322 case AF_IPX: 323 etype = htons(ETHERTYPE_IPX); 324 bcopy((caddr_t)&satosipx(dst)->sipx_addr.ipx_host, 325 (caddr_t)edst, sizeof (edst)); 326 /* If broadcasting on a simplex interface, loopback a copy */ 327 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) 328 mcopy = m_copy(m, 0, (int)M_COPYALL); 329 break; 330 #endif 331 #if 0 /*NRL INET6*/ 332 case AF_INET6: 333 /* 334 * The bottom line here is to either queue the outgoing packet 335 * in the discovery engine, or fill in edst with something 336 * that'll work. 337 */ 338 if (m->m_flags & M_MCAST) { 339 /* 340 * If multicast dest., then use IPv6 -> Ethernet 341 * mcast mapping. Really simple. 342 */ 343 ETHER_MAP_IPV6_MULTICAST(&((struct sockaddr_in6 *)dst)->sin6_addr, 344 edst); 345 } else { 346 /* Do unicast neighbor discovery stuff. */ 347 if (!ipv6_discov_resolve(ifp, rt, m, dst, edst)) 348 return 0; 349 } 350 etype = htons(ETHERTYPE_IPV6); 351 break; 352 #endif /* INET6 */ 353 #ifdef NETATALK 354 case AF_APPLETALK: { 355 struct at_ifaddr *aa; 356 357 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) { 358 #ifdef NETATALKDEBUG 359 extern char *prsockaddr(struct sockaddr *); 360 printf("aarpresolv: failed for %s\n", prsockaddr(dst)); 361 #endif /* NETATALKDEBUG */ 362 return (0); 363 } 364 365 /* 366 * ifaddr is the first thing in at_ifaddr 367 */ 368 aa = (struct at_ifaddr *)at_ifawithnet( 369 (struct sockaddr_at *)dst, 370 TAILQ_FIRST(&ifp->if_addrlist)); 371 if (aa == 0) 372 goto bad; 373 374 /* 375 * In the phase 2 case, we need to prepend an mbuf for the llc 376 * header. Since we must preserve the value of m, which is 377 * passed to us by value, we m_copy() the first mbuf, 378 * and use it for our llc header. 379 */ 380 if (aa->aa_flags & AFA_PHASE2) { 381 struct llc llc; 382 383 M_PREPEND(m, AT_LLC_SIZE, M_DONTWAIT); 384 if (m == NULL) 385 return (0); 386 /* 387 * FreeBSD doesn't count the LLC len in 388 * ifp->obytes, so they increment a length 389 * field here. We don't do this. 390 */ 391 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 392 llc.llc_control = LLC_UI; 393 bcopy(at_org_code, llc.llc_snap.org_code, 394 sizeof(at_org_code)); 395 llc.llc_snap.ether_type = htons( ETHERTYPE_AT ); 396 bcopy(&llc, mtod(m, caddr_t), AT_LLC_SIZE); 397 etype = htons(m->m_pkthdr.len); 398 } else { 399 etype = htons(ETHERTYPE_AT); 400 } 401 } break; 402 #endif /* NETATALK */ 403 #ifdef ISO 404 case AF_ISO: { 405 int snpalen; 406 struct llc *l; 407 register struct sockaddr_dl *sdl; 408 409 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 410 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 411 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 412 } else { 413 error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 414 (char *)edst, &snpalen); 415 if (error) 416 goto bad; /* Not Resolved */ 417 } 418 /* If broadcasting on a simplex interface, loopback a copy */ 419 if (*edst & 1) 420 m->m_flags |= (M_BCAST|M_MCAST); 421 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && 422 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 423 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 424 if (mcopy) { 425 eh = mtod(mcopy, struct ether_header *); 426 bcopy(edst, eh->ether_dhost, sizeof (edst)); 427 bcopy(ac->ac_enaddr, eh->ether_shost, 428 sizeof (edst)); 429 } 430 } 431 M_PREPEND(m, 3, M_DONTWAIT); 432 if (m == NULL) 433 return (0); 434 etype = htons(m->m_pkthdr.len); 435 l = mtod(m, struct llc *); 436 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 437 l->llc_control = LLC_UI; 438 #ifdef ARGO_DEBUG 439 if (argo_debug[D_ETHER]) { 440 int i; 441 printf("unoutput: sending pkt to: "); 442 for (i=0; i < ETHER_ADDR_LEN; i++) 443 printf("%x ", edst[i] & 0xff); 444 printf("\n"); 445 } 446 #endif 447 } break; 448 #endif /* ISO */ 449 /* case AF_NSAP: */ 450 case AF_CCITT: { 451 register struct sockaddr_dl *sdl = 452 (struct sockaddr_dl *) rt -> rt_gateway; 453 454 if (sdl && sdl->sdl_family == AF_LINK 455 && sdl->sdl_alen > 0) { 456 bcopy(LLADDR(sdl), (char *)edst, 457 sizeof(edst)); 458 } else goto bad; /* Not a link interface ? Funny ... */ 459 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) && 460 (mcopy = m_copy(m, 0, (int)M_COPYALL))) { 461 M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT); 462 if (mcopy) { 463 eh = mtod(mcopy, struct ether_header *); 464 bcopy(edst, eh->ether_dhost, sizeof (edst)); 465 bcopy(ac->ac_enaddr, eh->ether_shost, 466 sizeof (edst)); 467 } 468 } 469 etype = htons(m->m_pkthdr.len); 470 #ifdef LLC_DEBUG 471 { 472 int i; 473 register struct llc *l = mtod(m, struct llc *); 474 475 printf("ether_output: sending LLC2 pkt to: "); 476 for (i=0; i < ETHER_ADDR_LEN; i++) 477 printf("%x ", edst[i] & 0xff); 478 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 479 m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff, 480 l->llc_control & 0xff); 481 482 } 483 #endif /* LLC_DEBUG */ 484 } break; 485 486 case pseudo_AF_HDRCMPLT: 487 hdrcmplt = 1; 488 eh = (struct ether_header *)dst->sa_data; 489 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc)); 490 /* FALLTHROUGH */ 491 492 case AF_UNSPEC: 493 eh = (struct ether_header *)dst->sa_data; 494 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst)); 495 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */ 496 etype = eh->ether_type; 497 break; 498 499 default: 500 printf("%s: can't handle af%d\n", ifp->if_xname, 501 dst->sa_family); 502 senderr(EAFNOSUPPORT); 503 } 504 505 /* XXX Should we feed-back an unencrypted IPsec packet ? */ 506 if (mcopy) 507 (void) looutput(ifp, mcopy, dst, rt); 508 509 /* 510 * Add local net header. If no space in first mbuf, 511 * allocate another. 512 */ 513 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 514 if (m == 0) 515 senderr(ENOBUFS); 516 eh = mtod(m, struct ether_header *); 517 bcopy((caddr_t)&etype,(caddr_t)&eh->ether_type, 518 sizeof(eh->ether_type)); 519 bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst)); 520 if (hdrcmplt) 521 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost, 522 sizeof(eh->ether_shost)); 523 else 524 bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, 525 sizeof(eh->ether_shost)); 526 527 #if NBRIDGE > 0 528 /* 529 * Interfaces that are bridge members need special handling 530 * for output. 531 */ 532 if (ifp->if_bridge) { 533 struct m_tag *mtag; 534 535 /* 536 * Check if this packet has already been sent out through 537 * this bridge, in which case we simply send it out 538 * without further bridge processing. 539 */ 540 for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag; 541 mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) { 542 #ifdef DEBUG 543 /* Check that the information is there */ 544 if (mtag->m_tag_len != sizeof(caddr_t)) { 545 error = EINVAL; 546 goto bad; 547 } 548 #endif 549 if (!bcmp(&ifp->if_bridge, mtag + 1, sizeof(caddr_t))) 550 break; 551 } 552 if (mtag == NULL) { 553 /* Attach a tag so we can detect loops */ 554 mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t), 555 M_NOWAIT); 556 if (mtag == NULL) { 557 error = ENOBUFS; 558 goto bad; 559 } 560 bcopy(&ifp->if_bridge, mtag + 1, sizeof(caddr_t)); 561 m_tag_prepend(m, mtag); 562 bridge_output(ifp, m, NULL, NULL); 563 return (error); 564 } 565 } 566 #endif 567 568 mflags = m->m_flags; 569 len = m->m_pkthdr.len; 570 s = splimp(); 571 /* 572 * Queue message on interface, and start output if interface 573 * not yet active. 574 */ 575 IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); 576 if (error) { 577 /* mbuf is already freed */ 578 splx(s); 579 return (error); 580 } 581 ifp->if_obytes += len + sizeof (struct ether_header); 582 if (mflags & M_MCAST) 583 ifp->if_omcasts++; 584 if ((ifp->if_flags & IFF_OACTIVE) == 0) 585 (*ifp->if_start)(ifp); 586 splx(s); 587 return (error); 588 589 bad: 590 if (m) 591 m_freem(m); 592 return (error); 593 } 594 595 #ifdef ALTQ 596 /* 597 * This routine is a slight hack to allow a packet to be classified 598 * if the Ethernet headers are present. It will go away when ALTQ's 599 * classification engine understands link headers. 600 */ 601 void 602 altq_etherclassify(struct ifaltq *ifq, struct mbuf *m, 603 struct altq_pktattr *pktattr) 604 { 605 struct ether_header *eh; 606 u_int16_t ether_type; 607 int hlen, af, hdrsize; 608 caddr_t hdr; 609 610 hlen = ETHER_HDR_LEN; 611 eh = mtod(m, struct ether_header *); 612 613 ether_type = htons(eh->ether_type); 614 615 if (ether_type < ETHERMTU) { 616 /* LLC/SNAP */ 617 struct llc *llc = (struct llc *)(eh + 1); 618 hlen += 8; 619 620 if (m->m_len < hlen || 621 llc->llc_dsap != LLC_SNAP_LSAP || 622 llc->llc_ssap != LLC_SNAP_LSAP || 623 llc->llc_control != LLC_UI) { 624 /* Not SNAP. */ 625 goto bad; 626 } 627 628 ether_type = htons(llc->llc_un.type_snap.ether_type); 629 } 630 631 switch (ether_type) { 632 case ETHERTYPE_IP: 633 af = AF_INET; 634 hdrsize = 20; /* sizeof(struct ip) */ 635 break; 636 637 case ETHERTYPE_IPV6: 638 af = AF_INET6; 639 hdrsize = 40; /* sizeof(struct ip6_hdr) */ 640 break; 641 642 default: 643 af = AF_UNSPEC; 644 hdrsize = 0; 645 break; 646 } 647 648 while (m->m_len <= hlen) { 649 hlen -= m->m_len; 650 m = m->m_next; 651 } 652 if (m->m_len < (hlen + hdrsize)) { 653 /* 654 * protocol header not in a single mbuf. 655 * We can't cope with this situation right now 656 * (but it shouldn't ever happen, really, anyhow). 657 */ 658 #ifdef DEBUG 659 printf("altq_etherclassify: headers span multiple mbufs: " 660 "%d < %d\n", m->m_len, (hlen + hdrsize)); 661 #endif 662 goto bad; 663 } 664 665 m->m_data += hlen; 666 m->m_len -= hlen; 667 668 hdr = mtod(m, caddr_t); 669 670 if (ALTQ_NEEDS_CLASSIFY(ifq)) 671 pktattr->pattr_class = 672 (*ifq->altq_classify)(ifq->altq_clfier, m, af); 673 pktattr->pattr_af = af; 674 pktattr->pattr_hdr = hdr; 675 676 m->m_data -= hlen; 677 m->m_len += hlen; 678 679 return; 680 681 bad: 682 pktattr->pattr_class = NULL; 683 pktattr->pattr_hdr = NULL; 684 pktattr->pattr_af = AF_UNSPEC; 685 } 686 #endif /* ALTQ */ 687 688 /* 689 * Temporary function to migrate while 690 * removing ether_header * from ether_input(). 691 */ 692 void 693 ether_input_mbuf(ifp, m) 694 struct ifnet *ifp; 695 struct mbuf *m; 696 { 697 struct ether_header *eh; 698 699 eh = mtod(m, struct ether_header *); 700 m_adj(m, ETHER_HDR_LEN); 701 ether_input(ifp, eh, m); 702 } 703 704 /* 705 * Process a received Ethernet packet; 706 * the packet is in the mbuf chain m without 707 * the ether header, which is provided separately. 708 */ 709 void 710 ether_input(ifp, eh, m) 711 struct ifnet *ifp; 712 register struct ether_header *eh; 713 struct mbuf *m; 714 { 715 register struct ifqueue *inq; 716 u_int16_t etype; 717 int s, llcfound = 0; 718 register struct llc *l; 719 struct arpcom *ac; 720 721 if ((ifp->if_flags & IFF_UP) == 0) { 722 m_freem(m); 723 return; 724 } 725 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 726 if ((ifp->if_flags & IFF_SIMPLEX) == 0) { 727 struct ifaddr *ifa; 728 struct sockaddr_dl *sdl = NULL; 729 730 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 731 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && 732 sdl->sdl_family == AF_LINK) 733 break; 734 } 735 /* 736 * If this is not a simplex interface, drop the packet 737 * if it came from us. 738 */ 739 if (sdl && bcmp(LLADDR(sdl), eh->ether_shost, 740 ETHER_ADDR_LEN) == 0) { 741 m_freem(m); 742 return; 743 } 744 } 745 746 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 747 sizeof(etherbroadcastaddr)) == 0) 748 m->m_flags |= M_BCAST; 749 else 750 m->m_flags |= M_MCAST; 751 ifp->if_imcasts++; 752 } 753 754 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh); 755 756 etype = ntohs(eh->ether_type); 757 758 #if NBRIDGE > 0 759 /* 760 * Tap the packet off here for a bridge, if configured and 761 * active for this interface. bridge_input returns 762 * NULL if it has consumed the packet, otherwise, it 763 * gets processed as normal. 764 */ 765 if (ifp->if_bridge) { 766 if (m->m_flags & M_PROTO1) 767 m->m_flags &= ~M_PROTO1; 768 else { 769 m = bridge_input(ifp, eh, m); 770 if (m == NULL) 771 return; 772 /* The bridge has determined it's for us. */ 773 ifp = m->m_pkthdr.rcvif; 774 } 775 } 776 #endif 777 778 #if NVLAN > 0 779 if (etype == ETHERTYPE_8021Q) { 780 if (vlan_input(eh, m) < 0) 781 ifp->if_noproto++; 782 return; 783 } 784 #endif /* NVLAN > 0 */ 785 786 ac = (struct arpcom *)ifp; 787 788 /* 789 * If packet is unicast and we're in promiscuous mode, make sure it 790 * is for us. Drop otherwise. 791 */ 792 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 && 793 (ifp->if_flags & IFF_PROMISC)) { 794 if (bcmp(ac->ac_enaddr, (caddr_t)eh->ether_dhost, 795 ETHER_ADDR_LEN)) { 796 m_freem(m); 797 return; 798 } 799 } 800 801 decapsulate: 802 803 switch (etype) { 804 #ifdef INET 805 case ETHERTYPE_IP: 806 schednetisr(NETISR_IP); 807 inq = &ipintrq; 808 break; 809 810 case ETHERTYPE_ARP: 811 if (ifp->if_flags & IFF_NOARP) 812 goto dropanyway; 813 schednetisr(NETISR_ARP); 814 inq = &arpintrq; 815 break; 816 817 case ETHERTYPE_REVARP: 818 if (ifp->if_flags & IFF_NOARP) 819 goto dropanyway; 820 revarpinput(m); /* XXX queue? */ 821 return; 822 823 #endif 824 #ifdef INET6 825 /* 826 * Schedule IPv6 software interrupt for incoming IPv6 packet. 827 */ 828 case ETHERTYPE_IPV6: 829 schednetisr(NETISR_IPV6); 830 inq = &ip6intrq; 831 break; 832 #endif /* INET6 */ 833 #ifdef IPX 834 case ETHERTYPE_IPX: 835 schednetisr(NETISR_IPX); 836 inq = &ipxintrq; 837 break; 838 #endif 839 #ifdef NS 840 case ETHERTYPE_NS: 841 schednetisr(NETISR_NS); 842 inq = &nsintrq; 843 break; 844 #endif 845 #ifdef NETATALK 846 case ETHERTYPE_AT: 847 schednetisr(NETISR_ATALK); 848 inq = &atintrq1; 849 break; 850 case ETHERTYPE_AARP: 851 /* probably this should be done with a NETISR as well */ 852 /* XXX queue this */ 853 aarpinput((struct arpcom *)ifp, m); 854 return; 855 #endif 856 default: 857 if (llcfound || etype > ETHERMTU) 858 goto dropanyway; 859 llcfound = 1; 860 l = mtod(m, struct llc *); 861 switch (l->llc_dsap) { 862 case LLC_SNAP_LSAP: 863 #ifdef NETATALK 864 /* 865 * Some protocols (like Appletalk) need special 866 * handling depending on if they are type II 867 * or SNAP encapsulated. Everything else 868 * gets handled by stripping off the SNAP header 869 * and going back up to decapsulate. 870 */ 871 if (l->llc_control == LLC_UI && 872 l->llc_ssap == LLC_SNAP_LSAP && 873 Bcmp(&(l->llc_snap.org_code)[0], 874 at_org_code, sizeof(at_org_code)) == 0 && 875 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AT) { 876 inq = &atintrq2; 877 m_adj(m, AT_LLC_SIZE); 878 schednetisr(NETISR_ATALK); 879 break; 880 } 881 882 if (l->llc_control == LLC_UI && 883 l->llc_ssap == LLC_SNAP_LSAP && 884 Bcmp(&(l->llc_snap.org_code)[0], 885 aarp_org_code, sizeof(aarp_org_code)) == 0 && 886 ntohs(l->llc_snap.ether_type) == ETHERTYPE_AARP) { 887 m_adj(m, AT_LLC_SIZE); 888 /* XXX Really this should use netisr too */ 889 aarpinput((struct arpcom *)ifp, m); 890 return; 891 } 892 #endif /* NETATALK */ 893 if (l->llc_control == LLC_UI && 894 l->llc_dsap == LLC_SNAP_LSAP && 895 l->llc_ssap == LLC_SNAP_LSAP) { 896 /* SNAP */ 897 if (m->m_pkthdr.len > etype) 898 m_adj(m, etype - m->m_pkthdr.len); 899 m->m_data += 6; /* XXX */ 900 m->m_len -= 6; /* XXX */ 901 m->m_pkthdr.len -= 6; /* XXX */ 902 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 903 if (m == 0) 904 return; 905 *mtod(m, struct ether_header *) = *eh; 906 goto decapsulate; 907 } 908 goto dropanyway; 909 #ifdef ISO 910 case LLC_ISO_LSAP: 911 switch (l->llc_control) { 912 case LLC_UI: 913 /* LLC_UI_P forbidden in class 1 service */ 914 if ((l->llc_dsap == LLC_ISO_LSAP) && 915 (l->llc_ssap == LLC_ISO_LSAP)) { 916 /* LSAP for ISO */ 917 if (m->m_pkthdr.len > etype) 918 m_adj(m, etype - m->m_pkthdr.len); 919 m->m_data += 3; /* XXX */ 920 m->m_len -= 3; /* XXX */ 921 m->m_pkthdr.len -= 3; /* XXX */ 922 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 923 if (m == 0) 924 return; 925 *mtod(m, struct ether_header *) = *eh; 926 #ifdef ARGO_DEBUG 927 if (argo_debug[D_ETHER]) 928 printf("clnp packet"); 929 #endif 930 schednetisr(NETISR_ISO); 931 inq = &clnlintrq; 932 break; 933 } 934 goto dropanyway; 935 936 case LLC_XID: 937 case LLC_XID_P: 938 if(m->m_len < ETHER_ADDR_LEN) 939 goto dropanyway; 940 l->llc_window = 0; 941 l->llc_fid = 9; 942 l->llc_class = 1; 943 l->llc_dsap = l->llc_ssap = 0; 944 /* Fall through to */ 945 case LLC_TEST: 946 case LLC_TEST_P: 947 { 948 struct sockaddr sa; 949 register struct ether_header *eh2; 950 int i; 951 u_char c = l->llc_dsap; 952 953 l->llc_dsap = l->llc_ssap; 954 l->llc_ssap = c; 955 if (m->m_flags & (M_BCAST | M_MCAST)) 956 bcopy(ac->ac_enaddr, 957 eh->ether_dhost, ETHER_ADDR_LEN); 958 sa.sa_family = AF_UNSPEC; 959 sa.sa_len = sizeof(sa); 960 eh2 = (struct ether_header *)sa.sa_data; 961 for (i = 0; i < ETHER_ADDR_LEN; i++) { 962 eh2->ether_shost[i] = c = eh->ether_dhost[i]; 963 eh2->ether_dhost[i] = 964 eh->ether_dhost[i] = eh->ether_shost[i]; 965 eh->ether_shost[i] = c; 966 } 967 ifp->if_output(ifp, m, &sa, NULL); 968 return; 969 } 970 break; 971 } 972 #endif /* ISO */ 973 #ifdef CCITT 974 case LLC_X25_LSAP: 975 if (m->m_pkthdr.len > etype) 976 m_adj(m, etype - m->m_pkthdr.len); 977 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 978 if (m == 0) 979 return; 980 if (!sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 981 eh->ether_dhost, LLC_X25_LSAP, ETHER_ADDR_LEN, 982 mtod(m, struct sdl_hdr *))) 983 panic("ETHER cons addr failure"); 984 mtod(m, struct sdl_hdr *)->sdlhdr_len = etype; 985 #ifdef LLC_DEBUG 986 printf("llc packet\n"); 987 #endif /* LLC_DEBUG */ 988 schednetisr(NETISR_CCITT); 989 inq = &llcintrq; 990 break; 991 #endif /* CCITT */ 992 dropanyway: 993 default: 994 m_freem(m); 995 return; 996 } 997 } 998 999 s = splimp(); 1000 if (IF_QFULL(inq)) { 1001 IF_DROP(inq); 1002 m_freem(m); 1003 } else 1004 IF_ENQUEUE(inq, m); 1005 splx(s); 1006 } 1007 1008 /* 1009 * Convert Ethernet address to printable (loggable) representation. 1010 */ 1011 static char digits[] = "0123456789abcdef"; 1012 char * 1013 ether_sprintf(ap) 1014 register u_char *ap; 1015 { 1016 register int i; 1017 static char etherbuf[18]; 1018 register char *cp = etherbuf; 1019 1020 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1021 *cp++ = digits[*ap >> 4]; 1022 *cp++ = digits[*ap++ & 0xf]; 1023 *cp++ = ':'; 1024 } 1025 *--cp = 0; 1026 return (etherbuf); 1027 } 1028 1029 /* 1030 * Perform common duties while attaching to interface list 1031 */ 1032 void 1033 ether_ifattach(ifp) 1034 register struct ifnet *ifp; 1035 { 1036 1037 /* 1038 * Any interface which provides a MAC address which is obviously 1039 * invalid gets whacked, so that users will notice. 1040 */ 1041 if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr)) { 1042 ((struct arpcom *)ifp)->ac_enaddr[0] = 0x00; 1043 ((struct arpcom *)ifp)->ac_enaddr[1] = 0xfe; 1044 ((struct arpcom *)ifp)->ac_enaddr[2] = 0xe1; 1045 ((struct arpcom *)ifp)->ac_enaddr[3] = 0xba; 1046 ((struct arpcom *)ifp)->ac_enaddr[4] = 0xd0; 1047 /* 1048 * XXX use of random() by anything except the scheduler is 1049 * normally invalid, but this is boot time, so pre-scheduler, 1050 * and the random subsystem is not alive yet 1051 */ 1052 ((struct arpcom *)ifp)->ac_enaddr[5] = (u_char)random() & 0xff; 1053 } 1054 1055 ifp->if_type = IFT_ETHER; 1056 ifp->if_addrlen = ETHER_ADDR_LEN; 1057 ifp->if_hdrlen = ETHER_HDR_LEN; 1058 ifp->if_mtu = ETHERMTU; 1059 ifp->if_output = ether_output; 1060 1061 if_alloc_sadl(ifp); 1062 bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr, 1063 LLADDR(ifp->if_sadl), ifp->if_addrlen); 1064 LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs); 1065 #if NBPFILTER > 0 1066 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 1067 #endif 1068 } 1069 1070 void 1071 ether_ifdetach(ifp) 1072 struct ifnet *ifp; 1073 { 1074 struct arpcom *ac = (struct arpcom *)ifp; 1075 struct ether_multi *enm; 1076 1077 for (enm = LIST_FIRST(&ac->ac_multiaddrs); 1078 enm != LIST_END(&ac->ac_multiaddrs); 1079 enm = LIST_FIRST(&ac->ac_multiaddrs)) { 1080 LIST_REMOVE(enm, enm_list); 1081 free(enm, M_IFMADDR); 1082 } 1083 1084 if_free_sadl(ifp); 1085 } 1086 1087 #if 0 1088 /* 1089 * This is for reference. We have a table-driven version 1090 * of the little-endian crc32 generator, which is faster 1091 * than the double-loop. 1092 */ 1093 u_int32_t 1094 ether_crc32_le(const u_int8_t *buf, size_t len) 1095 { 1096 u_int32_t c, crc, carry; 1097 size_t i, j; 1098 1099 crc = 0xffffffffU; /* initial value */ 1100 1101 for (i = 0; i < len; i++) { 1102 c = buf[i]; 1103 for (j = 0; j < 8; j++) { 1104 carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); 1105 crc >>= 1; 1106 c >>= 1; 1107 if (carry) 1108 crc = (crc ^ ETHER_CRC_POLY_LE); 1109 } 1110 } 1111 1112 return (crc); 1113 } 1114 #else 1115 u_int32_t 1116 ether_crc32_le(const u_int8_t *buf, size_t len) 1117 { 1118 static const u_int32_t crctab[] = { 1119 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 1120 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 1121 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 1122 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 1123 }; 1124 u_int32_t crc; 1125 int i; 1126 1127 crc = 0xffffffffU; /* initial value */ 1128 1129 for (i = 0; i < len; i++) { 1130 crc ^= buf[i]; 1131 crc = (crc >> 4) ^ crctab[crc & 0xf]; 1132 crc = (crc >> 4) ^ crctab[crc & 0xf]; 1133 } 1134 1135 return (crc); 1136 } 1137 #endif 1138 1139 u_int32_t 1140 ether_crc32_be(const u_int8_t *buf, size_t len) 1141 { 1142 u_int32_t c, crc, carry; 1143 size_t i, j; 1144 1145 crc = 0xffffffffU; /* initial value */ 1146 1147 for (i = 0; i < len; i++) { 1148 c = buf[i]; 1149 for (j = 0; j < 8; j++) { 1150 carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); 1151 crc <<= 1; 1152 c >>= 1; 1153 if (carry) 1154 crc = (crc ^ ETHER_CRC_POLY_BE) | carry; 1155 } 1156 } 1157 1158 return (crc); 1159 } 1160 1161 #ifdef INET 1162 u_char ether_ipmulticast_min[ETHER_ADDR_LEN] = 1163 { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 }; 1164 u_char ether_ipmulticast_max[ETHER_ADDR_LEN] = 1165 { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff }; 1166 #endif 1167 1168 #ifdef INET6 1169 u_char ether_ip6multicast_min[ETHER_ADDR_LEN] = 1170 { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 }; 1171 u_char ether_ip6multicast_max[ETHER_ADDR_LEN] = 1172 { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff }; 1173 #endif 1174 1175 /* 1176 * Convert a sockaddr into an Ethernet address or range of Ethernet 1177 * addresses. 1178 */ 1179 int 1180 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN], 1181 u_int8_t addrhi[ETHER_ADDR_LEN]) 1182 { 1183 #ifdef INET 1184 struct sockaddr_in *sin; 1185 #endif /* INET */ 1186 #ifdef INET6 1187 struct sockaddr_in6 *sin6; 1188 #endif /* INET6 */ 1189 1190 switch (sa->sa_family) { 1191 1192 case AF_UNSPEC: 1193 bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN); 1194 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1195 break; 1196 1197 #ifdef INET 1198 case AF_INET: 1199 sin = satosin(sa); 1200 if (sin->sin_addr.s_addr == INADDR_ANY) { 1201 /* 1202 * An IP address of INADDR_ANY means listen to 1203 * or stop listening to all of the Ethernet 1204 * multicast addresses used for IP. 1205 * (This is for the sake of IP multicast routers.) 1206 */ 1207 bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN); 1208 bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN); 1209 } else { 1210 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo); 1211 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1212 } 1213 break; 1214 #endif 1215 #ifdef INET6 1216 case AF_INET6: 1217 sin6 = satosin6(sa); 1218 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1219 /* 1220 * An IP6 address of 0 means listen to or stop 1221 * listening to all of the Ethernet multicast 1222 * address used for IP6. 1223 * 1224 * (This might not be healthy, given IPv6's reliance on 1225 * multicast for things like neighbor discovery. 1226 * Perhaps initializing all-nodes, solicited nodes, and 1227 * possibly all-routers for this interface afterwards 1228 * is not a bad idea.) 1229 */ 1230 1231 bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN); 1232 bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN); 1233 } else { 1234 ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo); 1235 bcopy(addrlo, addrhi, ETHER_ADDR_LEN); 1236 } 1237 break; 1238 #endif 1239 1240 default: 1241 return (EAFNOSUPPORT); 1242 } 1243 return (0); 1244 } 1245 1246 /* 1247 * Add an Ethernet multicast address or range of addresses to the list for a 1248 * given interface. 1249 */ 1250 int 1251 ether_addmulti(ifr, ac) 1252 struct ifreq *ifr; 1253 register struct arpcom *ac; 1254 { 1255 register struct ether_multi *enm; 1256 u_char addrlo[ETHER_ADDR_LEN]; 1257 u_char addrhi[ETHER_ADDR_LEN]; 1258 int s = splimp(), error; 1259 1260 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 1261 if (error != 0) { 1262 splx(s); 1263 return (error); 1264 } 1265 1266 /* 1267 * Verify that we have valid Ethernet multicast addresses. 1268 */ 1269 if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) { 1270 splx(s); 1271 return (EINVAL); 1272 } 1273 /* 1274 * See if the address range is already in the list. 1275 */ 1276 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 1277 if (enm != NULL) { 1278 /* 1279 * Found it; just increment the reference count. 1280 */ 1281 ++enm->enm_refcount; 1282 splx(s); 1283 return (0); 1284 } 1285 /* 1286 * New address or range; malloc a new multicast record 1287 * and link it into the interface's multicast list. 1288 */ 1289 enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT); 1290 if (enm == NULL) { 1291 splx(s); 1292 return (ENOBUFS); 1293 } 1294 bcopy(addrlo, enm->enm_addrlo, ETHER_ADDR_LEN); 1295 bcopy(addrhi, enm->enm_addrhi, ETHER_ADDR_LEN); 1296 enm->enm_ac = ac; 1297 enm->enm_refcount = 1; 1298 LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list); 1299 ac->ac_multicnt++; 1300 splx(s); 1301 /* 1302 * Return ENETRESET to inform the driver that the list has changed 1303 * and its reception filter should be adjusted accordingly. 1304 */ 1305 return (ENETRESET); 1306 } 1307 1308 /* 1309 * Delete a multicast address record. 1310 */ 1311 int 1312 ether_delmulti(ifr, ac) 1313 struct ifreq *ifr; 1314 register struct arpcom *ac; 1315 { 1316 register struct ether_multi *enm; 1317 u_char addrlo[ETHER_ADDR_LEN]; 1318 u_char addrhi[ETHER_ADDR_LEN]; 1319 int s = splimp(), error; 1320 1321 error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi); 1322 if (error != 0) { 1323 splx(s); 1324 return (error); 1325 } 1326 1327 /* 1328 * Look up the address in our list. 1329 */ 1330 ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm); 1331 if (enm == NULL) { 1332 splx(s); 1333 return (ENXIO); 1334 } 1335 if (--enm->enm_refcount != 0) { 1336 /* 1337 * Still some claims to this record. 1338 */ 1339 splx(s); 1340 return (0); 1341 } 1342 /* 1343 * No remaining claims to this record; unlink and free it. 1344 */ 1345 LIST_REMOVE(enm, enm_list); 1346 free(enm, M_IFMADDR); 1347 ac->ac_multicnt--; 1348 splx(s); 1349 /* 1350 * Return ENETRESET to inform the driver that the list has changed 1351 * and its reception filter should be adjusted accordingly. 1352 */ 1353 return (ENETRESET); 1354 } 1355