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 int ngether_constructor(node_p *nodep); 130 static int ngether_rcvmsg(node_p node, struct ng_mesg *msg, 131 const char *retaddr, struct ng_mesg **resp); 132 static int ngether_rmnode(node_p node); 133 static int ngether_newhook(node_p node, hook_p hook, const char *name); 134 /*static hook_p ngether_findhook(node_p node, char *name);*/ 135 static int ngether_connect(hook_p hook); /* already PARTLY linked */ 136 static int ngether_rcvdata(hook_p hook, struct mbuf *m, meta_p meta); 137 static int ngether_disconnect(hook_p hook); /* notify on disconnect */ 138 139 static struct ng_type typestruct = { 140 NG_VERSION, 141 NG_ETHER_NODE_TYPE, 142 NULL, 143 ngether_constructor, 144 ngether_rcvmsg, 145 ngether_rmnode, 146 ngether_newhook, 147 NULL, 148 ngether_connect, 149 ngether_rcvdata, 150 ngether_rcvdata, 151 ngether_disconnect 152 }; 153 154 #define AC2NG(AC) ((node_p)((AC)->ac_ng)) 155 #define NGEF_DIVERT NGF_TYPE1 /* all packets sent to netgraph */ 156 #endif /* NETGRAPH */ 157 158 /* 159 * Ethernet output routine. 160 * Encapsulate a packet of type family for the local net. 161 * Use trailer local net encapsulation if enough data in first 162 * packet leaves a multiple of 512 bytes of data in remainder. 163 * Assumes that ifp is actually pointer to arpcom structure. 164 */ 165 int 166 ether_output(ifp, m0, dst, rt0) 167 register struct ifnet *ifp; 168 struct mbuf *m0; 169 struct sockaddr *dst; 170 struct rtentry *rt0; 171 { 172 short type; 173 int s, error = 0, hdrcmplt = 0; 174 u_char esrc[6], edst[6]; 175 register struct mbuf *m = m0; 176 register struct rtentry *rt; 177 register struct ether_header *eh; 178 int off, len = m->m_pkthdr.len, loop_copy = 0; 179 int hlen; /* link layer header lenght */ 180 struct arpcom *ac = IFP2AC(ifp); 181 182 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 183 senderr(ENETDOWN); 184 rt = rt0; 185 if (rt) { 186 if ((rt->rt_flags & RTF_UP) == 0) { 187 rt0 = rt = rtalloc1(dst, 1, 0UL); 188 if (rt0) 189 rt->rt_refcnt--; 190 else 191 senderr(EHOSTUNREACH); 192 } 193 if (rt->rt_flags & RTF_GATEWAY) { 194 if (rt->rt_gwroute == 0) 195 goto lookup; 196 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { 197 rtfree(rt); rt = rt0; 198 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 199 0UL); 200 if ((rt = rt->rt_gwroute) == 0) 201 senderr(EHOSTUNREACH); 202 } 203 } 204 if (rt->rt_flags & RTF_REJECT) 205 if (rt->rt_rmx.rmx_expire == 0 || 206 time_second < rt->rt_rmx.rmx_expire) 207 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); 208 } 209 hlen = ETHER_HDR_LEN; 210 switch (dst->sa_family) { 211 #ifdef INET 212 case AF_INET: 213 if (!arpresolve(ac, rt, m, dst, edst, rt0)) 214 return (0); /* if not yet resolved */ 215 off = m->m_pkthdr.len - m->m_len; 216 type = htons(ETHERTYPE_IP); 217 break; 218 #endif 219 #ifdef IPX 220 case AF_IPX: 221 type = htons(ETHERTYPE_IPX); 222 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host), 223 (caddr_t)edst, sizeof (edst)); 224 break; 225 #endif 226 #ifdef NETATALK 227 case AF_APPLETALK: 228 { 229 struct at_ifaddr *aa; 230 231 if ((aa = at_ifawithnet((struct sockaddr_at *)dst)) == NULL) { 232 goto bad; 233 } 234 if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) 235 return (0); 236 /* 237 * In the phase 2 case, need to prepend an mbuf for the llc header. 238 * Since we must preserve the value of m, which is passed to us by 239 * value, we m_copy() the first mbuf, and use it for our llc header. 240 */ 241 if ( aa->aa_flags & AFA_PHASE2 ) { 242 struct llc llc; 243 244 M_PREPEND(m, sizeof(struct llc), M_WAIT); 245 len += sizeof(struct llc); 246 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP; 247 llc.llc_control = LLC_UI; 248 bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code)); 249 llc.llc_snap_ether_type = htons( ETHERTYPE_AT ); 250 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc)); 251 type = htons(m->m_pkthdr.len); 252 hlen = sizeof(struct llc) + ETHER_HDR_LEN; 253 } else { 254 type = htons(ETHERTYPE_AT); 255 } 256 break; 257 } 258 #endif NETATALK 259 #ifdef NS 260 case AF_NS: 261 switch(ns_nettype){ 262 default: 263 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */ 264 type = 0x8137; 265 break; 266 case 0x0: /* Novell 802.3 */ 267 type = htons( m->m_pkthdr.len); 268 break; 269 case 0xe0e0: /* Novell 802.2 and Token-Ring */ 270 M_PREPEND(m, 3, M_WAIT); 271 type = htons( m->m_pkthdr.len); 272 cp = mtod(m, u_char *); 273 *cp++ = 0xE0; 274 *cp++ = 0xE0; 275 *cp++ = 0x03; 276 break; 277 } 278 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host), 279 (caddr_t)edst, sizeof (edst)); 280 /* 281 * XXX if ns_thishost is the same as the node's ethernet 282 * address then just the default code will catch this anyhow. 283 * So I'm not sure if this next clause should be here at all? 284 * [JRE] 285 */ 286 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){ 287 m->m_pkthdr.rcvif = ifp; 288 schednetisr(NETISR_NS); 289 inq = &nsintrq; 290 s = splimp(); 291 if (IF_QFULL(inq)) { 292 IF_DROP(inq); 293 m_freem(m); 294 } else 295 IF_ENQUEUE(inq, m); 296 splx(s); 297 return (error); 298 } 299 if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){ 300 m->m_flags |= M_BCAST; 301 } 302 break; 303 #endif /* NS */ 304 #ifdef ISO 305 case AF_ISO: { 306 int snpalen; 307 struct llc *l; 308 register struct sockaddr_dl *sdl; 309 310 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) && 311 sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) { 312 bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst)); 313 } else if (error = 314 iso_snparesolve(ifp, (struct sockaddr_iso *)dst, 315 (char *)edst, &snpalen)) 316 goto bad; /* Not Resolved */ 317 /* If broadcasting on a simplex interface, loopback a copy */ 318 if (*edst & 1) 319 m->m_flags |= (M_BCAST|M_MCAST); 320 M_PREPEND(m, 3, M_DONTWAIT); 321 if (m == NULL) 322 return (0); 323 type = htons(m->m_pkthdr.len); 324 l = mtod(m, struct llc *); 325 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP; 326 l->llc_control = LLC_UI; 327 len += 3; 328 IFDEBUG(D_ETHER) 329 int i; 330 printf("unoutput: sending pkt to: "); 331 for (i=0; i<6; i++) 332 printf("%x ", edst[i] & 0xff); 333 printf("\n"); 334 ENDDEBUG 335 } break; 336 #endif /* ISO */ 337 #ifdef LLC 338 /* case AF_NSAP: */ 339 case AF_CCITT: { 340 register struct sockaddr_dl *sdl = 341 (struct sockaddr_dl *) rt -> rt_gateway; 342 343 if (sdl && sdl->sdl_family == AF_LINK 344 && sdl->sdl_alen > 0) { 345 bcopy(LLADDR(sdl), (char *)edst, sizeof(edst)); 346 } else goto bad; /* Not a link interface ? Funny ... */ 347 if (*edst & 1) 348 loop_copy = 1; 349 type = htons(m->m_pkthdr.len); 350 #ifdef LLC_DEBUG 351 { 352 int i; 353 register struct llc *l = mtod(m, struct llc *); 354 355 printf("ether_output: sending LLC2 pkt to: "); 356 for (i=0; i<6; i++) 357 printf("%x ", edst[i] & 0xff); 358 printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 359 type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff, 360 l->llc_control & 0xff); 361 362 } 363 #endif /* LLC_DEBUG */ 364 } break; 365 #endif /* LLC */ 366 367 case pseudo_AF_HDRCMPLT: 368 hdrcmplt = 1; 369 eh = (struct ether_header *)dst->sa_data; 370 (void)memcpy(esrc, eh->ether_shost, sizeof (esrc)); 371 /* FALLTHROUGH */ 372 373 case AF_UNSPEC: 374 loop_copy = -1; /* if this is for us, don't do it */ 375 eh = (struct ether_header *)dst->sa_data; 376 (void)memcpy(edst, eh->ether_dhost, sizeof (edst)); 377 type = eh->ether_type; 378 break; 379 380 default: 381 printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit, 382 dst->sa_family); 383 senderr(EAFNOSUPPORT); 384 } 385 386 /* 387 * Add local net header. If no space in first mbuf, 388 * allocate another. 389 */ 390 M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT); 391 if (m == 0) 392 senderr(ENOBUFS); 393 eh = mtod(m, struct ether_header *); 394 (void)memcpy(&eh->ether_type, &type, 395 sizeof(eh->ether_type)); 396 (void)memcpy(eh->ether_dhost, edst, sizeof (edst)); 397 if (hdrcmplt) 398 (void)memcpy(eh->ether_shost, esrc, 399 sizeof(eh->ether_shost)); 400 else 401 (void)memcpy(eh->ether_shost, ac->ac_enaddr, 402 sizeof(eh->ether_shost)); 403 404 /* 405 * If a simplex interface, and the packet is being sent to our 406 * Ethernet address or a broadcast address, loopback a copy. 407 * XXX To make a simplex device behave exactly like a duplex 408 * device, we should copy in the case of sending to our own 409 * ethernet address (thus letting the original actually appear 410 * on the wire). However, we don't do that here for security 411 * reasons and compatibility with the original behavior. 412 */ 413 if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy != -1)) { 414 if ((m->m_flags & M_BCAST) || (loop_copy > 0)) { 415 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); 416 417 (void) if_simloop(ifp, n, dst, hlen); 418 } else if (bcmp(eh->ether_dhost, 419 eh->ether_shost, ETHER_ADDR_LEN) == 0) { 420 (void) if_simloop(ifp, m, dst, hlen); 421 return (0); /* XXX */ 422 } 423 } 424 #ifdef BRIDGE 425 if (do_bridge) { 426 struct mbuf *m0 = m ; 427 428 if (m->m_pkthdr.rcvif) 429 m->m_pkthdr.rcvif = NULL ; 430 ifp = bridge_dst_lookup(m); 431 bdg_forward(&m0, ifp); 432 if (m0) 433 m_freem(m0); 434 return (0); 435 } 436 #endif 437 s = splimp(); 438 /* 439 * Queue message on interface, and start output if interface 440 * not yet active. 441 */ 442 if (IF_QFULL(&ifp->if_snd)) { 443 IF_DROP(&ifp->if_snd); 444 splx(s); 445 senderr(ENOBUFS); 446 } 447 IF_ENQUEUE(&ifp->if_snd, m); 448 if ((ifp->if_flags & IFF_OACTIVE) == 0) 449 (*ifp->if_start)(ifp); 450 splx(s); 451 ifp->if_obytes += len + sizeof (struct ether_header); 452 if (m->m_flags & M_MCAST) 453 ifp->if_omcasts++; 454 return (error); 455 456 bad: 457 if (m) 458 m_freem(m); 459 return (error); 460 } 461 462 /* 463 * Process a received Ethernet packet; 464 * the packet is in the mbuf chain m without 465 * the ether header, which is provided separately. 466 */ 467 void 468 ether_input(ifp, eh, m) 469 struct ifnet *ifp; 470 register struct ether_header *eh; 471 struct mbuf *m; 472 { 473 register struct ifqueue *inq; 474 u_short ether_type; 475 int s; 476 #if defined (ISO) || defined (LLC) || defined(NETATALK) 477 register struct llc *l; 478 #endif 479 480 if ((ifp->if_flags & IFF_UP) == 0) { 481 m_freem(m); 482 return; 483 } 484 ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh); 485 if (eh->ether_dhost[0] & 1) { 486 if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, 487 sizeof(etherbroadcastaddr)) == 0) 488 m->m_flags |= M_BCAST; 489 else 490 m->m_flags |= M_MCAST; 491 } 492 if (m->m_flags & (M_BCAST|M_MCAST)) 493 ifp->if_imcasts++; 494 495 ether_type = ntohs(eh->ether_type); 496 497 #ifdef NETGRAPH 498 { 499 struct arpcom *ac = IFP2AC(ifp); 500 if (AC2NG(ac) && (AC2NG(ac)->flags & NGEF_DIVERT)) { 501 ngether_send(ac, eh, m); 502 return; 503 } 504 } 505 #endif /* NETGRAPH */ 506 507 #if NVLAN > 0 508 if (ether_type == vlan_proto) { 509 if (vlan_input(eh, m) < 0) 510 ifp->if_data.ifi_noproto++; 511 return; 512 } 513 #endif /* NVLAN > 0 */ 514 515 switch (ether_type) { 516 #ifdef INET 517 case ETHERTYPE_IP: 518 if (ipflow_fastforward(m)) 519 return; 520 schednetisr(NETISR_IP); 521 inq = &ipintrq; 522 break; 523 524 case ETHERTYPE_ARP: 525 schednetisr(NETISR_ARP); 526 inq = &arpintrq; 527 break; 528 #endif 529 #ifdef IPX 530 case ETHERTYPE_IPX: 531 schednetisr(NETISR_IPX); 532 inq = &ipxintrq; 533 break; 534 #endif 535 #ifdef NS 536 case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */ 537 schednetisr(NETISR_NS); 538 inq = &nsintrq; 539 break; 540 541 #endif /* NS */ 542 #ifdef NETATALK 543 case ETHERTYPE_AT: 544 schednetisr(NETISR_ATALK); 545 inq = &atintrq1; 546 break; 547 case ETHERTYPE_AARP: 548 /* probably this should be done with a NETISR as well */ 549 aarpinput(IFP2AC(ifp), m); /* XXX */ 550 return; 551 #endif NETATALK 552 default: 553 #ifdef NS 554 checksum = mtod(m, ushort *); 555 /* Novell 802.3 */ 556 if ((ether_type <= ETHERMTU) && 557 ((*checksum == 0xffff) || (*checksum == 0xE0E0))){ 558 if(*checksum == 0xE0E0) { 559 m->m_pkthdr.len -= 3; 560 m->m_len -= 3; 561 m->m_data += 3; 562 } 563 schednetisr(NETISR_NS); 564 inq = &nsintrq; 565 break; 566 } 567 #endif /* NS */ 568 #if defined (ISO) || defined (LLC) || defined(NETATALK) 569 if (ether_type > ETHERMTU) 570 goto dropanyway; 571 l = mtod(m, struct llc *); 572 switch (l->llc_dsap) { 573 #ifdef NETATALK 574 case LLC_SNAP_LSAP: 575 switch (l->llc_control) { 576 case LLC_UI: 577 if (l->llc_ssap != LLC_SNAP_LSAP) 578 goto dropanyway; 579 580 if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code, 581 sizeof(at_org_code)) == 0 && 582 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) { 583 inq = &atintrq2; 584 m_adj( m, sizeof( struct llc )); 585 schednetisr(NETISR_ATALK); 586 break; 587 } 588 589 if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code, 590 sizeof(aarp_org_code)) == 0 && 591 ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) { 592 m_adj( m, sizeof( struct llc )); 593 aarpinput(IFP2AC(ifp), m); /* XXX */ 594 return; 595 } 596 597 default: 598 goto dropanyway; 599 } 600 break; 601 #endif NETATALK 602 #ifdef ISO 603 case LLC_ISO_LSAP: 604 switch (l->llc_control) { 605 case LLC_UI: 606 /* LLC_UI_P forbidden in class 1 service */ 607 if ((l->llc_dsap == LLC_ISO_LSAP) && 608 (l->llc_ssap == LLC_ISO_LSAP)) { 609 /* LSAP for ISO */ 610 if (m->m_pkthdr.len > ether_type) 611 m_adj(m, ether_type - m->m_pkthdr.len); 612 m->m_data += 3; /* XXX */ 613 m->m_len -= 3; /* XXX */ 614 m->m_pkthdr.len -= 3; /* XXX */ 615 M_PREPEND(m, sizeof *eh, M_DONTWAIT); 616 if (m == 0) 617 return; 618 *mtod(m, struct ether_header *) = *eh; 619 IFDEBUG(D_ETHER) 620 printf("clnp packet"); 621 ENDDEBUG 622 schednetisr(NETISR_ISO); 623 inq = &clnlintrq; 624 break; 625 } 626 goto dropanyway; 627 628 case LLC_XID: 629 case LLC_XID_P: 630 if(m->m_len < 6) 631 goto dropanyway; 632 l->llc_window = 0; 633 l->llc_fid = 9; 634 l->llc_class = 1; 635 l->llc_dsap = l->llc_ssap = 0; 636 /* Fall through to */ 637 case LLC_TEST: 638 case LLC_TEST_P: 639 { 640 struct sockaddr sa; 641 register struct ether_header *eh2; 642 int i; 643 u_char c = l->llc_dsap; 644 645 l->llc_dsap = l->llc_ssap; 646 l->llc_ssap = c; 647 if (m->m_flags & (M_BCAST | M_MCAST)) 648 bcopy((caddr_t)ac->ac_enaddr, 649 (caddr_t)eh->ether_dhost, 6); 650 sa.sa_family = AF_UNSPEC; 651 sa.sa_len = sizeof(sa); 652 eh2 = (struct ether_header *)sa.sa_data; 653 for (i = 0; i < 6; i++) { 654 eh2->ether_shost[i] = c = eh->ether_dhost[i]; 655 eh2->ether_dhost[i] = 656 eh->ether_dhost[i] = eh->ether_shost[i]; 657 eh->ether_shost[i] = c; 658 } 659 ifp->if_output(ifp, m, &sa, NULL); 660 return; 661 } 662 default: 663 m_freem(m); 664 return; 665 } 666 break; 667 #endif /* ISO */ 668 #ifdef LLC 669 case LLC_X25_LSAP: 670 { 671 if (m->m_pkthdr.len > ether_type) 672 m_adj(m, ether_type - m->m_pkthdr.len); 673 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT); 674 if (m == 0) 675 return; 676 if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP, 677 eh->ether_dhost, LLC_X25_LSAP, 6, 678 mtod(m, struct sdl_hdr *))) 679 panic("ETHER cons addr failure"); 680 mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type; 681 #ifdef LLC_DEBUG 682 printf("llc packet\n"); 683 #endif /* LLC_DEBUG */ 684 schednetisr(NETISR_CCITT); 685 inq = &llcintrq; 686 break; 687 } 688 #endif /* LLC */ 689 dropanyway: 690 default: 691 #ifdef NETGRAPH 692 ngether_send(IFP2AC(ifp), eh, m); 693 #else /* NETGRAPH */ 694 m_freem(m); 695 #endif /* NETGRAPH */ 696 return; 697 } 698 #else /* ISO || LLC || NETATALK */ 699 #ifdef NETGRAPH 700 ngether_send(IFP2AC(ifp), eh, m); 701 #else /* NETGRAPH */ 702 m_freem(m); 703 #endif /* NETGRAPH */ 704 return; 705 #endif /* ISO || LLC || NETATALK */ 706 } 707 708 s = splimp(); 709 if (IF_QFULL(inq)) { 710 IF_DROP(inq); 711 m_freem(m); 712 } else 713 IF_ENQUEUE(inq, m); 714 splx(s); 715 } 716 717 /* 718 * Perform common duties while attaching to interface list 719 */ 720 void 721 ether_ifattach(ifp) 722 register struct ifnet *ifp; 723 { 724 register struct ifaddr *ifa; 725 register struct sockaddr_dl *sdl; 726 727 ifp->if_type = IFT_ETHER; 728 ifp->if_addrlen = 6; 729 ifp->if_hdrlen = 14; 730 ifp->if_mtu = ETHERMTU; 731 ifp->if_resolvemulti = ether_resolvemulti; 732 if (ifp->if_baudrate == 0) 733 ifp->if_baudrate = 10000000; 734 ifa = ifnet_addrs[ifp->if_index - 1]; 735 if (ifa == 0) { 736 printf("ether_ifattach: no lladdr!\n"); 737 return; 738 } 739 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 740 sdl->sdl_type = IFT_ETHER; 741 sdl->sdl_alen = ifp->if_addrlen; 742 bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen); 743 #ifdef NETGRAPH 744 ngether_init(ifp); 745 #endif /* NETGRAPH */ 746 } 747 748 SYSCTL_DECL(_net_link); 749 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); 750 751 int 752 ether_ioctl(ifp, command, data) 753 struct ifnet *ifp; 754 int command; 755 caddr_t data; 756 { 757 struct ifaddr *ifa = (struct ifaddr *) data; 758 struct ifreq *ifr = (struct ifreq *) data; 759 int error = 0; 760 761 switch (command) { 762 case SIOCSIFADDR: 763 ifp->if_flags |= IFF_UP; 764 765 switch (ifa->ifa_addr->sa_family) { 766 #ifdef INET 767 case AF_INET: 768 ifp->if_init(ifp->if_softc); /* before arpwhohas */ 769 arp_ifinit(IFP2AC(ifp), ifa); 770 break; 771 #endif 772 #ifdef IPX 773 /* 774 * XXX - This code is probably wrong 775 */ 776 case AF_IPX: 777 { 778 register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr); 779 struct arpcom *ac = IFP2AC(ifp); 780 781 if (ipx_nullhost(*ina)) 782 ina->x_host = 783 *(union ipx_host *) 784 ac->ac_enaddr; 785 else { 786 bcopy((caddr_t) ina->x_host.c_host, 787 (caddr_t) ac->ac_enaddr, 788 sizeof(ac->ac_enaddr)); 789 } 790 791 /* 792 * Set new address 793 */ 794 ifp->if_init(ifp->if_softc); 795 break; 796 } 797 #endif 798 #ifdef NS 799 /* 800 * XXX - This code is probably wrong 801 */ 802 case AF_NS: 803 { 804 register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 805 struct arpcom *ac = IFP2AC(ifp); 806 807 if (ns_nullhost(*ina)) 808 ina->x_host = 809 *(union ns_host *) (ac->ac_enaddr); 810 else { 811 bcopy((caddr_t) ina->x_host.c_host, 812 (caddr_t) ac->ac_enaddr, 813 sizeof(ac->ac_enaddr)); 814 } 815 816 /* 817 * Set new address 818 */ 819 ifp->if_init(ifp->if_softc); 820 break; 821 } 822 #endif 823 default: 824 ifp->if_init(ifp->if_softc); 825 break; 826 } 827 break; 828 829 case SIOCGIFADDR: 830 { 831 struct sockaddr *sa; 832 833 sa = (struct sockaddr *) & ifr->ifr_data; 834 bcopy(IFP2AC(ifp)->ac_enaddr, 835 (caddr_t) sa->sa_data, ETHER_ADDR_LEN); 836 } 837 break; 838 839 case SIOCSIFMTU: 840 /* 841 * Set the interface MTU. 842 */ 843 if (ifr->ifr_mtu > ETHERMTU) { 844 error = EINVAL; 845 } else { 846 ifp->if_mtu = ifr->ifr_mtu; 847 } 848 break; 849 } 850 return (error); 851 } 852 853 int 854 ether_resolvemulti(ifp, llsa, sa) 855 struct ifnet *ifp; 856 struct sockaddr **llsa; 857 struct sockaddr *sa; 858 { 859 struct sockaddr_dl *sdl; 860 struct sockaddr_in *sin; 861 u_char *e_addr; 862 863 switch(sa->sa_family) { 864 case AF_LINK: 865 /* 866 * No mapping needed. Just check that it's a valid MC address. 867 */ 868 sdl = (struct sockaddr_dl *)sa; 869 e_addr = LLADDR(sdl); 870 if ((e_addr[0] & 1) != 1) 871 return EADDRNOTAVAIL; 872 *llsa = 0; 873 return 0; 874 875 #ifdef INET 876 case AF_INET: 877 sin = (struct sockaddr_in *)sa; 878 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 879 return EADDRNOTAVAIL; 880 MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR, 881 M_WAITOK); 882 sdl->sdl_len = sizeof *sdl; 883 sdl->sdl_family = AF_LINK; 884 sdl->sdl_index = ifp->if_index; 885 sdl->sdl_type = IFT_ETHER; 886 sdl->sdl_nlen = 0; 887 sdl->sdl_alen = ETHER_ADDR_LEN; 888 sdl->sdl_slen = 0; 889 e_addr = LLADDR(sdl); 890 ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr); 891 *llsa = (struct sockaddr *)sdl; 892 return 0; 893 #endif 894 895 default: 896 /* 897 * Well, the text isn't quite right, but it's the name 898 * that counts... 899 */ 900 return EAFNOSUPPORT; 901 } 902 } 903 904 #ifdef NETGRAPH 905 906 /*********************************************************************** 907 * This section contains the methods for the Netgraph interface 908 ***********************************************************************/ 909 /* It's Ascii-art time! 910 * The ifnet is the first part of the arpcom which must be 911 * the first part of the device's softc.. yuk. 912 * 913 * +--------------------------+-----+---------+ 914 * | struct ifnet (*ifp) | | | 915 * | | | | 916 * +--------------------------+ | | 917 * +--|[ac_ng] struct arpcom (*ac) | | 918 * | +--------------------------------+ | 919 * | | struct softc (*ifp->if_softc) (device) | 920 * | +------------------------------------------+ 921 * | ^ 922 * AC2NG() | 923 * | v 924 * | +----------------------+ 925 * | | [private] [flags] | 926 * +------>| struct ng_node | 927 * | [hooks] | ** we only allow one hook 928 * +----------------------+ 929 * ^ 930 * | 931 * v 932 * +-------------+ 933 * | [node] | 934 * | hook | 935 * | [private]|-- *unused* 936 * +-------------+ 937 */ 938 939 /* 940 * called during interface attaching 941 */ 942 static void 943 ngether_init(void *ifpvoid) 944 { 945 struct ifnet *ifp = ifpvoid; 946 struct arpcom *ac = IFP2AC(ifp); 947 static int ngether_done_init; 948 char namebuf[32]; 949 node_p node; 950 951 /* 952 * we have found a node, make sure our 'type' is availabe. 953 */ 954 if (ngether_done_init == 0) { 955 if (ng_newtype(&typestruct)) { 956 printf("ngether install failed\n"); 957 return; 958 } 959 ngether_done_init = 1; 960 } 961 if (ng_make_node_common(&typestruct, &node) != 0) 962 return; 963 ac->ac_ng = node; 964 node->private = ifp; 965 sprintf(namebuf, "%s%d", ifp->if_name, ifp->if_unit); 966 ng_name_node(AC2NG(ac), namebuf); 967 } 968 969 /* 970 * It is not possible or allowable to create a node of this type. 971 * If the hardware exists, it will already have created it. 972 */ 973 static int 974 ngether_constructor(node_p *nodep) 975 { 976 return (EINVAL); 977 } 978 979 /* 980 * Give our ok for a hook to be added... 981 * 982 * Allow one hook at a time (rawdata). 983 * It can eiteh rdivert everything or only unclaimed packets. 984 */ 985 static int 986 ngether_newhook(node_p node, hook_p hook, const char *name) 987 { 988 989 /* check if there is already a hook */ 990 if (LIST_FIRST(&(node->hooks))) 991 return(EISCONN); 992 /* 993 * Check for which mode hook we want. 994 */ 995 if (strcmp(name, NG_ETHER_HOOK_ORPHAN) != 0) { 996 if (strcmp(name, NG_ETHER_HOOK_DIVERT) != 0) { 997 return (EINVAL); 998 } 999 node->flags |= NGEF_DIVERT; 1000 } else { 1001 node->flags &= ~NGEF_DIVERT; 1002 } 1003 return (0); 1004 } 1005 1006 /* 1007 * incoming messages. 1008 * Just respond to the generic TEXT_STATUS message 1009 */ 1010 static int 1011 ngether_rcvmsg(node_p node, 1012 struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp) 1013 { 1014 struct ifnet *ifp; 1015 int error = 0; 1016 1017 ifp = node->private; 1018 switch (msg->header.typecookie) { 1019 case NGM_ETHER_COOKIE: 1020 error = EINVAL; 1021 break; 1022 case NGM_GENERIC_COOKIE: 1023 switch(msg->header.cmd) { 1024 case NGM_TEXT_STATUS: { 1025 char *arg; 1026 int pos = 0; 1027 int resplen = sizeof(struct ng_mesg) + 512; 1028 MALLOC(*resp, struct ng_mesg *, resplen, 1029 M_NETGRAPH, M_NOWAIT); 1030 if (*resp == NULL) { 1031 error = ENOMEM; 1032 break; 1033 } 1034 bzero(*resp, resplen); 1035 arg = (*resp)->data; 1036 1037 /* 1038 * Put in the throughput information. 1039 */ 1040 pos = sprintf(arg, "%ld bytes in, %ld bytes out\n", 1041 ifp->if_ibytes, ifp->if_obytes); 1042 pos += sprintf(arg + pos, 1043 "%ld output errors\n", 1044 ifp->if_oerrors); 1045 pos += sprintf(arg + pos, 1046 "ierrors = %ld\n", 1047 ifp->if_ierrors); 1048 1049 (*resp)->header.version = NG_VERSION; 1050 (*resp)->header.arglen = strlen(arg) + 1; 1051 (*resp)->header.token = msg->header.token; 1052 (*resp)->header.typecookie = NGM_ETHER_COOKIE; 1053 (*resp)->header.cmd = msg->header.cmd; 1054 strncpy((*resp)->header.cmdstr, "status", 1055 NG_CMDSTRLEN); 1056 } 1057 break; 1058 default: 1059 error = EINVAL; 1060 break; 1061 } 1062 break; 1063 default: 1064 error = EINVAL; 1065 break; 1066 } 1067 free(msg, M_NETGRAPH); 1068 return (error); 1069 } 1070 1071 /* 1072 * Receive a completed ethernet packet. 1073 * Queue it for output. 1074 */ 1075 static int 1076 ngether_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) 1077 { 1078 struct ifnet *ifp; 1079 int error = 0; 1080 int s; 1081 struct ether_header *eh; 1082 1083 ifp = hook->node->private; 1084 1085 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 1086 senderr(ENETDOWN); 1087 /* 1088 * If a simplex interface, and the packet is being sent to our 1089 * Ethernet address or a broadcast address, loopback a copy. 1090 * XXX To make a simplex device behave exactly like a duplex 1091 * device, we should copy in the case of sending to our own 1092 * ethernet address (thus letting the original actually appear 1093 * on the wire). However, we don't do that here for security 1094 * reasons and compatibility with the original behavior. 1095 */ 1096 if (ifp->if_flags & IFF_SIMPLEX) { 1097 eh = mtod(m, struct ether_header *); 1098 if (m->m_flags & M_BCAST) { 1099 struct mbuf *n = m_copy(m, 0, (int)M_COPYALL); 1100 1101 ng_queue_data(hook, n, meta); 1102 } else if (bcmp(eh->ether_dhost, 1103 eh->ether_shost, ETHER_ADDR_LEN) == 0) { 1104 ng_queue_data(hook, m, meta); 1105 return (0); /* XXX */ 1106 } 1107 } 1108 s = splimp(); 1109 /* 1110 * Queue message on interface, and start output if interface 1111 * not yet active. 1112 * XXX if we lookead at the priority in the meta data we could 1113 * queue high priority items at the head. 1114 */ 1115 if (IF_QFULL(&ifp->if_snd)) { 1116 IF_DROP(&ifp->if_snd); 1117 splx(s); 1118 senderr(ENOBUFS); 1119 } 1120 IF_ENQUEUE(&ifp->if_snd, m); 1121 if ((ifp->if_flags & IFF_OACTIVE) == 0) 1122 (*ifp->if_start)(ifp); 1123 splx(s); 1124 ifp->if_obytes += m->m_pkthdr.len; 1125 if (m->m_flags & M_MCAST) 1126 ifp->if_omcasts++; 1127 return (error); 1128 1129 bad: 1130 NG_FREE_DATA(m, meta); 1131 return (error); 1132 } 1133 1134 /* 1135 * pass an mbuf out to the connected hook 1136 */ 1137 static void 1138 ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m) 1139 { 1140 node_p node = AC2NG(ac); 1141 struct ether_header *eh2; 1142 1143 if (node && LIST_FIRST(&(node->hooks))) { 1144 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); 1145 if (m == 0) 1146 return; 1147 eh2 = mtod(m, struct ether_header *); 1148 /* 1149 * Possibly 'eh' already points 1150 * to the right place. 1151 */ 1152 if (eh2 != eh) 1153 bcopy(eh, eh2, sizeof(*eh)); 1154 ng_queue_data(LIST_FIRST(&(node->hooks)), m, NULL); 1155 } else { 1156 m_freem(m); 1157 } 1158 } 1159 /* 1160 * do local shutdown processing.. 1161 * This node will refuse to go away, unless the hardware says to.. 1162 * don't unref the node, or remove our name. just clear our links up. 1163 */ 1164 static int 1165 ngether_rmnode(node_p node) 1166 { 1167 ng_cutlinks(node); 1168 node->flags &= ~NG_INVALID; /* bounce back to life */ 1169 return (0); 1170 } 1171 1172 /* already linked */ 1173 static int 1174 ngether_connect(hook_p hook) 1175 { 1176 /* be really amiable and just say "YUP that's OK by me! " */ 1177 return (0); 1178 } 1179 1180 /* 1181 * notify on hook disconnection (destruction) 1182 * 1183 * For this type, removal of the last lins no effect. The interface can run 1184 * independently. 1185 * Since we have no per-hook information, this is rather simple. 1186 */ 1187 static int 1188 ngether_disconnect(hook_p hook) 1189 { 1190 hook->node->flags &= ~NGEF_DIVERT; 1191 return (0); 1192 } 1193 #endif /* NETGRAPH */ 1194 1195 /********************************** END *************************************/ 1196