Date: Thu, 15 Aug 2019 19:52:33 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351102 - head/sbin/ping6 Message-ID: <201908151952.x7FJqXVt034174@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: asomers Date: Thu Aug 15 19:52:32 2019 New Revision: 351102 URL: https://svnweb.freebsd.org/changeset/base/351102 Log: ping6: Fix alignment errors This fixes -Wcast-align errors when compiled with WARNS=6. Submitted by: Ján Sučan <sucanjan@gmail.com> MFC after: 2 weeks Sponsored by: Google, inc. (Google Summer of Code 2019) Differential Revision: https://reviews.freebsd.org/D21217 Modified: head/sbin/ping6/ping6.c Modified: head/sbin/ping6/ping6.c ============================================================================== --- head/sbin/ping6/ping6.c Thu Aug 15 19:27:36 2019 (r351101) +++ head/sbin/ping6/ping6.c Thu Aug 15 19:52:32 2019 (r351102) @@ -313,7 +313,8 @@ main(int argc, char *argv[]) int sockbufsize = 0; #endif int usepktinfo = 0; - struct in6_pktinfo *pktinfo = NULL; + struct in6_pktinfo pktinfo; + char *cmsg_pktinfo = NULL; struct ip6_rthdr *rthdr = NULL; #ifdef IPSEC_POLICY_IPSEC char *policy_in = NULL; @@ -332,6 +333,7 @@ main(int argc, char *argv[]) /* just to be sure */ memset(&smsghdr, 0, sizeof(smsghdr)); memset(&smsgiov, 0, sizeof(smsgiov)); + memset(&pktinfo, 0, sizeof(pktinfo)); intvl.tv_sec = interval / 1000; intvl.tv_nsec = interval % 1000 * 1000000; @@ -896,11 +898,10 @@ main(int argc, char *argv[]) errx(1, "can't allocate enough memory"); smsghdr.msg_control = (caddr_t)scmsg; smsghdr.msg_controllen = ip6optlen; - scmsgp = (struct cmsghdr *)scmsg; + scmsgp = CMSG_FIRSTHDR(&smsghdr); } if (usepktinfo) { - pktinfo = (struct in6_pktinfo *)(CMSG_DATA(scmsgp)); - memset(pktinfo, 0, sizeof(*pktinfo)); + cmsg_pktinfo = CMSG_DATA(scmsgp); scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); scmsgp->cmsg_level = IPPROTO_IPV6; scmsgp->cmsg_type = IPV6_PKTINFO; @@ -911,7 +912,7 @@ main(int argc, char *argv[]) if (ifname) { #ifndef USE_SIN6_SCOPE_ID /* pktinfo must have already been allocated */ - if ((pktinfo->ipi6_ifindex = if_nametoindex(ifname)) == 0) + if ((pktinfo.ipi6_ifindex = if_nametoindex(ifname)) == 0) errx(1, "%s: invalid interface name", ifname); #else if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0) @@ -922,7 +923,7 @@ main(int argc, char *argv[]) scmsgp->cmsg_len = CMSG_LEN(sizeof(int)); scmsgp->cmsg_level = IPPROTO_IPV6; scmsgp->cmsg_type = IPV6_HOPLIMIT; - *(int *)(CMSG_DATA(scmsgp)) = hoplimit; + memcpy(CMSG_DATA(scmsgp), &hoplimit, sizeof(hoplimit)); scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); } @@ -986,9 +987,9 @@ main(int argc, char *argv[]) src.sin6_port = ntohs(DUMMY_PORT); src.sin6_scope_id = dst.sin6_scope_id; - if (pktinfo && + if (usepktinfo && setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO, - (void *)pktinfo, sizeof(*pktinfo))) + (void *)&pktinfo, sizeof(pktinfo))) err(1, "UDP setsockopt(IPV6_PKTINFO)"); if (hoplimit != -1 && @@ -1015,6 +1016,10 @@ main(int argc, char *argv[]) close(dummy); } + /* Save pktinfo in the ancillary data. */ + if (usepktinfo) + memcpy(cmsg_pktinfo, &pktinfo, sizeof(pktinfo)); + if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0) err(1, "connect() ssend"); @@ -1310,6 +1315,8 @@ pinger(void) CLR(seq % mx_dup_ck); if (options & F_FQDN) { + uint16_t s; + icp->icmp6_type = ICMP6_NI_QUERY; icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; nip->ni_qtype = htons(NI_QTYPE_FQDN); @@ -1317,13 +1324,15 @@ pinger(void) memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = htons(seq); + s = htons(seq); + memcpy(nip->icmp6_ni_nonce, &s, sizeof(s)); memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, sizeof(dst.sin6_addr)); cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); datalen = 0; } else if (options & F_FQDNOLD) { + uint16_t s; /* packet format in 03 draft - no Subject data on queries */ icp->icmp6_type = ICMP6_NI_QUERY; icp->icmp6_code = 0; /* code field is always 0 */ @@ -1332,11 +1341,14 @@ pinger(void) memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = htons(seq); + s = htons(seq); + memcpy(nip->icmp6_ni_nonce, &s, sizeof(s)); cc = ICMP6_NIQLEN; datalen = 0; } else if (options & F_NODEADDR) { + uint16_t s; + icp->icmp6_type = ICMP6_NI_QUERY; icp->icmp6_code = ICMP6_NI_SUBJ_IPV6; nip->ni_qtype = htons(NI_QTYPE_NODEADDR); @@ -1344,13 +1356,16 @@ pinger(void) memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = htons(seq); + s = htons(seq); + memcpy(nip->icmp6_ni_nonce, &s, sizeof(s)); memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr, sizeof(dst.sin6_addr)); cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr); datalen = 0; } else if (options & F_SUPTYPES) { + uint16_t s; + icp->icmp6_type = ICMP6_NI_QUERY; icp->icmp6_code = ICMP6_NI_SUBJ_FQDN; /*empty*/ nip->ni_qtype = htons(NI_QTYPE_SUPTYPES); @@ -1359,7 +1374,9 @@ pinger(void) memcpy(nip->icmp6_ni_nonce, nonce, sizeof(nip->icmp6_ni_nonce)); - *(u_int16_t *)nip->icmp6_ni_nonce = htons(seq); + s = htons(seq); + memcpy(nip->icmp6_ni_nonce, &s, sizeof(s)); + cc = ICMP6_NIQLEN; datalen = 0; } else { @@ -1369,17 +1386,17 @@ pinger(void) icp->icmp6_seq = htons(seq); if (timing) { struct timespec tv; - struct tv32 *tv32; + struct tv32 tv32; (void)clock_gettime(CLOCK_MONOTONIC, &tv); - tv32 = (struct tv32 *)&outpack[ICMP6ECHOLEN]; /* * Truncate seconds down to 32 bits in order * to fit the timestamp within 8 bytes of the * packet. We're only concerned with * durations, not absolute times. */ - tv32->tv32_sec = (uint32_t)htonl(tv.tv_sec); - tv32->tv32_nsec = (uint32_t)htonl(tv.tv_nsec); + tv32.tv32_sec = (uint32_t)htonl(tv.tv_sec); + tv32.tv32_nsec = (uint32_t)htonl(tv.tv_nsec); + memcpy(&outpack[ICMP6ECHOLEN], &tv32, sizeof(tv32)); } cc = ICMP6ECHOLEN + datalen; } @@ -1509,7 +1526,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) u_char *cp = NULL, *dp, *end = buf + cc; struct in6_pktinfo *pktinfo = NULL; struct timespec tv, tp; - struct tv32 *tpp; + struct tv32 tpp; double triptime = 0; int dupflag; size_t off; @@ -1554,9 +1571,9 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) seq = ntohs(icp->icmp6_seq); ++nreceived; if (timing) { - tpp = (struct tv32 *)(icp + 1); - tp.tv_sec = ntohl(tpp->tv32_sec); - tp.tv_nsec = ntohl(tpp->tv32_nsec); + memcpy(&tpp, icp + 1, sizeof(tpp)); + tp.tv_sec = ntohl(tpp.tv32_sec); + tp.tv_nsec = ntohl(tpp.tv32_nsec); timespecsub(&tv, &tp, &tv); triptime = ((double)tv.tv_sec) * 1000.0 + ((double)tv.tv_nsec) / 1000000.0; @@ -1620,7 +1637,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) } } } else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) { - seq = ntohs(*(u_int16_t *)ni->icmp6_ni_nonce); + memcpy(&seq, ni->icmp6_ni_nonce, sizeof(seq)); + seq = ntohs(seq); ++nreceived; if (TST(seq % mx_dup_ck)) { ++nrepeats; @@ -1698,6 +1716,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) } } if (options & F_VERBOSE) { + u_long t; int32_t ttl; int comma = 0; @@ -1720,7 +1739,8 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr) putchar(')'); goto fqdnend; } - ttl = (int32_t)ntohl(*(u_long *)&buf[off+ICMP6ECHOLEN+8]); + memcpy(&t, &buf[off+ICMP6ECHOLEN+8], sizeof(t)); + ttl = (int32_t)ntohl(t); if (comma) printf(","); if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) { @@ -2086,8 +2106,10 @@ pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen) u_int32_t ttl = 0; if (withttl) { - /* XXX: alignment? */ - ttl = (u_int32_t)ntohl(*(u_int32_t *)cp); + uint32_t t; + + memcpy(&t, cp, sizeof(t)); + ttl = (u_int32_t)ntohl(t); cp += sizeof(u_int32_t); nilen -= sizeof(u_int32_t); } @@ -2126,8 +2148,12 @@ get_hoplim(struct msghdr *mhdr) if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_HOPLIMIT && - cm->cmsg_len == CMSG_LEN(sizeof(int))) - return(*(int *)CMSG_DATA(cm)); + cm->cmsg_len == CMSG_LEN(sizeof(int))) { + int r; + + memcpy(&r, CMSG_DATA(cm), sizeof(r)); + return(r); + } } return(-1); @@ -2136,6 +2162,7 @@ get_hoplim(struct msghdr *mhdr) static struct in6_pktinfo * get_rcvpktinfo(struct msghdr *mhdr) { + static struct in6_pktinfo pi; struct cmsghdr *cm; for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; @@ -2145,8 +2172,10 @@ get_rcvpktinfo(struct msghdr *mhdr) if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO && - cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) - return((struct in6_pktinfo *)CMSG_DATA(cm)); + cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) { + memcpy(&pi, CMSG_DATA(cm), sizeof(pi)); + return(&pi); + } } return(NULL); @@ -2157,7 +2186,7 @@ get_pathmtu(struct msghdr *mhdr) { #ifdef IPV6_RECVPATHMTU struct cmsghdr *cm; - struct ip6_mtuinfo *mtuctl = NULL; + struct ip6_mtuinfo mtuctl; for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { @@ -2167,7 +2196,7 @@ get_pathmtu(struct msghdr *mhdr) if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PATHMTU && cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) { - mtuctl = (struct ip6_mtuinfo *)CMSG_DATA(cm); + memcpy(&mtuctl, CMSG_DATA(cm), sizeof(mtuctl)); /* * If the notified destination is different from @@ -2177,17 +2206,17 @@ get_pathmtu(struct msghdr *mhdr) * have used the default scope zone ID for sending, * in which case the scope ID value is 0. */ - if (!IN6_ARE_ADDR_EQUAL(&mtuctl->ip6m_addr.sin6_addr, + if (!IN6_ARE_ADDR_EQUAL(&mtuctl.ip6m_addr.sin6_addr, &dst.sin6_addr) || - (mtuctl->ip6m_addr.sin6_scope_id && + (mtuctl.ip6m_addr.sin6_scope_id && dst.sin6_scope_id && - mtuctl->ip6m_addr.sin6_scope_id != + mtuctl.ip6m_addr.sin6_scope_id != dst.sin6_scope_id)) { if ((options & F_VERBOSE) != 0) { printf("path MTU for %s is notified. " "(ignored)\n", - pr_addr((struct sockaddr *)&mtuctl->ip6m_addr, - sizeof(mtuctl->ip6m_addr))); + pr_addr((struct sockaddr *)&mtuctl.ip6m_addr, + sizeof(mtuctl.ip6m_addr))); } return(0); } @@ -2196,11 +2225,11 @@ get_pathmtu(struct msghdr *mhdr) * Ignore an invalid MTU. XXX: can we just believe * the kernel check? */ - if (mtuctl->ip6m_mtu < IPV6_MMTU) + if (mtuctl.ip6m_mtu < IPV6_MMTU) return(0); /* notification for our destination. return the MTU. */ - return((int)mtuctl->ip6m_mtu); + return((int)mtuctl.ip6m_mtu); } } #endif @@ -2571,6 +2600,8 @@ pr_retip(struct ip6_hdr *ip6, u_char *end) nh = ip6->ip6_nxt; cp += hlen; while (end - cp >= 8) { + struct ah ah; + switch (nh) { case IPPROTO_HOPOPTS: printf("HBH "); @@ -2595,8 +2626,9 @@ pr_retip(struct ip6_hdr *ip6, u_char *end) #ifdef IPSEC case IPPROTO_AH: printf("AH "); - hlen = (((struct ah *)cp)->ah_len+2) << 2; - nh = ((struct ah *)cp)->ah_nxt; + memcpy(&ah, cp, sizeof(ah)); + hlen = (ah.ah_len+2) << 2; + nh = ah.ah_nxt; break; #endif case IPPROTO_ICMPV6:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908151952.x7FJqXVt034174>