aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2011-04-30 11:18:16 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2011-04-30 11:18:16 +0000
commite6194c2ed4c3fe69ba25a005d1b8b387d1ce982f (patch)
tree019e1b80ac539c2f5a7eeb9a859cfe17f3d979f9 /sys/netinet
parent79288c112cc4b7f2f9acccbe904d45fe5d1baf7a (diff)
downloadsrc-e6194c2ed4c3fe69ba25a005d1b8b387d1ce982f.tar.gz
src-e6194c2ed4c3fe69ba25a005d1b8b387d1ce982f.zip
Improve compilation of SCTP code without INET support.
Some bugs where fixed while doing this: * ASCONF-ACK messages might use wrong port number when using IPv6. * Checking for additional addresses takes the correct address into account and also does not do more comparisons than necessary. This patch is based on one received from bz@ who was sponsored by The FreeBSD Foundation and iXsystems. MFC after: 1 week
Notes
Notes: svn path=/head/; revision=221249
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_asconf.c851
-rw-r--r--sys/netinet/sctp_bsd_addr.c67
-rw-r--r--sys/netinet/sctp_input.c113
-rw-r--r--sys/netinet/sctp_os_bsd.h2
-rw-r--r--sys/netinet/sctp_output.c1433
-rw-r--r--sys/netinet/sctp_pcb.c587
-rw-r--r--sys/netinet/sctp_sysctl.c36
-rw-r--r--sys/netinet/sctp_usrreq.c239
-rw-r--r--sys/netinet/sctp_var.h7
-rw-r--r--sys/netinet/sctputil.c10
10 files changed, 2054 insertions, 1291 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index ed8c118b2f45..1c0a454bea12 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -57,41 +57,51 @@ static void
sctp_asconf_get_source_ip(struct mbuf *m, struct sockaddr *sa)
{
struct ip *iph;
+
+#ifdef INET
struct sockaddr_in *sin;
+#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
- /* IPv4 source */
- sin = (struct sockaddr_in *)sa;
- bzero(sin, sizeof(*sin));
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(struct sockaddr_in);
- sin->sin_port = 0;
- sin->sin_addr.s_addr = iph->ip_src.s_addr;
- return;
- }
+ switch (iph->ip_v) {
+#ifdef INET
+ case IPVERSION:
+ {
+ /* IPv4 source */
+ sin = (struct sockaddr_in *)sa;
+ bzero(sin, sizeof(*sin));
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(struct sockaddr_in);
+ sin->sin_port = 0;
+ sin->sin_addr.s_addr = iph->ip_src.s_addr;
+ break;
+ }
+#endif
#ifdef INET6
- else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* IPv6 source */
- struct ip6_hdr *ip6;
+ case (IPV6_VERSION >> 4):
+ {
+ /* IPv6 source */
+ struct ip6_hdr *ip6;
- sin6 = (struct sockaddr_in6 *)sa;
- bzero(sin6, sizeof(*sin6));
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(struct sockaddr_in6);
- sin6->sin6_port = 0;
- ip6 = mtod(m, struct ip6_hdr *);
- sin6->sin6_addr = ip6->ip6_src;
- return;
- }
+ sin6 = (struct sockaddr_in6 *)sa;
+ bzero(sin6, sizeof(*sin6));
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+ sin6->sin6_port = 0;
+ ip6 = mtod(m, struct ip6_hdr *);
+ sin6->sin6_addr = ip6->ip6_src;
+ break;
+ }
#endif /* INET6 */
- else
- return;
+ default:
+ break;
+ }
+ return;
}
/*
@@ -192,33 +202,36 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
{
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_source, sa_store;
- struct sctp_ipv4addr_param *v4addr;
+ struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
- struct sockaddr_in *sin;
int zero_address = 0;
+#ifdef INET
+ struct sockaddr_in *sin;
+ struct sctp_ipv4addr_param *v4addr;
+
+#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
struct sctp_ipv6addr_param *v6addr;
-#endif /* INET6 */
+#endif
aparam_length = ntohs(aph->ph.param_length);
- v4addr = (struct sctp_ipv4addr_param *)(aph + 1);
-#ifdef INET6
- v6addr = (struct sctp_ipv6addr_param *)(aph + 1);
-#endif /* INET6 */
- param_type = ntohs(v4addr->ph.param_type);
- param_length = ntohs(v4addr->ph.param_length);
+ ph = (struct sctp_paramhdr *)(aph + 1);
+ param_type = ntohs(ph->param_type);
+ param_length = ntohs(ph->param_length);
sa = (struct sockaddr *)&sa_store;
switch (param_type) {
+#ifdef INET
case SCTP_IPV4_ADDRESS:
if (param_length != sizeof(struct sctp_ipv4addr_param)) {
/* invalid param size */
return NULL;
}
+ v4addr = (struct sctp_ipv4addr_param *)ph;
sin = (struct sockaddr_in *)&sa_store;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
@@ -230,12 +243,14 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
break;
- case SCTP_IPV6_ADDRESS:
+#endif
#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
if (param_length != sizeof(struct sctp_ipv6addr_param)) {
/* invalid param size */
return NULL;
}
+ v6addr = (struct sctp_ipv6addr_param *)ph;
sin6 = (struct sockaddr_in6 *)&sa_store;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
@@ -247,18 +262,13 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
zero_address = 1;
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
-#else
- /* IPv6 not enabled! */
- /* FIX ME: currently sends back an invalid param error */
- m_reply = sctp_asconf_error_response(aph->correlation_id,
- SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph, aparam_length);
- SCTPDBG(SCTP_DEBUG_ASCONF1,
- "process_asconf_add_ip: v6 disabled- skipping ");
- SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
- return m_reply;
-#endif
break;
+#endif
default:
+ /*
+ * XXX: Is this the correct error cause? Maybe
+ * SCTP_CAUSE_INVALID_PARAM is a better choice.
+ */
m_reply = sctp_asconf_error_response(aph->correlation_id,
SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
aparam_length);
@@ -293,7 +303,6 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
stcb, NULL);
}
-
return m_reply;
}
@@ -331,37 +340,40 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
{
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_source, sa_store;
- struct sctp_ipv4addr_param *v4addr;
+ struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
- struct sockaddr_in *sin;
int zero_address = 0;
int result;
+#ifdef INET
+ struct sockaddr_in *sin;
+ struct sctp_ipv4addr_param *v4addr;
+
+#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
struct sctp_ipv6addr_param *v6addr;
-#endif /* INET6 */
+#endif
/* get the source IP address for src and 0.0.0.0/::0 delete checks */
sctp_asconf_get_source_ip(m, (struct sockaddr *)&sa_source);
aparam_length = ntohs(aph->ph.param_length);
- v4addr = (struct sctp_ipv4addr_param *)(aph + 1);
-#ifdef INET6
- v6addr = (struct sctp_ipv6addr_param *)(aph + 1);
-#endif /* INET6 */
- param_type = ntohs(v4addr->ph.param_type);
- param_length = ntohs(v4addr->ph.param_length);
+ ph = (struct sctp_paramhdr *)(aph + 1);
+ param_type = ntohs(ph->param_type);
+ param_length = ntohs(ph->param_length);
sa = (struct sockaddr *)&sa_store;
switch (param_type) {
+#ifdef INET
case SCTP_IPV4_ADDRESS:
if (param_length != sizeof(struct sctp_ipv4addr_param)) {
/* invalid param size */
return NULL;
}
+ v4addr = (struct sctp_ipv4addr_param *)ph;
sin = (struct sockaddr_in *)&sa_store;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
@@ -374,12 +386,14 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
"process_asconf_delete_ip: deleting ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
break;
+#endif
+#ifdef INET6
case SCTP_IPV6_ADDRESS:
if (param_length != sizeof(struct sctp_ipv6addr_param)) {
/* invalid param size */
return NULL;
}
-#ifdef INET6
+ v6addr = (struct sctp_ipv6addr_param *)ph;
sin6 = (struct sockaddr_in6 *)&sa_store;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
@@ -392,15 +406,8 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_asconf_delete_ip: deleting ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
-#else
- /* IPv6 not enabled! No "action" needed; just ack it */
- SCTPDBG(SCTP_DEBUG_ASCONF1,
- "process_asconf_delete_ip: v6 disabled- ignoring: ");
- SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
- /* just respond with a "success" ASCONF-ACK */
- return NULL;
-#endif
break;
+#endif
default:
m_reply = sctp_asconf_error_response(aph->correlation_id,
SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
@@ -466,33 +473,36 @@ sctp_process_asconf_set_primary(struct mbuf *m,
{
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_source, sa_store;
- struct sctp_ipv4addr_param *v4addr;
+ struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
- struct sockaddr_in *sin;
int zero_address = 0;
+#ifdef INET
+ struct sockaddr_in *sin;
+ struct sctp_ipv4addr_param *v4addr;
+
+#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
struct sctp_ipv6addr_param *v6addr;
-#endif /* INET6 */
+#endif
aparam_length = ntohs(aph->ph.param_length);
- v4addr = (struct sctp_ipv4addr_param *)(aph + 1);
-#ifdef INET6
- v6addr = (struct sctp_ipv6addr_param *)(aph + 1);
-#endif /* INET6 */
- param_type = ntohs(v4addr->ph.param_type);
- param_length = ntohs(v4addr->ph.param_length);
+ ph = (struct sctp_paramhdr *)(aph + 1);
+ param_type = ntohs(ph->param_type);
+ param_length = ntohs(ph->param_length);
sa = (struct sockaddr *)&sa_store;
switch (param_type) {
+#ifdef INET
case SCTP_IPV4_ADDRESS:
if (param_length != sizeof(struct sctp_ipv4addr_param)) {
/* invalid param size */
return NULL;
}
+ v4addr = (struct sctp_ipv4addr_param *)ph;
sin = (struct sockaddr_in *)&sa_store;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
@@ -503,12 +513,14 @@ sctp_process_asconf_set_primary(struct mbuf *m,
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
break;
+#endif
+#ifdef INET6
case SCTP_IPV6_ADDRESS:
if (param_length != sizeof(struct sctp_ipv6addr_param)) {
/* invalid param size */
return NULL;
}
-#ifdef INET6
+ v6addr = (struct sctp_ipv6addr_param *)ph;
sin6 = (struct sockaddr_in6 *)&sa_store;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
@@ -519,15 +531,8 @@ sctp_process_asconf_set_primary(struct mbuf *m,
zero_address = 1;
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
-#else
- /* IPv6 not enabled! No "action" needed; just ack it */
- SCTPDBG(SCTP_DEBUG_ASCONF1,
- "process_asconf_set_primary: v6 disabled- ignoring: ");
- SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
- /* just respond with a "success" ASCONF-ACK */
- return NULL;
-#endif
break;
+#endif
default:
m_reply = sctp_asconf_error_response(aph->correlation_id,
SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
@@ -655,7 +660,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
if (first) {
/* delete old cache */
- SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing firstASCONF. Try to delte old cache\n");
+ SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
if (ack->serial_number == serial_num)
@@ -825,10 +830,8 @@ send_reply:
ack->last_sent_to = NULL;
ack->data = m_ack;
ack->len = 0;
- n = m_ack;
- while (n) {
+ for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
ack->len += SCTP_BUF_LEN(n);
- n = SCTP_BUF_NEXT(n);
}
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
@@ -846,12 +849,13 @@ send_reply:
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
/* pullup already done, IP options already stripped */
iph = mtod(m, struct ip *);
- sh = (struct sctphdr *)((caddr_t)iph + sizeof(*iph));
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
struct sockaddr_in *from4;
+ sh = (struct sctphdr *)((caddr_t)iph + sizeof(*iph));
from4 = (struct sockaddr_in *)&from_store;
bzero(from4, sizeof(*from4));
from4->sin_family = AF_INET;
@@ -860,6 +864,7 @@ send_reply:
from4->sin_port = sh->src_port;
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
@@ -867,6 +872,7 @@ send_reply:
struct sockaddr_in6 *from6;
ip6 = mtod(m, struct ip6_hdr *);
+ sh = (struct sctphdr *)((caddr_t)ip6 + sizeof(*ip6));
from6 = (struct sockaddr_in6 *)&from_store;
bzero(from6, sizeof(*from6));
from6->sin6_family = AF_INET6;
@@ -908,28 +914,36 @@ send_reply:
static uint32_t
sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
{
+ switch (sa->sa_family) {
#ifdef INET6
- if (sa->sa_family == AF_INET6) {
- /* IPv6 sa address */
- /* XXX scopeid */
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
-
- if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
- (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
- sizeof(struct in6_addr)) == 0)) {
- return (1);
+ case AF_INET6:
+ {
+ /* XXX scopeid */
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
+ (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
+ sizeof(struct in6_addr)) == 0)) {
+ return (1);
+ }
+ break;
}
- } else
-#endif /* INET6 */
- if (sa->sa_family == AF_INET) {
- /* IPv4 sa address */
- struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+#endif
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
- if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
- (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
- sizeof(struct in_addr)) == 0)) {
- return (1);
+ if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
+ (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
+ sizeof(struct in_addr)) == 0)) {
+ return (1);
+ }
+ break;
}
+#endif
+ default:
+ break;
}
return (0);
}
@@ -938,43 +952,48 @@ sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
* does the address match? returns 0 if not, 1 if so
*/
static uint32_t
-sctp_addr_match(
- struct sctp_ipv6addr_param *v6addr,
- struct sockaddr *sa)
+sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
{
uint16_t param_type, param_length;
- struct sctp_ipv4addr_param *v4addr = (struct sctp_ipv4addr_param *)v6addr;
+ param_type = ntohs(ph->param_type);
+ param_length = ntohs(ph->param_length);
+ switch (sa->sa_family) {
#ifdef INET6
- if (sa->sa_family == AF_INET6) {
- /* IPv6 sa address */
- /* XXX scopeid */
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
-
- param_type = ntohs(v6addr->ph.param_type);
- param_length = ntohs(v6addr->ph.param_length);
-
- if ((param_type == SCTP_IPV6_ADDRESS) &&
- param_length == sizeof(struct sctp_ipv6addr_param) &&
- (memcmp(&v6addr->addr, &sin6->sin6_addr,
- sizeof(struct in6_addr)) == 0)) {
- return (1);
+ case AF_INET6:
+ {
+ /* XXX scopeid */
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+ struct sctp_ipv6addr_param *v6addr;
+
+ v6addr = (struct sctp_ipv6addr_param *)ph;
+ if ((param_type == SCTP_IPV6_ADDRESS) &&
+ param_length == sizeof(struct sctp_ipv6addr_param) &&
+ (memcmp(&v6addr->addr, &sin6->sin6_addr,
+ sizeof(struct in6_addr)) == 0)) {
+ return (1);
+ }
+ break;
}
- }
#endif
- if (sa->sa_family == AF_INET) {
- /* IPv4 sa address */
- struct sockaddr_in *sin = (struct sockaddr_in *)sa;
-
- param_type = ntohs(v4addr->ph.param_type);
- param_length = ntohs(v4addr->ph.param_length);
-
- if ((param_type == SCTP_IPV4_ADDRESS) &&
- param_length == sizeof(struct sctp_ipv4addr_param) &&
- (memcmp(&v4addr->addr, &sin->sin_addr,
- sizeof(struct in_addr)) == 0)) {
- return (1);
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ struct sctp_ipv4addr_param *v4addr;
+
+ v4addr = (struct sctp_ipv4addr_param *)ph;
+ if ((param_type == SCTP_IPV4_ADDRESS) &&
+ param_length == sizeof(struct sctp_ipv4addr_param) &&
+ (memcmp(&v4addr->addr, &sin->sin_addr,
+ sizeof(struct in_addr)) == 0)) {
+ return (1);
+ }
+ break;
}
+#endif
+ default:
+ break;
}
return (0);
}
@@ -1179,17 +1198,25 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
continue;
changed = 0;
- if (net->ro._l_addr.sa.sa_family == AF_INET) {
- if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *) & net->ro))
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *) & net->ro)) {
changed = 1;
- }
+ }
+ break;
+#endif
#ifdef INET6
- if (net->ro._l_addr.sa.sa_family == AF_INET6) {
+ case AF_INET6:
if (sctp_v6src_match_nexthop(
- &newifa->address.sin6, (sctp_route_t *) & net->ro))
+ &newifa->address.sin6, (sctp_route_t *) & net->ro)) {
changed = 1;
- }
+ }
+ break;
#endif
+ default:
+ break;
+ }
/*
* if the newly added address does not relate routing
* information, we skip.
@@ -1316,31 +1343,40 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
aa->ifa = ifa;
atomic_add_int(&ifa->refcount, 1);
/* correlation_id filled in during send routine later... */
- if (ifa->address.sa.sa_family == AF_INET6) {
- /* IPv6 address */
- struct sockaddr_in6 *sin6;
+ switch (ifa->address.sa.sa_family) {
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
- sa = (struct sockaddr *)sin6;
- aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
- aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
- aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
- sizeof(struct sctp_ipv6addr_param);
- memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
- sizeof(struct in6_addr));
- } else if (ifa->address.sa.sa_family == AF_INET) {
- /* IPv4 address */
- struct sockaddr_in *sin;
+ sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
+ sa = (struct sockaddr *)sin6;
+ aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
+ aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
+ aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
+ sizeof(struct sctp_ipv6addr_param);
+ memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
+ sizeof(struct in6_addr));
+ break;
+ }
+#endif
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&ifa->address.sa;
- sa = (struct sockaddr *)sin;
- aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
- aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
- aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
- sizeof(struct sctp_ipv4addr_param);
- memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
- sizeof(struct in_addr));
- } else {
+ sin = (struct sockaddr_in *)&ifa->address.sa;
+ sa = (struct sockaddr *)sin;
+ aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
+ aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
+ aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
+ sizeof(struct sctp_ipv4addr_param);
+ memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
+ sizeof(struct in_addr));
+ break;
+ }
+#endif
+ default:
/* invalid family! */
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
sctp_free_ifa(ifa);
@@ -1522,26 +1558,37 @@ sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
if (ifa)
atomic_add_int(&ifa->refcount, 1);
/* correlation_id filled in during send routine later... */
- if (sa->sa_family == AF_INET6) {
- /* IPv6 address */
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)sa;
- aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
- aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
- aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
- memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
- sizeof(struct in6_addr));
- } else if (sa->sa_family == AF_INET) {
- /* IPv4 address */
- struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ switch (sa->sa_family) {
+#ifdef INET6
+ case AF_INET6:
+ {
+ /* IPv6 address */
+ struct sockaddr_in6 *sin6;
- aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
- aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
- aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
- memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
- sizeof(struct in_addr));
- } else {
+ sin6 = (struct sockaddr_in6 *)sa;
+ aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
+ aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
+ aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
+ memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
+ sizeof(struct in6_addr));
+ break;
+ }
+#endif
+#ifdef INET
+ case AF_INET:
+ {
+ /* IPv4 address */
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
+ aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
+ aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
+ memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
+ sizeof(struct in_addr));
+ break;
+ }
+#endif
+ default:
/* invalid family! */
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
if (ifa)
@@ -1923,10 +1970,19 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
/* first, make sure it's a good address family */
- if (ifa->address.sa.sa_family != AF_INET6 &&
- ifa->address.sa.sa_family != AF_INET) {
+ switch (ifa->address.sa.sa_family) {
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+ default:
return;
}
+#ifdef INET6
/* make sure we're "allowed" to add this type of addr */
if (ifa->address.sa.sa_family == AF_INET6) {
/* invalid if we're not a v6 endpoint */
@@ -1937,6 +1993,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return;
}
}
+#endif
/* put this address on the "pending/do not use yet" list */
sctp_add_local_addr_restricted(stcb, ifa);
/*
@@ -1971,6 +2028,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
break;
}
#endif
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin;
@@ -1993,6 +2051,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
break;
}
+#endif
default:
/* else, not AF_INET or AF_INET6, so skip */
return;
@@ -2036,35 +2095,38 @@ sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val)
asc = (struct sctp_asconf_iterator *)ptr;
LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
ifa = l->ifa;
- if (ifa->address.sa.sa_family == AF_INET6) {
+ switch (ifa->address.sa.sa_family) {
+#ifdef INET6
+ case AF_INET6:
/* invalid if we're not a v6 endpoint */
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
cnt_invalid++;
if (asc->cnt == cnt_invalid)
return (1);
- else
- continue;
}
- } else if (ifa->address.sa.sa_family == AF_INET) {
- /* invalid if we are a v6 only endpoint */
- struct in6pcb *inp6;
+ break;
+#endif
+#ifdef INET
+ case AF_INET:
+ {
+ /* invalid if we are a v6 only endpoint */
+ struct in6pcb *inp6;
- inp6 = (struct in6pcb *)&inp->ip_inp.inp;
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6)) {
- cnt_invalid++;
- if (asc->cnt == cnt_invalid)
- return (1);
- else
- continue;
+ inp6 = (struct in6pcb *)&inp->ip_inp.inp;
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+ SCTP_IPV6_V6ONLY(inp6)) {
+ cnt_invalid++;
+ if (asc->cnt == cnt_invalid)
+ return (1);
+ }
+ break;
}
- } else {
+#endif
+ default:
/* invalid address family */
cnt_invalid++;
if (asc->cnt == cnt_invalid)
return (1);
- else
- continue;
}
}
return (0);
@@ -2153,6 +2215,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
break;
}
#endif
+#ifdef INET
case AF_INET:
{
/* invalid if we are a v6 only endpoint */
@@ -2184,6 +2247,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
break;
}
+#endif
default:
/* invalid address family */
cnt_invalid++;
@@ -2374,7 +2438,7 @@ sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
struct sctp_asconf_chunk *acp;
struct sctp_asconf_paramhdr *aph;
uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
- struct sctp_ipv6addr_param *p_addr;
+ struct sctp_paramhdr *ph;
int add_cnt, del_cnt;
uint16_t last_param_type;
@@ -2389,12 +2453,12 @@ sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
acp = mtod(chk->data, struct sctp_asconf_chunk *);
offset += sizeof(struct sctp_asconf_chunk);
asconf_limit = ntohs(acp->ch.chunk_length);
- p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
- if (p_addr == NULL) {
+ ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
+ if (ph == NULL) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
continue;
}
- offset += ntohs(p_addr->ph.param_length);
+ offset += ntohs(ph->param_length);
aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
if (aph == NULL) {
@@ -2423,8 +2487,8 @@ sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
break;
}
- p_addr = (struct sctp_ipv6addr_param *)(aph + 1);
- if (sctp_addr_match(p_addr, &sctp_ifa->address.sa) != 0) {
+ ph = (struct sctp_paramhdr *)(aph + 1);
+ if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
switch (param_type) {
case SCTP_ADD_IP_ADDRESS:
add_cnt++;
@@ -2480,52 +2544,72 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
continue;
}
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
- if (sctp_ifa->address.sa.sa_family == AF_INET &&
- stcb->asoc.ipv4_addr_legal) {
- struct sockaddr_in *sin;
+ switch (sctp_ifa->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (stcb->asoc.ipv4_addr_legal) {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ if (sin->sin_addr.s_addr == 0) {
+ /* skip unspecifed addresses */
+ continue;
+ }
+ if (stcb->asoc.ipv4_local_scope == 0 &&
+ IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
+ continue;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
- if (sin->sin_addr.s_addr == 0) {
- /* skip unspecifed addresses */
- continue;
+ if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
+ (!sctp_is_addr_pending(stcb, sctp_ifa)))
+ continue;
+ /*
+ * found a valid local v4 address to
+ * use
+ */
+ if (addr_locked == SCTP_ADDR_NOT_LOCKED)
+ SCTP_IPI_ADDR_RUNLOCK();
+ return (&sctp_ifa->address.sa);
}
- if (stcb->asoc.ipv4_local_scope == 0 &&
- IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
- continue;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (stcb->asoc.ipv6_addr_legal) {
+ struct sockaddr_in6 *sin6;
- if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
- (!sctp_is_addr_pending(stcb, sctp_ifa)))
- continue;
- /* found a valid local v4 address to use */
- if (addr_locked == SCTP_ADDR_NOT_LOCKED)
- SCTP_IPI_ADDR_RUNLOCK();
- return (&sctp_ifa->address.sa);
- } else if (sctp_ifa->address.sa.sa_family == AF_INET6 &&
- stcb->asoc.ipv6_addr_legal) {
- struct sockaddr_in6 *sin6;
+ if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
+ continue;
+ }
+ sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * we skip unspecifed
+ * addresses
+ */
+ continue;
+ }
+ if (stcb->asoc.local_scope == 0 &&
+ IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+ continue;
+ if (stcb->asoc.site_scope == 0 &&
+ IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
+ continue;
- if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
- continue;
- }
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /* we skip unspecifed addresses */
- continue;
+ if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
+ (!sctp_is_addr_pending(stcb, sctp_ifa)))
+ continue;
+ /*
+ * found a valid local v6 address to
+ * use
+ */
+ if (addr_locked == SCTP_ADDR_NOT_LOCKED)
+ SCTP_IPI_ADDR_RUNLOCK();
+ return (&sctp_ifa->address.sa);
}
- if (stcb->asoc.local_scope == 0 &&
- IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
- continue;
- if (stcb->asoc.site_scope == 0 &&
- IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
- continue;
-
- if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
- (!sctp_is_addr_pending(stcb, sctp_ifa)))
- continue;
- /* found a valid local v6 address to use */
- if (addr_locked == SCTP_ADDR_NOT_LOCKED)
- SCTP_IPI_ADDR_RUNLOCK();
- return (&sctp_ifa->address.sa);
+ break;
+#endif
+ default:
+ break;
}
}
}
@@ -2697,7 +2781,9 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
if (found_addr != NULL) {
- if (found_addr->sa_family == AF_INET6) {
+ switch (found_addr->sa_family) {
+#ifdef INET6
+ case AF_INET6:
/* copy IPv6 address */
lookup->ph.param_type =
htons(SCTP_IPV6_ADDRESS);
@@ -2705,7 +2791,10 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
addr_size = sizeof(struct in6_addr);
addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
found_addr)->sin6_addr;
- } else {
+ break;
+#endif
+#ifdef INET
+ case AF_INET:
/* copy IPv4 address */
lookup->ph.param_type =
htons(SCTP_IPV4_ADDRESS);
@@ -2713,6 +2802,13 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
addr_size = sizeof(struct in_addr);
addr_ptr = (caddr_t)&((struct sockaddr_in *)
found_addr)->sin_addr;
+ break;
+#endif
+ default:
+ p_size = 0;
+ addr_size = 0;
+ addr_ptr = NULL;
+ break;
}
lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
memcpy(lookup->addr, addr_ptr, addr_size);
@@ -2722,7 +2818,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
/* uh oh... don't have any address?? */
SCTPDBG(SCTP_DEBUG_ASCONF1,
"compose_asconf: no lookup addr!\n");
- /* for now, we send a IPv4 address of 0.0.0.0 */
+ /* XXX for now, we send a IPv4 address of 0.0.0.0 */
lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
bzero(lookup->addr, sizeof(struct in_addr));
@@ -2754,8 +2850,15 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
uint16_t plen, ptype;
struct sctp_ifa *sctp_ifa;
struct sctp_ipv6addr_param addr_store;
+
+#ifdef INET6
struct sockaddr_in6 sin6;
+
+#endif
+#ifdef INET
struct sockaddr_in sin;
+
+#endif
struct sockaddr *sa;
uint32_t vrf_id;
@@ -2770,51 +2873,66 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
return;
}
/* init the addresses */
+#ifdef INET6
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
sin6.sin6_port = stcb->rport;
+#endif
+#ifdef INET
bzero(&sin, sizeof(sin));
- sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
sin.sin_port = stcb->rport;
+#endif
/* go through the addresses in the init-ack */
- ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
- sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
+ ph = (struct sctp_paramhdr *)
+ sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
+ (uint8_t *) & tmp_param);
while (ph != NULL) {
ptype = ntohs(ph->param_type);
plen = ntohs(ph->param_length);
- if (ptype == SCTP_IPV6_ADDRESS) {
- struct sctp_ipv6addr_param *a6p;
-
- /* get the entire IPv6 address param */
- a6p = (struct sctp_ipv6addr_param *)
- sctp_m_getptr(m, offset,
- sizeof(struct sctp_ipv6addr_param),
- (uint8_t *) & addr_store);
- if (plen != sizeof(struct sctp_ipv6addr_param) ||
- a6p == NULL) {
- return;
+ switch (ptype) {
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
+ {
+ struct sctp_ipv6addr_param *a6p;
+
+ /* get the entire IPv6 address param */
+ a6p = (struct sctp_ipv6addr_param *)
+ sctp_m_getptr(m, offset,
+ sizeof(struct sctp_ipv6addr_param),
+ (uint8_t *) & addr_store);
+ if (plen != sizeof(struct sctp_ipv6addr_param) ||
+ a6p == NULL) {
+ return;
+ }
+ memcpy(&sin6.sin6_addr, a6p->addr,
+ sizeof(struct in6_addr));
+ sa = (struct sockaddr *)&sin6;
+ break;
}
- memcpy(&sin6.sin6_addr, a6p->addr,
- sizeof(struct in6_addr));
- sa = (struct sockaddr *)&sin6;
- } else if (ptype == SCTP_IPV4_ADDRESS) {
- struct sctp_ipv4addr_param *a4p;
-
- /* get the entire IPv4 address param */
- a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
- sizeof(struct sctp_ipv4addr_param),
- (uint8_t *) & addr_store);
- if (plen != sizeof(struct sctp_ipv4addr_param) ||
- a4p == NULL) {
- return;
+#endif
+#ifdef INET
+ case SCTP_IPV4_ADDRESS:
+ {
+ struct sctp_ipv4addr_param *a4p;
+
+ /* get the entire IPv4 address param */
+ a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
+ sizeof(struct sctp_ipv4addr_param),
+ (uint8_t *) & addr_store);
+ if (plen != sizeof(struct sctp_ipv4addr_param) ||
+ a4p == NULL) {
+ return;
+ }
+ sin.sin_addr.s_addr = a4p->addr;
+ sa = (struct sockaddr *)&sin;
}
- sin.sin_addr.s_addr = a4p->addr;
- sa = (struct sockaddr *)&sin;
- } else {
+#endif
+ default:
goto next_addr;
}
@@ -2885,22 +3003,31 @@ sctp_addr_in_initack(struct sctp_tcb *stcb, struct mbuf *m, uint32_t offset,
struct sctp_paramhdr tmp_param, *ph;
uint16_t plen, ptype;
struct sctp_ipv6addr_param addr_store;
+
+#ifdef INET
struct sockaddr_in *sin;
struct sctp_ipv4addr_param *a4p;
+#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
struct sctp_ipv6addr_param *a6p;
struct sockaddr_in6 sin6_tmp;
-#endif /* INET6 */
+#endif
- if (
+ switch (sa->sa_family) {
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
#ifdef INET6
- (sa->sa_family != AF_INET6) &&
-#endif /* INET6 */
- (sa->sa_family != AF_INET))
+ case AF_INET6:
+ break;
+#endif
+ default:
return (0);
+ }
SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
@@ -2918,55 +3045,68 @@ sctp_addr_in_initack(struct sctp_tcb *stcb, struct mbuf *m, uint32_t offset,
while (ph != NULL) {
ptype = ntohs(ph->param_type);
plen = ntohs(ph->param_length);
+ switch (ptype) {
#ifdef INET6
- if (ptype == SCTP_IPV6_ADDRESS && sa->sa_family == AF_INET6) {
- /* get the entire IPv6 address param */
- a6p = (struct sctp_ipv6addr_param *)
- sctp_m_getptr(m, offset,
- sizeof(struct sctp_ipv6addr_param),
- (uint8_t *) & addr_store);
- if (plen != sizeof(struct sctp_ipv6addr_param) ||
- (ph == NULL) ||
- (a6p == NULL)) {
- return (0);
- }
- sin6 = (struct sockaddr_in6 *)sa;
- if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
- /* create a copy and clear scope */
- memcpy(&sin6_tmp, sin6,
- sizeof(struct sockaddr_in6));
- sin6 = &sin6_tmp;
- in6_clearscope(&sin6->sin6_addr);
- }
- if (memcmp(&sin6->sin6_addr, a6p->addr,
- sizeof(struct in6_addr)) == 0) {
- /* found it */
- return (1);
+ case SCTP_IPV6_ADDRESS:
+ if (sa->sa_family == AF_INET6) {
+ /* get the entire IPv6 address param */
+ if (plen != sizeof(struct sctp_ipv6addr_param)) {
+ break;
+ }
+ /* get the entire IPv6 address param */
+ a6p = (struct sctp_ipv6addr_param *)
+ sctp_m_getptr(m, offset,
+ sizeof(struct sctp_ipv6addr_param),
+ (uint8_t *) & addr_store);
+ if (a6p == NULL) {
+ return (0);
+ }
+ sin6 = (struct sockaddr_in6 *)sa;
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
+ /* create a copy and clear scope */
+ memcpy(&sin6_tmp, sin6,
+ sizeof(struct sockaddr_in6));
+ sin6 = &sin6_tmp;
+ in6_clearscope(&sin6->sin6_addr);
+ }
+ if (memcmp(&sin6->sin6_addr, a6p->addr,
+ sizeof(struct in6_addr)) == 0) {
+ /* found it */
+ return (1);
+ }
}
- } else
+ break;
#endif /* INET6 */
-
- if (ptype == SCTP_IPV4_ADDRESS &&
- sa->sa_family == AF_INET) {
- /* get the entire IPv4 address param */
- a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m,
- offset, sizeof(struct sctp_ipv4addr_param),
- (uint8_t *) & addr_store);
- if (plen != sizeof(struct sctp_ipv4addr_param) ||
- (ph == NULL) ||
- (a4p == NULL)) {
- return (0);
- }
- sin = (struct sockaddr_in *)sa;
- if (sin->sin_addr.s_addr == a4p->addr) {
- /* found it */
- return (1);
+#ifdef INET
+ case SCTP_IPV4_ADDRESS:
+ if (sa->sa_family == AF_INET) {
+ if (plen != sizeof(struct sctp_ipv4addr_param)) {
+ break;
+ }
+ /* get the entire IPv4 address param */
+ a4p = (struct sctp_ipv4addr_param *)
+ sctp_m_getptr(m, offset,
+ sizeof(struct sctp_ipv4addr_param),
+ (uint8_t *) & addr_store);
+ if (a4p == NULL) {
+ return (0);
+ }
+ sin = (struct sockaddr_in *)sa;
+ if (sin->sin_addr.s_addr == a4p->addr) {
+ /* found it */
+ return (1);
+ }
}
+ break;
+#endif
+ default:
+ break;
}
/* get next parameter */
offset += SCTP_SIZE32(plen);
- if (offset + sizeof(struct sctp_paramhdr) > length)
+ if (offset + sizeof(struct sctp_paramhdr) > length) {
return (0);
+ }
ph = (struct sctp_paramhdr *)
sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
(uint8_t *) & tmp_param);
@@ -3198,8 +3338,11 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
struct sctp_asconf_addr *aa;
struct sctp_ifa *sctp_ifap;
struct sctp_asconf_tag_param *vtag;
+
+#ifdef INET
struct sockaddr_in *to;
+#endif
#ifdef INET6
struct sockaddr_in6 *to6;
@@ -3247,24 +3390,28 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
memset(aa, 0, sizeof(struct sctp_asconf_addr));
/* fill in asconf address parameter fields */
/* ADD(0.0.0.0) */
- if (net->ro._l_addr.sa.sa_family == AF_INET) {
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
- }
+ break;
+#endif
#ifdef INET6
- else if (net->ro._l_addr.sa.sa_family == AF_INET6) {
+ case AF_INET6:
aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
+ break;
+#endif
}
-#endif /* INET6 */
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
SCTP_M_ASC_ADDR);
if (aa == NULL) {
@@ -3276,24 +3423,28 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
memset(aa, 0, sizeof(struct sctp_asconf_addr));
/* fill in asconf address parameter fields */
/* ADD(0.0.0.0) */
- if (net->ro._l_addr.sa.sa_family == AF_INET) {
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
- }
+ break;
+#endif
#ifdef INET6
- else if (net->ro._l_addr.sa.sa_family == AF_INET6) {
+ case AF_INET6:
aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
/* No need to add an address, we are using 0.0.0.0 */
TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
+ break;
+#endif
}
-#endif /* INET6 */
/* Now we must hunt the addresses and add all global addresses */
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
struct sctp_vrf *vrf = NULL;
@@ -3308,18 +3459,20 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
SCTP_IPI_ADDR_RLOCK();
LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
- if (sctp_ifap->address.sa.sa_family == AF_INET) {
+ switch (sctp_ifap->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
to = &sctp_ifap->address.sin;
-
if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
continue;
}
if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
continue;
}
- }
+ break;
+#endif
#ifdef INET6
- else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
+ case AF_INET6:
to6 = &sctp_ifap->address.sin6;
if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
continue;
@@ -3327,8 +3480,11 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
continue;
}
- }
+ break;
#endif
+ default:
+ continue;
+ }
sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
}
}
@@ -3354,18 +3510,20 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
continue;
}
sctp_ifap = laddr->ifa;
- if (sctp_ifap->address.sa.sa_family == AF_INET) {
+ switch (sctp_ifap->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
to = &sctp_ifap->address.sin;
-
if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
continue;
}
if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
continue;
}
- }
+ break;
+#endif
#ifdef INET6
- else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
+ case AF_INET6:
to6 = &sctp_ifap->address.sin6;
if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
continue;
@@ -3373,8 +3531,11 @@ sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
continue;
}
- }
+ break;
#endif
+ default:
+ continue;
+ }
sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
}
}
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index 0a35df07f961..3d004b6b108c 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -228,10 +228,14 @@ sctp_init_ifns_for_vrf(int vrfid)
*/
struct ifnet *ifn;
struct ifaddr *ifa;
- struct in6_ifaddr *ifa6;
struct sctp_ifa *sctp_ifa;
uint32_t ifa_flags;
+#ifdef INET6
+ struct in6_ifaddr *ifa6;
+
+#endif
+
IFNET_RLOCK();
TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) {
IF_ADDR_LOCK(ifn);
@@ -239,29 +243,44 @@ sctp_init_ifns_for_vrf(int vrfid)
if (ifa->ifa_addr == NULL) {
continue;
}
- if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
- /* non inet/inet6 skip */
- continue;
- }
- if (ifa->ifa_addr->sa_family == AF_INET6) {
- if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
- /* skip unspecifed addresses */
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
continue;
}
- } else {
- if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
+ /* skip unspecifed addresses */
continue;
}
+ break;
+#endif
+ default:
+ continue;
}
if (sctp_is_desired_interface_type(ifa) == 0) {
/* non desired type */
continue;
}
- if (ifa->ifa_addr->sa_family == AF_INET6) {
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ ifa_flags = 0;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
ifa6 = (struct in6_ifaddr *)ifa;
ifa_flags = ifa6->ia6_flags;
- } else {
+ break;
+#endif
+ default:
ifa_flags = 0;
+ break;
}
sctp_ifa = sctp_add_addr_to_vrf(vrfid,
(void *)ifn,
@@ -320,20 +339,26 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
if (ifa->ifa_addr == NULL) {
return;
}
- if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
- /* non inet/inet6 skip */
- return;
- }
- if (ifa->ifa_addr->sa_family == AF_INET6) {
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
+ return;
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags;
if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
/* skip unspecifed addresses */
return;
}
- } else {
- if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
- return;
- }
+ break;
+#endif
+ default:
+ /* non inet/inet6 skip */
+ return;
}
if (sctp_is_desired_interface_type(ifa) == 0) {
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 3c25eaabf291..63771d7e8932 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -530,38 +530,57 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
struct sctp_tcb *stcb, struct sctp_nets *net)
{
struct sockaddr_storage store;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
struct sctp_nets *r_net, *f_net;
struct timeval tv;
int req_prim = 0;
+#ifdef INET
+ struct sockaddr_in *sin;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+
+#endif
+
if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) {
/* Invalid length */
return;
}
- sin = (struct sockaddr_in *)&store;
- sin6 = (struct sockaddr_in6 *)&store;
-
memset(&store, 0, sizeof(store));
- if (cp->heartbeat.hb_info.addr_family == AF_INET &&
- cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) {
- sin->sin_family = cp->heartbeat.hb_info.addr_family;
- sin->sin_len = cp->heartbeat.hb_info.addr_len;
- sin->sin_port = stcb->rport;
- memcpy(&sin->sin_addr, cp->heartbeat.hb_info.address,
- sizeof(sin->sin_addr));
- } else if (cp->heartbeat.hb_info.addr_family == AF_INET6 &&
- cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) {
- sin6->sin6_family = cp->heartbeat.hb_info.addr_family;
- sin6->sin6_len = cp->heartbeat.hb_info.addr_len;
- sin6->sin6_port = stcb->rport;
- memcpy(&sin6->sin6_addr, cp->heartbeat.hb_info.address,
- sizeof(sin6->sin6_addr));
- } else {
+ switch (cp->heartbeat.hb_info.addr_family) {
+#ifdef INET
+ case AF_INET:
+ if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) {
+ sin = (struct sockaddr_in *)&store;
+ sin->sin_family = cp->heartbeat.hb_info.addr_family;
+ sin->sin_len = cp->heartbeat.hb_info.addr_len;
+ sin->sin_port = stcb->rport;
+ memcpy(&sin->sin_addr, cp->heartbeat.hb_info.address,
+ sizeof(sin->sin_addr));
+ } else {
+ return;
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) {
+ sin6 = (struct sockaddr_in6 *)&store;
+ sin6->sin6_family = cp->heartbeat.hb_info.addr_family;
+ sin6->sin6_len = cp->heartbeat.hb_info.addr_len;
+ sin6->sin6_port = stcb->rport;
+ memcpy(&sin6->sin6_addr, cp->heartbeat.hb_info.address,
+ sizeof(sin6->sin6_addr));
+ } else {
+ return;
+ }
+ break;
+#endif
+ default:
return;
}
- r_net = sctp_findnet(stcb, (struct sockaddr *)sin);
+ r_net = sctp_findnet(stcb, (struct sockaddr *)&store);
if (r_net == NULL) {
SCTPDBG(SCTP_DEBUG_INPUT1, "Huh? I can't find the address I sent it to, discard\n");
return;
@@ -1940,8 +1959,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
struct sctp_init_ack_chunk *initack_cp, initack_buf;
struct sockaddr_storage sa_store;
struct sockaddr *initack_src = (struct sockaddr *)&sa_store;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
struct sctp_association *asoc;
int chk_length;
int init_offset, initack_offset, initack_limit;
@@ -1950,6 +1967,14 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
uint32_t old_tag;
uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
+#ifdef INET
+ struct sockaddr_in *sin;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+
+#endif
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
@@ -2169,14 +2194,19 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
/* warning, we re-use sin, sin6, sa_store here! */
/* pull in local_address (our "from" address) */
- if (cookie->laddr_type == SCTP_IPV4_ADDRESS) {
+ switch (cookie->laddr_type) {
+#ifdef INET
+ case SCTP_IPV4_ADDRESS:
/* source addr is IPv4 */
sin = (struct sockaddr_in *)initack_src;
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr.s_addr = cookie->laddress[0];
- } else if (cookie->laddr_type == SCTP_IPV6_ADDRESS) {
+ break;
+#endif
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
/* source addr is IPv6 */
sin6 = (struct sockaddr_in6 *)initack_src;
memset(sin6, 0, sizeof(*sin6));
@@ -2185,7 +2215,9 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
sin6->sin6_scope_id = cookie->scope_id;
memcpy(&sin6->sin6_addr, cookie->laddress,
sizeof(sin6->sin6_addr));
- } else {
+ break;
+#endif
+ default:
atomic_add_int(&stcb->asoc.refcnt, 1);
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_TCB_UNLOCK(stcb);
@@ -2295,8 +2327,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
struct sctp_tcb **locked_tcb, uint32_t vrf_id, uint16_t port)
{
struct sctp_state_cookie *cookie;
- struct sockaddr_in6 sin6;
- struct sockaddr_in sin;
struct sctp_tcb *l_stcb = *stcb;
struct sctp_inpcb *l_inp;
struct sockaddr *to;
@@ -2318,6 +2348,15 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
int had_a_existing_tcb = 0;
int send_int_conf = 0;
+#ifdef INET
+ struct sockaddr_in sin;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 sin6;
+
+#endif
+
SCTPDBG(SCTP_DEBUG_INPUT2,
"sctp_handle_cookie: handling COOKIE-ECHO\n");
@@ -2327,6 +2366,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
/* its IPv4 */
@@ -2341,6 +2381,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
size_of_pkt = SCTP_GET_IPV4_LENGTH(iph);
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
@@ -2535,7 +2576,9 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
* up.
*/
to = NULL;
- if (cookie->addr_type == SCTP_IPV6_ADDRESS) {
+ switch (cookie->addr_type) {
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
@@ -2544,14 +2587,19 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
memcpy(&sin6.sin6_addr.s6_addr, cookie->address,
sizeof(sin6.sin6_addr.s6_addr));
to = (struct sockaddr *)&sin6;
- } else if (cookie->addr_type == SCTP_IPV4_ADDRESS) {
+ break;
+#endif
+#ifdef INET
+ case SCTP_IPV4_ADDRESS:
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(sin);
sin.sin_port = sh->src_port;
sin.sin_addr.s_addr = cookie->address[0];
to = (struct sockaddr *)&sin;
- } else {
+ break;
+#endif
+ default:
/* This should not happen */
return (NULL);
}
@@ -5705,6 +5753,7 @@ sctp_print_mbuf_chain(struct mbuf *m)
#endif
+#ifdef INET
void
sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
{
@@ -6003,3 +6052,5 @@ sctp_input(struct mbuf *m, int off)
#endif
sctp_input_with_port(m, off, 0);
}
+
+#endif
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index 4e0dcab53520..4ab0add869de 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -39,7 +39,9 @@ __FBSDID("$FreeBSD$");
#include "opt_ipsec.h"
#include "opt_compat.h"
#include "opt_inet6.h"
+#if 1
#include "opt_inet.h"
+#endif
#include "opt_sctp.h"
#include <sys/param.h>
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 23361baf57aa..1e16b99e6315 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -1880,6 +1880,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
return (0);
}
switch (ifa->address.sa.sa_family) {
+#ifdef INET
case AF_INET:
if (ipv4_addr_legal) {
struct sockaddr_in *sin;
@@ -1898,6 +1899,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
return (0);
}
break;
+#endif
#ifdef INET6
case AF_INET6:
if (ipv6_addr_legal) {
@@ -1945,12 +1947,18 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa)
struct mbuf *mret;
int len;
- if (ifa->address.sa.sa_family == AF_INET) {
+ switch (ifa->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
len = sizeof(struct sctp_ipv4addr_param);
- } else if (ifa->address.sa.sa_family == AF_INET6) {
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
len = sizeof(struct sctp_ipv6addr_param);
- } else {
- /* unknown type */
+ break;
+#endif
+ default:
return (m);
}
if (M_TRAILINGSPACE(m) >= len) {
@@ -1973,6 +1981,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa)
}
/* now add the parameter */
switch (ifa->address.sa.sa_family) {
+#ifdef INET
case AF_INET:
{
struct sctp_ipv4addr_param *ipv4p;
@@ -1986,6 +1995,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa)
SCTP_BUF_LEN(mret) += len;
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -2225,6 +2235,7 @@ sctp_is_ifa_addr_preferred(struct sctp_ifa *ifa,
SCTPDBG(SCTP_DEBUG_OUTPUT2, "Is destination preferred:");
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &ifa->address.sa);
/* Ok the address may be ok */
+#ifdef INET6
if (fam == AF_INET6) {
/* ok to use deprecated addresses? no lets not! */
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
@@ -2244,6 +2255,7 @@ sctp_is_ifa_addr_preferred(struct sctp_ifa *ifa,
}
}
}
+#endif
/*
* Now that we know what is what, implement or table this could in
* theory be done slicker (it used to be), but this is
@@ -2312,6 +2324,7 @@ sctp_is_ifa_addr_acceptable(struct sctp_ifa *ifa,
if ((dest_is_loop == 0) && (dest_is_priv == 0)) {
dest_is_global = 1;
}
+#ifdef INET6
if (fam == AF_INET6) {
/* ok to use deprecated addresses? */
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
@@ -2323,6 +2336,7 @@ sctp_is_ifa_addr_acceptable(struct sctp_ifa *ifa,
return (NULL);
}
}
+#endif
/*
* Now that we know what is what, implement our table. This could in
* theory be done slicker (it used to be), but this is
@@ -2734,6 +2748,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
}
}
#endif
+#ifdef INET
/* Avoid topologically incorrect IPv4 address */
if (stcb && fam == AF_INET &&
sctp_is_mobility_feature_on(stcb->sctp_ep, SCTP_MOBILITY_BASE)) {
@@ -2741,6 +2756,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
continue;
}
}
+#endif
if (stcb) {
if (sctp_is_address_in_scope(ifa,
stcb->asoc.ipv4_addr_legal,
@@ -3077,15 +3093,18 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
struct sctp_nets *net,
int non_asoc_addr_ok, uint32_t vrf_id)
{
+ struct sctp_ifa *answer;
+ uint8_t dest_is_priv, dest_is_loop;
+ sa_family_t fam;
+
+#ifdef INET
struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst;
+#endif
#ifdef INET6
struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst;
#endif
- struct sctp_ifa *answer;
- uint8_t dest_is_priv, dest_is_loop;
- sa_family_t fam;
/*-
* Rules: - Find the route if needed, cache if I can. - Look at
@@ -3158,10 +3177,11 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
if (ro->ro_rt == NULL) {
return (NULL);
}
- fam = to->sin_family;
+ fam = ro->ro_dst.sa_family;
dest_is_priv = dest_is_loop = 0;
/* Setup our scopes for the destination */
switch (fam) {
+#ifdef INET
case AF_INET:
/* Scope based on outbound address */
if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
@@ -3174,6 +3194,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
dest_is_priv = 1;
}
break;
+#endif
#ifdef INET6
case AF_INET6:
/* Scope based on outbound address */
@@ -3197,7 +3218,7 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
#endif
}
SCTPDBG(SCTP_DEBUG_OUTPUT2, "Select source addr for:");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)to);
+ SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&ro->ro_dst);
SCTP_IPI_ADDR_RLOCK();
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
/*
@@ -3398,6 +3419,70 @@ sctp_get_ect(struct sctp_tcb *stcb,
}
}
+static void
+sctp_handle_no_route(struct sctp_tcb *stcb,
+ struct sctp_nets *net,
+ int so_locked)
+{
+ SCTPDBG(SCTP_DEBUG_OUTPUT1, "dropped packet - no valid source addr\n");
+
+ if (net) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT1, "Destination was ");
+ SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT1, &net->ro._l_addr.sa);
+ if (net->dest_state & SCTP_ADDR_CONFIRMED) {
+ if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT1, "no route takes interface %p down\n", net);
+ sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
+ stcb,
+ SCTP_FAILED_THRESHOLD,
+ (void *)net,
+ so_locked);
+ net->dest_state &= ~SCTP_ADDR_REACHABLE;
+ net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
+ /*
+ * JRS 5/14/07 - If a destination is
+ * unreachable, the PF bit is turned off.
+ * This allows an unambiguous use of the PF
+ * bit for destinations that are reachable
+ * but potentially failed. If the
+ * destination is set to the unreachable
+ * state, also set the destination to the PF
+ * state.
+ */
+ /*
+ * Add debug message here if destination is
+ * not in PF state.
+ */
+ /* Stop any running T3 timers here? */
+ if ((stcb->asoc.sctp_cmt_on_off > 0) &&
+ (stcb->asoc.sctp_cmt_pf > 0)) {
+ net->dest_state &= ~SCTP_ADDR_PF;
+ SCTPDBG(SCTP_DEBUG_OUTPUT1, "Destination %p moved from PF to unreachable.\n",
+ net);
+ }
+ }
+ }
+ if (stcb) {
+ if (net == stcb->asoc.primary_destination) {
+ /* need a new primary */
+ struct sctp_nets *alt;
+
+ alt = sctp_find_alternate_net(stcb, net, 0);
+ if (alt != net) {
+ if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, alt) == 0) {
+ net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
+ if (net->ro._s_addr) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ }
+ net->src_addr_selected = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
static int
sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
struct sctp_tcb *stcb, /* may be NULL */
@@ -3464,658 +3549,617 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
if ((auth != NULL) && (stcb != NULL)) {
sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
}
- if (to->sa_family == AF_INET) {
- struct ip *ip = NULL;
- sctp_route_t iproute;
- uint8_t tos_value;
- int len;
-
- len = sizeof(struct ip) + sizeof(struct sctphdr);
- if (port) {
- len += sizeof(struct udphdr);
- }
- newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
- if (newm == NULL) {
- sctp_m_freem(m);
- SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
- }
- SCTP_ALIGN_TO_END(newm, len);
- SCTP_BUF_LEN(newm) = len;
- SCTP_BUF_NEXT(newm) = m;
- m = newm;
- if (net != NULL) {
-#ifdef INVARIANTS
- if (net->flowidset == 0) {
- panic("Flow ID not set");
+ switch (to->sa_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct ip *ip = NULL;
+ sctp_route_t iproute;
+ uint8_t tos_value;
+ int len;
+
+ len = sizeof(struct ip) + sizeof(struct sctphdr);
+ if (port) {
+ len += sizeof(struct udphdr);
+ }
+ newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
+ if (newm == NULL) {
+ sctp_m_freem(m);
+ SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
+ return (ENOMEM);
}
+ SCTP_ALIGN_TO_END(newm, len);
+ SCTP_BUF_LEN(newm) = len;
+ SCTP_BUF_NEXT(newm) = m;
+ m = newm;
+ if (net != NULL) {
+#ifdef INVARIANTS
+ if (net->flowidset == 0) {
+ panic("Flow ID not set");
+ }
#endif
- m->m_pkthdr.flowid = net->flowid;
- m->m_flags |= M_FLOWID;
- } else {
- if ((init != NULL) && (init->m_flags & M_FLOWID)) {
- m->m_pkthdr.flowid = init->m_pkthdr.flowid;
+ m->m_pkthdr.flowid = net->flowid;
m->m_flags |= M_FLOWID;
+ } else {
+ if ((init != NULL) && (init->m_flags & M_FLOWID)) {
+ m->m_pkthdr.flowid = init->m_pkthdr.flowid;
+ m->m_flags |= M_FLOWID;
+ }
}
- }
- packet_length = sctp_calculate_len(m);
- ip = mtod(m, struct ip *);
- ip->ip_v = IPVERSION;
- ip->ip_hl = (sizeof(struct ip) >> 2);
- if (net) {
- tos_value = net->tos_flowlabel & 0x000000ff;
- } else {
- tos_value = inp->ip_inp.inp.inp_ip_tos;
- }
- if ((nofragment_flag) && (port == 0)) {
- ip->ip_off = IP_DF;
- } else
- ip->ip_off = 0;
-
- /* FreeBSD has a function for ip_id's */
- ip->ip_id = ip_newid();
+ packet_length = sctp_calculate_len(m);
+ ip = mtod(m, struct ip *);
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = (sizeof(struct ip) >> 2);
+ if (net) {
+ tos_value = net->tos_flowlabel & 0x000000ff;
+ } else {
+ tos_value = inp->ip_inp.inp.inp_ip_tos;
+ }
+ if ((nofragment_flag) && (port == 0)) {
+ ip->ip_off = IP_DF;
+ } else
+ ip->ip_off = 0;
- ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
- ip->ip_len = packet_length;
- ip->ip_tos = tos_value & 0xfc;
- if (ecn_ok) {
- ip->ip_tos |= sctp_get_ect(stcb, chk);
- }
- if (port) {
- ip->ip_p = IPPROTO_UDP;
- } else {
- ip->ip_p = IPPROTO_SCTP;
- }
- ip->ip_sum = 0;
- if (net == NULL) {
- ro = &iproute;
- memset(&iproute, 0, sizeof(iproute));
- memcpy(&ro->ro_dst, to, to->sa_len);
- } else {
- ro = (sctp_route_t *) & net->ro;
- }
- /* Now the address selection part */
- ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
+ /* FreeBSD has a function for ip_id's */
+ ip->ip_id = ip_newid();
- /* call the routine to select the src address */
- if (net && out_of_asoc_ok == 0) {
- if (net->ro._s_addr && (net->ro._s_addr->localifa_flags & (SCTP_BEING_DELETED | SCTP_ADDR_IFA_UNUSEABLE))) {
- sctp_free_ifa(net->ro._s_addr);
- net->ro._s_addr = NULL;
- net->src_addr_selected = 0;
- if (ro->ro_rt) {
- RTFREE(ro->ro_rt);
- ro->ro_rt = NULL;
- }
+ ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
+ ip->ip_len = packet_length;
+ ip->ip_tos = tos_value & 0xfc;
+ if (ecn_ok) {
+ ip->ip_tos |= sctp_get_ect(stcb, chk);
}
- if (net->src_addr_selected == 0) {
- /* Cache the source address */
- net->ro._s_addr = sctp_source_address_selection(inp, stcb,
- ro, net, 0,
- vrf_id);
- net->src_addr_selected = 1;
- }
- if (net->ro._s_addr == NULL) {
- /* No route to host */
- net->src_addr_selected = 0;
- goto no_route;
+ if (port) {
+ ip->ip_p = IPPROTO_UDP;
+ } else {
+ ip->ip_p = IPPROTO_SCTP;
}
- ip->ip_src = net->ro._s_addr->address.sin.sin_addr;
- } else {
- if (over_addr == NULL) {
- struct sctp_ifa *_lsrc;
-
- _lsrc = sctp_source_address_selection(inp, stcb, ro,
- net,
- out_of_asoc_ok,
- vrf_id);
- if (_lsrc == NULL) {
- goto no_route;
- }
- ip->ip_src = _lsrc->address.sin.sin_addr;
- sctp_free_ifa(_lsrc);
+ ip->ip_sum = 0;
+ if (net == NULL) {
+ ro = &iproute;
+ memset(&iproute, 0, sizeof(iproute));
+ memcpy(&ro->ro_dst, to, to->sa_len);
} else {
- ip->ip_src = over_addr->sin.sin_addr;
- SCTP_RTALLOC(ro, vrf_id);
+ ro = (sctp_route_t *) & net->ro;
}
- }
- if (port) {
- udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip));
- udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
- udp->uh_dport = port;
- udp->uh_ulen = htons(packet_length - sizeof(struct ip));
- udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
- sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
- } else {
- sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip));
- }
-
- sctphdr->src_port = src_port;
- sctphdr->dest_port = dest_port;
- sctphdr->v_tag = v_tag;
- sctphdr->checksum = 0;
+ /* Now the address selection part */
+ ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
- /*
- * If source address selection fails and we find no route
- * then the ip_output should fail as well with a
- * NO_ROUTE_TO_HOST type error. We probably should catch
- * that somewhere and abort the association right away
- * (assuming this is an INIT being sent).
- */
- if ((ro->ro_rt == NULL)) {
- /*
- * src addr selection failed to find a route (or
- * valid source addr), so we can't get there from
- * here (yet)!
- */
- no_route:
- SCTPDBG(SCTP_DEBUG_OUTPUT1,
- "%s: dropped packet - no valid source addr\n",
- __FUNCTION__);
- if (net) {
- SCTPDBG(SCTP_DEBUG_OUTPUT1,
- "Destination was ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT1,
- &net->ro._l_addr.sa);
- if (net->dest_state & SCTP_ADDR_CONFIRMED) {
- if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) {
- SCTPDBG(SCTP_DEBUG_OUTPUT1, "no route takes interface %p down\n", net);
- sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
- stcb,
- SCTP_FAILED_THRESHOLD,
- (void *)net,
- so_locked);
- net->dest_state &= ~SCTP_ADDR_REACHABLE;
- net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
- /*
- * JRS 5/14/07 - If a
- * destination is
- * unreachable, the PF bit
- * is turned off. This
- * allows an unambiguous use
- * of the PF bit for
- * destinations that are
- * reachable but potentially
- * failed. If the
- * destination is set to the
- * unreachable state, also
- * set the destination to
- * the PF state.
- */
- /*
- * Add debug message here if
- * destination is not in PF
- * state.
- */
- /*
- * Stop any running T3
- * timers here?
- */
- if ((stcb->asoc.sctp_cmt_on_off > 0) &&
- (stcb->asoc.sctp_cmt_pf > 0)) {
- net->dest_state &= ~SCTP_ADDR_PF;
- SCTPDBG(SCTP_DEBUG_OUTPUT1, "Destination %p moved from PF to unreachable.\n",
- net);
- }
+ /* call the routine to select the src address */
+ if (net && out_of_asoc_ok == 0) {
+ if (net->ro._s_addr && (net->ro._s_addr->localifa_flags & (SCTP_BEING_DELETED | SCTP_ADDR_IFA_UNUSEABLE))) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ net->src_addr_selected = 0;
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = NULL;
}
}
- if (stcb) {
- if (net == stcb->asoc.primary_destination) {
- /* need a new primary */
- struct sctp_nets *alt;
-
- alt = sctp_find_alternate_net(stcb, net, 0);
- if (alt != net) {
- if (sctp_set_primary_addr(stcb,
- (struct sockaddr *)NULL,
- alt) == 0) {
- net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
- if (net->ro._s_addr) {
- sctp_free_ifa(net->ro._s_addr);
- net->ro._s_addr = NULL;
- }
- net->src_addr_selected = 0;
- }
- }
+ if (net->src_addr_selected == 0) {
+ /* Cache the source address */
+ net->ro._s_addr = sctp_source_address_selection(inp, stcb,
+ ro, net, 0,
+ vrf_id);
+ net->src_addr_selected = 1;
+ }
+ if (net->ro._s_addr == NULL) {
+ /* No route to host */
+ net->src_addr_selected = 0;
+ sctp_handle_no_route(stcb, net, so_locked);
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
+ sctp_m_freem(m);
+ return (EHOSTUNREACH);
+ }
+ ip->ip_src = net->ro._s_addr->address.sin.sin_addr;
+ } else {
+ if (over_addr == NULL) {
+ struct sctp_ifa *_lsrc;
+
+ _lsrc = sctp_source_address_selection(inp, stcb, ro,
+ net,
+ out_of_asoc_ok,
+ vrf_id);
+ if (_lsrc == NULL) {
+ sctp_handle_no_route(stcb, net, so_locked);
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
+ sctp_m_freem(m);
+ return (EHOSTUNREACH);
}
+ ip->ip_src = _lsrc->address.sin.sin_addr;
+ sctp_free_ifa(_lsrc);
+ } else {
+ ip->ip_src = over_addr->sin.sin_addr;
+ SCTP_RTALLOC(ro, vrf_id);
}
}
- SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
- sctp_m_freem(m);
- return (EHOSTUNREACH);
- }
- if (ro != &iproute) {
- memcpy(&iproute, ro, sizeof(*ro));
- }
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv4 output routine from low level src addr:%x\n",
- (uint32_t) (ntohl(ip->ip_src.s_addr)));
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "Destination is %x\n",
- (uint32_t) (ntohl(ip->ip_dst.s_addr)));
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "RTP route is %p through\n",
- ro->ro_rt);
+ if (port) {
+ udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip));
+ udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
+ udp->uh_dport = port;
+ udp->uh_ulen = htons(packet_length - sizeof(struct ip));
+ udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
+ sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+ } else {
+ sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip));
+ }
- if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
- /* failed to prepend data, give up */
- SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- sctp_m_freem(m);
- return (ENOMEM);
- }
+ sctphdr->src_port = src_port;
+ sctphdr->dest_port = dest_port;
+ sctphdr->v_tag = v_tag;
+ sctphdr->checksum = 0;
+
+ /*
+ * If source address selection fails and we find no
+ * route then the ip_output should fail as well with
+ * a NO_ROUTE_TO_HOST type error. We probably should
+ * catch that somewhere and abort the association
+ * right away (assuming this is an INIT being sent).
+ */
+ if (ro->ro_rt == NULL) {
+ /*
+ * src addr selection failed to find a route
+ * (or valid source addr), so we can't get
+ * there from here (yet)!
+ */
+ sctp_handle_no_route(stcb, net, so_locked);
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
+ sctp_m_freem(m);
+ return (EHOSTUNREACH);
+ }
+ if (ro != &iproute) {
+ memcpy(&iproute, ro, sizeof(*ro));
+ }
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv4 output routine from low level src addr:%x\n",
+ (uint32_t) (ntohl(ip->ip_src.s_addr)));
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Destination is %x\n",
+ (uint32_t) (ntohl(ip->ip_dst.s_addr)));
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "RTP route is %p through\n",
+ ro->ro_rt);
+
+ if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
+ /* failed to prepend data, give up */
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
+ sctp_m_freem(m);
+ return (ENOMEM);
+ }
#ifdef SCTP_PACKET_LOGGING
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
- sctp_packet_log(m, packet_length);
+ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
+ sctp_packet_log(m, packet_length);
#endif
- SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
- if (port) {
+ SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
+ if (port) {
#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
- if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (stcb) &&
- (stcb->asoc.loopback_scope))) {
- sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
- SCTP_STAT_INCR(sctps_sendswcrc);
- } else {
SCTP_STAT_INCR(sctps_sendnocrc);
- }
+#else
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
#endif
- SCTP_ENABLE_UDP_CSUM(o_pak);
- } else {
+ SCTP_ENABLE_UDP_CSUM(o_pak);
+ } else {
#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
+ SCTP_STAT_INCR(sctps_sendnocrc);
#else
- m->m_pkthdr.csum_flags = CSUM_SCTP;
- m->m_pkthdr.csum_data = 0;
- SCTP_STAT_INCR(sctps_sendhwcrc);
+ m->m_pkthdr.csum_flags = CSUM_SCTP;
+ m->m_pkthdr.csum_data = 0;
+ SCTP_STAT_INCR(sctps_sendhwcrc);
#endif
- }
- /* send it out. table id is taken from stcb */
+ }
+ /* send it out. table id is taken from stcb */
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
- if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
- so = SCTP_INP_SO(inp);
- SCTP_SOCKET_UNLOCK(so, 0);
- }
+ if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
+ so = SCTP_INP_SO(inp);
+ SCTP_SOCKET_UNLOCK(so, 0);
+ }
#endif
- SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id);
+ SCTP_IP_OUTPUT(ret, o_pak, ro, stcb, vrf_id);
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
- if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
- atomic_add_int(&stcb->asoc.refcnt, 1);
- SCTP_TCB_UNLOCK(stcb);
- SCTP_SOCKET_LOCK(so, 0);
- SCTP_TCB_LOCK(stcb);
- atomic_subtract_int(&stcb->asoc.refcnt, 1);
- }
+ if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
+ atomic_add_int(&stcb->asoc.refcnt, 1);
+ SCTP_TCB_UNLOCK(stcb);
+ SCTP_SOCKET_LOCK(so, 0);
+ SCTP_TCB_LOCK(stcb);
+ atomic_subtract_int(&stcb->asoc.refcnt, 1);
+ }
#endif
- SCTP_STAT_INCR(sctps_sendpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
- if (ret)
- SCTP_STAT_INCR(sctps_senderrors);
+ SCTP_STAT_INCR(sctps_sendpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
+ if (ret)
+ SCTP_STAT_INCR(sctps_senderrors);
+
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "IP output returns %d\n", ret);
+ if (net == NULL) {
+ /* free tempy routes */
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = NULL;
+ }
+ } else {
+ /*
+ * PMTU check versus smallest asoc MTU goes
+ * here
+ */
+ if ((ro->ro_rt != NULL) &&
+ (net->ro._s_addr)) {
+ uint32_t mtu;
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "IP output returns %d\n", ret);
- if (net == NULL) {
- /* free tempy routes */
- if (ro->ro_rt) {
- RTFREE(ro->ro_rt);
- ro->ro_rt = NULL;
- }
- } else {
- /* PMTU check versus smallest asoc MTU goes here */
- if ((ro->ro_rt != NULL) &&
- (net->ro._s_addr)) {
- uint32_t mtu;
-
- mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
- if (net->port) {
- mtu -= sizeof(struct udphdr);
- }
- if (mtu && (stcb->asoc.smallest_mtu > mtu)) {
- sctp_mtu_size_reset(inp, &stcb->asoc, mtu);
- net->mtu = mtu;
- }
- } else if (ro->ro_rt == NULL) {
- /* route was freed */
- if (net->ro._s_addr &&
- net->src_addr_selected) {
- sctp_free_ifa(net->ro._s_addr);
- net->ro._s_addr = NULL;
+ mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
+ if (net->port) {
+ mtu -= sizeof(struct udphdr);
+ }
+ if (mtu && (stcb->asoc.smallest_mtu > mtu)) {
+ sctp_mtu_size_reset(inp, &stcb->asoc, mtu);
+ net->mtu = mtu;
+ }
+ } else if (ro->ro_rt == NULL) {
+ /* route was freed */
+ if (net->ro._s_addr &&
+ net->src_addr_selected) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ }
+ net->src_addr_selected = 0;
}
- net->src_addr_selected = 0;
}
+ return (ret);
}
- return (ret);
- }
+#endif
#ifdef INET6
- else if (to->sa_family == AF_INET6) {
- uint32_t flowlabel;
- struct ip6_hdr *ip6h;
- struct route_in6 ip6route;
- struct ifnet *ifp;
- u_char flowTop;
- uint16_t flowBottom;
- u_char tosBottom, tosTop;
- struct sockaddr_in6 *sin6, tmp, *lsa6, lsa6_tmp;
- int prev_scope = 0;
- struct sockaddr_in6 lsa6_storage;
- int error;
- u_short prev_port = 0;
- int len;
-
- if (net != NULL) {
- flowlabel = net->tos_flowlabel;
- } else {
- flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
- }
+ case AF_INET6:
+ {
+ uint32_t flowlabel;
+ struct ip6_hdr *ip6h;
+ struct route_in6 ip6route;
+ struct ifnet *ifp;
+ u_char flowTop;
+ uint16_t flowBottom;
+ u_char tosBottom, tosTop;
+ struct sockaddr_in6 *sin6, tmp, *lsa6, lsa6_tmp;
+ int prev_scope = 0;
+ struct sockaddr_in6 lsa6_storage;
+ int error;
+ u_short prev_port = 0;
+ int len;
- len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
- if (port) {
- len += sizeof(struct udphdr);
- }
- newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
- if (newm == NULL) {
- sctp_m_freem(m);
- SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
- }
- SCTP_ALIGN_TO_END(newm, len);
- SCTP_BUF_LEN(newm) = len;
- SCTP_BUF_NEXT(newm) = m;
- m = newm;
- if (net != NULL) {
-#ifdef INVARIANTS
- if (net->flowidset == 0) {
- panic("Flow ID not set");
+ if (net != NULL) {
+ flowlabel = net->tos_flowlabel;
+ } else {
+ flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
+ }
+
+ len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
+ if (port) {
+ len += sizeof(struct udphdr);
}
+ newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
+ if (newm == NULL) {
+ sctp_m_freem(m);
+ SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
+ return (ENOMEM);
+ }
+ SCTP_ALIGN_TO_END(newm, len);
+ SCTP_BUF_LEN(newm) = len;
+ SCTP_BUF_NEXT(newm) = m;
+ m = newm;
+ if (net != NULL) {
+#ifdef INVARIANTS
+ if (net->flowidset == 0) {
+ panic("Flow ID not set");
+ }
#endif
- m->m_pkthdr.flowid = net->flowid;
- m->m_flags |= M_FLOWID;
- } else {
- if ((init != NULL) && (init->m_flags & M_FLOWID)) {
- m->m_pkthdr.flowid = init->m_pkthdr.flowid;
+ m->m_pkthdr.flowid = net->flowid;
m->m_flags |= M_FLOWID;
+ } else {
+ if ((init != NULL) && (init->m_flags & M_FLOWID)) {
+ m->m_pkthdr.flowid = init->m_pkthdr.flowid;
+ m->m_flags |= M_FLOWID;
+ }
}
- }
- packet_length = sctp_calculate_len(m);
+ packet_length = sctp_calculate_len(m);
- ip6h = mtod(m, struct ip6_hdr *);
- /*
- * We assume here that inp_flow is in host byte order within
- * the TCB!
- */
- flowBottom = flowlabel & 0x0000ffff;
- flowTop = ((flowlabel & 0x000f0000) >> 16);
- tosTop = (((flowlabel & 0xf0) >> 4) | IPV6_VERSION);
- /* protect *sin6 from overwrite */
- sin6 = (struct sockaddr_in6 *)to;
- tmp = *sin6;
- sin6 = &tmp;
-
- /* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
- SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
- return (EINVAL);
- }
- if (net == NULL) {
- memset(&ip6route, 0, sizeof(ip6route));
- ro = (sctp_route_t *) & ip6route;
- memcpy(&ro->ro_dst, sin6, sin6->sin6_len);
- } else {
- ro = (sctp_route_t *) & net->ro;
- }
- tosBottom = (((struct in6pcb *)inp)->in6p_flowinfo & 0x0c);
- if (ecn_ok) {
- tosBottom |= sctp_get_ect(stcb, chk);
- }
- tosBottom <<= 4;
- ip6h->ip6_flow = htonl(((tosTop << 24) | ((tosBottom | flowTop) << 16) | flowBottom));
- if (port) {
- ip6h->ip6_nxt = IPPROTO_UDP;
- } else {
- ip6h->ip6_nxt = IPPROTO_SCTP;
- }
- ip6h->ip6_plen = (packet_length - sizeof(struct ip6_hdr));
- ip6h->ip6_dst = sin6->sin6_addr;
+ ip6h = mtod(m, struct ip6_hdr *);
+ /*
+ * We assume here that inp_flow is in host byte
+ * order within the TCB!
+ */
+ flowBottom = flowlabel & 0x0000ffff;
+ flowTop = ((flowlabel & 0x000f0000) >> 16);
+ tosTop = (((flowlabel & 0xf0) >> 4) | IPV6_VERSION);
+ /* protect *sin6 from overwrite */
+ sin6 = (struct sockaddr_in6 *)to;
+ tmp = *sin6;
+ sin6 = &tmp;
- /*
- * Add SRC address selection here: we can only reuse to a
- * limited degree the kame src-addr-sel, since we can try
- * their selection but it may not be bound.
- */
- bzero(&lsa6_tmp, sizeof(lsa6_tmp));
- lsa6_tmp.sin6_family = AF_INET6;
- lsa6_tmp.sin6_len = sizeof(lsa6_tmp);
- lsa6 = &lsa6_tmp;
- if (net && out_of_asoc_ok == 0) {
- if (net->ro._s_addr && (net->ro._s_addr->localifa_flags & (SCTP_BEING_DELETED | SCTP_ADDR_IFA_UNUSEABLE))) {
- sctp_free_ifa(net->ro._s_addr);
- net->ro._s_addr = NULL;
- net->src_addr_selected = 0;
- if (ro->ro_rt) {
- RTFREE(ro->ro_rt);
- ro->ro_rt = NULL;
- }
+ /* KAME hack: embed scopeid */
+ if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ return (EINVAL);
}
- if (net->src_addr_selected == 0) {
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ if (net == NULL) {
+ memset(&ip6route, 0, sizeof(ip6route));
+ ro = (sctp_route_t *) & ip6route;
+ memcpy(&ro->ro_dst, sin6, sin6->sin6_len);
+ } else {
+ ro = (sctp_route_t *) & net->ro;
+ }
+ tosBottom = (((struct in6pcb *)inp)->in6p_flowinfo & 0x0c);
+ if (ecn_ok) {
+ tosBottom |= sctp_get_ect(stcb, chk);
+ }
+ tosBottom <<= 4;
+ ip6h->ip6_flow = htonl(((tosTop << 24) | ((tosBottom | flowTop) << 16) | flowBottom));
+ if (port) {
+ ip6h->ip6_nxt = IPPROTO_UDP;
+ } else {
+ ip6h->ip6_nxt = IPPROTO_SCTP;
+ }
+ ip6h->ip6_plen = (packet_length - sizeof(struct ip6_hdr));
+ ip6h->ip6_dst = sin6->sin6_addr;
+
+ /*
+ * Add SRC address selection here: we can only reuse
+ * to a limited degree the kame src-addr-sel, since
+ * we can try their selection but it may not be
+ * bound.
+ */
+ bzero(&lsa6_tmp, sizeof(lsa6_tmp));
+ lsa6_tmp.sin6_family = AF_INET6;
+ lsa6_tmp.sin6_len = sizeof(lsa6_tmp);
+ lsa6 = &lsa6_tmp;
+ if (net && out_of_asoc_ok == 0) {
+ if (net->ro._s_addr && (net->ro._s_addr->localifa_flags & (SCTP_BEING_DELETED | SCTP_ADDR_IFA_UNUSEABLE))) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
+ net->src_addr_selected = 0;
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = NULL;
+ }
+ }
+ if (net->src_addr_selected == 0) {
+ sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ /* KAME hack: embed scopeid */
+ if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ return (EINVAL);
+ }
+ /* Cache the source address */
+ net->ro._s_addr = sctp_source_address_selection(inp,
+ stcb,
+ ro,
+ net,
+ 0,
+ vrf_id);
+ (void)sa6_recoverscope(sin6);
+ net->src_addr_selected = 1;
+ }
+ if (net->ro._s_addr == NULL) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "V6:No route to host\n");
+ net->src_addr_selected = 0;
+ sctp_handle_no_route(stcb, net, so_locked);
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
+ sctp_m_freem(m);
+ return (EHOSTUNREACH);
+ }
+ lsa6->sin6_addr = net->ro._s_addr->address.sin6.sin6_addr;
+ } else {
+ sin6 = (struct sockaddr_in6 *)&ro->ro_dst;
/* KAME hack: embed scopeid */
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
return (EINVAL);
}
- /* Cache the source address */
- net->ro._s_addr = sctp_source_address_selection(inp,
- stcb,
- ro,
- net,
- 0,
- vrf_id);
+ if (over_addr == NULL) {
+ struct sctp_ifa *_lsrc;
+
+ _lsrc = sctp_source_address_selection(inp, stcb, ro,
+ net,
+ out_of_asoc_ok,
+ vrf_id);
+ if (_lsrc == NULL) {
+ sctp_handle_no_route(stcb, net, so_locked);
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
+ sctp_m_freem(m);
+ return (EHOSTUNREACH);
+ }
+ lsa6->sin6_addr = _lsrc->address.sin6.sin6_addr;
+ sctp_free_ifa(_lsrc);
+ } else {
+ lsa6->sin6_addr = over_addr->sin6.sin6_addr;
+ SCTP_RTALLOC(ro, vrf_id);
+ }
(void)sa6_recoverscope(sin6);
- net->src_addr_selected = 1;
}
- if (net->ro._s_addr == NULL) {
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "V6:No route to host\n");
- net->src_addr_selected = 0;
- goto no_route;
+ lsa6->sin6_port = inp->sctp_lport;
+
+ if (ro->ro_rt == NULL) {
+ /*
+ * src addr selection failed to find a route
+ * (or valid source addr), so we can't get
+ * there from here!
+ */
+ sctp_handle_no_route(stcb, net, so_locked);
+ SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EHOSTUNREACH);
+ sctp_m_freem(m);
+ return (EHOSTUNREACH);
}
- lsa6->sin6_addr = net->ro._s_addr->address.sin6.sin6_addr;
- } else {
- sin6 = (struct sockaddr_in6 *)&ro->ro_dst;
- /* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
- SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
- return (EINVAL);
+ /*
+ * XXX: sa6 may not have a valid sin6_scope_id in
+ * the non-SCOPEDROUTING case.
+ */
+ bzero(&lsa6_storage, sizeof(lsa6_storage));
+ lsa6_storage.sin6_family = AF_INET6;
+ lsa6_storage.sin6_len = sizeof(lsa6_storage);
+ lsa6_storage.sin6_addr = lsa6->sin6_addr;
+ if ((error = sa6_recoverscope(&lsa6_storage)) != 0) {
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "recover scope fails error %d\n", error);
+ sctp_m_freem(m);
+ return (error);
}
- if (over_addr == NULL) {
- struct sctp_ifa *_lsrc;
-
- _lsrc = sctp_source_address_selection(inp, stcb, ro,
- net,
- out_of_asoc_ok,
- vrf_id);
- if (_lsrc == NULL) {
- goto no_route;
- }
- lsa6->sin6_addr = _lsrc->address.sin6.sin6_addr;
- sctp_free_ifa(_lsrc);
+ /* XXX */
+ lsa6_storage.sin6_addr = lsa6->sin6_addr;
+ lsa6_storage.sin6_port = inp->sctp_lport;
+ lsa6 = &lsa6_storage;
+ ip6h->ip6_src = lsa6->sin6_addr;
+
+ if (port) {
+ udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
+ udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
+ udp->uh_dport = port;
+ udp->uh_ulen = htons(packet_length - sizeof(struct ip6_hdr));
+ udp->uh_sum = 0;
+ sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
} else {
- lsa6->sin6_addr = over_addr->sin6.sin6_addr;
- SCTP_RTALLOC(ro, vrf_id);
+ sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
}
- (void)sa6_recoverscope(sin6);
- }
- lsa6->sin6_port = inp->sctp_lport;
- if (ro->ro_rt == NULL) {
+ sctphdr->src_port = src_port;
+ sctphdr->dest_port = dest_port;
+ sctphdr->v_tag = v_tag;
+ sctphdr->checksum = 0;
+
/*
- * src addr selection failed to find a route (or
- * valid source addr), so we can't get there from
- * here!
+ * We set the hop limit now since there is a good
+ * chance that our ro pointer is now filled
*/
- goto no_route;
- }
- /*
- * XXX: sa6 may not have a valid sin6_scope_id in the
- * non-SCOPEDROUTING case.
- */
- bzero(&lsa6_storage, sizeof(lsa6_storage));
- lsa6_storage.sin6_family = AF_INET6;
- lsa6_storage.sin6_len = sizeof(lsa6_storage);
- lsa6_storage.sin6_addr = lsa6->sin6_addr;
- if ((error = sa6_recoverscope(&lsa6_storage)) != 0) {
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "recover scope fails error %d\n", error);
- sctp_m_freem(m);
- return (error);
- }
- /* XXX */
- lsa6_storage.sin6_addr = lsa6->sin6_addr;
- lsa6_storage.sin6_port = inp->sctp_lport;
- lsa6 = &lsa6_storage;
- ip6h->ip6_src = lsa6->sin6_addr;
-
- if (port) {
- udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
- udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
- udp->uh_dport = port;
- udp->uh_ulen = htons(packet_length - sizeof(struct ip6_hdr));
- udp->uh_sum = 0;
- sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
- } else {
- sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
- }
-
- sctphdr->src_port = src_port;
- sctphdr->dest_port = dest_port;
- sctphdr->v_tag = v_tag;
- sctphdr->checksum = 0;
-
- /*
- * We set the hop limit now since there is a good chance
- * that our ro pointer is now filled
- */
- ip6h->ip6_hlim = SCTP_GET_HLIM(inp, ro);
- ifp = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
+ ip6h->ip6_hlim = SCTP_GET_HLIM(inp, ro);
+ ifp = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
#ifdef SCTP_DEBUG
- /* Copy to be sure something bad is not happening */
- sin6->sin6_addr = ip6h->ip6_dst;
- lsa6->sin6_addr = ip6h->ip6_src;
+ /* Copy to be sure something bad is not happening */
+ sin6->sin6_addr = ip6h->ip6_dst;
+ lsa6->sin6_addr = ip6h->ip6_src;
#endif
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv6 output routine from low level\n");
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "src: ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)lsa6);
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "dst: ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)sin6);
- if (net) {
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- /* preserve the port and scope for link local send */
- prev_scope = sin6->sin6_scope_id;
- prev_port = sin6->sin6_port;
- }
- if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
- /* failed to prepend data, give up */
- sctp_m_freem(m);
- SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
- return (ENOMEM);
- }
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Calling ipv6 output routine from low level\n");
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "src: ");
+ SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)lsa6);
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "dst: ");
+ SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)sin6);
+ if (net) {
+ sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ /*
+ * preserve the port and scope for link
+ * local send
+ */
+ prev_scope = sin6->sin6_scope_id;
+ prev_port = sin6->sin6_port;
+ }
+ if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) {
+ /* failed to prepend data, give up */
+ sctp_m_freem(m);
+ SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
+ return (ENOMEM);
+ }
#ifdef SCTP_PACKET_LOGGING
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
- sctp_packet_log(m, packet_length);
+ if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
+ sctp_packet_log(m, packet_length);
#endif
- SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
- if (port) {
+ SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
+ if (port) {
#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
-#else
- if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (stcb) &&
- (stcb->asoc.loopback_scope))) {
- sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
- SCTP_STAT_INCR(sctps_sendswcrc);
- } else {
SCTP_STAT_INCR(sctps_sendnocrc);
- }
+#else
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
#endif
- if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) {
- udp->uh_sum = 0xffff;
- }
- } else {
+ if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) {
+ udp->uh_sum = 0xffff;
+ }
+ } else {
#if defined(SCTP_WITH_NO_CSUM)
- SCTP_STAT_INCR(sctps_sendnocrc);
+ SCTP_STAT_INCR(sctps_sendnocrc);
#else
- m->m_pkthdr.csum_flags = CSUM_SCTP;
- m->m_pkthdr.csum_data = 0;
- SCTP_STAT_INCR(sctps_sendhwcrc);
+ m->m_pkthdr.csum_flags = CSUM_SCTP;
+ m->m_pkthdr.csum_data = 0;
+ SCTP_STAT_INCR(sctps_sendhwcrc);
#endif
- }
- /* send it out. table id is taken from stcb */
+ }
+ /* send it out. table id is taken from stcb */
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
- if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
- so = SCTP_INP_SO(inp);
- SCTP_SOCKET_UNLOCK(so, 0);
- }
+ if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
+ so = SCTP_INP_SO(inp);
+ SCTP_SOCKET_UNLOCK(so, 0);
+ }
#endif
- SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, stcb, vrf_id);
+ SCTP_IP6_OUTPUT(ret, o_pak, (struct route_in6 *)ro, &ifp, stcb, vrf_id);
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
- if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
- atomic_add_int(&stcb->asoc.refcnt, 1);
- SCTP_TCB_UNLOCK(stcb);
- SCTP_SOCKET_LOCK(so, 0);
- SCTP_TCB_LOCK(stcb);
- atomic_subtract_int(&stcb->asoc.refcnt, 1);
- }
-#endif
- if (net) {
- /* for link local this must be done */
- sin6->sin6_scope_id = prev_scope;
- sin6->sin6_port = prev_port;
- }
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "return from send is %d\n", ret);
- SCTP_STAT_INCR(sctps_sendpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
- if (ret) {
- SCTP_STAT_INCR(sctps_senderrors);
- }
- if (net == NULL) {
- /* Now if we had a temp route free it */
- if (ro->ro_rt) {
- RTFREE(ro->ro_rt);
+ if ((SCTP_BASE_SYSCTL(sctp_output_unlocked)) && (so_locked)) {
+ atomic_add_int(&stcb->asoc.refcnt, 1);
+ SCTP_TCB_UNLOCK(stcb);
+ SCTP_SOCKET_LOCK(so, 0);
+ SCTP_TCB_LOCK(stcb);
+ atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
- } else {
- /* PMTU check versus smallest asoc MTU goes here */
- if (ro->ro_rt == NULL) {
- /* Route was freed */
- if (net->ro._s_addr &&
- net->src_addr_selected) {
- sctp_free_ifa(net->ro._s_addr);
- net->ro._s_addr = NULL;
+#endif
+ if (net) {
+ /* for link local this must be done */
+ sin6->sin6_scope_id = prev_scope;
+ sin6->sin6_port = prev_port;
+ }
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "return from send is %d\n", ret);
+ SCTP_STAT_INCR(sctps_sendpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
+ if (ret) {
+ SCTP_STAT_INCR(sctps_senderrors);
+ }
+ if (net == NULL) {
+ /* Now if we had a temp route free it */
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
}
- net->src_addr_selected = 0;
- }
- if ((ro->ro_rt != NULL) &&
- (net->ro._s_addr)) {
- uint32_t mtu;
-
- mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
- if (mtu &&
- (stcb->asoc.smallest_mtu > mtu)) {
- sctp_mtu_size_reset(inp, &stcb->asoc, mtu);
- net->mtu = mtu;
- if (net->port) {
- net->mtu -= sizeof(struct udphdr);
+ } else {
+ /*
+ * PMTU check versus smallest asoc MTU goes
+ * here
+ */
+ if (ro->ro_rt == NULL) {
+ /* Route was freed */
+ if (net->ro._s_addr &&
+ net->src_addr_selected) {
+ sctp_free_ifa(net->ro._s_addr);
+ net->ro._s_addr = NULL;
}
+ net->src_addr_selected = 0;
}
- } else if (ifp) {
- if (ND_IFINFO(ifp)->linkmtu &&
- (stcb->asoc.smallest_mtu > ND_IFINFO(ifp)->linkmtu)) {
- sctp_mtu_size_reset(inp,
- &stcb->asoc,
- ND_IFINFO(ifp)->linkmtu);
+ if ((ro->ro_rt != NULL) &&
+ (net->ro._s_addr)) {
+ uint32_t mtu;
+
+ mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt);
+ if (mtu &&
+ (stcb->asoc.smallest_mtu > mtu)) {
+ sctp_mtu_size_reset(inp, &stcb->asoc, mtu);
+ net->mtu = mtu;
+ if (net->port) {
+ net->mtu -= sizeof(struct udphdr);
+ }
+ }
+ } else if (ifp) {
+ if (ND_IFINFO(ifp)->linkmtu &&
+ (stcb->asoc.smallest_mtu > ND_IFINFO(ifp)->linkmtu)) {
+ sctp_mtu_size_reset(inp,
+ &stcb->asoc,
+ ND_IFINFO(ifp)->linkmtu);
+ }
}
}
+ return (ret);
}
- return (ret);
- }
#endif
- else {
+ default:
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Unknown protocol (TSNH) type %d\n",
((struct sockaddr *)to)->sa_family);
sctp_m_freem(m);
@@ -4213,15 +4257,23 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
/* now the address restriction */
+ /* XXX Should we take the address family of the socket into account? */
sup_addr = (struct sctp_supported_addr_param *)((caddr_t)init +
sizeof(*init));
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
#ifdef INET6
- /* we support 2 types: IPv6/IPv4 */
+#ifdef INET
+ /* we support 2 types: IPv4/IPv6 */
sup_addr->ph.param_length = htons(sizeof(*sup_addr) + sizeof(uint16_t));
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS);
#else
+ /* we support 1 type: IPv6 */
+ sup_addr->ph.param_length = htons(sizeof(*sup_addr) + sizeof(uint8_t));
+ sup_addr->addr_type[0] = htons(SCTP_IPV6_ADDRESS);
+ sup_addr->addr_type[1] = htons(0); /* this is the padding */
+#endif
+#else
/* we support 1 type: IPv4 */
sup_addr->ph.param_length = htons(sizeof(*sup_addr) + sizeof(uint8_t));
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
@@ -4750,34 +4802,31 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
* must return (1) to drop the packet if we see a un-understood
* parameter that tells us to drop the chunk.
*/
- struct sockaddr_in sin4, *sa4;
-
-#ifdef INET6
- struct sockaddr_in6 sin6, *sa6;
-
-#endif
struct sockaddr *sa_touse;
struct sockaddr *sa;
struct sctp_paramhdr *phdr, params;
+ uint16_t ptype, plen;
+ uint8_t fnd;
+ struct sctp_nets *net;
struct ip *iph;
+#ifdef INET
+ struct sockaddr_in sin4, *sa4;
+
+#endif
#ifdef INET6
+ struct sockaddr_in6 sin6, *sa6;
struct ip6_hdr *ip6h;
#endif
- struct mbuf *mat;
- uint16_t ptype, plen;
- int err_at;
- uint8_t fnd;
- struct sctp_nets *net;
+#ifdef INET
memset(&sin4, 0, sizeof(sin4));
-#ifdef INET6
- memset(&sin6, 0, sizeof(sin6));
-#endif
sin4.sin_family = AF_INET;
sin4.sin_len = sizeof(sin4);
+#endif
#ifdef INET6
+ memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
#endif
@@ -4785,11 +4834,13 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
/* First what about the src address of the pkt ? */
iph = mtod(in_initpkt, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
/* source addr is IPv4 */
sin4.sin_addr = iph->ip_src;
sa_touse = (struct sockaddr *)&sin4;
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
/* source addr is IPv6 */
@@ -4806,19 +4857,19 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
sa = (struct sockaddr *)&net->ro._l_addr;
if (sa->sa_family == sa_touse->sa_family) {
+#ifdef INET
if (sa->sa_family == AF_INET) {
sa4 = (struct sockaddr_in *)sa;
- if (sa4->sin_addr.s_addr ==
- sin4.sin_addr.s_addr) {
+ if (sa4->sin_addr.s_addr == sin4.sin_addr.s_addr) {
fnd = 1;
break;
}
}
+#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
sa6 = (struct sockaddr_in6 *)sa;
- if (SCTP6_ARE_ADDR_EQUAL(sa6,
- &sin6)) {
+ if (SCTP6_ARE_ADDR_EQUAL(sa6, &sin6)) {
fnd = 1;
break;
}
@@ -4831,41 +4882,48 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
return (1);
}
/* Ok so far lets munge through the rest of the packet */
- mat = in_initpkt;
- err_at = 0;
- sa_touse = NULL;
offset += sizeof(struct sctp_init_chunk);
- phdr = sctp_get_next_param(mat, offset, &params, sizeof(params));
+ phdr = sctp_get_next_param(in_initpkt, offset, &params, sizeof(params));
while (phdr) {
+ sa_touse = NULL;
ptype = ntohs(phdr->param_type);
plen = ntohs(phdr->param_length);
- if (ptype == SCTP_IPV4_ADDRESS) {
- struct sctp_ipv4addr_param *p4, p4_buf;
+ switch (ptype) {
+#ifdef INET
+ case SCTP_IPV4_ADDRESS:
+ {
+ struct sctp_ipv4addr_param *p4, p4_buf;
- phdr = sctp_get_next_param(mat, offset,
- (struct sctp_paramhdr *)&p4_buf, sizeof(p4_buf));
- if (plen != sizeof(struct sctp_ipv4addr_param) ||
- phdr == NULL) {
- return (1);
+ phdr = sctp_get_next_param(in_initpkt, offset,
+ (struct sctp_paramhdr *)&p4_buf, sizeof(p4_buf));
+ if (plen != sizeof(struct sctp_ipv4addr_param) ||
+ phdr == NULL) {
+ return (1);
+ }
+ p4 = (struct sctp_ipv4addr_param *)phdr;
+ sin4.sin_addr.s_addr = p4->addr;
+ sa_touse = (struct sockaddr *)&sin4;
}
- p4 = (struct sctp_ipv4addr_param *)phdr;
- sin4.sin_addr.s_addr = p4->addr;
- sa_touse = (struct sockaddr *)&sin4;
- } else if (ptype == SCTP_IPV6_ADDRESS) {
- struct sctp_ipv6addr_param *p6, p6_buf;
+#endif
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
+ {
+ struct sctp_ipv6addr_param *p6, p6_buf;
- phdr = sctp_get_next_param(mat, offset,
- (struct sctp_paramhdr *)&p6_buf, sizeof(p6_buf));
- if (plen != sizeof(struct sctp_ipv6addr_param) ||
- phdr == NULL) {
- return (1);
+ phdr = sctp_get_next_param(in_initpkt, offset,
+ (struct sctp_paramhdr *)&p6_buf, sizeof(p6_buf));
+ if (plen != sizeof(struct sctp_ipv6addr_param) ||
+ phdr == NULL) {
+ return (1);
+ }
+ p6 = (struct sctp_ipv6addr_param *)phdr;
+ memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
+ sizeof(p6->addr));
+ sa_touse = (struct sockaddr *)&sin6;
}
- p6 = (struct sctp_ipv6addr_param *)phdr;
-#ifdef INET6
- memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
- sizeof(p6->addr));
#endif
- sa_touse = (struct sockaddr *)&sin4;
+ default:
+ sa_touse = NULL;
}
if (sa_touse) {
/* ok, sa_touse points to one to check */
@@ -4875,6 +4933,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
if (sa->sa_family != sa_touse->sa_family) {
continue;
}
+#ifdef INET
if (sa->sa_family == AF_INET) {
sa4 = (struct sockaddr_in *)sa;
if (sa4->sin_addr.s_addr ==
@@ -4883,6 +4942,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
break;
}
}
+#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
sa6 = (struct sockaddr_in6 *)sa;
@@ -4900,7 +4960,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
}
}
offset += SCTP_SIZE32(plen);
- phdr = sctp_get_next_param(mat, offset, &params, sizeof(params));
+ phdr = sctp_get_next_param(in_initpkt, offset, &params, sizeof(params));
}
return (0);
}
@@ -4924,8 +4984,11 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_prsctp_supported_param *prsctp;
struct sctp_supported_chunk_types_param *pr_supported;
union sctp_sockstore store, store1, *over_addr;
+
+#ifdef INET
struct sockaddr_in *sin, *to_sin;
+#endif
#ifdef INET6
struct sockaddr_in6 *sin6, *to_sin6;
@@ -5037,8 +5100,10 @@ do_a_abort:
/* now for scope setup */
memset((caddr_t)&store, 0, sizeof(store));
memset((caddr_t)&store1, 0, sizeof(store1));
+#ifdef INET
sin = &store.sin;
to_sin = &store1.sin;
+#endif
#ifdef INET6
sin6 = &store.sin6;
to_sin6 = &store1.sin6;
@@ -5046,12 +5111,14 @@ do_a_abort:
iph = mtod(init_pkt, struct ip *);
/* establish the to_addr's */
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
to_sin->sin_port = sh->dest_port;
to_sin->sin_family = AF_INET;
to_sin->sin_len = sizeof(struct sockaddr_in);
to_sin->sin_addr = iph->ip_dst;
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
ip6 = mtod(init_pkt, struct ip6_hdr *);
@@ -5070,6 +5137,7 @@ do_a_abort:
if (net == NULL) {
to = (struct sockaddr *)&store;
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
sin->sin_family = AF_INET;
@@ -5106,6 +5174,7 @@ do_a_abort:
}
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
@@ -5211,6 +5280,7 @@ do_a_abort:
/* use the net pointer */
to = (struct sockaddr *)&net->ro._l_addr;
switch (to->sa_family) {
+#ifdef INET
case AF_INET:
sin = (struct sockaddr_in *)to;
stc.address[0] = sin->sin_addr.s_addr;
@@ -5238,6 +5308,7 @@ do_a_abort:
stc.laddress[3] = 0;
stc.laddr_type = SCTP_IPV4_ADDRESS;
break;
+#endif
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)to;
@@ -7455,9 +7526,11 @@ again_one_more_time:
}
}
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
+#ifdef INET
case AF_INET:
mtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
break;
+#endif
#ifdef INET6
case AF_INET6:
mtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
@@ -10320,21 +10393,27 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
/* formulate and SEND a SHUTDOWN-COMPLETE */
struct mbuf *o_pak;
struct mbuf *mout;
- struct ip *iph, *iph_out;
+ struct ip *iph;
struct udphdr *udp = NULL;
+ int offset_out, len, mlen;
+ struct sctp_shutdown_complete_msg *comp_cp;
+
+#ifdef INET
+ struct ip *iph_out;
+#endif
#ifdef INET6
struct ip6_hdr *ip6, *ip6_out;
#endif
- int offset_out, len, mlen;
- struct sctp_shutdown_complete_msg *comp_cp;
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
len = (sizeof(struct ip) + sizeof(struct sctp_shutdown_complete_msg));
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
len = (sizeof(struct ip6_hdr) + sizeof(struct sctp_shutdown_complete_msg));
@@ -10357,13 +10436,16 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
mout->m_pkthdr.flowid = m->m_pkthdr.flowid;
mout->m_flags |= M_FLOWID;
}
+#ifdef INET
iph_out = NULL;
+#endif
#ifdef INET6
ip6_out = NULL;
#endif
offset_out = 0;
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
iph_out = mtod(mout, struct ip *);
@@ -10388,6 +10470,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
comp_cp = (struct sctp_shutdown_complete_msg *)(
(caddr_t)iph_out + offset_out);
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
ip6 = (struct ip6_hdr *)iph;
@@ -10423,8 +10506,10 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
udp->uh_dport = port;
udp->uh_ulen = htons(sizeof(struct sctp_shutdown_complete_msg) + sizeof(struct udphdr));
+#ifdef INET
if (iph_out)
udp->uh_sum = in_pseudo(iph_out->ip_src.s_addr, iph_out->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
+#endif
offset_out += sizeof(struct udphdr);
comp_cp = (struct sctp_shutdown_complete_msg *)((caddr_t)comp_cp + sizeof(struct udphdr));
}
@@ -10442,6 +10527,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
comp_cp->shut_cmp.ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
comp_cp->shut_cmp.ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
+#ifdef INET
if (iph_out != NULL) {
sctp_route_t ro;
int ret;
@@ -10479,6 +10565,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
if (ro.ro_rt)
RTFREE(ro.ro_rt);
}
+#endif
#ifdef INET6
if (ip6_out != NULL) {
struct route_in6 ro;
@@ -10610,8 +10697,6 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
struct sctp_nets *net;
struct sctp_heartbeat_chunk *hb;
struct timeval now;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
SCTP_TCB_LOCK_ASSERT(stcb);
if (user_req == 0) {
@@ -10637,12 +10722,17 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
}
(void)SCTP_GETTIME_TIMEVAL(&now);
}
- sin = (struct sockaddr_in *)&net->ro._l_addr;
- if (sin->sin_family != AF_INET) {
- if (sin->sin_family != AF_INET6) {
- /* huh */
- return (0);
- }
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif
+ default:
+ return (0);
}
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
@@ -10680,8 +10770,8 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
hb->heartbeat.hb_info.time_value_2 = now.tv_usec;
/* Did our user request this one, put it in */
hb->heartbeat.hb_info.user_req = user_req;
- hb->heartbeat.hb_info.addr_family = sin->sin_family;
- hb->heartbeat.hb_info.addr_len = sin->sin_len;
+ hb->heartbeat.hb_info.addr_family = net->ro._l_addr.sa.sa_family;
+ hb->heartbeat.hb_info.addr_len = net->ro._l_addr.sa.sa_len;
if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
/*
* we only take from the entropy pool if the address is not
@@ -10693,15 +10783,24 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
net->heartbeat_random1 = hb->heartbeat.hb_info.random_value1 = 0;
net->heartbeat_random2 = hb->heartbeat.hb_info.random_value2 = 0;
}
- if (sin->sin_family == AF_INET) {
- memcpy(hb->heartbeat.hb_info.address, &sin->sin_addr, sizeof(sin->sin_addr));
- } else if (sin->sin_family == AF_INET6) {
- /* We leave the scope the way it is in our lookup table. */
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- memcpy(hb->heartbeat.hb_info.address, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
- } else {
- /* huh compiler bug */
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ memcpy(hb->heartbeat.hb_info.address,
+ &net->ro._l_addr.sin.sin_addr,
+ sizeof(net->ro._l_addr.sin.sin_addr));
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ memcpy(hb->heartbeat.hb_info.address,
+ &net->ro._l_addr.sin6.sin6_addr,
+ sizeof(net->ro._l_addr.sin6.sin6_addr));
+ break;
+#endif
+ default:
return (0);
+ break;
}
/*
@@ -10860,10 +10959,12 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
return;
}
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
/* IPv4 */
len = chk->send_size = iph->ip_len;
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
/* IPv6 */
@@ -11377,14 +11478,18 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
struct mbuf *o_pak;
struct mbuf *mout;
struct sctp_abort_msg *abm;
- struct ip *iph, *iph_out;
+ struct ip *iph;
struct udphdr *udp;
+ int iphlen_out, len;
+#ifdef INET
+ struct ip *iph_out;
+
+#endif
#ifdef INET6
struct ip6_hdr *ip6, *ip6_out;
#endif
- int iphlen_out, len;
/* don't respond to ABORT with ABORT */
if (sctp_is_there_an_abort_here(m, iphlen, &vtag)) {
@@ -11394,9 +11499,11 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
}
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
len = (sizeof(struct ip) + sizeof(struct sctp_abort_msg));
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
len = (sizeof(struct ip6_hdr) + sizeof(struct sctp_abort_msg));
@@ -11425,11 +11532,14 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
mout->m_pkthdr.flowid = m->m_pkthdr.flowid;
mout->m_flags |= M_FLOWID;
}
+#ifdef INET
iph_out = NULL;
+#endif
#ifdef INET6
ip6_out = NULL;
#endif
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
iph_out = mtod(mout, struct ip *);
@@ -11453,6 +11563,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
iphlen_out = sizeof(*iph_out);
abm = (struct sctp_abort_msg *)((caddr_t)iph_out + iphlen_out);
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
ip6 = (struct ip6_hdr *)iph;
@@ -11530,6 +11641,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
sctp_m_freem(mout);
return;
}
+#ifdef INET
if (iph_out != NULL) {
sctp_route_t ro;
int ret;
@@ -11573,6 +11685,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
if (ro.ro_rt)
RTFREE(ro.ro_rt);
}
+#endif
#ifdef INET6
if (ip6_out != NULL) {
struct route_in6 ro;
@@ -11630,22 +11743,28 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
struct mbuf *o_pak;
struct sctphdr *sh, *sh_out;
struct sctp_chunkhdr *ch;
- struct ip *iph, *iph_out;
+ struct ip *iph;
struct udphdr *udp = NULL;
struct mbuf *mout;
+ int iphlen_out, len;
+
+#ifdef INET
+ struct ip *iph_out;
+#endif
#ifdef INET6
struct ip6_hdr *ip6, *ip6_out;
#endif
- int iphlen_out, len;
iph = mtod(m, struct ip *);
sh = (struct sctphdr *)((caddr_t)iph + iphlen);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
len = (sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr));
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
len = (sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr));
@@ -11674,11 +11793,14 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
mout->m_pkthdr.flowid = m->m_pkthdr.flowid;
mout->m_flags |= M_FLOWID;
}
+#ifdef INET
iph_out = NULL;
+#endif
#ifdef INET6
ip6_out = NULL;
#endif
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
iph_out = mtod(mout, struct ip *);
@@ -11702,6 +11824,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
iphlen_out = sizeof(struct ip);
sh_out = (struct sctphdr *)((caddr_t)iph_out + iphlen_out);
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
ip6 = (struct ip6_hdr *)iph;
@@ -11776,6 +11899,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
sctp_m_freem(mout);
return;
}
+#ifdef INET
if (iph_out != NULL) {
sctp_route_t ro;
int ret;
@@ -11817,6 +11941,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
if (ro.ro_rt)
RTFREE(ro.ro_rt);
}
+#endif
#ifdef INET6
if (ip6_out != NULL) {
struct route_in6 ro;
@@ -13428,6 +13553,7 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
int
sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t * ro)
{
+#ifdef INET
struct sockaddr_in *sin, *mask;
struct ifaddr *ifa;
struct in_addr srcnetaddr, gwnetaddr;
@@ -13452,5 +13578,6 @@ sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t * ro)
if (srcnetaddr.s_addr == gwnetaddr.s_addr) {
return (1);
}
+#endif
return (0);
}
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 797816147195..b7c8dc6113ab 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -426,10 +426,20 @@ sctp_add_ifa_to_ifn(struct sctp_ifn *sctp_ifnp, struct sctp_ifa *sctp_ifap)
/* update address counts */
sctp_ifnp->ifa_count++;
ifa_af = sctp_ifap->address.sa.sa_family;
- if (ifa_af == AF_INET)
+ switch (ifa_af) {
+#ifdef INET
+ case AF_INET:
sctp_ifnp->num_v4++;
- else
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
sctp_ifnp->num_v6++;
+ break;
+#endif
+ default:
+ break;
+ }
if (sctp_ifnp->ifa_count == 1) {
/* register the new interface */
SCTP_REGISTER_INTERFACE(sctp_ifnp->ifn_index, ifa_af);
@@ -452,10 +462,20 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa *sctp_ifap)
if (sctp_ifap->ifn_p) {
/* update address counts */
sctp_ifap->ifn_p->ifa_count--;
- if (sctp_ifap->address.sa.sa_family == AF_INET6)
- sctp_ifap->ifn_p->num_v6--;
- else if (sctp_ifap->address.sa.sa_family == AF_INET)
+ switch (sctp_ifap->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
sctp_ifap->ifn_p->num_v4--;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ sctp_ifap->ifn_p->num_v6--;
+ break;
+#endif
+ default:
+ break;
+ }
ifn_index = sctp_ifap->ifn_p->ifn_index;
if (LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) {
@@ -613,6 +633,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifap->flags = ifa_flags;
/* Set scope */
switch (sctp_ifap->address.sa.sa_family) {
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin;
@@ -630,6 +651,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
new_ifn_af = AF_INET;
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -846,14 +868,29 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
if ((to == NULL) || (from == NULL)) {
return (NULL);
}
- if (to->sa_family == AF_INET && from->sa_family == AF_INET) {
- lport = ((struct sockaddr_in *)to)->sin_port;
- rport = ((struct sockaddr_in *)from)->sin_port;
- } else if (to->sa_family == AF_INET6 && from->sa_family == AF_INET6) {
- lport = ((struct sockaddr_in6 *)to)->sin6_port;
- rport = ((struct sockaddr_in6 *)from)->sin6_port;
- } else {
- return NULL;
+ switch (to->sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (from->sa_family == AF_INET) {
+ lport = ((struct sockaddr_in *)to)->sin_port;
+ rport = ((struct sockaddr_in *)from)->sin_port;
+ } else {
+ return (NULL);
+ }
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (from->sa_family == AF_INET6) {
+ lport = ((struct sockaddr_in6 *)to)->sin6_port;
+ rport = ((struct sockaddr_in6 *)from)->sin6_port;
+ } else {
+ return (NULL);
+ }
+ break;
+#endif
+ default:
+ return (NULL);
}
ephead = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR((lport | rport), SCTP_BASE_INFO(hashtcpmark))];
/*
@@ -894,17 +931,21 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
if (laddr->ifa->address.sa.sa_family ==
to->sa_family) {
/* see if it matches */
- struct sockaddr_in *intf_addr, *sin;
- intf_addr = &laddr->ifa->address.sin;
- sin = (struct sockaddr_in *)to;
+#ifdef INET
if (from->sa_family == AF_INET) {
+ struct sockaddr_in *intf_addr,
+ *sin;
+
+ intf_addr = &laddr->ifa->address.sin;
+ sin = (struct sockaddr_in *)to;
if (sin->sin_addr.s_addr ==
intf_addr->sin_addr.s_addr) {
match = 1;
break;
}
}
+#endif
#ifdef INET6
if (from->sa_family == AF_INET6) {
struct sockaddr_in6 *intf_addr6;
@@ -959,6 +1000,7 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
continue;
}
switch (from->sa_family) {
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin, *rsin;
@@ -981,6 +1023,7 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
}
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -1256,6 +1299,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
continue;
}
switch (remote->sa_family) {
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin,
@@ -1284,6 +1328,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
}
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -1357,6 +1402,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
continue;
}
switch (remote->sa_family) {
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin,
@@ -1385,6 +1431,7 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
}
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -1505,15 +1552,14 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
uint16_t lport, uint32_t vrf_id)
{
struct sctp_inpcb *inp;
- struct sockaddr_in *sin;
+ struct sctp_laddr *laddr;
-#ifdef INET6
- struct sockaddr_in6 *sin6;
+#ifdef INET
+ struct sockaddr_in *sin;
#endif
- struct sctp_laddr *laddr;
-
#ifdef INET6
+ struct sockaddr_in6 *sin6;
struct sockaddr_in6 *intf_addr6;
#endif
@@ -1523,14 +1569,18 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
/*
* Endpoint probe expects that the INP_INFO is locked.
*/
+#ifdef INET
sin = NULL;
+#endif
#ifdef INET6
sin6 = NULL;
#endif
switch (nam->sa_family) {
+#ifdef INET
case AF_INET:
sin = (struct sockaddr_in *)nam;
break;
+#endif
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)nam;
@@ -1553,6 +1603,7 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) &&
(inp->sctp_lport == lport)) {
/* got it */
+#ifdef INET
if ((nam->sa_family == AF_INET) &&
(inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
SCTP_IPV6_V6ONLY(inp)) {
@@ -1560,12 +1611,15 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
SCTP_INP_RUNLOCK(inp);
continue;
}
+#endif
+#ifdef INET6
/* A V6 address and the endpoint is NOT bound V6 */
if (nam->sa_family == AF_INET6 &&
(inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
SCTP_INP_RUNLOCK(inp);
continue;
}
+#endif
/* does a VRF id match? */
fnd = 0;
if (inp->def_vrf_id == vrf_id)
@@ -1578,18 +1632,26 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
}
SCTP_INP_RUNLOCK(inp);
}
- if ((nam->sa_family == AF_INET) &&
- (sin->sin_addr.s_addr == INADDR_ANY)) {
- /* Can't hunt for one that has no address specified */
- return (NULL);
- }
+ switch (nam->sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (sin->sin_addr.s_addr == INADDR_ANY) {
+ /* Can't hunt for one that has no address specified */
+ return (NULL);
+ }
+ break;
+#endif
#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);
- }
+ case AF_INET6:
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /* Can't hunt for one that has no address specified */
+ return (NULL);
+ }
+ break;
#endif
+ default:
+ break;
+ }
/*
* ok, not bound to all so see if we can find a EP bound to this
* address.
@@ -1635,17 +1697,16 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
}
if (laddr->ifa->address.sa.sa_family == nam->sa_family) {
/* possible, see if it matches */
- struct sockaddr_in *intf_addr;
-
- intf_addr = &laddr->ifa->address.sin;
switch (nam->sa_family) {
+#ifdef INET
case AF_INET:
if (sin->sin_addr.s_addr ==
- intf_addr->sin_addr.s_addr) {
+ laddr->ifa->address.sin.sin_addr.s_addr) {
SCTP_INP_RUNLOCK(inp);
return (inp);
}
break;
+#endif
#ifdef INET6
case AF_INET6:
intf_addr6 = &laddr->ifa->address.sin6;
@@ -1774,19 +1835,32 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock,
*/
struct sctp_inpcb *inp;
struct sctppcbhead *head;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
int lport;
unsigned int i;
- if (nam->sa_family == AF_INET) {
+#ifdef INET
+ struct sockaddr_in *sin;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+
+#endif
+
+ switch (nam->sa_family) {
+#ifdef INET
+ case AF_INET:
sin = (struct sockaddr_in *)nam;
lport = ((struct sockaddr_in *)nam)->sin_port;
- } else if (nam->sa_family == AF_INET6) {
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
sin6 = (struct sockaddr_in6 *)nam;
lport = ((struct sockaddr_in6 *)nam)->sin6_port;
- } else {
- /* unsupported family */
+ break;
+#endif
+ default:
return (NULL);
}
/*
@@ -1893,20 +1967,31 @@ sctp_findassociation_special_addr(struct mbuf *m, int iphlen, int offset,
struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp,
struct sockaddr *dest)
{
- struct sockaddr_in sin4;
- struct sockaddr_in6 sin6;
struct sctp_paramhdr *phdr, parm_buf;
struct sctp_tcb *retval;
uint32_t ptype, plen;
+#ifdef INET
+ struct sockaddr_in sin4;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 sin6;
+
+#endif
+
+#ifdef INET
memset(&sin4, 0, sizeof(sin4));
- memset(&sin6, 0, sizeof(sin6));
sin4.sin_len = sizeof(sin4);
sin4.sin_family = AF_INET;
sin4.sin_port = sh->src_port;
+#endif
+#ifdef INET6
+ memset(&sin6, 0, sizeof(sin6));
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
sin6.sin6_port = sh->src_port;
+#endif
retval = NULL;
offset += sizeof(struct sctp_init_chunk);
@@ -1919,6 +2004,7 @@ sctp_findassociation_special_addr(struct mbuf *m, int iphlen, int offset,
if (plen == 0) {
break;
}
+#ifdef INET
if (ptype == SCTP_IPV4_ADDRESS &&
plen == sizeof(struct sctp_ipv4addr_param)) {
/* Get the rest of the address */
@@ -1937,7 +2023,10 @@ sctp_findassociation_special_addr(struct mbuf *m, int iphlen, int offset,
if (retval != NULL) {
return (retval);
}
- } else if (ptype == SCTP_IPV6_ADDRESS &&
+ }
+#endif
+#ifdef INET6
+ if (ptype == SCTP_IPV6_ADDRESS &&
plen == sizeof(struct sctp_ipv6addr_param)) {
/* Get the rest of the address */
struct sctp_ipv6addr_param ip6_parm, *p6;
@@ -1956,6 +2045,7 @@ sctp_findassociation_special_addr(struct mbuf *m, int iphlen, int offset,
return (retval);
}
}
+#endif
offset += SCTP_SIZE32(plen);
phdr = sctp_get_next_param(m, offset, &parm_buf,
sizeof(parm_buf));
@@ -2082,6 +2172,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
/* its IPv4 */
@@ -2095,6 +2186,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
from4->sin_port = sh->src_port;
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
@@ -2123,6 +2215,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
/* its IPv4 */
@@ -2136,6 +2229,7 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
to4->sin_port = sh->dest_port;
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
@@ -2224,24 +2318,22 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
{
struct sctp_tcb *stcb;
- struct sockaddr_in *sin;
-
-#ifdef INET6
- struct sockaddr_in6 *sin6;
-
-#endif
struct sockaddr_storage local_store, remote_store;
struct sockaddr *to;
struct ip *iph;
+ struct sctp_paramhdr parm_buf, *phdr;
+ int ptype;
+ int zero_address = 0;
+#ifdef INET
+ struct sockaddr_in *sin;
+
+#endif
#ifdef INET6
struct ip6_hdr *ip6;
+ struct sockaddr_in6 *sin6;
#endif
- struct sctp_paramhdr parm_buf, *phdr;
- int ptype;
- int zero_address = 0;
-
memset(&local_store, 0, sizeof(local_store));
memset(&remote_store, 0, sizeof(remote_store));
@@ -2249,6 +2341,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
/* its IPv4 */
sin = (struct sockaddr_in *)&local_store;
@@ -2257,6 +2350,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
sin->sin_port = sh->dest_port;
sin->sin_addr.s_addr = iph->ip_dst.s_addr;
break;
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
/* its IPv6 */
@@ -2309,6 +2403,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
break;
}
#endif
+#ifdef INET
case SCTP_IPV4_ADDRESS:
{
/* ipv4 address param */
@@ -2334,6 +2429,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
zero_address = 1;
break;
}
+#endif
default:
/* invalid address param type */
return NULL;
@@ -2733,6 +2829,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
#endif
if (addr != NULL) {
switch (addr->sa_family) {
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin;
@@ -2762,6 +2859,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
}
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -3033,18 +3131,27 @@ continue_anyway:
struct sockaddr_storage store_sa;
memset(&store_sa, 0, sizeof(store_sa));
- if (addr->sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (addr->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&store_sa;
- memcpy(sin, addr, sizeof(struct sockaddr_in));
- sin->sin_port = 0;
- } else if (addr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
+ sin = (struct sockaddr_in *)&store_sa;
+ memcpy(sin, addr, sizeof(struct sockaddr_in));
+ sin->sin_port = 0;
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&store_sa;
- memcpy(sin6, addr, sizeof(struct sockaddr_in6));
- sin6->sin6_port = 0;
+ sin6 = (struct sockaddr_in6 *)&store_sa;
+ memcpy(sin6, addr, sizeof(struct sockaddr_in6));
+ sin6->sin6_port = 0;
+ break;
+ }
+ default:
+ break;
}
/*
* first find the interface with the bound address need to
@@ -3069,6 +3176,7 @@ continue_anyway:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EADDRNOTAVAIL);
return (EADDRNOTAVAIL);
}
+#ifdef INET6
if (addr->sa_family == AF_INET6) {
/* GAK, more FIXME IFA lock? */
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
@@ -3079,6 +3187,7 @@ continue_anyway:
return (EINVAL);
}
}
+#endif
/* we're not bound all */
inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL;
/* allow bindx() to send ASCONF's for binding changes */
@@ -3612,10 +3721,13 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
(void)sctp_m_free(ip_pcb->inp_options);
ip_pcb->inp_options = 0;
}
+#ifdef INET
if (ip_pcb->inp_moptions) {
inp_freemoptions(ip_pcb->inp_moptions);
ip_pcb->inp_moptions = 0;
}
+#endif
+
#ifdef INET6
if (ip_pcb->inp_vflag & INP_IPV6) {
struct in6pcb *in6p;
@@ -3740,84 +3852,96 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
return (0);
}
addr_inscope = 1;
- if (newaddr->sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (newaddr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)newaddr;
- if (sin->sin_addr.s_addr == 0) {
- /* Invalid address */
- return (-1);
- }
- /* zero out the bzero area */
- memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
+ sin = (struct sockaddr_in *)newaddr;
+ if (sin->sin_addr.s_addr == 0) {
+ /* Invalid address */
+ return (-1);
+ }
+ /* zero out the bzero area */
+ memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
- /* assure len is set */
- sin->sin_len = sizeof(struct sockaddr_in);
- if (set_scope) {
+ /* assure len is set */
+ sin->sin_len = sizeof(struct sockaddr_in);
+ if (set_scope) {
#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
- stcb->ipv4_local_scope = 1;
+ stcb->ipv4_local_scope = 1;
#else
- if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
- stcb->asoc.ipv4_local_scope = 1;
- }
+ if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
+ stcb->asoc.ipv4_local_scope = 1;
+ }
#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
- } else {
- /* Validate the address is in scope */
- if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
- (stcb->asoc.ipv4_local_scope == 0)) {
- addr_inscope = 0;
+ } else {
+ /* Validate the address is in scope */
+ if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
+ (stcb->asoc.ipv4_local_scope == 0)) {
+ addr_inscope = 0;
+ }
}
+ break;
}
+#endif
#ifdef INET6
- } else if (newaddr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)newaddr;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /* Invalid address */
- return (-1);
- }
- /* assure len is set */
- sin6->sin6_len = sizeof(struct sockaddr_in6);
- if (set_scope) {
- if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
- stcb->asoc.loopback_scope = 1;
- stcb->asoc.local_scope = 0;
- stcb->asoc.ipv4_local_scope = 1;
- stcb->asoc.site_scope = 1;
- } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- /*
- * If the new destination is a LINK_LOCAL we
- * must have common site scope. Don't set
- * the local scope since we may not share
- * all links, only loopback can do this.
- * Links on the local network would also be
- * on our private network for v4 too.
- */
- stcb->asoc.ipv4_local_scope = 1;
- stcb->asoc.site_scope = 1;
- } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
- /*
- * If the new destination is SITE_LOCAL then
- * we must have site scope in common.
- */
- stcb->asoc.site_scope = 1;
+ sin6 = (struct sockaddr_in6 *)newaddr;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /* Invalid address */
+ return (-1);
}
- } else {
- /* Validate the address is in scope */
- if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
- (stcb->asoc.loopback_scope == 0)) {
- addr_inscope = 0;
- } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
- (stcb->asoc.local_scope == 0)) {
- addr_inscope = 0;
- } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
- (stcb->asoc.site_scope == 0)) {
- addr_inscope = 0;
+ /* assure len is set */
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+ if (set_scope) {
+ if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) {
+ stcb->asoc.loopback_scope = 1;
+ stcb->asoc.local_scope = 0;
+ stcb->asoc.ipv4_local_scope = 1;
+ stcb->asoc.site_scope = 1;
+ } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ /*
+ * If the new destination is a
+ * LINK_LOCAL we must have common
+ * site scope. Don't set the local
+ * scope since we may not share all
+ * links, only loopback can do this.
+ * Links on the local network would
+ * also be on our private network
+ * for v4 too.
+ */
+ stcb->asoc.ipv4_local_scope = 1;
+ stcb->asoc.site_scope = 1;
+ } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
+ /*
+ * If the new destination is
+ * SITE_LOCAL then we must have site
+ * scope in common.
+ */
+ stcb->asoc.site_scope = 1;
+ }
+ } else {
+ /* Validate the address is in scope */
+ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
+ (stcb->asoc.loopback_scope == 0)) {
+ addr_inscope = 0;
+ } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
+ (stcb->asoc.local_scope == 0)) {
+ addr_inscope = 0;
+ } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
+ (stcb->asoc.site_scope == 0)) {
+ addr_inscope = 0;
+ }
}
+ break;
}
#endif
- } else {
+ default:
/* not supported family type */
return (-1);
}
@@ -3829,10 +3953,19 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
bzero(net, sizeof(*net));
(void)SCTP_GETTIME_TIMEVAL(&net->start_time);
memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len);
- if (newaddr->sa_family == AF_INET) {
+ switch (newaddr->sa_family) {
+#ifdef INET
+ case AF_INET:
((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport;
- } else if (newaddr->sa_family == AF_INET6) {
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport;
+ break;
+#endif
+ default:
+ break;
}
net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id);
if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) {
@@ -4136,38 +4269,63 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
#ifdef SCTP_DEBUG
if (firstaddr) {
SCTPDBG_ADDR(SCTP_DEBUG_PCB3, firstaddr);
- SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
- ntohs(((struct sockaddr_in *)firstaddr)->sin_port));
+ switch (firstaddr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
+ ntohs(((struct sockaddr_in *)firstaddr)->sin_port));
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ SCTPDBG(SCTP_DEBUG_PCB3, "Port:%d\n",
+ ntohs(((struct sockaddr_in6 *)firstaddr)->sin6_port));
+ break;
+#endif
+ default:
+ break;
+ }
} else {
SCTPDBG(SCTP_DEBUG_PCB3, "None\n");
}
#endif /* SCTP_DEBUG */
- if (firstaddr->sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (firstaddr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)firstaddr;
- if ((sin->sin_port == 0) || (sin->sin_addr.s_addr == 0)) {
- /* Invalid address */
- SCTP_INP_RUNLOCK(inp);
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- *error = EINVAL;
- return (NULL);
+ sin = (struct sockaddr_in *)firstaddr;
+ if ((sin->sin_port == 0) || (sin->sin_addr.s_addr == 0)) {
+ /* Invalid address */
+ SCTP_INP_RUNLOCK(inp);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ *error = EINVAL;
+ return (NULL);
+ }
+ rport = sin->sin_port;
+ break;
}
- rport = sin->sin_port;
- } else if (firstaddr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)firstaddr;
- if ((sin6->sin6_port == 0) ||
- (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
- /* Invalid address */
- SCTP_INP_RUNLOCK(inp);
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- *error = EINVAL;
- return (NULL);
+ sin6 = (struct sockaddr_in6 *)firstaddr;
+ if ((sin6->sin6_port == 0) ||
+ (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
+ /* Invalid address */
+ SCTP_INP_RUNLOCK(inp);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ *error = EINVAL;
+ return (NULL);
+ }
+ rport = sin6->sin6_port;
+ break;
}
- rport = sin6->sin6_port;
- } else {
+#endif
+ default:
/* not supported family type */
SCTP_INP_RUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
@@ -5135,13 +5293,17 @@ sctp_destination_is_reachable(struct sctp_tcb *stcb, struct sockaddr *destaddr)
return (1);
}
/* NOTE: all "scope" checks are done when local addresses are added */
- if (destaddr->sa_family == AF_INET6) {
+ switch (destaddr->sa_family) {
+ case AF_INET6:
answer = inp->ip_inp.inp.inp_vflag & INP_IPV6;
- } else if (destaddr->sa_family == AF_INET) {
+ break;
+ case AF_INET:
answer = inp->ip_inp.inp.inp_vflag & INP_IPV4;
- } else {
+ break;
+ default:
/* invalid family, so it's unreachable */
answer = 0;
+ break;
}
return (answer);
}
@@ -5166,10 +5328,19 @@ sctp_update_ep_vflag(struct sctp_inpcb *inp)
if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) {
continue;
}
- if (laddr->ifa->address.sa.sa_family == AF_INET6) {
+ switch (laddr->ifa->address.sa.sa_family) {
+#ifdef INET6
+ case AF_INET6:
inp->ip_inp.inp.inp_vflag |= INP_IPV6;
- } else if (laddr->ifa->address.sa.sa_family == AF_INET) {
+ break;
+#endif
+#ifdef INET
+ case AF_INET:
inp->ip_inp.inp.inp_vflag |= INP_IPV4;
+ break;
+#endif
+ default:
+ break;
}
}
}
@@ -5190,12 +5361,14 @@ sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t ac
/* You are already bound to all. You have it already */
return;
}
+#ifdef INET6
if (ifa->address.sa.sa_family == AF_INET6) {
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
/* Can't bind a non-useable addr. */
return;
}
}
+#endif
/* first, is it already present? */
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
if (laddr->ifa == ifa) {
@@ -5211,10 +5384,19 @@ sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t ac
return;
inp->laddr_count++;
/* update inp_vflag flags */
- if (ifa->address.sa.sa_family == AF_INET6) {
+ switch (ifa->address.sa.sa_family) {
+#ifdef INET6
+ case AF_INET6:
inp->ip_inp.inp.inp_vflag |= INP_IPV6;
- } else if (ifa->address.sa.sa_family == AF_INET) {
+ break;
+#endif
+#ifdef INET6
+ case AF_INET:
inp->ip_inp.inp.inp_vflag |= INP_IPV4;
+ break;
+#endif
+ default:
+ break;
}
}
return;
@@ -5343,12 +5525,14 @@ sctp_add_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
list = &stcb->asoc.sctp_restricted_addrs;
inp = stcb->sctp_ep;
+#ifdef INET6
if (ifa->address.sa.sa_family == AF_INET6) {
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
/* Can't bind a non-existent addr. */
return;
}
}
+#endif
/* does the address already exist? */
LIST_FOREACH(laddr, list, sctp_nxt_addr) {
if (laddr->ifa == ifa) {
@@ -5906,8 +6090,6 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
struct sockaddr *sa;
struct sockaddr_storage dest_store;
struct sockaddr *local_sa = (struct sockaddr *)&dest_store;
- struct sockaddr_in sin;
- struct sockaddr_in6 sin6;
uint8_t random_store[SCTP_PARAM_BUFFER_SIZE];
struct sctp_auth_random *p_random = NULL;
uint16_t random_len = 0;
@@ -5924,20 +6106,32 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
int got_random = 0, got_hmacs = 0, got_chklist = 0;
uint8_t ecn_allowed;
+#ifdef INET
+ struct sockaddr_in sin;
+
+#endif
+#ifdef INET6
+ struct sockaddr_in6 sin6;
+
+#endif
+
/* First get the destination address setup too. */
+#ifdef INET
memset(&sin, 0, sizeof(sin));
- memset(&sin6, 0, sizeof(sin6));
-
sin.sin_family = AF_INET;
sin.sin_len = sizeof(sin);
sin.sin_port = stcb->rport;
-
+#endif
+#ifdef INET6
+ memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_port = stcb->rport;
+#endif
if (altsa == NULL) {
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
/* its IPv4 */
@@ -5953,6 +6147,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sa = (struct sockaddr *)&sin;
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
@@ -5998,16 +6193,27 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) {
/* we must add the source address */
/* no scope set here since we have a tcb already. */
- if ((sa->sa_family == AF_INET) &&
- (stcb->asoc.ipv4_addr_legal)) {
- if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
- return (-1);
+ switch (sa->sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (stcb->asoc.ipv4_addr_legal) {
+ if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
+ return (-1);
+ }
}
- } else if ((sa->sa_family == AF_INET6) &&
- (stcb->asoc.ipv6_addr_legal)) {
- if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
- return (-2);
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ if (stcb->asoc.ipv6_addr_legal) {
+ if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
+ return (-2);
+ }
}
+ break;
+#endif
+ default:
+ break;
}
} else {
if (net_tmp != NULL && stcb_tmp == stcb) {
@@ -6044,6 +6250,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
if (plen == 0) {
break;
}
+#ifdef INET
if (ptype == SCTP_IPV4_ADDRESS) {
if (stcb->asoc.ipv4_addr_legal) {
struct sctp_ipv4addr_param *p4, p4_buf;
@@ -6127,7 +6334,10 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
return (-13);
}
}
- } else if (ptype == SCTP_IPV6_ADDRESS) {
+ } else
+#endif
+#ifdef INET6
+ if (ptype == SCTP_IPV6_ADDRESS) {
if (stcb->asoc.ipv6_addr_legal) {
/* ok get the v6 address and check/add */
struct sctp_ipv6addr_param *p6, p6_buf;
@@ -6215,7 +6425,9 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
return (-22);
}
}
- } else if (ptype == SCTP_ECN_CAPABLE) {
+ } else
+#endif
+ if (ptype == SCTP_ECN_CAPABLE) {
ecn_allowed = 1;
} else if (ptype == SCTP_ULP_ADAPTATION) {
if (stcb->asoc.state != SCTP_STATE_OPEN) {
@@ -6232,10 +6444,14 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
}
} else if (ptype == SCTP_SET_PRIM_ADDR) {
struct sctp_asconf_addr_param lstore, *fee;
- struct sctp_asconf_addrv4_param *fii;
int lptype;
struct sockaddr *lsa = NULL;
+#ifdef INET
+ struct sctp_asconf_addrv4_param *fii;
+
+#endif
+
stcb->asoc.peer_supports_asconf = 1;
if (plen > sizeof(lstore)) {
return (-23);
@@ -6248,7 +6464,9 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
}
fee = (struct sctp_asconf_addr_param *)phdr;
lptype = ntohs(fee->addrp.ph.param_type);
- if (lptype == SCTP_IPV4_ADDRESS) {
+ switch (lptype) {
+#ifdef INET
+ case SCTP_IPV4_ADDRESS:
if (plen !=
sizeof(struct sctp_asconf_addrv4_param)) {
SCTP_PRINTF("Sizeof setprim in init/init ack not %d but %d - ignored\n",
@@ -6259,7 +6477,10 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sin.sin_addr.s_addr = fii->addrp.addr;
lsa = (struct sockaddr *)&sin;
}
- } else if (lptype == SCTP_IPV6_ADDRESS) {
+ break;
+#endif
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
if (plen !=
sizeof(struct sctp_asconf_addr_param)) {
SCTP_PRINTF("Sizeof setprim (v6) in init/init ack not %d but %d - ignored\n",
@@ -6271,6 +6492,10 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sizeof(fee->addrp.addr));
lsa = (struct sockaddr *)&sin6;
}
+ break;
+#endif
+ default:
+ break;
}
if (lsa) {
(void)sctp_set_primary_addr(stcb, sa, NULL);
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index a8d080aaaafd..bb7b6e265d22 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -155,17 +155,33 @@ number_of_addresses(struct sctp_inpcb *inp)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
- if ((sctp_ifa->address.sa.sa_family == AF_INET) ||
- (sctp_ifa->address.sa.sa_family == AF_INET6)) {
+ switch (sctp_ifa->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+#endif
+#ifdef INET6
+ case AF_INET6:
+#endif
cnt++;
+ break;
+ default:
+ break;
}
}
}
} else {
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
- if ((laddr->ifa->address.sa.sa_family == AF_INET) ||
- (laddr->ifa->address.sa.sa_family == AF_INET6)) {
+ switch (laddr->ifa->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+#endif
+#ifdef INET6
+ case AF_INET6:
+#endif
cnt++;
+ break;
+ default:
+ break;
}
}
}
@@ -233,6 +249,7 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
continue;
}
switch (sctp_ifa->address.sa.sa_family) {
+#ifdef INET
case AF_INET:
if (ipv4_addr_legal) {
struct sockaddr_in *sin;
@@ -246,6 +263,7 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
continue;
}
break;
+#endif
#ifdef INET6
case AF_INET6:
if (ipv6_addr_legal) {
@@ -535,6 +553,8 @@ skip:
if ((var) < (min)) { (var) = (min); } \
else if ((var) > (max)) { (var) = (max); }
+/* XXX: Remove the #if after tunneling over IPv6 works also on FreeBSD. */
+#if !defined(__FreeBSD__) || defined(INET)
static int
sysctl_sctp_udp_tunneling_check(SYSCTL_HANDLER_ARGS)
{
@@ -566,6 +586,8 @@ out:
return (error);
}
+#endif
+
static int
sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
@@ -646,7 +668,10 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), SCTPCTL_RTTVAR_DCCCECN_MIN, SCTPCTL_RTTVAR_DCCCECN_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
+/* XXX: Remove the #if after tunneling over IPv6 works also on FreeBSD. */
+#if !defined(__FreeBSD__) || defined(INET)
RANGECHK(SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable), SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MIN, SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_MAX);
+#endif
RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
@@ -1083,6 +1108,8 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, clear_trace, CTLTYPE_UINT | CTLFLAG_R
"Clear SCTP Logging buffer");
#endif
+/* XXX: Remove the #if after tunneling over IPv6 works also on FreeBSD. */
+#if !defined(__FreeBSD__) || defined(INET)
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_for_client_enable, CTLTYPE_UINT | CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_udp_tunneling_for_client_enable), 0, sysctl_sctp_check, "IU",
SCTPCTL_UDP_TUNNELING_FOR_CLIENT_ENABLE_DESC);
@@ -1090,6 +1117,7 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_for_client_enable, CTLT
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_port, CTLTYPE_UINT | CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), 0, sysctl_sctp_udp_tunneling_check, "IU",
SCTPCTL_UDP_TUNNELING_PORT_DESC);
+#endif
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, enable_sack_immediately, CTLTYPE_UINT | CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), 0, sysctl_sctp_check, "IU",
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index b4e9fd5e3278..cecfde741e73 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -150,6 +150,7 @@ sctp_pathmtu_adjustment(struct sctp_inpcb *inp,
}
}
+#ifdef INET
static void
sctp_notify_mbuf(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
@@ -220,6 +221,7 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
SCTP_TCB_UNLOCK(stcb);
}
+#endif
void
sctp_notify(struct sctp_inpcb *inp,
@@ -335,6 +337,7 @@ sctp_notify(struct sctp_inpcb *inp,
}
}
+#ifdef INET
void
sctp_ctlinput(cmd, sa, vip)
int cmd;
@@ -404,6 +407,8 @@ sctp_ctlinput(cmd, sa, vip)
return;
}
+#endif
+
static int
sctp_getcred(SYSCTL_HANDLER_ARGS)
{
@@ -466,6 +471,7 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW,
0, 0, sctp_getcred, "S,ucred", "Get the ucred of a SCTP connection");
+#ifdef INET
static void
sctp_abort(struct socket *so)
{
@@ -599,6 +605,7 @@ sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
return error;
}
+#endif
void
sctp_close(struct socket *so)
{
@@ -1209,6 +1216,7 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
}
}
switch (sctp_ifa->address.sa.sa_family) {
+#ifdef INET
case AF_INET:
if (ipv4_addr_legal) {
struct sockaddr_in *sin;
@@ -1248,6 +1256,7 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
continue;
}
break;
+#endif
#ifdef INET6
case AF_INET6:
if (ipv6_addr_legal) {
@@ -1373,28 +1382,46 @@ sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
/* Count them if they are the right type */
- if (sctp_ifa->address.sa.sa_family == AF_INET) {
+ switch (sctp_ifa->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
cnt += sizeof(struct sockaddr_in6);
else
cnt += sizeof(struct sockaddr_in);
-
- } else if (sctp_ifa->address.sa.sa_family == AF_INET6)
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
cnt += sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ break;
+ }
}
}
} else {
struct sctp_laddr *laddr;
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
- if (laddr->ifa->address.sa.sa_family == AF_INET) {
+ switch (laddr->ifa->address.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
cnt += sizeof(struct sockaddr_in6);
else
cnt += sizeof(struct sockaddr_in);
-
- } else if (laddr->ifa->address.sa.sa_family == AF_INET6)
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
cnt += sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ break;
+ }
}
}
return (cnt);
@@ -1517,10 +1544,20 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
}
SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_COOKIE_WAIT);
/* move to second address */
- if (sa->sa_family == AF_INET)
+ switch (sa->sa_family) {
+#ifdef INET
+ case AF_INET:
sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
- else
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
+ break;
+#endif
+ default:
+ break;
+ }
error = 0;
added = sctp_connectx_helper_add(stcb, sa, (totaddr - 1), &error);
@@ -2126,14 +2163,23 @@ flags_out:
size = 0;
/* Count the sizes */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) ||
- (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
+ if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
size += sizeof(struct sockaddr_in6);
- } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
- size += sizeof(struct sockaddr_in);
} else {
- /* huh */
- break;
+ switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
+#ifdef INET
+ case AF_INET:
+ size += sizeof(struct sockaddr_in);
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ size += sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ break;
+ }
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -2165,20 +2211,33 @@ flags_out:
sas = (struct sockaddr_storage *)&saddr->addr[0];
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) ||
- (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
+ if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
cpsz = sizeof(struct sockaddr_in6);
- } else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
- cpsz = sizeof(struct sockaddr_in);
} else {
- /* huh */
+ switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
+#ifdef INET
+ case AF_INET:
+ cpsz = sizeof(struct sockaddr_in);
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ cpsz = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ cpsz = 0;
+ break;
+ }
+ }
+ if (cpsz == 0) {
break;
}
if (left < cpsz) {
/* not enough room. */
break;
}
-#ifdef INET6
+#if defined(INET) && defined(INET6)
if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
(((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET)) {
/* Must map the address */
@@ -2187,7 +2246,7 @@ flags_out:
} else {
#endif
memcpy(sas, &net->ro._l_addr, cpsz);
-#ifdef INET6
+#if defined(INET) && defined(INET6)
}
#endif
((struct sockaddr_in *)sas)->sin_port = stcb->rport;
@@ -2250,6 +2309,7 @@ flags_out:
struct sockaddr *sa;
sa = (struct sockaddr *)&paddrp->spp_address;
+#ifdef INET
if (sa->sa_family == AF_INET) {
struct sockaddr_in *sin;
@@ -2260,7 +2320,10 @@ flags_out:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
break;
}
- } else if (sa->sa_family == AF_INET6) {
+ } else
+#endif
+#ifdef INET6
+ if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
@@ -2270,7 +2333,9 @@ flags_out:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
break;
}
- } else {
+ } else
+#endif
+ {
error = EAFNOSUPPORT;
SCTP_TCB_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
@@ -3857,7 +3922,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
struct sockaddr *sa;
sa = (struct sockaddr *)&paddrp->spp_address;
+#ifdef INET
if (sa->sa_family == AF_INET) {
+
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)sa;
@@ -3867,7 +3934,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
error = EINVAL;
break;
}
- } else if (sa->sa_family == AF_INET6) {
+ } else
+#endif
+#ifdef INET6
+ if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)sa;
@@ -3877,7 +3947,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
error = EINVAL;
break;
}
- } else {
+ } else
+#endif
+ {
error = EAFNOSUPPORT;
SCTP_TCB_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
@@ -4305,6 +4377,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
td = (struct thread *)p;
SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses,
optsize);
+#ifdef INET
if (addrs->addr->sa_family == AF_INET) {
sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in);
if (optsize < sz) {
@@ -4316,8 +4389,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
break;
}
+ } else
+#endif
#ifdef INET6
- } else if (addrs->addr->sa_family == AF_INET6) {
+ if (addrs->addr->sa_family == AF_INET6) {
sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6);
if (optsize < sz) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -4329,8 +4404,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
break;
}
+ } else
#endif
- } else {
+ {
error = EAFNOSUPPORT;
break;
}
@@ -4348,6 +4424,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
td = (struct thread *)p;
SCTP_CHECK_AND_CAST(addrs, optval, struct sctp_getaddresses, optsize);
+#ifdef INET
if (addrs->addr->sa_family == AF_INET) {
sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in);
if (optsize < sz) {
@@ -4359,8 +4436,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
break;
}
+ } else
+#endif
#ifdef INET6
- } else if (addrs->addr->sa_family == AF_INET6) {
+ if (addrs->addr->sa_family == AF_INET6) {
sz = sizeof(struct sctp_getaddresses) - sizeof(struct sockaddr) + sizeof(struct sockaddr_in6);
if (optsize < sz) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -4372,8 +4451,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
break;
}
+ } else
#endif
- } else {
+ {
error = EAFNOSUPPORT;
break;
}
@@ -4410,9 +4490,13 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
#ifdef INET6
if (INP_CHECK_SOCKAF(so, AF_INET6))
error = ip6_ctloutput(so, sopt);
- else
#endif /* INET6 */
+#if defined(INET) && defined (INET6)
+ else
+#endif
+#ifdef INET
error = ip_ctloutput(so, sopt);
+#endif
return (error);
}
optsize = sopt->sopt_valsize;
@@ -4447,7 +4531,7 @@ out:
return (error);
}
-
+#ifdef INET
static int
sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
{
@@ -4467,34 +4551,42 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return EINVAL;
}
+ switch (addr->sa_family) {
#ifdef INET6
- if (addr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6p;
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6p;
- if (addr->sa_len != sizeof(struct sockaddr_in6)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
- return (EINVAL);
- }
- sin6p = (struct sockaddr_in6 *)addr;
- if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6p->sin6_addr)) != 0) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
- return (error);
+ if (addr->sa_len != sizeof(struct sockaddr_in6)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ return (EINVAL);
+ }
+ sin6p = (struct sockaddr_in6 *)addr;
+ if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6p->sin6_addr)) != 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
+ return (error);
+ }
+ break;
}
- } else
#endif
- if (addr->sa_family == AF_INET) {
- struct sockaddr_in *sinp;
+#ifdef INET
+ case AF_INET:
+ {
+ struct sockaddr_in *sinp;
- if (addr->sa_len != sizeof(struct sockaddr_in)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
- return (EINVAL);
- }
- sinp = (struct sockaddr_in *)addr;
- if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sinp->sin_addr)) != 0) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
- return (error);
+ if (addr->sa_len != sizeof(struct sockaddr_in)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ return (EINVAL);
+ }
+ sinp = (struct sockaddr_in *)addr;
+ if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sinp->sin_addr)) != 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
+ return (error);
+ }
+ break;
}
- } else {
+#endif
+ default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
return (EAFNOSUPPORT);
}
@@ -4601,6 +4693,8 @@ out_now:
return error;
}
+#endif
+
int
sctp_listen(struct socket *so, int backlog, struct thread *p)
{
@@ -4634,7 +4728,20 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
memcpy(&store, &laddr->ifa->address, sizeof(store));
- sp->sin.sin_port = inp->sctp_lport;
+ switch (sp->sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ sp->sin.sin_port = inp->sctp_lport;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ sp->sin6.sin6_port = inp->sctp_lport;
+ break;
+#endif
+ default:
+ break;
+ }
tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
@@ -4653,17 +4760,32 @@ sctp_listen(struct socket *so, int backlog, struct thread *p)
} else {
/* Setup a local addr bound all */
memset(&store, 0, sizeof(store));
- store.sin.sin_port = inp->sctp_lport;
+ switch (sp->sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ store.sin.sin_port = inp->sctp_lport;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ sp->sin6.sin6_port = inp->sctp_lport;
+ break;
+#endif
+ default:
+ break;
+ }
#ifdef INET6
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
store.sa.sa_family = AF_INET6;
store.sa.sa_len = sizeof(struct sockaddr_in6);
}
#endif
+#ifdef INET
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
store.sa.sa_family = AF_INET;
store.sa.sa_len = sizeof(struct sockaddr_in);
}
+#endif
tinp = sctp_pcb_findep(&sp->sa, 0, 0, inp->def_vrf_id);
if (tinp && (tinp != inp) &&
((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
@@ -4780,6 +4902,7 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE;
SCTP_TCB_UNLOCK(stcb);
switch (store.sa.sa_family) {
+#ifdef INET
case AF_INET:
{
struct sockaddr_in *sin;
@@ -4794,6 +4917,7 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
*addr = (struct sockaddr *)sin;
break;
}
+#endif
#ifdef INET6
case AF_INET6:
{
@@ -4855,6 +4979,7 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
return (0);
}
+#ifdef INET
int
sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
{
@@ -5015,6 +5140,7 @@ sctp_peeraddr(struct socket *so, struct sockaddr **addr)
return (0);
}
+#ifdef INET
struct pr_usrreqs sctp_usrreqs = {
.pru_abort = sctp_abort,
.pru_accept = sctp_accept,
@@ -5035,3 +5161,6 @@ struct pr_usrreqs sctp_usrreqs = {
.pru_sosend = sctp_sosend,
.pru_soreceive = sctp_soreceive
};
+
+#endif
+#endif
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index 3ab04c0348ab..c972a166e07a 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -300,8 +300,15 @@ int sctp_disconnect(struct socket *so);
void sctp_ctlinput __P((int, struct sockaddr *, void *));
int sctp_ctloutput __P((struct socket *, struct sockopt *));
+
+#ifdef INET
void sctp_input_with_port __P((struct mbuf *, int, uint16_t));
+
+#endif
+#ifdef INET
void sctp_input __P((struct mbuf *, int));
+
+#endif
void sctp_pathmtu_adjustment __P((struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *, uint16_t));
void sctp_drain __P((void));
void sctp_init __P((void));
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index ffd131ffc6c5..22e5c5b836bb 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -4826,6 +4826,7 @@ sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
continue;
if (addr->sa_family != laddr->ifa->address.sa.sa_family)
continue;
+#ifdef INET
if (addr->sa_family == AF_INET) {
if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
laddr->ifa->address.sin.sin_addr.s_addr) {
@@ -4837,6 +4838,7 @@ sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
break;
}
}
+#endif
#ifdef INET6
if (addr->sa_family == AF_INET6) {
if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr,
@@ -4924,6 +4926,7 @@ stage_right:
}
if (addr->sa_family != sctp_ifap->address.sa.sa_family)
continue;
+#ifdef INET
if (addr->sa_family == AF_INET) {
if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
sctp_ifap->address.sin.sin_addr.s_addr) {
@@ -4934,6 +4937,7 @@ stage_right:
break;
}
}
+#endif
#ifdef INET6
if (addr->sa_family == AF_INET6) {
if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr,
@@ -6729,7 +6733,7 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored)
struct ip *iph;
struct mbuf *sp, *last;
struct udphdr *uhdr;
- uint16_t port = 0, len;
+ uint16_t port = 0;
int header_size = sizeof(struct udphdr) + sizeof(struct sctphdr);
/*
@@ -6779,8 +6783,11 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored)
/* Now its ready for sctp_input or sctp6_input */
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
+#ifdef INET
case IPVERSION:
{
+ uint16_t len;
+
/* its IPv4 */
len = SCTP_GET_IPV4_LENGTH(iph);
len -= sizeof(struct udphdr);
@@ -6788,6 +6795,7 @@ sctp_recv_udp_tunneled_packet(struct mbuf *m, int off, struct inpcb *ignored)
sctp_input_with_port(m, off, port);
break;
}
+#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{