The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
decode.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 869c0953c554275994f1280f97aea874a7e08eae $
19 *
20 * @file protocols/bfd/decode.c
21 * @brief Functions to decode BFD packets
22 *
23 * @copyright 2023 Network RADIUS SAS (legal@networkradius.com)
24 */
25RCSID("$Id: 869c0953c554275994f1280f97aea874a7e08eae $")
26
27#include <freeradius-devel/util/struct.h>
28#include <freeradius-devel/io/test_point.h>
29#include <freeradius-devel/internal/internal.h>
30
31#include "attrs.h"
32
33static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
35 uint8_t const *data, size_t const data_len, UNUSED void *decode_ctx)
36{
37 ssize_t slen;
39
40 FR_PROTO_HEX_DUMP(data, data_len, "decode_value");
41
43 if (!vp) return PAIR_DECODE_OOM;
44
45 slen = fr_value_box_from_network(vp, &vp->data, vp->vp_type, vp->da,
46 &FR_DBUFF_TMP(data, data_len), data_len, true);
47 if (slen < 0) {
49 return slen;
50 }
51
52 fr_assert(vp != NULL);
53
54 vp->vp_tainted = true;
56
57 return data_len;
58}
59
60
61/** Decode a raw BFD packet into VPs.
62 *
63 */
65 uint8_t const *packet, size_t packet_len,
66 char const *secret, UNUSED size_t secret_len)
67{
68 ssize_t slen;
69 fr_bfd_ctx_t packet_ctx;
70 bfd_packet_t const *bfd;
72 fr_dbuff_t dbuff;
73
74 packet_ctx.secret = secret;
75
76 bfd = (bfd_packet_t const *) packet;
77
78 slen = fr_struct_from_network(ctx, out, attr_bfd_packet, packet, bfd->length,
79 &packet_ctx, decode_value, NULL);
80 if (slen < 0) return slen;
81
82 if (bfd->length == packet_len) return packet_len;
83
84 /*
85 * Try to decode additional data.
86 */
88 if (!vp) return packet_len;
89
90 fr_dbuff_init(&dbuff, packet + slen, packet_len - slen);
91
92 if ((fr_internal_decode_list_dbuff(vp, &vp->vp_group, fr_dict_root(dict_bfd), &dbuff, NULL) < 0) ||
93 (fr_pair_list_num_elements(&vp->vp_group) == 0)) {
94 TALLOC_FREE(vp);
95 } else {
97 }
98
99 return slen;
100}
101
102static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict,
103 UNUSED fr_dict_attr_t const *root_da)
104{
105 fr_bfd_ctx_t *test_ctx;
106
107 test_ctx = talloc_zero(ctx, fr_bfd_ctx_t);
108 test_ctx->secret = talloc_strdup(test_ctx, "testing123");
109 test_ctx->tmp_ctx = talloc_zero(test_ctx, uint8_t);
110
111 *out = test_ctx;
112
113 return 0;
114}
115
117 uint8_t const *data, size_t data_len, void *proto_ctx)
118{
119 fr_pair_t *vp;
120 bfd_packet_t const *packet;
121 fr_bfd_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_bfd_ctx_t);
122
123 if (data_len < FR_BFD_HEADER_LENGTH) {
124 fr_strerror_const("Packet is too small for BFD");
125 return -1;
126 }
127
128 packet = (bfd_packet_t const *) data;
129
130 if (packet->length > data_len) {
131 fr_strerror_const("Packet.length is larger than received data");
132 return -1;
133 }
134
135 if (packet->length < FR_BFD_HEADER_LENGTH) {
136 fr_strerror_const("Packet.length is smaller then BFD header size");
137 return -1;
138 }
139
140 if (packet->version != 1) {
141 fr_strerror_const("Packet.version has invalid value");
142 return -1;
143 }
144
145 if (packet->detect_multi == 0) {
146 fr_strerror_const("Packet.detect-multi has invalid value zero");
147 return -1;
148 }
149
150 if (packet->detect_multi == 0) {
151 fr_strerror_const("Packet.detect-multi has invalid value zero");
152 return -1;
153 }
154
155 if (packet->multipoint != 0) {
156 fr_strerror_const("Packet.multipoint has invalid non-zero value");
157 return -1;
158 }
159
160 if (packet->my_disc == 0) {
161 fr_strerror_const("Packet.my-discriminator has invalid value zero");
162 return -1;
163 }
164
165 if ((packet->your_disc == 0) &&
166 !((packet->state == BFD_STATE_DOWN) ||
167 (packet->state == BFD_STATE_ADMIN_DOWN))) {
168 fr_strerror_const("Packet has invalid values for your-discriminator and state");
169 return 0;
170 }
171
172 /*
173 * Get the packet type.
174 */
176 if (!vp) {
177 fr_strerror_const("Failed creating Packet-Type");
178 return -1;
179 }
180
181 vp->vp_uint32 = packet->state;
183
184#if 0
185 /*
186 * We always decode the packet as a nested VP.
187 */
189 if (!vp) {
190 fr_strerror_const("Failed creating Packet");
191 return -1;
192 }
194#endif
195
196 /* coverity[tainted_data] */
197 return fr_bfd_decode(ctx, out, data, data_len,
198 test_ctx->secret, talloc_array_length(test_ctx->secret) - 1);
199}
200
201/*
202 * Test points
203 */
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
Definition bfd.h:155
#define FR_BFD_HEADER_LENGTH
Definition bfd.h:141
char const * secret
shared secret. MUST be talloc'd
Definition bfd.h:156
@ BFD_STATE_DOWN
Definition bfd.h:35
@ BFD_STATE_ADMIN_DOWN
Definition bfd.h:34
#define RCSID(id)
Definition build.h:485
#define UNUSED
Definition build.h:317
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
Definition dbuff.h:356
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:516
static fr_dict_attr_t const * attr_packet_type
Definition dhcpclient.c:89
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2496
#define PAIR_DECODE_OOM
Fatal error - Out of memory.
Definition pair.h:45
talloc_free(reap)
long int ssize_t
unsigned char uint8_t
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1353
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition pair.c:287
static fr_dict_attr_t const * attr_bfd_packet
Definition proto_bfd.c:69
static fr_dict_t const * dict_bfd
Definition proto_bfd.c:60
HIDDEN fr_dict_attr_t const * attr_bfd_additional_data
Definition base.c:52
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)
Decode a raw BFD packet into VPs.
Definition decode.c:64
static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict, UNUSED fr_dict_attr_t const *root_da)
Definition decode.c:102
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)
Definition decode.c:116
fr_test_point_proto_decode_t bfd_tp_decode_proto
Definition decode.c:205
ssize_t fr_internal_decode_list_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *dbuff, void *decode_ctx)
Retrieve all pairs from the dbuff.
Definition decode.c:310
#define decode_value
Definition decode.c:410
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:38
static char * secret
fr_pair_t * vp
ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv)
Convert a STRUCT to one or more VPs.
Definition struct.c:32
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Definition test_point.h:68
Entry point for protocol decoders.
Definition test_point.h:67
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
static fr_slen_t parent
Definition pair.h:841
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
Definition proto.h:42
#define fr_strerror_const(_msg)
Definition strerror.h:223
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
Definition value.c:1913
static fr_slen_t data
Definition value.h:1293
static size_t char ** out
Definition value.h:1023