mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 04:52:01 +00:00
vrrpd: fix packet encode
* Properly encode VRRP packets * Calculate checksum appropriately * Update signature to provide caller both packet and result length Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
ef4cc1ebff
commit
3eca38577a
@ -19,32 +19,48 @@
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "ipaddr.h"
|
||||
#include "lib/memory.h"
|
||||
#include "lib/ipaddr.h"
|
||||
#include "lib/checksum.h"
|
||||
|
||||
#include "vrrp_packet.h"
|
||||
|
||||
/*
|
||||
* Builds a VRRP packet.
|
||||
*/
|
||||
struct vrrp_pkt *vrrp_pkt_build(uint8_t vrid, uint8_t prio,
|
||||
uint16_t max_adver_int, bool v6, uint8_t numip,
|
||||
void **ips)
|
||||
ssize_t vrrp_pkt_build(struct vrrp_pkt **pkt, uint8_t vrid, uint8_t prio,
|
||||
uint16_t max_adver_int, bool v6, uint8_t numip,
|
||||
void **ips)
|
||||
{
|
||||
/* Used for pointer math when filling IPvX field */
|
||||
struct in6_addr *v6ptr;
|
||||
struct in_addr *v4ptr;
|
||||
|
||||
size_t addrsz = v6 ? sizeof(struct in6_addr) : sizeof(struct in_addr);
|
||||
struct vrrp_pkt *pkt =
|
||||
XCALLOC(MTYPE_TMP, sizeof(struct vrrp_pkt) + addrsz * numip);
|
||||
size_t pktsize = sizeof(struct vrrp_hdr) + addrsz * numip;
|
||||
*pkt = XCALLOC(MTYPE_TMP, pktsize);
|
||||
|
||||
pkt->hdr.version = VRRP_VERSION;
|
||||
pkt->hdr.type = VRRP_TYPE_ADVERTISEMENT;
|
||||
pkt->hdr.vrid = vrid;
|
||||
pkt->hdr.priority = prio;
|
||||
pkt->hdr.v3.rsvd = 0;
|
||||
pkt->hdr.v3.adver_int = max_adver_int;
|
||||
for (uint8_t i = 0; i < numip; i++)
|
||||
memcpy(&pkt->addrs[i].v4, ips[i], addrsz);
|
||||
/* FIXME */
|
||||
pkt->hdr.chksum = 0;
|
||||
v6ptr = (struct in6_addr *) (*pkt)->addrs;
|
||||
v4ptr = (struct in_addr *) (*pkt)->addrs;
|
||||
|
||||
return pkt;
|
||||
(*pkt)->hdr.vertype |= VRRP_VERSION << 4;
|
||||
(*pkt)->hdr.vertype |= VRRP_TYPE_ADVERTISEMENT;
|
||||
(*pkt)->hdr.vrid = vrid;
|
||||
(*pkt)->hdr.priority = prio;
|
||||
(*pkt)->hdr.naddr = numip;
|
||||
(*pkt)->hdr.v3.adver_int = htons(max_adver_int);
|
||||
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
for (int i = 0; i < numip; i++) {
|
||||
/* If v4, treat as array of v4 addresses */
|
||||
inet_ntop(AF_INET, ips[i], buf, sizeof(buf));
|
||||
if (!v6)
|
||||
memcpy(&v4ptr[i], ips[i], addrsz);
|
||||
else
|
||||
memcpy(&v6ptr[i], ips[i], addrsz);
|
||||
inet_ntop(AF_INET, &v4ptr[i], buf, sizeof(buf));
|
||||
}
|
||||
(*pkt)->hdr.chksum = 0;
|
||||
|
||||
uint16_t chksum = in_cksum(*pkt, pktsize);
|
||||
(*pkt)->hdr.chksum = htons(chksum);
|
||||
|
||||
return pktsize;
|
||||
}
|
||||
|
@ -30,8 +30,12 @@
|
||||
* Shared header for VRRPv2/v3 packets.
|
||||
*/
|
||||
struct vrrp_hdr {
|
||||
uint8_t version : 4;
|
||||
uint8_t type : 4;
|
||||
/*
|
||||
* H L H L
|
||||
* 0000 0000
|
||||
* ver type
|
||||
*/
|
||||
uint8_t vertype;
|
||||
uint8_t vrid;
|
||||
uint8_t priority;
|
||||
uint8_t naddr;
|
||||
@ -42,9 +46,13 @@ struct vrrp_hdr {
|
||||
uint8_t adver_int;
|
||||
} v2;
|
||||
struct {
|
||||
/* advertisement interval (in centiseconds) */
|
||||
uint16_t rsvd : 4;
|
||||
uint16_t adver_int : 12;
|
||||
/*
|
||||
* advertisement interval (in centiseconds)
|
||||
* H L H L
|
||||
* 0000 000000000000
|
||||
* rsvd adver_int
|
||||
*/
|
||||
uint16_t adver_int;
|
||||
} v3;
|
||||
};
|
||||
uint16_t chksum;
|
||||
@ -60,7 +68,29 @@ struct vrrp_pkt {
|
||||
|
||||
/*
|
||||
* Builds a VRRP packet.
|
||||
*
|
||||
* pkt
|
||||
* Pointer to store pointer to result buffer in
|
||||
*
|
||||
* vrid
|
||||
* Virtual Router Identifier
|
||||
*
|
||||
* prio
|
||||
* Virtual Router Priority
|
||||
*
|
||||
* max_adver_int
|
||||
* time between ADVERTISEMENTs
|
||||
*
|
||||
* v6
|
||||
* whether 'ips' is an array of v4 or v6 addresses
|
||||
*
|
||||
* numip
|
||||
* number of IPvX addresses in 'ips'
|
||||
*
|
||||
* ips
|
||||
* array of pointer to either struct in_addr (v6 = false) or struct in6_addr
|
||||
* (v6 = true)
|
||||
*/
|
||||
struct vrrp_pkt *vrrp_pkt_build(uint8_t vrid, uint8_t prio,
|
||||
uint16_t max_adver_int, bool v6, uint8_t numip,
|
||||
void **ips);
|
||||
ssize_t vrrp_pkt_build(struct vrrp_pkt **pkt, uint8_t vrid, uint8_t prio,
|
||||
uint16_t max_adver_int, bool v6, uint8_t numip,
|
||||
void **ips);
|
||||
|
Loading…
Reference in New Issue
Block a user