sctp6_usrreq.c (179157) | sctp6_usrreq.c (179783) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 16 unchanged lines hidden (view full) --- 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30/* $KAME: sctp6_usrreq.c,v 1.38 2005/08/24 08:08:56 suz Exp $ */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 16 unchanged lines hidden (view full) --- 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30/* $KAME: sctp6_usrreq.c,v 1.38 2005/08/24 08:08:56 suz Exp $ */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 179157 2008-05-20 13:47:46Z rrs $"); | 33__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 179783 2008-06-14 07:58:05Z rrs $"); |
34 35#include <netinet/sctp_os.h> 36#include <sys/proc.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctp_header.h> 39#include <netinet/sctp_var.h> 40#if defined(INET6) 41#include <netinet6/sctp6_var.h> --- 4 unchanged lines hidden (view full) --- 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> | 34 35#include <netinet/sctp_os.h> 36#include <sys/proc.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctp_header.h> 39#include <netinet/sctp_var.h> 40#if defined(INET6) 41#include <netinet6/sctp6_var.h> --- 4 unchanged lines hidden (view full) --- 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/udp.h> |
|
54 55#ifdef IPSEC 56#include <netipsec/ipsec.h> 57#if defined(INET6) 58#include <netipsec/ipsec6.h> 59#endif /* INET6 */ 60#endif /* IPSEC */ 61 --- 12 unchanged lines hidden (view full) --- 74 uint32_t vrf_id = 0; 75 struct inpcb *in6p_ip; 76 struct sctp_chunkhdr *ch; 77 int length, mlen, offset, iphlen; 78 uint8_t ecn_bits; 79 struct sctp_tcb *stcb = NULL; 80 int pkt_len = 0; 81 int off = *offp; | 55 56#ifdef IPSEC 57#include <netipsec/ipsec.h> 58#if defined(INET6) 59#include <netipsec/ipsec6.h> 60#endif /* INET6 */ 61#endif /* IPSEC */ 62 --- 12 unchanged lines hidden (view full) --- 75 uint32_t vrf_id = 0; 76 struct inpcb *in6p_ip; 77 struct sctp_chunkhdr *ch; 78 int length, mlen, offset, iphlen; 79 uint8_t ecn_bits; 80 struct sctp_tcb *stcb = NULL; 81 int pkt_len = 0; 82 int off = *offp; |
83 uint16_t port = 0; |
|
82 83 /* get the VRF and table id's */ 84 if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { 85 SCTP_RELEASE_PKT(*i_pak); 86 return (-1); 87 } 88 m = SCTP_HEADER_TO_CHAIN(*i_pak); 89 pkt_len = SCTP_HEADER_LEN((*i_pak)); --- 30 unchanged lines hidden (view full) --- 120 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 121 /* No multi-cast support in SCTP */ 122 goto bad; 123 } 124 /* destination port of 0 is illegal, based on RFC2960. */ 125 if (sh->dest_port == 0) 126 goto bad; 127 check = sh->checksum; /* save incoming checksum */ | 84 85 /* get the VRF and table id's */ 86 if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { 87 SCTP_RELEASE_PKT(*i_pak); 88 return (-1); 89 } 90 m = SCTP_HEADER_TO_CHAIN(*i_pak); 91 pkt_len = SCTP_HEADER_LEN((*i_pak)); --- 30 unchanged lines hidden (view full) --- 122 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 123 /* No multi-cast support in SCTP */ 124 goto bad; 125 } 126 /* destination port of 0 is illegal, based on RFC2960. */ 127 if (sh->dest_port == 0) 128 goto bad; 129 check = sh->checksum; /* save incoming checksum */ |
128 if ((check == 0) && (sctp_no_csum_on_loopback) && | 130 if ((check == 0) && (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback)) && |
129 (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &ip6->ip6_dst))) { 130 goto sctp_skip_csum; 131 } 132 sh->checksum = 0; /* prepare for calc */ 133 calc_check = sctp_calculate_sum(m, &mlen, iphlen); 134 if (calc_check != check) { 135 SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 136 calc_check, check, m, mlen, iphlen); 137 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), 138 sh, ch, &in6p, &net, vrf_id); | 131 (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, &ip6->ip6_dst))) { 132 goto sctp_skip_csum; 133 } 134 sh->checksum = 0; /* prepare for calc */ 135 calc_check = sctp_calculate_sum(m, &mlen, iphlen); 136 if (calc_check != check) { 137 SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 138 calc_check, check, m, mlen, iphlen); 139 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), 140 sh, ch, &in6p, &net, vrf_id); |
141 if ((net) && (port)) { 142 if (net->port == 0) { 143 sctp_pathmtu_adjustment(in6p, stcb, net, net->mtu - sizeof(struct udphdr)); 144 } 145 net->port = port; 146 } |
|
139 /* in6p's ref-count increased && stcb locked */ 140 if ((in6p) && (stcb)) { 141 sctp_send_packet_dropped(stcb, net, m, iphlen, 1); 142 sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); 143 } else if ((in6p != NULL) && (stcb == NULL)) { 144 refcount_up = 1; 145 } 146 SCTP_STAT_INCR(sctps_badsum); --- 5 unchanged lines hidden (view full) --- 152sctp_skip_csum: 153 net = NULL; 154 /* 155 * Locate pcb and tcb for datagram sctp_findassociation_addr() wants 156 * IP/SCTP/first chunk header... 157 */ 158 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), 159 sh, ch, &in6p, &net, vrf_id); | 147 /* in6p's ref-count increased && stcb locked */ 148 if ((in6p) && (stcb)) { 149 sctp_send_packet_dropped(stcb, net, m, iphlen, 1); 150 sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); 151 } else if ((in6p != NULL) && (stcb == NULL)) { 152 refcount_up = 1; 153 } 154 SCTP_STAT_INCR(sctps_badsum); --- 5 unchanged lines hidden (view full) --- 160sctp_skip_csum: 161 net = NULL; 162 /* 163 * Locate pcb and tcb for datagram sctp_findassociation_addr() wants 164 * IP/SCTP/first chunk header... 165 */ 166 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), 167 sh, ch, &in6p, &net, vrf_id); |
168 if ((net) && (port)) { 169 if (net->port == 0) { 170 sctp_pathmtu_adjustment(in6p, stcb, net, net->mtu - sizeof(struct udphdr)); 171 } 172 net->port = port; 173 } |
|
160 /* in6p's ref-count increased */ 161 if (in6p == NULL) { 162 struct sctp_init_chunk *init_chk, chunk_buf; 163 164 SCTP_STAT_INCR(sctps_noport); 165 if (ch->chunk_type == SCTP_INITIATION) { 166 /* 167 * we do a trick here to get the INIT tag, dig in --- 4 unchanged lines hidden (view full) --- 172 iphlen + sizeof(*sh), sizeof(*init_chk), 173 (uint8_t *) & chunk_buf); 174 if (init_chk) 175 sh->v_tag = init_chk->init.initiate_tag; 176 else 177 sh->v_tag = 0; 178 } 179 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { | 174 /* in6p's ref-count increased */ 175 if (in6p == NULL) { 176 struct sctp_init_chunk *init_chk, chunk_buf; 177 178 SCTP_STAT_INCR(sctps_noport); 179 if (ch->chunk_type == SCTP_INITIATION) { 180 /* 181 * we do a trick here to get the INIT tag, dig in --- 4 unchanged lines hidden (view full) --- 186 iphlen + sizeof(*sh), sizeof(*init_chk), 187 (uint8_t *) & chunk_buf); 188 if (init_chk) 189 sh->v_tag = init_chk->init.initiate_tag; 190 else 191 sh->v_tag = 0; 192 } 193 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { |
180 sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id, 0); | 194 sctp_send_shutdown_complete2(m, iphlen, sh, vrf_id, port); |
181 goto bad; 182 } 183 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 184 goto bad; 185 } 186 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) | 195 goto bad; 196 } 197 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 198 goto bad; 199 } 200 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) |
187 sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, 0); | 201 sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port); |
188 goto bad; 189 } else if (stcb == NULL) { 190 refcount_up = 1; 191 } 192 in6p_ip = (struct inpcb *)in6p; 193#ifdef IPSEC 194 /* 195 * Check AH/ESP integrity. --- 11 unchanged lines hidden (view full) --- 207 offset -= sizeof(*ch); 208 ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 209 210 /* Length now holds the total packet length payload + iphlen */ 211 length = ntohs(ip6->ip6_plen) + iphlen; 212 213 /* sa_ignore NO_NULL_CHK */ 214 sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, | 202 goto bad; 203 } else if (stcb == NULL) { 204 refcount_up = 1; 205 } 206 in6p_ip = (struct inpcb *)in6p; 207#ifdef IPSEC 208 /* 209 * Check AH/ESP integrity. --- 11 unchanged lines hidden (view full) --- 221 offset -= sizeof(*ch); 222 ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 223 224 /* Length now holds the total packet length payload + iphlen */ 225 length = ntohs(ip6->ip6_plen) + iphlen; 226 227 /* sa_ignore NO_NULL_CHK */ 228 sctp_common_input_processing(&m, iphlen, offset, length, sh, ch, |
215 in6p, stcb, net, ecn_bits, vrf_id, 0); | 229 in6p, stcb, net, ecn_bits, vrf_id, port); |
216 /* inp's ref-count reduced && stcb unlocked */ 217 /* XXX this stuff below gets moved to appropriate parts later... */ 218 if (m) 219 sctp_m_freem(m); 220 if ((in6p) && refcount_up) { 221 /* reduce ref-count */ 222 SCTP_INP_WLOCK(in6p); 223 SCTP_INP_DECR_REF(in6p); --- 155 unchanged lines hidden (view full) --- 379 * destination is set to the unreachable state, also 380 * set the destination to the PF state. 381 */ 382 /* 383 * Add debug message here if destination is not in 384 * PF state. 385 */ 386 /* Stop any running T3 timers here? */ | 230 /* inp's ref-count reduced && stcb unlocked */ 231 /* XXX this stuff below gets moved to appropriate parts later... */ 232 if (m) 233 sctp_m_freem(m); 234 if ((in6p) && refcount_up) { 235 /* reduce ref-count */ 236 SCTP_INP_WLOCK(in6p); 237 SCTP_INP_DECR_REF(in6p); --- 155 unchanged lines hidden (view full) --- 393 * destination is set to the unreachable state, also 394 * set the destination to the PF state. 395 */ 396 /* 397 * Add debug message here if destination is not in 398 * PF state. 399 */ 400 /* Stop any running T3 timers here? */ |
387 if (sctp_cmt_on_off && sctp_cmt_pf) { | 401 if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) { |
388 net->dest_state &= ~SCTP_ADDR_PF; 389 SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n", 390 net); 391 } 392 net->error_count = net->failure_threshold + 1; 393 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 394 stcb, SCTP_FAILED_THRESHOLD, 395 (void *)net, SCTP_SO_NOT_LOCKED); --- 243 unchanged lines hidden (view full) --- 639 uint32_t vrf_id = SCTP_DEFAULT_VRFID; 640 641 inp = (struct sctp_inpcb *)so->so_pcb; 642 if (inp != NULL) { 643 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 644 return EINVAL; 645 } 646 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { | 402 net->dest_state &= ~SCTP_ADDR_PF; 403 SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n", 404 net); 405 } 406 net->error_count = net->failure_threshold + 1; 407 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 408 stcb, SCTP_FAILED_THRESHOLD, 409 (void *)net, SCTP_SO_NOT_LOCKED); --- 243 unchanged lines hidden (view full) --- 653 uint32_t vrf_id = SCTP_DEFAULT_VRFID; 654 655 inp = (struct sctp_inpcb *)so->so_pcb; 656 if (inp != NULL) { 657 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 658 return EINVAL; 659 } 660 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { |
647 error = SCTP_SORESERVE(so, sctp_sendspace, sctp_recvspace); | 661 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); |
648 if (error) 649 return error; 650 } 651 error = sctp_inpcb_alloc(so, vrf_id); 652 if (error) 653 return error; 654 inp = (struct sctp_inpcb *)so->so_pcb; 655 SCTP_INP_WLOCK(inp); --- 617 unchanged lines hidden --- | 662 if (error) 663 return error; 664 } 665 error = sctp_inpcb_alloc(so, vrf_id); 666 if (error) 667 return error; 668 inp = (struct sctp_inpcb *)so->so_pcb; 669 SCTP_INP_WLOCK(inp); --- 617 unchanged lines hidden --- |