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 if ((m = ip_fastforward(m)) == NULL) 609 return; 610 isr = NETISR_IP; 611 break; 612 613 case ETHERTYPE_ARP: 614 { 615 struct arphdr *ah; 616 ah = mtod(m, struct arphdr *); 617 618 /* 619 * Adjust the arp packet to insert an empty tha slot. 620 */ 621 m->m_len += ah->ar_hln; 622 m->m_pkthdr.len += ah->ar_hln; 623 bcopy(ar_tha(ah), ar_tpa(ah), ah->ar_pln); 624 isr = NETISR_ARP; 625 break; 626 } 627 #endif 628 629 #ifdef INET6 630 case ETHERTYPE_IPV6: 631 isr = NETISR_IPV6; 632 break; 633 #endif 634 635 default: 636 m_freem(m); 637 return; 638 } 639 640 M_SETFIB(m, ifp->if_fib); 641 netisr_dispatch(isr, m); 642 } 643 644 int 645 firewire_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 646 { 647 struct ifaddr *ifa = (struct ifaddr *) data; 648 struct ifreq *ifr = (struct ifreq *) data; 649 int error = 0; 650 651 switch (command) { 652 case SIOCSIFADDR: 653 ifp->if_flags |= IFF_UP; 654 655 switch (ifa->ifa_addr->sa_family) { 656 #ifdef INET 657 case AF_INET: 658 ifp->if_init(ifp->if_softc); /* before arpwhohas */ 659 arp_ifinit(ifp, ifa); 660 break; 661 #endif 662 default: 663 ifp->if_init(ifp->if_softc); 664 break; 665 } 666 break; 667 668 case SIOCGIFADDR: 669 { 670 struct sockaddr *sa; 671 672 sa = (struct sockaddr *) & ifr->ifr_data; 673 bcopy(&IFP2FWC(ifp)->fc_hwaddr, 674 (caddr_t) sa->sa_data, sizeof(struct fw_hwaddr)); 675 } 676 break; 677 678 case SIOCSIFMTU: 679 /* 680 * Set the interface MTU. 681 */ 682 if (ifr->ifr_mtu > 1500) { 683 error = EINVAL; 684 } else { 685 ifp->if_mtu = ifr->ifr_mtu; 686 } 687 break; 688 default: 689 error = EINVAL; /* XXX netbsd has ENOTTY??? */ 690 break; 691 } 692 return (error); 693 } 694 695 static int 696 firewire_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa, 697 struct sockaddr *sa) 698 { 699 #ifdef INET 700 struct sockaddr_in *sin; 701 #endif 702 #ifdef INET6 703 struct sockaddr_in6 *sin6; 704 #endif 705 706 switch(sa->sa_family) { 707 case AF_LINK: 708 /* 709 * No mapping needed. 710 */ 711 *llsa = 0; 712 return 0; 713 714 #ifdef INET 715 case AF_INET: 716 sin = (struct sockaddr_in *)sa; 717 if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 718 return EADDRNOTAVAIL; 719 *llsa = 0; 720 return 0; 721 #endif 722 #ifdef INET6 723 case AF_INET6: 724 sin6 = (struct sockaddr_in6 *)sa; 725 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 726 /* 727 * An IP6 address of 0 means listen to all 728 * of the Ethernet multicast address used for IP6. 729 * (This is used for multicast routers.) 730 */ 731 ifp->if_flags |= IFF_ALLMULTI; 732 *llsa = 0; 733 return 0; 734 } 735 if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) 736 return EADDRNOTAVAIL; 737 *llsa = 0; 738 return 0; 739 #endif 740 741 default: 742 /* 743 * Well, the text isn't quite right, but it's the name 744 * that counts... 745 */ 746 return EAFNOSUPPORT; 747 } 748 } 749 750 void 751 firewire_ifattach(struct ifnet *ifp, struct fw_hwaddr *llc) 752 { 753 struct fw_com *fc = IFP2FWC(ifp); 754 struct ifaddr *ifa; 755 struct sockaddr_dl *sdl; 756 static const char* speeds[] = { 757 "S100", "S200", "S400", "S800", 758 "S1600", "S3200" 759 }; 760 761 fc->fc_speed = llc->sspd; 762 STAILQ_INIT(&fc->fc_frags); 763 764 ifp->if_addrlen = sizeof(struct fw_hwaddr); 765 ifp->if_hdrlen = 0; 766 if_attach(ifp); 767 ifp->if_mtu = 1500; /* XXX */ 768 ifp->if_output = firewire_output; 769 ifp->if_resolvemulti = firewire_resolvemulti; 770 ifp->if_broadcastaddr = (u_char *) &firewire_broadcastaddr; 771 772 ifa = ifp->if_addr; 773 KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__)); 774 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 775 sdl->sdl_type = IFT_IEEE1394; 776 sdl->sdl_alen = ifp->if_addrlen; 777 bcopy(llc, LLADDR(sdl), ifp->if_addrlen); 778 779 bpfattach(ifp, DLT_APPLE_IP_OVER_IEEE1394, 780 sizeof(struct fw_hwaddr)); 781 782 if_printf(ifp, "Firewire address: %8D @ 0x%04x%08x, %s, maxrec %d\n", 783 (uint8_t *) &llc->sender_unique_ID_hi, ":", 784 ntohs(llc->sender_unicast_FIFO_hi), 785 ntohl(llc->sender_unicast_FIFO_lo), 786 speeds[llc->sspd], 787 (2 << llc->sender_max_rec)); 788 } 789 790 void 791 firewire_ifdetach(struct ifnet *ifp) 792 { 793 bpfdetach(ifp); 794 if_detach(ifp); 795 } 796 797 void 798 firewire_busreset(struct ifnet *ifp) 799 { 800 struct fw_com *fc = IFP2FWC(ifp); 801 struct fw_reass *r; 802 struct mbuf *m; 803 804 /* 805 * Discard any partial datagrams since the host ids may have changed. 806 */ 807 while ((r = STAILQ_FIRST(&fc->fc_frags))) { 808 STAILQ_REMOVE_HEAD(&fc->fc_frags, fr_link); 809 while (r->fr_frags) { 810 m = r->fr_frags; 811 r->fr_frags = m->m_nextpkt; 812 m_freem(m); 813 } 814 free(r, M_TEMP); 815 } 816 } 817 818 static void * 819 firewire_alloc(u_char type, struct ifnet *ifp) 820 { 821 struct fw_com *fc; 822 823 fc = malloc(sizeof(struct fw_com), M_FWCOM, M_WAITOK | M_ZERO); 824 fc->fc_ifp = ifp; 825 826 return (fc); 827 } 828 829 static void 830 firewire_free(void *com, u_char type) 831 { 832 833 free(com, M_FWCOM); 834 } 835 836 static int 837 firewire_modevent(module_t mod, int type, void *data) 838 { 839 840 switch (type) { 841 case MOD_LOAD: 842 if_register_com_alloc(IFT_IEEE1394, 843 firewire_alloc, firewire_free); 844 break; 845 case MOD_UNLOAD: 846 if_deregister_com_alloc(IFT_IEEE1394); 847 break; 848 default: 849 return (EOPNOTSUPP); 850 } 851 852 return (0); 853 } 854 855 static moduledata_t firewire_mod = { 856 "if_firewire", 857 firewire_modevent, 858 0 859 }; 860 861 DECLARE_MODULE(if_firewire, firewire_mod, SI_SUB_INIT_IF, SI_ORDER_ANY); 862 MODULE_VERSION(if_firewire, 1); 863