From c2acd568867621cf9d5e17465fca76ea03b3b47d Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 24 Aug 2020 08:25:00 +0000 Subject: [PATCH] MFC r362473: leanup the defintion of struct sctp_getaddresses. This stucture is used by the IPPROTO_SCTP level socket options SCTP_GET_PEER_ADDRESSES and SCTP_GET_LOCAL_ADDRESSES, which are used by libc to implement sctp_getladdrs() and sctp_getpaddrs(). These changes allow an old libc to work on a newer kernel. --- lib/libc/net/sctp_sys_calls.c | 16 +++++----- sys/netinet/sctp_uio.h | 17 +++++----- sys/netinet/sctp_usrreq.c | 60 +++++++++++++++++------------------ 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c index f93b0b0658a..c4713213a21 100644 --- a/lib/libc/net/sctp_sys_calls.c +++ b/lib/libc/net/sctp_sys_calls.c @@ -406,7 +406,7 @@ sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) return (-1); } /* size required is returned in 'asoc' */ - opt_len = (socklen_t)((size_t)asoc + sizeof(sctp_assoc_t)); + opt_len = (socklen_t)((size_t)asoc + sizeof(struct sctp_getaddresses)); addrs = calloc(1, (size_t)opt_len); if (addrs == NULL) { errno = ENOMEM; @@ -419,9 +419,9 @@ sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) free(addrs); return (-1); } - *raddrs = (struct sockaddr *)&addrs->addr[0]; + *raddrs = &addrs->addr[0].sa; cnt = 0; - sa = (struct sockaddr *)&addrs->addr[0]; + sa = &addrs->addr[0].sa; lim = (caddr_t)addrs + opt_len; while (((caddr_t)sa < lim) && (sa->sa_len > 0)) { sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); @@ -436,7 +436,7 @@ sctp_freepaddrs(struct sockaddr *addrs) void *fr_addr; /* Take away the hidden association id */ - fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t)); + fr_addr = (void *)((caddr_t)addrs - offsetof(struct sctp_getaddresses, addr)); /* Now free it */ free(fr_addr); } @@ -466,7 +466,7 @@ sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) errno = ENOTCONN; return (-1); } - opt_len = (socklen_t)(size_of_addresses + sizeof(sctp_assoc_t)); + opt_len = (socklen_t)(size_of_addresses + sizeof(struct sctp_getaddresses)); addrs = calloc(1, (size_t)opt_len); if (addrs == NULL) { errno = ENOMEM; @@ -480,9 +480,9 @@ sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) errno = ENOMEM; return (-1); } - *raddrs = (struct sockaddr *)&addrs->addr[0]; + *raddrs = &addrs->addr[0].sa; cnt = 0; - sa = (struct sockaddr *)&addrs->addr[0]; + sa = &addrs->addr[0].sa; lim = (caddr_t)addrs + opt_len; while (((caddr_t)sa < lim) && (sa->sa_len > 0)) { sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); @@ -497,7 +497,7 @@ sctp_freeladdrs(struct sockaddr *addrs) void *fr_addr; /* Take away the hidden association id */ - fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t)); + fr_addr = (void *)((caddr_t)addrs - offsetof(struct sctp_getaddresses, addr)); /* Now free it */ free(fr_addr); } diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index 022589de717..a57197ee236 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$"); #define _NETINET_SCTP_UIO_H_ -#if ! defined(_KERNEL) +#if !defined(_KERNEL) #include #endif #include @@ -633,10 +633,15 @@ struct sctp_setpeerprim { uint8_t sspp_padding[4]; }; +union sctp_sockstore { + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + struct sockaddr sa; +}; + struct sctp_getaddresses { sctp_assoc_t sget_assoc_id; - /* addr is filled in for N * sockaddr_storage */ - struct sockaddr addr[1]; + union sctp_sockstore addr[]; }; struct sctp_status { @@ -1143,12 +1148,6 @@ struct sctpstat { #define SCTP_STAT_DECR_COUNTER64(_x) SCTP_STAT_DECR(_x) #define SCTP_STAT_DECR_GAUGE32(_x) SCTP_STAT_DECR(_x) -union sctp_sockstore { - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr sa; -}; - /***********************************/ /* And something for us old timers */ diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index ed5a4a4c05f..92009730580 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -970,7 +970,7 @@ sctp_shutdown(struct socket *so) * returns 0 on success, 1 on error */ static uint32_t -sctp_fill_user_address(struct sockaddr_storage *ss, struct sockaddr *sa) +sctp_fill_user_address(union sctp_sockstore *ss, struct sockaddr *sa) { #ifdef INET6 struct sockaddr_in6 lsa6; @@ -991,7 +991,7 @@ static size_t sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, struct sctp_tcb *stcb, size_t limit, - struct sockaddr_storage *sas, + union sctp_sockstore *addr, uint32_t vrf_id) { struct sctp_ifn *sctp_ifn; @@ -1106,18 +1106,18 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, if (actual + sizeof(struct sockaddr_in6) > limit) { return (actual); } - 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)); + in6_sin_2_v4mapsin6(sin, &addr->sin6); + addr->sin6.sin6_port = inp->sctp_lport; + addr = (union sctp_sockstore *)((caddr_t)addr + sizeof(struct sockaddr_in6)); actual += sizeof(struct sockaddr_in6); } else { #endif if (actual + sizeof(struct sockaddr_in) > limit) { return (actual); } - memcpy(sas, sin, sizeof(struct sockaddr_in)); - ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; - sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in)); + memcpy(addr, sin, sizeof(struct sockaddr_in)); + addr->sin.sin_port = inp->sctp_lport; + addr = (union sctp_sockstore *)((caddr_t)addr + sizeof(struct sockaddr_in)); actual += sizeof(struct sockaddr_in); #ifdef INET6 } @@ -1169,9 +1169,9 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, if (actual + sizeof(struct sockaddr_in6) > limit) { return (actual); } - memcpy(sas, sin6, sizeof(struct sockaddr_in6)); - ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; - sas = (struct sockaddr_storage *)((caddr_t)sas + sizeof(struct sockaddr_in6)); + memcpy(addr, sin6, sizeof(struct sockaddr_in6)); + addr->sin6.sin6_port = inp->sctp_lport; + addr = (union sctp_sockstore *)((caddr_t)addr + sizeof(struct sockaddr_in6)); actual += sizeof(struct sockaddr_in6); } else { continue; @@ -1198,24 +1198,24 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp, if (actual + sa_len > limit) { return (actual); } - if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) + if (sctp_fill_user_address(addr, &laddr->ifa->address.sa)) continue; switch (laddr->ifa->address.sa.sa_family) { #ifdef INET case AF_INET: - ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; + addr->sin.sin_port = inp->sctp_lport; break; #endif #ifdef INET6 case AF_INET6: - ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; + addr->sin6.sin6_port = inp->sctp_lport; break; #endif default: /* TSNH */ break; } - sas = (struct sockaddr_storage *)((caddr_t)sas + sa_len); + addr = (union sctp_sockstore *)((caddr_t)addr + sa_len); actual += sa_len; } } @@ -1226,13 +1226,13 @@ static size_t sctp_fill_up_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, size_t limit, - struct sockaddr_storage *sas) + union sctp_sockstore *addr) { size_t size = 0; SCTP_IPI_ADDR_RLOCK(); /* fill up addresses for the endpoint's default vrf */ - size = sctp_fill_up_addresses_vrf(inp, stcb, limit, sas, + size = sctp_fill_up_addresses_vrf(inp, stcb, limit, addr, inp->def_vrf_id); SCTP_IPI_ADDR_RUNLOCK(); return (size); @@ -2207,7 +2207,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, */ { size_t cpsz, left; - struct sockaddr_storage *sas; + union sctp_sockstore *addr; struct sctp_nets *net; struct sctp_getaddresses *saddr; @@ -2215,9 +2215,9 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); if (stcb) { - left = (*optsize) - sizeof(sctp_assoc_t); - *optsize = sizeof(sctp_assoc_t); - sas = (struct sockaddr_storage *)&saddr->addr[0]; + left = *optsize - offsetof(struct sctp_getaddresses, addr); + *optsize = offsetof(struct sctp_getaddresses, addr); + addr = &saddr->addr[0]; TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { switch (net->ro._l_addr.sa.sa_family) { @@ -2255,16 +2255,16 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, (net->ro._l_addr.sa.sa_family == AF_INET)) { /* Must map the address */ in6_sin_2_v4mapsin6(&net->ro._l_addr.sin, - (struct sockaddr_in6 *)sas); + &addr->sin6); } else { - memcpy(sas, &net->ro._l_addr, cpsz); + memcpy(addr, &net->ro._l_addr, cpsz); } #else - memcpy(sas, &net->ro._l_addr, cpsz); + memcpy(addr, &net->ro._l_addr, cpsz); #endif - ((struct sockaddr_in *)sas)->sin_port = stcb->rport; + addr->sin.sin_port = stcb->rport; - sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz); + addr = (union sctp_sockstore *)((caddr_t)addr + cpsz); left -= cpsz; *optsize += cpsz; } @@ -2278,19 +2278,17 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, case SCTP_GET_LOCAL_ADDRESSES: { size_t limit, actual; - struct sockaddr_storage *sas; struct sctp_getaddresses *saddr; SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize); SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id); - sas = (struct sockaddr_storage *)&saddr->addr[0]; - limit = *optsize - sizeof(sctp_assoc_t); - actual = sctp_fill_up_addresses(inp, stcb, limit, sas); + limit = *optsize - offsetof(struct sctp_getaddresses, addr); + actual = sctp_fill_up_addresses(inp, stcb, limit, saddr->addr); if (stcb) { SCTP_TCB_UNLOCK(stcb); } - *optsize = sizeof(sctp_assoc_t) + actual; + *optsize = offsetof(struct sctp_getaddresses, addr) + actual; break; } case SCTP_PEER_ADDR_PARAMS: -- 2.45.0