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