diff options
author | Mobashshera Rasool <mrasool@vmware.com> | 2021-07-16 13:55:56 +0200 |
---|---|---|
committer | Mobashshera Rasool <mrasool@vmware.com> | 2021-07-19 21:46:00 +0200 |
commit | ff4ad8709b087b8e1c35ab5008eb34e0af9cd18a (patch) | |
tree | 7aab3c4e538f8e4fdc54fb5e7185f98e5ed70fc3 /pimd | |
parent | Merge pull request #9038 from donaldsharp/realloc_bgp (diff) | |
download | frr-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.c | 45 | ||||
-rw-r--r-- | pimd/pim_igmp.h | 3 |
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); |