sctp6_usrreq.c (237569) | sctp6_usrreq.c (237715) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 237569 2012-06-25 19:13:43Z tuexen $"); | 34__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 237715 2012-06-28 16:01:08Z tuexen $"); |
35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_pcb.h> 39#include <netinet/sctp_header.h> 40#include <netinet/sctp_var.h> 41#if defined(INET6) 42#include <netinet6/sctp6_var.h> --- 23 unchanged lines hidden (view full) --- 66 67int 68sctp6_input(struct mbuf **i_pak, int *offp, int proto) 69{ 70 struct mbuf *m; 71 int iphlen; 72 uint32_t vrf_id = 0; 73 uint8_t ecn_bits; | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_pcb.h> 39#include <netinet/sctp_header.h> 40#include <netinet/sctp_var.h> 41#if defined(INET6) 42#include <netinet6/sctp6_var.h> --- 23 unchanged lines hidden (view full) --- 66 67int 68sctp6_input(struct mbuf **i_pak, int *offp, int proto) 69{ 70 struct mbuf *m; 71 int iphlen; 72 uint32_t vrf_id = 0; 73 uint8_t ecn_bits; |
74 struct sockaddr_in6 src, dst; |
|
74 struct ip6_hdr *ip6; 75 struct sctphdr *sh; 76 struct sctp_chunkhdr *ch; 77 struct sctp_inpcb *inp = NULL; 78 struct sctp_tcb *stcb = NULL; 79 struct sctp_nets *net = NULL; 80 int refcount_up = 0; 81 int length, offset; --- 44 unchanged lines hidden (view full) --- 126 IP6_EXTHDR_GET(sh, struct sctphdr *, m, iphlen, 127 (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))); 128 if (sh == NULL) { 129 SCTP_STAT_INCR(sctps_hdrops); 130 return (IPPROTO_DONE); 131 } 132 ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 133 offset -= sizeof(struct sctp_chunkhdr); | 75 struct ip6_hdr *ip6; 76 struct sctphdr *sh; 77 struct sctp_chunkhdr *ch; 78 struct sctp_inpcb *inp = NULL; 79 struct sctp_tcb *stcb = NULL; 80 struct sctp_nets *net = NULL; 81 int refcount_up = 0; 82 int length, offset; --- 44 unchanged lines hidden (view full) --- 127 IP6_EXTHDR_GET(sh, struct sctphdr *, m, iphlen, 128 (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))); 129 if (sh == NULL) { 130 SCTP_STAT_INCR(sctps_hdrops); 131 return (IPPROTO_DONE); 132 } 133 ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 134 offset -= sizeof(struct sctp_chunkhdr); |
134 if (faithprefix_p != NULL && (*faithprefix_p) (&ip6->ip6_dst)) { | 135 memset(&src, 0, sizeof(struct sockaddr_in6)); 136 src.sin6_family = AF_INET6; 137 src.sin6_len = sizeof(struct sockaddr_in6); 138 src.sin6_port = sh->src_port; 139 src.sin6_addr = ip6->ip6_src; 140 if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) { 141 goto bad; 142 } 143 memset(&dst, 0, sizeof(struct sockaddr_in6)); 144 dst.sin6_family = AF_INET6; 145 dst.sin6_len = sizeof(struct sockaddr_in6); 146 dst.sin6_port = sh->dest_port; 147 dst.sin6_addr = ip6->ip6_dst; 148 if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) { 149 goto bad; 150 } 151 if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) { |
135 /* XXX send icmp6 host/port unreach? */ 136 goto bad; 137 } 138 length = ntohs(ip6->ip6_plen) + iphlen; 139 /* Validate mbuf chain length with IP payload length. */ 140 if (SCTP_HEADER_LEN(*i_pak) != length) { 141 SCTPDBG(SCTP_DEBUG_INPUT1, 142 "sctp6_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(*i_pak)); --- 21 unchanged lines hidden (view full) --- 164 sh->checksum = 0; 165 calc_check = sctp_calculate_cksum(m, iphlen); 166 sh->checksum = check; 167 SCTP_STAT_INCR(sctps_recvswcrc); 168 if (calc_check != check) { 169 SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 170 calc_check, check, m, length, iphlen); 171 stcb = sctp_findassociation_addr(m, offset, | 152 /* XXX send icmp6 host/port unreach? */ 153 goto bad; 154 } 155 length = ntohs(ip6->ip6_plen) + iphlen; 156 /* Validate mbuf chain length with IP payload length. */ 157 if (SCTP_HEADER_LEN(*i_pak) != length) { 158 SCTPDBG(SCTP_DEBUG_INPUT1, 159 "sctp6_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(*i_pak)); --- 21 unchanged lines hidden (view full) --- 181 sh->checksum = 0; 182 calc_check = sctp_calculate_cksum(m, iphlen); 183 sh->checksum = check; 184 SCTP_STAT_INCR(sctps_recvswcrc); 185 if (calc_check != check) { 186 SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 187 calc_check, check, m, length, iphlen); 188 stcb = sctp_findassociation_addr(m, offset, |
189 (struct sockaddr *)&src, 190 (struct sockaddr *)&dst, |
|
172 sh, ch, &inp, &net, vrf_id); 173 if ((net) && (port)) { 174 if (net->port == 0) { 175 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 176 } 177 net->port = port; 178 } 179 if ((net != NULL) && (use_mflowid != 0)) { --- 15 unchanged lines hidden (view full) --- 195sctp_skip_csum: 196#endif 197 /* destination port of 0 is illegal, based on RFC2960. */ 198 if (sh->dest_port == 0) { 199 SCTP_STAT_INCR(sctps_hdrops); 200 goto bad; 201 } 202 stcb = sctp_findassociation_addr(m, offset, | 191 sh, ch, &inp, &net, vrf_id); 192 if ((net) && (port)) { 193 if (net->port == 0) { 194 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 195 } 196 net->port = port; 197 } 198 if ((net != NULL) && (use_mflowid != 0)) { --- 15 unchanged lines hidden (view full) --- 214sctp_skip_csum: 215#endif 216 /* destination port of 0 is illegal, based on RFC2960. */ 217 if (sh->dest_port == 0) { 218 SCTP_STAT_INCR(sctps_hdrops); 219 goto bad; 220 } 221 stcb = sctp_findassociation_addr(m, offset, |
222 (struct sockaddr *)&src, 223 (struct sockaddr *)&dst, |
|
203 sh, ch, &inp, &net, vrf_id); 204 if ((net) && (port)) { 205 if (net->port == 0) { 206 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 207 } 208 net->port = port; 209 } 210 if ((net != NULL) && (use_mflowid != 0)) { 211 net->flowid = mflowid; 212#ifdef INVARIANTS 213 net->flowidset = 1; 214#endif 215 } 216 if (inp == NULL) { 217 SCTP_STAT_INCR(sctps_noport); 218 if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) 219 goto bad; 220 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { | 224 sh, ch, &inp, &net, vrf_id); 225 if ((net) && (port)) { 226 if (net->port == 0) { 227 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 228 } 229 net->port = port; 230 } 231 if ((net != NULL) && (use_mflowid != 0)) { 232 net->flowid = mflowid; 233#ifdef INVARIANTS 234 net->flowidset = 1; 235#endif 236 } 237 if (inp == NULL) { 238 SCTP_STAT_INCR(sctps_noport); 239 if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) 240 goto bad; 241 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { |
221 sctp_send_shutdown_complete2(m, sh, | 242 sctp_send_shutdown_complete2((struct sockaddr *)&src, 243 (struct sockaddr *)&dst, 244 sh, |
222 use_mflowid, mflowid, 223 vrf_id, port); 224 goto bad; 225 } 226 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 227 goto bad; 228 } 229 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { 230 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 231 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 232 (ch->chunk_type != SCTP_INIT))) { | 245 use_mflowid, mflowid, 246 vrf_id, port); 247 goto bad; 248 } 249 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 250 goto bad; 251 } 252 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { 253 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 254 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 255 (ch->chunk_type != SCTP_INIT))) { |
233 sctp_send_abort(m, iphlen, sh, 0, NULL, | 256 sctp_send_abort(m, iphlen, 257 (struct sockaddr *)&src, 258 (struct sockaddr *)&dst, 259 sh, 0, NULL, |
234 use_mflowid, mflowid, 235 vrf_id, port); 236 } 237 } 238 goto bad; 239 } else if (stcb == NULL) { 240 refcount_up = 1; 241 } --- 6 unchanged lines hidden (view full) --- 248 MODULE_GLOBAL(ipsec6stat).in_polvio++; 249 SCTP_STAT_INCR(sctps_hdrops); 250 goto bad; 251 } 252#endif 253 254 ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 255 /* sa_ignore NO_NULL_CHK */ | 260 use_mflowid, mflowid, 261 vrf_id, port); 262 } 263 } 264 goto bad; 265 } else if (stcb == NULL) { 266 refcount_up = 1; 267 } --- 6 unchanged lines hidden (view full) --- 274 MODULE_GLOBAL(ipsec6stat).in_polvio++; 275 SCTP_STAT_INCR(sctps_hdrops); 276 goto bad; 277 } 278#endif 279 280 ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 281 /* sa_ignore NO_NULL_CHK */ |
256 sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, 257 inp, stcb, net, ecn_bits, | 282 sctp_common_input_processing(&m, iphlen, offset, length, 283 (struct sockaddr *)&src, 284 (struct sockaddr *)&dst, 285 sh, ch, inp, stcb, net, ecn_bits, |
258 use_mflowid, mflowid, 259 vrf_id, port); 260 if (m) { 261 sctp_m_freem(m); 262 } 263 if ((inp) && (refcount_up)) { 264 /* reduce ref-count */ 265 SCTP_INP_WLOCK(inp); --- 226 unchanged lines hidden (view full) --- 492 net = NULL; 493 m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off, sizeof(sh), 494 (caddr_t)&sh); 495 ip6cp->ip6c_src->sin6_port = sh.src_port; 496 final.sin6_len = sizeof(final); 497 final.sin6_family = AF_INET6; 498 final.sin6_addr = ((struct sockaddr_in6 *)pktdst)->sin6_addr; 499 final.sin6_port = sh.dest_port; | 286 use_mflowid, mflowid, 287 vrf_id, port); 288 if (m) { 289 sctp_m_freem(m); 290 } 291 if ((inp) && (refcount_up)) { 292 /* reduce ref-count */ 293 SCTP_INP_WLOCK(inp); --- 226 unchanged lines hidden (view full) --- 520 net = NULL; 521 m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off, sizeof(sh), 522 (caddr_t)&sh); 523 ip6cp->ip6c_src->sin6_port = sh.src_port; 524 final.sin6_len = sizeof(final); 525 final.sin6_family = AF_INET6; 526 final.sin6_addr = ((struct sockaddr_in6 *)pktdst)->sin6_addr; 527 final.sin6_port = sh.dest_port; |
500 stcb = sctp_findassociation_addr_sa((struct sockaddr *)ip6cp->ip6c_src, 501 (struct sockaddr *)&final, | 528 stcb = sctp_findassociation_addr_sa((struct sockaddr *)&final, 529 (struct sockaddr *)ip6cp->ip6c_src, |
502 &inp, &net, 1, vrf_id); 503 /* inp's ref-count increased && stcb locked */ 504 if (stcb != NULL && inp && (inp->sctp_socket != NULL)) { 505 if (cmd == PRC_MSGSIZE) { 506 sctp6_notify_mbuf(inp, 507 ip6cp->ip6c_icmp6, 508 &sh, 509 stcb, --- 50 unchanged lines hidden (view full) --- 560 if (req->oldlen != sizeof(struct ucred)) { 561 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 562 return (EINVAL); 563 } 564 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 565 if (error) 566 return (error); 567 | 530 &inp, &net, 1, vrf_id); 531 /* inp's ref-count increased && stcb locked */ 532 if (stcb != NULL && inp && (inp->sctp_socket != NULL)) { 533 if (cmd == PRC_MSGSIZE) { 534 sctp6_notify_mbuf(inp, 535 ip6cp->ip6c_icmp6, 536 &sh, 537 stcb, --- 50 unchanged lines hidden (view full) --- 588 if (req->oldlen != sizeof(struct ucred)) { 589 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 590 return (EINVAL); 591 } 592 error = SYSCTL_IN(req, addrs, sizeof(addrs)); 593 if (error) 594 return (error); 595 |
568 stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[0]), 569 sin6tosa(&addrs[1]), | 596 stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[1]), 597 sin6tosa(&addrs[0]), |
570 &inp, &net, 1, vrf_id); 571 if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 572 if ((inp != NULL) && (stcb == NULL)) { 573 /* reduce ref-count */ 574 SCTP_INP_WLOCK(inp); 575 SCTP_INP_DECR_REF(inp); 576 goto cred_can_cont; 577 } --- 755 unchanged lines hidden --- | 598 &inp, &net, 1, vrf_id); 599 if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 600 if ((inp != NULL) && (stcb == NULL)) { 601 /* reduce ref-count */ 602 SCTP_INP_WLOCK(inp); 603 SCTP_INP_DECR_REF(inp); 604 goto cred_can_cont; 605 } --- 755 unchanged lines hidden --- |