LCOV - code coverage report
Current view: top level - util/net - fd_ip6.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 32 33 97.0 %
Date: 2026-08-13 04:56:22 Functions: 11 925 1.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_net_fd_ip6_h
       2             : #define HEADER_fd_src_util_net_fd_ip6_h
       3             : 
       4             : #include "../bits/fd_bits.h"
       5             : 
       6             : /* IPv6 address with an optional scope. */
       7             : 
       8             : struct fd_ip6_addr {
       9             :   uchar addr[ 16 ];
      10             :   uint  scope_id; /* 0 implies global */
      11             : };
      12             : 
      13             : typedef struct fd_ip6_addr fd_ip6_addr_t;
      14             : 
      15             : FD_PROTOTYPES_BEGIN
      16             : 
      17             : static inline void
      18             : fd_ip6_addr_ip4_mapped( uchar      ip6_addr[16],
      19          45 :                         uint const ip4_addr ) {
      20          45 :   memset( ip6_addr, 0, 10 );
      21          45 :   ip6_addr[ 10 ] = (uchar)0xff;
      22          45 :   ip6_addr[ 11 ] = (uchar)0xff;
      23          45 :   memcpy( ip6_addr+12, &ip4_addr, 4 );
      24          45 : }
      25             : 
      26             : static inline int
      27         339 : fd_ip6_addr_is_ip4_mapped( uchar const ip6_addr[16] ) {
      28         339 :   return (
      29         339 :     (ip6_addr[  0 ]==0x00) & (ip6_addr[  1 ]==0x00) &
      30         339 :     (ip6_addr[  2 ]==0x00) & (ip6_addr[  3 ]==0x00) &
      31         339 :     (ip6_addr[  4 ]==0x00) & (ip6_addr[  5 ]==0x00) &
      32         339 :     (ip6_addr[  6 ]==0x00) & (ip6_addr[  7 ]==0x00) &
      33         339 :     (ip6_addr[  8 ]==0x00) & (ip6_addr[  9 ]==0x00) &
      34         339 :     (ip6_addr[ 10 ]==0xff) & (ip6_addr[ 11 ]==0xff)
      35         339 :   );
      36         339 : }
      37             : 
      38             : static inline uint
      39          42 : fd_ip6_addr_to_ip4( uchar const ip6_addr[16] ) {
      40          42 :   uint ip4_addr;
      41          42 :   memcpy( &ip4_addr, ip6_addr+12, 4 );
      42          42 :   return ip4_addr;
      43          42 : }
      44             : 
      45             : /* fd_ip6_addr_is_unspecified returns 1 if the given address is the
      46             :    wildcard address (::), otherwise 0.  Binding a socket to the wildcard
      47             :    address listens on all addresses of all interfaces (both IPv6 and,
      48             :    unless IPV6_V6ONLY is set, IPv4). */
      49             : 
      50             : static inline int
      51          57 : fd_ip6_addr_is_unspecified( uchar const ip6_addr[16] ) {
      52          57 :   ulong hi, lo;
      53          57 :   memcpy( &hi, ip6_addr,   8 );
      54          57 :   memcpy( &lo, ip6_addr+8, 8 );
      55          57 :   return !(hi|lo);
      56          57 : }
      57             : 
      58             : /* fd_ip6_addr_is_scoped returns 1 if the given address has a scope
      59             :    narrower than global, i.e. a zone ID is required to identify which
      60             :    interface the address belongs to.  These are the link-local unicast
      61             :    addresses (fe80::/10) and the multicast addresses with a scope field
      62             :    below 'global' (ff00::/8 with the low nibble of byte 1 <0xe). */
      63             : 
      64             : static inline int
      65          57 : fd_ip6_addr_is_scoped( uchar const ip6_addr[16] ) {
      66          57 :   int link_local = (ip6_addr[0]==0xfe) & ((ip6_addr[1]&0xc0)==0x80);
      67          57 :   int multicast  = (ip6_addr[0]==0xff) & ((ip6_addr[1]&0x0f)< 0x0e);
      68          57 :   return link_local | multicast;
      69          57 : }
      70             : 
      71             : /* fd_cstr_to_ip6_addr parses an IPv6 address literal (RFC 4291), with
      72             :    an optional zone ID suffix (RFC 4007) naming the interface that the
      73             :    address belongs to.  The zone ID is either an interface name or a
      74             :    numeric interface index, e.g. "fe80::1%eth0" or "fe80::1%2".
      75             : 
      76             :    On success, stores the address to out and returns 1.  On failure,
      77             :    returns 0 and leaves out untouched.  Fails if a zone ID is given for
      78             :    an address that is not scoped, or names an interface that does not
      79             :    exist.
      80             : 
      81             :    Calls libc if_nametoindex (requires ioctl/Netlink access). */
      82             : 
      83             : int
      84             : fd_cstr_to_ip6_addr( char const *    s,
      85             :                      fd_ip6_addr_t * out );
      86             : 
      87             : /* fd_cstr_to_ip46_addr is like fd_cstr_to_ip6_addr, but additionally
      88             :    accepts an IPv4 address literal, which is stored as an IPv4-mapped
      89             :    IPv6 address (::ffff:a.b.c.d).  Note that the IPv4 wildcard address
      90             :    (0.0.0.0) maps to ::ffff:0.0.0.0.
      91             : 
      92             :    Calls libc if_nametoindex (requires ioctl/Netlink access).  */
      93             : 
      94             : int
      95             : fd_cstr_to_ip46_addr( char const *    s,
      96             :                       fd_ip6_addr_t * out );
      97             : 
      98             : /* FD_IP6_ADDR_CSTR_MAX is the buffer size required by
      99             :    fd_ip6_addr_cstr. */
     100             : 
     101             : #define FD_IP6_ADDR_CSTR_MAX (80UL)
     102             : 
     103             : /* fd_ip6_addr_cstr pretty prints an address for use as the host part of
     104             :    an URL, in the canonical text representation (RFC 5952).  IPv4-mapped
     105             :    addresses without a zone ID print as an IPv4 dotted quad (1.2.3.4),
     106             :    all others print bracketed, with a numeric zone ID suffix if the
     107             :    address is scoped (e.g. [fe80::1%2]).  Returns buf. */
     108             : 
     109             : char *
     110             : fd_ip6_addr_cstr( char                  buf[ static FD_IP6_ADDR_CSTR_MAX ],
     111             :                   fd_ip6_addr_t const * addr );
     112             : 
     113             : #define FD_IP6_ADDR_CSTR( name, addr ) \
     114           0 :   char name[ FD_IP6_ADDR_CSTR_MAX ]; fd_ip6_addr_cstr( name, (addr) )
     115             : 
     116             : FD_PROTOTYPES_END
     117             : 
     118             : #endif /* HEADER_fd_src_util_net_fd_ip6_h */

Generated by: LCOV version 1.14