LCOV - code coverage report
Current view: top level - util/net - fd_igmp.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 39 0.0 %
Date: 2025-01-08 12:08:44 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_util_net_fd_igmp_h
       2             : #define HEADER_fd_src_util_net_fd_igmp_h
       3             : 
       4             : #include "fd_ip4.h"
       5             : 
       6             : /* FIXME: IGMP CRASH COURSE HERE */
       7             : 
       8             : /* FD_IGMP_TYPE_{QUERY,V1_REPORT,V2_REPORT,V2_LEAVE}:
       9             : 
      10             :    QUERY     - IGMP is a query (if to a specific ip4, specific query, if to
      11             :                224.0.0.1, general query) from LAN switch regarding host's
      12             :                mcast join status
      13             :    V1_REPORT - IGMP is a V1 report to router indicating to join / remain
      14             :                in mcast group (V1 IGMP host)
      15             :    V2_REPORT - IGMP is a V2 report to router indicating to join / remain
      16             :                in mcast group (V1 IGMP host)
      17             :    LEAVE     - IGMP is a V2 report to router indicating to leave mcast
      18             :                group (V2 IGMP host) */
      19             : 
      20             : #define FD_IGMP_TYPE_QUERY     ((uchar)0x11)
      21             : #define FD_IGMP_TYPE_V1_REPORT ((uchar)0x12)
      22             : #define FD_IGMP_TYPE_V2_REPORT ((uchar)0x16)
      23             : #define FD_IGMP_TYPE_V2_LEAVE  ((uchar)0x17)
      24             : 
      25             : union fd_igmp {
      26             :   struct {
      27             :     uchar  type;  /* IGMP type */
      28             :     uchar  resp;  /* v1 - 0 on send, ignore on recv, v2 - 0 on send, required response time in 0.1 s increments on recv */
      29             :     ushort check; /* IGMP checksum ("invariant" order) */
      30             :     uint   group; /* IGMP group (IP4 mcast addr), technically net order but all APIs below work with this directly */
      31             :   };
      32             :   uint u[2]; /* Used for checksum calcs */
      33             : };
      34             : 
      35             : typedef union fd_igmp fd_igmp_t;
      36             : 
      37             : /* FIXME: CONSIDER AN OVERALL IGMP PRETTY PRINTER? */
      38             : 
      39             : struct fd_ip4_igmp {
      40             :   fd_ip4_hdr_t ip4[1];
      41             :   uchar        opt[4];
      42             :   fd_igmp_t    igmp[1];
      43             : };
      44             : 
      45             : typedef struct fd_ip4_igmp fd_ip4_igmp_t;
      46             : 
      47             : FD_PROTOTYPES_BEGIN
      48             : 
      49             : /* fd_igmp_check is used for igmp check field computation and
      50             :    validation.  igmp points to the first byte a memory region containing
      51             :    an igmp message.  If the message has no checksum (check==0), this
      52             :    returns the value to use for check.  If the message has a checksum
      53             :    (check!=0), this returns 0 if message has a valid checksum or
      54             :    non-zero if not.  Reasonably fast O(1). */
      55             : 
      56             : FD_FN_PURE static inline ushort
      57           0 : fd_igmp_check( fd_igmp_t const * igmp ) {
      58           0 :   uint const * u = igmp->u;
      59           0 :   ulong        c = (ulong)u[0] + (ulong)u[1];
      60           0 :   c  = ( c>>32            ) +
      61           0 :        ((c>>16) & 0xffffUL) +
      62           0 :        ( c      & 0xffffUL);
      63           0 :   c += ( c>>16            );
      64           0 :   return (ushort)~c;
      65           0 : }
      66             : 
      67             : /* fd_ip4_igmp populates the memory region of size sizeof(fd_ip4_igmp_t)
      68             :    and whose first byte is pointed to by the non-NULL _msg with a well
      69             :    formed ip4 / igmp message.  The message is addressed as from
      70             :    ip4_saddr (assumed valid ip4 ucast on subnet) and to ip4_daddr
      71             :    (assumed valid ip4 mcast).  It be an igmp of the given type, with the
      72             :    given response and to the given igmp_group (usually igmp_group should
      73             :    be ip4_daddr).  Returns _msg. */
      74             : 
      75             : static inline fd_ip4_igmp_t *
      76             : fd_ip4_igmp( void * _msg,
      77             :              uint   ip4_saddr,
      78             :              uint   ip4_daddr,
      79             :              uchar  igmp_type,
      80             :              uchar  igmp_resp,
      81           0 :              uint   igmp_group ) {
      82           0 :   fd_ip4_igmp_t * msg = (fd_ip4_igmp_t *)_msg;
      83           0 : 
      84           0 :   msg->ip4->verihl       = FD_IP4_VERIHL(6U,4U);
      85           0 :   msg->ip4->tos          = FD_IP4_HDR_TOS_PREC_INTERNETCONTROL;
      86           0 :   msg->ip4->net_tot_len  = fd_ushort_bswap( (ushort)32 );
      87           0 :   msg->ip4->net_id       = (ushort)0;
      88           0 :   msg->ip4->net_frag_off = fd_ushort_bswap( FD_IP4_HDR_FRAG_OFF_DF );
      89           0 :   msg->ip4->ttl          = (uchar)1;
      90           0 :   msg->ip4->protocol     = FD_IP4_HDR_PROTOCOL_IGMP;
      91           0 :   msg->ip4->check        = (ushort)0; /* Computation completed below */
      92           0 : 
      93           0 :   memcpy( msg->ip4->saddr_c, &ip4_saddr, 4U );
      94           0 :   memcpy( msg->ip4->daddr_c, &ip4_daddr, 4U );
      95           0 : 
      96           0 :   msg->opt[0]            = FD_IP4_OPT_RA;
      97           0 :   msg->opt[1]            = (uchar)4;
      98           0 :   msg->opt[2]            = (uchar)0;
      99           0 :   msg->opt[3]            = (uchar)0;
     100           0 : 
     101           0 :   msg->igmp->type        = igmp_type;
     102           0 :   msg->igmp->resp        = igmp_resp;
     103           0 :   msg->igmp->check       = (ushort)0; /* Computation completed below */
     104           0 :   msg->igmp->group       = igmp_group;
     105           0 : 
     106           0 :   msg->ip4->check        = fd_ip4_hdr_check( msg->ip4  );
     107           0 :   msg->igmp->check       = fd_igmp_check   ( msg->igmp );
     108           0 : 
     109           0 :   return msg;
     110           0 : }
     111             : 
     112             : FD_PROTOTYPES_END
     113             : 
     114             : #endif /* HEADER_fd_src_util_net_fd_igmp_h */

Generated by: LCOV version 1.14