summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_pcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/sctp_pcb.c')
-rw-r--r--sys/netinet/sctp_pcb.c795
1 files changed, 475 insertions, 320 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 25e5c79..7ad3f7f 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -51,6 +51,7 @@ struct sctp_epinfo sctppcbinfo;
/* FIX: we don't handle multiple link local scopes */
/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
+#ifdef INET6
int
SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
{
@@ -64,6 +65,8 @@ SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
}
+#endif
+
void
sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
{
@@ -608,37 +611,47 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
sctp_ifap->flags = ifa_flags;
/* Set scope */
- if (sctp_ifap->address.sa.sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (sctp_ifap->address.sa.sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
- if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
- (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
- sctp_ifap->src_is_loop = 1;
- }
- if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
- sctp_ifap->src_is_priv = 1;
+ sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
+ if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
+ (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
+ sctp_ifap->src_is_loop = 1;
+ }
+ if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
+ sctp_ifap->src_is_priv = 1;
+ }
+ sctp_ifnp->num_v4++;
+ if (new_ifn_af)
+ new_ifn_af = AF_INET;
+ break;
}
- sctp_ifnp->num_v4++;
- if (new_ifn_af)
- new_ifn_af = AF_INET;
- } else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
- /* ok to use deprecated addresses? */
- struct sockaddr_in6 *sin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ /* ok to use deprecated addresses? */
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
- if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
- (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
- sctp_ifap->src_is_loop = 1;
- }
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- sctp_ifap->src_is_priv = 1;
+ sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
+ if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
+ (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
+ sctp_ifap->src_is_loop = 1;
+ }
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ sctp_ifap->src_is_priv = 1;
+ }
+ sctp_ifnp->num_v6++;
+ if (new_ifn_af)
+ new_ifn_af = AF_INET6;
+ break;
}
- sctp_ifnp->num_v6++;
- if (new_ifn_af)
- new_ifn_af = AF_INET6;
- } else {
+#endif
+ default:
new_ifn_af = 0;
+ break;
}
hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
@@ -893,7 +906,9 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
match = 1;
break;
}
- } else {
+ }
+#ifdef INET6
+ if (from->sa_family == AF_INET6) {
struct sockaddr_in6 *intf_addr6;
struct sockaddr_in6 *sin6;
@@ -907,6 +922,7 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
break;
}
}
+#endif
}
}
if (match == 0) {
@@ -944,38 +960,56 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
/* not the same family, can't be a match */
continue;
}
- if (from->sa_family == AF_INET) {
- struct sockaddr_in *sin, *rsin;
-
- sin = (struct sockaddr_in *)&net->ro._l_addr;
- rsin = (struct sockaddr_in *)from;
- if (sin->sin_addr.s_addr ==
- rsin->sin_addr.s_addr) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
+ switch (from->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin, *rsin;
+
+ sin = (struct sockaddr_in *)&net->ro._l_addr;
+ rsin = (struct sockaddr_in *)from;
+ if (sin->sin_addr.s_addr ==
+ rsin->sin_addr.s_addr) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ /*
+ * Update the endpoint
+ * pointer
+ */
+ *inp_p = inp;
+ SCTP_INP_RUNLOCK(inp);
+ return (stcb);
}
- /* Update the endpoint pointer */
- *inp_p = inp;
- SCTP_INP_RUNLOCK(inp);
- return (stcb);
+ break;
}
- } else {
- struct sockaddr_in6 *sin6, *rsin6;
-
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- rsin6 = (struct sockaddr_in6 *)from;
- if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
- &rsin6->sin6_addr)) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6, *rsin6;
+
+ sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ rsin6 = (struct sockaddr_in6 *)from;
+ if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
+ &rsin6->sin6_addr)) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ /*
+ * Update the endpoint
+ * pointer
+ */
+ *inp_p = inp;
+ SCTP_INP_RUNLOCK(inp);
+ return (stcb);
}
- /* Update the endpoint pointer */
- *inp_p = inp;
- SCTP_INP_RUNLOCK(inp);
- return (stcb);
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -1076,53 +1110,67 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
/* not the same family */
continue;
}
- if (remote->sa_family == AF_INET) {
- struct sockaddr_in *sin, *rsin;
-
- sin = (struct sockaddr_in *)
- &net->ro._l_addr;
- rsin = (struct sockaddr_in *)remote;
- if (sin->sin_addr.s_addr ==
- rsin->sin_addr.s_addr) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ switch (remote->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin,
+ *rsin;
+
+ sin = (struct sockaddr_in *)
+ &net->ro._l_addr;
+ rsin = (struct sockaddr_in *)remote;
+ if (sin->sin_addr.s_addr ==
+ rsin->sin_addr.s_addr) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
- } else if (remote->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6, *rsin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6,
+ *rsin6;
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- rsin6 = (struct sockaddr_in6 *)remote;
- if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
- &rsin6->sin6_addr)) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ rsin6 = (struct sockaddr_in6 *)remote;
+ if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
+ &rsin6->sin6_addr)) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -1159,54 +1207,68 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
/* not the same family */
continue;
}
- if (remote->sa_family == AF_INET) {
- struct sockaddr_in *sin, *rsin;
-
- sin = (struct sockaddr_in *)
- &net->ro._l_addr;
- rsin = (struct sockaddr_in *)remote;
- if (sin->sin_addr.s_addr ==
- rsin->sin_addr.s_addr) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ switch (remote->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin,
+ *rsin;
+
+ sin = (struct sockaddr_in *)
+ &net->ro._l_addr;
+ rsin = (struct sockaddr_in *)remote;
+ if (sin->sin_addr.s_addr ==
+ rsin->sin_addr.s_addr) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
- } else if (remote->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6, *rsin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6,
+ *rsin6;
- sin6 = (struct sockaddr_in6 *)
- &net->ro._l_addr;
- rsin6 = (struct sockaddr_in6 *)remote;
- if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
- &rsin6->sin6_addr)) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ sin6 = (struct sockaddr_in6 *)
+ &net->ro._l_addr;
+ rsin6 = (struct sockaddr_in6 *)remote;
+ if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
+ &rsin6->sin6_addr)) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -1332,20 +1394,37 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
{
struct sctp_inpcb *inp;
struct sockaddr_in *sin;
+
+#ifdef INET6
struct sockaddr_in6 *sin6;
+
+#endif
struct sctp_laddr *laddr;
+
+#ifdef INET6
+ struct sockaddr_in6 *intf_addr6;
+
+#endif
+
int fnd;
/*
* Endpoing probe expects that the INP_INFO is locked.
*/
- if (nam->sa_family == AF_INET) {
+ sin = NULL;
+#ifdef INET6
+ sin6 = NULL;
+#endif
+ switch (nam->sa_family) {
+ case AF_INET:
sin = (struct sockaddr_in *)nam;
- sin6 = NULL;
- } else if (nam->sa_family == AF_INET6) {
+ break;
+#ifdef INET6
+ case AF_INET6:
sin6 = (struct sockaddr_in6 *)nam;
- sin = NULL;
- } else {
+ break;
+#endif
+ default:
/* unsupported family */
return (NULL);
}
@@ -1390,11 +1469,14 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
(sin->sin_addr.s_addr == INADDR_ANY)) {
/* Can't hunt for one that has no address specified */
return (NULL);
- } else if ((nam->sa_family == AF_INET6) &&
+ }
+#ifdef INET6
+ if ((nam->sa_family == AF_INET6) &&
(IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
/* Can't hunt for one that has no address specified */
return (NULL);
}
+#endif
/*
* ok, not bound to all so see if we can find a EP bound to this
* address.
@@ -1443,21 +1525,24 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
struct sockaddr_in *intf_addr;
intf_addr = &laddr->ifa->address.sin;
- if (nam->sa_family == AF_INET) {
+ switch (nam->sa_family) {
+ case AF_INET:
if (sin->sin_addr.s_addr ==
intf_addr->sin_addr.s_addr) {
SCTP_INP_RUNLOCK(inp);
return (inp);
}
- } else if (nam->sa_family == AF_INET6) {
- struct sockaddr_in6 *intf_addr6;
-
+ break;
+#ifdef INET6
+ case AF_INET6:
intf_addr6 = &laddr->ifa->address.sin6;
if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
&intf_addr6->sin6_addr)) {
SCTP_INP_RUNLOCK(inp);
return (inp);
}
+ break;
+#endif
}
}
}
@@ -1774,33 +1859,42 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
struct sctp_inpcb *inp;
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *from4;
-
- from4 = (struct sockaddr_in *)&from_store;
- bzero(from4, sizeof(*from4));
- from4->sin_family = AF_INET;
- from4->sin_len = sizeof(struct sockaddr_in);
- from4->sin_addr.s_addr = iph->ip_src.s_addr;
- from4->sin_port = sh->src_port;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *from6;
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *from4;
+
+ from4 = (struct sockaddr_in *)&from_store;
+ bzero(from4, sizeof(*from4));
+ from4->sin_family = AF_INET;
+ from4->sin_len = sizeof(struct sockaddr_in);
+ from4->sin_addr.s_addr = iph->ip_src.s_addr;
+ from4->sin_port = sh->src_port;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *from6;
- ip6 = mtod(m, struct ip6_hdr *);
- from6 = (struct sockaddr_in6 *)&from_store;
- bzero(from6, sizeof(*from6));
- from6->sin6_family = AF_INET6;
- from6->sin6_len = sizeof(struct sockaddr_in6);
- from6->sin6_addr = ip6->ip6_src;
- from6->sin6_port = sh->src_port;
- /* Get the scopes in properly to the sin6 addr's */
- /* we probably don't need these operations */
- (void)sa6_recoverscope(from6);
- sa6_embedscope(from6, ip6_use_defzone);
- } else {
+ ip6 = mtod(m, struct ip6_hdr *);
+ from6 = (struct sockaddr_in6 *)&from_store;
+ bzero(from6, sizeof(*from6));
+ from6->sin6_family = AF_INET6;
+ from6->sin6_len = sizeof(struct sockaddr_in6);
+ from6->sin6_addr = ip6->ip6_src;
+ from6->sin6_port = sh->src_port;
+ /* Get the scopes in properly to the sin6 addr's */
+ /* we probably don't need these operations */
+ (void)sa6_recoverscope(from6);
+ sa6_embedscope(from6, ip6_use_defzone);
+ break;
+ }
+#endif
+ default:
/* Currently not supported. */
return (NULL);
}
@@ -1812,32 +1906,44 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
return (retval);
}
}
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *to4;
-
- to4 = (struct sockaddr_in *)&to_store;
- bzero(to4, sizeof(*to4));
- to4->sin_family = AF_INET;
- to4->sin_len = sizeof(struct sockaddr_in);
- to4->sin_addr.s_addr = iph->ip_dst.s_addr;
- to4->sin_port = sh->dest_port;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *to6;
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *to4;
+
+ to4 = (struct sockaddr_in *)&to_store;
+ bzero(to4, sizeof(*to4));
+ to4->sin_family = AF_INET;
+ to4->sin_len = sizeof(struct sockaddr_in);
+ to4->sin_addr.s_addr = iph->ip_dst.s_addr;
+ to4->sin_port = sh->dest_port;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *to6;
- ip6 = mtod(m, struct ip6_hdr *);
- to6 = (struct sockaddr_in6 *)&to_store;
- bzero(to6, sizeof(*to6));
- to6->sin6_family = AF_INET6;
- to6->sin6_len = sizeof(struct sockaddr_in6);
- to6->sin6_addr = ip6->ip6_dst;
- to6->sin6_port = sh->dest_port;
- /* Get the scopes in properly to the sin6 addr's */
- /* we probably don't need these operations */
- (void)sa6_recoverscope(to6);
- sa6_embedscope(to6, ip6_use_defzone);
+ ip6 = mtod(m, struct ip6_hdr *);
+ to6 = (struct sockaddr_in6 *)&to_store;
+ bzero(to6, sizeof(*to6));
+ to6->sin6_family = AF_INET6;
+ to6->sin6_len = sizeof(struct sockaddr_in6);
+ to6->sin6_addr = ip6->ip6_dst;
+ to6->sin6_port = sh->dest_port;
+ /* Get the scopes in properly to the sin6 addr's */
+ /* we probably don't need these operations */
+ (void)sa6_recoverscope(to6);
+ sa6_embedscope(to6, ip6_use_defzone);
+ break;
+ }
+#endif
+ default:
+ /* TSNH */
+ break;
}
find_tcp_pool = 0;
if ((ch->chunk_type != SCTP_INITIATION) &&
@@ -1895,9 +2001,18 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
{
struct sctp_tcb *stcb;
struct sockaddr_in *sin;
+
+#ifdef INET6
struct sockaddr_in6 *sin6;
+
+#endif
struct sockaddr_storage local_store, remote_store;
struct ip *iph;
+
+#ifdef INET6
+ struct ip6_hdr *ip6;
+
+#endif
struct sctp_paramhdr parm_buf, *phdr;
int ptype;
int zero_address = 0;
@@ -1908,24 +2023,27 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
+ switch (iph->ip_v) {
+ case IPVERSION:
/* its IPv4 */
sin = (struct sockaddr_in *)&local_store;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
sin->sin_port = sh->dest_port;
sin->sin_addr.s_addr = iph->ip_dst.s_addr;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
/* its IPv6 */
- struct ip6_hdr *ip6;
-
ip6 = mtod(m, struct ip6_hdr *);
sin6 = (struct sockaddr_in6 *)&local_store;
sin6->sin6_family = AF_INET6;
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_port = sh->dest_port;
sin6->sin6_addr = ip6->ip6_dst;
- } else {
+ break;
+#endif
+ default:
return NULL;
}
@@ -1938,51 +2056,60 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
}
ptype = (int)((uint32_t) ntohs(phdr->param_type));
/* get the correlation address */
- if (ptype == SCTP_IPV6_ADDRESS) {
- /* ipv6 address param */
- struct sctp_ipv6addr_param *p6, p6_buf;
-
- if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
- return NULL;
- }
- p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
- offset + sizeof(struct sctp_asconf_chunk),
- &p6_buf.ph, sizeof(*p6));
- if (p6 == NULL) {
- SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v6 lookup addr\n",
- __FUNCTION__);
- return (NULL);
+ switch (ptype) {
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
+ {
+ /* ipv6 address param */
+ struct sctp_ipv6addr_param *p6, p6_buf;
+
+ if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
+ return NULL;
+ }
+ p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
+ offset + sizeof(struct sctp_asconf_chunk),
+ &p6_buf.ph, sizeof(*p6));
+ if (p6 == NULL) {
+ SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v6 lookup addr\n",
+ __FUNCTION__);
+ return (NULL);
+ }
+ sin6 = (struct sockaddr_in6 *)&remote_store;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_port = sh->src_port;
+ memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
+ zero_address = 1;
+ break;
}
- sin6 = (struct sockaddr_in6 *)&remote_store;
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(*sin6);
- sin6->sin6_port = sh->src_port;
- memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
- zero_address = 1;
- } else if (ptype == SCTP_IPV4_ADDRESS) {
- /* ipv4 address param */
- struct sctp_ipv4addr_param *p4, p4_buf;
-
- if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
- return NULL;
- }
- p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
- offset + sizeof(struct sctp_asconf_chunk),
- &p4_buf.ph, sizeof(*p4));
- if (p4 == NULL) {
- SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v4 lookup addr\n",
- __FUNCTION__);
- return (NULL);
+#endif
+ case SCTP_IPV4_ADDRESS:
+ {
+ /* ipv4 address param */
+ struct sctp_ipv4addr_param *p4, p4_buf;
+
+ if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
+ return NULL;
+ }
+ p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
+ offset + sizeof(struct sctp_asconf_chunk),
+ &p4_buf.ph, sizeof(*p4));
+ if (p4 == NULL) {
+ SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v4 lookup addr\n",
+ __FUNCTION__);
+ return (NULL);
+ }
+ sin = (struct sockaddr_in *)&remote_store;
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = sh->src_port;
+ memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ zero_address = 1;
+ break;
}
- sin = (struct sockaddr_in *)&remote_store;
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_port = sh->src_port;
- memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
- if (sin->sin_addr.s_addr == INADDR_ANY)
- zero_address = 1;
- } else {
+ default:
/* invalid address param type */
return NULL;
}
@@ -2416,62 +2543,76 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
prison = 1;
}
if (addr != NULL) {
- if (addr->sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (addr->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- /* IPV6_V6ONLY socket? */
- if (SCTP_IPV6_V6ONLY(ip_inp)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
- }
- if (addr->sa_len != sizeof(*sin)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
- }
- sin = (struct sockaddr_in *)addr;
- lport = sin->sin_port;
- if (prison) {
- /*
- * For INADDR_ANY and LOOPBACK the
- * prison_ip() call will transmute the ip
- * address to the proper value (i.e. the IP
- * address owned by the jail).
- */
- if (prison_ip(p->td_ucred, 0, &sin->sin_addr.s_addr)) {
+ /* IPV6_V6ONLY socket? */
+ if (SCTP_IPV6_V6ONLY(ip_inp)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
return (EINVAL);
}
+ if (addr->sa_len != sizeof(*sin)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ return (EINVAL);
+ }
+ sin = (struct sockaddr_in *)addr;
+ lport = sin->sin_port;
+ if (prison) {
+ /*
+ * For INADDR_ANY and LOOPBACK the
+ * prison_ip() call will transmute
+ * the ip address to the proper
+ * value (i.e. the IP address owned
+ * by the jail).
+ */
+ if (prison_ip(p->td_ucred, 0, &sin->sin_addr.s_addr)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ return (EINVAL);
+ }
+ }
+ if (sin->sin_addr.s_addr != INADDR_ANY) {
+ bindall = 0;
+ }
+ break;
}
- if (sin->sin_addr.s_addr != INADDR_ANY) {
- bindall = 0;
- }
- } else if (addr->sa_family == AF_INET6) {
- /* Only for pure IPv6 Address. (No IPv4 Mapped!) */
- struct sockaddr_in6 *sin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ /*
+ * Only for pure IPv6 Address. (No IPv4
+ * Mapped!)
+ */
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)addr;
+ sin6 = (struct sockaddr_in6 *)addr;
- if (addr->sa_len != sizeof(*sin6)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
- }
- lport = sin6->sin6_port;
- /*
- * Jail checks for IPv6 should go HERE! i.e. add the
- * prison_ip() equivilant in this postion to
- * transmute the addresses to the proper one jailed.
- */
- if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- bindall = 0;
- /* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, ip6_use_defzone) != 0) {
+ if (addr->sa_len != sizeof(*sin6)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
return (EINVAL);
}
+ lport = sin6->sin6_port;
+ /*
+ * Jail checks for IPv6 should go HERE! i.e.
+ * add the prison_ip() equivilant in this
+ * postion to transmute the addresses to the
+ * proper one jailed.
+ */
+ if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ bindall = 0;
+ /* KAME hack: embed scopeid */
+ if (sa6_embedscope(sin6, ip6_use_defzone) != 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ return (EINVAL);
+ }
+ }
+ /* this must be cleared for ifa_ifwithaddr() */
+ sin6->sin6_scope_id = 0;
+ break;
}
- /* this must be cleared for ifa_ifwithaddr() */
- sin6->sin6_scope_id = 0;
- } else {
+#endif
+ default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EAFNOSUPPORT);
return (EAFNOSUPPORT);
}
@@ -3472,6 +3613,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
/* Now generate a route for this guy */
+#ifdef INET6
/* KAME hack: embed scopeid */
if (newaddr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
@@ -3480,14 +3622,17 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
(void)sa6_embedscope(sin6, ip6_use_defzone);
sin6->sin6_scope_id = 0;
}
+#endif
SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id);
+#ifdef INET6
if (newaddr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
(void)sa6_recoverscope(sin6);
}
+#endif
if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
/* Get source address */
net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
@@ -5205,33 +5350,43 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sin6.sin6_port = stcb->rport;
if (altsa == NULL) {
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *sin_2;
-
- sin_2 = (struct sockaddr_in *)(local_sa);
- memset(sin_2, 0, sizeof(sin));
- sin_2->sin_family = AF_INET;
- sin_2->sin_len = sizeof(sin);
- sin_2->sin_port = sh->dest_port;
- sin_2->sin_addr.s_addr = iph->ip_dst.s_addr;
- sin.sin_addr = iph->ip_src;
- sa = (struct sockaddr *)&sin;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *sin6_2;
-
- ip6 = mtod(m, struct ip6_hdr *);
- sin6_2 = (struct sockaddr_in6 *)(local_sa);
- memset(sin6_2, 0, sizeof(sin6));
- sin6_2->sin6_family = AF_INET6;
- sin6_2->sin6_len = sizeof(struct sockaddr_in6);
- sin6_2->sin6_port = sh->dest_port;
- sin6.sin6_addr = ip6->ip6_src;
- sa = (struct sockaddr *)&sin6;
- } else {
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *sin_2;
+
+ sin_2 = (struct sockaddr_in *)(local_sa);
+ memset(sin_2, 0, sizeof(sin));
+ sin_2->sin_family = AF_INET;
+ sin_2->sin_len = sizeof(sin);
+ sin_2->sin_port = sh->dest_port;
+ sin_2->sin_addr.s_addr = iph->ip_dst.s_addr;
+ sin.sin_addr = iph->ip_src;
+ sa = (struct sockaddr *)&sin;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *sin6_2;
+
+ ip6 = mtod(m, struct ip6_hdr *);
+ sin6_2 = (struct sockaddr_in6 *)(local_sa);
+ memset(sin6_2, 0, sizeof(sin6));
+ sin6_2->sin6_family = AF_INET6;
+ sin6_2->sin6_len = sizeof(struct sockaddr_in6);
+ sin6_2->sin6_port = sh->dest_port;
+ sin6.sin6_addr = ip6->ip6_src;
+ sa = (struct sockaddr *)&sin6;
+ break;
+ }
+#endif
+ default:
sa = NULL;
+ break;
}
} else {
/*
OpenPOWER on IntegriCloud