back to topotato report
topotato coverage report
Current view: top level - pimd - pim_util.c (source / functions) Hit Total Coverage
Test: test_pim_crp.py::PIMCandidateBSRTest Lines: 38 58 65.5 %
Date: 2023-02-16 02:09:37 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /*
       2             :  * PIM for Quagga
       3             :  * Copyright (C) 2008  Everton da Silva Marques
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or modify
       6             :  * it under the terms of the GNU General Public License as published by
       7             :  * the Free Software Foundation; either version 2 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful, but
      11             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13             :  * General Public License for 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             : #include <zebra.h>
      21             : 
      22             : #include "log.h"
      23             : #include "prefix.h"
      24             : #include "plist.h"
      25             : 
      26             : #include "pim_util.h"
      27             : 
      28             : /*
      29             :   RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
      30             : 
      31             :   If QQIC < 128,  QQI = QQIC
      32             :   If QQIC >= 128, QQI = (mant | 0x10) << (exp + 3)
      33             : 
      34             :   0 1 2 3 4 5 6 7
      35             :   +-+-+-+-+-+-+-+-+
      36             :   |1| exp | mant  |
      37             :   +-+-+-+-+-+-+-+-+
      38             : 
      39             :   Since exp=0..7 then (exp+3)=3..10, then QQI has
      40             :   one of the following bit patterns:
      41             : 
      42             :   exp=0: QQI = 0000.0000.1MMM.M000
      43             :   exp=1: QQI = 0000.0001.MMMM.0000
      44             :   ...
      45             :   exp=6: QQI = 001M.MMM0.0000.0000
      46             :   exp=7: QQI = 01MM.MM00.0000.0000
      47             :   --------- ---------
      48             :   0x4  0x0  0x0  0x0
      49             : */
      50           2 : uint8_t igmp_msg_encode16to8(uint16_t value)
      51             : {
      52           2 :         uint8_t code;
      53             : 
      54           2 :         if (value < 128) {
      55           2 :                 code = value;
      56             :         } else {
      57             :                 uint16_t mask = 0x4000;
      58             :                 uint8_t exp;
      59             :                 uint16_t mant;
      60           0 :                 for (exp = 7; exp > 0; --exp) {
      61           0 :                         if (mask & value)
      62             :                                 break;
      63           0 :                         mask >>= 1;
      64             :                 }
      65           0 :                 mant = 0x000F & (value >> (exp + 3));
      66           0 :                 code = ((uint8_t)1 << 7) | ((uint8_t)exp << 4) | (uint8_t)mant;
      67             :         }
      68             : 
      69           2 :         return code;
      70             : }
      71             : 
      72             : /*
      73             :   RFC 3376: 4.1.7. QQIC (Querier's Query Interval Code)
      74             : 
      75             :   If QQIC < 128,  QQI = QQIC
      76             :   If QQIC >= 128, QQI = (mant | 0x10) << (exp + 3)
      77             : 
      78             :   0 1 2 3 4 5 6 7
      79             :   +-+-+-+-+-+-+-+-+
      80             :   |1| exp | mant  |
      81             :   +-+-+-+-+-+-+-+-+
      82             : */
      83           2 : uint16_t igmp_msg_decode8to16(uint8_t code)
      84             : {
      85           2 :         uint16_t value;
      86             : 
      87           2 :         if (code < 128) {
      88           2 :                 value = code;
      89             :         } else {
      90           0 :                 uint16_t mant = (code & 0x0F);
      91           0 :                 uint8_t exp = (code & 0x70) >> 4;
      92           0 :                 value = (mant | 0x10) << (exp + 3);
      93             :         }
      94             : 
      95           2 :         return value;
      96             : }
      97             : 
      98           0 : void pim_pkt_dump(const char *label, const uint8_t *buf, int size)
      99             : {
     100           0 :         zlog_debug("%s: pkt dump size=%d", label, size);
     101           0 :         zlog_hexdump(buf, size);
     102           0 : }
     103             : 
     104         135 : int pim_is_group_224_0_0_0_24(struct in_addr group_addr)
     105             : {
     106         135 :         static int first = 1;
     107         135 :         static struct prefix group_224;
     108         135 :         struct prefix group;
     109             : 
     110         135 :         if (first) {
     111           3 :                 if (!str2prefix("224.0.0.0/24", &group_224))
     112             :                         return 0;
     113           3 :                 first = 0;
     114             :         }
     115             : 
     116         135 :         group.family = AF_INET;
     117         135 :         group.u.prefix4 = group_addr;
     118         135 :         group.prefixlen = IPV4_MAX_BITLEN;
     119             : 
     120         135 :         return prefix_match(&group_224, &group);
     121             : }
     122             : 
     123          63 : int pim_is_group_224_4(struct in_addr group_addr)
     124             : {
     125          63 :         static int first = 1;
     126          63 :         static struct prefix group_all;
     127          63 :         struct prefix group;
     128             : 
     129          63 :         if (first) {
     130           3 :                 if (!str2prefix("224.0.0.0/4", &group_all))
     131             :                         return 0;
     132           3 :                 first = 0;
     133             :         }
     134             : 
     135          63 :         group.family = AF_INET;
     136          63 :         group.u.prefix4 = group_addr;
     137          63 :         group.prefixlen = IPV4_MAX_BITLEN;
     138             : 
     139          63 :         return prefix_match(&group_all, &group);
     140             : }
     141             : 
     142          99 : bool pim_is_group_filtered(struct pim_interface *pim_ifp, pim_addr *grp)
     143             : {
     144          99 :         struct prefix grp_pfx;
     145          99 :         struct prefix_list *pl;
     146             : 
     147          99 :         if (!pim_ifp->boundary_oil_plist)
     148             :                 return false;
     149             : 
     150           0 :         pim_addr_to_prefix(&grp_pfx, *grp);
     151             : 
     152           0 :         pl = prefix_list_lookup(PIM_AFI, pim_ifp->boundary_oil_plist);
     153           0 :         return pl ? prefix_list_apply_ext(pl, NULL, &grp_pfx, true) ==
     154             :                                PREFIX_DENY
     155           0 :                   : false;
     156             : }
     157             : 
     158             : 
     159             : /* This function returns all multicast group */
     160           3 : int pim_get_all_mcast_group(struct prefix *prefix)
     161             : {
     162             : #if PIM_IPV == 4
     163           3 :         if (!str2prefix("224.0.0.0/4", prefix))
     164           0 :                 return 0;
     165             : #else
     166             :         if (!str2prefix("FF00::0/8", prefix))
     167             :                 return 0;
     168             : #endif
     169             :         return 1;
     170             : }
     171             : 
     172           0 : bool pim_addr_is_multicast(pim_addr addr)
     173             : {
     174             : #if PIM_IPV == 4
     175           0 :         if (IN_MULTICAST(addr.s_addr))
     176           0 :                 return true;
     177             : #else
     178             :         if (IN6_IS_ADDR_MULTICAST(&addr))
     179             :                 return true;
     180             : #endif
     181             :         return false;
     182             : }

Generated by: LCOV version v1.16-topotato