1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2004 Doug Rabson 5 * Copyright (c) 1982, 1989, 1993 6 * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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 #include "opt_inet.h" 34 #include "opt_inet6.h" 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/module.h> 42 #include <sys/socket.h> 43 #include <sys/sockio.h> 44 45 #include <net/if.h> 46 #include <net/if_var.h> 47 #include <net/if_private.h> 48 #include <net/netisr.h> 49 #include <net/route.h> 50 #include <net/if_llc.h> 51 #include <net/if_dl.h> 52 #include <net/if_types.h> 53 #include <net/bpf.h> 54 #include <net/firewire.h> 55 #include <net/if_llatbl.h> 56 57 #if defined(INET) || defined(INET6) 58 #include <netinet/in.h> 59 #include <netinet/in_var.h> 60 #include <netinet/if_ether.h> 61 #endif 62 #ifdef INET6 63 #include <netinet6/nd6.h> 64 #endif 65 66 #include <security/mac/mac_framework.h> 67 68 static MALLOC_DEFINE(M_FWCOM, "fw_com", "firewire interface internals"); 69 70 struct fw_hwaddr firewire_broadcastaddr = { 71 0xffffffff, 72 0xffffffff, 73 0xff, 74 0xff, 75 0xffff, 76 0xffffffff 77 }; 78 79 static int 80 firewire_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 81 struct route *ro) 82 { 83 struct fw_com *fc = IFP2FWC(ifp); 84 int error, type; 85 struct m_tag *mtag; 86 union fw_encap *enc; 87 struct fw_hwaddr *destfw; 88 uint8_t speed; 89 uint16_t psize, fsize, dsize; 90 struct mbuf *mtail; 91 int unicast, dgl, foff; 92 static int next_dgl; 93 #if defined(INET) || defined(INET6) 94 int is_gw = 0; 95 #endif 96 int af = RO_GET_FAMILY(ro, dst); 97 98 #ifdef MAC 99 error = mac_ifnet_check_transmit(ifp, m); 100 if (error) 101 goto bad; 102 #endif 103 104 if (!((ifp->if_flags & IFF_UP) && 105 (ifp->if_drv_flags & IFF_DRV_RUNNING))) { 106 error = ENETDOWN; 107 goto bad; 108 } 109 110 #if defined(INET) || defined(INET6) 111 if (ro != NULL) 112 is_gw = (ro->ro_flags & RT_HAS_GW) != 0; 113 #endif 114 /* 115 * For unicast, we make a tag to store the lladdr of the 116 * destination. This might not be the first time we have seen 117 * the packet (for instance, the arp code might be trying to 118 * re-send it after receiving an arp reply) so we only 119 * allocate a tag if there isn't one there already. For 120 * multicast, we will eventually use a different tag to store 121 * the channel number. 122 */ 123 unicast = !(m->m_flags & (M_BCAST | M_MCAST)); 124 if (unicast) { 125 mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, NULL); 126 if (!mtag) { 127 mtag = m_tag_alloc(MTAG_FIREWIRE, MTAG_FIREWIRE_HWADDR, 128 sizeof (struct fw_hwaddr), M_NOWAIT); 129 if (!mtag) { 130 error = ENOMEM; 131 goto bad; 132 } 133 m_tag_prepend(m, mtag); 134 } 135 destfw = (struct fw_hwaddr *)(mtag + 1); 136 } else { 137 destfw = NULL; 138 } 139 140 switch (af) { 141 #ifdef INET 142 case AF_INET: 143 type = ETHERTYPE_IP; 144 break; 145 case AF_ARP: 146 type = ETHERTYPE_ARP; 147 break; 148 #endif 149 #ifdef INET6 150 case AF_INET6: 151 type = ETHERTYPE_IPV6; 152 break; 153 #endif 154 default: 155 if_printf(ifp, "can't handle af%d\n", af); 156 error = EAFNOSUPPORT; 157 goto bad; 158 } 159 160 switch (dst->sa_family) { 161 #ifdef INET 162 case AF_INET: 163 /* 164 * Only bother with arp for unicast. Allocation of 165 * channels etc. for firewire is quite different and 166 * doesn't fit into the arp model. 167 */ 168 if (unicast) { 169 error = arpresolve(ifp, is_gw, m, dst, 170 (u_char *) destfw, NULL, NULL); 171 if (error) 172 return (error == EWOULDBLOCK ? 0 : error); 173 } 174 break; 175 176 case AF_ARP: 177 { 178 struct arphdr *ah; 179 ah = mtod(m, struct arphdr *); 180 ah->ar_hrd = htons(ARPHRD_IEEE1394); 181 if (unicast) 182 *destfw = *(struct fw_hwaddr *) ar_tha(ah); 183 184 /* 185 * The standard arp code leaves a hole for the target 186 * hardware address which we need to close up. 187 */ 188 bcopy(ar_tpa(ah), ar_tha(ah), ah->ar_pln); 189 m_adj(m, -ah->ar_hln); 190 break; 191 } 192 #endif 193 194 #ifdef INET6 195 case AF_INET6: 196 if (unicast) { 197 error = nd6_resolve(fc->fc_ifp, LLE_SF(af, is_gw), m, 198 dst, (u_char *) destfw, NULL, NULL); 199 if (error) 200 return (error == EWOULDBLOCK ? 0 : error); 201 } 202 break; 203 #endif 204 205 default: 206 if_printf(ifp, "can't handle af%d\n", dst->sa_family); 207 error = EAFNOSUPPORT; 208 goto bad; 209 } 210 211 /* 212 * Let BPF tap off a copy before we encapsulate. 213 */ 214 if (bpf_peers_present(ifp->if_bpf)) { 215 struct fw_bpfhdr h; 216 if (unicast) 217 bcopy(destfw, h.firewire_dhost, 8); 218 else 219 bcopy(&firewire_broadcastaddr, h.firewire_dhost, 8); 220 bcopy(&fc->fc_hwaddr, h.firewire_shost, 8); 221 h.firewire_type = htons(type); 222 bpf_mtap2(ifp->if_bpf, &h, sizeof(h), m); 223 } 224 225 /* 226 * Punt on MCAP for now and send all multicast packets on the 227 * broadcast channel. 228 */ 229 if (m->m_flags & M_MCAST) 230 m->m_flags |= M_BCAST; 231 232 /* 233 * Figure out what speed to use and what the largest supported 234 * packet size is. For unicast, this is the minimum of what we 235 * can speak and what they can hear. For broadcast, lets be 236 * conservative and use S100. We could possibly improve that 237 * by examining the bus manager's speed map or similar. We 238 * also reduce the packet size for broadcast to account for 239 * the GASP header. 240 */ 241 if (unicast) { 242 speed = min(fc->fc_speed, destfw->sspd); 243 psize = min(512 << speed, 2 << destfw->sender_max_rec); 244 } else { 245 speed = 0; 246 psize = 512 - 2*sizeof(uint32_t); 247 } 248 249 /* 250 * Next, we encapsulate, possibly fragmenting the original 251 * datagram if it won't fit into a single packet. 252 */ 253 if (m->m_pkthdr.len <= psize - sizeof(uint32_t)) { 254 /* 255 * No fragmentation is necessary. 256 */ 257 M_PREPEND(m, sizeof(uint32_t), M_NOWAIT); 258 if (!m) { 259 error = ENOBUFS; 260 goto bad; 261 } 262 enc = mtod(m, union fw_encap *); 263 enc->unfrag.ether_type = type; 264 enc->unfrag.lf = FW_ENCAP_UNFRAG; 265 enc->unfrag.reserved = 0; 266 267 /* 268 * Byte swap the encapsulation header manually. 269 */ 270 enc->ul[0] = htonl(enc->ul[0]); 271 272 error = (ifp->if_transmit)(ifp, m); 273 return (error); 274 } else { 275 /* 276 * Fragment the datagram, making sure to leave enough 277 * space for the encapsulation header in each packet. 278 */ 279 fsize = psize - 2*sizeof(uint32_t); 280 dgl = next_dgl++; 281 dsize = m->m_pkthdr.len; 282 foff = 0; 283 while (m) { 284 if (m->m_pkthdr.len > fsize) { 285 /* 286 * Split off the tail segment from the 287 * datagram, copying our tags over. 288 */ 289 mtail = m_split(m, fsize, M_NOWAIT); 290 m_tag_copy_chain(mtail, m, M_NOWAIT); 291 } else { 292 mtail = NULL; 293 } 294 295 /* 296 * Add our encapsulation header to this 297 * fragment and hand it off to the link. 298 */ 299 M_PREPEND(m, 2*sizeof(uint32_t), M_NOWAIT); 300 if (!m) { 301 error = ENOBUFS; 302 goto bad; 303 } 304 enc = mtod(m, union fw_encap *); 305 if (foff == 0) { 306 enc->firstfrag.lf = FW_ENCAP_FIRST; 307 enc->firstfrag.reserved1 = 0; 308 enc->firstfrag.reserved2 = 0; 309 enc->firstfrag.datagram_size = dsize - 1; 310 enc->firstfrag.ether_type = type; 311 enc->firstfrag.dgl = dgl; 312 } else { 313 if (mtail) 314 enc->nextfrag.lf = FW_ENCAP_NEXT; 315 else 316 enc->nextfrag.lf = FW_ENCAP_LAST; 317 enc->nextfrag.reserved1 = 0; 318 enc->nextfrag.reserved2 = 0; 319 enc->nextfrag.reserved3 = 0; 320 enc->nextfrag.datagram_size = dsize - 1; 321 enc->nextfrag.fragment_offset = foff; 322 enc->nextfrag.dgl = dgl; 323 } 324 foff += m->m_pkthdr.len - 2*sizeof(uint32_t); 325 326 /* 327 * Byte swap the encapsulation header manually. 328 */ 329 enc->ul[0] = htonl(enc->ul[0]); 330 enc->ul[1] = htonl(enc->ul[1]); 331 332 error = (ifp->if_transmit)(ifp, m); 333 if (error) { 334 if (mtail) 335 m_freem(mtail); 336 return (ENOBUFS); 337 } 338 339 m = mtail; 340 } 341 342 return (0); 343 } 344 345 bad: 346 if (m) 347 m_freem(m); 348 return (error); 349 } 350 351 static struct mbuf * 352 firewire_input_fragment(struct fw_com *fc, struct mbuf *m, int src) 353 { 354 union fw_encap *enc; 355 struct fw_reass *r; 356 struct mbuf *mf, *mprev; 357 int dsize; 358 int fstart, fend, start, end, islast; 359 uint32_t id; 360 361 /* 362 * Find an existing reassembly buffer or create a new one. 363 */ 364 enc = mtod(m, union fw_encap *); 365 id = enc->firstfrag.dgl | (src << 16); 366 STAILQ_FOREACH(r, &fc->fc_frags, fr_link) 367 if (r->fr_id == id) 368 break; 369 if (!r) { 370 r = malloc(sizeof(struct fw_reass), M_TEMP, M_NOWAIT); 371 if (!r) { 372 m_freem(m); 373 return 0; 374 } 375 r->fr_id = id; 376 r->fr_frags = 0; 377 STAILQ_INSERT_HEAD(&fc->fc_frags, r, fr_link); 378 } 379 380 /* 381 * If this fragment overlaps any other fragment, we must discard 382 * the partial reassembly and start again. 383 */ 384 if (enc->firstfrag.lf == FW_ENCAP_FIRST) 385 fstart = 0; 386 else 387 fstart = enc->nextfrag.fragment_offset; 388 fend = fstart + m->m_pkthdr.len - 2*sizeof(uint32_t); 389 dsize = enc->nextfrag.datagram_size; 390 islast = (enc->nextfrag.lf == FW_ENCAP_LAST); 391 392 for (mf = r->fr_frags; mf; mf = mf->m_nextpkt) { 393 enc = mtod(mf, union fw_encap *); 394 if (enc->nextfrag.datagram_size != dsize) { 395 /* 396 * This fragment must be from a different 397 * packet. 398 */ 399 goto bad; 400 } 401 if (enc->firstfrag.lf == FW_ENCAP_FIRST) 402 start = 0; 403 else 404 start = enc->nextfrag.fragment_offset; 405 end = start + mf->m_pkthdr.len - 2*sizeof(uint32_t); 406 if ((fstart < end && fend > start) || 407 (islast && enc->nextfrag.lf == FW_ENCAP_LAST)) { 408 /* 409 * Overlap - discard reassembly buffer and start 410 * again with this fragment. 411 */ 412 goto bad; 413 } 414 } 415 416 /* 417 * Find where to put this fragment in the list. 418 */ 419 for (mf = r->fr_frags, mprev = NULL; mf; 420 mprev = mf, mf = mf->m_nextpkt) { 421 enc = mtod(mf, union fw_encap *); 422 if (enc->firstfrag.lf == FW_ENCAP_FIRST) 423 start = 0; 424 else 425 start = enc->nextfrag.fragment_offset; 426 if (start >= fend) 427 break; 428 } 429 430 /* 431 * If this is a last fragment and we are not adding at the end 432 * of the list, discard the buffer. 433 */ 434 if (islast && mprev && mprev->m_nextpkt) 435 goto bad; 436 437 if (mprev) { 438 m->m_nextpkt = mprev->m_nextpkt; 439 mprev->m_nextpkt = m; 440 441 /* 442 * Coalesce forwards and see if we can make a whole 443 * datagram. 444 */ 445 enc = mtod(mprev, union fw_encap *); 446 if (enc->firstfrag.lf == FW_ENCAP_FIRST) 447 start = 0; 448 else 449 start = enc->nextfrag.fragment_offset; 450 end = start + mprev->m_pkthdr.len - 2*sizeof(uint32_t); 451 while (end == fstart) { 452 /* 453 * Strip off the encap header from m and 454 * append it to mprev, freeing m. 455 */ 456 m_adj(m, 2*sizeof(uint32_t)); 457 mprev->m_nextpkt = m->m_nextpkt; 458 mprev->m_pkthdr.len += m->m_pkthdr.len; 459 m_cat(mprev, m); 460 461 if (mprev->m_pkthdr.len == dsize + 1 + 2*sizeof(uint32_t)) { 462 /* 463 * We have assembled a complete packet 464 * we must be finished. Make sure we have 465 * merged the whole chain. 466 */ 467 STAILQ_REMOVE(&fc->fc_frags, r, fw_reass, fr_link); 468 free(r, M_TEMP); 469 m = mprev->m_nextpkt; 470 while (m) { 471 mf = m->m_nextpkt; 472 m_freem(m); 473 m = mf; 474 } 475 mprev->m_nextpkt = NULL; 476 477 return (mprev); 478 } 479 480 /* 481 * See if we can continue merging forwards. 482 */ 483 end = fend; 484 m = mprev->m_nextpkt; 485 if (m) { 486 enc = mtod(m, union fw_encap *); 487 if (enc->firstfrag.lf == FW_ENCAP_FIRST) 488 fstart = 0; 489 else 490 fstart = enc->nextfrag.fragment_offset; 491 fend = fstart + m->m_pkthdr.len 492 - 2*sizeof(uint32_t); 493 } else { 494 break; 495 } 496 } 497 } else { 498 m->m_nextpkt = 0; 499 r->fr_frags = m; 500 } 501 502 return (0); 503 504 bad: 505 while (r->fr_frags) { 506 mf = r->fr_frags; 507 r->fr_frags = mf->m_nextpkt; 508 m_freem(mf); 509 } 510 m->m_nextpkt = 0; 511 r->fr_frags = m; 512 513 return (0); 514 } 515 516 void 517 firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src) 518 { 519 struct fw_com *fc = IFP2FWC(ifp); 520 union fw_encap *enc; 521 int type, isr; 522 523 /* 524 * The caller has already stripped off the packet header 525 * (stream or wreqb) and marked the mbuf's M_BCAST flag 526 * appropriately. We de-encapsulate the IP packet and pass it 527 * up the line after handling link-level fragmentation. 528 */ 529 if (m->m_pkthdr.len < sizeof(uint32_t)) { 530 if_printf(ifp, "discarding frame without " 531 "encapsulation header (len %u pkt len %u)\n", 532 m->m_len, m->m_pkthdr.len); 533 } 534 535 m = m_pullup(m, sizeof(uint32_t)); 536 if (m == NULL) 537 return; 538 enc = mtod(m, union fw_encap *); 539 540 /* 541 * Byte swap the encapsulation header manually. 542 */ 543 enc->ul[0] = ntohl(enc->ul[0]); 544 545 if (enc->unfrag.lf != 0) { 546 m = m_pullup(m, 2*sizeof(uint32_t)); 547 if (!m) 548 return; 549 enc = mtod(m, union fw_encap *); 550 enc->ul[1] = ntohl(enc->ul[1]); 551 m = firewire_input_fragment(fc, m, src); 552 if (!m) 553 return; 554 enc = mtod(m, union fw_encap *); 555 type = enc->firstfrag.ether_type; 556 m_adj(m, 2*sizeof(uint32_t)); 557 } else { 558 type = enc->unfrag.ether_type; 559 m_adj(m, sizeof(uint32_t)); 560 } 561 562 if (m->m_pkthdr.rcvif == NULL) { 563 if_printf(ifp, "discard frame w/o interface pointer\n"); 564 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 565 m_freem(m); 566 return; 567 } 568 #ifdef DIAGNOSTIC 569 if (m->m_pkthdr.rcvif != ifp) { 570 if_printf(ifp, "Warning, frame marked as received on %s\n", 571 m->m_pkthdr.rcvif->if_xname); 572 } 573 #endif 574 575 #ifdef MAC 576 /* 577 * Tag the mbuf with an appropriate MAC label before any other 578 * consumers can get to it. 579 */ 580 mac_ifnet_create_mbuf(ifp, m); 581 #endif 582 583 /* 584 * Give bpf a chance at the packet. The link-level driver 585 * should have left us a tag with the EUID of the sender. 586 */ 587 if (bpf_peers_present(ifp->if_bpf)) { 588 struct fw_bpfhdr h; 589 struct m_tag *mtag; 590 591 mtag = m_tag_locate(m, MTAG_FIREWIRE, MTAG_FIREWIRE_SENDER_EUID, 0); 592 if (mtag) 593 bcopy(mtag + 1, h.firewire_shost, 8); 594 else 595 bcopy(&firewire_broadcastaddr, h.firewire_dhost, 8); 596 bcopy(&fc->fc_hwaddr, h.firewire_dhost, 8); 597 h.firewire_type = htons(type); 598 bpf_mtap2(ifp->if_bpf, &h, sizeof(h), m); 599 } 600 601 if (ifp->if_flags & IFF_MONITOR) { 602 /* 603 * Interface marked for monitoring; discard packet. 604 */ 605 m_freem(m); 606 return; 607 } 608 609 if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); 610 611 /* Discard packet if interface is not up */ 612 if ((ifp->if_flags & IFF_UP) == 0) { 613 m_freem(m); 614 return; 615 } 616 617 if (m->m_flags & (M_BCAST|M_MCAST)) 618 if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1); 619 620 switch (type) { 621 #ifdef INET 622 case ETHERTYPE_IP: 623 isr = NETISR_IP; 624 break; 625 626 case ETHERTYPE_ARP: 627 { 628 struct arphdr *ah; 629 ah = mtod(m, struct arphdr *); 630 631 /* 632 * Adjust the arp packet to insert an empty tha slot. 633 */ 634 m->m_len += ah->ar_hln; 635 m->m_pkthdr.len += ah->ar_hln; 636 bcopy(ar_tha(ah), ar_tpa(ah), ah->ar_pln); 637 isr = NETISR_ARP; 638 break; 639 } 640 #endif 641 642 #ifdef INET6 643 case ETHERTYPE_IPV6: 644 isr = NETISR_IPV6; 645 break; 646 #endif 647 648 default: 649 m_freem(m); 650 return; 651 } 652 653 M_SETFIB(m, ifp->if_fib); 654 CURVNET_SET_QUIET(ifp->if_vnet); 655 netisr_dispatch(isr, m); 656 CURVNET_RESTORE(); 657 } 658 659 int 660 firewire_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 661 { 662 struct ifaddr *ifa = (struct ifaddr *) data; 663 struct ifreq *ifr = (struct ifreq *) data; 664 int error = 0; 665 666 switch (command) { 667 case SIOCSIFADDR: 668 ifp->if_flags |= IFF_UP; 669 670 switch (ifa->ifa_addr->sa_family) { 671 #ifdef INET 672 case AF_INET: 673 ifp->if_init(ifp->if_softc); /* before arpwhohas */ 674 arp_ifinit(ifp, ifa); 675 break; 676 #endif 677 default: 678 ifp->if_init(ifp->if_softc); 679 break; 680 } 681 break; 682 683 case SIOCGIFADDR: 684 bcopy(&IFP2FWC(ifp)->fc_hwaddr, &ifr->ifr_addr.sa_data[0], 685 sizeof(struct fw_hwaddr)); 686 break; 687 688 case SIOCSIFMTU: 689 /* 690 * Set the interface MTU. 691 */ 692 if (ifr->ifr_mtu > 1500) { 693 error = EINVAL; 694 } else { 695 ifp->if_mtu = ifr->ifr_mtu; 696 } 697 break; 698 default: 699 error = EINVAL; /* XXX netbsd has ENOTTY??? */ 700 break; 701 } 702 return (error); 703 } 704 705 static int 706 firewire_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa, 707 struct sockaddr *sa) 708 { 709 #ifdef INET 710 struct sockaddr_in *sin; 711 #endif 712 #ifdef INET6 713 struct sockaddr_in6 *sin6; 714 #endif 715 716 switch(sa->sa_family) { 717 case AF_LINK: 718 /* 719 * No mapping needed. 720 */ 721 *llsa = NULL; 722 return 0; 723 724 #ifdef INET 725 case AF_INET: 726 sin = (struct sockaddr_in *)sa; 727 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 728 return EADDRNOTAVAIL; 729 *llsa = NULL; 730 return 0; 731 #endif 732 #ifdef INET6 733 case AF_INET6: 734 sin6 = (struct sockaddr_in6 *)sa; 735 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 736 /* 737 * An IP6 address of 0 means listen to all 738 * of the Ethernet multicast address used for IP6. 739 * (This is used for multicast routers.) 740 */ 741 ifp->if_flags |= IFF_ALLMULTI; 742 *llsa = NULL; 743 return 0; 744 } 745 if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 746 return EADDRNOTAVAIL; 747 *llsa = NULL; 748 return 0; 749 #endif 750 751 default: 752 /* 753 * Well, the text isn't quite right, but it's the name 754 * that counts... 755 */ 756 return EAFNOSUPPORT; 757 } 758 } 759 760 void 761 firewire_ifattach(struct ifnet *ifp, struct fw_hwaddr *llc) 762 { 763 struct fw_com *fc = IFP2FWC(ifp); 764 struct ifaddr *ifa; 765 struct sockaddr_dl *sdl; 766 static const char* speeds[] = { 767 "S100", "S200", "S400", "S800", 768 "S1600", "S3200" 769 }; 770 771 fc->fc_speed = llc->sspd; 772 STAILQ_INIT(&fc->fc_frags); 773 774 ifp->if_addrlen = sizeof(struct fw_hwaddr); 775 ifp->if_hdrlen = 0; 776 if_attach(ifp); 777 ifp->if_mtu = 1500; /* XXX */ 778 ifp->if_output = firewire_output; 779 ifp->if_resolvemulti = firewire_resolvemulti; 780 ifp->if_broadcastaddr = (u_char *) &firewire_broadcastaddr; 781 782 ifa = ifp->if_addr; 783 KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); 784 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 785 sdl->sdl_type = IFT_IEEE1394; 786 sdl->sdl_alen = ifp->if_addrlen; 787 bcopy(llc, LLADDR(sdl), ifp->if_addrlen); 788 789 bpfattach(ifp, DLT_APPLE_IP_OVER_IEEE1394, 790 sizeof(struct fw_hwaddr)); 791 792 if_printf(ifp, "Firewire address: %8D @ 0x%04x%08x, %s, maxrec %d\n", 793 (uint8_t *) &llc->sender_unique_ID_hi, ":", 794 ntohs(llc->sender_unicast_FIFO_hi), 795 ntohl(llc->sender_unicast_FIFO_lo), 796 speeds[llc->sspd], 797 (2 << llc->sender_max_rec)); 798 } 799 800 void 801 firewire_ifdetach(struct ifnet *ifp) 802 { 803 bpfdetach(ifp); 804 if_detach(ifp); 805 NET_EPOCH_DRAIN_CALLBACKS(); 806 } 807 808 void 809 firewire_busreset(struct ifnet *ifp) 810 { 811 struct fw_com *fc = IFP2FWC(ifp); 812 struct fw_reass *r; 813 struct mbuf *m; 814 815 /* 816 * Discard any partial datagrams since the host ids may have changed. 817 */ 818 while ((r = STAILQ_FIRST(&fc->fc_frags))) { 819 STAILQ_REMOVE_HEAD(&fc->fc_frags, fr_link); 820 while (r->fr_frags) { 821 m = r->fr_frags; 822 r->fr_frags = m->m_nextpkt; 823 m_freem(m); 824 } 825 free(r, M_TEMP); 826 } 827 } 828 829 static void * 830 firewire_alloc(u_char type, struct ifnet *ifp) 831 { 832 struct fw_com *fc; 833 834 fc = malloc(sizeof(struct fw_com), M_FWCOM, M_WAITOK | M_ZERO); 835 fc->fc_ifp = ifp; 836 837 return (fc); 838 } 839 840 static void 841 firewire_free(void *com, u_char type) 842 { 843 844 free(com, M_FWCOM); 845 } 846 847 static int 848 firewire_modevent(module_t mod, int type, void *data) 849 { 850 851 switch (type) { 852 case MOD_LOAD: 853 if_register_com_alloc(IFT_IEEE1394, 854 firewire_alloc, firewire_free); 855 break; 856 case MOD_UNLOAD: 857 if_deregister_com_alloc(IFT_IEEE1394); 858 break; 859 default: 860 return (EOPNOTSUPP); 861 } 862 863 return (0); 864 } 865 866 static moduledata_t firewire_mod = { 867 "if_firewire", 868 firewire_modevent, 869 0 870 }; 871 872 DECLARE_MODULE(if_firewire, firewire_mod, SI_SUB_INIT_IF, SI_ORDER_ANY); 873 MODULE_VERSION(if_firewire, 1); 874