@ -138,10 +138,9 @@ static int ip_route_cmd(const char *ifname, uint32_t network, uint8_t prefix_len
return ( ret = = 0 ) ? 0 : - 1 ;
}
int tun_route_add ( const char * ifname , uint32_t network , uint8_t prefix_len ) {
int ifindex = if_nametoindex ( ifname ) ;
int tun_route_add ( uint32_t ifindex , uint32_t network , uint8_t prefix_len ) {
if ( ifindex = = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Interface %s not found " , ifname ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Interface index is 0 " ) ;
return - 1 ;
}
@ -153,7 +152,9 @@ int tun_route_add(const char *ifname, uint32_t network, uint8_t prefix_len) {
}
// Fallback to ip route command
DEBUG_WARN ( DEBUG_CATEGORY_TUN , " Netlink failed, trying ip route command for %s " , ifname ) ;
DEBUG_WARN ( DEBUG_CATEGORY_TUN , " Netlink failed, trying ip route command for ifindex %u " , ifindex ) ;
char ifname [ 16 ] ;
snprintf ( ifname , sizeof ( ifname ) , " %u " , ifindex ) ;
return ip_route_cmd ( ifname , ntohl ( network ) , prefix_len , " add " ) ;
}
@ -198,16 +199,36 @@ int tun_route_flush(const char *ifname) {
// Windows IP Helper API implementation
int tun_route_add ( const char * ifname , uint32_t network , uint8_t prefix_len ) {
int tun_route_add ( uint32_t ifindex , uint32_t network , uint8_t prefix_len ) {
if ( ifindex = = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " tun_route_add: ifindex is 0 " ) ;
return - 1 ;
}
uint32_t dest = htonl ( network ) ;
uint32_t mask = prefix_to_netmask ( prefix_len ) ;
char cmd [ 256 ] ;
struct in_addr dest_addr ;
dest_addr . s_addr = dest ;
snprintf ( cmd , sizeof ( cmd ) , " netsh interface ip add route %s/%d interface=%lu store=active " ,
inet_ntoa ( dest_addr ) , prefix_len , ( unsigned long ) ifindex ) ;
int sys_ret = system ( cmd ) ;
if ( sys_ret = = 0 ) {
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " Added route %s/%d via ifindex=%lu " ,
inet_ntoa ( dest_addr ) , prefix_len , ( unsigned long ) ifindex ) ;
return 0 ;
}
MIB_IPFORWARDROW route ;
memset ( & route , 0 , sizeof ( route ) ) ;
route . dwForwardDest = htonl ( network ) ;
route . dwForwardMask = prefix_to_netmask ( prefix_len ) ;
route . dwForwardDest = dest ;
route . dwForwardMask = mask ;
route . dwForwardPolicy = 0 ;
route . dwForwardNextHop = 0 ; // On-link route
route . dwForwardIfIndex = if_nametoindex ( ifname ) ;
route . dwForwardType = MIB_IPROUTE_TYPE_DIRECT ;
route . dwForwardNextHop = 0 ;
route . dwForwardIfIndex = ifindex ;
route . dwForwardType = MIB_IPROUTE_TYPE_IN DIRECT ;
route . dwForwardProto = MIB_IPPROTO_NETMGMT ;
route . dwForwardAge = 0 ;
route . dwForwardNextHopAS = 0 ;
@ -219,7 +240,8 @@ int tun_route_add(const char *ifname, uint32_t network, uint8_t prefix_len) {
DWORD ret = CreateIpForwardEntry ( & route ) ;
if ( ret ! = NO_ERROR ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to add route: %lu " , ret ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Failed to add route %s/%d: %lu " ,
inet_ntoa ( dest_addr ) , prefix_len , ret ) ;
return - 1 ;
}
return 0 ;
@ -356,10 +378,9 @@ static int route_cmd(const char *ifname, uint32_t network, uint8_t prefix_len, c
return ( ret = = 0 ) ? 0 : - 1 ;
}
int tun_route_add ( const char * ifname , uint32_t network , uint8_t prefix_len ) {
int ifindex = if_nametoindex ( ifname ) ;
int tun_route_add ( uint32_t ifindex , uint32_t network , uint8_t prefix_len ) {
if ( ifindex = = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Interface %s not found " , ifname ) ;
DEBUG_ERROR ( DEBUG_CATEGORY_TUN , " Interface index is 0 " ) ;
return - 1 ;
}
@ -369,7 +390,9 @@ int tun_route_add(const char *ifname, uint32_t network, uint8_t prefix_len) {
}
// Fallback to route command
DEBUG_WARN ( DEBUG_CATEGORY_TUN , " Routing socket failed, trying route command for %s " , ifname ) ;
DEBUG_WARN ( DEBUG_CATEGORY_TUN , " Routing socket failed, trying route command for ifindex %u " , ifindex ) ;
char ifname [ 16 ] ;
snprintf ( ifname , sizeof ( ifname ) , " %u " , ifindex ) ;
return route_cmd ( ifname , network , prefix_len , " add " ) ;
}
@ -406,14 +429,14 @@ int tun_route_flush(const char *ifname) {
// Platform-independent functions
int tun_route_add_all ( const char * ifname , struct CFG_ROUTE_ENTRY * routes ) {
int tun_route_add_all ( uint32_t ifindex , const char * ifname , struct CFG_ROUTE_ENTRY * routes ) {
int count = 0 ;
struct CFG_ROUTE_ENTRY * entry = routes ;
while ( entry ) {
uint32_t network = ntohl ( entry - > ip . addr . v4 . s_addr ) ;
if ( entry - > ip . family = = AF_INET ) {
if ( tun_route_add ( ifname , network , entry - > netmask ) = = 0 ) {
if ( tun_route_add ( ifindex , network , entry - > netmask ) = = 0 ) {
struct in_addr addr ;
addr . s_addr = entry - > ip . addr . v4 . s_addr ;
DEBUG_INFO ( DEBUG_CATEGORY_TUN , " Added route %s/%d via %s " , ip_to_str ( & addr , AF_INET ) . str , entry - > netmask , ifname ) ;