diff options
-rw-r--r-- | vrrpd/vrrp_packet.c | 9 | ||||
-rw-r--r-- | vrrpd/vrrp_packet.h | 17 |
2 files changed, 16 insertions, 10 deletions
diff --git a/vrrpd/vrrp_packet.c b/vrrpd/vrrp_packet.c index 970c8d7d7..102750eaf 100644 --- a/vrrpd/vrrp_packet.c +++ b/vrrpd/vrrp_packet.c @@ -119,7 +119,7 @@ ssize_t vrrp_pkt_adver_build(struct vrrp_pkt **pkt, struct ipaddr *src, addrsz = IPADDRSZ(ips[0]); } - size_t pktsize = VRRP_PKT_SIZE(v6 ? AF_INET6 : AF_INET, numip); + size_t pktsize = VRRP_PKT_SIZE(v6 ? AF_INET6 : AF_INET, version, numip); *pkt = XCALLOC(MTYPE_VRRP_PKT, pktsize); (*pkt)->hdr.vertype |= version << 4; @@ -283,9 +283,10 @@ ssize_t vrrp_pkt_parse_datagram(int family, int version, struct msghdr *m, VRRP_PKT_VCHECK(((*pkt)->hdr.vertype & 0x0F) == 1, "Bad type %" PRIu8, (*pkt)->hdr.vertype & 0x0f); - /* # addresses check */ - size_t ves = VRRP_PKT_SIZE(family, (*pkt)->hdr.naddr); - VRRP_PKT_VCHECK(pktsize == ves, "Packet has incorrect # addresses"); + /* Exact size check */ + size_t ves = VRRP_PKT_SIZE(family, pktver, (*pkt)->hdr.naddr); + VRRP_PKT_VCHECK(pktsize == ves, "Packet has incorrect # addresses%s", + pktver == 2 ? " or missing auth fields" : ""); /* auth type check */ if (version == 2) diff --git a/vrrpd/vrrp_packet.h b/vrrpd/vrrp_packet.h index 2061b63c6..475e4780d 100644 --- a/vrrpd/vrrp_packet.h +++ b/vrrpd/vrrp_packet.h @@ -70,6 +70,10 @@ struct vrrp_pkt { * When used, this is actually an array of one or the other, not an * array of union. If N v4 addresses are stored then * sizeof(addrs) == N * sizeof(struct in_addr). + * + * Under v2, the last 2 entries in this array are the authentication + * data fields. We don't support auth in v2 so these are always just 8 + * bytes of 0x00. */ union { struct in_addr v4; @@ -77,17 +81,18 @@ struct vrrp_pkt { } addrs[]; } __attribute__((packed)); -#define VRRP_PKT_SIZE(_f, _naddr) \ +#define VRRP_PKT_SIZE(_f, _ver, _naddr) \ ({ \ size_t _asz = ((_f) == AF_INET) ? sizeof(struct in_addr) \ : sizeof(struct in6_addr); \ - sizeof(struct vrrp_hdr) + (_asz * (_naddr)); \ + size_t _auth = 2 * sizeof(uint32_t) * (3 - (_ver)); \ + sizeof(struct vrrp_hdr) + (_asz * (_naddr)) + _auth; \ }) -#define VRRP_MIN_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 1) -#define VRRP_MAX_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 255) -#define VRRP_MIN_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 1) -#define VRRP_MAX_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 255) +#define VRRP_MIN_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 3, 1) +#define VRRP_MAX_PKT_SIZE_V4 VRRP_PKT_SIZE(AF_INET, 2, 255) +#define VRRP_MIN_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 1) +#define VRRP_MAX_PKT_SIZE_V6 VRRP_PKT_SIZE(AF_INET6, 3, 255) #define VRRP_MIN_PKT_SIZE VRRP_MIN_PKT_SIZE_V4 #define VRRP_MAX_PKT_SIZE VRRP_MAX_PKT_SIZE_V6 |