]>
Commit | Line | Data |
---|---|---|
12e41d03 | 1 | /* |
896014f4 DL |
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 | */ | |
12e41d03 DL |
19 | |
20 | #ifndef PIM_MSG_H | |
21 | #define PIM_MSG_H | |
22 | ||
23 | #include <netinet/in.h> | |
d1fd950a MR |
24 | #if PIM_IPV == 6 |
25 | #include <netinet/ip6.h> | |
26 | #endif | |
12e41d03 | 27 | |
982bff89 | 28 | #include "pim_jp_agg.h" |
d57a8bbf | 29 | |
30 | #define PIM_HDR_LEN sizeof(struct pim_msg_header) | |
12e41d03 | 31 | /* |
d62a17ae | 32 | Number Description |
12e41d03 DL |
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 | */ | |
34687162 | 41 | enum pim_msg_address_family { |
d62a17ae | 42 | PIM_MSG_ADDRESS_FAMILY_RESERVED, |
43 | PIM_MSG_ADDRESS_FAMILY_IPV4, | |
44 | PIM_MSG_ADDRESS_FAMILY_IPV6, | |
34687162 | 45 | }; |
12e41d03 | 46 | |
70ce34ae | 47 | /* |
be6a3245 | 48 | * pim_msg_hdr |
d57a8bbf | 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 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
70ce34ae DS |
57 | */ |
58 | struct pim_msg_header { | |
be6a3245 | 59 | #if (BYTE_ORDER == LITTLE_ENDIAN) |
d62a17ae | 60 | uint8_t type : 4; |
61 | uint8_t ver : 4; | |
be6a3245 BA |
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; | |
d57a8bbf | 67 | uint8_t Nbit : 1; /* No Fwd Bit */ |
68 | uint8_t reserved : 7; | |
be6a3245 BA |
69 | #else |
70 | #error"Please set byte order" | |
71 | #endif | |
d62a17ae | 72 | uint16_t checksum; |
73 | } __attribute__((packed)); | |
70ce34ae | 74 | |
74ac496f | 75 | struct pim_encoded_ipv4_unicast { |
d62a17ae | 76 | uint8_t family; |
77 | uint8_t reserved; | |
78 | struct in_addr addr; | |
79 | } __attribute__((packed)); | |
74ac496f | 80 | |
16763d77 DL |
81 | struct pim_encoded_ipv6_unicast { |
82 | uint8_t family; | |
83 | uint8_t reserved; | |
84 | struct in6_addr addr; | |
85 | } __attribute__((packed)); | |
86 | ||
71361a2c | 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 | */ | |
74ac496f | 97 | struct pim_encoded_group_ipv4 { |
d62a17ae | 98 | uint8_t family; |
71361a2c | 99 | uint8_t ne; |
be6a3245 BA |
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) | |
d57a8bbf | 105 | uint8_t bidir : 1; /* Bidir bit */ |
106 | uint8_t reserved : 6; /* Reserved */ | |
107 | uint8_t sz : 1; /* scope zone bit */ | |
be6a3245 BA |
108 | #else |
109 | #error"Please set byte order" | |
110 | #endif | |
d62a17ae | 111 | uint8_t mask; |
112 | struct in_addr addr; | |
113 | } __attribute__((packed)); | |
74ac496f | 114 | |
16763d77 DL |
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)); | |
71361a2c | 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 | */ | |
74ac496f | 143 | struct pim_encoded_source_ipv4 { |
d62a17ae | 144 | uint8_t family; |
71361a2c | 145 | uint8_t ne; |
d62a17ae | 146 | uint8_t bits; |
147 | uint8_t mask; | |
148 | struct in_addr addr; | |
149 | } __attribute__((packed)); | |
74ac496f | 150 | |
16763d77 DL |
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; | |
a5fa9822 | 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 | |
16763d77 DL |
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; | |
a5fa9822 | 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 | |
16763d77 DL |
176 | #endif |
177 | /* clang-format on */ | |
178 | ||
74ac496f | 179 | struct pim_jp_groups { |
16763d77 | 180 | pim_encoded_group g; |
d62a17ae | 181 | uint16_t joins; |
182 | uint16_t prunes; | |
16763d77 | 183 | pim_encoded_source s[1]; |
d62a17ae | 184 | } __attribute__((packed)); |
74ac496f DS |
185 | |
186 | struct pim_jp { | |
d62a17ae | 187 | struct pim_msg_header header; |
16763d77 | 188 | pim_encoded_unicast addr; |
d62a17ae | 189 | uint8_t reserved; |
190 | uint8_t num_groups; | |
191 | uint16_t holdtime; | |
192 | struct pim_jp_groups groups[1]; | |
193 | } __attribute__((packed)); | |
74ac496f | 194 | |
d1fd950a MR |
195 | #if PIM_IPV == 4 |
196 | static inline pim_sgaddr pim_sgaddr_from_iphdr(const void *iphdr) | |
197 | { | |
198 | const struct ip *ipv4_hdr = iphdr; | |
199 | pim_sgaddr sg; | |
200 | ||
201 | sg.src = ipv4_hdr->ip_src; | |
202 | sg.grp = ipv4_hdr->ip_dst; | |
203 | ||
204 | 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 | ||
d62a17ae | 219 | void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size, |
d57a8bbf | 220 | uint8_t pim_msg_type, bool no_fwd); |
f8e7d799 DS |
221 | uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, struct in_addr addr); |
222 | uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr); | |
984c84f4 DS |
223 | |
224 | #define PIM_ENCODE_SPARSE_BIT 0x04 | |
225 | #define PIM_ENCODE_WC_BIT 0x02 | |
226 | #define PIM_ENCODE_RPT_BIT 0x01 | |
d62a17ae | 227 | uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr, |
228 | uint8_t bits); | |
12e41d03 | 229 | |
16763d77 DL |
230 | uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr); |
231 | uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr); | |
232 | uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr, | |
233 | uint8_t bits); | |
234 | ||
235 | uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr); | |
236 | uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr); | |
237 | uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits); | |
346cffe3 | 238 | |
d62a17ae | 239 | size_t pim_msg_get_jp_group_size(struct list *sources); |
240 | size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp, | |
241 | struct pim_jp_agg_group *sgs, size_t size); | |
12e41d03 | 242 | #endif /* PIM_MSG_H */ |