mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 07:27:50 +00:00
vrrpd: specify version when parsing vrrp packet
Move a bit more validation into vrrp_packet.c Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
2884f9bbe4
commit
8cb3d80332
@ -654,8 +654,8 @@ static int vrrp_read(struct thread *thread)
|
|||||||
r->vr->vrid, family2str(r->family));
|
r->vr->vrid, family2str(r->family));
|
||||||
zlog_hexdump(r->ibuf, nbytes);
|
zlog_hexdump(r->ibuf, nbytes);
|
||||||
|
|
||||||
pktsize = vrrp_pkt_parse_datagram(r->family, &m, nbytes, &src, &pkt,
|
pktsize = vrrp_pkt_parse_datagram(r->family, r->vr->version, &m, nbytes,
|
||||||
errbuf, sizeof(errbuf));
|
&src, &pkt, errbuf, sizeof(errbuf));
|
||||||
|
|
||||||
if (pktsize < 0) {
|
if (pktsize < 0) {
|
||||||
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
|
||||||
|
@ -171,9 +171,10 @@ size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt)
|
|||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t vrrp_pkt_parse_datagram(int family, struct msghdr *m, size_t read,
|
ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
|
||||||
struct ipaddr *src, struct vrrp_pkt **pkt,
|
size_t read, struct ipaddr *src,
|
||||||
char *errmsg, size_t errmsg_len)
|
struct vrrp_pkt **pkt, char *errmsg,
|
||||||
|
size_t errmsg_len)
|
||||||
{
|
{
|
||||||
/* Source (MAC & IP), Dest (MAC & IP) TTL validation done by kernel */
|
/* Source (MAC & IP), Dest (MAC & IP) TTL validation done by kernel */
|
||||||
size_t addrsz = (family == AF_INET) ? sizeof(struct in_addr)
|
size_t addrsz = (family == AF_INET) ? sizeof(struct in_addr)
|
||||||
@ -260,19 +261,20 @@ ssize_t vrrp_pkt_parse_datagram(int family, struct msghdr *m, size_t read,
|
|||||||
"VRRP packet is oversized (%lu > %lu)", pktsize,
|
"VRRP packet is oversized (%lu > %lu)", pktsize,
|
||||||
VRRP_MAX_PKT_SIZE);
|
VRRP_MAX_PKT_SIZE);
|
||||||
|
|
||||||
|
/* Version check */
|
||||||
|
uint8_t pktver = (*pkt)->hdr.vertype >> 4;
|
||||||
|
VRRP_PKT_VCHECK(pktver == version, "Bad version %u", pktver);
|
||||||
|
|
||||||
/* Checksum check */
|
/* Checksum check */
|
||||||
uint16_t chksum = vrrp_pkt_checksum(*pkt, pktsize, src);
|
uint16_t chksum = vrrp_pkt_checksum(*pkt, pktsize, src);
|
||||||
VRRP_PKT_VCHECK((*pkt)->hdr.chksum == chksum,
|
VRRP_PKT_VCHECK((*pkt)->hdr.chksum == chksum,
|
||||||
"Bad VRRP checksum %" PRIu16 "; should be %" PRIu16 "",
|
"Bad VRRP checksum %" PRIu16 "; should be %" PRIu16 "",
|
||||||
(*pkt)->hdr.chksum, chksum);
|
(*pkt)->hdr.chksum, chksum);
|
||||||
|
|
||||||
/* Version check */
|
|
||||||
uint8_t version = (*pkt)->hdr.vertype >> 4;
|
|
||||||
VRRP_PKT_VCHECK(version == 3 || version == 2, "Bad version %u",
|
|
||||||
version);
|
|
||||||
/* Type check */
|
/* Type check */
|
||||||
VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %u",
|
VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %u",
|
||||||
(*pkt)->hdr.vertype & 0x0f);
|
(*pkt)->hdr.vertype & 0x0f);
|
||||||
|
|
||||||
/* # addresses check */
|
/* # addresses check */
|
||||||
size_t ves = VRRP_PKT_SIZE(family, (*pkt)->hdr.naddr);
|
size_t ves = VRRP_PKT_SIZE(family, (*pkt)->hdr.naddr);
|
||||||
VRRP_PKT_VCHECK(pktsize == ves, "Packet has incorrect # addresses");
|
VRRP_PKT_VCHECK(pktsize == ves, "Packet has incorrect # addresses");
|
||||||
|
@ -153,17 +153,25 @@ size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt);
|
|||||||
/*
|
/*
|
||||||
* Parses a VRRP packet, checking for illegal or invalid data.
|
* Parses a VRRP packet, checking for illegal or invalid data.
|
||||||
*
|
*
|
||||||
* This function does not check that the local router is not the IPvX owner for
|
* This function parses both VRRPv2 and VRRPv3 packets. Which version is
|
||||||
* the addresses received; that should be done by the caller.
|
* expected is determined by the version argument. For example, if version is 3
|
||||||
|
* and the received packet has version field 2 it will fail to parse.
|
||||||
|
*
|
||||||
|
* Note that this function only checks whether the packet itself is a valid
|
||||||
|
* VRRP packet. It is up to the caller to validate whether the VRID is correct,
|
||||||
|
* priority and timer values are correct, etc.
|
||||||
*
|
*
|
||||||
* family
|
* family
|
||||||
* Address family of received packet
|
* Address family of received packet
|
||||||
*
|
*
|
||||||
|
* version
|
||||||
|
* VRRP version to use for validation
|
||||||
|
*
|
||||||
* m
|
* m
|
||||||
* msghdr containing results of recvmsg() on VRRP router socket
|
* msghdr containing results of recvmsg() on VRRP router socket
|
||||||
*
|
*
|
||||||
* read
|
* read
|
||||||
* return value of recvmsg() on VRRP router socket; must be non-negative
|
* Return value of recvmsg() on VRRP router socket; must be non-negative
|
||||||
*
|
*
|
||||||
* src
|
* src
|
||||||
* Pointer to struct ipaddr to store address of datagram sender
|
* Pointer to struct ipaddr to store address of datagram sender
|
||||||
@ -181,8 +189,9 @@ size_t vrrp_pkt_adver_dump(char *buf, size_t buflen, struct vrrp_pkt *pkt);
|
|||||||
* Returns:
|
* Returns:
|
||||||
* Size of VRRP packet, or -1 upon error
|
* Size of VRRP packet, or -1 upon error
|
||||||
*/
|
*/
|
||||||
ssize_t vrrp_pkt_parse_datagram(int family, struct msghdr *m, size_t read,
|
ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m,
|
||||||
struct ipaddr *src, struct vrrp_pkt **pkt,
|
size_t read, struct ipaddr *src,
|
||||||
char *errmsg, size_t errmsg_len);
|
struct vrrp_pkt **pkt, char *errmsg,
|
||||||
|
size_t errmsg_len);
|
||||||
|
|
||||||
#endif /* __VRRP_PACKET_H__ */
|
#endif /* __VRRP_PACKET_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user