1515 */
1616
1717use std:: {
18+ ffi:: CStr ,
1819 net:: { IpAddr , Ipv4Addr , Ipv6Addr } ,
1920 ptr,
2021} ;
2122
22- use log:: { debug, warn} ;
23+ use log:: { debug, trace , warn} ;
2324use pcap;
2425use regex:: Regex ;
2526use windows:: Win32 :: {
2627 Foundation :: { CHAR , ERROR_BUFFER_OVERFLOW , NO_ERROR } ,
2728 NetworkManagement :: IpHelper :: {
2829 GetAdaptersAddresses , GetBestInterfaceEx , GetBestRoute2 , IfOperStatusUp ,
2930 ResolveIpNetEntry2 , AF_INET , AF_INET6 , AF_UNSPEC , GAA_FLAG_INCLUDE_ALL_INTERFACES ,
30- IP_ADAPTER_ADDRESSES_LH , IP_ADAPTER_ADDRESSES_LH_0 , IP_ADAPTER_ADDRESSES_LH_0_0 ,
31- MIB_IPFORWARD_ROW2 , MIB_IPNET_ROW2 ,
31+ GAA_FLAG_INCLUDE_PREFIX , IP_ADAPTER_ADDRESSES_LH , IP_ADAPTER_ADDRESSES_LH_0 ,
32+ IP_ADAPTER_ADDRESSES_LH_0_0 , MIB_IPFORWARD_ROW2 , MIB_IPNET_ROW2 ,
3233 } ,
3334 Networking :: WinSock :: {
3435 IN6_ADDR , IN6_ADDR_0 , IN_ADDR , IN_ADDR_0 , SOCKADDR , SOCKADDR_IN , SOCKADDR_IN6 ,
@@ -100,7 +101,7 @@ pub fn neighbor_lookup(mut dest_addr: IpAddr) -> Result<NeighborEntry> {
100101 ) ) ) ;
101102 }
102103
103- let link = get_interface_by_index ( route. oif_index ) ?;
104+ let link = get_interface_by_index_from_pcap ( route. oif_index ) ?;
104105
105106 let mac_addr = MacAddr (
106107 ipnet_row
@@ -124,7 +125,74 @@ pub fn neighbor_lookup(mut dest_addr: IpAddr) -> Result<NeighborEntry> {
124125 } )
125126}
126127
127- pub fn get_interface_by_index ( if_index : u32 ) -> Result < Link > {
128+ pub fn get_interface_by_index_from_win32 ( if_index : u32 ) -> Result < Link > {
129+ let family = AF_UNSPEC as u32 ;
130+ let flags = GAA_FLAG_INCLUDE_PREFIX ;
131+ let mut buffer_len: u32 = 0 ;
132+
133+ unsafe {
134+ let result = GetAdaptersAddresses (
135+ family,
136+ flags,
137+ ptr:: null_mut ( ) ,
138+ ptr:: null_mut ( ) ,
139+ & mut buffer_len,
140+ ) ;
141+
142+ if result != 111 {
143+ return Err ( Error :: Windows ( format ! (
144+ "Get buffer len by GetAdaptersAddresses failed error code {}" ,
145+ result
146+ ) ) ) ;
147+ }
148+ }
149+
150+ let mut buffer = vec ! [ 0u8 ; buffer_len as usize ] ;
151+ let adapter_addresses = buffer. as_mut_ptr ( ) as * mut IP_ADAPTER_ADDRESSES_LH ;
152+
153+ unsafe {
154+ let result = GetAdaptersAddresses (
155+ family,
156+ flags,
157+ ptr:: null_mut ( ) ,
158+ adapter_addresses,
159+ & mut buffer_len,
160+ ) ;
161+ if result != 0 {
162+ return Err ( Error :: Windows ( format ! (
163+ "Get adapter addresses by GetAdaptersAddresses failed error code {}" ,
164+ result
165+ ) ) ) ;
166+ }
167+ }
168+
169+ let mut current_adapter = adapter_addresses;
170+ while !current_adapter. is_null ( ) {
171+ let mac_address = unsafe {
172+ let adapter_ref = & * current_adapter;
173+ if if_index != adapter_ref. Anonymous1 . Anonymous . IfIndex {
174+ current_adapter = adapter_ref. Next ;
175+ continue ;
176+ }
177+ if adapter_ref. PhysicalAddressLength == 6 {
178+ std:: slice:: from_raw_parts (
179+ adapter_ref. PhysicalAddress . as_ptr ( ) ,
180+ adapter_ref. PhysicalAddressLength as usize ,
181+ )
182+ } else {
183+ & [ 0 , 0 , 0 , 0 , 0 , 0 ]
184+ }
185+ } ;
186+ let mut link = Link :: default ( ) ;
187+ link. if_index = if_index;
188+ link. mac_addr = MacAddr :: try_from ( mac_address) . unwrap_or_default ( ) ;
189+ return Ok ( link) ;
190+ }
191+
192+ Err ( Error :: Windows ( format ! ( "Not found if_index {}" , if_index) ) )
193+ }
194+
195+ fn get_interface_by_index_from_pcap ( if_index : u32 ) -> Result < Link > {
128196 let adapters = get_pcap_interfaces ( ) ?;
129197 debug ! ( "adapters: {:?}, if_index: {}" , adapters. clone( ) , if_index) ;
130198 adapters
@@ -194,7 +262,8 @@ pub fn links_by_name_regex<S: AsRef<str>>(regex: S) -> Result<Vec<Link>> {
194262
195263pub fn get_route_src_ip_and_mac ( dest_addr : & IpAddr ) -> Result < ( IpAddr , MacAddr ) > {
196264 route_get ( * dest_addr) . and_then ( |r| {
197- get_interface_by_index ( r. oif_index ) . map ( |link| ( r. pref_src . unwrap ( ) , link. mac_addr ) )
265+ get_interface_by_index_from_win32 ( r. oif_index )
266+ . map ( |link| ( r. pref_src . unwrap ( ) , link. mac_addr ) )
198267 } )
199268}
200269
0 commit comments