Coverage Report

Created: 2026-01-01 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/pimd/pim_msg.h
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * PIM for Quagga
4
 * Copyright (C) 2008  Everton da Silva Marques
5
 */
6
7
#ifndef PIM_MSG_H
8
#define PIM_MSG_H
9
10
#include <netinet/in.h>
11
#if PIM_IPV == 6
12
#include <netinet/ip6.h>
13
#endif
14
15
#include "pim_jp_agg.h"
16
17
0
#define PIM_HDR_LEN  sizeof(struct pim_msg_header)
18
/*
19
  Number       Description
20
  ----------   ------------------
21
  0            Reserved
22
  1            IP (IP version 4)
23
  2            IP6 (IP version 6)
24
25
  From:
26
  http://www.iana.org/assignments/address-family-numbers
27
*/
28
enum pim_msg_address_family {
29
  PIM_MSG_ADDRESS_FAMILY_RESERVED,
30
  PIM_MSG_ADDRESS_FAMILY_IPV4,
31
  PIM_MSG_ADDRESS_FAMILY_IPV6,
32
};
33
34
/*
35
 * pim_msg_hdr
36
 * =========================
37
 *  PIM Header definition as per RFC 5059. N bit introduced to indicate
38
 *  do-not-forward option in PIM Boot strap Message.
39
 *    0                   1                   2                   3
40
 *   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
41
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42
 *  |PIM Ver| Type  |N|  Reserved   |           Checksum            |
43
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44
 */
45
struct pim_msg_header {
46
#if (BYTE_ORDER == LITTLE_ENDIAN)
47
  uint8_t type : 4;
48
  uint8_t ver : 4;
49
  uint8_t reserved : 7;
50
  uint8_t Nbit : 1; /* No Fwd Bit */
51
#elif (BYTE_ORDER == BIG_ENDIAN)
52
  uint8_t ver : 4;
53
  uint8_t type : 4;
54
  uint8_t Nbit : 1; /* No Fwd Bit */
55
  uint8_t reserved : 7;
56
#else
57
#error"Please set byte order"
58
#endif
59
  uint16_t checksum;
60
} __attribute__((packed));
61
62
struct pim_encoded_ipv4_unicast {
63
  uint8_t family;
64
  uint8_t reserved;
65
  struct in_addr addr;
66
} __attribute__((packed));
67
68
struct pim_encoded_ipv6_unicast {
69
  uint8_t family;
70
  uint8_t reserved;
71
  struct in6_addr addr;
72
} __attribute__((packed));
73
74
/*
75
 *  Encoded Group format. RFC 4601 Sec 4.9.1
76
 *   0                   1                   2                   3
77
 *   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
78
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79
 *  |  Addr Family  | Encoding Type |B| Reserved  |Z|  Mask Len     |
80
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81
 *  |                Group multicast Address
82
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
83
 */
84
struct pim_encoded_group_ipv4 {
85
  uint8_t family;
86
  uint8_t ne;
87
#if (BYTE_ORDER == LITTLE_ENDIAN)
88
  uint8_t sz : 1; /* scope zone bit */
89
  uint8_t reserved : 6; /* Reserved */
90
  uint8_t bidir : 1;  /* Bidir bit */
91
#elif (BYTE_ORDER == BIG_ENDIAN)
92
  uint8_t bidir : 1;  /* Bidir bit */
93
  uint8_t reserved : 6; /* Reserved */
94
  uint8_t sz : 1;   /* scope zone bit */
95
#else
96
#error"Please set byte order"
97
#endif
98
  uint8_t mask;
99
  struct in_addr addr;
100
} __attribute__((packed));
101
102
struct pim_encoded_group_ipv6 {
103
  uint8_t family;
104
  uint8_t ne;
105
#if (BYTE_ORDER == LITTLE_ENDIAN)
106
  uint8_t sz : 1;       /* scope zone bit */
107
  uint8_t reserved : 6; /* Reserved */
108
  uint8_t bidir : 1;    /* Bidir bit */
109
#elif (BYTE_ORDER == BIG_ENDIAN)
110
  uint8_t bidir : 1;  /* Bidir bit */
111
  uint8_t reserved : 6; /* Reserved */
112
  uint8_t sz : 1;   /* scope zone bit */
113
#else
114
#error "Please set byte order"
115
#endif
116
  uint8_t mask;
117
  struct in6_addr addr;
118
} __attribute__((packed));
119
120
/*
121
 *  Encoded Source format. RFC 4601 Sec 4.9.1
122
 *   0                   1                   2                   3
123
 *   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
124
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125
 *  | Addr Family   | Encoding Type | Rsrvd   |S|W|R|  Mask Len     |
126
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
127
 *  |                        Source Address
128
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...
129
 */
