LCOV - code coverage report
Current view: top level - app/platform - fd_net_util.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 69 0.0 %
Date: 2026-03-19 18:19:27 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "fd_net_util.h"
       3             : 
       4             : #include <fcntl.h>
       5             : #include <errno.h>
       6             : #include <sched.h>
       7             : #include <unistd.h>
       8             : #include <net/if.h>
       9             : #include <sys/ioctl.h>
      10             : #include <sys/socket.h>
      11             : #include <linux/netlink.h>
      12             : #include <linux/rtnetlink.h>
      13             : #include <netinet/in.h>
      14             : 
      15             : int
      16           0 : fd_net_util_internet_ifindex( uint * ifindex ) {
      17           0 :   int sock = socket( AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE );
      18           0 :   if( FD_UNLIKELY( -1==sock ) ) return -1;
      19             : 
      20           0 :   struct {
      21           0 :     struct nlmsghdr nlh;
      22           0 :     struct rtmsg rt;
      23           0 :     char buf[ 8192UL ];
      24           0 :   } request;
      25             : 
      26           0 :   memset(&request, 0, sizeof(request));
      27           0 :   request.nlh.nlmsg_len   = NLMSG_LENGTH(sizeof(struct rtmsg));
      28           0 :   request.nlh.nlmsg_flags = NLM_F_REQUEST;
      29           0 :   request.nlh.nlmsg_type  = RTM_GETROUTE;
      30           0 :   request.rt.rtm_family   = AF_INET;
      31           0 :   request.rt.rtm_dst_len  = 32;
      32             : 
      33           0 :   struct rtattr *rta = (struct rtattr *)( ( (char *)&request ) + NLMSG_ALIGN( request.nlh.nlmsg_len ) );
      34           0 :   rta->rta_len          = RTA_LENGTH(4);
      35           0 :   rta->rta_type         = RTA_DST;
      36           0 :   request.nlh.nlmsg_len = NLMSG_ALIGN( request.nlh.nlmsg_len ) + (uint)RTA_LENGTH( 4 );
      37             : 
      38           0 :   uint ip = (8 << 24) | (8 << 16) | (8 << 8) | 8;
      39           0 :   fd_memcpy( RTA_DATA( rta ), &ip, 4 );
      40             : 
      41           0 :   long sent = send( sock, &request, request.nlh.nlmsg_len, 0 );
      42           0 :   if( FD_UNLIKELY( -1==sent ) ) {
      43           0 :     close( sock );
      44           0 :     return -1;
      45           0 :   }
      46           0 :   FD_TEST( sent==request.nlh.nlmsg_len );
      47             : 
      48           0 :   char response[ 8192UL ];
      49           0 :   long len = recv( sock, response, sizeof(response), 0 );
      50           0 :   if( FD_UNLIKELY( -1==len ) ) {
      51           0 :     close( sock );
      52           0 :     return -1;
      53           0 :   } else if( FD_UNLIKELY( len==sizeof(response) ) ) {
      54           0 :     errno = ENOBUFS;
      55           0 :     close( sock );
      56           0 :     return -1;
      57           0 :   }
      58             : 
      59           0 :   struct nlmsghdr *nlh;
      60           0 :   int result = -1;
      61           0 :   for( nlh = (struct nlmsghdr *)response; NLMSG_OK( nlh, len ); nlh = NLMSG_NEXT( nlh, len ) ) {
      62           0 :       struct rtmsg *rt = NLMSG_DATA( nlh );
      63             : 
      64           0 :       struct rtattr *rta = RTM_RTA( rt );
      65           0 :       uint rtl = (uint)RTM_PAYLOAD( nlh );
      66             : 
      67           0 :       for (; RTA_OK( rta, rtl ); rta = RTA_NEXT( rta, rtl ) ) {
      68           0 :           if (rta->rta_type == RTA_OIF) {
      69           0 :             result = *(int *)RTA_DATA(rta);
      70           0 :           }
      71           0 :       }
      72           0 :   }
      73             : 
      74           0 :   if( FD_UNLIKELY( -1==close( sock ) ) ) return -1;
      75             : 
      76           0 :   if( FD_LIKELY( result>=0 ) ) {
      77           0 :     *ifindex = (uint)result;
      78           0 :     return 0;
      79           0 :   } else {
      80           0 :     errno = ENODEV;
      81           0 :     return -1;
      82           0 :   }
      83           0 : }
      84             : 
      85             : int
      86             : fd_net_util_if_addr( const char * interface,
      87           0 :                      uint *       addr ) {
      88           0 :   int fd = socket( AF_INET, SOCK_DGRAM, 0 );
      89           0 :   if( FD_UNLIKELY( -1==fd ) ) return -1;
      90             : 
      91           0 :   struct ifreq ifr = {0};
      92           0 :   ifr.ifr_addr.sa_family = AF_INET;
      93           0 :   strncpy( ifr.ifr_name, interface, IFNAMSIZ );
      94           0 :   ifr.ifr_name[ IFNAMSIZ-1 ] = '\0';
      95             : 
      96           0 :   if( FD_UNLIKELY( -1==ioctl( fd, SIOCGIFADDR, &ifr ) ) ) return -1;
      97           0 :   if( FD_UNLIKELY( -1==close( fd ) ) ) return -1;
      98             : 
      99           0 :   *addr = ((struct sockaddr_in *)fd_type_pun( &ifr.ifr_addr ))->sin_addr.s_addr;
     100           0 :   return 0;
     101           0 : }

Generated by: LCOV version 1.14