Skip to content

Commit a0c80dc

Browse files
committed
Rewrite the iterator function logic
1 parent 2606322 commit a0c80dc

File tree

2 files changed

+92
-51
lines changed

2 files changed

+92
-51
lines changed

src/adapter.rs

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -312,23 +312,27 @@ impl Adapter {
312312
let mut adapter_addresses = vec![];
313313

314314
util::get_adapters_addresses(|adapter| {
315-
let name_iter = unsafe { util::win_pstr_to_string(adapter.AdapterName) }?;
315+
let name_iter = match unsafe { util::win_pstr_to_string(adapter.AdapterName) } {
316+
Ok(name) => name,
317+
Err(err) => {
318+
log::error!("Failed to parse adapter name: {}", err);
319+
return false;
320+
}
321+
};
316322
if name_iter == name {
317323
let mut current_address = adapter.FirstUnicastAddress;
318324
while !current_address.is_null() {
319325
let address = unsafe { (*current_address).Address };
320-
let address = util::retrieve_ipaddr_from_socket_address(&address);
321-
if let Err(err) = address {
322-
log::error!("Failed to parse address: {}", err);
323-
} else {
324-
adapter_addresses.push(address?);
325-
}
326-
unsafe {
327-
current_address = (*current_address).Next;
326+
match util::retrieve_ipaddr_from_socket_address(&address) {
327+
Ok(addr) => adapter_addresses.push(addr),
328+
Err(err) => {
329+
log::error!("Failed to parse address: {}", err);
330+
}
328331
}
332+
unsafe { current_address = (*current_address).Next };
329333
}
330334
}
331-
Ok(())
335+
true
332336
})?;
333337

334338
Ok(adapter_addresses)
@@ -339,23 +343,27 @@ impl Adapter {
339343
let name = util::guid_to_win_style_string(&GUID::from_u128(self.guid))?;
340344
let mut gateways = vec![];
341345
util::get_adapters_addresses(|adapter| {
342-
let name_iter = unsafe { util::win_pstr_to_string(adapter.AdapterName) }?;
346+
let name_iter = match unsafe { util::win_pstr_to_string(adapter.AdapterName) } {
347+
Ok(name) => name,
348+
Err(err) => {
349+
log::error!("Failed to parse adapter name: {}", err);
350+
return false;
351+
}
352+
};
343353
if name_iter == name {
344354
let mut current_gateway = adapter.FirstGatewayAddress;
345355
while !current_gateway.is_null() {
346356
let gateway = unsafe { (*current_gateway).Address };
347-
let gateway = util::retrieve_ipaddr_from_socket_address(&gateway);
348-
if let Err(err) = gateway {
349-
log::error!("Failed to parse gateway: {}", err);
350-
} else {
351-
gateways.push(gateway?);
352-
}
353-
unsafe {
354-
current_gateway = (*current_gateway).Next;
357+
match util::retrieve_ipaddr_from_socket_address(&gateway) {
358+
Ok(addr) => gateways.push(addr),
359+
Err(err) => {
360+
log::error!("Failed to parse gateway: {}", err);
361+
}
355362
}
363+
unsafe { current_gateway = (*current_gateway).Next };
356364
}
357365
}
358-
Ok(())
366+
true
359367
})?;
360368
Ok(gateways)
361369
}
@@ -365,39 +373,55 @@ impl Adapter {
365373
let name = util::guid_to_win_style_string(&GUID::from_u128(self.guid))?;
366374
let mut subnet_mask = None;
367375
util::get_adapters_addresses(|adapter| {
368-
let name_iter = unsafe { util::win_pstr_to_string(adapter.AdapterName) }?;
376+
let name_iter = match unsafe { util::win_pstr_to_string(adapter.AdapterName) } {
377+
Ok(name) => name,
378+
Err(err) => {
379+
log::warn!("Failed to parse adapter name: {}", err);
380+
return false;
381+
}
382+
};
369383
if name_iter == name {
370384
let mut current_address = adapter.FirstUnicastAddress;
371385
while !current_address.is_null() {
372386
let address = unsafe { (*current_address).Address };
373-
let address = util::retrieve_ipaddr_from_socket_address(&address);
374-
if let Err(ref err) = address {
375-
log::warn!("Failed to parse address: {}", err);
376-
}
377-
let address = address?;
387+
let address = match util::retrieve_ipaddr_from_socket_address(&address) {
388+
Ok(addr) => addr,
389+
Err(err) => {
390+
log::warn!("Failed to parse address: {}", err);
391+
return false;
392+
}
393+
};
378394
if address == *target_address {
379395
let masklength = unsafe { (*current_address).OnLinkPrefixLength };
380396
match address {
381397
IpAddr::V4(_) => {
382398
let mut mask = 0_u32;
383399
match unsafe { ConvertLengthToIpv4Mask(masklength as u32, &mut mask as *mut u32) } {
384400
0 => {}
385-
err => return Err(std::io::Error::from_raw_os_error(err as i32).into()),
401+
err => {
402+
log::warn!("Failed to convert length to mask: {}", err);
403+
return false;
404+
}
386405
}
387406
subnet_mask = Some(IpAddr::V4(Ipv4Addr::from(mask.to_le_bytes())));
388407
}
389408
IpAddr::V6(_) => {
390-
subnet_mask = Some(IpAddr::V6(util::ipv6_netmask_for_prefix(masklength)?));
409+
let v = match util::ipv6_netmask_for_prefix(masklength) {
410+
Ok(v) => v,
411+
Err(err) => {
412+
log::warn!("Failed to convert length to mask: {}", err);
413+
return false;
414+
}
415+
};
416+
subnet_mask = Some(IpAddr::V6(v));
391417
}
392418
}
393419
break;
394420
}
395-
unsafe {
396-
current_address = (*current_address).Next;
397-
}
421+
unsafe { current_address = (*current_address).Next };
398422
}
399423
}
400-
Ok(())
424+
true
401425
})?;
402426

403427
Ok(subnet_mask.ok_or("Unable to find matching address")?)

src/util.rs

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,19 @@ pub fn get_active_network_interface_gateways() -> std::io::Result<Vec<IpAddr>> {
135135
{
136136
let sockaddr_ptr = gateway.Address.lpSockaddr;
137137
let sockaddr = unsafe { &*(sockaddr_ptr as *const SOCKADDR) };
138-
let a = unsafe { sockaddr_to_socket_addr(sockaddr) }?;
138+
let a = match unsafe { sockaddr_to_socket_addr(sockaddr) } {
139+
Ok(a) => a,
140+
Err(e) => {
141+
log::error!("Failed to convert sockaddr to socket address: {}", e);
142+
return false;
143+
}
144+
};
139145
addrs.push(a.ip());
140146
}
141147
current_gateway = gateway.Next;
142148
}
143149
}
144-
Ok(())
150+
true
145151
})?;
146152
Ok(addrs)
147153
}
@@ -237,7 +243,7 @@ pub(crate) unsafe fn sockaddr_in6_to_socket_addr(sockaddr_in6: &SOCKADDR_IN6) ->
237243

