Skip to content

Commit dbac5c1

Browse files
authored
fix: correct IP address type tests (#1925)
Signed-off-by: John Gardiner Myers <[email protected]>
1 parent d9f133a commit dbac5c1

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

kclvm/runtime/src/net/mod.rs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -352,20 +352,13 @@ pub extern "C-unwind" fn kclvm_net_is_interface_local_multicast_IP(
352352
let args = ptr_as_ref(args);
353353
let kwargs = ptr_as_ref(kwargs);
354354
if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) {
355-
if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) {
356-
// For IPv4, interface-local multicast addresses are in the range 224.0.0.0/24
357-
let is_interface_local =
358-
addr.octets()[0] == 224 && addr.octets()[1] == 0 && addr.octets()[2] == 0;
359-
let x = is_interface_local && addr.is_multicast();
360-
return kclvm_value_Bool(ctx, x as i8);
361-
}
362355
if let Ok(addr) = Ipv6Addr::from_str(ip.as_ref()) {
363-
// For IPv6, interface-local multicast addresses start with ff01::/16
364-
let is_interface_local = addr.segments()[0] == 0xff01;
356+
// For IPv6, interface-local multicast addresses start with ffx1::/16
357+
let is_interface_local = (addr.segments()[0] & 0xff0f) == 0xff01;
365358
let x = is_interface_local && addr.is_multicast();
366359
return kclvm_value_Bool(ctx, x as i8);
367360
}
368-
return kclvm_value_Bool(ctx, 0); // False for invalid IP addresses
361+
return kclvm_value_Bool(ctx, 0); // False for IPv4 and invalid IP addresses
369362
}
370363
panic!("is_interface_local_multicast_IP() missing 1 required positional argument: 'ip'");
371364
}
@@ -391,8 +384,8 @@ pub extern "C-unwind" fn kclvm_net_is_link_local_multicast_IP(
391384
return kclvm_value_Bool(ctx, x as i8);
392385
}
393386
if let Ok(addr) = Ipv6Addr::from_str(ip.as_ref()) {
394-
// For IPv6, link-local multicast addresses start with ff02::/16
395-
let is_link_local_multicast = addr.segments()[0] == 0xff02;
387+
// For IPv6, link-local multicast addresses start with ffx2::/16
388+
let is_link_local_multicast = (addr.segments()[0] & 0xff0f) == 0xff02;
396389
let x = is_link_local_multicast && addr.is_multicast();
397390
return kclvm_value_Bool(ctx, x as i8);
398391
}
@@ -419,8 +412,8 @@ pub extern "C-unwind" fn kclvm_net_is_link_local_unicast_IP(
419412
let x = addr.is_link_local() && (!addr.is_multicast());
420413
return kclvm_value_Bool(ctx, x as i8);
421414
}
422-
if let Ok(_addr) = Ipv6Addr::from_str(ip.as_ref()) {
423-
let x = Ipv6Addr_is_unicast_link_local(&_addr) && (!_addr.is_multicast());
415+
if let Ok(addr) = Ipv6Addr::from_str(ip.as_ref()) {
416+
let x = Ipv6Addr_is_unicast_link_local(&addr) && (!addr.is_multicast());
424417
return kclvm_value_Bool(ctx, x as i8);
425418
}
426419
return kclvm_value_False(ctx);
@@ -429,6 +422,35 @@ pub extern "C-unwind" fn kclvm_net_is_link_local_unicast_IP(
429422
panic!("is_link_local_unicast_IP() missing 1 required positional argument: 'ip'");
430423
}
431424

425+
#[allow(non_camel_case_types, non_snake_case)]
426+
fn Ipv6Addr_is_global(_self: &std::net::Ipv6Addr) -> bool {
427+
let segments = _self.segments();
428+
// 2000::/3 global unicast
429+
if (segments[0] & 0xe000) == 0x2000 {
430+
// 2001:db8::/32 documentation
431+
if segments[0] == 0x2001 && segments[1] == 0xdb8 {
432+
return false;
433+
}
434+
// 2001:2::/48 benchmarking
435+
if segments[0] == 0x2001 && segments[1] == 2 && segments[2] == 0 {
436+
return false;
437+
}
438+
return true;
439+
}
440+
// 64:ff9b::/96 NAT64
441+
if segments[0] == 0x64
442+
&& segments[1] == 0xff9b
443+
&& segments[2] == 0
444+
&& segments[3] == 0
445+
&& segments[4] == 0
446+
&& segments[5] == 0
447+
{
448+
let ipv4 = Ipv4Addr::from(((segments[6] as u32) << 16) + segments[7] as u32);
449+
return Ipv4Addr_is_global(&ipv4) && (!ipv4.is_multicast());
450+
}
451+
return false;
452+
}
453+
432454
#[allow(non_camel_case_types, non_snake_case)]
433455
pub const fn Ipv6Addr_is_unicast_link_local(_self: &Ipv6Addr) -> bool {
434456
(_self.segments()[0] & 0xffc0) == 0xfe80
@@ -452,7 +474,7 @@ pub extern "C-unwind" fn kclvm_net_is_global_unicast_IP(
452474
return kclvm_value_Bool(ctx, x as i8);
453475
}
454476
if let Ok(addr) = Ipv6Addr::from_str(ip.as_ref()) {
455-
return kclvm_value_Bool(ctx, addr.is_multicast() as i8);
477+
return kclvm_value_Bool(ctx, Ipv6Addr_is_global(&addr) as i8);
456478
}
457479

458480
return kclvm_value_False(ctx);

0 commit comments

Comments
 (0)