]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add BFD decoder
authorAlan T. DeKok <aland@freeradius.org>
Tue, 28 Feb 2023 21:07:09 +0000 (16:07 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 28 Feb 2023 21:15:35 +0000 (16:15 -0500)
src/protocols/bfd/all.mk
src/protocols/bfd/bfd.h
src/protocols/bfd/decode.c [new file with mode: 0644]
src/protocols/bfd/encode.c
src/tests/unit/protocols/bfd/base.txt

index 23b7badc4d96c08275990308aaf95c6deca7e527..7cac90134ef577e0cf5117b7fe57fd6c396b2846 100644 (file)
@@ -1,5 +1,5 @@
 TARGET         := libfreeradius-bfd$(L)
 
-SOURCES                := base.c encode.c
+SOURCES                := base.c encode.c decode.c
 
 TGT_PREREQS    := libfreeradius-util$(L)
index 4f0462dc898d0bb66fb83d9d9e71a4154517d9ea..b72b1200b22b15acba691a47ef1de7f3ce4a583e 100644 (file)
@@ -148,6 +148,9 @@ typedef struct {
 ssize_t                fr_bfd_encode(uint8_t *packet, size_t packet_len,  uint8_t const *original,
                              char const *secret,  size_t secret_len, fr_pair_list_t *vps);
 
+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);
 
 int    fr_bfd_init(void);
 void   fr_bfd_free(void);
diff --git a/src/protocols/bfd/decode.c b/src/protocols/bfd/decode.c
new file mode 100644 (file)
index 0000000..4546570
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2.1 of the License, or (at your option) any later version.
+ *
+ *   This library 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
+ *   Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public
+ *   License along with this library; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ *
+ * @file protocols/bfd/decode.c
+ * @brief Functions to decode BFD packets
+ *
+ * @copyright 2023 Network RADIUS SAS (legal@networkradius.com)
+ */
+RCSID("$Id$")
+
+#include <freeradius-devel/util/struct.h>
+#include <freeradius-devel/io/test_point.h>
+#include <freeradius-devel/protocol/radius/freeradius.internal.h>
+
+#include "attrs.h"
+
+static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                           fr_dict_attr_t const *parent,
+                           uint8_t const *data, size_t const data_len, UNUSED void *decode_ctx)
+{
+       ssize_t slen;
+       fr_pair_t *vp;
+
+       FR_PROTO_HEX_DUMP(data, data_len, "decode_value");
+
+       vp = fr_pair_afrom_da(ctx, parent);
+       if (!vp) return PAIR_DECODE_OOM;
+
+       slen =  fr_value_box_from_network(vp, &vp->data, vp->da->type, vp->da,
+                                         &FR_DBUFF_TMP(data, data_len), data_len, true);
+       if (slen < 0) {
+               talloc_free(vp);
+               return slen;
+       }
+
+       fr_assert(vp != NULL);
+
+       vp->vp_tainted = true;
+       fr_pair_append(out, vp);
+
+       return data_len;
+}
+
+
+/** Decode a raw BFD packet into VPs.
+ *
+ */
+ssize_t fr_bfd_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                     uint8_t const *packet, size_t packet_len,
+                     char const *secret, UNUSED size_t secret_len)
+{
+       ssize_t                 slen;
+       fr_bfd_ctx_t            packet_ctx;
+
+       packet_ctx.secret = secret;
+
+       slen = fr_struct_from_network(ctx, out, attr_bfd_packet, packet, packet_len, true,
+                                     &packet_ctx, decode_value, NULL);
+       if (slen < 0) return slen;
+
+       return slen;
+}
+
+static int _test_ctx_free(UNUSED fr_bfd_ctx_t *ctx)
+{
+       fr_bfd_free();
+
+       return 0;
+}
+
+static int decode_test_ctx(void **out, TALLOC_CTX *ctx)
+{
+       fr_bfd_ctx_t    *test_ctx;
+
+       if (fr_bfd_init() < 0) return -1;
+
+       test_ctx = talloc_zero(ctx, fr_bfd_ctx_t);
+       test_ctx->secret = talloc_strdup(test_ctx, "testing123");
+       test_ctx->tmp_ctx = talloc_zero(test_ctx, uint8_t);
+       talloc_set_destructor(test_ctx, _test_ctx_free);
+
+       *out = test_ctx;
+
+       return 0;
+}
+
+static ssize_t fr_bfd_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                                  uint8_t const *data, size_t data_len, void *proto_ctx)
+{
+       fr_pair_t       *vp;
+       bfd_packet_t const *packet;
+       fr_bfd_ctx_t    *test_ctx = talloc_get_type_abort(proto_ctx, fr_bfd_ctx_t);
+
+       if (data_len < FR_BFD_HEADER_LENGTH) {
+               fr_strerror_const("Packet is too small for BFD");
+               return -1;
+       }
+
+       packet = (bfd_packet_t const *) data;
+
+       if (packet->length > data_len) {
+               fr_strerror_const("Packet.lenth is larger than received data");
+               return -1;
+       }
+
+       /*
+        *      Get the packet type.
+        */
+       vp = fr_pair_afrom_da(ctx, attr_packet_type);
+       if (!vp) {
+               fr_strerror_const("Failed creating Packet-Type");
+               return -1;
+       }
+
+       vp->vp_uint32 = packet->state;
+       fr_pair_append(out, vp);
+
+#if 0
+       /*
+        *      We always decode the packet as a nested VP.
+        */
+       vp = fr_pair_afrom_da(ctx, attr_bfd_packet);
+       if (!vp) {
+               fr_strerror_const("Failed creating Packet");
+               return -1;
+       }
+       fr_pair_append(out, vp);
+#endif
+
+       /* coverity[tainted_data] */
+       return fr_bfd_decode(ctx, out, data, data_len,
+                            test_ctx->secret, talloc_array_length(test_ctx->secret) - 1);
+}
+
+/*
+ *     Test points
+ */
+extern fr_test_point_proto_decode_t bfd_tp_decode_proto;
+fr_test_point_proto_decode_t bfd_tp_decode_proto = {
+       .test_ctx       = decode_test_ctx,
+       .func           = fr_bfd_decode_proto
+};
index ff6c3e41aef8a176db276dc5663480f3e2a959f4..44589f673746f2efcfda87c5004a37dd0dd9c3f3 100644 (file)
@@ -30,8 +30,6 @@ RCSID("$Id$")
 #include <freeradius-devel/io/test_point.h>
 #include "attrs.h"
 