130
struct pim_encoded_source_ipv4 {
131
  uint8_t family;
132
  uint8_t ne;
133
  uint8_t bits;
134
  uint8_t mask;
135
  struct in_addr addr;
136
} __attribute__((packed));
137
138
struct pim_encoded_source_ipv6 {
139
  uint8_t family;
140
  uint8_t ne;
141
  uint8_t bits;
142
  uint8_t mask;
143
  struct in6_addr addr;
144
} __attribute__((packed));
145
146
/* clang-format off */
147
#if PIM_IPV == 4
148
typedef struct pim_encoded_ipv4_unicast pim_encoded_unicast;
149
typedef struct pim_encoded_group_ipv4   pim_encoded_group;
150
typedef struct pim_encoded_source_ipv4  pim_encoded_source;
151
typedef struct ip       ipv_hdr;
152
0
#define IPV_SRC(ip_hdr)     ((ip_hdr))->ip_src
153
0
#define IPV_DST(ip_hdr)     ((ip_hdr))->ip_dst
154
#define IPV_LEN(ip_hdr)     ((ip_hdr))->ip_len
155
#else
156
typedef struct pim_encoded_ipv6_unicast pim_encoded_unicast;
157
typedef struct pim_encoded_group_ipv6   pim_encoded_group;
158
typedef struct pim_encoded_source_ipv6  pim_encoded_source;
159
typedef struct ip6_hdr      ipv_hdr;
160
#define IPV_SRC(ip_hdr)     ((ip_hdr))->ip6_src
161
#define IPV_DST(ip_hdr)     ((ip_hdr))->ip6_dst
162
#define IPV_LEN(ip_hdr)     ((ip_hdr))->ip6_plen
163
#endif
164
/* clang-format on */
165
166
struct pim_jp_groups {
167
  pim_encoded_group g;
168
  uint16_t joins;
169
  uint16_t prunes;
170
  pim_encoded_source s[1];
171
} __attribute__((packed));
172
173
struct pim_jp {
174
  struct pim_msg_header header;
175
  pim_encoded_unicast addr;
176
  uint8_t reserved;
177
  uint8_t num_groups;
178
  uint16_t holdtime;
179
  struct pim_jp_groups groups[1];
180
} __attribute__((packed));
181
182
#if PIM_IPV == 4
183
static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
184
3.01k
{
185
3.01k
  const struct ip *ipv4_hdr = iphdr;
186
3.01k
  pim_sgaddr sg;
187
188
3.01k
  sg.src = ipv4_hdr->ip_src;
189
3.01k
  sg.grp = ipv4_hdr->ip_dst;
190
191
3.01k
  return sg;
192
3.01k
}
Unexecuted instantiation: pim_assert.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_bfd.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_bsm.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_cmd_common.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_hello.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_iface.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_ifchannel.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_instance.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_join.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_jp_agg.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_macro.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_mroute.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_msg.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_nb_config.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_neighbor.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_nht.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_oil.c:pim_sgaddr_from_iphdr
pim_pim.c:pim_sgaddr_from_iphdr
Line
Count
Source
184
2.99k
{
185
2.99k
  const struct ip *ipv4_hdr = iphdr;
186
2.99k
  pim_sgaddr sg;
187
188
2.99k
  sg.src = ipv4_hdr->ip_src;
189
2.99k
  sg.grp = ipv4_hdr->ip_dst;
190
191
2.99k
  return sg;
192
2.99k
}
Unexecuted instantiation: pim_rp.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_rpf.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_sock.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_ssm.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_ssmpingd.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_static.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_tib.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_tlv.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_upstream.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_vty.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_zebra.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_zlookup.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_vxlan.c:pim_sgaddr_from_iphdr
pim_register.c:pim_sgaddr_from_iphdr
Line
Count
Source
184
20
{
185
20
  const struct ip *ipv4_hdr = iphdr;
186
20
  pim_sgaddr sg;
187
188
20
  sg.src = ipv4_hdr->ip_src;
189
20
  sg.grp = ipv4_hdr->ip_dst;
190
191
20
  return sg;
192
20
}
Unexecuted instantiation: pimd.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_cmd.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_igmp.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_igmp_mtrace.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_igmpv2.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_igmpv3.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_main.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_mlag.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_msdp.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_msdp_packet.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_msdp_socket.c:pim_sgaddr_from_iphdr
Unexecuted instantiation: pim_zpthread.c:pim_sgaddr_from_iphdr
193
#else
194
static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr)
195
{
196
  const struct ip6_hdr *ipv6_hdr = iphdr;
197
  pim_sgaddr sg;
198
199
  sg.src = ipv6_hdr->ip6_src;
200
  sg.grp = ipv6_hdr->ip6_dst;
201
202
  return sg;
203
}
204
#endif
205
206
void pim_msg_build_header(pim_addr src, pim_addr dst, uint8_t *pim_msg,
207
        size_t pim_msg_size, uint8_t pim_msg_type,
208
        bool no_fwd);
209
uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr);
210
uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr);
211
212
0
#define PIM_ENCODE_SPARSE_BIT      0x04
213
101k
#define PIM_ENCODE_WC_BIT          0x02
214
155k
#define PIM_ENCODE_RPT_BIT         0x01
215
uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
216
           uint8_t bits);
217
218
uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr);
219
uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr);
220
uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
221
           uint8_t bits);
222
223
uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr);
224
uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr);
225
uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits);
226
227
size_t pim_msg_get_jp_group_size(struct list *sources);
228
size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,
229
             struct pim_jp_agg_group *sgs, size_t size);
230
#endif /* PIM_MSG_H */