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