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

Generated by: LCOV version 1.14