summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
authorMobashshera Rasool <mrasool@vmware.com>2021-07-16 13:55:56 +0200
committerMobashshera Rasool <mrasool@vmware.com>2021-07-19 21:46:00 +0200
commitff4ad8709b087b8e1c35ab5008eb34e0af9cd18a (patch)
tree7aab3c4e538f8e4fdc54fb5e7185f98e5ed70fc3 /pimd
parentMerge pull request #9038 from donaldsharp/realloc_bgp (diff)
downloadfrr-ff4ad8709b087b8e1c35ab5008eb34e0af9cd18a.tar.xz
frr-ff4ad8709b087b8e1c35ab5008eb34e0af9cd18a.zip
pimd: Abstracting header verification for igmp
Moving the header verification checks inside a function. Signed-off-by: Mobashshera Rasool <mrassol@vmware.com>
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim_igmp.c45
-rw-r--r--pimd/pim_igmp.h3
2 files changed, 31 insertions, 17 deletions
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 73dcdbddb..36f044b16 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -469,6 +469,24 @@ static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from,
return 0;
}
+bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len,
+ int msg_type)
+{
+ if (len < sizeof(*ip_hdr)) {
+ zlog_warn("IGMP packet size=%zu shorter than minimum=%zu", len,
+ sizeof(*ip_hdr));
+ return false;
+ }
+
+ if (igmp_msg_len < PIM_IGMP_MIN_LEN) {
+ zlog_warn("IGMP message size=%d shorter than minimum=%d",
+ igmp_msg_len, PIM_IGMP_MIN_LEN);
+ return false;
+ }
+
+ return true;
+}
+
int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
{
struct ip *ip_hdr;
@@ -479,17 +497,8 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
char from_str[INET_ADDRSTRLEN];
char to_str[INET_ADDRSTRLEN];
- if (len < sizeof(*ip_hdr)) {
- zlog_warn("IGMP packet size=%zu shorter than minimum=%zu", len,
- sizeof(*ip_hdr));
- return -1;
- }
-
ip_hdr = (struct ip *)buf;
- pim_inet4_dump("<src?>", ip_hdr->ip_src, from_str, sizeof(from_str));
- pim_inet4_dump("<dst?>", ip_hdr->ip_dst, to_str, sizeof(to_str));
-
ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
if (ip_hlen > len) {
@@ -501,15 +510,11 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
igmp_msg = buf + ip_hlen;
igmp_msg_len = len - ip_hlen;
-
- if (igmp_msg_len < PIM_IGMP_MIN_LEN) {
- zlog_warn("IGMP message size=%d shorter than minimum=%d",
- igmp_msg_len, PIM_IGMP_MIN_LEN);
- return -1;
- }
-
msg_type = *igmp_msg;
+ pim_inet4_dump("<src?>", ip_hdr->ip_src, from_str, sizeof(from_str));
+ pim_inet4_dump("<dst?>", ip_hdr->ip_dst, to_str, sizeof(to_str));
+
if (PIM_DEBUG_IGMP_PACKETS) {
zlog_debug(
"Recv IGMP packet from %s to %s on %s: size=%zu ttl=%d msg_type=%d msg_size=%d",
@@ -517,6 +522,14 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
msg_type, igmp_msg_len);
}
+ if (!pim_igmp_verify_header(ip_hdr, len, igmp_msg_len, msg_type)) {
+ zlog_warn(
+ "Recv IGMP packet from %s to %s on %s: size=%zu ttl=%u msg_type=%d msg_size=%d",
+ from_str, to_str, igmp->interface->name, len,
+ ip_hdr->ip_ttl, msg_type, igmp_msg_len);
+ return -1;
+ }
+
switch (msg_type) {
case PIM_IGMP_MEMBERSHIP_QUERY: {
int max_resp_code = igmp_msg[1];
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index a0681128c..88324b793 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -116,7 +116,8 @@ void igmp_sock_delete(struct igmp_sock *igmp);
void igmp_sock_free(struct igmp_sock *igmp);
void igmp_sock_delete_all(struct interface *ifp);
int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len);
-
+bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len,
+ int msg_type);
void pim_igmp_general_query_on(struct igmp_sock *igmp);
void pim_igmp_general_query_off(struct igmp_sock *igmp);
void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp);