back to topotato report
topotato coverage report
Current view: top level - pimd - pim6_mld_protocol.h (source / functions) Hit Total Coverage
Test: test_pim6_basic.py::PIM6Basic Lines: 11 16 68.8 %
Date: 2023-02-24 18:38:38 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * MLD protocol definitions
       3             :  * Copyright (C) 2022  David Lamparter for NetDEF, Inc.
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or modify it
       6             :  * under the terms of the GNU General Public License as published by the Free
       7             :  * Software Foundation; either version 2 of the License, or (at your option)
       8             :  * any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
      13             :  * more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License along
      16             :  * with this program; see the file COPYING; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      18             :  */
      19             : 
      20             : #ifndef _PIM6_MLD_PROTOCOL_H
      21             : #define _PIM6_MLD_PROTOCOL_H
      22             : 
      23             : #include <stdalign.h>
      24             : #include <stdint.h>
      25             : 
      26             : /* There is a struct icmp6_hdr provided by OS, but it includes 4 bytes of data.
      27             :  * Not helpful for us if we want to put the MLD struct after it.
      28             :  */
      29             : 
      30             : struct icmp6_plain_hdr {
      31             :         uint8_t icmp6_type;
      32             :         uint8_t icmp6_code;
      33             :         uint16_t icmp6_cksum;
      34             : };
      35             : static_assert(sizeof(struct icmp6_plain_hdr) == 4, "struct mismatch");
      36             : static_assert(alignof(struct icmp6_plain_hdr) <= 4, "struct mismatch");
      37             : 
      38             : /* for MLDv1 query, report and leave all use the same packet format */
      39             : struct mld_v1_pkt {
      40             :         uint16_t max_resp_code;
      41             :         uint16_t rsvd0;
      42             :         struct in6_addr grp;
      43             : };
      44             : static_assert(sizeof(struct mld_v1_pkt) == 20, "struct mismatch");
      45             : static_assert(alignof(struct mld_v1_pkt) <= 4, "struct mismatch");
      46             : 
      47             : 
      48             : struct mld_v2_query_hdr {
      49             :         uint16_t max_resp_code;
      50             :         uint16_t rsvd0;
      51             :         struct in6_addr grp;
      52             :         uint8_t flags;
      53             :         uint8_t qqic;
      54             :         uint16_t n_src;
      55             :         struct in6_addr srcs[0];
      56             : };
      57             : static_assert(sizeof(struct mld_v2_query_hdr) == 24, "struct mismatch");
      58             : static_assert(alignof(struct mld_v2_query_hdr) <= 4, "struct mismatch");
      59             : 
      60             : 
      61             : struct mld_v2_report_hdr {
      62             :         uint16_t rsvd;
      63             :         uint16_t n_records;
      64             : };
      65             : static_assert(sizeof(struct mld_v2_report_hdr) == 4, "struct mismatch");
      66             : static_assert(alignof(struct mld_v2_report_hdr) <= 4, "struct mismatch");
      67             : 
      68             : 
      69             : struct mld_v2_rec_hdr {
      70             :         uint8_t type;
      71             :         uint8_t aux_len;
      72             :         uint16_t n_src;
      73             :         struct in6_addr grp;
      74             :         struct in6_addr srcs[0];
      75             : };
      76             : static_assert(sizeof(struct mld_v2_rec_hdr) == 20, "struct mismatch");
      77             : static_assert(alignof(struct mld_v2_rec_hdr) <= 4, "struct mismatch");
      78             : 
      79             : /* clang-format off */
      80             : enum icmp6_mld_type {
      81             :         ICMP6_MLD_QUERY                 = 130,
      82             :         ICMP6_MLD_V1_REPORT             = 131,
      83             :         ICMP6_MLD_V1_DONE               = 132,
      84             :         ICMP6_MLD_V2_REPORT             = 143,
      85             : };
      86             : 
      87             : enum mld_v2_rec_type {
      88             :         MLD_RECTYPE_IS_INCLUDE          = 1,
      89             :         MLD_RECTYPE_IS_EXCLUDE          = 2,
      90             :         MLD_RECTYPE_CHANGE_TO_INCLUDE   = 3,
      91             :         MLD_RECTYPE_CHANGE_TO_EXCLUDE   = 4,
      92             :         MLD_RECTYPE_ALLOW_NEW_SOURCES   = 5,
      93             :         MLD_RECTYPE_BLOCK_OLD_SOURCES   = 6,
      94             : };
      95             : /* clang-format on */
      96             : 
      97             : /* helper functions */
      98             : 
      99           5 : static inline unsigned int mld_max_resp_decode(uint16_t wire)
     100             : {
     101           5 :         uint16_t code = ntohs(wire);
     102           5 :         uint8_t exp;
     103             : 
     104           5 :         if (code < 0x8000)
     105           5 :                 return code;
     106           0 :         exp = (code >> 12) & 0x7;
     107           0 :         return ((code & 0xfff) | 0x1000) << (exp + 3);
     108             : }
     109             : 
     110           4 : static inline uint16_t mld_max_resp_encode(uint32_t value)
     111             : {
     112           4 :         uint16_t code;
     113           4 :         uint8_t exp;
     114             : 
     115           4 :         if (value < 0x8000)
     116           4 :                 code = value;
     117             :         else {
     118           0 :                 exp = 16 - __builtin_clz(value);
     119           0 :                 code = (value >> (exp + 3)) & 0xfff;
     120           0 :                 code |= 0x8000 | (exp << 12);
     121             :         }
     122           4 :         return htons(code);
     123             : }
     124             : 
     125             : #endif /* _PIM6_MLD_PROTOCOL_H */

Generated by: LCOV version v1.16-topotato