1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/stream.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 34 #include <netinet/in.h> 35 #include <netinet/ip6.h> 36 37 #include <inet/common.h> 38 #include <inet/ipclassifier.h> 39 #include <inet/ip.h> 40 #include <inet/ip6.h> 41 #include <inet/mib2.h> 42 #include <inet/nd.h> 43 #include <inet/optcom.h> 44 #include "sctp_impl.h" 45 #include "sctp_addr.h" 46 47 /* 48 * This will compute the checksum over the SCTP packet, so this 49 * function should only be called after the whole packet has been 50 * built. 51 * 52 * rptr should point to the IP / SCTP composite header. 53 * len should be the length of the entire packet, including the IP 54 * header. 55 */ 56 void 57 sctp_add_hdr(sctp_t *sctp, uchar_t *rptr, size_t len) 58 { 59 ipha_t *iphdr; 60 short iplen; 61 62 ASSERT(len >= sctp->sctp_hdr_len); 63 64 /* Copy the common header from the template */ 65 bcopy(sctp->sctp_iphc, rptr, sctp->sctp_hdr_len); 66 67 /* Set the total length in the IP hdr */ 68 iplen = (short)len; 69 iphdr = (ipha_t *)rptr; 70 U16_TO_ABE16(iplen, &iphdr->ipha_length); 71 } 72 73 /*ARGSUSED*/ 74 size_t 75 sctp_supaddr_param_len(sctp_t *sctp) 76 { 77 return (sizeof (sctp_parm_hdr_t) + sizeof (int32_t)); 78 } 79 80 size_t 81 sctp_supaddr_param(sctp_t *sctp, uchar_t *p) 82 { 83 sctp_parm_hdr_t *sph; 84 uint16_t *addrtype; 85 86 sph = (sctp_parm_hdr_t *)p; 87 sph->sph_type = htons(PARM_SUPP_ADDRS); 88 addrtype = (uint16_t *)(sph + 1); 89 switch (sctp->sctp_ipversion) { 90 case IPV4_VERSION: 91 *addrtype++ = htons(PARM_ADDR4); 92 *addrtype = 0; 93 sph->sph_len = htons(sizeof (*sph) + sizeof (*addrtype)); 94 break; 95 case IPV6_VERSION: 96 *addrtype++ = htons(PARM_ADDR6); 97 if (!sctp->sctp_connp->conn_ipv6_v6only) { 98 *addrtype = htons(PARM_ADDR4); 99 sph->sph_len = htons(sizeof (*sph) + 100 sizeof (*addrtype) * 2); 101 } else { 102 *addrtype = 0; 103 sph->sph_len = htons(sizeof (*sph) + 104 sizeof (*addrtype)); 105 } 106 break; 107 default: 108 break; 109 } 110 return (sizeof (*sph) + (sizeof (*addrtype) * 2)); 111 } 112 113 /* 114 * Currently, we support on PRSCTP option, there is more to come. 115 */ 116 /*ARGSUSED*/ 117 size_t 118 sctp_options_param_len(const sctp_t *sctp, int option) 119 { 120 size_t optlen; 121 122 switch (option) { 123 case SCTP_PRSCTP_OPTION: 124 optlen = sizeof (sctp_parm_hdr_t); 125 break; 126 default: 127 ASSERT(0); 128 } 129 130 return (optlen); 131 } 132 133 /*ARGSUSED*/ 134 size_t 135 sctp_options_param(const sctp_t *sctp, void *p, int option) 136 { 137 sctp_parm_hdr_t *sph = (sctp_parm_hdr_t *)p; 138 139 switch (option) { 140 case SCTP_PRSCTP_OPTION: 141 sph->sph_type = htons(PARM_FORWARD_TSN); 142 sph->sph_len = htons(sizeof (*sph)); 143 break; 144 default: 145 ASSERT(0); 146 } 147 148 return (sizeof (*sph)); 149 150 } 151 152 size_t 153 sctp_adaption_code_param(sctp_t *sctp, uchar_t *p) 154 { 155 sctp_parm_hdr_t *sph; 156 157 if (!sctp->sctp_send_adaption) { 158 return (0); 159 } 160 sph = (sctp_parm_hdr_t *)p; 161 sph->sph_type = htons(PARM_ADAPT_LAYER_IND); 162 sph->sph_len = htons(sizeof (*sph) + sizeof (uint32_t)); 163 *(uint32_t *)(sph + 1) = htonl(sctp->sctp_tx_adaption_code); 164 165 return (sizeof (*sph) + sizeof (uint32_t)); 166 } 167 168 mblk_t * 169 sctp_init_mp(sctp_t *sctp) 170 { 171 mblk_t *mp; 172 uchar_t *p; 173 size_t initlen; 174 sctp_init_chunk_t *icp; 175 sctp_chunk_hdr_t *chp; 176 uint16_t schlen; 177 int supp_af; 178 179 if (sctp->sctp_family == AF_INET) { 180 supp_af = PARM_SUPP_V4; 181 } else { 182 /* Assume here that a v6 endpoint supports v4 address. */ 183 if (sctp->sctp_connp->conn_ipv6_v6only) 184 supp_af = PARM_SUPP_V6; 185 else 186 supp_af = PARM_SUPP_V6 | PARM_SUPP_V4; 187 } 188 initlen = sizeof (*chp) + sizeof (*icp); 189 if (sctp->sctp_send_adaption) { 190 initlen += (sizeof (sctp_parm_hdr_t) + sizeof (uint32_t)); 191 } 192 initlen += sctp_supaddr_param_len(sctp); 193 initlen += sctp_addr_params_len(sctp, supp_af, B_TRUE); 194 if (sctp->sctp_prsctp_aware && sctp_prsctp_enabled) 195 initlen += sctp_options_param_len(sctp, SCTP_PRSCTP_OPTION); 196 197 /* 198 * This could be a INIT retransmission in which case sh_verf may 199 * be non-zero, zero it out just to be sure. 200 */ 201 sctp->sctp_sctph->sh_verf = 0; 202 sctp->sctp_sctph6->sh_verf = 0; 203 204 mp = sctp_make_mp(sctp, NULL, initlen); 205 if (mp == NULL) { 206 SCTP_KSTAT(sctp_send_init_failed); 207 return (NULL); 208 } 209 210 /* Lay in a new INIT chunk, starting with the chunk header */ 211 chp = (sctp_chunk_hdr_t *)mp->b_wptr; 212 chp->sch_id = CHUNK_INIT; 213 chp->sch_flags = 0; 214 schlen = (uint16_t)initlen; 215 U16_TO_ABE16(schlen, &(chp->sch_len)); 216 217 mp->b_wptr += initlen; 218 219 icp = (sctp_init_chunk_t *)(chp + 1); 220 icp->sic_inittag = sctp->sctp_lvtag; 221 U32_TO_ABE32(sctp->sctp_rwnd, &(icp->sic_a_rwnd)); 222 U16_TO_ABE16(sctp->sctp_num_ostr, &(icp->sic_outstr)); 223 U16_TO_ABE16(sctp->sctp_num_istr, &(icp->sic_instr)); 224 U32_TO_ABE32(sctp->sctp_ltsn, &(icp->sic_inittsn)); 225 226 p = (uchar_t *)(icp + 1); 227 228 /* Adaption layer param */ 229 p += sctp_adaption_code_param(sctp, p); 230 231 /* Add supported address types parameter */ 232 p += sctp_supaddr_param(sctp, p); 233 234 /* Add address parameters */ 235 p += sctp_addr_params(sctp, supp_af, p); 236 237 /* Add Forward-TSN-Supported param */ 238 if (sctp->sctp_prsctp_aware && sctp_prsctp_enabled) 239 p += sctp_options_param(sctp, p, SCTP_PRSCTP_OPTION); 240 241 BUMP_LOCAL(sctp->sctp_obchunks); 242 243 sctp_set_iplen(sctp, mp); 244 245 return (mp); 246 } 247 248 /* 249 * Extracts the verification tag from an INIT chunk. If the INIT 250 * chunk is truncated or malformed, returns 0. 251 */ 252 uint32_t 253 sctp_init2vtag(sctp_chunk_hdr_t *initch) 254 { 255 sctp_init_chunk_t *init; 256 257 init = (sctp_init_chunk_t *)(initch + 1); 258 return (init->sic_inittag); 259 } 260 261 size_t 262 sctp_addr_params_len(sctp_t *sctp, int af, boolean_t modify) 263 { 264 ASSERT(sctp->sctp_nsaddrs > 0); 265 266 /* 267 * If we have only one local address or it is a loopback or linklocal 268 * association, we let the peer pull the address from the IP header. 269 */ 270 if (sctp->sctp_nsaddrs == 1 || sctp->sctp_loopback || 271 sctp->sctp_linklocal) { 272 return (0); 273 } 274 275 return (sctp_saddr_info(sctp, af, NULL, modify)); 276 } 277 278 size_t 279 sctp_addr_params(sctp_t *sctp, int af, uchar_t *p) 280 { 281 /* 282 * If we have only one local address or it is a loopback or linklocal 283 * association, we let the peer pull the address from the IP header. 284 */ 285 if (sctp->sctp_nsaddrs == 1 || sctp->sctp_loopback || 286 sctp->sctp_linklocal) { 287 return (0); 288 } 289 return (sctp_saddr_info(sctp, af, p, B_FALSE)); 290 } 291