-extern fr_dict_attr_t const *attr_bfd_packet;
-
 /** Encodes the data portion of an attribute
  *
  * @return
index 754690ad217de6c5e8d844c02884c7c75fb6b5c9..ce015719024bd41e0b04059fc316ef18bb39addf 100644 (file)
@@ -12,5 +12,8 @@ fuzzer-out bfd
 encode-proto Packet = { version = 1, diagnostic = none, state = up, poll = false, final = false, control-plane-independent = false, auth-present = false, demand = false, multipoint = false, detect-multi = 3, my-discriminator = 0xdeadbeef, your-discriminator = 0x21126809, desired-min-tx-interval = 31us, required-min-tx-interval = 127us, required-min-echo-interval   = 255us }
 match 20 c0 03 18 de ad be ef 21 12 68 09 00 00 00 1f 00 00 00 7f 00 00 00 ff
 
+decode-proto -
+match Packet-Type = Up, Packet = { version = 1, diagnostic = none, state = up, poll = no, final = no, control-plane-independent = no, auth-present = no, demand = no, multipoint = no, detect-multi = 3, length = 24, my-discriminator = 3735928559, your-discriminator = 554854409, desired-min-tx-interval = 31, required-min-tx-interval = 127, required-min-echo-interval = 255 }
+
 count
-match 5
+match 7