Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
This patch is not absolutely necessary, but it allows us to drop the special handling of sa_len = 0. For any non-zero netmask the alignment makes sure we can read the full sin_addr, although there is no guarantee that the extra bytes contain zeroes. --- dlls/iphlpapi/ipstats.c | 52 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 25 deletions(-)
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 38f5927cc0..3d9718d1ec 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -1548,33 +1548,35 @@ DWORD WINAPI AllocateAndGetIpForwardTableFromStack(PMIB_IPFORWARDTABLE *ppIpForw
ADVANCE (addrPtr, sa);
- /* default routes are encoded by length-zero sockaddr */ - if (sa->sa_len == 0) { - addr = 0; - }else { - /* Apple's netstat prints the netmask together with the destination - * and only looks at the destination's address family. The netmask's - * sa_family sometimes contains the non-existent value 0xff. */ - switch(i == RTA_NETMASK ? dst_family : sa->sa_family) { - case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - addr = sin->sin_addr.s_addr; - break; - } + /* Apple's netstat prints the netmask together with the destination + * and only looks at the destination's address family. The netmask's + * sa_family sometimes contains the non-existent value 0xff. */ + switch(i == RTA_NETMASK ? dst_family : sa->sa_family) { + case AF_INET: { + /* Netmasks (and possibly other addresses) have only enough size + * to represent the non-zero bits, e.g. a netmask of 255.0.0.0 has + * 56 bytes (1 sa_len, 1 sa_family, 2 sa_port and 1 for the first + * byte of sin_addr). Due to the alignment constraint we can de + * facto read the full 4 bytes of sin_addr (except for the case of + * netmask 0). Don't assume though that the extra bytes are zeroed. */ + struct sockaddr_in sin = {0}; + memcpy(&sin, sa, sa->sa_len); + addr = sin.sin_addr.s_addr; + break; + } #ifdef AF_LINK - case AF_LINK: - if(i == RTA_GATEWAY && row.u1.ForwardType == MIB_IPROUTE_TYPE_DIRECT) { - /* For direct route we may simply use dest addr as next hop */ - C_ASSERT(RTA_DST < RTA_GATEWAY); - addr = row.dwForwardDest; - break; - } - /* fallthrough */ -#endif - default: - WARN ("Received unsupported sockaddr family 0x%x\n", sa->sa_family); - addr = 0; + case AF_LINK: + if(i == RTA_GATEWAY && row.u1.ForwardType == MIB_IPROUTE_TYPE_DIRECT) { + /* For direct route we may simply use dest addr as next hop */ + C_ASSERT(RTA_DST < RTA_GATEWAY); + addr = row.dwForwardDest; + break; } + /* fallthrough */ +#endif + default: + WARN ("Received unsupported sockaddr family 0x%x\n", sa->sa_family); + addr = 0; }
switch (i)