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