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