From 46c1402f150b5863312ee1d702c995b33161c8fe Mon Sep 17 00:00:00 2001 From: nickkelsey Date: Sun, 30 Oct 2022 10:24:27 -0700 Subject: [PATCH] 20221030 --- hdhomerun_control.c | 2 +- hdhomerun_device.c | 4 +- hdhomerun_discover.c | 111 ++++++++---------------------------- hdhomerun_sock.c | 73 ++++++++++++++++++++++++ hdhomerun_sock.h | 6 ++ hdhomerun_sock_getifaddrs.c | 11 +++- hdhomerun_sock_netdevice.c | 6 +- hdhomerun_sock_netlink.c | 14 +++-- 8 files changed, 128 insertions(+), 99 deletions(-) diff --git a/hdhomerun_control.c b/hdhomerun_control.c index 2c65656..b137646 100644 --- a/hdhomerun_control.c +++ b/hdhomerun_control.c @@ -152,7 +152,7 @@ static bool hdhomerun_control_connect_sock(struct hdhomerun_control_sock_t *cs) hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: no device specified\n"); return false; } - if (hdhomerun_discover_is_ip_multicast_ex((struct sockaddr *)&cs->desired_device_addr)) { + if (hdhomerun_sock_sockaddr_is_multicast((struct sockaddr *)&cs->desired_device_addr)) { hdhomerun_debug_printf(cs->dbg, "hdhomerun_control_connect_sock: cannot use multicast ip address for device operations\n"); return false; } diff --git a/hdhomerun_device.c b/hdhomerun_device.c index 161abae..38337ad 100644 --- a/hdhomerun_device.c +++ b/hdhomerun_device.c @@ -50,7 +50,7 @@ int hdhomerun_device_set_device_ex(struct hdhomerun_device_t *hd, uint32_t devic return -1; } - if (hdhomerun_discover_is_ip_multicast_ex(device_addr)) { + if (hdhomerun_sock_sockaddr_is_multicast(device_addr)) { hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_device: invalid address\n"); return -1; } @@ -93,7 +93,7 @@ int hdhomerun_device_set_multicast(struct hdhomerun_device_t *hd, uint32_t multi int hdhomerun_device_set_multicast_ex(struct hdhomerun_device_t *hd, const struct sockaddr *multicast_addr) { - if (!hdhomerun_discover_is_ip_multicast_ex(multicast_addr)) { + if (!hdhomerun_sock_sockaddr_is_multicast(multicast_addr)) { hdhomerun_debug_printf(hd->dbg, "hdhomerun_device_set_device_multicast: invalid address\n"); return -1; } diff --git a/hdhomerun_discover.c b/hdhomerun_discover.c index c7ffadd..2eef869 100644 --- a/hdhomerun_discover.c +++ b/hdhomerun_discover.c @@ -478,63 +478,6 @@ static bool hdhomerun_discover_send_request(struct hdhomerun_discover_t *ds, str return hdhomerun_sock_sendto_ex(dss->sock, remote_addr, tx_pkt->start, tx_pkt->end - tx_pkt->start, 0); } -static inline bool hdhomerun_discover_is_ipv4_localhost(const struct sockaddr *ip_addr) -{ - if (ip_addr->sa_family != AF_INET) { - return false; - } - - const struct sockaddr_in *sock_addr_in = (const struct sockaddr_in *)ip_addr; - uint8_t *addr_bytes = (uint8_t *)&sock_addr_in->sin_addr.s_addr; - return (addr_bytes[0] == 0x7F); -} - -static inline bool hdhomerun_discover_is_ipv4_autoip(const struct sockaddr *ip_addr) -{ - if (ip_addr->sa_family != AF_INET) { - return false; - } - - const struct sockaddr_in *sock_addr_in = (const struct sockaddr_in *)ip_addr; - uint8_t *addr_bytes = (uint8_t *)&sock_addr_in->sin_addr.s_addr; - return (addr_bytes[0] == 169) && (addr_bytes[1] == 254); -} - -static inline bool hdhomerun_discover_is_ipv6_localhost(const struct sockaddr *ip_addr) -{ - if (ip_addr->sa_family != AF_INET6) { - return false; - } - - const struct sockaddr_in6 *sock_addr_in6 = (const struct sockaddr_in6 *)ip_addr; - uint8_t *addr_bytes = (uint8_t *)sock_addr_in6->sin6_addr.s6_addr; - - static uint8_t hdhomerun_discover_ipv6_localhost_bytes[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; - return (memcmp(addr_bytes, hdhomerun_discover_ipv6_localhost_bytes, 16) == 0); -} - -static inline bool hdhomerun_discover_is_ipv6_routable(const struct sockaddr *ip_addr) -{ - if (ip_addr->sa_family != AF_INET6) { - return false; - } - - const struct sockaddr_in6 *sock_addr_in6 = (const struct sockaddr_in6 *)ip_addr; - uint8_t *addr_bytes = (uint8_t *)sock_addr_in6->sin6_addr.s6_addr; - return ((addr_bytes[0] & 0xE0) == 0x20); -} - -static inline bool hdhomerun_discover_is_ipv6_linklocal(const struct sockaddr *ip_addr) -{ - if (ip_addr->sa_family != AF_INET6) { - return false; - } - - const struct sockaddr_in6 *sock_addr_in6 = (const struct sockaddr_in6 *)ip_addr; - uint8_t *addr_bytes = (uint8_t *)sock_addr_in6->sin6_addr.s6_addr; - return (addr_bytes[0] == 0xFE) && ((addr_bytes[1] & 0xC0) == 0x80); -} - static void hdhomerun_discover_send_ipv6_targeted(struct hdhomerun_discover_t *ds, const struct sockaddr *target_addr, uint32_t flags, const uint32_t device_types[], size_t device_types_count, uint32_t device_id, struct hdhomerun_discover_sock_t **recv_list) { struct hdhomerun_discover_sock_t *default_dss = ds->ipv6_socks; @@ -550,10 +493,10 @@ static void hdhomerun_discover_send_ipv6_targeted(struct hdhomerun_discover_t *d target_addr_in.sin6_port = htons(HDHOMERUN_DISCOVER_UDP_PORT); /* ipv6 linklocal - send out every interface if the scope id isn't provided */ - if (hdhomerun_discover_is_ipv6_linklocal(target_addr) && (target_addr_in.sin6_scope_id == 0)) { + if (hdhomerun_sock_sockaddr_is_ipv6_linklocal(target_addr) && (target_addr_in.sin6_scope_id == 0)) { struct hdhomerun_discover_sock_t *dss = default_dss->next; while (dss) { - if (!hdhomerun_discover_is_ipv6_linklocal((const struct sockaddr *)&dss->local_ip)) { + if (!hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&dss->local_ip)) { dss = dss->next; continue; } @@ -620,7 +563,7 @@ static void hdhomerun_discover_send_ipv4_targeted(struct hdhomerun_discover_t *d return; } - if (hdhomerun_discover_is_ipv4_autoip(target_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv4_autoip(target_addr)) { return; } @@ -648,7 +591,7 @@ static void hdhomerun_discover_send_ipv6_multicast(struct hdhomerun_discover_t * struct hdhomerun_discover_sock_t *dss = default_dss->next; while (dss) { - bool linklocal = hdhomerun_discover_is_ipv6_linklocal((const struct sockaddr *)&dss->local_ip); + bool linklocal = hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&dss->local_ip); if ((linklocal && !send_linklocal) || (!linklocal && !send_general)) { dss = dss->next; continue; @@ -759,27 +702,27 @@ static void hdhomerun_discover_send_ipv4_localhost(struct hdhomerun_discover_t * static uint8_t hdhomerun_discover_compute_device_if_priority(struct hdhomerun_discover2_device_if_t *device_if) { - if (hdhomerun_discover_is_ipv6_localhost((const struct sockaddr *)&device_if->ip_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv6_localhost((const struct sockaddr *)&device_if->ip_addr)) { return 0; /* highest priority */ } - if (hdhomerun_discover_is_ipv4_localhost((const struct sockaddr *)&device_if->ip_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv4_localhost((const struct sockaddr *)&device_if->ip_addr)) { return 1; } if (device_if->ip_addr.ss_family == AF_INET6) { - if (hdhomerun_discover_is_ipv6_routable((const struct sockaddr *)&device_if->ip_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv6_global((const struct sockaddr *)&device_if->ip_addr)) { return 2; } - if (!hdhomerun_discover_is_ipv6_linklocal((const struct sockaddr *)&device_if->ip_addr)) { + if (!hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&device_if->ip_addr)) { return 3; } return 4; } - if (!hdhomerun_discover_is_ipv4_autoip((const struct sockaddr *)&device_if->ip_addr)) { + if (!hdhomerun_sock_sockaddr_is_ipv4_autoip((const struct sockaddr *)&device_if->ip_addr)) { return 5; } @@ -1143,11 +1086,11 @@ static void hdhomerun_discover_recv_merge_device(struct hdhomerun_discover_t *ds static bool hdhomerun_discover_recvfrom_match_flags(const struct sockaddr *remote_addr, uint32_t flags) { if (remote_addr->sa_family == AF_INET6) { - if (hdhomerun_discover_is_ipv6_localhost(remote_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv6_localhost(remote_addr)) { return (flags & HDHOMERUN_DISCOVER_FLAGS_IPV6_LOCALHOST) != 0; } - if (hdhomerun_discover_is_ipv6_linklocal(remote_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv6_linklocal(remote_addr)) { return (flags & HDHOMERUN_DISCOVER_FLAGS_IPV6_LINKLOCAL) != 0; } @@ -1155,7 +1098,7 @@ static bool hdhomerun_discover_recvfrom_match_flags(const struct sockaddr *remot } if (remote_addr->sa_family == AF_INET) { - if (hdhomerun_discover_is_ipv4_localhost(remote_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv4_localhost(remote_addr)) { return (flags & HDHOMERUN_DISCOVER_FLAGS_IPV4_LOCALHOST) != 0; } @@ -1249,11 +1192,11 @@ static bool hdhomerun_discover_recvfrom(struct hdhomerun_discover_t *ds, struct static uint32_t hdhomerun_discover2_find_devices_targeted_flags(const struct sockaddr *target_addr) { if (target_addr->sa_family == AF_INET6) { - if (hdhomerun_discover_is_ipv6_localhost(target_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv6_localhost(target_addr)) { return HDHOMERUN_DISCOVER_FLAGS_IPV6_LOCALHOST; } - if (hdhomerun_discover_is_ipv6_linklocal(target_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv6_linklocal(target_addr)) { return HDHOMERUN_DISCOVER_FLAGS_IPV6_LINKLOCAL; } @@ -1261,7 +1204,7 @@ static uint32_t hdhomerun_discover2_find_devices_targeted_flags(const struct soc } if (target_addr->sa_family == AF_INET) { - if (hdhomerun_discover_is_ipv4_localhost(target_addr)) { + if (hdhomerun_sock_sockaddr_is_ipv4_localhost(target_addr)) { return HDHOMERUN_DISCOVER_FLAGS_IPV4_LOCALHOST; } @@ -1500,12 +1443,12 @@ bool hdhomerun_discover2_device_if_addr_is_ipv4(struct hdhomerun_discover2_devic bool hdhomerun_discover2_device_if_addr_is_ipv6_linklocal(struct hdhomerun_discover2_device_if_t *device_if) { - return hdhomerun_discover_is_ipv6_linklocal((const struct sockaddr *)&device_if->ip_addr); + return hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&device_if->ip_addr); } uint32_t hdhomerun_discover2_device_if_get_ipv6_linklocal_scope_id(struct hdhomerun_discover2_device_if_t *device_if) { - if (!hdhomerun_discover_is_ipv6_linklocal((const struct sockaddr *)&device_if->ip_addr)) { + if (!hdhomerun_sock_sockaddr_is_ipv6_linklocal((const struct sockaddr *)&device_if->ip_addr)) { return 0; } @@ -1741,21 +1684,15 @@ bool hdhomerun_discover_validate_device_id(uint32_t device_id) bool hdhomerun_discover_is_ip_multicast(uint32_t ip_addr) { - return (ip_addr >= 0xE0000000) && (ip_addr < 0xF0000000); + struct sockaddr_in addr_in; + memset(&addr_in, 0, sizeof(struct sockaddr_in)); + addr_in.sin_family = AF_INET; + addr_in.sin_addr.s_addr = htonl(ip_addr); + + return hdhomerun_sock_sockaddr_is_multicast((const struct sockaddr *)&addr_in); } bool hdhomerun_discover_is_ip_multicast_ex(const struct sockaddr *ip_addr) { - if (ip_addr->sa_family == AF_INET6) { - const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *)ip_addr; - return (addr_in6->sin6_addr.s6_addr[0] == 0xFF); - } - - if (ip_addr->sa_family == AF_INET) { - const struct sockaddr_in *addr_in = (const struct sockaddr_in *)ip_addr; - uint32_t v = ntohl(addr_in->sin_addr.s_addr); - return (v >= 0xE0000000) && (v < 0xF0000000); - } - - return false; + return hdhomerun_sock_sockaddr_is_multicast(ip_addr); } diff --git a/hdhomerun_sock.c b/hdhomerun_sock.c index 2180a61..428ca00 100644 --- a/hdhomerun_sock.c +++ b/hdhomerun_sock.c @@ -46,6 +46,79 @@ bool hdhomerun_sock_sockaddr_is_addr(const struct sockaddr *addr) return false; } +bool hdhomerun_sock_sockaddr_is_multicast(const struct sockaddr *ip_addr) +{ + if (ip_addr->sa_family == AF_INET6) { + const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *)ip_addr; + return (addr_in6->sin6_addr.s6_addr[0] == 0xFF); + } + + if (ip_addr->sa_family == AF_INET) { + const struct sockaddr_in *addr_in = (const struct sockaddr_in *)ip_addr; + uint32_t v = ntohl(addr_in->sin_addr.s_addr); + return (v >= 0xE0000000) && (v < 0xF0000000); + } + + return false; +} + +bool hdhomerun_sock_sockaddr_is_ipv4_localhost(const struct sockaddr *ip_addr) +{ + if (ip_addr->sa_family != AF_INET) { + return false; + } + + const struct sockaddr_in *sock_addr_in = (const struct sockaddr_in *)ip_addr; + uint8_t *addr_bytes = (uint8_t *)&sock_addr_in->sin_addr.s_addr; + return (addr_bytes[0] == 0x7F); +} + +bool hdhomerun_sock_sockaddr_is_ipv4_autoip(const struct sockaddr *ip_addr) +{ + if (ip_addr->sa_family != AF_INET) { + return false; + } + + const struct sockaddr_in *sock_addr_in = (const struct sockaddr_in *)ip_addr; + uint8_t *addr_bytes = (uint8_t *)&sock_addr_in->sin_addr.s_addr; + return (addr_bytes[0] == 169) && (addr_bytes[1] == 254); +} + +bool hdhomerun_sock_sockaddr_is_ipv6_localhost(const struct sockaddr *ip_addr) +{ + if (ip_addr->sa_family != AF_INET6) { + return false; + } + + const struct sockaddr_in6 *sock_addr_in6 = (const struct sockaddr_in6 *)ip_addr; + uint8_t *addr_bytes = (uint8_t *)sock_addr_in6->sin6_addr.s6_addr; + + static uint8_t hdhomerun_discover_ipv6_localhost_bytes[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + return (memcmp(addr_bytes, hdhomerun_discover_ipv6_localhost_bytes, 16) == 0); +} + +bool hdhomerun_sock_sockaddr_is_ipv6_linklocal(const struct sockaddr *addr) +{ + if (addr->sa_family != AF_INET6) { + return false; + } + + const struct sockaddr_in6 *addr_in6 = (const struct sockaddr_in6 *)addr; + uint8_t *addr_bytes = (uint8_t *)addr_in6->sin6_addr.s6_addr; + return (addr_bytes[0] == 0xFE) && ((addr_bytes[1] & 0xC0) == 0x80); +} + +bool hdhomerun_sock_sockaddr_is_ipv6_global(const struct sockaddr *ip_addr) +{ + if (ip_addr->sa_family != AF_INET6) { + return false; + } + + const struct sockaddr_in6 *sock_addr_in6 = (const struct sockaddr_in6 *)ip_addr; + uint8_t *addr_bytes = (uint8_t *)sock_addr_in6->sin6_addr.s6_addr; + return ((addr_bytes[0] & 0xE0) == 0x20); +} + uint16_t hdhomerun_sock_sockaddr_get_port(const struct sockaddr *addr) { if (addr->sa_family == AF_INET6) { diff --git a/hdhomerun_sock.h b/hdhomerun_sock.h index 892a7cc..67dfcb2 100644 --- a/hdhomerun_sock.h +++ b/hdhomerun_sock.h @@ -38,6 +38,12 @@ extern "C" { */ extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_addr(const struct sockaddr *addr); +extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_multicast(const struct sockaddr *ip_addr); +extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_ipv4_localhost(const struct sockaddr *addr); +extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_ipv4_autoip(const struct sockaddr *addr); +extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_ipv6_localhost(const struct sockaddr *addr); +extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_ipv6_linklocal(const struct sockaddr *addr); +extern LIBHDHOMERUN_API bool hdhomerun_sock_sockaddr_is_ipv6_global(const struct sockaddr *addr); extern LIBHDHOMERUN_API uint16_t hdhomerun_sock_sockaddr_get_port(const struct sockaddr *addr); extern LIBHDHOMERUN_API void hdhomerun_sock_sockaddr_set_port(struct sockaddr *addr, uint16_t port); extern LIBHDHOMERUN_API void hdhomerun_sock_sockaddr_copy(struct sockaddr_storage *result, const struct sockaddr *addr); diff --git a/hdhomerun_sock_getifaddrs.c b/hdhomerun_sock_getifaddrs.c index 6c105cf..e358bf6 100644 --- a/hdhomerun_sock_getifaddrs.c +++ b/hdhomerun_sock_getifaddrs.c @@ -87,8 +87,15 @@ bool hdhomerun_local_ip_info2(int af, hdhomerun_local_ip_info2_callback_t callba continue; } - unsigned int flags = ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_UP | IFF_RUNNING | IFF_MULTICAST); - if (flags != (IFF_UP | IFF_RUNNING | IFF_MULTICAST)) { + if ((ifa->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) { + ifa = ifa->ifa_next; + continue; + } + if ((ifa->ifa_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) { + ifa = ifa->ifa_next; + continue; + } + if ((ifa->ifa_addr->sa_family == AF_INET6) && ((ifa->ifa_flags & IFF_MULTICAST) == 0)) { ifa = ifa->ifa_next; continue; } diff --git a/hdhomerun_sock_netdevice.c b/hdhomerun_sock_netdevice.c index 39dd3f6..cd3eb2b 100644 --- a/hdhomerun_sock_netdevice.c +++ b/hdhomerun_sock_netdevice.c @@ -98,8 +98,10 @@ bool hdhomerun_local_ip_info2(int af, hdhomerun_local_ip_info2_callback_t callba continue; } - unsigned int flags = ifr->ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_UP | IFF_RUNNING | IFF_MULTICAST); - if (flags != (IFF_UP | IFF_RUNNING | IFF_MULTICAST)) { + if ((ifr->ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) { + continue; + } + if ((ifr->ifr_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) { continue; } diff --git a/hdhomerun_sock_netlink.c b/hdhomerun_sock_netlink.c index 83e94a1..87080dd 100644 --- a/hdhomerun_sock_netlink.c +++ b/hdhomerun_sock_netlink.c @@ -61,13 +61,17 @@ static void hdhomerun_local_ip_info2_newaddr(int af_sock, struct nlmsghdr *hdr, return; } - uint32_t flags = ifr.ifr_flags; - flags &= (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_UP | IFF_RUNNING | IFF_MULTICAST); - if (flags != (IFF_UP | IFF_RUNNING | IFF_MULTICAST)) { + if ((ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) { + return; + } + if ((ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) { + return; + } + if ((addrmsg->ifa_family == AF_INET6) && ((ifr.ifr_flags & IFF_MULTICAST) == 0)) { return; } - /* addresses */ + /* addresses */ size_t ifa_payload_length = IFA_PAYLOAD(hdr); struct rtattr *rta = IFA_RTA(addrmsg); while (1) { @@ -177,7 +181,7 @@ bool hdhomerun_local_ip_info2(int af, hdhomerun_local_ip_info2_callback_t callba struct nlmsghdr *hdr = (struct nlmsghdr *)nl_buffer; while (1) { - if (!NLMSG_OK(hdr, length)) { + if (!NLMSG_OK(hdr, (unsigned int)length)) { break; }