]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add fr_bfd_packet_ok() and use it in proto_bfd_udp
authorAlan T. DeKok <aland@freeradius.org>
Thu, 9 Mar 2023 22:11:46 +0000 (17:11 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 9 Mar 2023 22:35:56 +0000 (17:35 -0500)
src/listen/bfd/proto_bfd_udp.c
src/protocols/bfd/base.c
src/protocols/bfd/bfd.h

index e2109a1feb9b2bc30626c04e31c0853b688668a0..eee7733bb7ea663c0445f3e3bc47da2cf9e15248 100644 (file)
@@ -113,6 +113,7 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time
        size_t                          packet_len;
 
        bfd_packet_t                    *packet;
+       char const                      *err = NULL;
 
        *leftover = 0;          /* always for UDP */
 
@@ -141,9 +142,8 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time
 
        packet_len = data_size;
 
-       if (data_size < FR_BFD_HEADER_LENGTH) {
-               DEBUG2("proto_bfd_udp got 'too short' packet size %zd", data_size);
-       fail:
+       if (!fr_bfd_packet_ok(&err, buffer, packet_len)) {
+               DEBUG2("proto_bfd_udp - Received invalid packet on %s - %s", thread->name, err);
                thread->stats.total_malformed_requests++;
                return 0;
        }
@@ -152,68 +152,6 @@ static ssize_t mod_read(fr_listen_t *li, void **packet_ctx, fr_time_t *recv_time
 
        packet = (bfd_packet_t *) buffer;
 
-       if (packet->version != 1) {
-               DEBUG("BFD packet has wrong version (%d != 1)", packet->version);
-               goto fail;
-       }
-
-       if (packet->length < FR_BFD_HEADER_LENGTH) {
-               DEBUG("BFD packet header has wrong length (%d < 24)", packet->length);
-               goto fail;
-       }
-
-       if (packet->length > sizeof(*packet)) {
-               DEBUG("BFD packet length is larger than received packet (%d > %zd)", packet->length, sizeof(*packet));
-               goto fail;
-       }
-
-       if (packet->length != packet_len) {
-               DEBUG("BFD packet is not the size of the data we read from UDP (%d > %zd)", packet->length, packet_len);
-               goto fail;
-       }
-
-       if (packet->auth_present) {
-               if (packet->length < (FR_BFD_HEADER_LENGTH + 2)) { /* auth-type and auth-len */
-                       DEBUG("BFD packet length is not enough for auth-type and auth-len (%d < 26)",
-                             packet->length);
-                       goto fail;
-               }
-
-               if (packet->length < 24 + packet->auth.basic.auth_len) {
-                       DEBUG("BFD packet length is not enough for authentication data (%d < %d)",
-                             packet->length, FR_BFD_HEADER_LENGTH + packet->auth.basic.auth_len);
-                       goto fail;
-
-               }
-
-               if (packet->length != FR_BFD_HEADER_LENGTH + packet->auth.basic.auth_len) {
-                       DEBUG("WARNING: What is the extra data?");
-               }
-
-       }
-
-       if (packet->detect_multi == 0) {
-               DEBUG("BFD packet has detect_multi == 0");
-               goto fail;
-       }
-
-       if (packet->multipoint != 0) {
-               DEBUG("BFD packet has multi != 0");
-               goto fail;
-       }
-
-       if (packet->my_disc == 0) {
-               DEBUG("BFD packet has my_disc == 0");
-               goto fail;
-       }
-
-       if ((packet->your_disc == 0) &&
-           !((packet->state == BFD_STATE_DOWN) ||
-             (packet->state == BFD_STATE_ADMIN_DOWN))) {
-               DEBUG("BFD packet has invalid your-disc / state");
-               goto fail;
-       }
-
        /*
         *      Print out what we received.
         */
index 732a5133772d6d9c9ec0a06dd3983b969339374e..5322213a7db3d6bcd57f52d0bd06fccfa87bcbc5 100644 (file)
@@ -76,6 +76,81 @@ fr_table_num_ordered_t const bfd_auth_type_table[] = {
 size_t const bfd_auth_type_table_len = NUM_ELEMENTS(bfd_auth_type_table);
 
 
+bool fr_bfd_packet_ok(char const **err, uint8_t const *packet, size_t packet_len)
+{
+       bfd_packet_t const *bfd;
+       char const *msg = NULL;
+
+       if (packet_len < FR_BFD_HEADER_LENGTH) {
+               msg = "Packet is too short to be BFD";
+       fail:
+               if (err) *err = msg;
+               return false;
+       }
+
+       bfd = (bfd_packet_t const *) packet;
+
+       if (bfd->version != 1) {
+               msg = "Packet has wrong version - should be 1";
+               goto fail;
+       }
+
+       if (bfd->length < FR_BFD_HEADER_LENGTH) {
+               msg = "Header length is too small";
+               goto fail;
+       }
+
+       if (bfd->length > sizeof(*bfd)) {
+               msg = "Header length is larger than received packet";
+               goto fail;
+       }
+
+       if (bfd->length != packet_len) {
+               msg = "Header length is not the same as the amount of data we read";
+               goto fail;
+       }
+
+       if (bfd->auth_present) {
+               if (bfd->length < (FR_BFD_HEADER_LENGTH + 2)) { /* auth-type and auth-len */
+                       msg = "Header length is not enough for auth-type and auth-len";
+                       goto fail;
+               }
+
+               if (bfd->length != FR_BFD_HEADER_LENGTH + bfd->auth.basic.auth_len) {
+                       msg = "Header length mismatch with auth-len and amount of received data";
+                       goto fail;
+
+               }
+       }
+
+       if (bfd->detect_multi == 0) {
+               msg = "Packet has invalid detect-multi == 0";
+               goto fail;
+       }
+
+       if (bfd->multipoint != 0) {
+               msg = "Packet has invalid multipoint != 0";
+               goto fail;
+       }
+
+       if (bfd->my_disc == 0) {
+               msg = "Packet has invalid my-discriminator == 0";
+               goto fail;
+       }
+
+       if ((bfd->your_disc == 0) &&
+           !((bfd->state == BFD_STATE_DOWN) ||
+             (bfd->state == BFD_STATE_ADMIN_DOWN))) {
+               msg = "Packet has your-discrimator==0, but state is not down or admin-down";
+               goto fail;
+       }
+
+       if (err) *err = NULL;
+       return true;
+}
+
+
+
 int fr_bfd_init(void)
 {
        if (instance_count > 0) {
index 4993c2bf36b76050c3d04a8a4a1a425c9be6cb35..9ea39d0d015cc97c0b5b3b09cc3ee18a2af4b112 100644 (file)
@@ -163,6 +163,8 @@ ssize_t             fr_bfd_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
                              uint8_t const *packet, size_t packet_len,
                              char const *secret, size_t secret_len);
 
+bool           fr_bfd_packet_ok(char const **err, uint8_t const *packet, size_t packet_len);
+
 int    fr_bfd_init(void);
 void   fr_bfd_free(void);