1 /* 2 * Copyright (c) 1982, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 34 * $FreeBSD$ 35 */ 36 37 #include "opt_atalk.h" 38 #include "opt_inet.h" 39 #include "opt_ipx.h" 40 #include "opt_bdg.h" 41 #include "opt_netgraph.h" 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/kernel.h> 46 #include <sys/malloc.h> 47 #include <sys/mbuf.h> 48 #include <sys/socket.h> 49 #include <sys/sockio.h> 50 #include <sys/sysctl.h> 51 52 #include <net/if.h> 53 #include <net/netisr.h> 54 #include <net/route.h> 55 #include <net/if_llc.h> 56 #include <net/if_dl.h> 57 #include <net/if_types.h> 58 59 #ifdef INET 60 #include <netinet/in.h> 61 #include <netinet/in_var.h> 62 #include <netinet/if_ether.h> 63 #endif 64 65 #ifdef IPX 66 #include <netipx/ipx.h> 67 #include <netipx/ipx_if.h> 68 #endif 69 70 #ifdef NS 71 #include <netns/ns.h> 72 #include <netns/ns_if.h> 73 ushort ns_nettype; 74 int ether_outputdebug = 0; 75 int ether_inputdebug = 0; 76 #endif 77 78 #ifdef ISO 79 #include <netiso/argo_debug.h> 80 #include <netiso/iso.h> 81 #include <netiso/iso_var.h> 82 #include <netiso/iso_snpac.h> 83 #endif 84 85 /*#ifdef LLC 86 #include <netccitt/dll.h> 87 #include <netccitt/llc_var.h> 88 #endif*/ 89 90 #if defined(LLC) && defined(CCITT) 91 extern struct ifqueue pkintrq; 92 #endif 93 94 #ifdef NETATALK 95 #include <netatalk/at.h> 96 #include <netatalk/at_var.h> 97 #include <netatalk/at_extern.h> 98 99 #define llc_snap_org_code llc_un.type_snap.org_code 100 #define llc_snap_ether_type llc_un.type_snap.ether_type 101 102 extern u_char at_org_code[3]; 103 extern u_char aarp_org_code[3]; 104 #endif /* NETATALK */ 105 106 #ifdef BRIDGE 107 #include <net/bridge.h> 108 #endif 109 110 #include "vlan.h" 111 #if NVLAN > 0 112 #include <net/if_vlan_var.h> 113 #endif /* NVLAN > 0 */ 114 115 static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **, 116 struct sockaddr *)); 117 u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 118 #define senderr(e) do { error = (e); goto bad;} while (0) 119 #define IFP2AC(IFP) ((struct arpcom *)IFP) 120 121 #ifdef NETGRAPH 122 #include <netgraph/ng_ether.h> 123 #include <netgraph/ng_message.h> 124 #include <netgraph/netgraph.h> 125 126 static void ngether_init(void* ignored); 127 static void ngether_send(struct arpcom *ac, 128 struct ether_header *eh, struct mbuf *m); 129 static ng_constructor_t ngether_constructor; 130 static ng_rcvmsg_t ngether_rcvmsg; 131 static ng_shutdown_t ngether_rmnode; 132 static ng_newhook_t ngether_newhook; 133 static ng_connect_t ngether_connect; 134 static ng_rcvdata_t ngether_rcvdata; 135 static ng_disconnect_t ngether_disconnect; 136 137 static struct ng_type typestruct = { 138 NG_VERSION, 139 NG_ETHER_NODE_TYPE, 140 NULL, 141 ngether_constructor, 142 ngether_rcvmsg, 143 ngether_rmnode, 144 ngether_newhook, 145 NULL, 146 ngether_connect, 147 ngether_rcvdata, 148 ngether_rcvdata, 149 ngether_disconnect 150 }; 151 152 #define AC2NG(AC) ((node_p)((AC)->ac_ng)) 153 #define NGEF_DIVERT NGF_TYPE1 /* all packets sent to netgraph */ 154 #endif /* NETGRAPH */ 155 156 /* 157 * Ethernet output routine. 158 * Encapsulate a packet of type family for the local net. 159 * Use trailer local net encapsulation if enough data in first 160 * packet leaves a multiple of 512 bytes of data in remainder. 161 * Assumes that ifp is actually pointer to arpcom structure. 162 */ 163 int 164 ether_output(ifp, m0, dst, rt0) 165 register struct ifnet *ifp; 166 struct mbuf *m0; 167 struct sockaddr *dst; 168 struct rtentry *rt0; 169 { 170 short type; 171 int s, error = 0, hdrcmplt = 0; 172 u_char esrc[6], edst[6]; 173 register struct mbuf *m = m0; 174 register struct rtentry *rt; 175 register struct ether_header *eh; 176 int off, len = m->m_pkthdr.len, loop_copy = 0; 177 int hlen; /* link layer header lenght */ 178 struct arpcom *ac = IFP2AC(ifp); 179 180 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 181 senderr(ENETDOWN); 182 rt = rt0; 183 if (rt) { 184 if ((rt->rt_flags & RTF_UP) == 0) { 185 rt0 = rt = rtalloc1(dst, 1, 0UL); 186 if (rt0) 187 rt->rt_refcnt--; 188 else 189 senderr(EHOSTUNREACH); 190 } 191 if (rt->rt_flags & RTF_GATEWAY) { 192 if (rt->rt_gwroute == 0) 193 goto lookup; 194 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 195 rtfree(rt); rt = rt0; 196 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 197 0UL); 198 if ((rt = rt->rt_gwroute) == 0) 199 senderr(EHOSTUNREACH); 200 } 201 } 202 if (rt->rt_flags & RTF_REJECT) 203 if (rt->rt_rmx.rmx_expire == 0 || 204 time_second < rt->rt_rmx.rmx_expire) 205 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 206 } 207 hlen = ETHER_HDR_LEN; 208 switch (dst->sa_family) { 209 #ifdef INET 210 case AF_INET: 211 if (!arpresolve(ac, rt, m, dst, edst, rt0)) 212 return (0); /* if not yet resolved */ 213 off = m->m_pkthdr.len - m->m_len; 214 type = htons(ETHERTYPE_IP); 215 break; 216 #endif 217 #ifdef IPX 218 case AF_IPX: 219 type = htons(ETHERTYPE_IPX); 220 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host), 221 (caddr_t)edst, sizeof (edst)); 222 break; 223 #endif 224 #ifdef NETATALK 225 case AF_APPLETALK: 226 { 227 struct at_ifaddr *aa; 228 229 if ((aa = at_ifawithnet((struct sockaddr_at *)dst)) == NULL) { 230 goto bad; 231 } 232 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) 233 return (0); 234 /* 235 * In the phase 2 case, need to prepend an mbuf for the llc header. 236 * Since we must preserve the value of m, which is passed to us by 237 * value, we m_copy() the first mbuf, and use it for our llc header. 238 */ 239 if ( aa->aa_flags & AFA_PHASE2 ) { 240 struct llc llc; 241 242 M_PREPEND(m, sizeof(struct llc), M_WAIT); 243 len += sizeof(struct llc); 244 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 245 llc.llc_control = LLC_UI; 246 bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code)); 247 llc.llc_snap_ether_type = htons( ETHERTYPE_AT ); 248 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc)); 249 type = htons(m->m_pkthdr.len); 250 hlen = sizeof(struct llc) + ETHER_HDR_LEN; 251 } else { 252 type = htons(ETHERTYPE_AT); 253 } 254 break; 255 } 256 #endif NETATALK 257 #ifdef NS 258 case AF_NS: 259 switch(ns_nettype){ 260 default: 261 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */ 262 type = 0x8137; 263 break; 264 case 0x0: /* Novell 802.3 */ 265 type = htons( m->m_pkthdr.len); 266 break; 267 case 0xe0e0: /* Novell 802.2 and Token-Ring */ 268 M_PREPEND(m, 3, M_WAIT); 269 type = htons( m->m_pkthdr.len); 270 cp = mtod(m, u_char *); 271 *cp++ = 0xE0; 272 *cp++ = 0xE0; 273 *cp++ = 0x03; 274 break; 275 } 276 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 277 (caddr_t)edst, sizeof (edst)); 278 /* 279 * XXX if ns_thishost is the same as the node's ethernet 280 * address then just the default code will catch this anyhow. 281 * So I'm not sure if this next clause should be here at all? 282 * [JRE] 283 */ 284 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){ 285 m->m_pkthdr.rcvif = ifp; 286 schednetisr(NETISR_NS); 287 inq = &nsintrq; 288 s = splimp(); 289 if (IF_QFULL(inq)) { 290 IF_DROP(inq); 291 m_freem(m); 292 } else 293 IF_ENQUEUE(inq, m); 294 splx(s); 295 return (error); 296 } 297 if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){ 298 m->m_flags |= M_BCAST; 299 } 300 break; 301 #endif /* NS */ 302 #ifdef ISO 303 case AF_ISO: { 304 int snpalen; 305 struct llc *l; 306 register struct sockaddr_dl *sdl; 307 308 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 309 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 310 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 311 } else if (error = 312 iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 313 (char *)edst, &snpalen)) 314 goto bad; /* Not Resolved */ 315 /* If broadcasting on a simplex interface, loopback a copy */ 316 if (*edst & 1) 317 m->m_flags |= (M_BCAST|M_MCAST); 318 M_PREPEND(m, 3, M_DONTWAIT); 319 if (m == NULL) 320 return (0); 321 type = htons(m->m_pkthdr.len); 322 l = mtod(m, struct llc *); 323 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 324 l->llc_control = LLC_UI; 325 len += 3; 326 IFDEBUG(D_ETHER) 327 int i; 328 printf("unoutput: sending pkt to: "); 329 for (i=0; i<6; i++) 330 printf("%x ", edst[i] & 0xff); 331 printf("\n"); 332 ENDDEBUG 333 } break; 334 #endif /* ISO */ 335 #ifdef LLC 336 /* case AF_NSAP: */ 337 case AF_CCITT: { 338 register struct sockaddr_dl *sdl = 339 (struct sockaddr_dl *) rt -> rt_gateway; 340 341 if (sdl && sdl->sdl_family == AF_LINK 342 && sdl->sdl_alen > 0) { 343 bcopy(LLADDR(sdl), (char *)edst, sizeof(edst)); 344 } else goto bad; /* Not a link interface ? Funny ... */ 345 if (*edst & 1) 346 loop_copy = 1; 347 type = htons(m->m_pkthdr.len); 348 #ifdef LLC_DEBUG 349 { 350 int i; 351 register struct llc *l = mtod(m, struct llc *); 352 353 printf("ether_output: sending LLC2 pkt to: "); 354 for (i=0; i<6; i++) 355 printf("%x ", edst[i] & 0xff); 356 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 357 type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff, 358 l->llc_control & 0xff); 359 360 } 361 #endif /* LLC_DEBUG */ 362 } break; 363 #endif /* LLC */ 364 365 case pseudo_AF_HDRCMPLT: 366 hdrcmplt = 1; 367 eh = (struct ether_header *)dst->sa_data; 368 (void)memcpy(esrc, eh->ether_shost, sizeof (esrc)); 369 /* FALLTHROUGH */ 370 371 case AF_UNSPEC: 372 loop_copy = -1; /* if this is for us, don't do it */ 373 eh = (struct ether_header *)dst->sa_data; 374 (void)memcpy(edst, eh->ether_dhost, sizeof (edst)); 375 type = eh->ether_type; 376 break; 377 378 default: 379 printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit, 380 dst->sa_family); 381 senderr(EAFNOSUPPORT); 382 } 383 384 /* 385 * Add local net header. If no space in first mbuf, 386 * allocate another. 387 */ 388 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 389 if (m == 0) 390 senderr(ENOBUFS); 391 eh = mtod(m, struct ether_header *); 392 (void)memcpy(&eh->ether_type, &type, 393 sizeof(eh->ether_type)); 394 (void)memcpy(eh->ether_dhost, edst, sizeof (edst)); 395 if (hdrcmplt) 396 (void)memcpy(eh->ether_shost, esrc, 397 sizeof(eh->ether_shost)); 398 else 399 (void)memcpy(eh->ether_shost, ac->ac_enaddr, 400 sizeof(eh->ether_shost)); 401 402 /* 403 * If a simplex interface, and the packet is being sent to our 404 * Ethernet address or a broadcast address, loopback a copy. 405 * XXX To make a simplex device behave exactly like a duplex 406 * device, we should copy in the case of sending to our own 407 * ethernet address (thus letting the original actually appear 408 * on the wire). However, we don't do that here for security 409 * reasons and compatibility with the original behavior. 410 */ 411 if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) { 412 if ((m->m_flags & M_BCAST) || (loop_copy > 0)) { 413 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); 414 415 (void) if_simloop(ifp, n, dst, hlen); 416 } else if (bcmp(eh->ether_dhost, 417 eh->ether_shost, ETHER_ADDR_LEN) == 0) { 418 (void) if_simloop(ifp, m, dst, hlen); 419 return (0); /* XXX */ 420 } 421 } 422 #ifdef BRIDGE 423 if (do_bridge) { 424 struct mbuf *m0 = m ; 425 426 if (m->m_pkthdr.rcvif) 427 m->m_pkthdr.rcvif = NULL ; 428 ifp = bridge_dst_lookup(m); 429 bdg_forward(&m0, ifp); 430 if (m0) 431 m_freem(m0); 432 return (0); 433 } 434 #endif 435 s = splimp(); 436 /* 437 * Queue message on interface, and start output if interface 438 * not yet active. 439 */ 440 if (IF_QFULL(&ifp->if_snd)) { 441 IF_DROP(&ifp->if_snd); 442 splx(s); 443 senderr(ENOBUFS); 444 } 445 IF_ENQUEUE(&ifp->if_snd, m); 446 if ((ifp->if_flags & IFF_OACTIVE) == 0) 447 (*ifp->if_start)(ifp); 448 splx(s); 449 ifp->if_obytes += len + sizeof (struct ether_header); 450 if (m->m_flags & M_MCAST) 451 ifp->if_omcasts++; 452 return (error); 453 454 bad: 455 if (m) 456 m_freem(m); 457 return (error); 458 } 459 460 /* 461 * Process a received Ethernet packet; 462 * the packet is in the mbuf chain m without 463 * the ether header, which is provided separately. 464 */ 465 void 466 ether_input(ifp, eh, m) 467 struct ifnet *ifp; 468 register struct ether_header *eh; 469 struct mbuf *m; 470 { 471 register struct ifqueue *inq; 472 u_short ether_type; 473 int s; 474 #if defined (ISO) || defined (LLC) || defined(NETATALK) 475 register struct llc *l; 476 #endif 477 478 if ((ifp->if_flags & IFF_UP) == 0) { 479 m_freem(m); 480 return; 481 } 482 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh); 483 if (eh->ether_dhost[0] & 1) { 484 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 485 sizeof(etherbroadcastaddr)) == 0) 486 m->m_flags |= M_BCAST; 487 else 488 m->m_flags |= M_MCAST; 489 } 490 if (m->m_flags & (M_BCAST|M_MCAST)) 491 ifp->if_imcasts++; 492 493 ether_type = ntohs(eh->ether_type); 494 495 #ifdef NETGRAPH 496 { 497 struct arpcom *ac = IFP2AC(ifp); 498 if (AC2NG(ac) && (AC2NG(ac)->flags & NGEF_DIVERT)) { 499 ngether_send(ac, eh, m); 500 return; 501 } 502 } 503 #endif /* NETGRAPH */ 504 505 #if NVLAN > 0 506 if (ether_type == vlan_proto) { 507 if (vlan_input(eh, m) < 0) 508 ifp->if_data.ifi_noproto++; 509 return; 510 } 511 #endif /* NVLAN > 0 */ 512 513 switch (ether_type) { 514 #ifdef INET 515 case ETHERTYPE_IP: 516 if (ipflow_fastforward(m)) 517 return; 518 schednetisr(NETISR_IP); 519 inq = &ipintrq; 520 break; 521 522 case ETHERTYPE_ARP: 523 schednetisr(NETISR_ARP); 524 inq = &arpintrq; 525 break; 526 #endif 527 #ifdef IPX 528 case ETHERTYPE_IPX: 529 schednetisr(NETISR_IPX); 530 inq = &ipxintrq; 531 break; 532 #endif 533 #ifdef NS 534 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */ 535 schednetisr(NETISR_NS); 536 inq = &nsintrq; 537 break; 538 539 #endif /* NS */ 540 #ifdef NETATALK 541 case ETHERTYPE_AT: 542 schednetisr(NETISR_ATALK); 543 inq = &atintrq1; 544 break; 545 case ETHERTYPE_AARP: 546 /* probably this should be done with a NETISR as well */ 547 aarpinput(IFP2AC(ifp), m); /* XXX */ 548 return; 549 #endif NETATALK 550 default: 551 #ifdef NS 552 checksum = mtod(m, ushort *); 553 /* Novell 802.3 */ 554 if ((ether_type <= ETHERMTU) && 555 ((*checksum == 0xffff) || (*checksum == 0xE0E0))){ 556 if(*checksum == 0xE0E0) { 557 m->m_pkthdr.len -= 3; 558 m->m_len -= 3; 559 m->m_data += 3; 560 } 561 schednetisr(NETISR_NS); 562 inq = &nsintrq; 563 break; 564 } 565 #endif /* NS */ 566 #if defined (ISO) || defined (LLC) || defined(NETATALK) 567 if (ether_type > ETHERMTU) 568 goto dropanyway; 569 l = mtod(m, struct llc *); 570 switch (l->llc_dsap) { 571 #ifdef NETATALK 572 case LLC_SNAP_LSAP: 573 switch (l->llc_control) { 574 case LLC_UI: 575 if (l->llc_ssap != LLC_SNAP_LSAP) 576 goto dropanyway; 577 578 if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code, 579 sizeof(at_org_code)) == 0 && 580 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) { 581 inq = &atintrq2; 582 m_adj( m, sizeof( struct llc )); 583 schednetisr(NETISR_ATALK); 584 break; 585 } 586 587 if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code, 588 sizeof(aarp_org_code)) == 0 && 589 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) { 590 m_adj( m, sizeof( struct llc )); 591 aarpinput(IFP2AC(ifp), m); /* XXX */ 592 return; 593 } 594 595 default: 596 goto dropanyway; 597 } 598 break; 599 #endif NETATALK 600 #ifdef ISO 601 case LLC_ISO_LSAP: 602 switch (l->llc_control) { 603 case LLC_UI: 604 /* LLC_UI_P forbidden in class 1 service */ 605 if ((l->llc_dsap == LLC_ISO_LSAP) && 606 (l->llc_ssap == LLC_ISO_LSAP)) { 607 /* LSAP for ISO */ 608 if (m->m_pkthdr.len > ether_type) 609 m_adj(m, ether_type - m->m_pkthdr.len); 610 m->m_data += 3; /* XXX */ 611 m->m_len -= 3; /* XXX */ 612 m->m_pkthdr.len -= 3; /* XXX */ 613 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 614 if (m == 0) 615 return; 616 *mtod(m, struct ether_header *) = *eh; 617 IFDEBUG(D_ETHER) 618 printf("clnp packet"); 619 ENDDEBUG 620 schednetisr(NETISR_ISO); 621 inq = &clnlintrq; 622 break; 623 } 624 goto dropanyway; 625 626 case LLC_XID: 627 case LLC_XID_P: 628 if(m->m_len < 6) 629 goto dropanyway; 630 l->llc_window = 0; 631 l->llc_fid = 9; 632 l->llc_class = 1; 633 l->llc_dsap = l->llc_ssap = 0; 634 /* Fall through to */ 635 case LLC_TEST: 636 case LLC_TEST_P: 637 { 638 struct sockaddr sa; 639 register struct ether_header *eh2; 640 int i; 641 u_char c = l->llc_dsap; 642 643 l->llc_dsap = l->llc_ssap; 644 l->llc_ssap = c; 645 if (m->m_flags & (M_BCAST | M_MCAST)) 646 bcopy((caddr_t)ac->ac_enaddr, 647 (caddr_t)eh->ether_dhost, 6); 648 sa.sa_family = AF_UNSPEC; 649 sa.sa_len = sizeof(sa); 650 eh2 = (struct ether_header *)sa.sa_data; 651 for (i = 0; i < 6; i++) { 652 eh2->ether_shost[i] = c = eh->ether_dhost[i]; 653 eh2->ether_dhost[i] = 654 eh->ether_dhost[i] = eh->ether_shost[i]; 655 eh->ether_shost[i] = c; 656 } 657 ifp->if_output(ifp, m, &sa, NULL); 658 return; 659 } 660 default: 661 m_freem(m); 662 return; 663 } 664 break; 665 #endif /* ISO */ 666 #ifdef LLC 667 case LLC_X25_LSAP: 668 { 669 if (m->m_pkthdr.len > ether_type) 670 m_adj(m, ether_type - m->m_pkthdr.len); 671 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 672 if (m == 0) 673 return; 674 if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 675 eh->ether_dhost, LLC_X25_LSAP, 6, 676 mtod(m, struct sdl_hdr *))) 677 panic("ETHER cons addr failure"); 678 mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type; 679 #ifdef LLC_DEBUG 680 printf("llc packet\n"); 681 #endif /* LLC_DEBUG */ 682 schednetisr(NETISR_CCITT); 683 inq = &llcintrq; 684 break; 685 } 686 #endif /* LLC */ 687 dropanyway: 688 default: 689 #ifdef NETGRAPH 690 ngether_send(IFP2AC(ifp), eh, m); 691 #else /* NETGRAPH */ 692 m_freem(m); 693 #endif /* NETGRAPH */ 694 return; 695 } 696 #else /* ISO || LLC || NETATALK */ 697 #ifdef NETGRAPH 698 ngether_send(IFP2AC(ifp), eh, m); 699 #else /* NETGRAPH */ 700 m_freem(m); 701 #endif /* NETGRAPH */ 702 return; 703 #endif /* ISO || LLC || NETATALK */ 704 } 705 706 s = splimp(); 707 if (IF_QFULL(inq)) { 708 IF_DROP(inq); 709 m_freem(m); 710 } else 711 IF_ENQUEUE(inq, m); 712 splx(s); 713 } 714 715 /* 716 * Perform common duties while attaching to interface list 717 */ 718 void 719 ether_ifattach(ifp) 720 register struct ifnet *ifp; 721 { 722 register struct ifaddr *ifa; 723 register struct sockaddr_dl *sdl; 724 725 ifp->if_type = IFT_ETHER; 726 ifp->if_addrlen = 6; 727 ifp->if_hdrlen = 14; 728 ifp->if_mtu = ETHERMTU; 729 ifp->if_resolvemulti = ether_resolvemulti; 730 if (ifp->if_baudrate == 0) 731 ifp->if_baudrate = 10000000; 732 ifa = ifnet_addrs[ifp->if_index - 1]; 733 if (ifa == 0) { 734 printf("ether_ifattach: no lladdr!\n"); 735 return; 736 } 737 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 738 sdl->sdl_type = IFT_ETHER; 739 sdl->sdl_alen = ifp->if_addrlen; 740 bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen); 741 #ifdef NETGRAPH 742 ngether_init(ifp); 743 #endif /* NETGRAPH */ 744 } 745 746 SYSCTL_DECL(_net_link); 747 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); 748 749 int 750 ether_ioctl(ifp, command, data) 751 struct ifnet *ifp; 752 int command; 753 caddr_t data; 754 { 755 struct ifaddr *ifa = (struct ifaddr *) data; 756 struct ifreq *ifr = (struct ifreq *) data; 757 int error = 0; 758 759 switch (command) { 760 case SIOCSIFADDR: 761 ifp->if_flags |= IFF_UP; 762 763 switch (ifa->ifa_addr->sa_family) { 764 #ifdef INET 765 case AF_INET: 766 ifp->if_init(ifp->if_softc); /* before arpwhohas */ 767 arp_ifinit(IFP2AC(ifp), ifa); 768 break; 769 #endif 770 #ifdef IPX 771 /* 772 * XXX - This code is probably wrong 773 */ 774 case AF_IPX: 775 { 776 register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 777 struct arpcom *ac = IFP2AC(ifp); 778 779 if (ipx_nullhost(*ina)) 780 ina->x_host = 781 *(union ipx_host *) 782 ac->ac_enaddr; 783 else { 784 bcopy((caddr_t) ina->x_host.c_host, 785 (caddr_t) ac->ac_enaddr, 786 sizeof(ac->ac_enaddr)); 787 } 788 789 /* 790 * Set new address 791 */ 792 ifp->if_init(ifp->if_softc); 793 break; 794 } 795 #endif 796 #ifdef NS 797 /* 798 * XXX - This code is probably wrong 799 */ 800 case AF_NS: 801 { 802 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 803 struct arpcom *ac = IFP2AC(ifp); 804 805 if (ns_nullhost(*ina)) 806 ina->x_host = 807 *(union ns_host *) (ac->ac_enaddr); 808 else { 809 bcopy((caddr_t) ina->x_host.c_host, 810 (caddr_t) ac->ac_enaddr, 811 sizeof(ac->ac_enaddr)); 812 } 813 814 /* 815 * Set new address 816 */ 817 ifp->if_init(ifp->if_softc); 818 break; 819 } 820 #endif 821 default: 822 ifp->if_init(ifp->if_softc); 823 break; 824 } 825 break; 826 827 case SIOCGIFADDR: 828 { 829 struct sockaddr *sa; 830 831 sa = (struct sockaddr *) & ifr->ifr_data; 832 bcopy(IFP2AC(ifp)->ac_enaddr, 833 (caddr_t) sa->sa_data, ETHER_ADDR_LEN); 834 } 835 break; 836 837 case SIOCSIFMTU: 838 /* 839 * Set the interface MTU. 840 */ 841 if (ifr->ifr_mtu > ETHERMTU) { 842 error = EINVAL; 843 } else { 844 ifp->if_mtu = ifr->ifr_mtu; 845 } 846 break; 847 } 848 return (error); 849 } 850 851 int 852 ether_resolvemulti(ifp, llsa, sa) 853 struct ifnet *ifp; 854 struct sockaddr **llsa; 855 struct sockaddr *sa; 856 { 857 struct sockaddr_dl *sdl; 858 struct sockaddr_in *sin; 859 u_char *e_addr; 860 861 switch(sa->sa_family) { 862 case AF_LINK: 863 /* 864 * No mapping needed. Just check that it's a valid MC address. 865 */ 866 sdl = (struct sockaddr_dl *)sa; 867 e_addr = LLADDR(sdl); 868 if ((e_addr[0] & 1) != 1) 869 return EADDRNOTAVAIL; 870 *llsa = 0; 871 return 0; 872 873 #ifdef INET 874 case AF_INET: 875 sin = (struct sockaddr_in *)sa; 876 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 877 return EADDRNOTAVAIL; 878 MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR, 879 M_WAITOK); 880 sdl->sdl_len = sizeof *sdl; 881 sdl->sdl_family = AF_LINK; 882 sdl->sdl_index = ifp->if_index; 883 sdl->sdl_type = IFT_ETHER; 884 sdl->sdl_nlen = 0; 885 sdl->sdl_alen = ETHER_ADDR_LEN; 886 sdl->sdl_slen = 0; 887 e_addr = LLADDR(sdl); 888 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr); 889 *llsa = (struct sockaddr *)sdl; 890 return 0; 891 #endif 892 893 default: 894 /* 895 * Well, the text isn't quite right, but it's the name 896 * that counts... 897 */ 898 return EAFNOSUPPORT; 899 } 900 } 901 902 #ifdef NETGRAPH 903 904 /*********************************************************************** 905 * This section contains the methods for the Netgraph interface 906 ***********************************************************************/ 907 /* It's Ascii-art time! 908 * The ifnet is the first part of the arpcom which must be 909 * the first part of the device's softc.. yuk. 910 * 911 * +--------------------------+-----+---------+ 912 * | struct ifnet (*ifp) | | | 913 * | | | | 914 * +--------------------------+ | | 915 * +--|[ac_ng] struct arpcom (*ac) | | 916 * | +--------------------------------+ | 917 * | | struct softc (*ifp->if_softc) (device) | 918 * | +------------------------------------------+ 919 * | ^ 920 * AC2NG() | 921 * | v 922 * | +----------------------+ 923 * | | [private] [flags] | 924 * +------>| struct ng_node | 925 * | [hooks] | ** we only allow one hook 926 * +----------------------+ 927 * ^ 928 * | 929 * v 930 * +-------------+ 931 * | [node] | 932 * | hook | 933 * | [private]|-- *unused* 934 * +-------------+ 935 */ 936 937 /* 938 * called during interface attaching 939 */ 940 static void 941 ngether_init(void *ifpvoid) 942 { 943 struct ifnet *ifp = ifpvoid; 944 struct arpcom *ac = IFP2AC(ifp); 945 static int ngether_done_init; 946 char namebuf[32]; 947 node_p node; 948 949 /* 950 * we have found a node, make sure our 'type' is availabe. 951 */ 952 if (ngether_done_init == 0) { 953 if (ng_newtype(&typestruct)) { 954 printf("ngether install failed\n"); 955 return; 956 } 957 ngether_done_init = 1; 958 } 959 if (ng_make_node_common(&typestruct, &node) != 0) 960 return; 961 ac->ac_ng = node; 962 node->private = ifp; 963 sprintf(namebuf, "%s%d", ifp->if_name, ifp->if_unit); 964 ng_name_node(AC2NG(ac), namebuf); 965 } 966 967 /* 968 * It is not possible or allowable to create a node of this type. 969 * If the hardware exists, it will already have created it. 970 */ 971 static int 972 ngether_constructor(node_p *nodep) 973 { 974 return (EINVAL); 975 } 976 977 /* 978 * Give our ok for a hook to be added... 979 * 980 * Allow one hook at a time (rawdata). 981 * It can eiteh rdivert everything or only unclaimed packets. 982 */ 983 static int 984 ngether_newhook(node_p node, hook_p hook, const char *name) 985 { 986 987 /* check if there is already a hook */ 988 if (LIST_FIRST(&(node->hooks))) 989 return(EISCONN); 990 /* 991 * Check for which mode hook we want. 992 */ 993 if (strcmp(name, NG_ETHER_HOOK_ORPHAN) != 0) { 994 if (strcmp(name, NG_ETHER_HOOK_DIVERT) != 0) { 995 return (EINVAL); 996 } 997 node->flags |= NGEF_DIVERT; 998 } else { 999 node->flags &= ~NGEF_DIVERT; 1000 } 1001 return (0); 1002 } 1003 1004 /* 1005 * incoming messages. 1006 * Just respond to the generic TEXT_STATUS message 1007 */ 1008 static int 1009 ngether_rcvmsg(node_p node, 1010 struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) 1011 { 1012 struct ifnet *ifp; 1013 int error = 0; 1014 1015 ifp = node->private; 1016 switch (msg->header.typecookie) { 1017 case NGM_ETHER_COOKIE: 1018 error = EINVAL; 1019 break; 1020 case NGM_GENERIC_COOKIE: 1021 switch(msg->header.cmd) { 1022 case NGM_TEXT_STATUS: { 1023 char *arg; 1024 int pos = 0; 1025 int resplen = sizeof(struct ng_mesg) + 512; 1026 MALLOC(*resp, struct ng_mesg *, resplen, 1027 M_NETGRAPH, M_NOWAIT); 1028 if (*resp == NULL) { 1029 error = ENOMEM; 1030 break; 1031 } 1032 bzero(*resp, resplen); 1033 arg = (*resp)->data; 1034 1035 /* 1036 * Put in the throughput information. 1037 */ 1038 pos = sprintf(arg, "%ld bytes in, %ld bytes out\n", 1039 ifp->if_ibytes, ifp->if_obytes); 1040 pos += sprintf(arg + pos, 1041 "%ld output errors\n", 1042 ifp->if_oerrors); 1043 pos += sprintf(arg + pos, 1044 "ierrors = %ld\n", 1045 ifp->if_ierrors); 1046 1047 (*resp)->header.version = NG_VERSION; 1048 (*resp)->header.arglen = strlen(arg) + 1; 1049 (*resp)->header.token = msg->header.token; 1050 (*resp)->header.typecookie = NGM_ETHER_COOKIE; 1051 (*resp)->header.cmd = msg->header.cmd; 1052 strncpy((*resp)->header.cmdstr, "status", 1053 NG_CMDSTRLEN); 1054 } 1055 break; 1056 default: 1057 error = EINVAL; 1058 break; 1059 } 1060 break; 1061 default: 1062 error = EINVAL; 1063 break; 1064 } 1065 free(msg, M_NETGRAPH); 1066 return (error); 1067 } 1068 1069 /* 1070 * Receive a completed ethernet packet. 1071 * Queue it for output. 1072 */ 1073 static int 1074 ngether_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) 1075 { 1076 struct ifnet *ifp; 1077 int error = 0; 1078 int s; 1079 struct ether_header *eh; 1080 1081 ifp = hook->node->private; 1082 1083 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 1084 senderr(ENETDOWN); 1085 /* 1086 * If a simplex interface, and the packet is being sent to our 1087 * Ethernet address or a broadcast address, loopback a copy. 1088 * XXX To make a simplex device behave exactly like a duplex 1089 * device, we should copy in the case of sending to our own 1090 * ethernet address (thus letting the original actually appear 1091 * on the wire). However, we don't do that here for security 1092 * reasons and compatibility with the original behavior. 1093 */ 1094 if (ifp->if_flags & IFF_SIMPLEX) { 1095 eh = mtod(m, struct ether_header *); 1096 if (m->m_flags & M_BCAST) { 1097 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); 1098 1099 ng_queue_data(hook, n, meta); 1100 } else if (bcmp(eh->ether_dhost, 1101 eh->ether_shost, ETHER_ADDR_LEN) == 0) { 1102 ng_queue_data(hook, m, meta); 1103 return (0); /* XXX */ 1104 } 1105 } 1106 s = splimp(); 1107 /* 1108 * Queue message on interface, and start output if interface 1109 * not yet active. 1110 * XXX if we lookead at the priority in the meta data we could 1111 * queue high priority items at the head. 1112 */ 1113 if (IF_QFULL(&ifp->if_snd)) { 1114 IF_DROP(&ifp->if_snd); 1115 splx(s); 1116 senderr(ENOBUFS); 1117 } 1118 IF_ENQUEUE(&ifp->if_snd, m); 1119 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1120 (*ifp->if_start)(ifp); 1121 splx(s); 1122 ifp->if_obytes += m->m_pkthdr.len; 1123 if (m->m_flags & M_MCAST) 1124 ifp->if_omcasts++; 1125 return (error); 1126 1127 bad: 1128 NG_FREE_DATA(m, meta); 1129 return (error); 1130 } 1131 1132 /* 1133 * pass an mbuf out to the connected hook 1134 * More complicated than just an m_prepend, as it tries to save later nodes 1135 * from needing to do lots of m_pullups. 1136 */ 1137 static void 1138 ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m) 1139 { 1140 int room; 1141 node_p node = AC2NG(ac); 1142 struct ether_header *eh2; 1143 1144 if (node && LIST_FIRST(&(node->hooks))) { 1145 /* 1146 * Possibly the header is already on the front, 1147 */ 1148 eh2 = mtod(m, struct ether_header *) - 1; 1149 if ( eh == eh2) { 1150 /* 1151 * This is the case so just move the markers back to 1152 * re-include it. We lucked out. 1153 * This allows us to avoid a yucky m_pullup 1154 * in later nodes if it works. 1155 */ 1156 m->m_len += sizeof(*eh); 1157 m->m_data -= sizeof(*eh); 1158 m->m_pkthdr.len += sizeof(*eh); 1159 } else { 1160 /* 1161 * Alternatively there may be room even though 1162 * it is stored somewhere else. If so, copy it in. 1163 * This only safe because we KNOW that this packet has 1164 * just been generated by an ethernet card, so there 1165 * are no aliases to the buffer. (unlike in outgoing 1166 * packets). 1167 * Nearly all ethernet cards will end up producing mbufs 1168 * that fall into these cases. So we are not optimising 1169 * contorted cases. 1170 */ 1171 1172 if (m->m_flags & M_EXT) { 1173 room = (mtod(m, caddr_t) - m->m_ext.ext_buf); 1174 if (room > m->m_ext.ext_size) /* garbage */ 1175 room = 0; /* fail immediatly */ 1176 } else { 1177 room = (mtod(m, caddr_t) - m->m_pktdat); 1178 } 1179 if (room > sizeof (*eh)) { 1180 /* we have room, just copy it and adjust */ 1181 m->m_len += sizeof(*eh); 1182 m->m_data -= sizeof(*eh); 1183 m->m_pkthdr.len += sizeof(*eh); 1184 bcopy ((caddr_t)eh, (caddr_t)eh2, sizeof(*eh)); 1185 } else { 1186 /* 1187 * Doing anything more is likely to get more 1188 * expensive than it's worth.. 1189 * it's probable that everything else is in one 1190 * big lump. The next node will do an m_pullup() 1191 * for exactly the amount of data it needs and 1192 * hopefully everything after that will not 1193 * need one. So let's just use m_prepend. 1194 */ 1195 m = m_prepend(m, MHLEN, M_DONTWAIT); 1196 if (m == NULL) 1197 return; 1198 } 1199 } 1200 ng_queue_data(LIST_FIRST(&(node->hooks)), m, NULL); 1201 } else { 1202 m_freem(m); 1203 } 1204 } 1205 1206 /* 1207 * do local shutdown processing.. 1208 * This node will refuse to go away, unless the hardware says to.. 1209 * don't unref the node, or remove our name. just clear our links up. 1210 */ 1211 static int 1212 ngether_rmnode(node_p node) 1213 { 1214 ng_cutlinks(node); 1215 node->flags &= ~NG_INVALID; /* bounce back to life */ 1216 return (0); 1217 } 1218 1219 /* already linked */ 1220 static int 1221 ngether_connect(hook_p hook) 1222 { 1223 /* be really amiable and just say "YUP that's OK by me! " */ 1224 return (0); 1225 } 1226 1227 /* 1228 * notify on hook disconnection (destruction) 1229 * 1230 * For this type, removal of the last lins no effect. The interface can run 1231 * independently. 1232 * Since we have no per-hook information, this is rather simple. 1233 */ 1234 static int 1235 ngether_disconnect(hook_p hook) 1236 { 1237 hook->node->flags &= ~NGEF_DIVERT; 1238 return (0); 1239 } 1240 #endif /* NETGRAPH */ 1241 1242 /********************************** END *************************************/ 1243