sctp6_usrreq.c (168124) | sctp6_usrreq.c (168299) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, 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. --- 15 unchanged lines hidden (view full) --- 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, 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. --- 15 unchanged lines hidden (view full) --- 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 168124 2007-03-31 11:47:30Z rrs $"); | 32__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 168299 2007-04-03 11:15:32Z rrs $"); |
33 34#include <netinet/sctp_os.h> 35#include <sys/proc.h> 36#include <netinet/sctp_pcb.h> 37#include <netinet/sctp_header.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_output.h> --- 13 unchanged lines hidden (view full) --- 54extern struct protosw inetsw[]; 55 56 57 58int 59sctp6_input(mp, offp, proto) 60 struct mbuf **mp; 61 int *offp; | 33 34#include <netinet/sctp_os.h> 35#include <sys/proc.h> 36#include <netinet/sctp_pcb.h> 37#include <netinet/sctp_header.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_output.h> --- 13 unchanged lines hidden (view full) --- 54extern struct protosw inetsw[]; 55 56 57 58int 59sctp6_input(mp, offp, proto) 60 struct mbuf **mp; 61 int *offp; |
62 | |
63 int proto; | 62 int proto; |
64 | |
65{ 66 struct mbuf *m; 67 struct ip6_hdr *ip6; 68 struct sctphdr *sh; 69 struct sctp_inpcb *in6p = NULL; 70 struct sctp_nets *net; 71 int refcount_up = 0; | 63{ 64 struct mbuf *m; 65 struct ip6_hdr *ip6; 66 struct sctphdr *sh; 67 struct sctp_inpcb *in6p = NULL; 68 struct sctp_nets *net; 69 int refcount_up = 0; |
72 u_int32_t check, calc_check; | 70 uint32_t check, calc_check, vrf_id; |
73 struct inpcb *in6p_ip; 74 struct sctp_chunkhdr *ch; 75 int length, mlen, offset, iphlen; | 71 struct inpcb *in6p_ip; 72 struct sctp_chunkhdr *ch; 73 int length, mlen, offset, iphlen; |
76 u_int8_t ecn_bits; | 74 uint8_t ecn_bits; |
77 struct sctp_tcb *stcb = NULL; 78 int off = *offp; 79 | 75 struct sctp_tcb *stcb = NULL; 76 int off = *offp; 77 |
78 vrf_id = SCTP_DEFAULT_VRFID; |
|
80 m = SCTP_HEADER_TO_CHAIN(*mp); 81 82 ip6 = mtod(m, struct ip6_hdr *); 83 /* Ensure that (sctphdr + sctp_chunkhdr) in a row. */ 84 IP6_EXTHDR_GET(sh, struct sctphdr *, m, off, sizeof(*sh) + sizeof(*ch)); 85 if (sh == NULL) { 86 SCTP_STAT_INCR(sctps_hdrops); 87 return IPPROTO_DONE; --- 45 unchanged lines hidden (view full) --- 133#ifdef SCTP_DEBUG 134 if (sctp_debug_on & SCTP_DEBUG_INPUT1) { 135 printf("Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 136 calc_check, check, m, 137 mlen, iphlen); 138 } 139#endif 140 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), | 79 m = SCTP_HEADER_TO_CHAIN(*mp); 80 81 ip6 = mtod(m, struct ip6_hdr *); 82 /* Ensure that (sctphdr + sctp_chunkhdr) in a row. */ 83 IP6_EXTHDR_GET(sh, struct sctphdr *, m, off, sizeof(*sh) + sizeof(*ch)); 84 if (sh == NULL) { 85 SCTP_STAT_INCR(sctps_hdrops); 86 return IPPROTO_DONE; --- 45 unchanged lines hidden (view full) --- 132#ifdef SCTP_DEBUG 133 if (sctp_debug_on & SCTP_DEBUG_INPUT1) { 134 printf("Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 135 calc_check, check, m, 136 mlen, iphlen); 137 } 138#endif 139 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), |
141 sh, ch, &in6p, &net); | 140 sh, ch, &in6p, &net, vrf_id); |
142 /* in6p's ref-count increased && stcb locked */ 143 if ((in6p) && (stcb)) { 144 sctp_send_packet_dropped(stcb, net, m, iphlen, 1); 145 sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, 2); 146 } else if ((in6p != NULL) && (stcb == NULL)) { 147 refcount_up = 1; 148 } 149 SCTP_STAT_INCR(sctps_badsum); --- 4 unchanged lines hidden (view full) --- 154 } 155sctp_skip_csum: 156 net = NULL; 157 /* 158 * Locate pcb and tcb for datagram sctp_findassociation_addr() wants 159 * IP/SCTP/first chunk header... 160 */ 161 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), | 141 /* in6p's ref-count increased && stcb locked */ 142 if ((in6p) && (stcb)) { 143 sctp_send_packet_dropped(stcb, net, m, iphlen, 1); 144 sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, 2); 145 } else if ((in6p != NULL) && (stcb == NULL)) { 146 refcount_up = 1; 147 } 148 SCTP_STAT_INCR(sctps_badsum); --- 4 unchanged lines hidden (view full) --- 153 } 154sctp_skip_csum: 155 net = NULL; 156 /* 157 * Locate pcb and tcb for datagram sctp_findassociation_addr() wants 158 * IP/SCTP/first chunk header... 159 */ 160 stcb = sctp_findassociation_addr(m, iphlen, offset - sizeof(*ch), |
162 sh, ch, &in6p, &net); | 161 sh, ch, &in6p, &net, vrf_id); |
163 /* in6p's ref-count increased */ 164 if (in6p == NULL) { 165 struct sctp_init_chunk *init_chk, chunk_buf; 166 167 SCTP_STAT_INCR(sctps_noport); 168 if (ch->chunk_type == SCTP_INITIATION) { 169 /* 170 * we do a trick here to get the INIT tag, dig in 171 * and get the tag from the INIT and put it in the 172 * common header. 173 */ 174 init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m, 175 iphlen + sizeof(*sh), sizeof(*init_chk), | 162 /* in6p's ref-count increased */ 163 if (in6p == NULL) { 164 struct sctp_init_chunk *init_chk, chunk_buf; 165 166 SCTP_STAT_INCR(sctps_noport); 167 if (ch->chunk_type == SCTP_INITIATION) { 168 /* 169 * we do a trick here to get the INIT tag, dig in 170 * and get the tag from the INIT and put it in the 171 * common header. 172 */ 173 init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m, 174 iphlen + sizeof(*sh), sizeof(*init_chk), |
176 (u_int8_t *) & chunk_buf); | 175 (uint8_t *) & chunk_buf); |
177 sh->v_tag = init_chk->init.initiate_tag; 178 } 179 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { 180 sctp_send_shutdown_complete2(m, iphlen, sh); 181 goto bad; 182 } 183 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 184 goto bad; --- 58 unchanged lines hidden (view full) --- 243 244static void 245sctp6_notify_mbuf(struct sctp_inpcb *inp, 246 struct icmp6_hdr *icmp6, 247 struct sctphdr *sh, 248 struct sctp_tcb *stcb, 249 struct sctp_nets *net) 250{ | 176 sh->v_tag = init_chk->init.initiate_tag; 177 } 178 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { 179 sctp_send_shutdown_complete2(m, iphlen, sh); 180 goto bad; 181 } 182 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 183 goto bad; --- 58 unchanged lines hidden (view full) --- 242 243static void 244sctp6_notify_mbuf(struct sctp_inpcb *inp, 245 struct icmp6_hdr *icmp6, 246 struct sctphdr *sh, 247 struct sctp_tcb *stcb, 248 struct sctp_nets *net) 249{ |
251 u_int32_t nxtsz; | 250 uint32_t nxtsz; |
252 253 if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 254 (icmp6 == NULL) || (sh == NULL)) { 255 goto out; 256 } 257 /* First do we even look at it? */ 258 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) 259 goto out; --- 20 unchanged lines hidden (view full) --- 280 if (stcb->asoc.smallest_mtu > nxtsz) { 281 struct sctp_tmit_chunk *chk; 282 283 /* Adjust that too */ 284 stcb->asoc.smallest_mtu = nxtsz; 285 /* now off to subtract IP_DF flag if needed */ 286 287 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { | 251 252 if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 253 (icmp6 == NULL) || (sh == NULL)) { 254 goto out; 255 } 256 /* First do we even look at it? */ 257 if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) 258 goto out; --- 20 unchanged lines hidden (view full) --- 279 if (stcb->asoc.smallest_mtu > nxtsz) { 280 struct sctp_tmit_chunk *chk; 281 282 /* Adjust that too */ 283 stcb->asoc.smallest_mtu = nxtsz; 284 /* now off to subtract IP_DF flag if needed */ 285 286 TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { |
288 if ((u_int32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) { | 287 if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) { |
289 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 290 } 291 } 292 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { | 288 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 289 } 290 } 291 TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { |
293 if ((u_int32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) { | 292 if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) { |
294 /* 295 * For this guy we also mark for immediate 296 * resend since we sent to big of chunk 297 */ 298 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 299 if (chk->sent != SCTP_DATAGRAM_RESEND) 300 stcb->asoc.sent_queue_retran_cnt++; 301 chk->sent = SCTP_DATAGRAM_RESEND; --- 632 unchanged lines hidden (view full) --- 934#endif /* INET */ 935 936 inp6 = (struct in6pcb *)so->so_pcb; 937 inp = (struct sctp_inpcb *)so->so_pcb; 938 if (inp == 0) { 939 return (ECONNRESET); /* I made the same as TCP since we are 940 * not setup? */ 941 } | 293 /* 294 * For this guy we also mark for immediate 295 * resend since we sent to big of chunk 296 */ 297 chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 298 if (chk->sent != SCTP_DATAGRAM_RESEND) 299 stcb->asoc.sent_queue_retran_cnt++; 300 chk->sent = SCTP_DATAGRAM_RESEND; --- 632 unchanged lines hidden (view full) --- 933#endif /* INET */ 934 935 inp6 = (struct in6pcb *)so->so_pcb; 936 inp = (struct sctp_inpcb *)so->so_pcb; 937 if (inp == 0) { 938 return (ECONNRESET); /* I made the same as TCP since we are 939 * not setup? */ 940 } |
942 vrf_id = SCTP_DEFAULT_VRFID; | 941 vrf_id = inp->def_vrf_id; |
943 SCTP_ASOC_CREATE_LOCK(inp); 944 SCTP_INP_RLOCK(inp); 945 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 946 SCTP_PCB_FLAGS_UNBOUND) { 947 /* Bind a ephemeral port */ 948 SCTP_INP_RUNLOCK(inp); 949 error = sctp6_bind(so, NULL, p); 950 if (error) { --- 139 unchanged lines hidden (view full) --- 1090 fnd = 1; 1091 break; 1092 } 1093 } 1094 if ((!fnd) || (sin_a6 == NULL)) { 1095 /* punt */ 1096 goto notConn6; 1097 } | 942 SCTP_ASOC_CREATE_LOCK(inp); 943 SCTP_INP_RLOCK(inp); 944 if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 945 SCTP_PCB_FLAGS_UNBOUND) { 946 /* Bind a ephemeral port */ 947 SCTP_INP_RUNLOCK(inp); 948 error = sctp6_bind(so, NULL, p); 949 if (error) { --- 139 unchanged lines hidden (view full) --- 1089 fnd = 1; 1090 break; 1091 } 1092 } 1093 if ((!fnd) || (sin_a6 == NULL)) { 1094 /* punt */ 1095 goto notConn6; 1096 } |
1098 vrf_id = SCTP_DEFAULT_VRFID; 1099 1100 sctp_ifa = sctp_source_address_selection(inp, stcb, (struct route *)&net->ro, net, 0, vrf_id); | 1097 vrf_id = inp->def_vrf_id; 1098 sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *) & net->ro, net, 0, vrf_id); |
1101 if (sctp_ifa) { 1102 sin6->sin6_addr = sctp_ifa->address.sin6.sin6_addr; 1103 } 1104 } else { 1105 /* For the bound all case you get back 0 */ 1106 notConn6: 1107 memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr)); 1108 } --- 171 unchanged lines hidden --- | 1099 if (sctp_ifa) { 1100 sin6->sin6_addr = sctp_ifa->address.sin6.sin6_addr; 1101 } 1102 } else { 1103 /* For the bound all case you get back 0 */ 1104 notConn6: 1105 memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr)); 1106 } --- 171 unchanged lines hidden --- |