if_fwsubr.c 20 KB

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