]> git.proxmox.com Git - mirror_frr.git/blob - vrrpd/vrrp_packet.h
Merge pull request #4365 from adharkar/frr-master-fpm_rtm_table
[mirror_frr.git] / vrrpd / vrrp_packet.h
1 /*
2 * VRRP packet crafting.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
4 * Quentin Young
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 #ifndef __VRRP_PACKET_H__
21 #define __VRRP_PACKET_H__
22
23 #include <zebra.h>
24
25 #include "lib/ipaddr.h"
26 #include "lib/memory.h"
27 #include "lib/prefix.h"
28
29 #define VRRP_TYPE_ADVERTISEMENT 1
30
31 extern const char *vrrp_packet_names[16];
32
33 /*
34 * Shared header for VRRPv2/v3 packets.
35 */
36 struct vrrp_hdr {
37 /*
38 * H L H L
39 * 0000 0000
40 * ver type
41 */
42 uint8_t vertype;
43 uint8_t vrid;
44 uint8_t priority;
45 uint8_t naddr;
46 union {
47 struct {
48 uint8_t auth_type;
49 /* advertisement interval (in sec) */
50 uint8_t adver_int;
51 } v2;
52 struct {
53 /*
54 * advertisement interval (in centiseconds)
55 * H L H L
56 * 0000 000000000000
57 * rsvd adver_int
58 */
59 uint16_t adver_int;
60 } v3;
61 };
62 uint16_t chksum;
63 } __attribute__((packed));
64
65 #define VRRP_HDR_SIZE sizeof(struct vrrp_hdr)
66
67 struct vrrp_pkt {
68 struct vrrp_hdr hdr;
69 /*
70 * When used, this is actually an array of one or the other, not an
71 * array of union. If N v4 addresses are stored then
72 * sizeof(addrs) == N * sizeof(struct in_addr).
73 *
74 * Under v2, the last 2 entries in this array are the authentication
75 * data fields. We don't support auth in v2 so these are always just 8
76 * bytes of 0x00.
77 */
78 union {
79 struct in_addr v4;
80 struct in6_addr v6;
81 } addrs[];
82 } __attribute__((packed));
83
84 #define VRRP_PKT_SIZE(_f, _ver, _naddr) \
85 ({ \
86 size_t _asz = ((_f) == AF_INET) ? sizeof(struct in_addr) \
87 : sizeof(struct in6_addr); \
88 size_t _auth = 2 * sizeof(uint32_t) * (3 - (_ver)); \
89 sizeof(struct vrrp_hdr) + (_asz * (_naddr)) + _auth; \
90 })
91
92 #define VRRP_MIN_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 3, 1)
93 #define VRRP_MAX_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 2, 255)
94 #define VRRP_MIN_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 1)
95 #define VRRP_MAX_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 255)
96
97 #define VRRP_MIN_PKT_SIZE VRRP_MIN_PKT_SIZE_V4
98 #define VRRP_MAX_PKT_SIZE VRRP_MAX_PKT_SIZE_V6
99
100 /*
101 * Builds a VRRP ADVERTISEMENT packet.
102 *
103 * pkt
104 * Pointer to store pointer to result buffer in
105 *
106 * src
107 * Source address packet will be transmitted from. This is needed to compute
108 * the VRRP checksum. The returned packet must be sent in an IP datagram with
109 * the source address equal to this field, or the checksum will be invalid.
110 *
111 * version
112 * VRRP version; must be 2 or 3
113 *
114 * vrid
115 * Virtual Router Identifier
116 *
117 * prio
118 * Virtual Router Priority
119 *
120 * max_adver_int
121 * time between ADVERTISEMENTs
122 *
123 * v6
124 * whether 'ips' is an array of v4 or v6 addresses
125 *
126 * numip
127 * number of IPvX addresses in 'ips'
128 *
129 * ips
130 * array of pointer to either struct in_addr (v6 = false) or struct in6_addr
131 * (v6 = true)
132 */
133 ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src,
134 uint8_t version, uint8_t vrid, uint8_t prio,
135 uint16_t max_adver_int, uint8_t numip,
136 struct ipaddr **ips);
137
138 /*
139 * Dumps a VRRP ADVERTISEMENT packet to a string.
140 *
141 * Currently only dumps the header.
142 *
143 * buf
144 * Buffer to store string representation
145 *
146 * buflen
147 * Size of buf
148 *
149 * pkt
150 * Packet to dump to a string
151 *
152 * Returns:
153 * # bytes written to buf
154 */
155 size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt);
156
157
158 /*
159 * Parses a VRRP packet, checking for illegal or invalid data.
160 *
161 * This function parses both VRRPv2 and VRRPv3 packets. Which version is
162 * expected is determined by the version argument. For example, if version is 3
163 * and the received packet has version field 2 it will fail to parse.
164 *
165 * Note that this function only checks whether the packet itself is a valid
166 * VRRP packet. It is up to the caller to validate whether the VRID is correct,
167 * priority and timer values are correct, etc.
168 *
169 * family
170 * Address family of received packet
171 *
172 * version
173 * VRRP version to use for validation
174 *
175 * m
176 * msghdr containing results of recvmsg() on VRRP router socket
177 *
178 * read
179 * Return value of recvmsg() on VRRP router socket; must be non-negative
180 *
181 * src
182 * Pointer to struct ipaddr to store address of datagram sender
183 *
184 * pkt
185 * Pointer to pointer to set to location of VRRP packet within buf
186 *
187 * errmsg
188 * Buffer to store human-readable error message in case of error; may be
189 * NULL, in which case no message will be stored
190 *
191 * errmsg_len
192 * Size of errmsg
193 *
194 * Returns:
195 * Size of VRRP packet, or -1 upon error
196 */
197 ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
198 size_t read, struct ipaddr *src,
199 struct vrrp_pkt **pkt, char *errmsg,
200 size_t errmsg_len);
201
202 #endif /* __VRRP_PACKET_H__ */