]> git.proxmox.com Git - mirror_frr.git/blame - vrrpd/vrrp_packet.c
vrrpd: ipv6 support
[mirror_frr.git] / vrrpd / vrrp_packet.c
CommitLineData
5435a2bf
QY
1/*
2 * VRRPD packet crafting
3 * Copyright (C) 2018 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#include <zebra.h>
21
3eca3857
QY
22#include "lib/memory.h"
23#include "lib/ipaddr.h"
24#include "lib/checksum.h"
5435a2bf
QY
25
26#include "vrrp_packet.h"
27
3eca3857 28ssize_t vrrp_pkt_build(struct vrrp_pkt **pkt, uint8_t vrid, uint8_t prio,
862f2f37
QY
29 uint16_t max_adver_int, uint8_t numip,
30 struct ipaddr **ips)
5435a2bf 31{
862f2f37 32 bool v6 = IS_IPADDR_V6(ips[0]);
3eca3857 33
5435a2bf 34 size_t addrsz = v6 ? sizeof(struct in6_addr) : sizeof(struct in_addr);
3eca3857
QY
35 size_t pktsize = sizeof(struct vrrp_hdr) + addrsz * numip;
36 *pkt = XCALLOC(MTYPE_TMP, pktsize);
37
3eca3857
QY
38 (*pkt)->hdr.vertype |= VRRP_VERSION << 4;
39 (*pkt)->hdr.vertype |= VRRP_TYPE_ADVERTISEMENT;
40 (*pkt)->hdr.vrid = vrid;
41 (*pkt)->hdr.priority = prio;
42 (*pkt)->hdr.naddr = numip;
43 (*pkt)->hdr.v3.adver_int = htons(max_adver_int);
44
862f2f37
QY
45 uint8_t *aptr = (void *)(*pkt)->addrs;
46
3eca3857 47 for (int i = 0; i < numip; i++) {
862f2f37
QY
48 memcpy(aptr, &ips[i]->ip.addr, addrsz);
49 aptr += addrsz;
3eca3857
QY
50 }
51 (*pkt)->hdr.chksum = 0;
52
53 uint16_t chksum = in_cksum(*pkt, pktsize);
54 (*pkt)->hdr.chksum = htons(chksum);
55
56 return pktsize;
5435a2bf 57}