| @@ -1,23 +1,132 @@ | | | @@ -1,23 +1,132 @@ |
1 | $NetBSD: patch-examples_dvbinfo_udp.c,v 1.2 2013/10/05 08:29:38 wiz Exp $ | | 1 | $NetBSD: patch-examples_dvbinfo_udp.c,v 1.3 2015/03/31 15:52:51 joerg Exp $ |
2 | | | 2 | |
3 | Portability fix from upstream (Jean-Paul Saman <jpsaman@videolan.org>). | | 3 | Portability fix from upstream (Jean-Paul Saman <jpsaman@videolan.org>). |
| | | 4 | Don't cast alignments away. |
4 | | | 5 | |
5 | --- examples/dvbinfo/udp.c.orig 2013-10-02 10:19:18.000000000 +0000 | | 6 | --- examples/dvbinfo/udp.c.orig 2014-04-16 07:22:14.000000000 +0000 |
6 | +++ examples/dvbinfo/udp.c | | 7 | +++ examples/dvbinfo/udp.c |
7 | @@ -61,6 +61,16 @@ | | 8 | @@ -61,43 +61,53 @@ |
8 | # include <fcntl.h> | | 9 | # include <fcntl.h> |
9 | #endif | | 10 | #endif |
10 | | | 11 | |
11 | +#ifndef SOL_IP | | 12 | +#ifndef SOL_IP |
12 | +# define SOL_IP IPPROTO_IP | | 13 | +# define SOL_IP IPPROTO_IP |
13 | +#endif | | 14 | +#endif |
14 | +#ifndef SOL_IPV6 | | 15 | +#ifndef SOL_IPV6 |
15 | +# define SOL_IPV6 IPPROTO_IPV6 | | 16 | +# define SOL_IPV6 IPPROTO_IPV6 |
16 | +#endif | | 17 | +#endif |
17 | +#ifndef IPPROTO_IPV6 | | 18 | +#ifndef IPPROTO_IPV6 |
18 | +# define IPPROTO_IPV6 41 /* IANA */ | | 19 | +# define IPPROTO_IPV6 41 /* IANA */ |
19 | +#endif | | 20 | +#endif |
20 | + | | 21 | + |
21 | #include <assert.h> | | 22 | #include <assert.h> |
22 | | | 23 | |
23 | #include "udp.h" | | 24 | #include "udp.h" |
| | | 25 | |
| | | 26 | #ifdef HAVE_SYS_SOCKET_H |
| | | 27 | -static bool is_multicast(const struct sockaddr_storage *saddr, socklen_t len) |
| | | 28 | +static bool is_multicast(const struct sockaddr *addr, socklen_t len) |
| | | 29 | { |
| | | 30 | - const struct sockaddr *addr = (const struct sockaddr *) saddr; |
| | | 31 | |
| | | 32 | switch(addr->sa_family) |
| | | 33 | { |
| | | 34 | #if defined(IN_MULTICAST) |
| | | 35 | case AF_INET: |
| | | 36 | { |
| | | 37 | - const struct sockaddr_in *ip = (const struct sockaddr_in *)saddr; |
| | | 38 | - if ((size_t)len < sizeof (*ip)) |
| | | 39 | + struct sockaddr_in ip; |
| | | 40 | + if ((size_t)len < sizeof (ip)) |
| | | 41 | return false; |
| | | 42 | - return IN_MULTICAST(ntohl(ip->sin_addr.s_addr)) != 0; |
| | | 43 | + memcpy(&ip, addr, sizeof(ip)); |
| | | 44 | + return IN_MULTICAST(ntohl(ip.sin_addr.s_addr)) != 0; |
| | | 45 | } |
| | | 46 | #endif |
| | | 47 | #if defined(IN6_IS_ADDR_MULTICAST) |
| | | 48 | case AF_INET6: |
| | | 49 | { |
| | | 50 | - const struct sockaddr_in6 *ip6 = (const struct sockaddr_in6 *)saddr; |
| | | 51 | - if ((size_t)len < sizeof (*ip6)) |
| | | 52 | + struct sockaddr_in6 ip6; |
| | | 53 | + if ((size_t)len < sizeof (ip6)) |
| | | 54 | return false; |
| | | 55 | - return IN6_IS_ADDR_MULTICAST(&ip6->sin6_addr) != 0; |
| | | 56 | + memcpy(&ip6, addr, sizeof(ip6)); |
| | | 57 | + return IN6_IS_ADDR_MULTICAST(&ip6.sin6_addr) != 0; |
| | | 58 | } |
| | | 59 | #endif |
| | | 60 | } |
| | | 61 | return false; |
| | | 62 | } |
| | | 63 | |
| | | 64 | -static bool mcast_connect(int s, const char *interface, const struct sockaddr_storage *saddr, socklen_t len) |
| | | 65 | +static bool mcast_connect(int s, const char *interface, const struct sockaddr *addr, socklen_t len) |
| | | 66 | { |
| | | 67 | unsigned int ifindex = interface ? if_nametoindex(interface) : 0; |
| | | 68 | - const struct sockaddr *addr = (const struct sockaddr *) saddr; |
| | | 69 | |
| | | 70 | #if defined(MCAST_JOIN_GROUP) |
| | | 71 | /* Source Specific Multicast Join */ |
| | | 72 | @@ -115,10 +125,13 @@ static bool mcast_connect(int s, const c |
| | | 73 | { |
| | | 74 | case AF_INET6: |
| | | 75 | { |
| | | 76 | - const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)saddr; |
| | | 77 | + struct sockaddr_in6 sin6; |
| | | 78 | assert(len >= sizeof (struct sockaddr_in6)); |
| | | 79 | - if (sin6->sin6_scope_id != 0) |
| | | 80 | - greq.gr_interface = sin6->sin6_scope_id; |
| | | 81 | + memcpy(&sin6, addr, sizeof(sin6)); |
| | | 82 | + if (sin6.sin6_scope_id != 0) { |
| | | 83 | + greq.gr_interface = sin6.sin6_scope_id; |
| | | 84 | + memcpy(&greq.gr_group, &sin6, sizeof(sin6)); |
| | | 85 | + } |
| | | 86 | if (setsockopt(s, SOL_IPV6, MCAST_JOIN_GROUP, &greq, sizeof(greq)) == 0) |
| | | 87 | return true; |
| | | 88 | break; |
| | | 89 | @@ -136,12 +149,14 @@ static bool mcast_connect(int s, const c |
| | | 90 | case AF_INET6: |
| | | 91 | { |
| | | 92 | struct ipv6_mreq ipv6mr; |
| | | 93 | - const struct sockaddr_in6 *ip6 = (const struct sockaddr_in6 *)saddr; |
| | | 94 | + struct sockaddr_in6 ip6; |
| | | 95 | + assert(len >= sizeof (struct sockaddr_in6)); |
| | | 96 | + memcpy(&ip6, addr, sizeof(ip6)); |
| | | 97 | |
| | | 98 | memset(&ipv6mr, 0, sizeof (ipv6mr)); |
| | | 99 | assert(len >= sizeof (struct sockaddr_in6)); |
| | | 100 | - ipv6mr.ipv6mr_multiaddr = ip6->sin6_addr; |
| | | 101 | - ipv6mr.ipv6mr_interface = (ifindex > 0) ? ifindex : ip6->sin6_scope_id; |
| | | 102 | + ipv6mr.ipv6mr_multiaddr = ip6.sin6_addr; |
| | | 103 | + ipv6mr.ipv6mr_interface = (ifindex > 0) ? ifindex : ip6.sin6_scope_id; |
| | | 104 | # ifdef IPV6_JOIN_GROUP |
| | | 105 | if (setsockopt(s, SOL_IPV6, IPV6_JOIN_GROUP, &ipv6mr, sizeof (ipv6mr)) == 0) |
| | | 106 | # else |
| | | 107 | @@ -154,10 +169,12 @@ static bool mcast_connect(int s, const c |
| | | 108 | case AF_INET: |
| | | 109 | { |
| | | 110 | struct ip_mreq imr; |
| | | 111 | + struct sockaddr_in ip; |
| | | 112 | |
| | | 113 | memset(&imr, 0, sizeof (imr)); |
| | | 114 | assert(len >= sizeof (struct sockaddr_in)); |
| | | 115 | - imr.imr_multiaddr = ((const struct sockaddr_in *)saddr)->sin_addr; |
| | | 116 | + memcpy(&ip, addr, sizeof(ip)); |
| | | 117 | + imr.imr_multiaddr = ip.sin_addr; |
| | | 118 | #if 0 /* TODO: Source Specific Multicast Join */ |
| | | 119 | if (ifaddr) /* Linux specific interface bound multicast address */ |
| | | 120 | imr.imr_address.s_addr = if_addr; |
| | | 121 | @@ -284,9 +301,8 @@ int udp_open(const char *interface, cons |
| | | 122 | continue; |
| | | 123 | } |
| | | 124 | |
| | | 125 | - const struct sockaddr_storage *saddr = (const struct sockaddr_storage *)&ptr->ai_addr; |
| | | 126 | - if (is_multicast(saddr, ptr->ai_addrlen) && |
| | | 127 | - mcast_connect(s_ctl, NULL, saddr, ptr->ai_addrlen)) |
| | | 128 | + if (is_multicast(ptr->ai_addr, ptr->ai_addrlen) && |
| | | 129 | + mcast_connect(s_ctl, NULL, ptr->ai_addr, ptr->ai_addrlen)) |
| | | 130 | { |
| | | 131 | close(s_ctl); |
| | | 132 | s_ctl = -1; |