summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2008-04-16 17:24:18 +0000
committerrrs <rrs@FreeBSD.org>2008-04-16 17:24:18 +0000
commit04ee4c21641124d83460020c6fe707fc41ffd21e (patch)
treeabbb57af9a9871bceb4e1d9c90dbd91f1ed64dfd
parent267b42a43bcc8d85b017b2fb402c25af07ba0212 (diff)
downloadFreeBSD-src-04ee4c21641124d83460020c6fe707fc41ffd21e.zip
FreeBSD-src-04ee4c21641124d83460020c6fe707fc41ffd21e.tar.gz
Allow SCTP to compile without INET6.
PR: 116816 Obtained from tuexen@fh-muenster.de: MFC after: 2 weeks
-rw-r--r--sys/conf/files28
-rw-r--r--sys/netinet/sctp_asconf.c240
-rw-r--r--sys/netinet/sctp_bsd_addr.c3
-rw-r--r--sys/netinet/sctp_bsd_addr.h3
-rw-r--r--sys/netinet/sctp_input.c67
-rw-r--r--sys/netinet/sctp_output.c771
-rw-r--r--sys/netinet/sctp_pcb.c795
-rw-r--r--sys/netinet/sctp_pcb.h3
-rw-r--r--sys/netinet/sctp_sysctl.c61
-rw-r--r--sys/netinet/sctp_usrreq.c215
-rw-r--r--sys/netinet/sctp_var.h2
-rw-r--r--sys/netinet/sctputil.c324
-rw-r--r--sys/netinet/sctputil.h4
13 files changed, 1544 insertions, 972 deletions
diff --git a/sys/conf/files b/sys/conf/files
index e386327..c1ca81e 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1901,20 +1901,20 @@ netinet/ip_mroute.c optional mrouting inet | mrouting inet6
netinet/ip_options.c optional inet
netinet/ip_output.c optional inet
netinet/raw_ip.c optional inet
-netinet/sctp_asconf.c optional inet inet6 sctp
-netinet/sctp_auth.c optional inet inet6 sctp
-netinet/sctp_bsd_addr.c optional inet inet6 sctp
-netinet/sctp_cc_functions.c optional inet inet6 sctp
-netinet/sctp_crc32.c optional inet inet6 sctp
-netinet/sctp_indata.c optional inet inet6 sctp
-netinet/sctp_input.c optional inet inet6 sctp
-netinet/sctp_output.c optional inet inet6 sctp
-netinet/sctp_pcb.c optional inet inet6 sctp
-netinet/sctp_peeloff.c optional inet inet6 sctp
-netinet/sctp_sysctl.c optional inet inet6 sctp
-netinet/sctp_timer.c optional inet inet6 sctp
-netinet/sctp_usrreq.c optional inet inet6 sctp
-netinet/sctputil.c optional inet inet6 sctp
+netinet/sctp_asconf.c optional inet sctp
+netinet/sctp_auth.c optional inet sctp
+netinet/sctp_bsd_addr.c optional inet sctp
+netinet/sctp_cc_functions.c optional inet sctp
+netinet/sctp_crc32.c optional inet sctp
+netinet/sctp_indata.c optional inet sctp
+netinet/sctp_input.c optional inet sctp
+netinet/sctp_output.c optional inet sctp
+netinet/sctp_pcb.c optional inet sctp
+netinet/sctp_peeloff.c optional inet sctp
+netinet/sctp_sysctl.c optional inet sctp
+netinet/sctp_timer.c optional inet sctp
+netinet/sctp_usrreq.c optional inet sctp
+netinet/sctputil.c optional inet sctp
netinet/tcp_debug.c optional tcpdebug
netinet/tcp_hostcache.c optional inet
netinet/tcp_input.c optional inet
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index f9f3660..e3bb19f 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -845,31 +845,43 @@ send_reply:
/* pullup already done, IP options already stripped */
iph = mtod(m, struct ip *);
sh = (struct sctphdr *)((caddr_t)iph + sizeof(*iph));
- if (iph->ip_v == IPVERSION) {
- struct sockaddr_in *from4;
-
- from4 = (struct sockaddr_in *)&from_store;
- bzero(from4, sizeof(*from4));
- from4->sin_family = AF_INET;
- from4->sin_len = sizeof(struct sockaddr_in);
- from4->sin_addr.s_addr = iph->ip_src.s_addr;
- from4->sin_port = sh->src_port;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *from6;
-
- ip6 = mtod(m, struct ip6_hdr *);
- from6 = (struct sockaddr_in6 *)&from_store;
- bzero(from6, sizeof(*from6));
- from6->sin6_family = AF_INET6;
- from6->sin6_len = sizeof(struct sockaddr_in6);
- from6->sin6_addr = ip6->ip6_src;
- from6->sin6_port = sh->src_port;
- /* Get the scopes in properly to the sin6 addr's */
- /* we probably don't need these operations */
- (void)sa6_recoverscope(from6);
- sa6_embedscope(from6, ip6_use_defzone);
- } else {
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ struct sockaddr_in *from4;
+
+ from4 = (struct sockaddr_in *)&from_store;
+ bzero(from4, sizeof(*from4));
+ from4->sin_family = AF_INET;
+ from4->sin_len = sizeof(struct sockaddr_in);
+ from4->sin_addr.s_addr = iph->ip_src.s_addr;
+ from4->sin_port = sh->src_port;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *from6;
+
+ ip6 = mtod(m, struct ip6_hdr *);
+ from6 = (struct sockaddr_in6 *)&from_store;
+ bzero(from6, sizeof(*from6));
+ from6->sin6_family = AF_INET6;
+ from6->sin6_len = sizeof(struct sockaddr_in6);
+ from6->sin6_addr = ip6->ip6_src;
+ from6->sin6_port = sh->src_port;
+ /*
+ * Get the scopes in properly to the sin6
+ * addr's
+ */
+ /* we probably don't need these operations */
+ (void)sa6_recoverscope(from6);
+ sa6_embedscope(from6, ip6_use_defzone);
+ break;
+ }
+#endif
+ default:
/* unknown address type */
from = NULL;
}
@@ -1162,11 +1174,13 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *) & net->ro))
changed = 1;
}
+#ifdef INET6
if (net->ro._l_addr.sa.sa_family == AF_INET6) {
if (sctp_v6src_match_nexthop(
&newifa->address.sin6, (sctp_route_t *) & net->ro))
changed = 1;
}
+#endif
/*
* if the newly added address does not relate routing
* information, we skip.
@@ -1858,6 +1872,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
}
}
+#ifdef INET6
static uint32_t
sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
{
@@ -1890,6 +1905,8 @@ sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
return (0);
}
+#endif
+
/*
* address management functions
*/
@@ -1932,47 +1949,56 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* anything... note: this would leave the address on both inp and
* asoc lists
*/
- if (ifa->address.sa.sa_family == AF_INET6) {
- 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.sin6;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /* we skip unspecifed addresses */
- return;
- }
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- if (stcb->asoc.local_scope == 0) {
+ sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /* we skip unspecifed addresses */
return;
}
- /* is it the right link local scope? */
- if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ if (stcb->asoc.local_scope == 0) {
+ return;
+ }
+ /* is it the right link local scope? */
+ if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
+ return;
+ }
+ }
+ if (stcb->asoc.site_scope == 0 &&
+ IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
return;
}
+ break;
}
- if (stcb->asoc.site_scope == 0 &&
- IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
- return;
- }
- } else if (ifa->address.sa.sa_family == AF_INET) {
- struct sockaddr_in *sin;
- struct in6pcb *inp6;
+#endif
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
+ struct in6pcb *inp6;
- inp6 = (struct in6pcb *)&inp->ip_inp.inp;
- /* invalid if we are a v6 only endpoint */
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6))
- return;
+ inp6 = (struct in6pcb *)&inp->ip_inp.inp;
+ /* invalid if we are a v6 only endpoint */
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+ SCTP_IPV6_V6ONLY(inp6))
+ return;
- sin = (struct sockaddr_in *)&ifa->address.sa;
- if (sin->sin_addr.s_addr == 0) {
- /* we skip unspecifed addresses */
- return;
- }
- if (stcb->asoc.ipv4_local_scope == 0 &&
- IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
- return;
+ sin = (struct sockaddr_in *)&ifa->address.sa;
+ if (sin->sin_addr.s_addr == 0) {
+ /* we skip unspecifed addresses */
+ return;
+ }
+ if (stcb->asoc.ipv4_local_scope == 0 &&
+ IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
+ return;
+ }
+ break;
}
- } else {
+ default:
/* else, not AF_INET or AF_INET6, so skip */
return;
}
@@ -2106,66 +2132,76 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
continue;
}
/* Same checks again for assoc */
- if (ifa->address.sa.sa_family == AF_INET6) {
- /* invalid if we're not a v6 endpoint */
- struct sockaddr_in6 *sin6;
+ switch (ifa->address.sa.sa_family) {
+#ifdef INET6
+ case AF_INET6:
+ {
+ /* invalid if we're not a v6 endpoint */
+ struct sockaddr_in6 *sin6;
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
- cnt_invalid++;
- if (asc->cnt == cnt_invalid)
- return;
- else
- continue;
- }
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /* we skip unspecifed addresses */
- continue;
- }
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- if (stcb->asoc.local_scope == 0) {
- continue;
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
+ cnt_invalid++;
+ if (asc->cnt == cnt_invalid)
+ return;
+ else
+ continue;
}
- /* is it the right link local scope? */
- if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
+ sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /* we skip unspecifed addresses */
continue;
}
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ if (stcb->asoc.local_scope == 0) {
+ continue;
+ }
+ /* is it the right link local scope? */
+ if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
+ continue;
+ }
+ }
+ break;
}
- } else if (ifa->address.sa.sa_family == AF_INET) {
- /* invalid if we are a v6 only endpoint */
- struct in6pcb *inp6;
- struct sockaddr_in *sin;
+#endif
+ case AF_INET:
+ {
+ /* invalid if we are a v6 only endpoint */
+ struct in6pcb *inp6;
+ struct sockaddr_in *sin;
- inp6 = (struct in6pcb *)&inp->ip_inp.inp;
- /* invalid if we are a v6 only endpoint */
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6))
- continue;
+ inp6 = (struct in6pcb *)&inp->ip_inp.inp;
+ /* invalid if we are a v6 only endpoint */
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+ SCTP_IPV6_V6ONLY(inp6))
+ continue;
- sin = (struct sockaddr_in *)&ifa->address.sa;
- if (sin->sin_addr.s_addr == 0) {
- /* we skip unspecifed addresses */
- continue;
- }
- if (stcb->asoc.ipv4_local_scope == 0 &&
- IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
- continue;;
- }
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
- SCTP_IPV6_V6ONLY(inp6)) {
- cnt_invalid++;
- if (asc->cnt == cnt_invalid)
- return;
- else
+ sin = (struct sockaddr_in *)&ifa->address.sa;
+ if (sin->sin_addr.s_addr == 0) {
+ /* we skip unspecifed addresses */
continue;
+ }
+ if (stcb->asoc.ipv4_local_scope == 0 &&
+ IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
+ continue;;
+ }
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+ SCTP_IPV6_V6ONLY(inp6)) {
+ cnt_invalid++;
+ if (asc->cnt == cnt_invalid)
+ return;
+ else
+ continue;
+ }
+ break;
}
- } else {
+ default:
/* invalid address family */
cnt_invalid++;
if (asc->cnt == cnt_invalid)
return;
else
continue;
+ break;
}
if (type == SCTP_ADD_IP_ADDRESS) {
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index fcb607c..993f641 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -116,7 +116,7 @@ sctp_startup_iterator(void)
#endif
-
+#ifdef INET6
void
sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
{
@@ -144,6 +144,7 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
}
}
+#endif
static uint32_t
diff --git a/sys/netinet/sctp_bsd_addr.h b/sys/netinet/sctp_bsd_addr.h
index 45a05b6..63d39b2 100644
--- a/sys/netinet/sctp_bsd_addr.h
+++ b/sys/netinet/sctp_bsd_addr.h
@@ -44,8 +44,11 @@ void sctp_startup_iterator(void);
#endif
+#ifdef INET6
void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
+#endif
+
#ifdef SCTP_PACKET_LOGGING
void sctp_packet_log(struct mbuf *m, int length);
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 4e57cb1..1602459 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -1248,7 +1248,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
/* pre-reserve some space */
+#ifdef INET6
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+#else
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+#endif
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
@@ -2116,31 +2120,40 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
}
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *lsin;
-
- lsin = (struct sockaddr_in *)(localep_sa);
- memset(lsin, 0, sizeof(*lsin));
- lsin->sin_family = AF_INET;
- lsin->sin_len = sizeof(*lsin);
- lsin->sin_port = sh->dest_port;
- lsin->sin_addr.s_addr = iph->ip_dst.s_addr;
- size_of_pkt = SCTP_GET_IPV4_LENGTH(iph);
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *lsin6;
-
- lsin6 = (struct sockaddr_in6 *)(localep_sa);
- memset(lsin6, 0, sizeof(*lsin6));
- lsin6->sin6_family = AF_INET6;
- lsin6->sin6_len = sizeof(struct sockaddr_in6);
- ip6 = mtod(m, struct ip6_hdr *);
- lsin6->sin6_port = sh->dest_port;
- lsin6->sin6_addr = ip6->ip6_dst;
- size_of_pkt = SCTP_GET_IPV6_LENGTH(ip6) + iphlen;
- } else {
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *lsin;
+
+ lsin = (struct sockaddr_in *)(localep_sa);
+ memset(lsin, 0, sizeof(*lsin));
+ lsin->sin_family = AF_INET;
+ lsin->sin_len = sizeof(*lsin);
+ lsin->sin_port = sh->dest_port;
+ lsin->sin_addr.s_addr = iph->ip_dst.s_addr;
+ size_of_pkt = SCTP_GET_IPV4_LENGTH(iph);
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *lsin6;
+
+ lsin6 = (struct sockaddr_in6 *)(localep_sa);
+ memset(lsin6, 0, sizeof(*lsin6));
+ lsin6->sin6_family = AF_INET6;
+ lsin6->sin6_len = sizeof(struct sockaddr_in6);
+ ip6 = mtod(m, struct ip6_hdr *);
+ lsin6->sin6_port = sh->dest_port;
+ lsin6->sin6_addr = ip6->ip6_dst;
+ size_of_pkt = SCTP_GET_IPV6_LENGTH(ip6) + iphlen;
+ break;
+ }
+#endif
+ default:
return (NULL);
}
@@ -2287,7 +2300,11 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
/* pre-reserve some space */
+#ifdef INET6
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+#else
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+#endif
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 7cfe60f..8fa1846 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -1874,47 +1874,60 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
*/
return (0);
}
- if ((ifa->address.sa.sa_family == AF_INET) && ipv4_addr_legal) {
- struct sockaddr_in *sin;
-
- sin = (struct sockaddr_in *)&ifa->address.sin;
- if (sin->sin_addr.s_addr == 0) {
- /* not in scope , unspecified */
- return (0);
- }
- if ((ipv4_local_scope == 0) &&
- (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
- /* private address not in scope */
+ switch (ifa->address.sa.sa_family) {
+ case AF_INET:
+ if (ipv4_addr_legal) {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&ifa->address.sin;
+ if (sin->sin_addr.s_addr == 0) {
+ /* not in scope , unspecified */
+ return (0);
+ }
+ if ((ipv4_local_scope == 0) &&
+ (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
+ /* private address not in scope */
+ return (0);
+ }
+ } else {
return (0);
}
- } else if ((ifa->address.sa.sa_family == AF_INET6) && ipv6_addr_legal) {
- struct sockaddr_in6 *sin6;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (ipv6_addr_legal) {
+ struct sockaddr_in6 *sin6;
- /*
- * Must update the flags, bummer, which means any IFA locks
- * must now be applied HERE <->
- */
- if (do_update) {
- sctp_gather_internal_ifa_flags(ifa);
- }
- if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
- return (0);
- }
- /* ok to use deprecated addresses? */
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /* skip unspecifed addresses */
- return (0);
- }
- if ( /* (local_scope == 0) && */
- (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
- return (0);
- }
- if ((site_scope == 0) &&
- (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
+ /*
+ * Must update the flags, bummer, which means any
+ * IFA locks must now be applied HERE <->
+ */
+ if (do_update) {
+ sctp_gather_internal_ifa_flags(ifa);
+ }
+ if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
+ return (0);
+ }
+ /* ok to use deprecated addresses? */
+ sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /* skip unspecifed addresses */
+ return (0);
+ }
+ if ( /* (local_scope == 0) && */
+ (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
+ return (0);
+ }
+ if ((site_scope == 0) &&
+ (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
+ return (0);
+ }
+ } else {
return (0);
}
- } else {
+ break;
+#endif
+ default:
return (0);
}
return (1);
@@ -1954,30 +1967,39 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa)
parmh = mtod(mret, struct sctp_paramhdr *);
}
/* now add the parameter */
- if (ifa->address.sa.sa_family == AF_INET) {
- struct sctp_ipv4addr_param *ipv4p;
- struct sockaddr_in *sin;
-
- sin = (struct sockaddr_in *)&ifa->address.sin;
- ipv4p = (struct sctp_ipv4addr_param *)parmh;
- parmh->param_type = htons(SCTP_IPV4_ADDRESS);
- parmh->param_length = htons(len);
- ipv4p->addr = sin->sin_addr.s_addr;
- SCTP_BUF_LEN(mret) += len;
- } else if (ifa->address.sa.sa_family == AF_INET6) {
- struct sctp_ipv6addr_param *ipv6p;
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
- ipv6p = (struct sctp_ipv6addr_param *)parmh;
- parmh->param_type = htons(SCTP_IPV6_ADDRESS);
- parmh->param_length = htons(len);
- memcpy(ipv6p->addr, &sin6->sin6_addr,
- sizeof(ipv6p->addr));
- /* clear embedded scope in the address */
- in6_clearscope((struct in6_addr *)ipv6p->addr);
- SCTP_BUF_LEN(mret) += len;
- } else {
+ switch (ifa->address.sa.sa_family) {
+ case AF_INET:
+ {
+ struct sctp_ipv4addr_param *ipv4p;
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&ifa->address.sin;
+ ipv4p = (struct sctp_ipv4addr_param *)parmh;
+ parmh->param_type = htons(SCTP_IPV4_ADDRESS);
+ parmh->param_length = htons(len);
+ ipv4p->addr = sin->sin_addr.s_addr;
+ SCTP_BUF_LEN(mret) += len;
+ break;
+ }
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sctp_ipv6addr_param *ipv6p;
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ ipv6p = (struct sctp_ipv6addr_param *)parmh;
+ parmh->param_type = htons(SCTP_IPV6_ADDRESS);
+ parmh->param_length = htons(len);
+ memcpy(ipv6p->addr, &sin6->sin6_addr,
+ sizeof(ipv6p->addr));
+ /* clear embedded scope in the address */
+ in6_clearscope((struct in6_addr *)ipv6p->addr);
+ SCTP_BUF_LEN(mret) += len;
+ break;
+ }
+#endif
+ default:
return (m);
}
return (mret);
@@ -2643,6 +2665,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
* addresses. We should use one corresponding to the
* next-hop. (by micchie)
*/
+#ifdef INET6
if (stcb && fam == AF_INET6 &&
sctp_is_mobility_feature_on(stcb->sctp_ep, SCTP_MOBILITY_BASE)) {
if (sctp_v6src_match_nexthop(&sifa->address.sin6, ro)
@@ -2650,6 +2673,7 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
continue;
}
}
+#endif
/* Avoid topologically incorrect IPv4 address */
if (stcb && fam == AF_INET &&
sctp_is_mobility_feature_on(stcb->sctp_ep, SCTP_MOBILITY_BASE)) {
@@ -2946,7 +2970,11 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
int non_asoc_addr_ok, uint32_t vrf_id)
{
struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst;
+
+#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;
@@ -3025,7 +3053,8 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
fam = to->sin_family;
dest_is_priv = dest_is_loop = 0;
/* Setup our scopes for the destination */
- if (fam == AF_INET) {
+ switch (fam) {
+ case AF_INET:
/* Scope based on outbound address */
if ((IN4_ISPRIVATE_ADDRESS(&to->sin_addr))) {
dest_is_priv = 1;
@@ -3036,7 +3065,9 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
net->addr_is_local = 1;
}
}
- } else if (fam == AF_INET6) {
+ break;
+#ifdef INET6
+ case AF_INET6:
/* Scope based on outbound address */
if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
/*
@@ -3053,6 +3084,8 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
} else if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
dest_is_priv = 1;
}
+ break;
+#endif
}
SCTPDBG(SCTP_DEBUG_OUTPUT2, "Select source addr for:");
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)to);
@@ -3931,6 +3964,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
net->dest_state &= ~SCTP_ADDR_UNCONFIRMED;
}
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT\n");
+#ifdef INET6
if (((struct sockaddr *)&(net->ro._l_addr))->sa_family == AF_INET6) {
/*
* special hook, if we are sending to link local it will not
@@ -3942,6 +3976,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
if (IN6_IS_ADDR_LINKLOCAL(&sin6l->sin6_addr))
cnt_inits_to = 1;
}
+#endif
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
/* This case should not happen */
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - failed timer?\n");
@@ -3987,11 +4022,17 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
sup_addr = (struct sctp_supported_addr_param *)((caddr_t)initm +
sizeof(*initm));
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
- /* we support 2 types IPv6/IPv4 */
- sup_addr->ph.param_length = htons(sizeof(*sup_addr) +
- sizeof(uint16_t));
+#ifdef INET6
+ /* we support 2 types: IPv6/IPv4 */
+ 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: IPv4 */
+ sup_addr->ph.param_length = htons(sizeof(*sup_addr) + sizeof(uint8_t));
+ sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
+ sup_addr->addr_type[1] = htons(0); /* this is the padding */
+#endif
SCTP_BUF_LEN(m) += sizeof(*sup_addr) + sizeof(uint16_t);
if (inp->sctp_ep.adaptation_layer_indicator) {
@@ -4327,7 +4368,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
*abort_processing = 1;
if (op_err == NULL) {
/* Ok need to try to get a mbuf */
+#ifdef INET6
l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+#else
+ l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+#endif
l_len += plen;
l_len += sizeof(struct sctp_paramhdr);
op_err = sctp_get_mbuf_for_msg(l_len, 0, M_DONTWAIT, 1, MT_DATA);
@@ -4338,7 +4383,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
* and sctp header and
* chunk hdr
*/
+#ifdef INET6
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+#else
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+#endif
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
}
@@ -4389,13 +4438,21 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
int l_len;
/* Ok need to try to get an mbuf */
+#ifdef INET6
l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+#else
+ l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+#endif
l_len += plen;
l_len += sizeof(struct sctp_paramhdr);
op_err = sctp_get_mbuf_for_msg(l_len, 0, M_DONTWAIT, 1, MT_DATA);
if (op_err) {
SCTP_BUF_LEN(op_err) = 0;
+#ifdef INET6
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+#else
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+#endif
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
}
@@ -4456,12 +4513,20 @@ invalid_size:
if ((op_err == NULL) && phdr) {
int l_len;
+#ifdef INET6
l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+#else
+ l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+#endif
l_len += (2 * sizeof(struct sctp_paramhdr));
op_err = sctp_get_mbuf_for_msg(l_len, 0, M_DONTWAIT, 1, MT_DATA);
if (op_err) {
SCTP_BUF_LEN(op_err) = 0;
+#ifdef INET6
SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+#else
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+#endif
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
}
@@ -4498,11 +4563,20 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
* 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;
struct ip *iph;
+
+#ifdef INET6
+ struct ip6_hdr *ip6h;
+
+#endif
struct mbuf *mat;
uint16_t ptype, plen;
int err_at;
@@ -4510,27 +4584,33 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
struct sctp_nets *net;
memset(&sin4, 0, sizeof(sin4));
+#ifdef INET6
memset(&sin6, 0, sizeof(sin6));
+#endif
sin4.sin_family = AF_INET;
sin4.sin_len = sizeof(sin4);
+#ifdef INET6
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
-
+#endif
sa_touse = NULL;
/* First what about the src address of the pkt ? */
iph = mtod(in_initpkt, struct ip *);
- if (iph->ip_v == IPVERSION) {
+ switch (iph->ip_v) {
+ case IPVERSION:
/* source addr is IPv4 */
sin4.sin_addr = iph->ip_src;
sa_touse = (struct sockaddr *)&sin4;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
/* source addr is IPv6 */
- struct ip6_hdr *ip6h;
-
ip6h = mtod(in_initpkt, struct ip6_hdr *);
sin6.sin6_addr = ip6h->ip6_src;
sa_touse = (struct sockaddr *)&sin6;
- } else {
+ break;
+#endif
+ default:
return (1);
}
@@ -4545,7 +4625,9 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
fnd = 1;
break;
}
- } else if (sa->sa_family == AF_INET6) {
+ }
+#ifdef INET6
+ if (sa->sa_family == AF_INET6) {
sa6 = (struct sockaddr_in6 *)sa;
if (SCTP6_ARE_ADDR_EQUAL(&sa6->sin6_addr,
&sin6.sin6_addr)) {
@@ -4553,6 +4635,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
break;
}
}
+#endif
}
}
if (fnd == 0) {
@@ -4590,8 +4673,10 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
return (1);
}
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;
}
if (sa_touse) {
@@ -4609,7 +4694,9 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
fnd = 1;
break;
}
- } else if (sa->sa_family == AF_INET6) {
+ }
+#ifdef INET6
+ if (sa->sa_family == AF_INET6) {
sa6 = (struct sockaddr_in6 *)sa;
if (SCTP6_ARE_ADDR_EQUAL(
&sa6->sin6_addr, &sin6.sin6_addr)) {
@@ -4617,6 +4704,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
break;
}
}
+#endif
}
if (!fnd) {
/* New addr added! no need to look further */
@@ -4649,10 +4737,18 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_supported_chunk_types_param *pr_supported;
struct sockaddr_storage store;
struct sockaddr_in *sin;
+
+#ifdef INET6
struct sockaddr_in6 *sin6;
+
+#endif
sctp_route_t *ro;
struct ip *iph;
+
+#ifdef INET6
struct ip6_hdr *ip6;
+
+#endif
struct sockaddr *to;
struct sctp_state_cookie stc;
struct sctp_nets *net = NULL;
@@ -4752,138 +4848,166 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* now for scope setup */
memset((caddr_t)&store, 0, sizeof(store));
sin = (struct sockaddr_in *)&store;
+#ifdef INET6
sin6 = (struct sockaddr_in6 *)&store;
+#endif
if (net == NULL) {
to = (struct sockaddr *)&store;
iph = mtod(init_pkt, struct ip *);
- if (iph->ip_v == IPVERSION) {
- struct sctp_ifa *addr;
- sctp_route_t iproute;
-
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(struct sockaddr_in);
- sin->sin_port = sh->src_port;
- sin->sin_addr = iph->ip_src;
- /* lookup address */
- stc.address[0] = sin->sin_addr.s_addr;
- stc.address[1] = 0;
- stc.address[2] = 0;
- stc.address[3] = 0;
- stc.addr_type = SCTP_IPV4_ADDRESS;
- /* local from address */
- memset(&iproute, 0, sizeof(iproute));
- ro = &iproute;
- memcpy(&ro->ro_dst, sin, sizeof(*sin));
- addr = sctp_source_address_selection(inp, NULL,
- ro, NULL, 0,
- vrf_id);
- if (addr == NULL)
- return;
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ struct sctp_ifa *addr;
+ sctp_route_t iproute;
+
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(struct sockaddr_in);
+ sin->sin_port = sh->src_port;
+ sin->sin_addr = iph->ip_src;
+ /* lookup address */
+ stc.address[0] = sin->sin_addr.s_addr;
+ stc.address[1] = 0;
+ stc.address[2] = 0;
+ stc.address[3] = 0;
+ stc.addr_type = SCTP_IPV4_ADDRESS;
+ /* local from address */
+ memset(&iproute, 0, sizeof(iproute));
+ ro = &iproute;
+ memcpy(&ro->ro_dst, sin, sizeof(*sin));
+ addr = sctp_source_address_selection(inp, NULL,
+ ro, NULL, 0,
+ vrf_id);
+ if (addr == NULL)
+ return;
- if (ro->ro_rt) {
- RTFREE(ro->ro_rt);
- ro->ro_rt = NULL;
- }
- stc.laddress[0] = addr->address.sin.sin_addr.s_addr;
- stc.laddress[1] = 0;
- stc.laddress[2] = 0;
- stc.laddress[3] = 0;
- stc.laddr_type = SCTP_IPV4_ADDRESS;
- /* scope_id is only for v6 */
- stc.scope_id = 0;
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = NULL;
+ }
+ stc.laddress[0] = addr->address.sin.sin_addr.s_addr;
+ stc.laddress[1] = 0;
+ stc.laddress[2] = 0;
+ stc.laddress[3] = 0;
+ stc.laddr_type = SCTP_IPV4_ADDRESS;
+ /* scope_id is only for v6 */
+ stc.scope_id = 0;
#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE
- if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
- stc.ipv4_scope = 1;
- }
+ if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
+ stc.ipv4_scope = 1;
+ }
#else
- stc.ipv4_scope = 1;
-#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
- /* Must use the address in this case */
- if (sctp_is_address_on_local_host((struct sockaddr *)sin, vrf_id)) {
- stc.loopback_scope = 1;
stc.ipv4_scope = 1;
- stc.site_scope = 1;
- stc.local_scope = 0;
- }
- sctp_free_ifa(addr);
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- struct sctp_ifa *addr;
- struct route_in6 iproute6;
-
- ip6 = mtod(init_pkt, struct ip6_hdr *);
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(struct sockaddr_in6);
- sin6->sin6_port = sh->src_port;
- sin6->sin6_addr = ip6->ip6_src;
- /* lookup address */
- memcpy(&stc.address, &sin6->sin6_addr,
- sizeof(struct in6_addr));
- sin6->sin6_scope_id = 0;
- stc.addr_type = SCTP_IPV6_ADDRESS;
- stc.scope_id = 0;
- if (sctp_is_address_on_local_host((struct sockaddr *)sin6, vrf_id)) {
- stc.loopback_scope = 1;
- stc.local_scope = 0;
- stc.site_scope = 1;
- stc.ipv4_scope = 1;
- } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- /*
- * If the new destination is a LINK_LOCAL we
- * must have common both site and local
- * scope. Don't set local scope though since
- * we must depend on the source to be added
- * implicitly. We cannot assure just because
- * we share one link that all links are
- * common.
- */
- stc.local_scope = 0;
- stc.site_scope = 1;
- stc.ipv4_scope = 1;
- /*
- * we start counting for the private address
- * stuff at 1. since the link local we
- * source from won't show up in our scoped
- * count.
- */
- cnt_inits_to = 1;
- /* pull out the scope_id from incoming pkt */
- /* FIX ME: does this have scope from rcvif? */
- (void)sa6_recoverscope(sin6);
-
- sa6_embedscope(sin6, ip6_use_defzone);
- stc.scope_id = sin6->sin6_scope_id;
- } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
- /*
- * If the new destination is SITE_LOCAL then
- * we must have site scope in common.
- */
- stc.site_scope = 1;
- }
- /* local from address */
- memset(&iproute6, 0, sizeof(iproute6));
- ro = (sctp_route_t *) & iproute6;
- memcpy(&ro->ro_dst, sin6, sizeof(*sin6));
- addr = sctp_source_address_selection(inp, NULL,
- ro, NULL, 0, vrf_id);
- if (addr == NULL)
- return;
+#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
+ /* Must use the address in this case */
+ if (sctp_is_address_on_local_host((struct sockaddr *)sin, vrf_id)) {
+ stc.loopback_scope = 1;
+ stc.ipv4_scope = 1;
+ stc.site_scope = 1;
+ stc.local_scope = 0;
+ }
+ sctp_free_ifa(addr);
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ struct sctp_ifa *addr;
+ struct route_in6 iproute6;
+
+ ip6 = mtod(init_pkt, struct ip6_hdr *);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+ sin6->sin6_port = sh->src_port;
+ sin6->sin6_addr = ip6->ip6_src;
+ /* lookup address */
+ memcpy(&stc.address, &sin6->sin6_addr,
+ sizeof(struct in6_addr));
+ sin6->sin6_scope_id = 0;
+ stc.addr_type = SCTP_IPV6_ADDRESS;
+ stc.scope_id = 0;
+ if (sctp_is_address_on_local_host((struct sockaddr *)sin6, vrf_id)) {
+ stc.loopback_scope = 1;
+ stc.local_scope = 0;
+ stc.site_scope = 1;
+ stc.ipv4_scope = 1;
+ } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ /*
+ * If the new destination is a
+ * LINK_LOCAL we must have common
+ * both site and local scope. Don't
+ * set local scope though since we
+ * must depend on the source to be
+ * added implicitly. We cannot
+ * assure just because we share one
+ * link that all links are common.
+ */
+ stc.local_scope = 0;
+ stc.site_scope = 1;
+ stc.ipv4_scope = 1;
+ /*
+ * we start counting for the private
+ * address stuff at 1. since the
+ * link local we source from won't
+ * show up in our scoped count.
+ */
+ cnt_inits_to = 1;
+ /*
+ * pull out the scope_id from
+ * incoming pkt
+ */
+ /*
+ * FIX ME: does this have scope from
+ * rcvif?
+ */
+ (void)sa6_recoverscope(sin6);
- if (ro->ro_rt) {
- RTFREE(ro->ro_rt);
- ro->ro_rt = NULL;
+ sa6_embedscope(sin6, ip6_use_defzone);
+ stc.scope_id = sin6->sin6_scope_id;
+ } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
+ /*
+ * If the new destination is
+ * SITE_LOCAL then we must have site
+ * scope in common.
+ */
+ stc.site_scope = 1;
+ }
+ /* local from address */
+ memset(&iproute6, 0, sizeof(iproute6));
+ ro = (sctp_route_t *) & iproute6;
+ memcpy(&ro->ro_dst, sin6, sizeof(*sin6));
+ addr = sctp_source_address_selection(inp, NULL,
+ ro, NULL, 0, vrf_id);
+ if (addr == NULL)
+ return;
+
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ ro->ro_rt = NULL;
+ }
+ memcpy(&stc.laddress, &addr->address.sin6.sin6_addr, sizeof(struct in6_addr));
+ stc.laddr_type = SCTP_IPV6_ADDRESS;
+ sctp_free_ifa(addr);
+ break;
}
- memcpy(&stc.laddress, &addr->address.sin6.sin6_addr, sizeof(struct in6_addr));
- stc.laddr_type = SCTP_IPV6_ADDRESS;
- sctp_free_ifa(addr);
+#endif
+ default:
+ /* TSNH */
+ break;
}
} else {
/* set the scope per the existing tcb */
+
+#ifdef INET6
struct sctp_nets *lnet;
+#endif
+
stc.loopback_scope = asoc->loopback_scope;
stc.ipv4_scope = asoc->ipv4_local_scope;
stc.site_scope = asoc->site_scope;
stc.local_scope = asoc->local_scope;
+#ifdef INET6
+ /* Why do we not consider IPv4 LL addresses? */
TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) {
if (lnet->ro._l_addr.sin6.sin6_family == AF_INET6) {
if (IN6_IS_ADDR_LINKLOCAL(&lnet->ro._l_addr.sin6.sin6_addr)) {
@@ -4895,10 +5019,11 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
}
-
+#endif
/* use the net pointer */
to = (struct sockaddr *)&net->ro._l_addr;
- if (to->sa_family == AF_INET) {
+ switch (to->sa_family) {
+ case AF_INET:
sin = (struct sockaddr_in *)to;
stc.address[0] = sin->sin_addr.s_addr;
stc.address[1] = 0;
@@ -4924,7 +5049,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
stc.laddress[2] = 0;
stc.laddress[3] = 0;
stc.laddr_type = SCTP_IPV4_ADDRESS;
- } else if (to->sa_family == AF_INET6) {
+ break;
+#ifdef INET6
+ case AF_INET6:
sin6 = (struct sockaddr_in6 *)to;
memcpy(&stc.address, &sin6->sin6_addr,
sizeof(struct in6_addr));
@@ -4945,6 +5072,8 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
memcpy(&stc.laddress, &net->ro._s_addr->address.sin6.sin6_addr,
sizeof(struct in6_addr));
stc.laddr_type = SCTP_IPV6_ADDRESS;
+ break;
+#endif
}
}
/* Now lets put the SCTP header in place */
@@ -6839,7 +6968,6 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
}
#else
goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;
- mtu_fromwheel = 0;
#endif
/* Need an allowance for the data chunk header too */
goal_mtu -= sizeof(struct sctp_data_chunk);
@@ -7233,10 +7361,19 @@ again_one_more_time:
continue;
}
}
- if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
+ switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
+ case AF_INET:
mtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
- } else {
+ break;
+#ifdef INET6
+ case AF_INET6:
mtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
+ break;
+#endif
+ default:
+ /* TSNH */
+ mtu = net->mtu;
+ break;
}
mx_mtu = mtu;
to_out = 0;
@@ -7513,16 +7650,25 @@ again_one_more_time:
mtu -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
}
/* now lets add any data within the MTU constraints */
- if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
+ switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
+ case AF_INET:
if (net->mtu > (sizeof(struct ip) + sizeof(struct sctphdr)))
omtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
else
omtu = 0;
- } else {
+ break;
+#ifdef INET6
+ case AF_INET6:
if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)))
omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
else
omtu = 0;
+ break;
+#endif
+ default:
+ /* TSNH */
+ omtu = 0;
+ break;
}
if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) && (skip_data_for_this_net == 0)) ||
(cookie)) {
@@ -9691,12 +9837,20 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
struct mbuf *o_pak;
struct mbuf *mout;
struct ip *iph, *iph_out;
+
+#ifdef INET6
struct ip6_hdr *ip6, *ip6_out;
+
+#endif
int offset_out, len, mlen;
struct sctp_shutdown_complete_msg *comp_cp;
/* Get room for the largest message */
+#ifdef INET6
len = (sizeof(struct ip6_hdr) + sizeof(struct sctp_shutdown_complete_msg));
+#else
+ len = (sizeof(struct ip) + sizeof(struct sctp_shutdown_complete_msg));
+#endif
mout = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
if (mout == NULL) {
return;
@@ -9704,9 +9858,12 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
SCTP_BUF_LEN(mout) = len;
iph = mtod(m, struct ip *);
iph_out = NULL;
+#ifdef INET6
ip6_out = NULL;
+#endif
offset_out = 0;
- if (iph->ip_v == IPVERSION) {
+ switch (iph->ip_v) {
+ case IPVERSION:
SCTP_BUF_LEN(mout) = sizeof(struct ip) +
sizeof(struct sctp_shutdown_complete_msg);
SCTP_BUF_NEXT(mout) = NULL;
@@ -9728,7 +9885,9 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
offset_out += sizeof(*iph_out);
comp_cp = (struct sctp_shutdown_complete_msg *)(
(caddr_t)iph_out + offset_out);
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
ip6 = (struct ip6_hdr *)iph;
SCTP_BUF_LEN(mout) = sizeof(struct ip6_hdr) +
sizeof(struct sctp_shutdown_complete_msg);
@@ -9749,7 +9908,9 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
offset_out += sizeof(*ip6_out);
comp_cp = (struct sctp_shutdown_complete_msg *)(
(caddr_t)ip6_out + offset_out);
- } else {
+ break;
+#endif
+ default:
/* Currently not supported. */
return;
}
@@ -9790,7 +9951,9 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
/* Free the route if we got one back */
if (ro.ro_rt)
RTFREE(ro.ro_rt);
- } else if (ip6_out != NULL) {
+ }
+#ifdef INET6
+ if (ip6_out != NULL) {
struct route_in6 ro;
int ret;
struct sctp_tcb *stcb = NULL;
@@ -9809,6 +9972,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
if (ro.ro_rt)
RTFREE(ro.ro_rt);
}
+#endif
SCTP_STAT_INCR(sctps_sendpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
@@ -10104,6 +10268,11 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
int len;
int was_trunc = 0;
struct ip *iph;
+
+#ifdef INET6
+ struct ip6_hdr *ip6h;
+
+#endif
int fullsz = 0, extra = 0;
long spc;
int offset;
@@ -10134,15 +10303,20 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
sctp_free_a_chunk(stcb, chk);
return;
}
- if (iph->ip_v == IPVERSION) {
+ switch (iph->ip_v) {
+ case IPVERSION:
/* IPv4 */
len = chk->send_size = iph->ip_len;
- } else {
- struct ip6_hdr *ip6h;
-
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
/* IPv6 */
ip6h = mtod(m, struct ip6_hdr *);
len = chk->send_size = htons(ip6h->ip6_plen);
+ break;
+#endif
+ default:
+ return;
}
/* Validate that we do not have an ABORT in here. */
offset = iphlen + sizeof(struct sctphdr);
@@ -10593,7 +10767,11 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
struct mbuf *mout;
struct sctp_abort_msg *abm;
struct ip *iph, *iph_out;
+
+#ifdef INET6
struct ip6_hdr *ip6, *ip6_out;
+
+#endif
int iphlen_out, len;
/* don't respond to ABORT with ABORT */
@@ -10602,8 +10780,11 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
sctp_m_freem(err_cause);
return;
}
+#ifdef INET6
len = (sizeof(struct ip6_hdr) + sizeof(struct sctp_abort_msg));
-
+#else
+ len = (sizeof(struct ip) + sizeof(struct sctp_abort_msg));
+#endif
mout = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
if (mout == NULL) {
if (err_cause)
@@ -10612,8 +10793,11 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
}
iph = mtod(m, struct ip *);
iph_out = NULL;
+#ifdef INET6
ip6_out = NULL;
- if (iph->ip_v == IPVERSION) {
+#endif
+ switch (iph->ip_v) {
+ case IPVERSION:
iph_out = mtod(mout, struct ip *);
SCTP_BUF_LEN(mout) = sizeof(*iph_out) + sizeof(*abm);
SCTP_BUF_NEXT(mout) = err_cause;
@@ -10633,7 +10817,9 @@ 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);
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
ip6 = (struct ip6_hdr *)iph;
ip6_out = mtod(mout, struct ip6_hdr *);
SCTP_BUF_LEN(mout) = sizeof(*ip6_out) + sizeof(*abm);
@@ -10648,7 +10834,9 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
iphlen_out = sizeof(*ip6_out);
abm = (struct sctp_abort_msg *)((caddr_t)ip6_out + iphlen_out);
- } else {
+ break;
+#endif
+ default:
/* Currently not supported */
if (err_cause)
sctp_m_freem(err_cause);
@@ -10722,7 +10910,9 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
/* Free the route if we got one back */
if (ro.ro_rt)
RTFREE(ro.ro_rt);
- } else if (ip6_out != NULL) {
+ }
+#ifdef INET6
+ if (ip6_out != NULL) {
struct route_in6 ro;
int ret;
struct sctp_tcb *stcb = NULL;
@@ -10744,6 +10934,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
if (ro.ro_rt)
RTFREE(ro.ro_rt);
}
+#endif
SCTP_STAT_INCR(sctps_sendpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
}
@@ -10801,7 +10992,11 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
len += padlen;
}
val = sctp_calculate_sum(scm, NULL, 0);
+#ifdef INET6
mout = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr), 1, M_DONTWAIT, 1, MT_DATA);
+#else
+ mout = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1, MT_DATA);
+#endif
if (mout == NULL) {
sctp_m_freem(scm);
return;
@@ -10812,89 +11007,101 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
return;
}
ohdr->checksum = val;
- if (iph->ip_v == IPVERSION) {
- /* V4 */
- struct ip *out;
- sctp_route_t ro;
- struct sctp_tcb *stcb = NULL;
-
- SCTP_BUF_LEN(mout) = sizeof(struct ip);
- len += sizeof(struct ip);
-
- bzero(&ro, sizeof ro);
- out = mtod(mout, struct ip *);
- out->ip_v = iph->ip_v;
- out->ip_hl = (sizeof(struct ip) / 4);
- out->ip_tos = iph->ip_tos;
- out->ip_id = iph->ip_id;
- out->ip_off = 0;
- out->ip_ttl = MAXTTL;
- out->ip_p = IPPROTO_SCTP;
- out->ip_sum = 0;
- out->ip_src = iph->ip_dst;
- out->ip_dst = iph->ip_src;
- out->ip_len = len;
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* V4 */
+ struct ip *out;
+ sctp_route_t ro;
+ struct sctp_tcb *stcb = NULL;
+
+ SCTP_BUF_LEN(mout) = sizeof(struct ip);
+ len += sizeof(struct ip);
+
+ bzero(&ro, sizeof ro);
+ out = mtod(mout, struct ip *);
+ out->ip_v = iph->ip_v;
+ out->ip_hl = (sizeof(struct ip) / 4);
+ out->ip_tos = iph->ip_tos;
+ out->ip_id = iph->ip_id;
+ out->ip_off = 0;
+ out->ip_ttl = MAXTTL;
+ out->ip_p = IPPROTO_SCTP;
+ out->ip_sum = 0;
+ out->ip_src = iph->ip_dst;
+ out->ip_dst = iph->ip_src;
+ out->ip_len = len;
#ifdef SCTP_PACKET_LOGGING
- if (sctp_logging_level & SCTP_LAST_PACKET_TRACING)
- sctp_packet_log(mout, len);
+ if (sctp_logging_level & SCTP_LAST_PACKET_TRACING)
+ sctp_packet_log(mout, len);
#endif
- SCTP_ATTACH_CHAIN(o_pak, mout, len);
+ SCTP_ATTACH_CHAIN(o_pak, mout, len);
- SCTP_IP_OUTPUT(retcode, o_pak, &ro, stcb, vrf_id);
+ SCTP_IP_OUTPUT(retcode, o_pak, &ro, stcb, vrf_id);
- SCTP_STAT_INCR(sctps_sendpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
- /* Free the route if we got one back */
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
- } else {
- /* V6 */
- struct route_in6 ro;
- int ret;
- struct sctp_tcb *stcb = NULL;
- struct ifnet *ifp = NULL;
- struct ip6_hdr *out6, *in6;
-
- SCTP_BUF_LEN(mout) = sizeof(struct ip6_hdr);
- len += sizeof(struct ip6_hdr);
- bzero(&ro, sizeof ro);
- in6 = mtod(m, struct ip6_hdr *);
- out6 = mtod(mout, struct ip6_hdr *);
- out6->ip6_flow = in6->ip6_flow;
- out6->ip6_hlim = ip6_defhlim;
- out6->ip6_nxt = IPPROTO_SCTP;
- out6->ip6_src = in6->ip6_dst;
- out6->ip6_dst = in6->ip6_src;
- out6->ip6_plen = len - sizeof(struct ip6_hdr);
+ SCTP_STAT_INCR(sctps_sendpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
+ /* Free the route if we got one back */
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt);
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* V6 */
+ struct route_in6 ro;
+ int ret;
+ struct sctp_tcb *stcb = NULL;
+ struct ifnet *ifp = NULL;
+ struct ip6_hdr *out6, *in6;
+
+ SCTP_BUF_LEN(mout) = sizeof(struct ip6_hdr);
+ len += sizeof(struct ip6_hdr);
+ bzero(&ro, sizeof ro);
+ in6 = mtod(m, struct ip6_hdr *);
+ out6 = mtod(mout, struct ip6_hdr *);
+ out6->ip6_flow = in6->ip6_flow;
+ out6->ip6_hlim = ip6_defhlim;
+ out6->ip6_nxt = IPPROTO_SCTP;
+ out6->ip6_src = in6->ip6_dst;
+ out6->ip6_dst = in6->ip6_src;
+ out6->ip6_plen = len - sizeof(struct ip6_hdr);
#ifdef SCTP_DEBUG
- bzero(&lsa6, sizeof(lsa6));
- lsa6.sin6_len = sizeof(lsa6);
- lsa6.sin6_family = AF_INET6;
- lsa6.sin6_addr = out6->ip6_src;
- bzero(&fsa6, sizeof(fsa6));
- fsa6.sin6_len = sizeof(fsa6);
- fsa6.sin6_family = AF_INET6;
- fsa6.sin6_addr = out6->ip6_dst;
+ bzero(&lsa6, sizeof(lsa6));
+ lsa6.sin6_len = sizeof(lsa6);
+ lsa6.sin6_family = AF_INET6;
+ lsa6.sin6_addr = out6->ip6_src;
+ bzero(&fsa6, sizeof(fsa6));
+ fsa6.sin6_len = sizeof(fsa6);
+ fsa6.sin6_family = AF_INET6;
+ fsa6.sin6_addr = out6->ip6_dst;
#endif
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "sctp_operr_to calling ipv6 output:\n");
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "src: ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&lsa6);
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "dst ");
- SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&fsa6);
+ SCTPDBG(SCTP_DEBUG_OUTPUT2, "sctp_operr_to calling ipv6 output:\n");
+ SCTPDBG(SCTP_DEBUG_OUTPUT2, "src: ");
+ SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&lsa6);
+ SCTPDBG(SCTP_DEBUG_OUTPUT2, "dst ");
+ SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&fsa6);
#ifdef SCTP_PACKET_LOGGING
- if (sctp_logging_level & SCTP_LAST_PACKET_TRACING)
- sctp_packet_log(mout, len);
+ if (sctp_logging_level & SCTP_LAST_PACKET_TRACING)
+ sctp_packet_log(mout, len);
#endif
- SCTP_ATTACH_CHAIN(o_pak, mout, len);
- SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
-
- SCTP_STAT_INCR(sctps_sendpackets);
- SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
- /* Free the route if we got one back */
- if (ro.ro_rt)
- RTFREE(ro.ro_rt);
+ SCTP_ATTACH_CHAIN(o_pak, mout, len);
+ SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id);
+
+ SCTP_STAT_INCR(sctps_sendpackets);
+ SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
+ /* Free the route if we got one back */
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt);
+ break;
+ }
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
@@ -12479,6 +12686,7 @@ sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
return (m);
}
+#ifdef INET6
int
sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
{
@@ -12527,6 +12735,9 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is not installed\n");
return (0);
}
+
+#endif
+
int
sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t * ro)
{
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 25e5c79..7ad3f7f 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -51,6 +51,7 @@ struct sctp_epinfo sctppcbinfo;
/* FIX: we don't handle multiple link local scopes */
/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
+#ifdef INET6
int
SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
{
@@ -64,6 +65,8 @@ SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b)
return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b));
}
+#endif
+
void
sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb)
{
@@ -608,37 +611,47 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
sctp_ifap->flags = ifa_flags;
/* Set scope */
- if (sctp_ifap->address.sa.sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (sctp_ifap->address.sa.sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
- if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
- (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
- sctp_ifap->src_is_loop = 1;
- }
- if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
- sctp_ifap->src_is_priv = 1;
+ sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
+ if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
+ (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
+ sctp_ifap->src_is_loop = 1;
+ }
+ if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
+ sctp_ifap->src_is_priv = 1;
+ }
+ sctp_ifnp->num_v4++;
+ if (new_ifn_af)
+ new_ifn_af = AF_INET;
+ break;
}
- sctp_ifnp->num_v4++;
- if (new_ifn_af)
- new_ifn_af = AF_INET;
- } else if (sctp_ifap->address.sa.sa_family == AF_INET6) {
- /* ok to use deprecated addresses? */
- struct sockaddr_in6 *sin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ /* ok to use deprecated addresses? */
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
- if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
- (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
- sctp_ifap->src_is_loop = 1;
- }
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- sctp_ifap->src_is_priv = 1;
+ sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
+ if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
+ (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
+ sctp_ifap->src_is_loop = 1;
+ }
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ sctp_ifap->src_is_priv = 1;
+ }
+ sctp_ifnp->num_v6++;
+ if (new_ifn_af)
+ new_ifn_af = AF_INET6;
+ break;
}
- sctp_ifnp->num_v6++;
- if (new_ifn_af)
- new_ifn_af = AF_INET6;
- } else {
+#endif
+ default:
new_ifn_af = 0;
+ break;
}
hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa);
@@ -893,7 +906,9 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
match = 1;
break;
}
- } else {
+ }
+#ifdef INET6
+ if (from->sa_family == AF_INET6) {
struct sockaddr_in6 *intf_addr6;
struct sockaddr_in6 *sin6;
@@ -907,6 +922,7 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
break;
}
}
+#endif
}
}
if (match == 0) {
@@ -944,38 +960,56 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from,
/* not the same family, can't be a match */
continue;
}
- if (from->sa_family == AF_INET) {
- struct sockaddr_in *sin, *rsin;
-
- sin = (struct sockaddr_in *)&net->ro._l_addr;
- rsin = (struct sockaddr_in *)from;
- if (sin->sin_addr.s_addr ==
- rsin->sin_addr.s_addr) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
+ switch (from->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin, *rsin;
+
+ sin = (struct sockaddr_in *)&net->ro._l_addr;
+ rsin = (struct sockaddr_in *)from;
+ if (sin->sin_addr.s_addr ==
+ rsin->sin_addr.s_addr) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ /*
+ * Update the endpoint
+ * pointer
+ */
+ *inp_p = inp;
+ SCTP_INP_RUNLOCK(inp);
+ return (stcb);
}
- /* Update the endpoint pointer */
- *inp_p = inp;
- SCTP_INP_RUNLOCK(inp);
- return (stcb);
+ break;
}
- } else {
- struct sockaddr_in6 *sin6, *rsin6;
-
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- rsin6 = (struct sockaddr_in6 *)from;
- if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
- &rsin6->sin6_addr)) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6, *rsin6;
+
+ sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ rsin6 = (struct sockaddr_in6 *)from;
+ if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
+ &rsin6->sin6_addr)) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ /*
+ * Update the endpoint
+ * pointer
+ */
+ *inp_p = inp;
+ SCTP_INP_RUNLOCK(inp);
+ return (stcb);
}
- /* Update the endpoint pointer */
- *inp_p = inp;
- SCTP_INP_RUNLOCK(inp);
- return (stcb);
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -1076,53 +1110,67 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
/* not the same family */
continue;
}
- if (remote->sa_family == AF_INET) {
- struct sockaddr_in *sin, *rsin;
-
- sin = (struct sockaddr_in *)
- &net->ro._l_addr;
- rsin = (struct sockaddr_in *)remote;
- if (sin->sin_addr.s_addr ==
- rsin->sin_addr.s_addr) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ switch (remote->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin,
+ *rsin;
+
+ sin = (struct sockaddr_in *)
+ &net->ro._l_addr;
+ rsin = (struct sockaddr_in *)remote;
+ if (sin->sin_addr.s_addr ==
+ rsin->sin_addr.s_addr) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
- } else if (remote->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6, *rsin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6,
+ *rsin6;
- sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- rsin6 = (struct sockaddr_in6 *)remote;
- if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
- &rsin6->sin6_addr)) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
+ rsin6 = (struct sockaddr_in6 *)remote;
+ if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
+ &rsin6->sin6_addr)) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -1159,54 +1207,68 @@ sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote,
/* not the same family */
continue;
}
- if (remote->sa_family == AF_INET) {
- struct sockaddr_in *sin, *rsin;
-
- sin = (struct sockaddr_in *)
- &net->ro._l_addr;
- rsin = (struct sockaddr_in *)remote;
- if (sin->sin_addr.s_addr ==
- rsin->sin_addr.s_addr) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ switch (remote->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin,
+ *rsin;
+
+ sin = (struct sockaddr_in *)
+ &net->ro._l_addr;
+ rsin = (struct sockaddr_in *)remote;
+ if (sin->sin_addr.s_addr ==
+ rsin->sin_addr.s_addr) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
- } else if (remote->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6, *rsin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6,
+ *rsin6;
- sin6 = (struct sockaddr_in6 *)
- &net->ro._l_addr;
- rsin6 = (struct sockaddr_in6 *)remote;
- if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
- &rsin6->sin6_addr)) {
- /* found it */
- if (netp != NULL) {
- *netp = net;
- }
- if (locked_tcb == NULL) {
- SCTP_INP_DECR_REF(inp);
- } else if (locked_tcb != stcb) {
- SCTP_TCB_LOCK(locked_tcb);
- }
- if (locked_tcb) {
- atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ sin6 = (struct sockaddr_in6 *)
+ &net->ro._l_addr;
+ rsin6 = (struct sockaddr_in6 *)remote;
+ if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
+ &rsin6->sin6_addr)) {
+ /* found it */
+ if (netp != NULL) {
+ *netp = net;
+ }
+ if (locked_tcb == NULL) {
+ SCTP_INP_DECR_REF(inp);
+ } else if (locked_tcb != stcb) {
+ SCTP_TCB_LOCK(locked_tcb);
+ }
+ if (locked_tcb) {
+ atomic_subtract_int(&locked_tcb->asoc.refcnt, 1);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ SCTP_INP_INFO_RUNLOCK();
+ return (stcb);
}
- SCTP_INP_WUNLOCK(inp);
- SCTP_INP_INFO_RUNLOCK();
- return (stcb);
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
SCTP_TCB_UNLOCK(stcb);
@@ -1332,20 +1394,37 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
{
struct sctp_inpcb *inp;
struct sockaddr_in *sin;
+
+#ifdef INET6
struct sockaddr_in6 *sin6;
+
+#endif
struct sctp_laddr *laddr;
+
+#ifdef INET6
+ struct sockaddr_in6 *intf_addr6;
+
+#endif
+
int fnd;
/*
* Endpoing probe expects that the INP_INFO is locked.
*/
- if (nam->sa_family == AF_INET) {
+ sin = NULL;
+#ifdef INET6
+ sin6 = NULL;
+#endif
+ switch (nam->sa_family) {
+ case AF_INET:
sin = (struct sockaddr_in *)nam;
- sin6 = NULL;
- } else if (nam->sa_family == AF_INET6) {
+ break;
+#ifdef INET6
+ case AF_INET6:
sin6 = (struct sockaddr_in6 *)nam;
- sin = NULL;
- } else {
+ break;
+#endif
+ default:
/* unsupported family */
return (NULL);
}
@@ -1390,11 +1469,14 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
(sin->sin_addr.s_addr == INADDR_ANY)) {
/* Can't hunt for one that has no address specified */
return (NULL);
- } else if ((nam->sa_family == AF_INET6) &&
+ }
+#ifdef INET6
+ if ((nam->sa_family == AF_INET6) &&
(IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))) {
/* Can't hunt for one that has no address specified */
return (NULL);
}
+#endif
/*
* ok, not bound to all so see if we can find a EP bound to this
* address.
@@ -1443,21 +1525,24 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head,
struct sockaddr_in *intf_addr;
intf_addr = &laddr->ifa->address.sin;
- if (nam->sa_family == AF_INET) {
+ switch (nam->sa_family) {
+ case AF_INET:
if (sin->sin_addr.s_addr ==
intf_addr->sin_addr.s_addr) {
SCTP_INP_RUNLOCK(inp);
return (inp);
}
- } else if (nam->sa_family == AF_INET6) {
- struct sockaddr_in6 *intf_addr6;
-
+ break;
+#ifdef INET6
+ case AF_INET6:
intf_addr6 = &laddr->ifa->address.sin6;
if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr,
&intf_addr6->sin6_addr)) {
SCTP_INP_RUNLOCK(inp);
return (inp);
}
+ break;
+#endif
}
}
}
@@ -1774,33 +1859,42 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
struct sctp_inpcb *inp;
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *from4;
-
- from4 = (struct sockaddr_in *)&from_store;
- bzero(from4, sizeof(*from4));
- from4->sin_family = AF_INET;
- from4->sin_len = sizeof(struct sockaddr_in);
- from4->sin_addr.s_addr = iph->ip_src.s_addr;
- from4->sin_port = sh->src_port;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *from6;
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *from4;
+
+ from4 = (struct sockaddr_in *)&from_store;
+ bzero(from4, sizeof(*from4));
+ from4->sin_family = AF_INET;
+ from4->sin_len = sizeof(struct sockaddr_in);
+ from4->sin_addr.s_addr = iph->ip_src.s_addr;
+ from4->sin_port = sh->src_port;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *from6;
- ip6 = mtod(m, struct ip6_hdr *);
- from6 = (struct sockaddr_in6 *)&from_store;
- bzero(from6, sizeof(*from6));
- from6->sin6_family = AF_INET6;
- from6->sin6_len = sizeof(struct sockaddr_in6);
- from6->sin6_addr = ip6->ip6_src;
- from6->sin6_port = sh->src_port;
- /* Get the scopes in properly to the sin6 addr's */
- /* we probably don't need these operations */
- (void)sa6_recoverscope(from6);
- sa6_embedscope(from6, ip6_use_defzone);
- } else {
+ ip6 = mtod(m, struct ip6_hdr *);
+ from6 = (struct sockaddr_in6 *)&from_store;
+ bzero(from6, sizeof(*from6));
+ from6->sin6_family = AF_INET6;
+ from6->sin6_len = sizeof(struct sockaddr_in6);
+ from6->sin6_addr = ip6->ip6_src;
+ from6->sin6_port = sh->src_port;
+ /* Get the scopes in properly to the sin6 addr's */
+ /* we probably don't need these operations */
+ (void)sa6_recoverscope(from6);
+ sa6_embedscope(from6, ip6_use_defzone);
+ break;
+ }
+#endif
+ default:
/* Currently not supported. */
return (NULL);
}
@@ -1812,32 +1906,44 @@ sctp_findassociation_addr(struct mbuf *m, int iphlen, int offset,
return (retval);
}
}
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *to4;
-
- to4 = (struct sockaddr_in *)&to_store;
- bzero(to4, sizeof(*to4));
- to4->sin_family = AF_INET;
- to4->sin_len = sizeof(struct sockaddr_in);
- to4->sin_addr.s_addr = iph->ip_dst.s_addr;
- to4->sin_port = sh->dest_port;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *to6;
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *to4;
+
+ to4 = (struct sockaddr_in *)&to_store;
+ bzero(to4, sizeof(*to4));
+ to4->sin_family = AF_INET;
+ to4->sin_len = sizeof(struct sockaddr_in);
+ to4->sin_addr.s_addr = iph->ip_dst.s_addr;
+ to4->sin_port = sh->dest_port;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *to6;
- ip6 = mtod(m, struct ip6_hdr *);
- to6 = (struct sockaddr_in6 *)&to_store;
- bzero(to6, sizeof(*to6));
- to6->sin6_family = AF_INET6;
- to6->sin6_len = sizeof(struct sockaddr_in6);
- to6->sin6_addr = ip6->ip6_dst;
- to6->sin6_port = sh->dest_port;
- /* Get the scopes in properly to the sin6 addr's */
- /* we probably don't need these operations */
- (void)sa6_recoverscope(to6);
- sa6_embedscope(to6, ip6_use_defzone);
+ ip6 = mtod(m, struct ip6_hdr *);
+ to6 = (struct sockaddr_in6 *)&to_store;
+ bzero(to6, sizeof(*to6));
+ to6->sin6_family = AF_INET6;
+ to6->sin6_len = sizeof(struct sockaddr_in6);
+ to6->sin6_addr = ip6->ip6_dst;
+ to6->sin6_port = sh->dest_port;
+ /* Get the scopes in properly to the sin6 addr's */
+ /* we probably don't need these operations */
+ (void)sa6_recoverscope(to6);
+ sa6_embedscope(to6, ip6_use_defzone);
+ break;
+ }
+#endif
+ default:
+ /* TSNH */
+ break;
}
find_tcp_pool = 0;
if ((ch->chunk_type != SCTP_INITIATION) &&
@@ -1895,9 +2001,18 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
{
struct sctp_tcb *stcb;
struct sockaddr_in *sin;
+
+#ifdef INET6
struct sockaddr_in6 *sin6;
+
+#endif
struct sockaddr_storage local_store, remote_store;
struct ip *iph;
+
+#ifdef INET6
+ struct ip6_hdr *ip6;
+
+#endif
struct sctp_paramhdr parm_buf, *phdr;
int ptype;
int zero_address = 0;
@@ -1908,24 +2023,27 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
+ switch (iph->ip_v) {
+ case IPVERSION:
/* its IPv4 */
sin = (struct sockaddr_in *)&local_store;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
sin->sin_port = sh->dest_port;
sin->sin_addr.s_addr = iph->ip_dst.s_addr;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
/* its IPv6 */
- struct ip6_hdr *ip6;
-
ip6 = mtod(m, struct ip6_hdr *);
sin6 = (struct sockaddr_in6 *)&local_store;
sin6->sin6_family = AF_INET6;
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_port = sh->dest_port;
sin6->sin6_addr = ip6->ip6_dst;
- } else {
+ break;
+#endif
+ default:
return NULL;
}
@@ -1938,51 +2056,60 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int iphlen, int offset,
}
ptype = (int)((uint32_t) ntohs(phdr->param_type));
/* get the correlation address */
- if (ptype == SCTP_IPV6_ADDRESS) {
- /* ipv6 address param */
- struct sctp_ipv6addr_param *p6, p6_buf;
-
- if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
- return NULL;
- }
- p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
- offset + sizeof(struct sctp_asconf_chunk),
- &p6_buf.ph, sizeof(*p6));
- if (p6 == NULL) {
- SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v6 lookup addr\n",
- __FUNCTION__);
- return (NULL);
+ switch (ptype) {
+#ifdef INET6
+ case SCTP_IPV6_ADDRESS:
+ {
+ /* ipv6 address param */
+ struct sctp_ipv6addr_param *p6, p6_buf;
+
+ if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv6addr_param)) {
+ return NULL;
+ }
+ p6 = (struct sctp_ipv6addr_param *)sctp_get_next_param(m,
+ offset + sizeof(struct sctp_asconf_chunk),
+ &p6_buf.ph, sizeof(*p6));
+ if (p6 == NULL) {
+ SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v6 lookup addr\n",
+ __FUNCTION__);
+ return (NULL);
+ }
+ sin6 = (struct sockaddr_in6 *)&remote_store;
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_port = sh->src_port;
+ memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
+ zero_address = 1;
+ break;
}
- sin6 = (struct sockaddr_in6 *)&remote_store;
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(*sin6);
- sin6->sin6_port = sh->src_port;
- memcpy(&sin6->sin6_addr, &p6->addr, sizeof(struct in6_addr));
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
- zero_address = 1;
- } else if (ptype == SCTP_IPV4_ADDRESS) {
- /* ipv4 address param */
- struct sctp_ipv4addr_param *p4, p4_buf;
-
- if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
- return NULL;
- }
- p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
- offset + sizeof(struct sctp_asconf_chunk),
- &p4_buf.ph, sizeof(*p4));
- if (p4 == NULL) {
- SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v4 lookup addr\n",
- __FUNCTION__);
- return (NULL);
+#endif
+ case SCTP_IPV4_ADDRESS:
+ {
+ /* ipv4 address param */
+ struct sctp_ipv4addr_param *p4, p4_buf;
+
+ if (ntohs(phdr->param_length) != sizeof(struct sctp_ipv4addr_param)) {
+ return NULL;
+ }
+ p4 = (struct sctp_ipv4addr_param *)sctp_get_next_param(m,
+ offset + sizeof(struct sctp_asconf_chunk),
+ &p4_buf.ph, sizeof(*p4));
+ if (p4 == NULL) {
+ SCTPDBG(SCTP_DEBUG_INPUT3, "%s: failed to get asconf v4 lookup addr\n",
+ __FUNCTION__);
+ return (NULL);
+ }
+ sin = (struct sockaddr_in *)&remote_store;
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = sh->src_port;
+ memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
+ if (sin->sin_addr.s_addr == INADDR_ANY)
+ zero_address = 1;
+ break;
}
- sin = (struct sockaddr_in *)&remote_store;
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_port = sh->src_port;
- memcpy(&sin->sin_addr, &p4->addr, sizeof(struct in_addr));
- if (sin->sin_addr.s_addr == INADDR_ANY)
- zero_address = 1;
- } else {
+ default:
/* invalid address param type */
return NULL;
}
@@ -2416,62 +2543,76 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
prison = 1;
}
if (addr != NULL) {
- if (addr->sa_family == AF_INET) {
- struct sockaddr_in *sin;
+ switch (addr->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
- /* IPV6_V6ONLY socket? */
- if (SCTP_IPV6_V6ONLY(ip_inp)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
- }
- if (addr->sa_len != sizeof(*sin)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
- }
- sin = (struct sockaddr_in *)addr;
- lport = sin->sin_port;
- if (prison) {
- /*
- * For INADDR_ANY and LOOPBACK the
- * prison_ip() call will transmute the ip
- * address to the proper value (i.e. the IP
- * address owned by the jail).
- */
- if (prison_ip(p->td_ucred, 0, &sin->sin_addr.s_addr)) {
+ /* IPV6_V6ONLY socket? */
+ if (SCTP_IPV6_V6ONLY(ip_inp)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
return (EINVAL);
}
+ if (addr->sa_len != sizeof(*sin)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ return (EINVAL);
+ }
+ sin = (struct sockaddr_in *)addr;
+ lport = sin->sin_port;
+ if (prison) {
+ /*
+ * For INADDR_ANY and LOOPBACK the
+ * prison_ip() call will transmute
+ * the ip address to the proper
+ * value (i.e. the IP address owned
+ * by the jail).
+ */
+ if (prison_ip(p->td_ucred, 0, &sin->sin_addr.s_addr)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ return (EINVAL);
+ }
+ }
+ if (sin->sin_addr.s_addr != INADDR_ANY) {
+ bindall = 0;
+ }
+ break;
}
- if (sin->sin_addr.s_addr != INADDR_ANY) {
- bindall = 0;
- }
- } else if (addr->sa_family == AF_INET6) {
- /* Only for pure IPv6 Address. (No IPv4 Mapped!) */
- struct sockaddr_in6 *sin6;
+#ifdef INET6
+ case AF_INET6:
+ {
+ /*
+ * Only for pure IPv6 Address. (No IPv4
+ * Mapped!)
+ */
+ struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)addr;
+ sin6 = (struct sockaddr_in6 *)addr;
- if (addr->sa_len != sizeof(*sin6)) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
- return (EINVAL);
- }
- lport = sin6->sin6_port;
- /*
- * Jail checks for IPv6 should go HERE! i.e. add the
- * prison_ip() equivilant in this postion to
- * transmute the addresses to the proper one jailed.
- */
- if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- bindall = 0;
- /* KAME hack: embed scopeid */
- if (sa6_embedscope(sin6, ip6_use_defzone) != 0) {
+ if (addr->sa_len != sizeof(*sin6)) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
return (EINVAL);
}
+ lport = sin6->sin6_port;
+ /*
+ * Jail checks for IPv6 should go HERE! i.e.
+ * add the prison_ip() equivilant in this
+ * postion to transmute the addresses to the
+ * proper one jailed.
+ */
+ if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ bindall = 0;
+ /* KAME hack: embed scopeid */
+ if (sa6_embedscope(sin6, ip6_use_defzone) != 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
+ return (EINVAL);
+ }
+ }
+ /* this must be cleared for ifa_ifwithaddr() */
+ sin6->sin6_scope_id = 0;
+ break;
}
- /* this must be cleared for ifa_ifwithaddr() */
- sin6->sin6_scope_id = 0;
- } else {
+#endif
+ default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EAFNOSUPPORT);
return (EAFNOSUPPORT);
}
@@ -3472,6 +3613,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
/* Now generate a route for this guy */
+#ifdef INET6
/* KAME hack: embed scopeid */
if (newaddr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
@@ -3480,14 +3622,17 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
(void)sa6_embedscope(sin6, ip6_use_defzone);
sin6->sin6_scope_id = 0;
}
+#endif
SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id);
+#ifdef INET6
if (newaddr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
(void)sa6_recoverscope(sin6);
}
+#endif
if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
/* Get source address */
net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
@@ -5205,33 +5350,43 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sin6.sin6_port = stcb->rport;
if (altsa == NULL) {
iph = mtod(m, struct ip *);
- if (iph->ip_v == IPVERSION) {
- /* its IPv4 */
- struct sockaddr_in *sin_2;
-
- sin_2 = (struct sockaddr_in *)(local_sa);
- memset(sin_2, 0, sizeof(sin));
- sin_2->sin_family = AF_INET;
- sin_2->sin_len = sizeof(sin);
- sin_2->sin_port = sh->dest_port;
- sin_2->sin_addr.s_addr = iph->ip_dst.s_addr;
- sin.sin_addr = iph->ip_src;
- sa = (struct sockaddr *)&sin;
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- /* its IPv6 */
- struct ip6_hdr *ip6;
- struct sockaddr_in6 *sin6_2;
-
- ip6 = mtod(m, struct ip6_hdr *);
- sin6_2 = (struct sockaddr_in6 *)(local_sa);
- memset(sin6_2, 0, sizeof(sin6));
- sin6_2->sin6_family = AF_INET6;
- sin6_2->sin6_len = sizeof(struct sockaddr_in6);
- sin6_2->sin6_port = sh->dest_port;
- sin6.sin6_addr = ip6->ip6_src;
- sa = (struct sockaddr *)&sin6;
- } else {
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ /* its IPv4 */
+ struct sockaddr_in *sin_2;
+
+ sin_2 = (struct sockaddr_in *)(local_sa);
+ memset(sin_2, 0, sizeof(sin));
+ sin_2->sin_family = AF_INET;
+ sin_2->sin_len = sizeof(sin);
+ sin_2->sin_port = sh->dest_port;
+ sin_2->sin_addr.s_addr = iph->ip_dst.s_addr;
+ sin.sin_addr = iph->ip_src;
+ sa = (struct sockaddr *)&sin;
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ /* its IPv6 */
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *sin6_2;
+
+ ip6 = mtod(m, struct ip6_hdr *);
+ sin6_2 = (struct sockaddr_in6 *)(local_sa);
+ memset(sin6_2, 0, sizeof(sin6));
+ sin6_2->sin6_family = AF_INET6;
+ sin6_2->sin6_len = sizeof(struct sockaddr_in6);
+ sin6_2->sin6_port = sh->dest_port;
+ sin6.sin6_addr = ip6->ip6_src;
+ sa = (struct sockaddr *)&sin6;
+ break;
+ }
+#endif
+ default:
sa = NULL;
+ break;
}
} else {
/*
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index 65e4b50..44ac300 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -434,8 +434,11 @@ struct sctp_tcb {
extern struct sctp_epinfo sctppcbinfo;
+#ifdef INET6
int SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b);
+#endif
+
void sctp_fill_pcbinfo(struct sctp_pcbinfo *);
struct sctp_ifn *
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index fd232d9..b428029 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -206,36 +206,51 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
if (sctp_is_addr_restricted(stcb, sctp_ifa))
continue;
}
- if ((sctp_ifa->address.sa.sa_family == AF_INET) && (ipv4_addr_legal)) {
- struct sockaddr_in *sin;
+ switch (sctp_ifa->address.sa.sa_family) {
+ case AF_INET:
+ if (ipv4_addr_legal) {
+ struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
- if (sin->sin_addr.s_addr == 0)
- continue;
- if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)))
- continue;
- } else if ((sctp_ifa->address.sa.sa_family == AF_INET6) && (ipv6_addr_legal)) {
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
+ sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ if (sin->sin_addr.s_addr == 0)
+ continue;
+ if ((ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)))
+ continue;
+ } else {
continue;
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- if (local_scope == 0)
+ }
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (ipv6_addr_legal) {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
continue;
- if (sin6->sin6_scope_id == 0) {
- /*
- * bad link local
- * address
- */
- if (sa6_recoverscope(sin6) != 0)
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ if (local_scope == 0)
continue;
+ if (sin6->sin6_scope_id == 0) {
+ /*
+ * bad link
+ * local
+ * address
+ */
+ if (sa6_recoverscope(sin6) != 0)
+ continue;
+ }
}
- }
- if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)))
+ if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)))
+ continue;
+ } else {
continue;
- } else
+ }
+ break;
+#endif
+ default:
continue;
+ }
memset((void *)&xladdr, 0, sizeof(struct xsctp_laddr));
memcpy((void *)&xladdr.address, (const void *)&sctp_ifa->address, sizeof(union sctp_sockstore));
SCTP_INP_RUNLOCK(inp);
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 62cdeab..1be19f9 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -1089,10 +1089,12 @@ skip_unlock:
static uint32_t
sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa)
{
+#ifdef INET6
struct sockaddr_in6 lsa6;
sa = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)sa,
&lsa6);
+#endif
memcpy(ss, sa, sa->sa_len);
return (0);
}
@@ -1166,72 +1168,101 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
continue;
}
}
- if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
- (ipv4_addr_legal)) {
- struct sockaddr_in *sin;
-
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
- if (sin->sin_addr.s_addr == 0) {
- /*
- * we skip unspecifed
- * addresses
- */
- continue;
- }
- if ((ipv4_local_scope == 0) &&
- (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
- continue;
- }
- if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) {
- in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
- ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
- sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
- actual += sizeof(struct sockaddr_in6);
+ switch (sctp_ifa->address.sa.sa_family) {
+ case AF_INET:
+ if (ipv4_addr_legal) {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ if (sin->sin_addr.s_addr == 0) {
+ /*
+ * we skip
+ * unspecifed
+ * addresses
+ */
+ continue;
+ }
+ if ((ipv4_local_scope == 0) &&
+ (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
+ continue;
+ }
+#ifdef INET6
+ if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
+ in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)sas);
+ ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
+ sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6));
+ actual += sizeof(struct sockaddr_in6);
+ } else {
+#endif
+ memcpy(sas, sin, sizeof(*sin));
+ ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
+ sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin));
+ actual += sizeof(*sin);
+#ifdef INET6
+ }
+#endif
+ if (actual >= limit) {
+ return (actual);
+ }
} else {
- memcpy(sas, sin, sizeof(*sin));
- ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport;
- sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin));
- actual += sizeof(*sin);
- }
- if (actual >= limit) {
- return (actual);
- }
- } else if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
- (ipv6_addr_legal)) {
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- /*
- * we skip unspecifed
- * addresses
- */
continue;
}
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- if (local_scope == 0)
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (ipv6_addr_legal) {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * we skip
+ * unspecifed
+ * addresses
+ */
continue;
- if (sin6->sin6_scope_id == 0) {
- if (sa6_recoverscope(sin6) != 0)
- /*
- * bad link
- * local
- * address
- */
+ }
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ if (local_scope == 0)
continue;
+ if (sin6->sin6_scope_id == 0) {
+ if (sa6_recoverscope(sin6) != 0)
+ /*
+ *
+ * bad
+ *
+ * li
+ * nk
+ *
+ * loc
+ * al
+ *
+ * add
+ * re
+ * ss
+ * */
+ continue;
+ }
}
- }
- if ((site_scope == 0) &&
- (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
+ if ((site_scope == 0) &&
+ (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
+ continue;
+ }
+ memcpy(sas, sin6, sizeof(*sin6));
+ ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
+ sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6));
+ actual += sizeof(*sin6);
+ if (actual >= limit) {
+ return (actual);
+ }
+ } else {
continue;
}
- memcpy(sas, sin6, sizeof(*sin6));
- ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport;
- sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(*sin6));
- actual += sizeof(*sin6);
- if (actual >= limit) {
- return (actual);
- }
+ break;
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
}
@@ -1303,7 +1334,7 @@ sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
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) {
- if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
+ if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
cnt += sizeof(struct sockaddr_in6);
else
cnt += sizeof(struct sockaddr_in);
@@ -1317,7 +1348,7 @@ sctp_count_max_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
if (laddr->ifa->address.sa.sa_family == AF_INET) {
- if (inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)
+ if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
cnt += sizeof(struct sockaddr_in6);
else
cnt += sizeof(struct sockaddr_in);
@@ -1972,7 +2003,7 @@ flags_out:
size = 0;
/* Count the sizes */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
+ if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) ||
(((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
size += sizeof(struct sockaddr_in6);
} else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
@@ -2011,7 +2042,7 @@ flags_out:
sas = (struct sockaddr_storage *)&saddr->addr[0];
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) ||
+ if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) ||
(((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET6)) {
cpsz = sizeof(struct sockaddr_in6);
} else if (((struct sockaddr *)&net->ro._l_addr)->sa_family == AF_INET) {
@@ -2024,14 +2055,18 @@ flags_out:
/* not enough room. */
break;
}
- if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
+#ifdef 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 */
in6_sin_2_v4mapsin6((struct sockaddr_in *)&net->ro._l_addr,
(struct sockaddr_in6 *)sas);
} else {
+#endif
memcpy(sas, &net->ro._l_addr, cpsz);
+#ifdef INET6
}
+#endif
((struct sockaddr_in *)sas)->sin_port = stcb->rport;
sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
@@ -4214,8 +4249,10 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
struct sctp_inpcb *inp;
union sctp_sockstore store;
+#ifdef INET6
int error;
+#endif
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == 0) {
@@ -4243,29 +4280,41 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
SCTP_INP_RUNLOCK(inp);
store = stcb->asoc.primary_destination->ro._l_addr;
SCTP_TCB_UNLOCK(stcb);
- if (store.sa.sa_family == AF_INET) {
- struct sockaddr_in *sin;
-
- SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
- sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
- *addr = (struct sockaddr *)sin;
- } else {
- struct sockaddr_in6 *sin6;
+ switch (store.sa.sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
+
+ SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
+ sin->sin_family = AF_INET;
+ sin->sin_len = sizeof(*sin);
+ sin->sin_port = ((struct sockaddr_in *)&store)->sin_port;
+ sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr;
+ *addr = (struct sockaddr *)sin;
+ break;
+ }
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(*sin6);
- sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
+ SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
+ sin6->sin6_family = AF_INET6;
+ sin6->sin6_len = sizeof(*sin6);
+ sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port;
- sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
- if ((error = sa6_recoverscope(sin6)) != 0) {
- SCTP_FREE_SONAME(sin6);
- return (error);
+ sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr;
+ if ((error = sa6_recoverscope(sin6)) != 0) {
+ SCTP_FREE_SONAME(sin6);
+ return (error);
+ }
+ *addr = (struct sockaddr *)sin6;
+ break;
}
- *addr = (struct sockaddr *)sin6;
+#endif
+ default:
+ /* TSNH */
+ break;
}
/* Wake any delayed sleep action */
if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index e977690..cae00b0 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -306,9 +306,7 @@ void sctp_init __P((void));
void sctp_pcbinfo_cleanup(void);
-
int sctp_flush(struct socket *, int);
-
int sctp_shutdown __P((struct socket *));
void sctp_notify
__P((struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 25b2f92..ac7c51a 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -3029,23 +3029,33 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
spc->spc_type = SCTP_PEER_ADDR_CHANGE;
spc->spc_flags = 0;
spc->spc_length = sizeof(struct sctp_paddr_change);
- if (sa->sa_family == AF_INET) {
+ switch (sa->sa_family) {
+ case AF_INET:
memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in));
- } else {
- struct sockaddr_in6 *sin6;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
+ memcpy(&spc->spc_aaddr, sa, sizeof(struct sockaddr_in6));
- sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
- if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
- if (sin6->sin6_scope_id == 0) {
- /* recover scope_id for user */
- (void)sa6_recoverscope(sin6);
- } else {
- /* clear embedded scope_id for user */
- in6_clearscope(&sin6->sin6_addr);
+ sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
+ if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
+ if (sin6->sin6_scope_id == 0) {
+ /* recover scope_id for user */
+ (void)sa6_recoverscope(sin6);
+ } else {
+ /* clear embedded scope_id for user */
+ in6_clearscope(&sin6->sin6_addr);
+ }
}
+ break;
}
+#endif
+ default:
+ /* TSNH */
+ break;
}
spc->spc_state = state;
spc->spc_error = error;
@@ -4048,6 +4058,7 @@ sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t * vtagfill)
* currently (2/02), ifa_addr embeds scope_id's and don't have sin6_scope_id
* set (i.e. it's 0) so, create this function to compare link local scopes
*/
+#ifdef INET6
uint32_t
sctp_is_same_scope(struct sockaddr_in6 *addr1, struct sockaddr_in6 *addr2)
{
@@ -4097,6 +4108,8 @@ sctp_recover_scope(struct sockaddr_in6 *addr, struct sockaddr_in6 *store)
return (addr);
}
+#endif
+
/*
* are the two addresses the same? currently a "scopeless" check returns: 1
* if same, 0 if not
@@ -4113,22 +4126,29 @@ sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2)
if (sa1->sa_family != sa2->sa_family)
return (0);
- if (sa1->sa_family == AF_INET6) {
- /* IPv6 addresses */
- struct sockaddr_in6 *sin6_1, *sin6_2;
-
- sin6_1 = (struct sockaddr_in6 *)sa1;
- sin6_2 = (struct sockaddr_in6 *)sa2;
- return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
- &sin6_2->sin6_addr));
- } else if (sa1->sa_family == AF_INET) {
- /* IPv4 addresses */
- struct sockaddr_in *sin_1, *sin_2;
-
- sin_1 = (struct sockaddr_in *)sa1;
- sin_2 = (struct sockaddr_in *)sa2;
- return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
- } else {
+ switch (sa1->sa_family) {
+#ifdef INET6
+ case AF_INET6:
+ {
+ /* IPv6 addresses */
+ struct sockaddr_in6 *sin6_1, *sin6_2;
+
+ sin6_1 = (struct sockaddr_in6 *)sa1;
+ sin6_2 = (struct sockaddr_in6 *)sa2;
+ return (SCTP6_ARE_ADDR_EQUAL(&sin6_1->sin6_addr,
+ &sin6_2->sin6_addr));
+ }
+#endif
+ case AF_INET:
+ {
+ /* IPv4 addresses */
+ struct sockaddr_in *sin_1, *sin_2;
+
+ sin_1 = (struct sockaddr_in *)sa1;
+ sin_2 = (struct sockaddr_in *)sa2;
+ return (sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr);
+ }
+ default:
/* we don't do these... */
return (0);
}
@@ -4137,69 +4157,94 @@ sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2)
void
sctp_print_address(struct sockaddr *sa)
{
+#ifdef INET6
char ip6buf[INET6_ADDRSTRLEN];
ip6buf[0] = 0;
- if (sa->sa_family == AF_INET6) {
- struct sockaddr_in6 *sin6;
+#endif
- sin6 = (struct sockaddr_in6 *)sa;
- SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
- ip6_sprintf(ip6buf, &sin6->sin6_addr),
- ntohs(sin6->sin6_port),
- sin6->sin6_scope_id);
- } else if (sa->sa_family == AF_INET) {
- struct sockaddr_in *sin;
- unsigned char *p;
+ switch (sa->sa_family) {
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
- sin = (struct sockaddr_in *)sa;
- p = (unsigned char *)&sin->sin_addr;
- SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n",
- p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
- } else {
+ sin6 = (struct sockaddr_in6 *)sa;
+ SCTP_PRINTF("IPv6 address: %s:port:%d scope:%u\n",
+ ip6_sprintf(ip6buf, &sin6->sin6_addr),
+ ntohs(sin6->sin6_port),
+ sin6->sin6_scope_id);
+ break;
+ }
+#endif
+ case AF_INET:
+ {
+ struct sockaddr_in *sin;
+ unsigned char *p;
+
+ sin = (struct sockaddr_in *)sa;
+ p = (unsigned char *)&sin->sin_addr;
+ SCTP_PRINTF("IPv4 address: %u.%u.%u.%u:%d\n",
+ p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
+ break;
+ }
+ default:
SCTP_PRINTF("?\n");
+ break;
}
}
void
sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
{
- if (iph->ip_v == IPVERSION) {
- struct sockaddr_in lsa, fsa;
-
- bzero(&lsa, sizeof(lsa));
- lsa.sin_len = sizeof(lsa);
- lsa.sin_family = AF_INET;
- lsa.sin_addr = iph->ip_src;
- lsa.sin_port = sh->src_port;
- bzero(&fsa, sizeof(fsa));
- fsa.sin_len = sizeof(fsa);
- fsa.sin_family = AF_INET;
- fsa.sin_addr = iph->ip_dst;
- fsa.sin_port = sh->dest_port;
- SCTP_PRINTF("src: ");
- sctp_print_address((struct sockaddr *)&lsa);
- SCTP_PRINTF("dest: ");
- sctp_print_address((struct sockaddr *)&fsa);
- } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
- struct ip6_hdr *ip6;
- struct sockaddr_in6 lsa6, fsa6;
-
- ip6 = (struct ip6_hdr *)iph;
- bzero(&lsa6, sizeof(lsa6));
- lsa6.sin6_len = sizeof(lsa6);
- lsa6.sin6_family = AF_INET6;
- lsa6.sin6_addr = ip6->ip6_src;
- lsa6.sin6_port = sh->src_port;
- bzero(&fsa6, sizeof(fsa6));
- fsa6.sin6_len = sizeof(fsa6);
- fsa6.sin6_family = AF_INET6;
- fsa6.sin6_addr = ip6->ip6_dst;
- fsa6.sin6_port = sh->dest_port;
- SCTP_PRINTF("src: ");
- sctp_print_address((struct sockaddr *)&lsa6);
- SCTP_PRINTF("dest: ");
- sctp_print_address((struct sockaddr *)&fsa6);
+ switch (iph->ip_v) {
+ case IPVERSION:
+ {
+ struct sockaddr_in lsa, fsa;
+
+ bzero(&lsa, sizeof(lsa));
+ lsa.sin_len = sizeof(lsa);
+ lsa.sin_family = AF_INET;
+ lsa.sin_addr = iph->ip_src;
+ lsa.sin_port = sh->src_port;
+ bzero(&fsa, sizeof(fsa));
+ fsa.sin_len = sizeof(fsa);
+ fsa.sin_family = AF_INET;
+ fsa.sin_addr = iph->ip_dst;
+ fsa.sin_port = sh->dest_port;
+ SCTP_PRINTF("src: ");
+ sctp_print_address((struct sockaddr *)&lsa);
+ SCTP_PRINTF("dest: ");
+ sctp_print_address((struct sockaddr *)&fsa);
+ break;
+ }
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 lsa6, fsa6;
+
+ ip6 = (struct ip6_hdr *)iph;
+ bzero(&lsa6, sizeof(lsa6));
+ lsa6.sin6_len = sizeof(lsa6);
+ lsa6.sin6_family = AF_INET6;
+ lsa6.sin6_addr = ip6->ip6_src;
+ lsa6.sin6_port = sh->src_port;
+ bzero(&fsa6, sizeof(fsa6));
+ fsa6.sin6_len = sizeof(fsa6);
+ fsa6.sin6_family = AF_INET6;
+ fsa6.sin6_addr = ip6->ip6_dst;
+ fsa6.sin6_port = sh->dest_port;
+ SCTP_PRINTF("src: ");
+ sctp_print_address((struct sockaddr *)&lsa6);
+ SCTP_PRINTF("dest: ");
+ sctp_print_address((struct sockaddr *)&fsa6);
+ break;
+ }
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
@@ -4723,7 +4768,9 @@ sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
return (laddr->ifa);
break;
}
- } else if (addr->sa_family == AF_INET6) {
+ }
+#ifdef INET6
+ if (addr->sa_family == AF_INET6) {
if (SCTP6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr,
&laddr->ifa->address.sin6.sin6_addr)) {
/* found him. */
@@ -4734,6 +4781,7 @@ sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr,
break;
}
}
+#endif
}
if (holds_lock == 0) {
SCTP_INP_RUNLOCK(inp);
@@ -4810,7 +4858,9 @@ sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
return (sctp_ifap);
break;
}
- } else if (addr->sa_family == AF_INET6) {
+ }
+#ifdef INET6
+ if (addr->sa_family == AF_INET6) {
if (SCTP6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr,
&sctp_ifap->address.sin6.sin6_addr)) {
/* found him. */
@@ -4820,6 +4870,7 @@ sctp_find_ifa_by_addr(struct sockaddr *addr, uint32_t vrf_id, int holds_lock)
break;
}
}
+#endif
}
if (holds_lock == 0)
SCTP_IPI_ADDR_RUNLOCK();
@@ -5399,7 +5450,7 @@ found_one:
to = from;
#if defined(INET) && defined(INET6)
- if ((inp->sctp_flags & SCTP_PCB_FLAGS_NEEDS_MAPPED_V4) &&
+ if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
(to->sa_family == AF_INET) &&
((size_t)fromlen >= sizeof(struct sockaddr_in6))) {
struct sockaddr_in *sin;
@@ -5409,10 +5460,10 @@ found_one:
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_addr.s6_addr16[2] = 0xffff;
+ sin6.sin6_addr.s6_addr32[2] = ntohl(0x0000ffff);
bcopy(&sin->sin_addr,
- &sin6.sin6_addr.s6_addr16[3],
- sizeof(sin6.sin6_addr.s6_addr16[3]));
+ &sin6.sin6_addr.s6_addr32[3],
+ sizeof(sin6.sin6_addr.s6_addr32[3]));
sin6.sin6_port = sin->sin_port;
memcpy(from, (caddr_t)&sin6, sizeof(sin6));
}
@@ -6185,8 +6236,12 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
uint32_t vrf_id, int *error, void *p)
{
struct sockaddr *addr_touse;
+
+#ifdef INET6
struct sockaddr_in sin;
+#endif
+
/* see if we're bound all already! */
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
@@ -6307,8 +6362,12 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp,
uint32_t vrf_id, int *error)
{
struct sockaddr *addr_touse;
+
+#ifdef INET6
struct sockaddr_in sin;
+#endif
+
/* see if we're bound all already! */
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
@@ -6424,49 +6483,72 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
if (sctp_is_addr_restricted(stcb, sctp_ifa))
continue;
+ switch (sctp_ifa->address.sa.sa_family) {
+ case AF_INET:
+ if (ipv4_addr_legal) {
+ struct sockaddr_in *sin;
- if ((sctp_ifa->address.sa.sa_family == AF_INET) &&
- (ipv4_addr_legal)) {
- struct sockaddr_in *sin;
-
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
- if (sin->sin_addr.s_addr == 0) {
- /* skip unspecified addrs */
- continue;
- }
- if ((ipv4_local_scope == 0) &&
- (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
- continue;
- }
- /* count this one */
- count++;
- } else if ((sctp_ifa->address.sa.sa_family == AF_INET6) &&
- (ipv6_addr_legal)) {
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ if (sin->sin_addr.s_addr == 0) {
+ /*
+ * skip unspecified
+ * addrs
+ */
+ continue;
+ }
+ if ((ipv4_local_scope == 0) &&
+ (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
+ continue;
+ }
+ /* count this one */
+ count++;
+ } else {
continue;
}
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- if (local_scope == 0)
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (ipv6_addr_legal) {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
continue;
- if (sin6->sin6_scope_id == 0) {
- if (sa6_recoverscope(sin6) != 0)
- /*
- * bad link
- * local
- * address
- */
+ }
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+ if (local_scope == 0)
continue;
+ if (sin6->sin6_scope_id == 0) {
+ if (sa6_recoverscope(sin6) != 0)
+ /*
+ *
+ * bad
+ *
+ * li
+ * nk
+ *
+ * loc
+ * al
+ *
+ * add
+ * re
+ * ss
+ * */
+ continue;
+ }
}
+ if ((site_scope == 0) &&
+ (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
+ continue;
+ }
+ /* count this one */
+ count++;
}
- if ((site_scope == 0) &&
- (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
- continue;
- }
- /* count this one */
- count++;
+ break;
+#endif
+ default:
+ /* TSNH */
+ break;
}
}
}
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index 24157e3..ec4631c 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -203,6 +203,8 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
int *totaddr, int *num_v4, int *num_v6, int *error, int limit, int *bad_addr);
int sctp_is_there_an_abort_here(struct mbuf *, int, uint32_t *);
+
+#ifdef INET6
uint32_t sctp_is_same_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
struct sockaddr_in6 *
@@ -222,7 +224,7 @@ struct sockaddr_in6 *
} \
} \
} while (0)
-
+#endif
int sctp_cmpaddr(struct sockaddr *, struct sockaddr *);
OpenPOWER on IntegriCloud