]> git.proxmox.com Git - mirror_frr.git/blobdiff - eigrpd/eigrp_hello.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / eigrpd / eigrp_hello.c
index 13a2c4206fbe73f8004970ecea772aed22f32fb3..f62f54b680671f7e65bc9f8e900d6097a241b4e1 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * EIGRP Sending and Receiving EIGRP Hello Packets.
  * Copyright (C) 2013-2016
  *   Tomas Hvorkovy
  *   Martin Kontsek
  *   Lukas Koribsky
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -74,19 +59,18 @@ static const struct message eigrp_general_tlv_type_str[] = {
  *
  * @param[in]   thread  current execution thread timer is associated with
  *
- * @return int  always returns 0
+ * @return void
  *
  * @par
  * Called once per "hello" time interval, default 5 seconds
  * Sends hello packet via multicast for all interfaces eigrp
  * is configured for
  */
-int eigrp_hello_timer(struct thread *thread)
+void eigrp_hello_timer(struct thread *thread)
 {
        struct eigrp_interface *ei;
 
        ei = THREAD_ARG(thread);
-       ei->t_hello = NULL;
 
        if (IS_DEBUG_EIGRP(0, TIMERS))
                zlog_debug("Start Hello Timer (%s) Expire [%u]", IF_NAME(ei),
@@ -96,11 +80,8 @@ int eigrp_hello_timer(struct thread *thread)
        eigrp_hello_send(ei, EIGRP_HELLO_NORMAL, NULL);
 
        /* Hello timer set. */
-       ei->t_hello = NULL;
        thread_add_timer(master, eigrp_hello_timer, ei, ei->params.v_hello,
                         &ei->t_hello);
-
-       return 0;
 }
 
 /**
@@ -125,6 +106,10 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
        struct eigrp *eigrp = nbr->ei->eigrp;
        struct TLV_Parameter_Type *param = (struct TLV_Parameter_Type *)tlv;
 
+       /* First validate TLV length */
+       if (tlv->length < sizeof(struct TLV_Parameter_Type))
+               return NULL;
+
        /* copy over the values passed in by the neighbor */
        nbr->K1 = param->K1;
        nbr->K2 = param->K2;
@@ -194,13 +179,22 @@ eigrp_hello_authentication_decode(struct stream *s,
 
        md5 = (struct TLV_MD5_Authentication_Type *)tlv_header;
 
-       if (md5->auth_type == EIGRP_AUTH_TYPE_MD5)
+       if (md5->auth_type == EIGRP_AUTH_TYPE_MD5) {
+               /* Validate tlv length */
+               if (md5->length < sizeof(struct TLV_MD5_Authentication_Type))
+                       return 0;
+
                return eigrp_check_md5_digest(s, md5, nbr,
                                              EIGRP_AUTH_BASIC_HELLO_FLAG);
-       else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256)
+       } else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256) {
+               /* Validate tlv length */
+               if (md5->length < sizeof(struct TLV_SHA256_Authentication_Type))
+                       return 0;
+
                return eigrp_check_sha256_digest(
                        s, (struct TLV_SHA256_Authentication_Type *)tlv_header,
                        nbr, EIGRP_AUTH_BASIC_HELLO_FLAG);
+       }
 
        return 0;
 }
@@ -223,6 +217,10 @@ static void eigrp_sw_version_decode(struct eigrp_neighbor *nbr,
 {
        struct TLV_Software_Type *version = (struct TLV_Software_Type *)tlv;
 
+       /* Validate TLV length */
+       if (tlv->length < sizeof(struct TLV_Software_Type))
+               return;
+
        nbr->os_rel_major = version->vender_major;
        nbr->os_rel_minor = version->vender_minor;
        nbr->tlv_rel_major = version->eigrp_major;
@@ -250,6 +248,10 @@ static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr,
        struct TLV_Peer_Termination_type *param =
                (struct TLV_Peer_Termination_type *)tlv;
 
+       /* Validate TLV length */
+       if (tlv->length < sizeof(struct TLV_Peer_Termination_type))
+               return;
+
        uint32_t my_ip = nbr->ei->address.u.prefix4.s_addr;
        uint32_t received_ip = param->neighbor_ip;
 
@@ -346,6 +348,10 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
                type = ntohs(tlv_header->type);
                length = ntohs(tlv_header->length);
 
+               /* Validate length against packet size */
+               if (length > size)
+                       return;
+
                if ((length > 0) && (length <= size)) {
                        if (IS_DEBUG_EIGRP_PACKET(0, RECV))
                                zlog_debug(