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 */ |