add IPv6 default route interface auto-detection for permanent/temporary IPv6 without netif
- get_default_route_netif_index(): UDP connect trick + getifaddrs to find default route iface - etcp_socket_add(): auto-detect netif_index when not specified in config - queue_new() API: explicit index_offset/index_size params instead of implicit from hash_size - radix: cleanup types (uint8_t*), replace bzero/bcmp with memset/memcmp, remove kernel ifdefs - route6_lib: new IPv6 routing library + get_node_v6_routes()
This commit is contained in:
1 parent
e1f051856f
commit
c24a6367cc
65 files changed
+34811
-556
No files matched your search
@@ -105,6 +105,80 @@ int get_interface_ipv6_by_index(uint32_t netif_index, int temporary, uint8_t* ad
|
||||
freeifaddrs(ifaddr);
|
||||
return found ? 0 : -1;
|
||||
}
|
||||
|
||||
uint32_t get_default_route_netif_index(int family) {
|
||||
if (family != AF_INET && family != AF_INET6) return 0;
|
||||
|
||||
int sock = socket(family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock < 0) return 0;
|
||||
|
||||
struct sockaddr_storage bind_addr;
|
||||
memset(&bind_addr, 0, sizeof(bind_addr));
|
||||
if (family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&bind_addr;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_addr.s_addr = INADDR_ANY;
|
||||
} else {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&bind_addr;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_addr = in6addr_any;
|
||||
}
|
||||
|
||||
socklen_t bind_len = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
|
||||
if (bind(sock, (struct sockaddr*)&bind_addr, bind_len) != 0) { close(sock); return 0; }
|
||||
|
||||
struct sockaddr_storage remote;
|
||||
memset(&remote, 0, sizeof(remote));
|
||||
socklen_t remote_len;
|
||||
if (family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&remote;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons(53);
|
||||
inet_pton(AF_INET, "8.8.8.8", &sin->sin_addr);
|
||||
remote_len = sizeof(struct sockaddr_in);
|
||||
} else {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&remote;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = htons(53);
|
||||
inet_pton(AF_INET6, "2001:4860:4860::8888", &sin6->sin6_addr);
|
||||
remote_len = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
|
||||
if (connect(sock, (struct sockaddr*)&remote, remote_len) != 0) { close(sock); return 0; }
|
||||
|
||||
struct sockaddr_storage src;
|
||||
socklen_t src_len = sizeof(src);
|
||||
if (getsockname(sock, (struct sockaddr*)&src, &src_len) != 0) { close(sock); return 0; }
|
||||
|
||||
close(sock);
|
||||
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
if (getifaddrs(&ifaddr) == -1) return 0;
|
||||
|
||||
uint32_t result = 0;
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL) continue;
|
||||
if (ifa->ifa_addr->sa_family != family) continue;
|
||||
if (family == AF_INET) {
|
||||
struct sockaddr_in* src_sin = (struct sockaddr_in*)&src;
|
||||
struct sockaddr_in* ifa_sin = (struct sockaddr_in*)ifa->ifa_addr;
|
||||
if (src_sin->sin_addr.s_addr == ifa_sin->sin_addr.s_addr) {
|
||||
if (ifa->ifa_name) result = if_nametoindex(ifa->ifa_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
struct sockaddr_in6* src_sin6 = (struct sockaddr_in6*)&src;
|
||||
struct sockaddr_in6* ifa_sin6 = (struct sockaddr_in6*)ifa->ifa_addr;
|
||||
if (memcmp(&src_sin6->sin6_addr, &ifa_sin6->sin6_addr, 16) == 0) {
|
||||
if (ifa->ifa_name) result = if_nametoindex(ifa->ifa_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
uint32_t get_interface_ip_by_index(uint32_t netif_index) {
|
||||
(void)netif_index;
|
||||
@@ -116,4 +190,9 @@ int get_interface_ipv6_by_index(uint32_t netif_index, int temporary, uint8_t* ad
|
||||
if (addr_out) memset(addr_out, 0, 16);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t get_default_route_netif_index(int family) {
|
||||
(void)family;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user