LCOV - code coverage report
Current view: top level - util/net - fd_net_headers.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 39 0.0 %
Date: 2025-09-17 04:38:03 Functions: 0 274 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_net_headers_h
       2             : #define HEADER_fd_src_util_net_headers_h
       3             : 
       4             : #include "fd_udp.h"
       5             : #include "fd_eth.h"
       6             : 
       7             : /* fd_ip4_udp_hdrs is useful to construct Ethernet+IPv4+UDP network
       8             :    headers. Assumes that the IPv4 header has no options (IHL=5). */
       9             : 
      10             : union fd_ip4_udp_hdrs {
      11             :   uchar uc[ 42 ];
      12             :   struct {
      13             :     fd_eth_hdr_t eth[1];
      14             :     fd_ip4_hdr_t ip4[1];
      15             :     fd_udp_hdr_t udp[1];
      16             :   };
      17             : };
      18             : 
      19             : typedef union fd_ip4_udp_hdrs fd_ip4_udp_hdrs_t;
      20             : 
      21             : FD_PROTOTYPES_BEGIN
      22             : 
      23             : /* Helper method to populate a header template containing Ethernet,
      24             :    IPv4 (no options), and UDP headers.  Note that IPv4 and UDP header
      25             :    checksums are set to 0. */
      26             : 
      27             : static inline fd_ip4_udp_hdrs_t *
      28             : fd_ip4_udp_hdr_init( fd_ip4_udp_hdrs_t * hdrs,
      29             :                      ulong               payload_sz,
      30             :                      uint                src_ip,
      31           0 :                      ushort              src_port ) {
      32           0 :   fd_eth_hdr_t * eth = hdrs->eth;
      33           0 :   memset( eth->dst, 0, 6UL );
      34           0 :   memset( eth->src, 0, 6UL );
      35           0 :   eth->net_type  = fd_ushort_bswap( FD_ETH_HDR_TYPE_IP );
      36             : 
      37           0 :   fd_ip4_hdr_t * ip4 = hdrs->ip4;
      38           0 :   ip4->verihl       = FD_IP4_VERIHL( 4U, 5U );
      39           0 :   ip4->tos          = (uchar)0;
      40           0 :   ip4->net_tot_len  = fd_ushort_bswap( (ushort)(payload_sz + sizeof(fd_ip4_hdr_t)+sizeof(fd_udp_hdr_t)) );
      41           0 :   ip4->net_frag_off = fd_ushort_bswap( FD_IP4_HDR_FRAG_OFF_DF );
      42           0 :   ip4->ttl          = (uchar)64;
      43           0 :   ip4->protocol     = FD_IP4_HDR_PROTOCOL_UDP;
      44           0 :   ip4->check        = 0U;
      45           0 :   ip4->saddr        = src_ip;
      46           0 :   ip4->daddr        = 0;
      47             : 
      48           0 :   fd_udp_hdr_t * udp = hdrs->udp;
      49           0 :   udp->net_sport = fd_ushort_bswap( src_port );
      50           0 :   udp->net_dport = (ushort)0;
      51           0 :   udp->net_len   = fd_ushort_bswap( (ushort)(payload_sz + sizeof(fd_udp_hdr_t)) );
      52           0 :   udp->check     = (ushort)0;
      53             : 
      54           0 :   return hdrs;
      55           0 : }
      56             : 
      57             : FD_PROTOTYPES_END
      58             : 
      59             : union fd_ip4_port {
      60             :   struct {
      61             :     uint   addr;  /* net order */
      62             :     ushort port;  /* net order */
      63             :   };
      64             :   ulong l;
      65             : };
      66             : 
      67             : typedef union fd_ip4_port fd_ip4_port_t;
      68             : 
      69             : /* fd_ip4_udp_hdr_strip deconstructs a network packet.  If any opt_* are
      70             :    set to NULL, then they are not populated. It copies pointers to
      71             :    Ethernet, IPv4 (no options), and UDP headers into opt_eth, opt_ip4,
      72             :    and opt_udp respectively. It copies a pointer to the start of the
      73             :    packet payload into opt_payload, and the packet payload size into
      74             :    opt_payload_sz.
      75             : 
      76             :    A few basic integrity checks are preformed on included size fields.
      77             :    Returns 1 on success and 0 on failure */
      78             : 
      79             : static inline int
      80             : fd_ip4_udp_hdr_strip( uchar const *         data,
      81             :                       ulong                 data_sz,
      82             :                       uchar ** const        opt_payload,
      83             :                       ulong *               opt_payload_sz,
      84             :                       fd_eth_hdr_t ** const opt_eth,
      85             :                       fd_ip4_hdr_t ** const opt_ip4,
      86           0 :                       fd_udp_hdr_t ** const opt_udp ) {
      87           0 :   fd_eth_hdr_t const * eth = (fd_eth_hdr_t const *)data;
      88           0 :   fd_ip4_hdr_t const * ip4 = (fd_ip4_hdr_t const *)( (ulong)eth + sizeof(fd_eth_hdr_t) );
      89           0 :   fd_udp_hdr_t const * udp = (fd_udp_hdr_t const *)( (ulong)ip4 + FD_IP4_GET_LEN( *ip4 ) );
      90             : 
      91             :   /* data_sz is less than the observed combined header size */
      92           0 :   if( FD_UNLIKELY( (ulong)udp+sizeof(fd_udp_hdr_t) > (ulong)eth+data_sz ) ) return 0;
      93           0 :   ulong udp_sz = fd_ushort_bswap( udp->net_len );
      94             : 
      95             :   /* observed udp_hdr+payload sz is smaller than minimum udp header sz */
      96           0 :   if( FD_UNLIKELY( udp_sz<sizeof(fd_udp_hdr_t) ) ) return 0;
      97           0 :   ulong payload_sz_ = udp_sz-sizeof(fd_udp_hdr_t);
      98           0 :   uchar * payload_     = (uchar *)( (ulong)udp + sizeof(fd_udp_hdr_t) );
      99             : 
     100             :   /* payload_sz is greater than the total packet size */
     101           0 :   if( FD_UNLIKELY( payload_+payload_sz_>data+data_sz ) ) return 0;
     102             : 
     103           0 :   fd_ulong_store_if( !!opt_eth,        (ulong*)opt_eth,     (ulong)eth      );
     104           0 :   fd_ulong_store_if( !!opt_ip4,        (ulong*)opt_ip4,     (ulong)ip4      );
     105           0 :   fd_ulong_store_if( !!opt_udp,        (ulong*)opt_udp,     (ulong)udp      );
     106           0 :   fd_ulong_store_if( !!opt_payload,    (ulong*)opt_payload, (ulong)payload_ );
     107           0 :   fd_ulong_store_if( !!opt_payload_sz, opt_payload_sz,      payload_sz_     );
     108             : 
     109           0 :   return 1;
     110           0 : }
     111             : 
     112             : #endif /* HEADER_fd_src_util_net_headers_h */

Generated by: LCOV version 1.14