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