@@ -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) ]
433455pub 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