sctp_pcb.c (236522) | sctp_pcb.c (237715) |
---|---|
1/*- 2 * Copyright (c) 2001-2008, 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-2008, 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/netinet/sctp_pcb.c 236522 2012-06-03 18:14:57Z tuexen $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.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_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_pcb.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp.h> --- 1843 unchanged lines hidden (view full) --- 1886} 1887 1888/* 1889 * Find an association for an endpoint with the pointer to whom you want to 1890 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may 1891 * need to change the *to to some other struct like a mbuf... 1892 */ 1893struct sctp_tcb * | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_pcb.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp.h> --- 1843 unchanged lines hidden (view full) --- 1886} 1887 1888/* 1889 * Find an association for an endpoint with the pointer to whom you want to 1890 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may 1891 * need to change the *to to some other struct like a mbuf... 1892 */ 1893struct sctp_tcb * |
1894sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from, | 1894sctp_findassociation_addr_sa(struct sockaddr *from, struct sockaddr *to, |
1895 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, 1896 uint32_t vrf_id) 1897{ 1898 struct sctp_inpcb *inp = NULL; 1899 struct sctp_tcb *retval; 1900 1901 SCTP_INP_INFO_RLOCK(); 1902 if (find_tcp_pool) { --- 38 unchanged lines hidden (view full) --- 1941/* 1942 * This routine will grub through the mbuf that is a INIT or INIT-ACK and 1943 * find all addresses that the sender has specified in any address list. Each 1944 * address will be used to lookup the TCB and see if one exits. 1945 */ 1946static struct sctp_tcb * 1947sctp_findassociation_special_addr(struct mbuf *m, int offset, 1948 struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp, | 1895 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, 1896 uint32_t vrf_id) 1897{ 1898 struct sctp_inpcb *inp = NULL; 1899 struct sctp_tcb *retval; 1900 1901 SCTP_INP_INFO_RLOCK(); 1902 if (find_tcp_pool) { --- 38 unchanged lines hidden (view full) --- 1941/* 1942 * This routine will grub through the mbuf that is a INIT or INIT-ACK and 1943 * find all addresses that the sender has specified in any address list. Each 1944 * address will be used to lookup the TCB and see if one exits. 1945 */ 1946static struct sctp_tcb * 1947sctp_findassociation_special_addr(struct mbuf *m, int offset, 1948 struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp, |
1949 struct sockaddr *dest) | 1949 struct sockaddr *dst) |
1950{ 1951 struct sctp_paramhdr *phdr, parm_buf; 1952 struct sctp_tcb *retval; 1953 uint32_t ptype, plen; 1954 1955#ifdef INET 1956 struct sockaddr_in sin4; 1957 --- 37 unchanged lines hidden (view full) --- 1995 (struct sctp_paramhdr *)&ip4_parm, min(plen, sizeof(ip4_parm))); 1996 if (phdr == NULL) { 1997 return (NULL); 1998 } 1999 p4 = (struct sctp_ipv4addr_param *)phdr; 2000 memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr)); 2001 /* look it up */ 2002 retval = sctp_findassociation_ep_addr(inp_p, | 1950{ 1951 struct sctp_paramhdr *phdr, parm_buf; 1952 struct sctp_tcb *retval; 1953 uint32_t ptype, plen; 1954 1955#ifdef INET 1956 struct sockaddr_in sin4; 1957 --- 37 unchanged lines hidden (view full) --- 1995 (struct sctp_paramhdr *)&ip4_parm, min(plen, sizeof(ip4_parm))); 1996 if (phdr == NULL) { 1997 return (NULL); 1998 } 1999 p4 = (struct sctp_ipv4addr_param *)phdr; 2000 memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr)); 2001 /* look it up */ 2002 retval = sctp_findassociation_ep_addr(inp_p, |
2003 (struct sockaddr *)&sin4, netp, dest, NULL); | 2003 (struct sockaddr *)&sin4, netp, dst, NULL); |
2004 if (retval != NULL) { 2005 return (retval); 2006 } 2007 } 2008#endif 2009#ifdef INET6 2010 if (ptype == SCTP_IPV6_ADDRESS && 2011 plen == sizeof(struct sctp_ipv6addr_param)) { --- 4 unchanged lines hidden (view full) --- 2016 (struct sctp_paramhdr *)&ip6_parm, min(plen, sizeof(ip6_parm))); 2017 if (phdr == NULL) { 2018 return (NULL); 2019 } 2020 p6 = (struct sctp_ipv6addr_param *)phdr; 2021 memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr)); 2022 /* look it up */ 2023 retval = sctp_findassociation_ep_addr(inp_p, | 2004 if (retval != NULL) { 2005 return (retval); 2006 } 2007 } 2008#endif 2009#ifdef INET6 2010 if (ptype == SCTP_IPV6_ADDRESS && 2011 plen == sizeof(struct sctp_ipv6addr_param)) { --- 4 unchanged lines hidden (view full) --- 2016 (struct sctp_paramhdr *)&ip6_parm, min(plen, sizeof(ip6_parm))); 2017 if (phdr == NULL) { 2018 return (NULL); 2019 } 2020 p6 = (struct sctp_ipv6addr_param *)phdr; 2021 memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr)); 2022 /* look it up */ 2023 retval = sctp_findassociation_ep_addr(inp_p, |
2024 (struct sockaddr *)&sin6, netp, dest, NULL); | 2024 (struct sockaddr *)&sin6, netp, dst, NULL); |
2025 if (retval != NULL) { 2026 return (retval); 2027 } 2028 } 2029#endif 2030 offset += SCTP_SIZE32(plen); 2031 phdr = sctp_get_next_param(m, offset, &parm_buf, 2032 sizeof(parm_buf)); --- 106 unchanged lines hidden (view full) --- 2139} 2140 2141/* 2142 * Find an association with the pointer to the inbound IP packet. This can be 2143 * a IPv4 or IPv6 packet. 2144 */ 2145struct sctp_tcb * 2146sctp_findassociation_addr(struct mbuf *m, int offset, | 2025 if (retval != NULL) { 2026 return (retval); 2027 } 2028 } 2029#endif 2030 offset += SCTP_SIZE32(plen); 2031 phdr = sctp_get_next_param(m, offset, &parm_buf, 2032 sizeof(parm_buf)); --- 106 unchanged lines hidden (view full) --- 2139} 2140 2141/* 2142 * Find an association with the pointer to the inbound IP packet. This can be 2143 * a IPv4 or IPv6 packet. 2144 */ 2145struct sctp_tcb * 2146sctp_findassociation_addr(struct mbuf *m, int offset, |
2147 struct sockaddr *src, struct sockaddr *dst, |
|
2147 struct sctphdr *sh, struct sctp_chunkhdr *ch, 2148 struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id) 2149{ 2150 int find_tcp_pool; | 2148 struct sctphdr *sh, struct sctp_chunkhdr *ch, 2149 struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id) 2150{ 2151 int find_tcp_pool; |
2151 struct ip *iph; | |
2152 struct sctp_tcb *retval; | 2152 struct sctp_tcb *retval; |
2153 struct sockaddr_storage to_store, from_store; 2154 struct sockaddr *to = (struct sockaddr *)&to_store; 2155 struct sockaddr *from = (struct sockaddr *)&from_store; | |
2156 struct sctp_inpcb *inp; 2157 | 2153 struct sctp_inpcb *inp; 2154 |
2158 iph = mtod(m, struct ip *); 2159 switch (iph->ip_v) { 2160#ifdef INET 2161 case IPVERSION: 2162 { 2163 /* its IPv4 */ 2164 struct sockaddr_in *from4; 2165 2166 from4 = (struct sockaddr_in *)&from_store; 2167 bzero(from4, sizeof(*from4)); 2168 from4->sin_family = AF_INET; 2169 from4->sin_len = sizeof(struct sockaddr_in); 2170 from4->sin_addr.s_addr = iph->ip_src.s_addr; 2171 from4->sin_port = sh->src_port; 2172 break; 2173 } 2174#endif 2175#ifdef INET6 2176 case IPV6_VERSION >> 4: 2177 { 2178 /* its IPv6 */ 2179 struct ip6_hdr *ip6; 2180 struct sockaddr_in6 *from6; 2181 2182 ip6 = mtod(m, struct ip6_hdr *); 2183 from6 = (struct sockaddr_in6 *)&from_store; 2184 bzero(from6, sizeof(*from6)); 2185 from6->sin6_family = AF_INET6; 2186 from6->sin6_len = sizeof(struct sockaddr_in6); 2187 from6->sin6_addr = ip6->ip6_src; 2188 from6->sin6_port = sh->src_port; 2189 /* Get the scopes in properly to the sin6 addr's */ 2190 sa6_embedscope(from6, MODULE_GLOBAL(ip6_use_defzone)); 2191 break; 2192 } 2193#endif 2194 default: 2195 /* Currently not supported. */ 2196 return (NULL); 2197 } 2198 2199 2200 switch (iph->ip_v) { 2201#ifdef INET 2202 case IPVERSION: 2203 { 2204 /* its IPv4 */ 2205 struct sockaddr_in *to4; 2206 2207 to4 = (struct sockaddr_in *)&to_store; 2208 bzero(to4, sizeof(*to4)); 2209 to4->sin_family = AF_INET; 2210 to4->sin_len = sizeof(struct sockaddr_in); 2211 to4->sin_addr.s_addr = iph->ip_dst.s_addr; 2212 to4->sin_port = sh->dest_port; 2213 break; 2214 } 2215#endif 2216#ifdef INET6 2217 case IPV6_VERSION >> 4: 2218 { 2219 /* its IPv6 */ 2220 struct ip6_hdr *ip6; 2221 struct sockaddr_in6 *to6; 2222 2223 ip6 = mtod(m, struct ip6_hdr *); 2224 to6 = (struct sockaddr_in6 *)&to_store; 2225 bzero(to6, sizeof(*to6)); 2226 to6->sin6_family = AF_INET6; 2227 to6->sin6_len = sizeof(struct sockaddr_in6); 2228 to6->sin6_addr = ip6->ip6_dst; 2229 to6->sin6_port = sh->dest_port; 2230 /* Get the scopes in properly to the sin6 addr's */ 2231 sa6_embedscope(to6, MODULE_GLOBAL(ip6_use_defzone)); 2232 break; 2233 } 2234#endif 2235 default: 2236 /* TSNH */ 2237 break; 2238 } | |
2239 if (sh->v_tag) { 2240 /* we only go down this path if vtag is non-zero */ | 2155 if (sh->v_tag) { 2156 /* we only go down this path if vtag is non-zero */ |
2241 retval = sctp_findassoc_by_vtag(from, to, ntohl(sh->v_tag), | 2157 retval = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag), |
2242 inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0); 2243 if (retval) { 2244 return (retval); 2245 } 2246 } 2247 find_tcp_pool = 0; 2248 if ((ch->chunk_type != SCTP_INITIATION) && 2249 (ch->chunk_type != SCTP_INITIATION_ACK) && 2250 (ch->chunk_type != SCTP_COOKIE_ACK) && 2251 (ch->chunk_type != SCTP_COOKIE_ECHO)) { 2252 /* Other chunk types go to the tcp pool. */ 2253 find_tcp_pool = 1; 2254 } 2255 if (inp_p) { | 2158 inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0); 2159 if (retval) { 2160 return (retval); 2161 } 2162 } 2163 find_tcp_pool = 0; 2164 if ((ch->chunk_type != SCTP_INITIATION) && 2165 (ch->chunk_type != SCTP_INITIATION_ACK) && 2166 (ch->chunk_type != SCTP_COOKIE_ACK) && 2167 (ch->chunk_type != SCTP_COOKIE_ECHO)) { 2168 /* Other chunk types go to the tcp pool. */ 2169 find_tcp_pool = 1; 2170 } 2171 if (inp_p) { |
2256 retval = sctp_findassociation_addr_sa(to, from, inp_p, netp, | 2172 retval = sctp_findassociation_addr_sa(src, dst, inp_p, netp, |
2257 find_tcp_pool, vrf_id); 2258 inp = *inp_p; 2259 } else { | 2173 find_tcp_pool, vrf_id); 2174 inp = *inp_p; 2175 } else { |
2260 retval = sctp_findassociation_addr_sa(to, from, &inp, netp, | 2176 retval = sctp_findassociation_addr_sa(src, dst, &inp, netp, |
2261 find_tcp_pool, vrf_id); 2262 } 2263 SCTPDBG(SCTP_DEBUG_PCB1, "retval:%p inp:%p\n", retval, inp); 2264 if (retval == NULL && inp) { 2265 /* Found a EP but not this address */ 2266 if ((ch->chunk_type == SCTP_INITIATION) || 2267 (ch->chunk_type == SCTP_INITIATION_ACK)) { 2268 /*- --- 6 unchanged lines hidden (view full) --- 2275 */ 2276 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) { 2277 if (inp_p) { 2278 *inp_p = NULL; 2279 } 2280 return (NULL); 2281 } 2282 retval = sctp_findassociation_special_addr(m, | 2177 find_tcp_pool, vrf_id); 2178 } 2179 SCTPDBG(SCTP_DEBUG_PCB1, "retval:%p inp:%p\n", retval, inp); 2180 if (retval == NULL && inp) { 2181 /* Found a EP but not this address */ 2182 if ((ch->chunk_type == SCTP_INITIATION) || 2183 (ch->chunk_type == SCTP_INITIATION_ACK)) { 2184 /*- --- 6 unchanged lines hidden (view full) --- 2191 */ 2192 if (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) { 2193 if (inp_p) { 2194 *inp_p = NULL; 2195 } 2196 return (NULL); 2197 } 2198 retval = sctp_findassociation_special_addr(m, |
2283 offset, sh, &inp, netp, to); | 2199 offset, sh, &inp, netp, dst); |
2284 if (inp_p != NULL) { 2285 *inp_p = inp; 2286 } 2287 } 2288 } 2289 SCTPDBG(SCTP_DEBUG_PCB1, "retval is %p\n", retval); 2290 return (retval); 2291} 2292 2293/* 2294 * lookup an association by an ASCONF lookup address. 2295 * if the lookup address is 0.0.0.0 or ::0, use the vtag to do the lookup 2296 */ 2297struct sctp_tcb * 2298sctp_findassociation_ep_asconf(struct mbuf *m, int offset, | 2200 if (inp_p != NULL) { 2201 *inp_p = inp; 2202 } 2203 } 2204 } 2205 SCTPDBG(SCTP_DEBUG_PCB1, "retval is %p\n", retval); 2206 return (retval); 2207} 2208 2209/* 2210 * lookup an association by an ASCONF lookup address. 2211 * if the lookup address is 0.0.0.0 or ::0, use the vtag to do the lookup 2212 */ 2213struct sctp_tcb * 2214sctp_findassociation_ep_asconf(struct mbuf *m, int offset, |
2299 struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id) | 2215 struct sockaddr *dst, struct sctphdr *sh, 2216 struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id) |
2300{ 2301 struct sctp_tcb *stcb; | 2217{ 2218 struct sctp_tcb *stcb; |
2302 struct sockaddr_storage local_store, remote_store; 2303 struct sockaddr *to; 2304 struct ip *iph; | 2219 struct sockaddr_storage remote_store; |
2305 struct sctp_paramhdr parm_buf, *phdr; 2306 int ptype; 2307 int zero_address = 0; 2308 2309#ifdef INET 2310 struct sockaddr_in *sin; 2311 2312#endif 2313#ifdef INET6 | 2220 struct sctp_paramhdr parm_buf, *phdr; 2221 int ptype; 2222 int zero_address = 0; 2223 2224#ifdef INET 2225 struct sockaddr_in *sin; 2226 2227#endif 2228#ifdef INET6 |
2314 struct ip6_hdr *ip6; | |
2315 struct sockaddr_in6 *sin6; 2316 2317#endif 2318 | 2229 struct sockaddr_in6 *sin6; 2230 2231#endif 2232 |
2319 memset(&local_store, 0, sizeof(local_store)); | |
2320 memset(&remote_store, 0, sizeof(remote_store)); | 2233 memset(&remote_store, 0, sizeof(remote_store)); |
2321 to = (struct sockaddr *)&local_store; 2322 /* First get the destination address setup too. */ 2323 iph = mtod(m, struct ip *); 2324 switch (iph->ip_v) { 2325#ifdef INET 2326 case IPVERSION: 2327 /* its IPv4 */ 2328 sin = (struct sockaddr_in *)&local_store; 2329 sin->sin_family = AF_INET; 2330 sin->sin_len = sizeof(*sin); 2331 sin->sin_port = sh->dest_port; 2332 sin->sin_addr.s_addr = iph->ip_dst.s_addr; 2333 break; 2334#endif 2335#ifdef INET6 2336 case IPV6_VERSION >> 4: 2337 /* its IPv6 */ 2338 ip6 = mtod(m, struct ip6_hdr *); 2339 sin6 = (struct sockaddr_in6 *)&local_store; 2340 sin6->sin6_family = AF_INET6; 2341 sin6->sin6_len = sizeof(*sin6); 2342 sin6->sin6_port = sh->dest_port; 2343 sin6->sin6_addr = ip6->ip6_dst; 2344 break; 2345#endif 2346 default: 2347 return NULL; 2348 } 2349 | |
2350 phdr = sctp_get_next_param(m, offset + sizeof(struct sctp_asconf_chunk), 2351 &parm_buf, sizeof(struct sctp_paramhdr)); 2352 if (phdr == NULL) { 2353 SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf lookup addr\n", 2354 __FUNCTION__); 2355 return NULL; 2356 } 2357 ptype = (int)((uint32_t) ntohs(phdr->param_type)); --- 54 unchanged lines hidden (view full) --- 2412 } 2413#endif 2414 default: 2415 /* invalid address param type */ 2416 return NULL; 2417 } 2418 2419 if (zero_address) { | 2234 phdr = sctp_get_next_param(m, offset + sizeof(struct sctp_asconf_chunk), 2235 &parm_buf, sizeof(struct sctp_paramhdr)); 2236 if (phdr == NULL) { 2237 SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf lookup addr\n", 2238 __FUNCTION__); 2239 return NULL; 2240 } 2241 ptype = (int)((uint32_t) ntohs(phdr->param_type)); --- 54 unchanged lines hidden (view full) --- 2296 } 2297#endif 2298 default: 2299 /* invalid address param type */ 2300 return NULL; 2301 } 2302 2303 if (zero_address) { |
2420 stcb = sctp_findassoc_by_vtag(NULL, to, ntohl(sh->v_tag), inp_p, | 2304 stcb = sctp_findassoc_by_vtag(NULL, dst, ntohl(sh->v_tag), inp_p, |
2421 netp, sh->src_port, sh->dest_port, 1, vrf_id, 0); 2422 /* 2423 * SCTP_PRINTF("findassociation_ep_asconf: zero lookup 2424 * address finds stcb 0x%x\n", (uint32_t)stcb); 2425 */ 2426 } else { 2427 stcb = sctp_findassociation_ep_addr(inp_p, 2428 (struct sockaddr *)&remote_store, netp, | 2305 netp, sh->src_port, sh->dest_port, 1, vrf_id, 0); 2306 /* 2307 * SCTP_PRINTF("findassociation_ep_asconf: zero lookup 2308 * address finds stcb 0x%x\n", (uint32_t)stcb); 2309 */ 2310 } else { 2311 stcb = sctp_findassociation_ep_addr(inp_p, 2312 (struct sockaddr *)&remote_store, netp, |
2429 to, NULL); | 2313 dst, NULL); |
2430 } 2431 return (stcb); 2432} 2433 2434 2435/* 2436 * allocate a sctp_inpcb and setup a temporary binding to a port/all 2437 * addresses. This way if we don't get a bind we by default pick a ephemeral --- 3636 unchanged lines hidden (view full) --- 6074#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) 6075 SCTP_FREE(SCTP_BASE_STATS, SCTP_M_MCORE); 6076#endif 6077} 6078 6079 6080int 6081sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, | 2314 } 2315 return (stcb); 2316} 2317 2318 2319/* 2320 * allocate a sctp_inpcb and setup a temporary binding to a port/all 2321 * addresses. This way if we don't get a bind we by default pick a ephemeral --- 3636 unchanged lines hidden (view full) --- 5958#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT) 5959 SCTP_FREE(SCTP_BASE_STATS, SCTP_M_MCORE); 5960#endif 5961} 5962 5963 5964int 5965sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, |
6082 int offset, int limit, struct sctphdr *sh, | 5966 int offset, int limit, 5967 struct sockaddr *src, struct sockaddr *dst, |
6083 struct sockaddr *altsa) 6084{ 6085 /* 6086 * grub through the INIT pulling addresses and loading them to the 6087 * nets structure in the asoc. The from address in the mbuf should 6088 * also be loaded (if it is not already). This routine can be called 6089 * with either INIT or INIT-ACK's as long as the m points to the IP 6090 * packet and the offset points to the beginning of the parameters. 6091 */ 6092 struct sctp_inpcb *inp; 6093 struct sctp_nets *net, *nnet, *net_tmp; | 5968 struct sockaddr *altsa) 5969{ 5970 /* 5971 * grub through the INIT pulling addresses and loading them to the 5972 * nets structure in the asoc. The from address in the mbuf should 5973 * also be loaded (if it is not already). This routine can be called 5974 * with either INIT or INIT-ACK's as long as the m points to the IP 5975 * packet and the offset points to the beginning of the parameters. 5976 */ 5977 struct sctp_inpcb *inp; 5978 struct sctp_nets *net, *nnet, *net_tmp; |
6094 struct ip *iph; | |
6095 struct sctp_paramhdr *phdr, parm_buf; 6096 struct sctp_tcb *stcb_tmp; 6097 uint16_t ptype, plen; 6098 struct sockaddr *sa; | 5979 struct sctp_paramhdr *phdr, parm_buf; 5980 struct sctp_tcb *stcb_tmp; 5981 uint16_t ptype, plen; 5982 struct sockaddr *sa; |
6099 struct sockaddr_storage dest_store; 6100 struct sockaddr *local_sa = (struct sockaddr *)&dest_store; | |
6101 uint8_t random_store[SCTP_PARAM_BUFFER_SIZE]; 6102 struct sctp_auth_random *p_random = NULL; 6103 uint16_t random_len = 0; 6104 uint8_t hmacs_store[SCTP_PARAM_BUFFER_SIZE]; 6105 struct sctp_auth_hmac_algo *hmacs = NULL; 6106 uint16_t hmacs_len = 0; 6107 uint8_t saw_asconf = 0; 6108 uint8_t saw_asconf_ack = 0; --- 22 unchanged lines hidden (view full) --- 6131 sin.sin_port = stcb->rport; 6132#endif 6133#ifdef INET6 6134 memset(&sin6, 0, sizeof(sin6)); 6135 sin6.sin6_family = AF_INET6; 6136 sin6.sin6_len = sizeof(struct sockaddr_in6); 6137 sin6.sin6_port = stcb->rport; 6138#endif | 5983 uint8_t random_store[SCTP_PARAM_BUFFER_SIZE]; 5984 struct sctp_auth_random *p_random = NULL; 5985 uint16_t random_len = 0; 5986 uint8_t hmacs_store[SCTP_PARAM_BUFFER_SIZE]; 5987 struct sctp_auth_hmac_algo *hmacs = NULL; 5988 uint16_t hmacs_len = 0; 5989 uint8_t saw_asconf = 0; 5990 uint8_t saw_asconf_ack = 0; --- 22 unchanged lines hidden (view full) --- 6013 sin.sin_port = stcb->rport; 6014#endif 6015#ifdef INET6 6016 memset(&sin6, 0, sizeof(sin6)); 6017 sin6.sin6_family = AF_INET6; 6018 sin6.sin6_len = sizeof(struct sockaddr_in6); 6019 sin6.sin6_port = stcb->rport; 6020#endif |
6139 iph = mtod(m, struct ip *); 6140 switch (iph->ip_v) { 6141#ifdef INET 6142 case IPVERSION: 6143 { 6144 /* its IPv4 */ 6145 struct sockaddr_in *sin_2; 6146 6147 sin_2 = (struct sockaddr_in *)(local_sa); 6148 memset(sin_2, 0, sizeof(sin)); 6149 sin_2->sin_family = AF_INET; 6150 sin_2->sin_len = sizeof(sin); 6151 sin_2->sin_port = sh->dest_port; 6152 sin_2->sin_addr.s_addr = iph->ip_dst.s_addr; 6153 if (altsa) { 6154 /* 6155 * For cookies we use the src address NOT 6156 * from the packet but from the original 6157 * INIT. 6158 */ 6159 sa = altsa; 6160 } else { 6161 sin.sin_addr = iph->ip_src; 6162 sa = (struct sockaddr *)&sin; 6163 } 6164 break; 6165 } 6166#endif 6167#ifdef INET6 6168 case IPV6_VERSION >> 4: 6169 { 6170 /* its IPv6 */ 6171 struct ip6_hdr *ip6; 6172 struct sockaddr_in6 *sin6_2; 6173 6174 ip6 = mtod(m, struct ip6_hdr *); 6175 sin6_2 = (struct sockaddr_in6 *)(local_sa); 6176 memset(sin6_2, 0, sizeof(sin6)); 6177 sin6_2->sin6_family = AF_INET6; 6178 sin6_2->sin6_len = sizeof(struct sockaddr_in6); 6179 sin6_2->sin6_port = sh->dest_port; 6180 sin6_2->sin6_addr = ip6->ip6_dst; 6181 if (altsa) { 6182 /* 6183 * For cookies we use the src address NOT 6184 * from the packet but from the original 6185 * INIT. 6186 */ 6187 sa = altsa; 6188 } else { 6189 sin6.sin6_addr = ip6->ip6_src; 6190 sa = (struct sockaddr *)&sin6; 6191 } 6192 break; 6193 } 6194#endif 6195 default: 6196 return (-1); 6197 break; | 6021 if (altsa) { 6022 sa = altsa; 6023 } else { 6024 sa = src; |
6198 } 6199 /* Turn off ECN until we get through all params */ 6200 ecn_allowed = 0; 6201 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 6202 /* mark all addresses that we have currently on the list */ 6203 net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC; 6204 } 6205 /* does the source address already exist? if so skip it */ 6206 inp = stcb->sctp_ep; 6207 atomic_add_int(&stcb->asoc.refcnt, 1); | 6025 } 6026 /* Turn off ECN until we get through all params */ 6027 ecn_allowed = 0; 6028 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 6029 /* mark all addresses that we have currently on the list */ 6030 net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC; 6031 } 6032 /* does the source address already exist? if so skip it */ 6033 inp = stcb->sctp_ep; 6034 atomic_add_int(&stcb->asoc.refcnt, 1); |
6208 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, local_sa, stcb); | 6035 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, dst, stcb); |
6209 atomic_add_int(&stcb->asoc.refcnt, -1); 6210 6211 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) { 6212 /* we must add the source address */ 6213 /* no scope set here since we have a tcb already. */ 6214 switch (sa->sa_family) { 6215#ifdef INET 6216 case AF_INET: --- 73 unchanged lines hidden (view full) --- 6290 if ((sin.sin_addr.s_addr == INADDR_BROADCAST) || 6291 (sin.sin_addr.s_addr == INADDR_ANY)) { 6292 goto next_param; 6293 } 6294 sa = (struct sockaddr *)&sin; 6295 inp = stcb->sctp_ep; 6296 atomic_add_int(&stcb->asoc.refcnt, 1); 6297 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net, | 6036 atomic_add_int(&stcb->asoc.refcnt, -1); 6037 6038 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) { 6039 /* we must add the source address */ 6040 /* no scope set here since we have a tcb already. */ 6041 switch (sa->sa_family) { 6042#ifdef INET 6043 case AF_INET: --- 73 unchanged lines hidden (view full) --- 6117 if ((sin.sin_addr.s_addr == INADDR_BROADCAST) || 6118 (sin.sin_addr.s_addr == INADDR_ANY)) { 6119 goto next_param; 6120 } 6121 sa = (struct sockaddr *)&sin; 6122 inp = stcb->sctp_ep; 6123 atomic_add_int(&stcb->asoc.refcnt, 1); 6124 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net, |
6298 local_sa, stcb); | 6125 dst, stcb); |
6299 atomic_add_int(&stcb->asoc.refcnt, -1); 6300 6301 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || 6302 inp == NULL) { 6303 /* we must add the source address */ 6304 /* 6305 * no scope set since we have a tcb 6306 * already --- 73 unchanged lines hidden (view full) --- 6380 * scope 6381 */ 6382 goto next_param; 6383 } 6384 sa = (struct sockaddr *)&sin6; 6385 inp = stcb->sctp_ep; 6386 atomic_add_int(&stcb->asoc.refcnt, 1); 6387 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net, | 6126 atomic_add_int(&stcb->asoc.refcnt, -1); 6127 6128 if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || 6129 inp == NULL) { 6130 /* we must add the source address */ 6131 /* 6132 * no scope set since we have a tcb 6133 * already --- 73 unchanged lines hidden (view full) --- 6207 * scope 6208 */ 6209 goto next_param; 6210 } 6211 sa = (struct sockaddr *)&sin6; 6212 inp = stcb->sctp_ep; 6213 atomic_add_int(&stcb->asoc.refcnt, 1); 6214 stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net, |
6388 local_sa, stcb); | 6215 dst, stcb); |
6389 atomic_add_int(&stcb->asoc.refcnt, -1); 6390 if (stcb_tmp == NULL && 6391 (inp == stcb->sctp_ep || inp == NULL)) { 6392 /* 6393 * we must validate the state again 6394 * here 6395 */ 6396 add_it_now6: --- 709 unchanged lines hidden --- | 6216 atomic_add_int(&stcb->asoc.refcnt, -1); 6217 if (stcb_tmp == NULL && 6218 (inp == stcb->sctp_ep || inp == NULL)) { 6219 /* 6220 * we must validate the state again 6221 * here 6222 */ 6223 add_it_now6: --- 709 unchanged lines hidden --- |