sctp6_usrreq.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  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. #include <sys/cdefs.h>
  35. __FBSDID("$FreeBSD$");
  36. #include <netinet/sctp_os.h>
  37. #ifdef INET6
  38. #include <sys/proc.h>
  39. #include <netinet/sctp_pcb.h>
  40. #include <netinet/sctp_header.h>
  41. #include <netinet/sctp_var.h>
  42. #include <netinet6/sctp6_var.h>
  43. #include <netinet/sctp_sysctl.h>
  44. #include <netinet/sctp_output.h>
  45. #include <netinet/sctp_uio.h>
  46. #include <netinet/sctp_asconf.h>
  47. #include <netinet/sctputil.h>
  48. #include <netinet/sctp_indata.h>
  49. #include <netinet/sctp_timer.h>
  50. #include <netinet/sctp_auth.h>
  51. #include <netinet/sctp_input.h>
  52. #include <netinet/sctp_output.h>
  53. #include <netinet/sctp_bsd_addr.h>
  54. #include <netinet/sctp_crc32.h>
  55. #include <netinet/icmp6.h>
  56. #include <netinet/udp.h>
  57. int
  58. sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
  59. {
  60. struct mbuf *m;
  61. int iphlen;
  62. uint32_t vrf_id;
  63. uint8_t ecn_bits;
  64. struct sockaddr_in6 src, dst;
  65. struct ip6_hdr *ip6;
  66. struct sctphdr *sh;
  67. struct sctp_chunkhdr *ch;
  68. int length, offset;
  69. uint8_t compute_crc;
  70. uint32_t mflowid;
  71. uint8_t mflowtype;
  72. uint16_t fibnum;
  73. iphlen = *offp;
  74. if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) {
  75. SCTP_RELEASE_PKT(*i_pak);
  76. return (IPPROTO_DONE);
  77. }
  78. m = SCTP_HEADER_TO_CHAIN(*i_pak);
  79. #ifdef SCTP_MBUF_LOGGING
  80. /* Log in any input mbufs */
  81. if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
  82. sctp_log_mbc(m, SCTP_MBUF_INPUT);
  83. }
  84. #endif
  85. #ifdef SCTP_PACKET_LOGGING
  86. if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
  87. sctp_packet_log(m);
  88. }
  89. #endif
  90. SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
  91. "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
  92. m->m_pkthdr.len,
  93. if_name(m->m_pkthdr.rcvif),
  94. (int)m->m_pkthdr.csum_flags, CSUM_BITS);
  95. mflowid = m->m_pkthdr.flowid;
  96. mflowtype = M_HASHTYPE_GET(m);
  97. fibnum = M_GETFIB(m);
  98. SCTP_STAT_INCR(sctps_recvpackets);
  99. SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
  100. /* Get IP, SCTP, and first chunk header together in the first mbuf. */
  101. offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
  102. if (m->m_len < offset) {
  103. m = m_pullup(m, offset);
  104. if (m == NULL) {
  105. SCTP_STAT_INCR(sctps_hdrops);
  106. return (IPPROTO_DONE);
  107. }
  108. }
  109. ip6 = mtod(m, struct ip6_hdr *);
  110. sh = (struct sctphdr *)(mtod(m, caddr_t)+iphlen);
  111. ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
  112. offset -= sizeof(struct sctp_chunkhdr);
  113. memset(&src, 0, sizeof(struct sockaddr_in6));
  114. src.sin6_family = AF_INET6;
  115. src.sin6_len = sizeof(struct sockaddr_in6);
  116. src.sin6_port = sh->src_port;
  117. src.sin6_addr = ip6->ip6_src;
  118. if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
  119. goto out;
  120. }
  121. memset(&dst, 0, sizeof(struct sockaddr_in6));
  122. dst.sin6_family = AF_INET6;
  123. dst.sin6_len = sizeof(struct sockaddr_in6);
  124. dst.sin6_port = sh->dest_port;
  125. dst.sin6_addr = ip6->ip6_dst;
  126. if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
  127. goto out;
  128. }
  129. length = ntohs(ip6->ip6_plen) + iphlen;
  130. /* Validate mbuf chain length with IP payload length. */
  131. if (SCTP_HEADER_LEN(m) != length) {
  132. SCTPDBG(SCTP_DEBUG_INPUT1,
  133. "sctp6_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m));
  134. SCTP_STAT_INCR(sctps_hdrops);
  135. goto out;
  136. }
  137. if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
  138. goto out;
  139. }
  140. ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
  141. if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
  142. SCTP_STAT_INCR(sctps_recvhwcrc);
  143. compute_crc = 0;
  144. } else {
  145. SCTP_STAT_INCR(sctps_recvswcrc);
  146. compute_crc = 1;
  147. }
  148. sctp_common_input_processing(&m, iphlen, offset, length,
  149. (struct sockaddr *)&src,
  150. (struct sockaddr *)&dst,
  151. sh, ch,
  152. compute_crc,
  153. ecn_bits,
  154. mflowtype, mflowid, fibnum,
  155. vrf_id, port);
  156. out:
  157. if (m) {
  158. sctp_m_freem(m);
  159. }
  160. return (IPPROTO_DONE);
  161. }
  162. int
  163. sctp6_input(struct mbuf **i_pak, int *offp, int proto SCTP_UNUSED)
  164. {
  165. return (sctp6_input_with_port(i_pak, offp, 0));
  166. }
  167. void
  168. sctp6_notify(struct sctp_inpcb *inp,
  169. struct sctp_tcb *stcb,
  170. struct sctp_nets *net,
  171. uint8_t icmp6_type,
  172. uint8_t icmp6_code,
  173. uint32_t next_mtu)
  174. {
  175. int timer_stopped;
  176. switch (icmp6_type) {
  177. case ICMP6_DST_UNREACH:
  178. if ((icmp6_code == ICMP6_DST_UNREACH_NOROUTE) ||
  179. (icmp6_code == ICMP6_DST_UNREACH_ADMIN) ||
  180. (icmp6_code == ICMP6_DST_UNREACH_BEYONDSCOPE) ||
  181. (icmp6_code == ICMP6_DST_UNREACH_ADDR)) {
  182. /* Mark the net unreachable. */
  183. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  184. /* Ok that destination is not reachable */
  185. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  186. net->dest_state &= ~SCTP_ADDR_PF;
  187. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
  188. stcb, 0, (void *)net, SCTP_SO_NOT_LOCKED);
  189. }
  190. }
  191. SCTP_TCB_UNLOCK(stcb);
  192. break;
  193. case ICMP6_PARAM_PROB:
  194. /* Treat it like an ABORT. */
  195. if (icmp6_code == ICMP6_PARAMPROB_NEXTHEADER) {
  196. sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED);
  197. (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
  198. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
  199. } else {
  200. SCTP_TCB_UNLOCK(stcb);
  201. }
  202. break;
  203. case ICMP6_PACKET_TOO_BIG:
  204. if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
  205. SCTP_TCB_UNLOCK(stcb);
  206. break;
  207. }
  208. if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  209. timer_stopped = 1;
  210. sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
  211. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
  212. } else {
  213. timer_stopped = 0;
  214. }
  215. /* Update the path MTU. */
  216. if (net->port) {
  217. next_mtu -= sizeof(struct udphdr);
  218. }
  219. if (net->mtu > next_mtu) {
  220. net->mtu = next_mtu;
  221. if (net->port) {
  222. sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr));
  223. } else {
  224. sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu);
  225. }
  226. }
  227. /* Update the association MTU */
  228. if (stcb->asoc.smallest_mtu > next_mtu) {
  229. sctp_pathmtu_adjustment(stcb, next_mtu);
  230. }
  231. /* Finally, start the PMTU timer if it was running before. */
  232. if (timer_stopped) {
  233. sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
  234. }
  235. SCTP_TCB_UNLOCK(stcb);
  236. break;
  237. default:
  238. SCTP_TCB_UNLOCK(stcb);
  239. break;
  240. }
  241. }
  242. void
  243. sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
  244. {
  245. struct ip6ctlparam *ip6cp;
  246. struct sctp_inpcb *inp;
  247. struct sctp_tcb *stcb;
  248. struct sctp_nets *net;
  249. struct sctphdr sh;
  250. struct sockaddr_in6 src, dst;
  251. if (pktdst->sa_family != AF_INET6 ||
  252. pktdst->sa_len != sizeof(struct sockaddr_in6)) {
  253. return;
  254. }
  255. if ((unsigned)cmd >= PRC_NCMDS) {
  256. return;
  257. }
  258. if (PRC_IS_REDIRECT(cmd)) {
  259. d = NULL;
  260. } else if (inet6ctlerrmap[cmd] == 0) {
  261. return;
  262. }
  263. /* If the parameter is from icmp6, decode it. */
  264. if (d != NULL) {
  265. ip6cp = (struct ip6ctlparam *)d;
  266. } else {
  267. ip6cp = (struct ip6ctlparam *)NULL;
  268. }
  269. if (ip6cp != NULL) {
  270. /*
  271. * XXX: We assume that when IPV6 is non NULL, M and OFF are
  272. * valid.
  273. */
  274. if (ip6cp->ip6c_m == NULL) {
  275. return;
  276. }
  277. /*
  278. * Check if we can safely examine the ports and the
  279. * verification tag of the SCTP common header.
  280. */
  281. if (ip6cp->ip6c_m->m_pkthdr.len <
  282. (int32_t)(ip6cp->ip6c_off + offsetof(struct sctphdr, checksum))) {
  283. return;
  284. }
  285. /* Copy out the port numbers and the verification tag. */
  286. memset(&sh, 0, sizeof(sh));
  287. m_copydata(ip6cp->ip6c_m,
  288. ip6cp->ip6c_off,
  289. sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t),
  290. (caddr_t)&sh);
  291. memset(&src, 0, sizeof(struct sockaddr_in6));
  292. src.sin6_family = AF_INET6;
  293. src.sin6_len = sizeof(struct sockaddr_in6);
  294. src.sin6_port = sh.src_port;
  295. src.sin6_addr = ip6cp->ip6c_ip6->ip6_src;
  296. if (in6_setscope(&src.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
  297. return;
  298. }
  299. memset(&dst, 0, sizeof(struct sockaddr_in6));
  300. dst.sin6_family = AF_INET6;
  301. dst.sin6_len = sizeof(struct sockaddr_in6);
  302. dst.sin6_port = sh.dest_port;
  303. dst.sin6_addr = ip6cp->ip6c_ip6->ip6_dst;
  304. if (in6_setscope(&dst.sin6_addr, ip6cp->ip6c_m->m_pkthdr.rcvif, NULL) != 0) {
  305. return;
  306. }
  307. inp = NULL;
  308. net = NULL;
  309. stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
  310. (struct sockaddr *)&src,
  311. &inp, &net, 1, SCTP_DEFAULT_VRFID);
  312. if ((stcb != NULL) &&
  313. (net != NULL) &&
  314. (inp != NULL)) {
  315. /* Check the verification tag */
  316. if (ntohl(sh.v_tag) != 0) {
  317. /*
  318. * This must be the verification tag used
  319. * for sending out packets. We don't
  320. * consider packets reflecting the
  321. * verification tag.
  322. */
  323. if (ntohl(sh.v_tag) != stcb->asoc.peer_vtag) {
  324. SCTP_TCB_UNLOCK(stcb);
  325. return;
  326. }
  327. } else {
  328. if (ip6cp->ip6c_m->m_pkthdr.len >=
  329. ip6cp->ip6c_off + sizeof(struct sctphdr) +
  330. sizeof(struct sctp_chunkhdr) +
  331. offsetof(struct sctp_init, a_rwnd)) {
  332. /*
  333. * In this case we can check if we
  334. * got an INIT chunk and if the
  335. * initiate tag matches.
  336. */
  337. uint32_t initiate_tag;
  338. uint8_t chunk_type;
  339. m_copydata(ip6cp->ip6c_m,
  340. ip6cp->ip6c_off +
  341. sizeof(struct sctphdr),
  342. sizeof(uint8_t),
  343. (caddr_t)&chunk_type);
  344. m_copydata(ip6cp->ip6c_m,
  345. ip6cp->ip6c_off +
  346. sizeof(struct sctphdr) +
  347. sizeof(struct sctp_chunkhdr),
  348. sizeof(uint32_t),
  349. (caddr_t)&initiate_tag);
  350. if ((chunk_type != SCTP_INITIATION) ||
  351. (ntohl(initiate_tag) != stcb->asoc.my_vtag)) {
  352. SCTP_TCB_UNLOCK(stcb);
  353. return;
  354. }
  355. } else {
  356. SCTP_TCB_UNLOCK(stcb);
  357. return;
  358. }
  359. }
  360. sctp6_notify(inp, stcb, net,
  361. ip6cp->ip6c_icmp6->icmp6_type,
  362. ip6cp->ip6c_icmp6->icmp6_code,
  363. ntohl(ip6cp->ip6c_icmp6->icmp6_mtu));
  364. } else {
  365. if ((stcb == NULL) && (inp != NULL)) {
  366. /* reduce inp's ref-count */
  367. SCTP_INP_WLOCK(inp);
  368. SCTP_INP_DECR_REF(inp);
  369. SCTP_INP_WUNLOCK(inp);
  370. }
  371. if (stcb) {
  372. SCTP_TCB_UNLOCK(stcb);
  373. }
  374. }
  375. }
  376. }
  377. /*
  378. * this routine can probably be collasped into the one in sctp_userreq.c
  379. * since they do the same thing and now we lookup with a sockaddr
  380. */
  381. static int
  382. sctp6_getcred(SYSCTL_HANDLER_ARGS)
  383. {
  384. struct xucred xuc;
  385. struct sockaddr_in6 addrs[2];
  386. struct sctp_inpcb *inp;
  387. struct sctp_nets *net;
  388. struct sctp_tcb *stcb;
  389. int error;
  390. uint32_t vrf_id;
  391. vrf_id = SCTP_DEFAULT_VRFID;
  392. error = priv_check(req->td, PRIV_NETINET_GETCRED);
  393. if (error)
  394. return (error);
  395. if (req->newlen != sizeof(addrs)) {
  396. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  397. return (EINVAL);
  398. }
  399. if (req->oldlen != sizeof(struct ucred)) {
  400. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  401. return (EINVAL);
  402. }
  403. error = SYSCTL_IN(req, addrs, sizeof(addrs));
  404. if (error)
  405. return (error);
  406. stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[1]),
  407. sin6tosa(&addrs[0]),
  408. &inp, &net, 1, vrf_id);
  409. if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
  410. if ((inp != NULL) && (stcb == NULL)) {
  411. /* reduce ref-count */
  412. SCTP_INP_WLOCK(inp);
  413. SCTP_INP_DECR_REF(inp);
  414. goto cred_can_cont;
  415. }
  416. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  417. error = ENOENT;
  418. goto out;
  419. }
  420. SCTP_TCB_UNLOCK(stcb);
  421. /*
  422. * We use the write lock here, only since in the error leg we need
  423. * it. If we used RLOCK, then we would have to
  424. * wlock/decr/unlock/rlock. Which in theory could create a hole.
  425. * Better to use higher wlock.
  426. */
  427. SCTP_INP_WLOCK(inp);
  428. cred_can_cont:
  429. error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket);
  430. if (error) {
  431. SCTP_INP_WUNLOCK(inp);
  432. goto out;
  433. }
  434. cru2x(inp->sctp_socket->so_cred, &xuc);
  435. SCTP_INP_WUNLOCK(inp);
  436. error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
  437. out:
  438. return (error);
  439. }
  440. SYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred,
  441. CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
  442. 0, 0, sctp6_getcred, "S,ucred",
  443. "Get the ucred of a SCTP6 connection");
  444. /* This is the same as the sctp_abort() could be made common */
  445. static void
  446. sctp6_abort(struct socket *so)
  447. {
  448. struct epoch_tracker et;
  449. struct sctp_inpcb *inp;
  450. uint32_t flags;
  451. inp = (struct sctp_inpcb *)so->so_pcb;
  452. if (inp == NULL) {
  453. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  454. return;
  455. }
  456. NET_EPOCH_ENTER(et);
  457. sctp_must_try_again:
  458. flags = inp->sctp_flags;
  459. #ifdef SCTP_LOG_CLOSING
  460. sctp_log_closing(inp, NULL, 17);
  461. #endif
  462. if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  463. (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
  464. #ifdef SCTP_LOG_CLOSING
  465. sctp_log_closing(inp, NULL, 16);
  466. #endif
  467. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
  468. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  469. SOCK_LOCK(so);
  470. SCTP_SB_CLEAR(so->so_snd);
  471. /*
  472. * same for the rcv ones, they are only here for the
  473. * accounting/select.
  474. */
  475. SCTP_SB_CLEAR(so->so_rcv);
  476. /* Now null out the reference, we are completely detached. */
  477. so->so_pcb = NULL;
  478. SOCK_UNLOCK(so);
  479. } else {
  480. flags = inp->sctp_flags;
  481. if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
  482. goto sctp_must_try_again;
  483. }
  484. }
  485. NET_EPOCH_EXIT(et);
  486. return;
  487. }
  488. static int
  489. sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED)
  490. {
  491. int error;
  492. struct sctp_inpcb *inp;
  493. uint32_t vrf_id = SCTP_DEFAULT_VRFID;
  494. inp = (struct sctp_inpcb *)so->so_pcb;
  495. if (inp != NULL) {
  496. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  497. return (EINVAL);
  498. }
  499. if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  500. error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
  501. if (error)
  502. return (error);
  503. }
  504. error = sctp_inpcb_alloc(so, vrf_id);
  505. if (error)
  506. return (error);
  507. inp = (struct sctp_inpcb *)so->so_pcb;
  508. SCTP_INP_WLOCK(inp);
  509. inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */
  510. inp->ip_inp.inp.inp_vflag |= INP_IPV6;
  511. inp->ip_inp.inp.in6p_hops = -1; /* use kernel default */
  512. inp->ip_inp.inp.in6p_cksum = -1; /* just to be sure */
  513. #ifdef INET
  514. /*
  515. * XXX: ugly!! IPv4 TTL initialization is necessary for an IPv6
  516. * socket as well, because the socket may be bound to an IPv6
  517. * wildcard address, which may match an IPv4-mapped IPv6 address.
  518. */
  519. inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
  520. #endif
  521. SCTP_INP_WUNLOCK(inp);
  522. return (0);
  523. }
  524. static int
  525. sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
  526. {
  527. struct sctp_inpcb *inp;
  528. int error;
  529. u_char vflagsav;
  530. inp = (struct sctp_inpcb *)so->so_pcb;
  531. if (inp == NULL) {
  532. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  533. return (EINVAL);
  534. }
  535. if (addr) {
  536. switch (addr->sa_family) {
  537. #ifdef INET
  538. case AF_INET:
  539. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  540. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  541. return (EINVAL);
  542. }
  543. break;
  544. #endif
  545. #ifdef INET6
  546. case AF_INET6:
  547. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  548. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  549. return (EINVAL);
  550. }
  551. break;
  552. #endif
  553. default:
  554. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  555. return (EINVAL);
  556. }
  557. }
  558. vflagsav = inp->ip_inp.inp.inp_vflag;
  559. inp->ip_inp.inp.inp_vflag &= ~INP_IPV4;
  560. inp->ip_inp.inp.inp_vflag |= INP_IPV6;
  561. if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp) == 0)) {
  562. switch (addr->sa_family) {
  563. #ifdef INET
  564. case AF_INET:
  565. /* binding v4 addr to v6 socket, so reset flags */
  566. inp->ip_inp.inp.inp_vflag |= INP_IPV4;
  567. inp->ip_inp.inp.inp_vflag &= ~INP_IPV6;
  568. break;
  569. #endif
  570. #ifdef INET6
  571. case AF_INET6:
  572. {
  573. struct sockaddr_in6 *sin6_p;
  574. sin6_p = (struct sockaddr_in6 *)addr;
  575. if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) {
  576. inp->ip_inp.inp.inp_vflag |= INP_IPV4;
  577. }
  578. #ifdef INET
  579. if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
  580. struct sockaddr_in sin;
  581. in6_sin6_2_sin(&sin, sin6_p);
  582. inp->ip_inp.inp.inp_vflag |= INP_IPV4;
  583. inp->ip_inp.inp.inp_vflag &= ~INP_IPV6;
  584. error = sctp_inpcb_bind(so, (struct sockaddr *)&sin, NULL, p);
  585. goto out;
  586. }
  587. #endif
  588. break;
  589. }
  590. #endif
  591. default:
  592. break;
  593. }
  594. } else if (addr != NULL) {
  595. struct sockaddr_in6 *sin6_p;
  596. /* IPV6_V6ONLY socket */
  597. #ifdef INET
  598. if (addr->sa_family == AF_INET) {
  599. /* can't bind v4 addr to v6 only socket! */
  600. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  601. error = EINVAL;
  602. goto out;
  603. }
  604. #endif
  605. sin6_p = (struct sockaddr_in6 *)addr;
  606. if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
  607. /* can't bind v4-mapped addrs either! */
  608. /* NOTE: we don't support SIIT */
  609. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  610. error = EINVAL;
  611. goto out;
  612. }
  613. }
  614. error = sctp_inpcb_bind(so, addr, NULL, p);
  615. out:
  616. if (error != 0)
  617. inp->ip_inp.inp.inp_vflag = vflagsav;
  618. return (error);
  619. }
  620. static void
  621. sctp6_close(struct socket *so)
  622. {
  623. sctp_close(so);
  624. }
  625. /* This could be made common with sctp_detach() since they are identical */
  626. static
  627. int
  628. sctp6_disconnect(struct socket *so)
  629. {
  630. return (sctp_disconnect(so));
  631. }
  632. int
  633. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  634. struct mbuf *control, struct thread *p);
  635. static int
  636. sctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  637. struct mbuf *control, struct thread *p)
  638. {
  639. struct sctp_inpcb *inp;
  640. #ifdef INET
  641. struct sockaddr_in6 *sin6;
  642. #endif /* INET */
  643. /* No SPL needed since sctp_output does this */
  644. inp = (struct sctp_inpcb *)so->so_pcb;
  645. if (inp == NULL) {
  646. if (control) {
  647. SCTP_RELEASE_PKT(control);
  648. control = NULL;
  649. }
  650. SCTP_RELEASE_PKT(m);
  651. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  652. return (EINVAL);
  653. }
  654. /*
  655. * For the TCP model we may get a NULL addr, if we are a connected
  656. * socket thats ok.
  657. */
  658. if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
  659. (addr == NULL)) {
  660. goto connected_type;
  661. }
  662. if (addr == NULL) {
  663. SCTP_RELEASE_PKT(m);
  664. if (control) {
  665. SCTP_RELEASE_PKT(control);
  666. control = NULL;
  667. }
  668. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EDESTADDRREQ);
  669. return (EDESTADDRREQ);
  670. }
  671. #ifdef INET
  672. sin6 = (struct sockaddr_in6 *)addr;
  673. if (SCTP_IPV6_V6ONLY(inp)) {
  674. /*
  675. * if IPV6_V6ONLY flag, we discard datagrams destined to a
  676. * v4 addr or v4-mapped addr
  677. */
  678. if (addr->sa_family == AF_INET) {
  679. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  680. return (EINVAL);
  681. }
  682. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  683. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  684. return (EINVAL);
  685. }
  686. }
  687. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  688. struct sockaddr_in sin;
  689. /* convert v4-mapped into v4 addr and send */
  690. in6_sin6_2_sin(&sin, sin6);
  691. return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin, control, p));
  692. }
  693. #endif /* INET */
  694. connected_type:
  695. /* now what about control */
  696. if (control) {
  697. if (inp->control) {
  698. SCTP_PRINTF("huh? control set?\n");
  699. SCTP_RELEASE_PKT(inp->control);
  700. inp->control = NULL;
  701. }
  702. inp->control = control;
  703. }
  704. /* Place the data */
  705. if (inp->pkt) {
  706. SCTP_BUF_NEXT(inp->pkt_last) = m;
  707. inp->pkt_last = m;
  708. } else {
  709. inp->pkt_last = inp->pkt = m;
  710. }
  711. if (
  712. /* FreeBSD and MacOSX uses a flag passed */
  713. ((flags & PRUS_MORETOCOME) == 0)
  714. ) {
  715. /*
  716. * note with the current version this code will only be used
  717. * by OpenBSD, NetBSD and FreeBSD have methods for
  718. * re-defining sosend() to use sctp_sosend(). One can
  719. * optionaly switch back to this code (by changing back the
  720. * defininitions but this is not advisable.
  721. */
  722. struct epoch_tracker et;
  723. int ret;
  724. NET_EPOCH_ENTER(et);
  725. ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
  726. NET_EPOCH_EXIT(et);
  727. inp->pkt = NULL;
  728. inp->control = NULL;
  729. return (ret);
  730. } else {
  731. return (0);
  732. }
  733. }
  734. static int
  735. sctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
  736. {
  737. struct epoch_tracker et;
  738. uint32_t vrf_id;
  739. int error = 0;
  740. struct sctp_inpcb *inp;
  741. struct sctp_tcb *stcb;
  742. #ifdef INET
  743. struct sockaddr_in6 *sin6;
  744. union sctp_sockstore store;
  745. #endif
  746. inp = (struct sctp_inpcb *)so->so_pcb;
  747. if (inp == NULL) {
  748. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
  749. return (ECONNRESET); /* I made the same as TCP since we are
  750. * not setup? */
  751. }
  752. if (addr == NULL) {
  753. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  754. return (EINVAL);
  755. }
  756. switch (addr->sa_family) {
  757. #ifdef INET
  758. case AF_INET:
  759. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  760. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  761. return (EINVAL);
  762. }
  763. break;
  764. #endif
  765. #ifdef INET6
  766. case AF_INET6:
  767. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  768. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  769. return (EINVAL);
  770. }
  771. break;
  772. #endif
  773. default:
  774. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  775. return (EINVAL);
  776. }
  777. vrf_id = inp->def_vrf_id;
  778. SCTP_ASOC_CREATE_LOCK(inp);
  779. SCTP_INP_RLOCK(inp);
  780. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) ==
  781. SCTP_PCB_FLAGS_UNBOUND) {
  782. /* Bind a ephemeral port */
  783. SCTP_INP_RUNLOCK(inp);
  784. error = sctp6_bind(so, NULL, p);
  785. if (error) {
  786. SCTP_ASOC_CREATE_UNLOCK(inp);
  787. return (error);
  788. }
  789. SCTP_INP_RLOCK(inp);
  790. }
  791. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  792. (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
  793. /* We are already connected AND the TCP model */
  794. SCTP_INP_RUNLOCK(inp);
  795. SCTP_ASOC_CREATE_UNLOCK(inp);
  796. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EADDRINUSE);
  797. return (EADDRINUSE);
  798. }
  799. #ifdef INET
  800. sin6 = (struct sockaddr_in6 *)addr;
  801. if (SCTP_IPV6_V6ONLY(inp)) {
  802. /*
  803. * if IPV6_V6ONLY flag, ignore connections destined to a v4
  804. * addr or v4-mapped addr
  805. */
  806. if (addr->sa_family == AF_INET) {
  807. SCTP_INP_RUNLOCK(inp);
  808. SCTP_ASOC_CREATE_UNLOCK(inp);
  809. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  810. return (EINVAL);
  811. }
  812. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  813. SCTP_INP_RUNLOCK(inp);
  814. SCTP_ASOC_CREATE_UNLOCK(inp);
  815. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  816. return (EINVAL);
  817. }
  818. }
  819. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  820. /* convert v4-mapped into v4 addr */
  821. in6_sin6_2_sin(&store.sin, sin6);
  822. addr = &store.sa;
  823. }
  824. #endif /* INET */
  825. /* Now do we connect? */
  826. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  827. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  828. if (stcb) {
  829. SCTP_TCB_LOCK(stcb);
  830. }
  831. SCTP_INP_RUNLOCK(inp);
  832. } else {
  833. SCTP_INP_RUNLOCK(inp);
  834. SCTP_INP_WLOCK(inp);
  835. SCTP_INP_INCR_REF(inp);
  836. SCTP_INP_WUNLOCK(inp);
  837. stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
  838. if (stcb == NULL) {
  839. SCTP_INP_WLOCK(inp);
  840. SCTP_INP_DECR_REF(inp);
  841. SCTP_INP_WUNLOCK(inp);
  842. }
  843. }
  844. if (stcb != NULL) {
  845. /* Already have or am bring up an association */
  846. SCTP_ASOC_CREATE_UNLOCK(inp);
  847. SCTP_TCB_UNLOCK(stcb);
  848. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EALREADY);
  849. return (EALREADY);
  850. }
  851. /* We are GOOD to go */
  852. stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
  853. inp->sctp_ep.pre_open_stream_count,
  854. inp->sctp_ep.port, p,
  855. SCTP_INITIALIZE_AUTH_PARAMS);
  856. SCTP_ASOC_CREATE_UNLOCK(inp);
  857. if (stcb == NULL) {
  858. /* Gak! no memory */
  859. return (error);
  860. }
  861. if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
  862. stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
  863. /* Set the connected flag so we can queue data */
  864. soisconnecting(so);
  865. }
  866. SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
  867. (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
  868. NET_EPOCH_ENTER(et);
  869. sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
  870. SCTP_TCB_UNLOCK(stcb);
  871. NET_EPOCH_EXIT(et);
  872. return (error);
  873. }
  874. static int
  875. sctp6_getaddr(struct socket *so, struct sockaddr **addr)
  876. {
  877. struct sockaddr_in6 *sin6;
  878. struct sctp_inpcb *inp;
  879. uint32_t vrf_id;
  880. struct sctp_ifa *sctp_ifa;
  881. int error;
  882. /*
  883. * Do the malloc first in case it blocks.
  884. */
  885. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6));
  886. if (sin6 == NULL)
  887. return (ENOMEM);
  888. sin6->sin6_family = AF_INET6;
  889. sin6->sin6_len = sizeof(*sin6);
  890. inp = (struct sctp_inpcb *)so->so_pcb;
  891. if (inp == NULL) {
  892. SCTP_FREE_SONAME(sin6);
  893. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
  894. return (ECONNRESET);
  895. }
  896. SCTP_INP_RLOCK(inp);
  897. sin6->sin6_port = inp->sctp_lport;
  898. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  899. /* For the bound all case you get back 0 */
  900. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  901. struct sctp_tcb *stcb;
  902. struct sockaddr_in6 *sin_a6;
  903. struct sctp_nets *net;
  904. int fnd;
  905. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  906. if (stcb == NULL) {
  907. SCTP_INP_RUNLOCK(inp);
  908. SCTP_FREE_SONAME(sin6);
  909. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  910. return (ENOENT);
  911. }
  912. fnd = 0;
  913. sin_a6 = NULL;
  914. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  915. sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr;
  916. if (sin_a6 == NULL)
  917. /* this will make coverity happy */
  918. continue;
  919. if (sin_a6->sin6_family == AF_INET6) {
  920. fnd = 1;
  921. break;
  922. }
  923. }
  924. if ((!fnd) || (sin_a6 == NULL)) {
  925. /* punt */
  926. SCTP_INP_RUNLOCK(inp);
  927. SCTP_FREE_SONAME(sin6);
  928. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  929. return (ENOENT);
  930. }
  931. vrf_id = inp->def_vrf_id;
  932. sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *)&net->ro, net, 0, vrf_id);
  933. if (sctp_ifa) {
  934. sin6->sin6_addr = sctp_ifa->address.sin6.sin6_addr;
  935. }
  936. } else {
  937. /* For the bound all case you get back 0 */
  938. memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
  939. }
  940. } else {
  941. /* Take the first IPv6 address in the list */
  942. struct sctp_laddr *laddr;
  943. int fnd = 0;
  944. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  945. if (laddr->ifa->address.sa.sa_family == AF_INET6) {
  946. struct sockaddr_in6 *sin_a;
  947. sin_a = &laddr->ifa->address.sin6;
  948. sin6->sin6_addr = sin_a->sin6_addr;
  949. fnd = 1;
  950. break;
  951. }
  952. }
  953. if (!fnd) {
  954. SCTP_FREE_SONAME(sin6);
  955. SCTP_INP_RUNLOCK(inp);
  956. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  957. return (ENOENT);
  958. }
  959. }
  960. SCTP_INP_RUNLOCK(inp);
  961. /* Scoping things for v6 */
  962. if ((error = sa6_recoverscope(sin6)) != 0) {
  963. SCTP_FREE_SONAME(sin6);
  964. return (error);
  965. }
  966. (*addr) = (struct sockaddr *)sin6;
  967. return (0);
  968. }
  969. static int
  970. sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
  971. {
  972. struct sockaddr_in6 *sin6;
  973. int fnd;
  974. struct sockaddr_in6 *sin_a6;
  975. struct sctp_inpcb *inp;
  976. struct sctp_tcb *stcb;
  977. struct sctp_nets *net;
  978. int error;
  979. /* Do the malloc first in case it blocks. */
  980. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  981. if (sin6 == NULL)
  982. return (ENOMEM);
  983. sin6->sin6_family = AF_INET6;
  984. sin6->sin6_len = sizeof(*sin6);
  985. inp = (struct sctp_inpcb *)so->so_pcb;
  986. if ((inp == NULL) ||
  987. ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
  988. /* UDP type and listeners will drop out here */
  989. SCTP_FREE_SONAME(sin6);
  990. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOTCONN);
  991. return (ENOTCONN);
  992. }
  993. SCTP_INP_RLOCK(inp);
  994. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  995. if (stcb) {
  996. SCTP_TCB_LOCK(stcb);
  997. }
  998. SCTP_INP_RUNLOCK(inp);
  999. if (stcb == NULL) {
  1000. SCTP_FREE_SONAME(sin6);
  1001. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
  1002. return (ECONNRESET);
  1003. }
  1004. fnd = 0;
  1005. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  1006. sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr;
  1007. if (sin_a6->sin6_family == AF_INET6) {
  1008. fnd = 1;
  1009. sin6->sin6_port = stcb->rport;
  1010. sin6->sin6_addr = sin_a6->sin6_addr;
  1011. break;
  1012. }
  1013. }
  1014. SCTP_TCB_UNLOCK(stcb);
  1015. if (!fnd) {
  1016. /* No IPv4 address */
  1017. SCTP_FREE_SONAME(sin6);
  1018. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
  1019. return (ENOENT);
  1020. }
  1021. if ((error = sa6_recoverscope(sin6)) != 0) {
  1022. SCTP_FREE_SONAME(sin6);
  1023. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, error);
  1024. return (error);
  1025. }
  1026. *addr = (struct sockaddr *)sin6;
  1027. return (0);
  1028. }
  1029. static int
  1030. sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
  1031. {
  1032. struct inpcb *inp = sotoinpcb(so);
  1033. int error;
  1034. if (inp == NULL) {
  1035. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1036. return (EINVAL);
  1037. }
  1038. /* allow v6 addresses precedence */
  1039. error = sctp6_getaddr(so, nam);
  1040. #ifdef INET
  1041. if (error) {
  1042. struct sockaddr_in6 *sin6;
  1043. /* try v4 next if v6 failed */
  1044. error = sctp_ingetaddr(so, nam);
  1045. if (error) {
  1046. return (error);
  1047. }
  1048. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  1049. if (sin6 == NULL) {
  1050. SCTP_FREE_SONAME(*nam);
  1051. return (ENOMEM);
  1052. }
  1053. in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
  1054. SCTP_FREE_SONAME(*nam);
  1055. *nam = (struct sockaddr *)sin6;
  1056. }
  1057. #endif
  1058. return (error);
  1059. }
  1060. static int
  1061. sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
  1062. {
  1063. struct inpcb *inp = sotoinpcb(so);
  1064. int error;
  1065. if (inp == NULL) {
  1066. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
  1067. return (EINVAL);
  1068. }
  1069. /* allow v6 addresses precedence */
  1070. error = sctp6_peeraddr(so, nam);
  1071. #ifdef INET
  1072. if (error) {
  1073. struct sockaddr_in6 *sin6;
  1074. /* try v4 next if v6 failed */
  1075. error = sctp_peeraddr(so, nam);
  1076. if (error) {
  1077. return (error);
  1078. }
  1079. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  1080. if (sin6 == NULL) {
  1081. SCTP_FREE_SONAME(*nam);
  1082. return (ENOMEM);
  1083. }
  1084. in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
  1085. SCTP_FREE_SONAME(*nam);
  1086. *nam = (struct sockaddr *)sin6;
  1087. }
  1088. #endif
  1089. return (error);
  1090. }
  1091. struct pr_usrreqs sctp6_usrreqs = {
  1092. .pru_abort = sctp6_abort,
  1093. .pru_accept = sctp_accept,
  1094. .pru_attach = sctp6_attach,
  1095. .pru_bind = sctp6_bind,
  1096. .pru_connect = sctp6_connect,
  1097. .pru_control = in6_control,
  1098. .pru_close = sctp6_close,
  1099. .pru_detach = sctp6_close,
  1100. .pru_sopoll = sopoll_generic,
  1101. .pru_flush = sctp_flush,
  1102. .pru_disconnect = sctp6_disconnect,
  1103. .pru_listen = sctp_listen,
  1104. .pru_peeraddr = sctp6_getpeeraddr,
  1105. .pru_send = sctp6_send,
  1106. .pru_shutdown = sctp_shutdown,
  1107. .pru_sockaddr = sctp6_in6getaddr,
  1108. .pru_sosend = sctp_sosend,
  1109. .pru_soreceive = sctp_soreceive
  1110. };
  1111. #endif