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