The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
base.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: 75daba373437b0ce1565c8aab7cd95d89d6f830b $
19 *
20 * @file protocols/bfd/base.c
21 * @brief Functions to send/receive BFD packets.
22 *
23 * @copyright 2023 Network RADIUS SAS (legal@networkradius.com)
24 */
25
26RCSID("$Id: 75daba373437b0ce1565c8aab7cd95d89d6f830b $")
27
28#include <fcntl.h>
29#include <ctype.h>
30
31#include "attrs.h"
32
33#include <freeradius-devel/io/pair.h>
34#include <freeradius-devel/util/net.h>
35#include <freeradius-devel/util/proto.h>
36#include <freeradius-devel/util/udp.h>
37
39
42
45 { .out = &dict_freeradius, .proto = "freeradius" },
46 { .out = &dict_bfd, .proto = "bfd" },
47 { NULL }
48};
49
53
56 { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_bfd },
57 { .out = &attr_bfd_packet, .name = "Packet", .type = FR_TYPE_STRUCT, .dict = &dict_bfd },
58 { .out = &attr_bfd_additional_data, .name = "Additional-Data", .type = FR_TYPE_GROUP, .dict = &dict_bfd },
59
60 { NULL }
61};
62
64 "Admin-Down",
65 "Down",
66 "Init",
67 "Up",
68};
69
71 { L("none"), BFD_AUTH_RESERVED },
72 { L("simple"), BFD_AUTH_SIMPLE },
73 { L("keyed-md5"), BFD_AUTH_KEYED_MD5 },
74 { L("met-keyed-md5"), BFD_AUTH_MET_KEYED_MD5 },
75 { L("keyed-sha1"), BFD_AUTH_KEYED_SHA1 },
76 { L("met-keyed-sha1"), BFD_AUTH_MET_KEYED_SHA1 },
77};
79
80/*
81 * Perform basic packet checks as per the first part of RFC 5880 Section 6.8.6.
82 */
83bool fr_bfd_packet_ok(char const **err, uint8_t const *packet, size_t packet_len)
84{
85 bfd_packet_t const *bfd;
86 char const *msg = NULL;
87
88 if (packet_len < FR_BFD_HEADER_LENGTH) {
89 msg = "Packet is too short to be BFD";
90 fail:
91 if (err) *err = msg;
92 return false;
93 }
94
95 bfd = (bfd_packet_t const *) packet;
96
97 /*
98 * If the version number is not correct (1), the packet MUST be
99 * discarded.
100 */
101 if (bfd->version != 1) {
102 msg = "Packet has wrong version - should be 1";
103 goto fail;
104 }
105
106 /*
107 * If the Length field is less than the minimum correct value (24 if
108 * the A bit is clear, or 26 if the A bit is set), the packet MUST be
109 * discarded.
110 */
111 if (bfd->length < FR_BFD_HEADER_LENGTH) {
112 msg = "Header length is too small";
113 goto fail;
114 }
115
116 /*
117 * If the Length field is greater than the payload of the
118 * encapsulating protocol, the packet MUST be discarded.
119 *
120 * Addendum: if the Length field is smaller than the
121 * received data, that's bad, too.
122 */
123 if (bfd->length > packet_len) {
124 msg = "Header length is not the same as the amount of data we read";
125 goto fail;
126 }
127
128 /*
129 * If the Length field is less than the minimum correct value (24 if
130 * the A bit is clear, or 26 if the A bit is set), the packet MUST be
131 * discarded.
132 *
133 * Addendum: if the Length field is not equal to 24 plus Auth-Len field,
134 * then the packet is discarded.
135 */
136 if (bfd->auth_present) {
137 if (bfd->length < (FR_BFD_HEADER_LENGTH + 2)) { /* auth-type and auth-len */
138 msg = "Header length is not enough for auth-type and auth-len";
139 goto fail;
140 }
141
142 if (bfd->length != FR_BFD_HEADER_LENGTH + bfd->auth.basic.auth_len) {
143 msg = "Header length mismatch with auth-len and amount of received data";
144 goto fail;
145
146 }
147
148 switch (bfd->auth.basic.auth_type) {
149 case BFD_AUTH_SIMPLE:
150 if ((bfd->auth.basic.auth_len < (3 + 1)) || (bfd->auth.basic.auth_len > (3 + 16))) {
151 msg = "Auth-Type Simple has invalid value for password length";
152 goto fail;
153 }
154 break;
155
158 if (bfd->auth.basic.auth_len != 24) {
159 msg = "Auth-Type MD5 has invalid value for digest length";
160 goto fail;
161 }
162 break;
163
166 if (bfd->auth.basic.auth_len != 28) {
167 msg = "Auth-Type SHA1 has invalid value for digest length";
168 goto fail;
169 }
170 break;
171
172 default:
173 msg = "Invalid Auth-Type";
174 goto fail;
175 }
176 }
177
178 /*
179 * If the Detect Mult field is zero, the packet MUST be discarded.
180 */
181 if (bfd->detect_multi == 0) {
182 msg = "Packet has invalid detect-multi == 0";
183 goto fail;
184 }
185
186 /*
187 * If the Multipoint (M) bit is nonzero, the packet MUST be
188 * discarded.
189 */
190 if (bfd->multipoint != 0) {
191 msg = "Packet has invalid multipoint != 0";
192 goto fail;
193 }
194
195 /*
196 * If the My Discriminator field is zero, the packet MUST be
197 * discarded.
198 */
199 if (bfd->my_disc == 0) {
200 msg = "Packet has invalid my-discriminator == 0";
201 goto fail;
202 }
203
204 /*
205 * If the Your Discriminator field is zero and the State field is not
206 * Down or AdminDown, the packet MUST be discarded.
207 */
208 if ((bfd->your_disc == 0) &&
209 !((bfd->state == BFD_STATE_DOWN) ||
210 (bfd->state == BFD_STATE_ADMIN_DOWN))) {
211 msg = "Packet has your-discrimator==0, but state is not down or admin-down";
212 goto fail;
213 }
214
215 if (err) *err = NULL;
216 return true;
217}
218
219
220
222{
223 if (instance_count > 0) {
225 return 0;
226 }
227
229
231 fail:
233 return -1;
234 }
235
238 goto fail;
239 }
240
241 return 0;
242}
243
245{
247
248 if (--instance_count > 0) return;
249
251}
252
255 .name = "bfd",
256 .default_type_size = 1,
257 .default_type_length = 1,
258
259 .init = fr_bfd_global_init,
260 .free = fr_bfd_global_free,
261};
log_entry msg
Definition acutest.h:794
@ BFD_AUTH_MET_KEYED_MD5
Definition bfd.h:56
@ BFD_AUTH_MET_KEYED_SHA1
Definition bfd.h:58
@ BFD_AUTH_SIMPLE
Definition bfd.h:54
@ BFD_AUTH_KEYED_SHA1
Definition bfd.h:57
@ BFD_AUTH_KEYED_MD5
Definition bfd.h:55
@ BFD_AUTH_RESERVED
Definition bfd.h:53
#define FR_BFD_HEADER_LENGTH
Definition bfd.h:141
#define FR_BFD_CODE_MAX
Definition bfd.h:149
@ BFD_STATE_DOWN
Definition bfd.h:35
@ BFD_STATE_ADMIN_DOWN
Definition bfd.h:34
#define RCSID(id)
Definition build.h:483
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define NUM_ELEMENTS(_t)
Definition build.h:337
#define fr_dict_autofree(_to_free)
Definition dict.h:853
static fr_slen_t err
Definition dict.h:824
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:268
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
Definition dict_util.c:4090
#define fr_dict_autoload(_to_load)
Definition dict.h:850
char const * name
name of this protocol
Definition dict.h:430
Specifies an attribute which must be present for the module to function.
Definition dict.h:267
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
Protocol-specific callbacks in libfreeradius-PROTOCOL.
Definition dict.h:429
static fr_dict_t const * dict_freeradius
Definition base.c:37
fr_dict_attr_t const * attr_packet_type
Definition base.c:93
static uint32_t instance_count
Definition base.c:44
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_GROUP
A grouping of other attributes.
unsigned int uint32_t
unsigned char uint8_t
static fr_dict_attr_t const * attr_bfd_packet
Definition base.c:38
static fr_dict_t const * dict_bfd
Definition base.c:29
fr_dict_attr_autoload_t libfreeradius_bfd_dict_attr[]
Definition base.c:55
char const * fr_bfd_packet_names[FR_BFD_CODE_MAX]
Definition base.c:63
int fr_bfd_global_init(void)
Definition base.c:221
void fr_bfd_global_free(void)
Definition base.c:244
size_t const bfd_auth_type_table_len
Definition base.c:78
fr_dict_attr_t const * attr_bfd_additional_data
Definition base.c:52
fr_dict_protocol_t libfreeradius_bfd_dict_protocol
Definition base.c:254
fr_table_num_ordered_t const bfd_auth_type_table[]
Definition base.c:70
bool fr_bfd_packet_ok(char const **err, uint8_t const *packet, size_t packet_len)
Definition base.c:83
fr_dict_autoload_t libfreeradius_bfd_dict[]
Definition base.c:44
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:38
An element in an arbitrarily ordered array of name to num mappings.
Definition table.h:57