4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
27 #include <sys/stream.h>
29 #include <sys/sunddi.h>
31 #include <netinet/in.h>
32 #include <netinet/ip6.h>
34 #include <inet/common.h>
35 #include <inet/ipclassifier.h>
38 #include <inet/mib2.h>
40 #include <inet/optcom.h>
41 #include <inet/ipclassifier.h>
42 #include <inet/sctp/sctp_impl.h>
43 #include <inet/sctp/sctp_addr.h>
47 sctp_supaddr_param_len(sctp_t
*sctp
)
49 return (sizeof (sctp_parm_hdr_t
) + sizeof (int32_t));
53 sctp_supaddr_param(sctp_t
*sctp
, uchar_t
*p
)
57 conn_t
*connp
= sctp
->sctp_connp
;
59 sph
= (sctp_parm_hdr_t
*)p
;
60 sph
->sph_type
= htons(PARM_SUPP_ADDRS
);
61 addrtype
= (uint16_t *)(sph
+ 1);
62 switch (connp
->conn_family
) {
64 *addrtype
++ = htons(PARM_ADDR4
);
66 sph
->sph_len
= htons(sizeof (*sph
) + sizeof (*addrtype
));
69 *addrtype
++ = htons(PARM_ADDR6
);
70 if (!sctp
->sctp_connp
->conn_ipv6_v6only
) {
71 *addrtype
= htons(PARM_ADDR4
);
72 sph
->sph_len
= htons(sizeof (*sph
) +
73 sizeof (*addrtype
) * 2);
76 sph
->sph_len
= htons(sizeof (*sph
) +
83 return (sizeof (*sph
) + (sizeof (*addrtype
) * 2));
87 * Currently, we support on PRSCTP option, there is more to come.
91 sctp_options_param_len(const sctp_t
*sctp
, int option
)
96 case SCTP_PRSCTP_OPTION
:
97 optlen
= sizeof (sctp_parm_hdr_t
);
108 sctp_options_param(const sctp_t
*sctp
, void *p
, int option
)
110 sctp_parm_hdr_t
*sph
= (sctp_parm_hdr_t
*)p
;
113 case SCTP_PRSCTP_OPTION
:
114 sph
->sph_type
= htons(PARM_FORWARD_TSN
);
115 sph
->sph_len
= htons(sizeof (*sph
));
121 return (sizeof (*sph
));
126 sctp_adaptation_code_param(sctp_t
*sctp
, uchar_t
*p
)
128 sctp_parm_hdr_t
*sph
;
130 if (!sctp
->sctp_send_adaptation
) {
133 sph
= (sctp_parm_hdr_t
*)p
;
134 sph
->sph_type
= htons(PARM_ADAPT_LAYER_IND
);
135 sph
->sph_len
= htons(sizeof (*sph
) + sizeof (uint32_t));
136 *(uint32_t *)(sph
+ 1) = htonl(sctp
->sctp_tx_adaptation_code
);
138 return (sizeof (*sph
) + sizeof (uint32_t));
142 sctp_init_mp(sctp_t
*sctp
, sctp_faddr_t
*fp
)
147 sctp_init_chunk_t
*icp
;
148 sctp_chunk_hdr_t
*chp
;
151 sctp_stack_t
*sctps
= sctp
->sctp_sctps
;
152 conn_t
*connp
= sctp
->sctp_connp
;
154 if (connp
->conn_family
== AF_INET
) {
155 supp_af
= PARM_SUPP_V4
;
157 if (sctp
->sctp_connp
->conn_ipv6_v6only
)
158 supp_af
= PARM_SUPP_V6
;
160 supp_af
= PARM_SUPP_V6
| PARM_SUPP_V4
;
162 initlen
= sizeof (*chp
) + sizeof (*icp
);
163 if (sctp
->sctp_send_adaptation
) {
164 initlen
+= (sizeof (sctp_parm_hdr_t
) + sizeof (uint32_t));
166 initlen
+= sctp_supaddr_param_len(sctp
);
167 initlen
+= sctp_addr_params(sctp
, supp_af
, NULL
, B_TRUE
);
168 if (sctp
->sctp_prsctp_aware
&& sctps
->sctps_prsctp_enabled
)
169 initlen
+= sctp_options_param_len(sctp
, SCTP_PRSCTP_OPTION
);
172 * This could be a INIT retransmission in which case sh_verf may
173 * be non-zero, zero it out just to be sure.
175 sctp
->sctp_sctph
->sh_verf
= 0;
176 sctp
->sctp_sctph6
->sh_verf
= 0;
178 mp
= sctp_make_mp(sctp
, fp
, initlen
);
180 SCTP_KSTAT(sctps
, sctp_send_init_failed
);
183 /* sctp_make_mp could have discovered we have no usable sources */
184 if (sctp
->sctp_nsaddrs
== 0) {
186 SCTP_KSTAT(sctps
, sctp_send_init_failed
);
190 /* Lay in a new INIT chunk, starting with the chunk header */
191 chp
= (sctp_chunk_hdr_t
*)mp
->b_wptr
;
192 chp
->sch_id
= CHUNK_INIT
;
194 schlen
= (uint16_t)initlen
;
195 U16_TO_ABE16(schlen
, &(chp
->sch_len
));
197 mp
->b_wptr
+= initlen
;
199 icp
= (sctp_init_chunk_t
*)(chp
+ 1);
200 icp
->sic_inittag
= sctp
->sctp_lvtag
;
201 U32_TO_ABE32(sctp
->sctp_rwnd
, &(icp
->sic_a_rwnd
));
202 U16_TO_ABE16(sctp
->sctp_num_ostr
, &(icp
->sic_outstr
));
203 U16_TO_ABE16(sctp
->sctp_num_istr
, &(icp
->sic_instr
));
204 U32_TO_ABE32(sctp
->sctp_ltsn
, &(icp
->sic_inittsn
));
206 p
= (uchar_t
*)(icp
+ 1);
208 /* Adaptation layer param */
209 p
+= sctp_adaptation_code_param(sctp
, p
);
211 /* Add supported address types parameter */
212 p
+= sctp_supaddr_param(sctp
, p
);
214 /* Add address parameters */
215 p
+= sctp_addr_params(sctp
, supp_af
, p
, B_FALSE
);
217 /* Add Forward-TSN-Supported param */
218 if (sctp
->sctp_prsctp_aware
&& sctps
->sctps_prsctp_enabled
)
219 p
+= sctp_options_param(sctp
, p
, SCTP_PRSCTP_OPTION
);
221 BUMP_LOCAL(sctp
->sctp_obchunks
);
223 sctp_set_iplen(sctp
, mp
, fp
->sf_ixa
);
229 * Extracts the verification tag from an INIT chunk. If the INIT
230 * chunk is truncated or malformed, returns 0.
233 sctp_init2vtag(sctp_chunk_hdr_t
*initch
)
235 sctp_init_chunk_t
*init
;
237 init
= (sctp_init_chunk_t
*)(initch
+ 1);
238 return (init
->sic_inittag
);
242 sctp_addr_params(sctp_t
*sctp
, int af
, uchar_t
*p
, boolean_t modify
)
246 ASSERT(sctp
->sctp_nsaddrs
> 0);
249 * If we have only one local address or it is a loopback or linklocal
250 * association, we let the peer pull the address from the IP header.
252 if ((!modify
&& sctp
->sctp_nsaddrs
== 1) || sctp
->sctp_loopback
||
253 sctp
->sctp_linklocal
) {
257 param_len
= sctp_saddr_info(sctp
, af
, p
, modify
);
258 return ((sctp
->sctp_nsaddrs
== 1) ? 0 : param_len
);