back to topotato report
topotato coverage report
Current view: top level - pimd - pim_msg.h (source / functions) Hit Total Coverage
Test: test_pim_bfd.py::PIMBFDTest Lines: 6 6 100.0 %
Date: 2023-02-24 18:39:40 Functions: 0 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             : #ifndef PIM_MSG_H
      21             : #define PIM_MSG_H
      22             : 
      23             : #include <netinet/in.h>
      24             : #if PIM_IPV == 6
      25             : #include <netinet/ip6.h>
      26             : #endif
      27             : 
      28             : #include "pim_jp_agg.h"
      29             : 
      30             : #define PIM_HDR_LEN  sizeof(struct pim_msg_header)
      31             : /*
      32             :   Number       Description
      33             :   ----------   ------------------
      34             :   0            Reserved
      35             :   1            IP (IP version 4)
      36             :   2            IP6 (IP version 6)
      37             : 
      38             :   From:
      39             :   http://www.iana.org/assignments/address-family-numbers
      40             : */
      41             : enum pim_msg_address_family {
      42             :         PIM_MSG_ADDRESS_FAMILY_RESERVED,
      43             :         PIM_MSG_ADDRESS_FAMILY_IPV4,
      44             :         PIM_MSG_ADDRESS_FAMILY_IPV6,
      45             : };
      46             : 
      47             : /*
      48             :  * pim_msg_hdr
      49             :  * =========================
      50             :  *  PIM Header definition as per RFC 5059. N bit introduced to indicate
      51             :  *  do-not-forward option in PIM Boot strap Message.
      52             :  *    0                   1                   2                   3
      53             :  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      54             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      55             :  *  |PIM Ver| Type  |N|  Reserved   |           Checksum            |
      56             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      57             :  */
      58             : struct pim_msg_header {
      59             : #if (BYTE_ORDER == LITTLE_ENDIAN)
      60             :         uint8_t type : 4;
      61             :         uint8_t ver : 4;
      62             :         uint8_t reserved : 7;
      63             :         uint8_t Nbit : 1; /* No Fwd Bit */
      64             : #elif (BYTE_ORDER == BIG_ENDIAN)
      65             :         uint8_t ver : 4;
      66             :         uint8_t type : 4;
      67             :         uint8_t Nbit : 1; /* No Fwd Bit */
      68             :         uint8_t reserved : 7;
      69             : #else
      70             : #error"Please set byte order"
      71             : #endif
      72             :         uint16_t checksum;
      73             : } __attribute__((packed));
      74             : 
      75             : struct pim_encoded_ipv4_unicast {
      76             :         uint8_t family;
      77             :         uint8_t reserved;
      78             :         struct in_addr addr;
      79             : } __attribute__((packed));
      80             : 
      81             : struct pim_encoded_ipv6_unicast {
      82             :         uint8_t family;
      83             :         uint8_t reserved;
      84             :         struct in6_addr addr;
      85             : } __attribute__((packed));
      86             : 
      87             : /*
      88             :  *  Encoded Group format. RFC 4601 Sec 4.9.1
      89             :  *   0                   1                   2                   3
      90             :  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      91             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      92             :  *  |  Addr Family  | Encoding Type |B| Reserved  |Z|  Mask Len     |
      93             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      94             :  *  |                Group multicast Address
      95             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
      96             :  */
      97             : struct pim_encoded_group_ipv4 {
      98             :         uint8_t family;
      99             :         uint8_t ne;
     100             : #if (BYTE_ORDER == LITTLE_ENDIAN)
     101             :         uint8_t sz : 1; /* scope zone bit */
     102             :         uint8_t reserved : 6;   /* Reserved */
     103             :         uint8_t bidir : 1;      /* Bidir bit */
     104             : #elif (BYTE_ORDER == BIG_ENDIAN)
     105             :         uint8_t bidir : 1;      /* Bidir bit */
     106             :         uint8_t reserved : 6;   /* Reserved */
     107             :         uint8_t sz : 1;         /* scope zone bit */
     108             : #else
     109             : #error"Please set byte order"
     110             : #endif
     111             :         uint8_t mask;
     112             :         struct in_addr addr;
     113             : } __attribute__((packed));
     114             : 
     115             : struct pim_encoded_group_ipv6 {
     116             :         uint8_t family;
     117             :         uint8_t ne;
     118             : #if (BYTE_ORDER == LITTLE_ENDIAN)
     119             :         uint8_t sz : 1;       /* scope zone bit */
     120             :         uint8_t reserved : 6; /* Reserved */
     121             :         uint8_t bidir : 1;    /* Bidir bit */
     122             : #elif (BYTE_ORDER == BIG_ENDIAN)
     123             :         uint8_t bidir : 1;      /* Bidir bit */
     124             :         uint8_t reserved : 6;   /* Reserved */
     125             :         uint8_t sz : 1;         /* scope zone bit */
     126             : #else
     127             : #error "Please set byte order"
     128             : #endif
     129             :         uint8_t mask;
     130             :         struct in6_addr addr;
     131             : } __attribute__((packed));
     132             : 
     133             : /*
     134             :  *  Encoded Source format. RFC 4601 Sec 4.9.1
     135             :  *   0                   1                   2                   3
     136             :  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     137             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     138             :  *  | Addr Family   | Encoding Type | Rsrvd   |S|W|R|  Mask Len     |
     139             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     140             :  *  |                        Source Address
     141             :  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...
     142             :  */
     143             : struct pim_encoded_source_ipv4 {
     144             :         uint8_t family;
     145             :         uint8_t ne;
     146             :         uint8_t bits;
     147             :         uint8_t mask;
     148             :         struct in_addr addr;
     149             : } __attribute__((packed));
     150             : 
     151             : struct pim_encoded_source_ipv6 {
     152             :         uint8_t family;
     153             :         uint8_t ne;
     154             :         uint8_t bits;
     155             :         uint8_t mask;
     156             :         struct in6_addr addr;
     157             : } __attribute__((packed));
     158             : 
     159             : /* clang-format off */
     160             : #if PIM_IPV == 4
     161             : typedef struct pim_encoded_ipv4_unicast pim_encoded_unicast;
     162             : typedef struct pim_encoded_group_ipv4   pim_encoded_group;
     163             : typedef struct pim_encoded_source_ipv4  pim_encoded_source;
     164             : typedef struct ip                       ipv_hdr;
     165             : #define IPV_SRC(ip_hdr)                 ((ip_hdr))->ip_src
     166             : #define IPV_DST(ip_hdr)                 ((ip_hdr))->ip_dst
     167             : #define IPV_LEN(ip_hdr)                 ((ip_hdr))->ip_len
     168             : #else
     169             : typedef struct pim_encoded_ipv6_unicast pim_encoded_unicast;
     170             : typedef struct pim_encoded_group_ipv6   pim_encoded_group;
     171             : typedef struct pim_encoded_source_ipv6  pim_encoded_source;
     172             : typedef struct ip6_hdr                  ipv_hdr;
     173             : #define IPV_SRC(ip_hdr)                 ((ip_hdr))->ip6_src
     174             : #define IPV_DST(ip_hdr)                 ((ip_hdr))->ip6_dst
     175             : #define IPV_LEN(ip_hdr)                 ((ip_hdr))->ip6_plen
     176             : #endif
     177             : /* clang-format on */
     178             : 
     179             : struct pim_jp_groups {
     180             :         pim_encoded_group g;
     181             :         uint16_t joins;
     182             :         uint16_t prunes;
     183             :         pim_encoded_source s[1];
     184             : } __attribute__((packed));
     185             : 
     186             : struct pim_jp {
     187             :         struct pim_msg_header header;
     188             :         pim_encoded_unicast addr;
     189             :         uint8_t reserved;
     190             :         uint8_t num_groups;
     191             :         uint16_t holdtime;
     192             :         struct pim_jp_groups groups[1];
     193             : } __attribute__((packed));
     194             : 
     195             : #if PIM_IPV == 4
     196          23 : static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
     197             : {
     198          23 :         const struct ip *ipv4_hdr = iphdr;
     199          23 :         pim_sgaddr sg;
     200             : 
     201          23 :         sg.src = ipv4_hdr->ip_src;
     202          23 :         sg.grp = ipv4_hdr->ip_dst;
     203             : 
     204          23 :         return sg;
     205             : }
     206             : #else
     207             : static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
     208             : {
     209             :         const struct ip6_hdr *ipv6_hdr = iphdr;
     210             :         pim_sgaddr sg;
     211             : 
     212             :         sg.src = ipv6_hdr->ip6_src;
     213             :         sg.grp = ipv6_hdr->ip6_dst;
     214             : 
     215             :         return sg;
     216             : }
     217             : #endif
     218             : 
     219             : void pim_msg_build_header(pim_addr src, pim_addr dst, uint8_t *pim_msg,
     220             :                           size_t pim_msg_size, uint8_t pim_msg_type,
     221             :                           bool no_fwd);
     222             : uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr);
     223             : uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
     224             : 
     225             : #define PIM_ENCODE_SPARSE_BIT      0x04
     226             : #define PIM_ENCODE_WC_BIT          0x02
     227             : #define PIM_ENCODE_RPT_BIT         0x01
     228             : uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
     229             :                                          uint8_t bits);
     230             : 
     231             : uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr);
     232             : uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr);
     233             : uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
     234             :                                          uint8_t bits);
     235             : 
     236             : uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr);
     237             : uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr);
     238             : uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits);
     239             : 
     240             : size_t pim_msg_get_jp_group_size(struct list *sources);
     241             : size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
     242             :                                struct pim_jp_agg_group *sgs, size_t size);
     243             : #endif /* PIM_MSG_H */

Generated by: LCOV version v1.16-topotato