Deleted Added
full compact
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 ---