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 (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/stream.h> 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 31 #include <netinet/in.h> 32 #include <netinet/ip6.h> 33 34 #include <inet/common.h> 35 #include <inet/ipclassifier.h> 36 #include <inet/ip.h> 37 #include <inet/ip6.h> 38 #include <inet/mib2.h> 39 #include <inet/nd.h> 40 #include <inet/optcom.h> 41 #include <inet/ipclassifier.h> 42 #include "sctp_impl.h" 43 #include "sctp_addr.h" 44 45 /*ARGSUSED*/ 46 size_t 47 sctp_supaddr_param_len(sctp_t *sctp) 48 { 49 return (sizeof (sctp_parm_hdr_t) + sizeof (int32_t)); 50 } 51 52 size_t 53 sctp_supaddr_param(sctp_t *sctp, uchar_t *p) 54 { 55 sctp_parm_hdr_t *sph; 56 uint16_t *addrtype; 57 conn_t *connp = sctp->sctp_connp; 58 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) { 63 case AF_INET: 64 *addrtype++ = htons(PARM_ADDR4); 65 *addrtype = 0; 66 sph->sph_len = htons(sizeof (*sph) + sizeof (*addrtype)); 67 break; 68 case AF_INET6: 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); 74 } else { 75 *addrtype = 0; 76 sph->sph_len = htons(sizeof (*sph) + 77 sizeof (*addrtype)); 78 } 79 break; 80 default: 81 break; 82 } 83 return (sizeof (*sph) + (sizeof (*addrtype) * 2)); 84 } 85 86 /* 87 * Currently, we support on PRSCTP option, there is more to come. 88 */ 89 /*ARGSUSED*/ 90 size_t 91 sctp_options_param_len(const sctp_t *sctp, int option) 92 { 93 size_t optlen; 94 95 switch (option) { 96 case SCTP_PRSCTP_OPTION: 97 optlen = sizeof (sctp_parm_hdr_t); 98 break; 99 default: 100 ASSERT(0); 101 } 102 103 return (optlen); 104 } 105 106 /*ARGSUSED*/ 107 size_t 108 sctp_options_param(const sctp_t *sctp, void *p, int option) 109 { 110 sctp_parm_hdr_t *sph = (sctp_parm_hdr_t *)p; 111 112 switch (option) { 113 case SCTP_PRSCTP_OPTION: 114 sph->sph_type = htons(PARM_FORWARD_TSN); 115 sph->sph_len = htons(sizeof (*sph)); 116 break; 117 default: 118 ASSERT(0); 119 } 120 121 return (sizeof (*sph)); 122 123 } 124 125 size_t 126 sctp_adaptation_code_param(sctp_t *sctp, uchar_t *p) 127 { 128 sctp_parm_hdr_t *sph; 129 130 if (!sctp->sctp_send_adaptation) { 131 return (0); 132 } 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); 137 138 return (sizeof (*sph) + sizeof (uint32_t)); 139 } 140 141 mblk_t * 142 sctp_init_mp(sctp_t *sctp, sctp_faddr_t *fp) 143 { 144 mblk_t *mp; 145 uchar_t *p; 146 size_t initlen; 147 sctp_init_chunk_t *icp; 148 sctp_chunk_hdr_t *chp; 149 uint16_t schlen; 150 int supp_af; 151 sctp_stack_t *sctps = sctp->sctp_sctps; 152 conn_t *connp = sctp->sctp_connp; 153 154 if (connp->conn_family == AF_INET) { 155 supp_af = PARM_SUPP_V4; 156 } else { 157 if (sctp->sctp_connp->conn_ipv6_v6only) 158 supp_af = PARM_SUPP_V6; 159 else 160 supp_af = PARM_SUPP_V6 | PARM_SUPP_V4; 161 } 162 initlen = sizeof (*chp) + sizeof (*icp); 163 if (sctp->sctp_send_adaptation) { 164 initlen += (sizeof (sctp_parm_hdr_t) + sizeof (uint32_t)); 165 } 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); 170 171 /* 172 * This could be a INIT retransmission in which case sh_verf may 173 * be non-zero, zero it out just to be sure. 174 */ 175 sctp->sctp_sctph->sh_verf = 0; 176 sctp->sctp_sctph6->sh_verf = 0; 177 178 mp = sctp_make_mp(sctp, fp, initlen); 179 if (mp == NULL) { 180 SCTP_KSTAT(sctps, sctp_send_init_failed); 181 return (NULL); 182 } 183 /* sctp_make_mp could have discovered we have no usable sources */ 184 if (sctp->sctp_nsaddrs == 0) { 185 freemsg(mp); 186 SCTP_KSTAT(sctps, sctp_send_init_failed); 187 return (NULL); 188 } 189 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; 193 chp->sch_flags = 0; 194 schlen = (uint16_t)initlen; 195 U16_TO_ABE16(schlen, &(chp->sch_len)); 196 197 mp->b_wptr += initlen; 198 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)); 205 206 p = (uchar_t *)(icp + 1); 207 208 /* Adaptation layer param */ 209 p += sctp_adaptation_code_param(sctp, p); 210 211 /* Add supported address types parameter */ 212 p += sctp_supaddr_param(sctp, p); 213 214 /* Add address parameters */ 215 p += sctp_addr_params(sctp, supp_af, p, B_FALSE); 216 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); 220 221 BUMP_LOCAL(sctp->sctp_obchunks); 222 223 sctp_set_iplen(sctp, mp, fp->sf_ixa); 224 225 return (mp); 226 } 227 228 /* 229 * Extracts the verification tag from an INIT chunk. If the INIT 230 * chunk is truncated or malformed, returns 0. 231 */ 232 uint32_t 233 sctp_init2vtag(sctp_chunk_hdr_t *initch) 234 { 235 sctp_init_chunk_t *init; 236 237 init = (sctp_init_chunk_t *)(initch + 1); 238 return (init->sic_inittag); 239 } 240 241 size_t 242 sctp_addr_params(sctp_t *sctp, int af, uchar_t *p, boolean_t modify) 243 { 244 size_t param_len; 245 246 ASSERT(sctp->sctp_nsaddrs > 0); 247 248 /* 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. 251 */ 252 if ((!modify && sctp->sctp_nsaddrs == 1) || sctp->sctp_loopback || 253 sctp->sctp_linklocal) { 254 return (0); 255 } 256 257 param_len = sctp_saddr_info(sctp, af, p, modify); 258 return ((sctp->sctp_nsaddrs == 1) ? 0 : param_len); 259 } 260