sctp6_usrreq.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851
  1. /*-
  2. * SPDX-License-Identifier: BSD-3-Clause
  3. *
  4. * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
  5. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
  6. * Copyright (c) 2008-2012, by Michael Tuexen. 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 are met:
  10. *
  11. * a) Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * b) Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the distribution.
  17. *
  18. * c) Neither the name of Cisco Systems, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived
  20. * from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  24. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #if defined(__FreeBSD__) && !defined(__Userspace__)
  35. #include <sys/cdefs.h>
  36. __FBSDID("$FreeBSD$");
  37. #endif
  38. #include <netinet/sctp_os.h>
  39. #ifdef INET6
  40. #if defined(__FreeBSD__) && !defined(__Userspace__)
  41. #include <sys/proc.h>
  42. #endif
  43. #include <netinet/sctp_pcb.h>
  44. #include <netinet/sctp_header.h>
  45. #include <netinet/sctp_var.h>
  46. #include <netinet6/sctp6_var.h>
  47. #include <netinet/sctp_sysctl.h>
  48. #include <netinet/sctp_output.h>
  49. #include <netinet/sctp_uio.h>
  50. #include <netinet/sctp_asconf.h>
  51. #include <netinet/sctputil.h>
  52. #include <netinet/sctp_indata.h>
  53. #include <netinet/sctp_timer.h>
  54. #include <netinet/sctp_auth.h>
  55. #include <netinet/sctp_input.h>
  56. #include <netinet/sctp_output.h>
  57. #include <netinet/sctp_bsd_addr.h>
  58. #include <netinet/sctp_crc32.h>
  59. #if !defined(_WIN32)
  60. #include <netinet/icmp6.h>
  61. #include <netinet/udp.h>
  62. #endif
  63. #if defined(__Userspace__)
  64. int ip6_v6only=0;
  65. #endif
  66. #if defined(__Userspace__)
  67. #ifdef INET
  68. void
  69. in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
  70. {
  71. #if defined(_WIN32)
  72. uint32_t temp;
  73. #endif
  74. memset(sin, 0, sizeof(*sin));
  75. #ifdef HAVE_SIN_LEN
  76. sin->sin_len = sizeof(struct sockaddr_in);
  77. #endif
  78. sin->sin_family = AF_INET;
  79. sin->sin_port = sin6->sin6_port;
  80. #if defined(_WIN32)
  81. temp = sin6->sin6_addr.s6_addr16[7];
  82. temp = temp << 16;
  83. temp = temp | sin6->sin6_addr.s6_addr16[6];
  84. sin->sin_addr.s_addr = temp;
  85. #else
  86. sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
  87. #endif
  88. }
  89. void
  90. in6_sin6_2_sin_in_sock(struct sockaddr *nam)
  91. {
  92. struct sockaddr_in *sin_p;
  93. struct sockaddr_in6 sin6;
  94. /* save original sockaddr_in6 addr and convert it to sockaddr_in */
  95. sin6 = *(struct sockaddr_in6 *)nam;
  96. sin_p = (struct sockaddr_in *)nam;
  97. in6_sin6_2_sin(sin_p, &sin6);
  98. }
  99. void
  100. in6_sin_2_v4mapsin6(const struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
  101. {
  102. memset(sin6, 0, sizeof(struct sockaddr_in6));
  103. sin6->sin6_family = AF_INET6;
  104. #ifdef HAVE_SIN6_LEN
  105. sin6->sin6_len = sizeof(struct sockaddr_in6);
  106. #endif
  107. sin6->sin6_port = sin->sin_port;
  108. #if defined(_WIN32)
  109. ((uint32_t *)&sin6->sin6_addr)[0] = 0;
  110. ((uint32_t *)&sin6->sin6_addr)[1] = 0;
  111. ((uint32_t *)&sin6->sin6_addr)[2] = htonl(0xffff);
  112. ((uint32_t *)&sin6->sin6_addr)[3] = sin->sin_addr.s_addr;
  113. #else
  114. sin6->sin6_addr.s6_addr32[0] = 0;
  115. sin6->sin6_addr.s6_addr32[1] = 0;
  116. sin6->sin6_addr.s6_addr32[2] = htonl(0xffff);
  117. sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
  118. #endif
  119. }
  120. #endif
  121. #endif
  122. #if !defined(__Userspace__)
  123. int
  124. #if defined(__APPLE__) || defined(__FreeBSD__)
  125. sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
  126. #else
  127. sctp6_input(struct mbuf **i_pak, int *offp, int proto)
  128. #endif
  129. {
  130. struct mbuf *m;
  131. int iphlen;
  132. uint32_t vrf_id;
  133. uint8_t ecn_bits;
  134. struct sockaddr_in6 src, dst;
  135. struct ip6_hdr *ip6;
  136. struct sctphdr *sh;
  137. struct sctp_chunkhdr *ch;
  138. int length, offset;
  139. uint8_t compute_crc;
  140. #if defined(__FreeBSD__)
  141. uint32_t mflowid;
  142. uint8_t mflowtype;
  143. uint16_t fibnum;
  144. #endif
  145. #if !(defined(__APPLE__) || defined(__FreeBSD__))
  146. uint16_t port = 0;
  147. #endif
  148. iphlen = *offp;
  149. if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) {
  150. SCTP_RELEASE_PKT(*i_pak);
  151. return (IPPROTO_DONE);
  152. }
  153. m = SCTP_HEADER_TO_CHAIN(*i_pak);
  154. #ifdef SCTP_MBUF_LOGGING
  155. /* Log in any input mbufs */
  156. if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
  157. sctp_log_mbc(m, SCTP_MBUF_INPUT);
  158. }
  159. #endif
  160. #ifdef SCTP_PACKET_LOGGING
  161. if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
  162. sctp_packet_log(m);
  163. }
  164. #endif
  165. #if defined(__FreeBSD__)
  166. SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
  167. "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
  168. m->m_pkthdr.len,
  169. if_name(m->m_pkthdr.rcvif),
  170. (int)m->m_pkthdr.csum_flags, CSUM_BITS);
  171. #endif
  172. #if defined(__APPLE__)
  173. SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
  174. "sctp6_input(): Packet of length %d received on %s%d with csum_flags 0x%x.\n",
  175. m->m_pkthdr.len,
  176. m->m_pkthdr.rcvif->if_name,
  177. m->m_pkthdr.rcvif->if_unit,
  178. m->m_pkthdr.csum_flags);
  179. #endif
  180. #if defined(_WIN32) && !defined(__Userspace__)
  181. SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
  182. "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
  183. m->m_pkthdr.len,
  184. m->m_pkthdr.rcvif->if_xname,
  185. m->m_pkthdr.csum_flags);
  186. #endif
  187. #if defined(__FreeBSD__)
  188. mflowid = m->m_pkthdr.flowid;
  189. mflowtype = M_HASHTYPE_GET(m);
  190. fibnum = M_GETFIB(m);
  191. #endif
  192. SCTP_STAT_INCR(sctps_recvpackets);
  193. SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
  194. /* Get IP, SCTP, and first chunk header together in the first mbuf. */
  195. offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
  196. if (m->m_len < offset) {
  197. m = m_pullup(m, offset);
  198. if (m == NULL) {
  199. SCTP_STAT_INCR(sctps_hdrops);
  200. return (IPPROTO_DONE);
  201. }
  202. }
  203. ip6 = mtod(m, struct ip6_hdr *);
  204. sh = (struct sctphdr *)(mtod(m, caddr_t) + iphlen);
  205. ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
  206. offset -= sizeof(struct sctp_chunkhdr);
  207. memset(&src, 0, sizeof(struct sockaddr_in6));
  208. src.sin6_family = AF_INET6;
  209. #ifdef HAVE_SIN6_LEN
  210. src.sin6_len = sizeof(struct sockaddr_in6);
  211. #endif
  212. src.sin6_port = sh->src_port;
  213. src.sin6_addr = ip6->ip6_src;
  214. #if defined(__FreeBSD__)
  215. #if defined(__APPLE__)
  216. /* XXX: This code should also be used on Apple */
  217. #endif
  218. if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
  219. goto out;
  220. }
  221. #endif
  222. memset(&dst, 0, sizeof(struct sockaddr_in6));
  223. dst.sin6_family = AF_INET6;
  224. #ifdef HAVE_SIN6_LEN
  225. dst.sin6_len = sizeof(struct sockaddr_in6);
  226. #endif
  227. dst.sin6_port = sh->dest_port;
  228. dst.sin6_addr = ip6->ip6_dst;
  229. #if defined(__FreeBSD__)
  230. #if defined(__APPLE__)
  231. /* XXX: This code should also be used on Apple */
  232. #endif
  233. if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
  234. goto out;
  235. }
  236. #endif
  237. #if defined(__APPLE__)
  238. #if defined(NFAITH) && 0 < NFAITH
  239. if (faithprefix(&dst.sin6_addr)) {
  240. goto out;
  241. }
  242. #endif
  243. #endif
  244. length = ntohs(ip6->ip6_plen) + iphlen;
  245. /* Validate mbuf chain length with IP payload length. */
  246. if (SCTP_HEADER_LEN(m) != length) {
  247. SCTPDBG(SCTP_DEBUG_INPUT1,
  248. "sctp6_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m));
  249. SCTP_STAT_INCR(sctps_hdrops);
  250. goto out;
  251. }
  252. if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
  253. goto out;
  254. }
  255. #if defined(__FreeBSD__)
  256. ecn_bits = IPV6_TRAFFIC_CLASS(ip6);
  257. if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
  258. SCTP_STAT_INCR(sctps_recvhwcrc);
  259. compute_crc = 0;
  260. } else {
  261. #else
  262. ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
  263. if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
  264. (IN6_ARE_ADDR_EQUAL(&src.sin6_addr, &dst.sin6_addr))) {
  265. SCTP_STAT_INCR(sctps_recvhwcrc);
  266. compute_crc = 0;
  267. } else {
  268. #endif
  269. SCTP_STAT_INCR(sctps_recvswcrc);
  270. compute_crc = 1;
  271. }
  272. sctp_common_input_processing(&m, iphlen, offset, length,
  273. (struct sockaddr *)&src,
  274. (struct sockaddr *)&dst,
  275. sh, ch,
  276. compute_crc,
  277. ecn_bits,
  278. #if defined(__FreeBSD__)
  279. mflowtype, mflowid, fibnum,
  280. #endif
  281. vrf_id, port);
  282. out:
  283. if (m) {
  284. sctp_m_freem(m);
  285. }
  286. return (IPPROTO_DONE);
  287. }
  288. #if defined(__APPLE__)
  289. int
  290. sctp6_input(struct mbuf **i_pak, int *offp)
  291. {
  292. return (sctp6_input_with_port(i_pak, offp, 0));
  293. }
  294. #endif
  295. #if defined(__FreeBSD__)
  296. int
  297. sctp6_input(struct mbuf **i_pak, int *offp, int proto SCTP_UNUSED)
  298. {
  299. return (sctp6_input_with_port(i_pak, offp, 0));
  300. }
  301. #endif
  302. void
  303. sctp6_notify(struct sctp_inpcb *inp,
  304. struct sctp_tcb *stcb,
  305. struct sctp_nets *net,
  306. uint8_t icmp6_type,
  307. uint8_t icmp6_code,
  308. uint32_t next_mtu)
  309. {
  310. #if defined(__APPLE__)
  311. struct socket *so;
  312. #endif
  313. int timer_stopped;
  314. switch (icmp6_type) {
  315. case ICMP6_DST_UNREACH:
  316. if ((icmp6_code == ICMP6_DST_UNREACH_NOROUTE) ||
  317. (icmp6_code == ICMP6_DST_UNREACH_ADMIN) ||
  318. (icmp6_code == ICMP6_DST_UNREACH_BEYONDSCOPE) ||
  319. (icmp6_code == ICMP6_DST_UNREACH_ADDR)) {
  320. /* Mark the net unreachable. */
  321. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  322. /* Ok that destination is not reachable */
  323. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  324. net->dest_state &= ~SCTP_ADDR_PF;
  325. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
  326. stcb, 0, (void *)net, SCTP_SO_NOT_LOCKED);
  327. }
  328. }
  329. SCTP_TCB_UNLOCK(stcb);
  330. break;
  331. case ICMP6_PARAM_PROB:
  332. /* Treat it like an ABORT. */
  333. if (icmp6_code == ICMP6_PARAMPROB_NEXTHEADER) {
  334. sctp_abort_notification(stcb, true, false, 0, NULL, SCTP_SO_NOT_LOCKED);
  335. #if defined(__APPLE__)
  336. so = SCTP_INP_SO(inp);
  337. atomic_add_int(&stcb->asoc.refcnt, 1);
  338. SCTP_TCB_UNLOCK(stcb);
  339. SCTP_SOCKET_LOCK(so, 1);
  340. SCTP_TCB_LOCK(stcb);
  341. atomic_subtract_int(&stcb->asoc.refcnt, 1);
  342. #endif
  343. (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
  344. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
  345. #if defined(__APPLE__)
  346. SCTP_SOCKET_UNLOCK(so, 1);
  347. #endif
  348. } else {
  349. SCTP_TCB_UNLOCK(stcb);
  350. }
  351. break;
  352. case ICMP6_PACKET_TOO_BIG:
  353. if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
  354. SCTP_TCB_UNLOCK(stcb);
  355. break;
  356. }
  357. if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  358. timer_stopped = 1;
  359. sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
  360. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
  361. } else {
  362. timer_stopped = 0;
  363. }
  364. /* Update the path MTU. */
  365. if (net->port) {
  366. next_mtu -= sizeof(struct udphdr);
  367. }
  368. if (net->mtu > next_mtu) {
  369. net->mtu = next_mtu;
  370. #if defined(__FreeBSD__)
  371. if (net->port) {
  372. sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr));
  373. } else {
  374. sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu);
  375. }
  376. #endif
  377. }
  378. /* Update the association MTU */
  379. if (stcb->asoc.smallest_mtu > next_mtu) {
  380. sctp_pathmtu_adjustment(stcb, next_mtu, true);
  381. }
  382. /* Finally, start the PMTU timer if it was running before. */
  383. if (timer_stopped) {
  384. sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
  385. }
  386. SCTP_TCB_UNLOCK(stcb);
  387. break;
  388. default:
  389. SCTP_TCB_UNLOCK(stcb);
  390. break;
  391. }
  392. }
  393. void
  394. #if defined(__APPLE__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
  395. sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d, struct ifnet *ifp SCTP_UNUSED)
  396. #else
  397. sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
  398. #endif
  399. {
  400. struct ip6ctlparam *ip6cp;
  401. struct sctp_inpcb *inp;
  402. struct sctp_tcb *stcb;
  403. struct sctp_nets *net;
  404. struct sctphdr sh;
  405. struct sockaddr_in6 src, dst;
  406. #ifdef HAVE_SA_LEN
  407. if (pktdst->sa_family != AF_INET6 ||
  408. pktdst->sa_len != sizeof(struct sockaddr_in6)) {
  409. #else
  410. if (pktdst->sa_family != AF_INET6) {
  411. #endif
  412. return;
  413. }
  414. if ((unsigned)cmd >= PRC_NCMDS) {
  415. return;
  416. }
  417. if (PRC_IS_REDIRECT(cmd)) {
  418. d = NULL;
  419. } else if (inet6ctlerrmap[cmd] == 0) {
  420. return;
  421. }
  422. /* If the parameter is from icmp6, decode it. */
  423. if (d != NULL) {
  424. ip6cp = (struct ip6ctlparam *)d;
  425. } else {
  426. ip6cp = (struct ip6ctlparam *)NULL;
  427. }
  428. if (ip6cp != NULL) {
  429. /*
  430. * XXX: We assume that when IPV6 is non NULL, M and OFF are
  431. * valid.
  432. */
  433. if (ip6cp->ip6c_m == NULL) {
  434. return;
  435. }
  436. /* Check if we can safely examine the ports and the
  437. * verification tag of the SCTP common header.
  438. */
  439. if (ip6cp->ip6c_m->m_pkthdr.len <
  440. (int32_t)(ip6cp->ip6c_off + offsetof(struct sctphdr, checksum))) {
  441. return;
  442. }
  443. /* Copy out the port numbers and the verification tag. */
  444. memset(&sh, 0, sizeof(sh));
  445. m_copydata(ip6cp->ip6c_m,
  446. ip6cp->ip6c_off,
  447. sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
  448. (caddr_t)&sh);
  449. memset(&src, 0, sizeof(struct sockaddr_in6));
  450. src.sin6_family = AF_INET6;
  451. #ifdef HAVE_SIN6_LEN
  452. src.sin6_len = sizeof(struct sockaddr_in6);
  453. #endif
  454. src.sin6_port = sh.src_port;
  455. src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
  456. #if defined(__FreeBSD__)
  457. if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
  458. return;
  459. }
  460. #endif
  461. memset(&dst, 0, sizeof(struct sockaddr_in6));
  462. dst.sin6_family = AF_INET6;
  463. #ifdef HAVE_SIN6_LEN
  464. dst.sin6_len = sizeof(struct sockaddr_in6);
  465. #endif
  466. dst.sin6_port = sh.dest_port;
  467. dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
  468. #if defined(__FreeBSD__)
  469. if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
  470. return;
  471. }
  472. #endif
  473. inp = NULL;
  474. net = NULL;
  475. stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
  476. (struct sockaddr *)&src,
  477. &inp, &net, 1, SCTP_DEFAULT_VRFID);
  478. if ((stcb != NULL) &&
  479. (net != NULL) &&
  480. (inp != NULL)) {
  481. /* Check the verification tag */
  482. if (ntohl(sh.v_tag) != 0) {
  483. /*
  484. * This must be the verification tag used for
  485. * sending out packets. We don't consider
  486. * packets reflecting the verification tag.
  487. */
  488. if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
  489. SCTP_TCB_UNLOCK(stcb);
  490. return;
  491. }
  492. } else {
  493. #if defined(__FreeBSD__)
  494. if (ip6cp->ip6c_m->m_pkthdr.len >=
  495. ip6cp->ip6c_off + sizeof(struct sctphdr) +
  496. sizeof(struct sctp_chunkhdr) +
  497. offsetof(struct sctp_init, a_rwnd)) {
  498. /*
  499. * In this case we can check if we
  500. * got an INIT chunk and if the
  501. * initiate tag matches.
  502. */
  503. uint32_t initiate_tag;
  504. uint8_t chunk_type;
  505. m_copydata(ip6cp->ip6c_m,
  506. ip6cp->ip6c_off +
  507. sizeof(struct sctphdr),
  508. sizeof(uint8_t),
  509. (caddr_t)&chunk_type);
  510. m_copydata(ip6cp->ip6c_m,
  511. ip6cp->ip6c_off +
  512. sizeof(struct sctphdr) +
  513. sizeof(struct sctp_chunkhdr),
  514. sizeof(uint32_t),
  515. (caddr_t)&initiate_tag);
  516. if ((chunk_type != SCTP_INITIATION) ||
  517. (ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
  518. SCTP_TCB_UNLOCK(stcb);
  519. return;
  520. }
  521. } else {
  522. SCTP_TCB_UNLOCK(stcb);
  523. return;
  524. }
  525. #else
  526. SCTP_TCB_UNLOCK(stcb);
  527. return;
  528. #endif
  529. }
  530. sctp6_notify(inp, stcb, net,
  531. ip6cp->ip6c_icmp6->icmp6_type,
  532. ip6cp->ip6c_icmp6->icmp6_code,
  533. ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
  534. #if defined(__Userspace__)
  535. if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  536. (stcb->sctp_socket != NULL)) {
  537. struct socket *upcall_socket;
  538. upcall_socket = stcb->sctp_socket;
  539. SOCK_LOCK(upcall_socket);
  540. soref(upcall_socket);
  541. SOCK_UNLOCK(upcall_socket);
  542. if ((upcall_socket->so_upcall != NULL) &&
  543. (upcall_socket->so_error != 0)) {
  544. (*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
  545. }
  546. ACCEPT_LOCK();
  547. SOCK_LOCK(upcall_socket);
  548. sorele(upcall_socket);
  549. }
  550. #endif
  551. } else {
  552. if ((stcb == NULL) && (inp != NULL)) {
  553. /* reduce inp's ref-count */
  554. SCTP_INP_WLOCK(inp);
  555. SCTP_INP_DECR_REF(inp);
  556. SCTP_INP_WUNLOCK(inp);
  557. }
  558. if (stcb) {
  559. SCTP_TCB_UNLOCK(stcb);
  560. }
  561. }
  562. }
  563. }
  564. #endif
  565. /*
  566. * this routine can probably be collasped into the one in sctp_userreq.c
  567. * since they do the same thing and now we lookup with a sockaddr
  568. */
  569. #if defined(__FreeBSD__) && !defined(__Userspace__)
  570. static int
  571. sctp6_getcred(SYSCTL_HANDLER_ARGS)
  572. {
  573. struct xucred xuc;
  574. struct sockaddr_in6 addrs[2];
  575. struct sctp_inpcb *inp;
  576. struct sctp_nets *net;
  577. struct sctp_tcb *stcb;
  578. int error;
  579. uint32_t vrf_id;
  580. vrf_id = SCTP_DEFAULT_VRFID;
  581. #if defined(__FreeBSD__) && !defined(__Userspace__)
  582. error = priv_check(req->td, PRIV_NETINET_GETCRED);
  583. #else
  584. error = suser(req->p);
  585. #endif
  586. if (error)
  587. return (error);
  588. if (req->newlen != sizeof(addrs)) {
  589. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  590. return (EINVAL);
  591. }
  592. if (req->oldlen != sizeof(struct ucred)) {
  593. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  594. return (EINVAL);
  595. }
  596. error = SYSCTL_IN(req, addrs, sizeof(addrs));
  597. if (error)
  598. return (error);
  599. stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[1]),
  600. sin6tosa(&addrs[0]),
  601. &inp, &net, 1, vrf_id);
  602. if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
  603. if ((inp != NULL) && (stcb == NULL)) {
  604. /* reduce ref-count */
  605. SCTP_INP_WLOCK(inp);
  606. SCTP_INP_DECR_REF(inp);
  607. goto cred_can_cont;
  608. }
  609. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  610. error = ENOENT;
  611. goto out;
  612. }
  613. SCTP_TCB_UNLOCK(stcb);
  614. /* We use the write lock here, only
  615. * since in the error leg we need it.
  616. * If we used RLOCK, then we would have
  617. * to wlock/decr/unlock/rlock. Which
  618. * in theory could create a hole. Better
  619. * to use higher wlock.
  620. */
  621. SCTP_INP_WLOCK(inp);
  622. cred_can_cont:
  623. error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket);
  624. if (error) {
  625. SCTP_INP_WUNLOCK(inp);
  626. goto out;
  627. }
  628. cru2x(inp->sctp_socket->so_cred, &xuc);
  629. SCTP_INP_WUNLOCK(inp);
  630. error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
  631. out:
  632. return (error);
  633. }
  634. SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred,
  635. CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
  636. 0, 0, sctp6_getcred, "S,ucred",
  637. "Get the ucred of a SCTP6 connection");
  638. #endif
  639. /* This is the same as the sctp_abort() could be made common */
  640. #if defined(__Userspace__)
  641. int
  642. #elif defined(__FreeBSD__) || defined(_WIN32)
  643. static void
  644. #else
  645. static int
  646. #endif
  647. sctp6_abort(struct socket *so)
  648. {
  649. #if defined(__FreeBSD__) && !defined(__Userspace__)
  650. struct epoch_tracker et;
  651. #endif
  652. struct sctp_inpcb *inp;
  653. uint32_t flags;
  654. inp = (struct sctp_inpcb *)so->so_pcb;
  655. if (inp == NULL) {
  656. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  657. #if (defined(__FreeBSD__) || defined(_WIN32)) && !defined(__Userspace__)
  658. return;
  659. #else
  660. return (EINVAL);
  661. #endif
  662. }
  663. #if defined(__FreeBSD__) && !defined(__Userspace__)
  664. NET_EPOCH_ENTER(et);
  665. #endif
  666. sctp_must_try_again:
  667. flags = inp->sctp_flags;
  668. #ifdef SCTP_LOG_CLOSING
  669. sctp_log_closing(inp, NULL, 17);
  670. #endif
  671. if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  672. (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
  673. #ifdef SCTP_LOG_CLOSING
  674. sctp_log_closing(inp, NULL, 16);
  675. #endif
  676. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
  677. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  678. SOCK_LOCK(so);
  679. SCTP_SB_CLEAR(so->so_snd);
  680. /* same for the rcv ones, they are only
  681. * here for the accounting/select.
  682. */
  683. SCTP_SB_CLEAR(so->so_rcv);
  684. #if defined(__APPLE__) && !defined(__Userspace__)
  685. so->so_usecount--;
  686. #else
  687. /* Now null out the reference, we are completely detached. */
  688. so->so_pcb = NULL;
  689. #endif
  690. SOCK_UNLOCK(so);
  691. } else {
  692. flags = inp->sctp_flags;
  693. if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
  694. goto sctp_must_try_again;
  695. }
  696. }
  697. #if defined(__FreeBSD__) && !defined(__Userspace__)
  698. NET_EPOCH_EXIT(et);
  699. return;
  700. #else
  701. return (0);
  702. #endif
  703. }
  704. #if defined(__Userspace__)
  705. int
  706. sctp6_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
  707. #elif defined(__FreeBSD__)
  708. static int
  709. sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED)
  710. #elif defined(_WIN32)
  711. static int
  712. sctp6_attach(struct socket *so, int proto SCTP_UNUSED, PKTHREAD p SCTP_UNUSED)
  713. #else
  714. static int
  715. sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct proc *p SCTP_UNUSED)
  716. #endif
  717. {
  718. int error;
  719. struct sctp_inpcb *inp;
  720. #if !defined(__Userspace__)
  721. uint32_t vrf_id = SCTP_DEFAULT_VRFID;
  722. #endif
  723. inp = (struct sctp_inpcb *)so->so_pcb;
  724. if (inp != NULL) {
  725. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  726. return (EINVAL);
  727. }
  728. if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  729. error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
  730. if (error)
  731. return (error);
  732. }
  733. error = sctp_inpcb_alloc(so, vrf_id);
  734. if (error)
  735. return (error);
  736. inp = (struct sctp_inpcb *)so->so_pcb;
  737. SCTP_INP_WLOCK(inp);
  738. inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */
  739. inp->ip_inp.inp.inp_vflag |= INP_IPV6;
  740. inp->ip_inp.inp.in6p_hops = -1; /* use kernel default */
  741. inp->ip_inp.inp.in6p_cksum = -1; /* just to be sure */
  742. #ifdef INET
  743. /*
  744. * XXX: ugly!! IPv4 TTL initialization is necessary for an IPv6
  745. * socket as well, because the socket may be bound to an IPv6
  746. * wildcard address, which may match an IPv4-mapped IPv6 address.
  747. */
  748. inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
  749. #endif
  750. SCTP_INP_WUNLOCK(inp);
  751. return (0);
  752. }
  753. #if defined(__Userspace__)
  754. int
  755. sctp6_bind(struct socket *so, struct sockaddr *addr, void * p)
  756. {
  757. #elif defined(__FreeBSD__)
  758. static int
  759. sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
  760. {
  761. #elif defined(__APPLE__)
  762. static int
  763. sctp6_bind(struct socket *so, struct sockaddr *addr, struct proc *p)
  764. {
  765. #elif defined(_WIN32)
  766. static int
  767. sctp6_bind(struct socket *so, struct sockaddr *addr, PKTHREAD p)
  768. {
  769. #else
  770. static int
  771. sctp6_bind(struct socket *so, struct mbuf *nam, struct proc *p)
  772. {
  773. struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL;
  774. #endif
  775. struct sctp_inpcb *inp;
  776. int error;
  777. u_char vflagsav;
  778. inp = (struct sctp_inpcb *)so->so_pcb;
  779. if (inp == NULL) {
  780. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  781. return (EINVAL);
  782. }
  783. #if !(defined(_WIN32) && !defined(__Userspace__))
  784. if (addr) {
  785. switch (addr->sa_family) {
  786. #ifdef INET
  787. case AF_INET:
  788. #ifdef HAVE_SA_LEN
  789. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  790. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  791. return (EINVAL);
  792. }
  793. #endif
  794. break;
  795. #endif
  796. #ifdef INET6
  797. case AF_INET6:
  798. #ifdef HAVE_SA_LEN
  799. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  800. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  801. return (EINVAL);
  802. }
  803. #endif
  804. break;
  805. #endif
  806. default:
  807. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  808. return (EINVAL);
  809. }
  810. }
  811. #endif
  812. vflagsav = inp->ip_inp.inp.inp_vflag;
  813. inp->ip_inp.inp.inp_vflag &= ~INP_IPV4;
  814. inp->ip_inp.inp.inp_vflag |= INP_IPV6;
  815. if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp) == 0)) {
  816. switch (addr->sa_family) {
  817. #ifdef INET
  818. case AF_INET:
  819. /* binding v4 addr to v6 socket, so reset flags */
  820. inp->ip_inp.inp.inp_vflag |= INP_IPV4;
  821. inp->ip_inp.inp.inp_vflag &= ~INP_IPV6;
  822. break;
  823. #endif
  824. #ifdef INET6
  825. case AF_INET6:
  826. {
  827. struct sockaddr_in6 *sin6_p;
  828. sin6_p = (struct sockaddr_in6 *)addr;
  829. if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) {
  830. inp->ip_inp.inp.inp_vflag |= INP_IPV4;
  831. }
  832. #ifdef INET
  833. if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
  834. struct sockaddr_in sin;
  835. in6_sin6_2_sin(&sin, sin6_p);
  836. inp->ip_inp.inp.inp_vflag |= INP_IPV4;
  837. inp->ip_inp.inp.inp_vflag &= ~INP_IPV6;
  838. error = sctp_inpcb_bind(so, (struct sockaddr *)&sin, NULL, p);
  839. goto out;
  840. }
  841. #endif
  842. break;
  843. }
  844. #endif
  845. default:
  846. break;
  847. }
  848. } else if (addr != NULL) {
  849. struct sockaddr_in6 *sin6_p;
  850. /* IPV6_V6ONLY socket */
  851. #ifdef INET
  852. if (addr->sa_family == AF_INET) {
  853. /* can't bind v4 addr to v6 only socket! */
  854. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  855. error = EINVAL;
  856. goto out;
  857. }
  858. #endif
  859. sin6_p = (struct sockaddr_in6 *)addr;
  860. if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
  861. /* can't bind v4-mapped addrs either! */
  862. /* NOTE: we don't support SIIT */
  863. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  864. error = EINVAL;
  865. goto out;
  866. }
  867. }
  868. error = sctp_inpcb_bind(so, addr, NULL, p);
  869. out:
  870. if (error != 0)
  871. inp->ip_inp.inp.inp_vflag = vflagsav;
  872. return (error);
  873. }
  874. #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
  875. #if !defined(__Userspace__)
  876. static void
  877. #else
  878. void
  879. #endif
  880. sctp6_close(struct socket *so)
  881. {
  882. sctp_close(so);
  883. }
  884. /* This could be made common with sctp_detach() since they are identical */
  885. #else
  886. static
  887. int
  888. sctp6_detach(struct socket *so)
  889. {
  890. #if defined(__Userspace__)
  891. sctp_close(so);
  892. return (0);
  893. #else
  894. return (sctp_detach(so));
  895. #endif
  896. }
  897. #endif
  898. #if !defined(__Userspace__)
  899. static
  900. #endif
  901. int
  902. sctp6_disconnect(struct socket *so)
  903. {
  904. return (sctp_disconnect(so));
  905. }
  906. int
  907. #if defined(__FreeBSD__) && !defined(__Userspace__)
  908. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  909. struct mbuf *control, struct thread *p);
  910. #else
  911. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  912. struct mbuf *control, struct proc *p);
  913. #endif
  914. #if !defined(_WIN32) && !defined(__Userspace__)
  915. #if defined(__FreeBSD__)
  916. static int
  917. sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  918. struct mbuf *control, struct thread *p)
  919. {
  920. #elif defined(__APPLE__)
  921. static int
  922. sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  923. struct mbuf *control, struct proc *p)
  924. {
  925. #else
  926. static int
  927. sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
  928. struct mbuf *control, struct proc *p)
  929. {
  930. struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL;
  931. #endif
  932. struct sctp_inpcb *inp;
  933. #ifdef INET
  934. struct sockaddr_in6 *sin6;
  935. #endif /* INET */
  936. /* No SPL needed since sctp_output does this */
  937. inp = (struct sctp_inpcb *)so->so_pcb;
  938. if (inp == NULL) {
  939. if (control) {
  940. SCTP_RELEASE_PKT(control);
  941. control = NULL;
  942. }
  943. SCTP_RELEASE_PKT(m);
  944. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  945. return (EINVAL);
  946. }
  947. /*
  948. * For the TCP model we may get a NULL addr, if we are a connected
  949. * socket thats ok.
  950. */
  951. if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
  952. (addr == NULL)) {
  953. goto connected_type;
  954. }
  955. if (addr == NULL) {
  956. SCTP_RELEASE_PKT(m);
  957. if (control) {
  958. SCTP_RELEASE_PKT(control);
  959. control = NULL;
  960. }
  961. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EDESTADDRREQ);
  962. return (EDESTADDRREQ);
  963. }
  964. switch (addr->sa_family) {
  965. #ifdef INET
  966. case AF_INET:
  967. #if defined(HAVE_SA_LEN)
  968. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  969. if (control) {
  970. SCTP_RELEASE_PKT(control);
  971. control = NULL;
  972. }
  973. SCTP_RELEASE_PKT(m);
  974. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  975. return (EINVAL);
  976. }
  977. #endif
  978. break;
  979. #endif
  980. #ifdef INET6
  981. case AF_INET6:
  982. #if defined(HAVE_SA_LEN)
  983. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  984. if (control) {
  985. SCTP_RELEASE_PKT(control);
  986. control = NULL;
  987. }
  988. SCTP_RELEASE_PKT(m);
  989. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  990. return (EINVAL);
  991. }
  992. #endif
  993. break;
  994. #endif
  995. default:
  996. if (control) {
  997. SCTP_RELEASE_PKT(control);
  998. control = NULL;
  999. }
  1000. SCTP_RELEASE_PKT(m);
  1001. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1002. return (EINVAL);
  1003. }
  1004. #ifdef INET
  1005. sin6 = (struct sockaddr_in6 *)addr;
  1006. if (SCTP_IPV6_V6ONLY(inp)) {
  1007. /*
  1008. * if IPV6_V6ONLY flag, we discard datagrams destined to a
  1009. * v4 addr or v4-mapped addr
  1010. */
  1011. if (addr->sa_family == AF_INET) {
  1012. if (control) {
  1013. SCTP_RELEASE_PKT(control);
  1014. control = NULL;
  1015. }
  1016. SCTP_RELEASE_PKT(m);
  1017. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1018. return (EINVAL);
  1019. }
  1020. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  1021. if (control) {
  1022. SCTP_RELEASE_PKT(control);
  1023. control = NULL;
  1024. }
  1025. SCTP_RELEASE_PKT(m);
  1026. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1027. return (EINVAL);
  1028. }
  1029. }
  1030. if ((addr->sa_family == AF_INET6) &&
  1031. IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  1032. struct sockaddr_in sin;
  1033. /* convert v4-mapped into v4 addr and send */
  1034. in6_sin6_2_sin(&sin, sin6);
  1035. return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin, control, p));
  1036. }
  1037. #endif /* INET */
  1038. connected_type:
  1039. /* now what about control */
  1040. if (control) {
  1041. if (inp->control) {
  1042. SCTP_PRINTF("huh? control set?\n");
  1043. SCTP_RELEASE_PKT(inp->control);
  1044. inp->control = NULL;
  1045. }
  1046. inp->control = control;
  1047. }
  1048. /* Place the data */
  1049. if (inp->pkt) {
  1050. SCTP_BUF_NEXT(inp->pkt_last) = m;
  1051. inp->pkt_last = m;
  1052. } else {
  1053. inp->pkt_last = inp->pkt = m;
  1054. }
  1055. if (
  1056. #if (defined(__FreeBSD__) || defined(__APPLE__)) && !defined(__Userspace__)
  1057. /* FreeBSD and MacOSX uses a flag passed */
  1058. ((flags & PRUS_MORETOCOME) == 0)
  1059. #else
  1060. 1 /* Open BSD does not have any "more to come"
  1061. * indication */
  1062. #endif
  1063. ) {
  1064. /*
  1065. * note with the current version this code will only be used
  1066. * by OpenBSD, NetBSD and FreeBSD have methods for
  1067. * re-defining sosend() to use sctp_sosend(). One can
  1068. * optionaly switch back to this code (by changing back the
  1069. * defininitions but this is not advisable.
  1070. */
  1071. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1072. struct epoch_tracker et;
  1073. #endif
  1074. int ret;
  1075. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1076. NET_EPOCH_ENTER(et);
  1077. #endif
  1078. ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
  1079. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1080. NET_EPOCH_EXIT(et);
  1081. #endif
  1082. inp->pkt = NULL;
  1083. inp->control = NULL;
  1084. return (ret);
  1085. } else {
  1086. return (0);
  1087. }
  1088. }
  1089. #endif
  1090. #if defined(__Userspace__)
  1091. int
  1092. sctp6_connect(struct socket *so, struct sockaddr *addr)
  1093. {
  1094. void *p = NULL;
  1095. #elif defined(__FreeBSD__)
  1096. static int
  1097. sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
  1098. {
  1099. #elif defined(__APPLE__)
  1100. static int
  1101. sctp6_connect(struct socket *so, struct sockaddr *addr, struct proc *p)
  1102. {
  1103. #elif defined(_WIN32)
  1104. static int
  1105. sctp6_connect(struct socket *so, struct sockaddr *addr, PKTHREAD p)
  1106. {
  1107. #else
  1108. static int
  1109. sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
  1110. {
  1111. struct sockaddr *addr = mtod(nam, struct sockaddr *);
  1112. #endif
  1113. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1114. struct epoch_tracker et;
  1115. #endif
  1116. uint32_t vrf_id;
  1117. int error = 0;
  1118. struct sctp_inpcb *inp;
  1119. struct sctp_tcb *stcb;
  1120. #ifdef INET
  1121. struct sockaddr_in6 *sin6;
  1122. union sctp_sockstore store;
  1123. #endif
  1124. inp = (struct sctp_inpcb *)so->so_pcb;
  1125. if (inp == NULL) {
  1126. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
  1127. return (ECONNRESET); /* I made the same as TCP since we are
  1128. * not setup? */
  1129. }
  1130. if (addr == NULL) {
  1131. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1132. return (EINVAL);
  1133. }
  1134. #if !(defined(_WIN32) && !defined(__Userspace__))
  1135. switch (addr->sa_family) {
  1136. #ifdef INET
  1137. case AF_INET:
  1138. #ifdef HAVE_SA_LEN
  1139. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  1140. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1141. return (EINVAL);
  1142. }
  1143. #endif
  1144. break;
  1145. #endif
  1146. #ifdef INET6
  1147. case AF_INET6:
  1148. #ifdef HAVE_SA_LEN
  1149. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  1150. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1151. return (EINVAL);
  1152. }
  1153. #endif
  1154. break;
  1155. #endif
  1156. default:
  1157. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1158. return (EINVAL);
  1159. }
  1160. #endif
  1161. vrf_id = inp->def_vrf_id;
  1162. SCTP_ASOC_CREATE_LOCK(inp);
  1163. SCTP_INP_RLOCK(inp);
  1164. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
  1165. SCTP_PCB_FLAGS_UNBOUND) {
  1166. /* Bind a ephemeral port */
  1167. SCTP_INP_RUNLOCK(inp);
  1168. error = sctp6_bind(so, NULL, p);
  1169. if (error) {
  1170. SCTP_ASOC_CREATE_UNLOCK(inp);
  1171. return (error);
  1172. }
  1173. SCTP_INP_RLOCK(inp);
  1174. }
  1175. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  1176. (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
  1177. /* We are already connected AND the TCP model */
  1178. SCTP_INP_RUNLOCK(inp);
  1179. SCTP_ASOC_CREATE_UNLOCK(inp);
  1180. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EADDRINUSE);
  1181. return (EADDRINUSE);
  1182. }
  1183. #ifdef INET
  1184. sin6 = (struct sockaddr_in6 *)addr;
  1185. if (SCTP_IPV6_V6ONLY(inp)) {
  1186. /*
  1187. * if IPV6_V6ONLY flag, ignore connections destined to a v4
  1188. * addr or v4-mapped addr
  1189. */
  1190. if (addr->sa_family == AF_INET) {
  1191. SCTP_INP_RUNLOCK(inp);
  1192. SCTP_ASOC_CREATE_UNLOCK(inp);
  1193. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1194. return (EINVAL);
  1195. }
  1196. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  1197. SCTP_INP_RUNLOCK(inp);
  1198. SCTP_ASOC_CREATE_UNLOCK(inp);
  1199. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1200. return (EINVAL);
  1201. }
  1202. }
  1203. if ((addr->sa_family == AF_INET6) &&
  1204. IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  1205. /* convert v4-mapped into v4 addr */
  1206. in6_sin6_2_sin(&store.sin, sin6);
  1207. addr = &store.sa;
  1208. }
  1209. #endif /* INET */
  1210. /* Now do we connect? */
  1211. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  1212. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  1213. if (stcb) {
  1214. SCTP_TCB_LOCK(stcb);
  1215. }
  1216. SCTP_INP_RUNLOCK(inp);
  1217. } else {
  1218. SCTP_INP_RUNLOCK(inp);
  1219. SCTP_INP_WLOCK(inp);
  1220. SCTP_INP_INCR_REF(inp);
  1221. SCTP_INP_WUNLOCK(inp);
  1222. stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
  1223. if (stcb == NULL) {
  1224. SCTP_INP_WLOCK(inp);
  1225. SCTP_INP_DECR_REF(inp);
  1226. SCTP_INP_WUNLOCK(inp);
  1227. }
  1228. }
  1229. if (stcb != NULL) {
  1230. /* Already have or am bring up an association */
  1231. SCTP_ASOC_CREATE_UNLOCK(inp);
  1232. SCTP_TCB_UNLOCK(stcb);
  1233. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EALREADY);
  1234. return (EALREADY);
  1235. }
  1236. /* We are GOOD to go */
  1237. stcb = sctp_aloc_assoc_connected(inp, addr, &error, 0, 0, vrf_id,
  1238. inp->sctp_ep.pre_open_stream_count,
  1239. inp->sctp_ep.port, p,
  1240. SCTP_INITIALIZE_AUTH_PARAMS);
  1241. SCTP_ASOC_CREATE_UNLOCK(inp);
  1242. if (stcb == NULL) {
  1243. /* Gak! no memory */
  1244. return (error);
  1245. }
  1246. SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
  1247. (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
  1248. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1249. NET_EPOCH_ENTER(et);
  1250. #endif
  1251. sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
  1252. SCTP_TCB_UNLOCK(stcb);
  1253. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1254. NET_EPOCH_EXIT(et);
  1255. #endif
  1256. return (error);
  1257. }
  1258. static int
  1259. #if !defined(__Userspace__)
  1260. sctp6_getaddr(struct socket *so, struct sockaddr **addr)
  1261. {
  1262. struct sockaddr_in6 *sin6;
  1263. #else
  1264. sctp6_getaddr(struct socket *so, struct mbuf *nam)
  1265. {
  1266. struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *);
  1267. #endif
  1268. struct sctp_inpcb *inp;
  1269. uint32_t vrf_id;
  1270. struct sctp_ifa *sctp_ifa;
  1271. #if defined(SCTP_KAME) && defined(SCTP_EMBEDDED_V6_SCOPE)
  1272. int error;
  1273. #endif
  1274. /*
  1275. * Do the malloc first in case it blocks.
  1276. */
  1277. #if !defined(__Userspace__)
  1278. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6));
  1279. if (sin6 == NULL)
  1280. return (ENOMEM);
  1281. #else
  1282. SCTP_BUF_LEN(nam) = sizeof(*sin6);
  1283. memset(sin6, 0, sizeof(*sin6));
  1284. #endif
  1285. sin6->sin6_family = AF_INET6;
  1286. #ifdef HAVE_SIN6_LEN
  1287. sin6->sin6_len = sizeof(*sin6);
  1288. #endif
  1289. inp = (struct sctp_inpcb *)so->so_pcb;
  1290. if (inp == NULL) {
  1291. #if !defined(__Userspace__)
  1292. SCTP_FREE_SONAME(sin6);
  1293. #endif
  1294. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
  1295. return (ECONNRESET);
  1296. }
  1297. SCTP_INP_RLOCK(inp);
  1298. sin6->sin6_port = inp->sctp_lport;
  1299. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  1300. /* For the bound all case you get back 0 */
  1301. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  1302. struct sctp_tcb *stcb;
  1303. struct sockaddr_in6 *sin_a6;
  1304. struct sctp_nets *net;
  1305. int fnd;
  1306. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  1307. if (stcb == NULL) {
  1308. SCTP_INP_RUNLOCK(inp);
  1309. #if !defined(__Userspace__)
  1310. SCTP_FREE_SONAME(sin6);
  1311. #endif
  1312. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  1313. return (ENOENT);
  1314. }
  1315. fnd = 0;
  1316. sin_a6 = NULL;
  1317. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  1318. sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr;
  1319. if (sin_a6 == NULL)
  1320. /* this will make coverity happy */
  1321. continue;
  1322. if (sin_a6->sin6_family == AF_INET6) {
  1323. fnd = 1;
  1324. break;
  1325. }
  1326. }
  1327. if ((!fnd) || (sin_a6 == NULL)) {
  1328. /* punt */
  1329. SCTP_INP_RUNLOCK(inp);
  1330. #if !defined(__Userspace__)
  1331. SCTP_FREE_SONAME(sin6);
  1332. #endif
  1333. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  1334. return (ENOENT);
  1335. }
  1336. vrf_id = inp->def_vrf_id;
  1337. sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *)&net->ro, net, 0, vrf_id);
  1338. if (sctp_ifa) {
  1339. sin6->sin6_addr = sctp_ifa->address.sin6.sin6_addr;
  1340. }
  1341. } else {
  1342. /* For the bound all case you get back 0 */
  1343. memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
  1344. }
  1345. } else {
  1346. /* Take the first IPv6 address in the list */
  1347. struct sctp_laddr *laddr;
  1348. int fnd = 0;
  1349. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  1350. if (laddr->ifa->address.sa.sa_family == AF_INET6) {
  1351. struct sockaddr_in6 *sin_a;
  1352. sin_a = &laddr->ifa->address.sin6;
  1353. sin6->sin6_addr = sin_a->sin6_addr;
  1354. fnd = 1;
  1355. break;
  1356. }
  1357. }
  1358. if (!fnd) {
  1359. #if !defined(__Userspace__)
  1360. SCTP_FREE_SONAME(sin6);
  1361. #endif
  1362. SCTP_INP_RUNLOCK(inp);
  1363. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  1364. return (ENOENT);
  1365. }
  1366. }
  1367. SCTP_INP_RUNLOCK(inp);
  1368. /* Scoping things for v6 */
  1369. #ifdef SCTP_EMBEDDED_V6_SCOPE
  1370. #ifdef SCTP_KAME
  1371. if ((error = sa6_recoverscope(sin6)) != 0) {
  1372. SCTP_FREE_SONAME(sin6);
  1373. return (error);
  1374. }
  1375. #else
  1376. if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
  1377. /* skip ifp check below */
  1378. in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
  1379. else
  1380. sin6->sin6_scope_id = 0; /* XXX */
  1381. #endif /* SCTP_KAME */
  1382. #endif /* SCTP_EMBEDDED_V6_SCOPE */
  1383. #if !defined(__Userspace__)
  1384. (*addr) = (struct sockaddr *)sin6;
  1385. #endif
  1386. return (0);
  1387. }
  1388. static int
  1389. #if !defined(__Userspace__)
  1390. sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
  1391. {
  1392. struct sockaddr_in6 *sin6;
  1393. #else
  1394. sctp6_peeraddr(struct socket *so, struct mbuf *nam)
  1395. {
  1396. struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *);
  1397. #endif
  1398. int fnd;
  1399. struct sockaddr_in6 *sin_a6;
  1400. struct sctp_inpcb *inp;
  1401. struct sctp_tcb *stcb;
  1402. struct sctp_nets *net;
  1403. #ifdef SCTP_KAME
  1404. int error;
  1405. #endif
  1406. /* Do the malloc first in case it blocks. */
  1407. #if !defined(__Userspace__)
  1408. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  1409. if (sin6 == NULL)
  1410. return (ENOMEM);
  1411. #else
  1412. SCTP_BUF_LEN(nam) = sizeof(*sin6);
  1413. memset(sin6, 0, sizeof(*sin6));
  1414. #endif
  1415. sin6->sin6_family = AF_INET6;
  1416. #ifdef HAVE_SIN6_LEN
  1417. sin6->sin6_len = sizeof(*sin6);
  1418. #endif
  1419. inp = (struct sctp_inpcb *)so->so_pcb;
  1420. if ((inp == NULL) ||
  1421. ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
  1422. /* UDP type and listeners will drop out here */
  1423. #if !defined(__Userspace__)
  1424. SCTP_FREE_SONAME(sin6);
  1425. #endif
  1426. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOTCONN);
  1427. return (ENOTCONN);
  1428. }
  1429. SCTP_INP_RLOCK(inp);
  1430. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  1431. if (stcb) {
  1432. SCTP_TCB_LOCK(stcb);
  1433. }
  1434. SCTP_INP_RUNLOCK(inp);
  1435. if (stcb == NULL) {
  1436. #if !defined(__Userspace__)
  1437. SCTP_FREE_SONAME(sin6);
  1438. #endif
  1439. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
  1440. return (ECONNRESET);
  1441. }
  1442. fnd = 0;
  1443. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  1444. sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr;
  1445. if (sin_a6->sin6_family == AF_INET6) {
  1446. fnd = 1;
  1447. sin6->sin6_port = stcb->rport;
  1448. sin6->sin6_addr = sin_a6->sin6_addr;
  1449. break;
  1450. }
  1451. }
  1452. SCTP_TCB_UNLOCK(stcb);
  1453. if (!fnd) {
  1454. /* No IPv4 address */
  1455. #if !defined(__Userspace__)
  1456. SCTP_FREE_SONAME(sin6);
  1457. #endif
  1458. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  1459. return (ENOENT);
  1460. }
  1461. #ifdef SCTP_EMBEDDED_V6_SCOPE
  1462. #ifdef SCTP_KAME
  1463. if ((error = sa6_recoverscope(sin6)) != 0) {
  1464. #if !defined(__Userspace__)
  1465. SCTP_FREE_SONAME(sin6);
  1466. #endif
  1467. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, error);
  1468. return (error);
  1469. }
  1470. #else
  1471. in6_recoverscope(sin6, &sin6->sin6_addr, NULL);
  1472. #endif /* SCTP_KAME */
  1473. #endif /* SCTP_EMBEDDED_V6_SCOPE */
  1474. #if !defined(__Userspace__)
  1475. *addr = (struct sockaddr *)sin6;
  1476. #endif
  1477. return (0);
  1478. }
  1479. #if !defined(__Userspace__)
  1480. static int
  1481. sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
  1482. {
  1483. #elif defined(__Userspace__)
  1484. int
  1485. sctp6_in6getaddr(struct socket *so, struct mbuf *nam)
  1486. {
  1487. #ifdef INET
  1488. struct sockaddr *addr = mtod(nam, struct sockaddr *);
  1489. #endif
  1490. #else
  1491. static int
  1492. sctp6_in6getaddr(struct socket *so, struct mbuf *nam)
  1493. {
  1494. #ifdef INET
  1495. struct sockaddr *addr = mtod(nam, struct sockaddr *);
  1496. #endif
  1497. #endif
  1498. struct inpcb *inp = sotoinpcb(so);
  1499. int error;
  1500. if (inp == NULL) {
  1501. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1502. return (EINVAL);
  1503. }
  1504. /* allow v6 addresses precedence */
  1505. error = sctp6_getaddr(so, nam);
  1506. #ifdef INET
  1507. if (error) {
  1508. #if !defined(__Userspace__)
  1509. struct sockaddr_in6 *sin6;
  1510. #else
  1511. struct sockaddr_in6 sin6;
  1512. #endif
  1513. /* try v4 next if v6 failed */
  1514. error = sctp_ingetaddr(so, nam);
  1515. if (error) {
  1516. return (error);
  1517. }
  1518. #if !defined(__Userspace__)
  1519. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  1520. if (sin6 == NULL) {
  1521. SCTP_FREE_SONAME(*nam);
  1522. return (ENOMEM);
  1523. }
  1524. in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
  1525. SCTP_FREE_SONAME(*nam);
  1526. *nam = (struct sockaddr *)sin6;
  1527. #else
  1528. in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
  1529. SCTP_BUF_LEN(nam) = sizeof(struct sockaddr_in6);
  1530. memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
  1531. #endif
  1532. }
  1533. #endif
  1534. return (error);
  1535. }
  1536. #if !defined(__Userspace__)
  1537. static int
  1538. sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
  1539. {
  1540. #elif defined(__Userspace__)
  1541. int
  1542. sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
  1543. {
  1544. #ifdef INET
  1545. struct sockaddr *addr = mtod(nam, struct sockaddr *);
  1546. #endif
  1547. #else
  1548. static
  1549. int
  1550. sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
  1551. {
  1552. #ifdef INET
  1553. struct sockaddr *addr = mtod(nam, struct sockaddr *);
  1554. #endif
  1555. #endif
  1556. struct inpcb *inp = sotoinpcb(so);
  1557. int error;
  1558. if (inp == NULL) {
  1559. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1560. return (EINVAL);
  1561. }
  1562. /* allow v6 addresses precedence */
  1563. error = sctp6_peeraddr(so, nam);
  1564. #ifdef INET
  1565. if (error) {
  1566. #if !defined(__Userspace__)
  1567. struct sockaddr_in6 *sin6;
  1568. #else
  1569. struct sockaddr_in6 sin6;
  1570. #endif
  1571. /* try v4 next if v6 failed */
  1572. error = sctp_peeraddr(so, nam);
  1573. if (error) {
  1574. return (error);
  1575. }
  1576. #if !defined(__Userspace__)
  1577. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  1578. if (sin6 == NULL) {
  1579. SCTP_FREE_SONAME(*nam);
  1580. return (ENOMEM);
  1581. }
  1582. in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
  1583. SCTP_FREE_SONAME(*nam);
  1584. *nam = (struct sockaddr *)sin6;
  1585. #else
  1586. in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
  1587. SCTP_BUF_LEN(nam) = sizeof(struct sockaddr_in6);
  1588. memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
  1589. #endif
  1590. }
  1591. #endif
  1592. return (error);
  1593. }
  1594. #if !defined(__Userspace__)
  1595. struct pr_usrreqs sctp6_usrreqs = {
  1596. #if defined(__FreeBSD__)
  1597. .pru_abort = sctp6_abort,
  1598. .pru_accept = sctp_accept,
  1599. .pru_attach = sctp6_attach,
  1600. .pru_bind = sctp6_bind,
  1601. .pru_connect = sctp6_connect,
  1602. .pru_control = in6_control,
  1603. .pru_close = sctp6_close,
  1604. .pru_detach = sctp6_close,
  1605. .pru_sopoll = sopoll_generic,
  1606. .pru_flush = sctp_flush,
  1607. .pru_disconnect = sctp6_disconnect,
  1608. .pru_listen = sctp_listen,
  1609. .pru_peeraddr = sctp6_getpeeraddr,
  1610. .pru_send = sctp6_send,
  1611. .pru_shutdown = sctp_shutdown,
  1612. .pru_sockaddr = sctp6_in6getaddr,
  1613. .pru_sosend = sctp_sosend,
  1614. .pru_soreceive = sctp_soreceive
  1615. #elif defined(__APPLE__) && !defined(__Userspace__)
  1616. .pru_abort = sctp6_abort,
  1617. .pru_accept = sctp_accept,
  1618. .pru_attach = sctp6_attach,
  1619. .pru_bind = sctp6_bind,
  1620. .pru_connect = sctp6_connect,
  1621. .pru_connect2 = pru_connect2_notsupp,
  1622. .pru_control = in6_control,
  1623. .pru_detach = sctp6_detach,
  1624. .pru_disconnect = sctp6_disconnect,
  1625. .pru_listen = sctp_listen,
  1626. .pru_peeraddr = sctp6_getpeeraddr,
  1627. .pru_rcvd = NULL,
  1628. .pru_rcvoob = pru_rcvoob_notsupp,
  1629. .pru_send = sctp6_send,
  1630. .pru_sense = pru_sense_null,
  1631. .pru_shutdown = sctp_shutdown,
  1632. .pru_sockaddr = sctp6_in6getaddr,
  1633. .pru_sosend = sctp_sosend,
  1634. .pru_soreceive = sctp_soreceive,
  1635. .pru_sopoll = sopoll
  1636. #elif defined(_WIN32) && !defined(__Userspace__)
  1637. sctp6_abort,
  1638. sctp_accept,
  1639. sctp6_attach,
  1640. sctp6_bind,
  1641. sctp6_connect,
  1642. pru_connect2_notsupp,
  1643. NULL,
  1644. NULL,
  1645. sctp6_disconnect,
  1646. sctp_listen,
  1647. sctp6_getpeeraddr,
  1648. NULL,
  1649. pru_rcvoob_notsupp,
  1650. NULL,
  1651. pru_sense_null,
  1652. sctp_shutdown,
  1653. sctp_flush,
  1654. sctp6_in6getaddr,
  1655. sctp_sosend,
  1656. sctp_soreceive,
  1657. sopoll_generic,
  1658. NULL,
  1659. sctp6_close
  1660. #endif
  1661. };
  1662. #elif !defined(__Userspace__)
  1663. int
  1664. sctp6_usrreq(so, req, m, nam, control, p)
  1665. struct socket *so;
  1666. int req;
  1667. struct mbuf *m, *nam, *control;
  1668. struct proc *p;
  1669. {
  1670. int error;
  1671. int family;
  1672. family = so->so_proto->pr_domain->dom_family;
  1673. if (req == PRU_CONTROL) {
  1674. switch (family) {
  1675. case PF_INET:
  1676. error = in_control(so, (long)m, (caddr_t)nam,
  1677. (struct ifnet *)control);
  1678. break;
  1679. #ifdef INET6
  1680. case PF_INET6:
  1681. error = in6_control(so, (long)m, (caddr_t)nam,
  1682. (struct ifnet *)control, p);
  1683. break;
  1684. #endif
  1685. default:
  1686. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT);
  1687. error = EAFNOSUPPORT;
  1688. }
  1689. return (error);
  1690. }
  1691. switch (req) {
  1692. case PRU_ATTACH:
  1693. error = sctp6_attach(so, family, p);
  1694. break;
  1695. case PRU_DETACH:
  1696. error = sctp6_detach(so);
  1697. break;
  1698. case PRU_BIND:
  1699. if (nam == NULL) {
  1700. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1701. return (EINVAL);
  1702. }
  1703. error = sctp6_bind(so, nam, p);
  1704. break;
  1705. case PRU_LISTEN:
  1706. error = sctp_listen(so, p);
  1707. break;
  1708. case PRU_CONNECT:
  1709. if (nam == NULL) {
  1710. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1711. return (EINVAL);
  1712. }
  1713. error = sctp6_connect(so, nam, p);
  1714. break;
  1715. case PRU_DISCONNECT:
  1716. error = sctp6_disconnect(so);
  1717. break;
  1718. case PRU_ACCEPT:
  1719. if (nam == NULL) {
  1720. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1721. return (EINVAL);
  1722. }
  1723. error = sctp_accept(so, nam);
  1724. break;
  1725. case PRU_SHUTDOWN:
  1726. error = sctp_shutdown(so);
  1727. break;
  1728. case PRU_RCVD:
  1729. /*
  1730. * For OpenBSD and NetBSD, this is real ugly. The (mbuf *)
  1731. * nam that is passed (by soreceive()) is the int flags cast
  1732. * as a (mbuf *) yuck!
  1733. */
  1734. error = sctp_usr_recvd(so, (int)((long)nam));
  1735. break;
  1736. case PRU_SEND:
  1737. /* Flags are ignored */
  1738. error = sctp6_send(so, 0, m, nam, control, p);
  1739. break;
  1740. case PRU_ABORT:
  1741. error = sctp6_abort(so);
  1742. break;
  1743. case PRU_SENSE:
  1744. error = 0;
  1745. break;
  1746. case PRU_RCVOOB:
  1747. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT);
  1748. error = EAFNOSUPPORT;
  1749. break;
  1750. case PRU_SENDOOB:
  1751. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT);
  1752. error = EAFNOSUPPORT;
  1753. break;
  1754. case PRU_PEERADDR:
  1755. error = sctp6_getpeeraddr(so, nam);
  1756. break;
  1757. case PRU_SOCKADDR:
  1758. error = sctp6_in6getaddr(so, nam);
  1759. break;
  1760. case PRU_SLOWTIMO:
  1761. error = 0;
  1762. break;
  1763. default:
  1764. error = 0;
  1765. break;
  1766. }
  1767. return (error);
  1768. }
  1769. #endif
  1770. #endif