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