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: e2788a0ea0e406ca83e33f273b8480f5d6d64dd6 $
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: e2788a0ea0e406ca83e33f273b8480f5d6d64dd6 $")
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{
104 fr_bfd_ctx_t *test_ctx;
105
106 test_ctx = talloc_zero(ctx, fr_bfd_ctx_t);
107 test_ctx->secret = talloc_strdup(test_ctx, "testing123");
108 test_ctx->tmp_ctx = talloc_zero(test_ctx, uint8_t);
109
110 *out = test_ctx;
111
112 return 0;
113}
114
116 uint8_t const *data, size_t data_len, void *proto_ctx)
117{
118 fr_pair_t *vp;
119 bfd_packet_t const *packet;
120 fr_bfd_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_bfd_ctx_t);
121
122 if (data_len < FR_BFD_HEADER_LENGTH) {
123 fr_strerror_const("Packet is too small for BFD");
124 return -1;
125 }
126
127 packet = (bfd_packet_t const *) data;
128
129 if (packet->length > data_len) {
130 fr_strerror_const("Packet.length is larger than received data");
131 return -1;
132 }
133
134 if (packet->length < FR_BFD_HEADER_LENGTH) {
135 fr_strerror_const("Packet.length is smaller then BFD header size");
136 return -1;
137 }
138
139 if (packet->version != 1) {
140 fr_strerror_const("Packet.version has invalid value");
141 return -1;
142 }
143
144 if (packet->detect_multi == 0) {
145 fr_strerror_const("Packet.detect-multi has invalid value zero");
146 return -1;
147 }
148
149 if (packet->detect_multi == 0) {
150 fr_strerror_const("Packet.detect-multi has invalid value zero");
151 return -1;
152 }
153
154 if (packet->multipoint != 0) {
155 fr_strerror_const("Packet.multipoint has invalid non-zero value");
156 return -1;
157 }
158
159 if (packet->my_disc == 0) {
160 fr_strerror_const("Packet.my-discriminator has invalid value zero");
161 return -1;
162 }
163
164 if ((packet->your_disc == 0) &&
165 !((packet->state == BFD_STATE_DOWN) ||
166 (packet->state == BFD_STATE_ADMIN_DOWN))) {
167 fr_strerror_const("Packet has invalid values for your-discriminator and state");
168 return 0;
169 }
170
171 /*
172 * Get the packet type.
173 */
175 if (!vp) {
176 fr_strerror_const("Failed creating Packet-Type");
177 return -1;
178 }
179
180 vp->vp_uint32 = packet->state;
182
183#if 0
184 /*
185 * We always decode the packet as a nested VP.
186 */
188 if (!vp) {
189 fr_strerror_const("Failed creating Packet");
190 return -1;
191 }
193#endif
194
195 /* coverity[tainted_data] */
196 return fr_bfd_decode(ctx, out, data, data_len,
197 test_ctx->secret, talloc_array_length(test_ctx->secret) - 1);
198}
199
200/*
201 * Test points
202 */
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:483
#define UNUSED
Definition build.h:315
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
Definition dbuff.h:354
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:514
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:2400
#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:1345
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:283
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)
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:115
fr_test_point_proto_decode_t bfd_tp_decode_proto
Definition decode.c:204
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:33
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:67
Entry point for protocol decoders.
Definition test_point.h:66
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:851
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
Definition proto.h:41
#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:1754
static fr_slen_t data
Definition value.h:1265
static size_t char ** out
Definition value.h:997