238244
pub(crate) fn get_adapters_addresses<F>(mut callback: F) -> Result<(), Error>
239245
where
240-
F: FnMut(IP_ADAPTER_ADDRESSES_LH) -> Result<(), Error>,
246+
F: FnMut(IP_ADAPTER_ADDRESSES_LH) -> bool,
241247
{
242248
let mut size = 0;
243249
let flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS;
@@ -276,7 +282,9 @@ where
276282
let mut current_addresses = addresses.as_ptr() as *const IP_ADAPTER_ADDRESSES_LH;
277283
while !current_addresses.is_null() {
278284
unsafe {
279-
callback(*current_addresses)?;
285+
if !callback(*current_addresses) {
286+
break;
287+
}
280288
current_addresses = (*current_addresses).Next;
281289
}
282290
}
@@ -285,7 +293,7 @@ where
285293

286294
fn get_interface_info_sys<F>(mut callback: F) -> Result<(), Error>
287295
where
288-
F: FnMut(IP_ADAPTER_INDEX_MAP) -> Result<(), Error>,
296+
F: FnMut(IP_ADAPTER_INDEX_MAP) -> bool,
289297
{
290298
let mut buf_len: u32 = 0;
291299
//First figure out the size of the buffer needed to store the adapter info
@@ -357,7 +365,9 @@ where
357365
let interfaces = unsafe { std::slice::from_raw_parts(first_adapter, adapter_count as usize) };
358366

359367
for interface in interfaces {
360-
callback(*interface)?;
368+
if !callback(*interface) {
369+
break;
370+
}
361371
}
362372
Ok(())
363373
}
@@ -366,16 +376,24 @@ where
366376
pub(crate) fn get_interface_info() -> Result<Vec<(u32, String)>, Error> {
367377
let mut v = vec![];
368378
get_interface_info_sys(|mut interface| {
369-
let name = unsafe { win_pwstr_to_string(&mut interface.Name as _)? };
379+
let name = match unsafe { win_pwstr_to_string(&mut interface.Name as _) } {
380+
Ok(name) => name,
381+
Err(e) => {
382+
log::error!("Failed to convert interface name: {}", e);
383+
return false;
384+
}
385+
};
370386
// Nam is something like: \DEVICE\TCPIP_{29C47F55-C7BD-433A-8BF7-408DFD3B3390}
371387
// where the GUID is the {29C4...90}, separated by dashes
372-
let guid = name
373-
.split('{')
374-
.nth(1)
375-
.and_then(|s| s.split('}').next())
376-
.ok_or(format!("Failed to find GUID inside adapter name: {}", name))?;
377-
v.push((interface.Index, guid.to_string()));
378-
Ok(())
388+
let guid = match name.split('{').nth(1).and_then(|s| s.split('}').next()) {
389+
Some(guid) => guid.to_string(),
390+
None => {
391+
log::error!("Failed to extract GUID from interface name: {}", name);
392+
return false;
393+
}
394+
};
395+
v.push((interface.Index, guid));
396+
true
379397
})?;
380398
Ok(v)
381399
}
@@ -538,7 +556,7 @@ pub(crate) fn get_mtu_by_index(index: u32, is_ipv6: bool) -> std::io::Result<u32
538556
if item.InterfaceIndex == index {
539557
mtu = Some(item.NlMtu);
540558
}
541-
Ok(())
559+
true
542560
},
543561
is_ipv6,
544562
)?;
@@ -555,7 +573,7 @@ pub fn decode_utf16(string: &[u16]) -> String {
555573

556574
pub fn get_ip_interface_table<F>(mut callback: F, is_ipv6: bool) -> std::io::Result<()>
557575
where
558-
F: FnMut(&MIB_IPINTERFACE_ROW) -> std::io::Result<()>,
576+
F: FnMut(&MIB_IPINTERFACE_ROW) -> bool,
559577
{
560578
let mut if_table: *mut MIB_IPINTERFACE_TABLE = std::ptr::null_mut();
561579
unsafe {
@@ -568,9 +586,8 @@ where
568586
use std::slice::from_raw_parts;
569587
let ifaces = from_raw_parts::<MIB_IPINTERFACE_ROW>(&(*if_table).Table[0], (*if_table).NumEntries as usize);
570588
for item in ifaces {
571-
if let Err(e) = callback(item) {
572-
FreeMibTable(if_table as _);
573-
return Err(e);
589+
if !callback(item) {
590+
break;
574591
}
575592
}
576593
FreeMibTable(if_table as _);

0 commit comments

Comments
 (0)