1
- use std:: { io, marker:: Unpin } ;
1
+ use std:: {
2
+ io:: { self , ErrorKind } ,
3
+ marker:: Unpin ,
4
+ mem,
5
+ } ;
2
6
7
+ use log:: { error, trace} ;
3
8
use tokio:: io:: { AsyncWrite , AsyncWriteExt } ;
4
- use tun:: platform:: Device as TunDevice ;
9
+ use tun:: { platform:: Device as TunDevice , Device } ;
10
+ use windows_sys:: Win32 :: {
11
+ Foundation :: NO_ERROR ,
12
+ NetworkManagement :: IpHelper :: {
13
+ CreateIpForwardEntry ,
14
+ GetBestInterface ,
15
+ MIB_IPFORWARDROW ,
16
+ MIB_IPROUTE_TYPE_INDIRECT ,
17
+ } ,
18
+ Networking :: WinSock :: MIB_IPPROTO_NETMGMT ,
19
+ } ;
5
20
6
21
/// Packet Information length in bytes
7
22
///
@@ -16,6 +31,52 @@ pub async fn write_packet_with_pi<W: AsyncWrite + Unpin>(writer: &mut W, packet:
16
31
}
17
32
18
33
/// Set platform specific route configuration
19
- pub async fn set_route_configuration ( _device : & TunDevice ) -> io:: Result < ( ) > {
34
+ pub async fn set_route_configuration ( device : & TunDevice ) -> io:: Result < ( ) > {
35
+ let tun_address = match device. address ( ) {
36
+ Ok ( t) => t,
37
+ Err ( err) => {
38
+ error ! ( "tun device doesn't have address, error: {}" , err) ;
39
+ return Err ( io:: Error :: new ( ErrorKind :: Other , err) ) ;
40
+ }
41
+ } ;
42
+
43
+ let tun_netmask = match device. netmask ( ) {
44
+ Ok ( m) => m,
45
+ Err ( err) => {
46
+ error ! ( "tun device doesn't have netmask, error: {}" , err) ;
47
+ return Err ( io:: Error :: new ( ErrorKind :: Other , err) ) ;
48
+ }
49
+ } ;
50
+
51
+ unsafe {
52
+ // https://learn.microsoft.com/en-us/windows/win32/api/ipmib/ns-ipmib-mib_ipforwardrow
53
+ let mut ipfrow: MIB_IPFORWARDROW = mem:: zeroed ( ) ;
54
+
55
+ ipfrow. dwForwardDest = u32:: from ( tun_address) ;
56
+ ipfrow. dwForwardMask = u32:: from ( tun_netmask) ;
57
+
58
+ // Get ifindex of this inteface
59
+ // https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getbestinterface
60
+ let mut if_index: u32 = 0 ;
61
+ let ret = GetBestInterface ( ipfrow. dwForwardDest , & mut if_index) ;
62
+ if ret != NO_ERROR {
63
+ error ! ( "GetBestInterface failed, ret: {}, destination: {}" , ret, tun_address) ;
64
+ return Err ( io:: Error :: new ( ErrorKind :: Other , format ! ( "GetBestInterface {}" , ret) ) ) ;
65
+ }
66
+ ipfrow. dwForwardIfIndex = if_index;
67
+
68
+ ipfrow. Anonymous1 . dwForwardType = MIB_IPROUTE_TYPE_INDIRECT as u32 ;
69
+ ipfrow. Anonymous2 . dwForwardProto = MIB_IPPROTO_NETMGMT as u32 ;
70
+
71
+ let status = CreateIpForwardEntry ( & ipfrow) ;
72
+ if status != NO_ERROR {
73
+ error ! ( "CreateIpForwardEntry failed, status: {}" , status) ;
74
+ return Err ( io:: Error :: new (
75
+ ErrorKind :: Other ,
76
+ format ! ( "CreateIpForwardEntry {}" , status) ,
77
+ ) ) ;
78
+ }
79
+ }
80
+
20
81
Ok ( ( ) )
21
82
}
0 commit comments