The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
packet.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: 383f8840e72a22f8532ba01878e7498b1b2d3618 $
19 *
20 * @file protocols/radius/packet.c
21 * @brief Functions to deal with fr_packet_t data structures.
22 *
23 * @copyright 2000-2017 The FreeRADIUS server project
24 */
25RCSID("$Id: 383f8840e72a22f8532ba01878e7498b1b2d3618 $")
26
27#include "attrs.h"
28
29#include <freeradius-devel/util/udp.h>
30#include <freeradius-devel/util/syserror.h>
31
32#include <fcntl.h>
33
34/*
35 * Some messages get printed out only in debugging mode.
36 */
37#define FR_DEBUG_STRERROR_PRINTF if (fr_debug_lvl) fr_strerror_printf
38
39
40/** Encode a packet
41 *
42 */
44 fr_packet_t const *original, char const *secret)
45{
46 ssize_t slen;
47 fr_radius_ctx_t common = {};
48 fr_radius_encode_ctx_t packet_ctx;
49
50 /*
51 * A 4K packet, aligned on 64-bits.
52 */
54
55#ifndef NDEBUG
57#endif
58
59 common.secret = secret;
60 common.secret_length = talloc_array_length(secret) - 1;
61
62 packet_ctx = (fr_radius_encode_ctx_t) {
63 .common = &common,
64 .request_authenticator = original ? original->data + 4 : NULL,
65 .rand_ctx = (fr_fast_rand_t) {
66 .a = fr_rand(),
67 .b = fr_rand(),
68 },
69 .request_code = original ? original->data[0] : 0,
70 .code = packet->code,
71 .id = packet->id,
72 };
73
74 slen = fr_radius_encode(&FR_DBUFF_TMP(data, sizeof(data)), list, &packet_ctx);
75 if (slen < 0) return slen;
76
77 /*
78 * Fill in the rest of the fields, and copy the data over
79 * from the local stack to the newly allocated memory.
80 *
81 * Yes, all this 'memcpy' is slow, but it means
82 * that we only allocate the minimum amount of
83 * memory for a request.
84 */
85 packet->data_len = (size_t) slen;
86 packet->data = talloc_array(packet, uint8_t, packet->data_len);
87 if (!packet->data) {
88 fr_strerror_const("Out of memory");
89 return -1;
90 }
91
92 memcpy(packet->data, data, packet->data_len);
93
94 return 0;
95}
96
97/** See if the data pointed to by PTR is a valid RADIUS packet.
98 *
99 * Packet is not 'const * const' because we may update data_len, if there's more data
100 * in the UDP packet than in the RADIUS packet.
101 *
102 * @param[in] packet to check.
103 * @param[in] max_attributes to decode.
104 * @param[in] require_message_authenticator to require Message-Authenticator.
105 * @param[out] reason if not NULL, will have the failure reason written to where it points.
106 * @return
107 * - True on success.
108 * - False on failure.
109 */
110bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason)
111{
112 if (!fr_radius_ok(packet->data, &packet->data_len, max_attributes, require_message_authenticator, reason)) {
113 return false;
114 }
115
116 /*
117 * Fill RADIUS header fields
118 */
119 packet->code = packet->data[0];
120 packet->id = packet->data[1];
121 memcpy(packet->vector, packet->data + 4, sizeof(packet->vector));
122 return true;
123}
124
125
126/** Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet
127 *
128 */
129int fr_packet_verify(fr_packet_t *packet, fr_packet_t *original, char const *secret)
130{
131 char buffer[INET6_ADDRSTRLEN];
132
133 if (!packet->data) return -1;
134
135 if (fr_radius_verify(packet->data, original ? original->data + 4 : NULL,
136 (uint8_t const *) secret, talloc_array_length(secret) - 1, false, false) < 0) {
137 fr_strerror_printf_push("Received invalid packet from %s",
138 inet_ntop(packet->socket.inet.src_ipaddr.af, &packet->socket.inet.src_ipaddr.addr,
139 buffer, sizeof(buffer)));
140 return -1;
141 }
142
143 return 0;
144}
145
146
147/** Sign a previously encoded packet
148 *
149 */
150int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original,
151 char const *secret)
152{
153 int ret;
154
155 ret = fr_radius_sign(packet->data, original ? original->data + 4 : NULL,
156 (uint8_t const *) secret, talloc_array_length(secret) - 1);
157 if (ret < 0) return ret;
158
159 memcpy(packet->vector, packet->data + 4, RADIUS_AUTH_VECTOR_LENGTH);
160 return 0;
161}
162
163
164/** Wrapper for recvfrom, which handles recvfromto, IPv6, and all possible combinations
165 *
166 */
167static ssize_t rad_recvfrom(int sockfd, fr_packet_t *packet, int flags)
168{
169 ssize_t data_len;
170
171 data_len = fr_radius_recv_header(sockfd, &packet->socket.inet.src_ipaddr, &packet->socket.inet.src_port, &packet->code);
172 if (data_len < 0) {
173 if ((errno == EAGAIN) || (errno == EINTR)) return 0;
174 return -1;
175 }
176
177 if (data_len == 0) return -1; /* invalid packet */
178
179 packet->data = talloc_array(packet, uint8_t, data_len);
180 if (!packet->data) return -1;
181
182 packet->data_len = data_len;
183
184 return udp_recv(sockfd, flags, &packet->socket, packet->data, packet->data_len, &packet->timestamp);
185}
186
187
188/** Receive UDP client requests, and fill in the basics of a fr_packet_t structure
189 *
190 */
191fr_packet_t *fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator)
192{
193 ssize_t data_len;
194 fr_packet_t *packet;
195
196 /*
197 * Allocate the new request data structure
198 */
199 packet = fr_packet_alloc(ctx, false);
200 if (!packet) {
201 fr_strerror_const("out of memory");
202 return NULL;
203 }
204
205 data_len = rad_recvfrom(fd, packet, flags);
206 if (data_len < 0) {
207 FR_DEBUG_STRERROR_PRINTF("Error receiving packet: %s", fr_syserror(errno));
208 fr_packet_free(&packet);
209 return NULL;
210 }
211
212#ifdef WITH_VERIFY_PTR
213 /*
214 * Double-check that the fields we want are filled in.
215 */
216 if ((packet->socket.inet.src_ipaddr.af == AF_UNSPEC) ||
217 (packet->socket.inet.src_port == 0) ||
218 (packet->socket.inet.dst_ipaddr.af == AF_UNSPEC) ||
219 (packet->socket.inet.dst_port == 0)) {
220 FR_DEBUG_STRERROR_PRINTF("Error receiving packet: %s", fr_syserror(errno));
221 fr_packet_free(&packet);
222 return NULL;
223 }
224#endif
225
226 packet->data_len = data_len; /* unsigned vs signed */
227
228 /*
229 * If the packet is too big, then rad_recvfrom did NOT
230 * allocate memory. Instead, it just discarded the
231 * packet.
232 */
233 if (packet->data_len > MAX_PACKET_LEN) {
234 FR_DEBUG_STRERROR_PRINTF("Discarding packet: Larger than RFC limitation of 4096 bytes");
235 fr_packet_free(&packet);
236 return NULL;
237 }
238
239 /*
240 * Read no data. Continue.
241 * This check is AFTER the MAX_PACKET_LEN check above, because
242 * if the packet is larger than MAX_PACKET_LEN, we also have
243 * packet->data == NULL
244 */
245 if ((packet->data_len == 0) || !packet->data) {
246 FR_DEBUG_STRERROR_PRINTF("Empty packet: Socket is not ready");
247 fr_packet_free(&packet);
248 return NULL;
249 }
250
251 /*
252 * See if it's a well-formed RADIUS packet.
253 */
254 if (!fr_packet_ok(packet, max_attributes, require_message_authenticator, NULL)) {
255 fr_packet_free(&packet);
256 return NULL;
257 }
258
259 /*
260 * Remember which socket we read the packet from.
261 */
262 packet->socket.fd = fd;
263
264 /*
265 * FIXME: Do even more filtering by only permitting
266 * certain IP's. The problem is that we don't know
267 * how to do this properly for all possible clients...
268 */
269
270 return packet;
271}
272
273/** Reply to the request
274 *
275 * Also attach reply attribute value pairs and any user message provided.
276 */
278 fr_packet_t const *original, char const *secret)
279{
280 /*
281 * Maybe it's a fake packet. Don't send it.
282 */
283 if (packet->socket.fd < 0) {
284 return 0;
285 }
286
287 /*
288 * First time through, allocate room for the packet
289 */
290 if (!packet->data) {
291 /*
292 * Encode the packet.
293 */
294 if (fr_packet_encode(packet, list, original, secret) < 0) {
295 return -1;
296 }
297
298 /*
299 * Re-sign it, including updating the
300 * Message-Authenticator.
301 */
302 if (fr_packet_sign(packet, original, secret) < 0) {
303 return -1;
304 }
305
306 /*
307 * If packet->data points to data, then we print out
308 * the VP list again only for debugging.
309 */
310 }
311
312 /*
313 * If the socket is TCP, call write(). Calling sendto()
314 * is allowed on some platforms, but it's not nice.
315 */
316 if (packet->socket.type == SOCK_STREAM) {
317 ssize_t ret;
318
319 ret = write(packet->socket.fd, packet->data, packet->data_len);
320 if (ret >= 0) return ret;
321
322 fr_strerror_printf("sendto failed: %s", fr_syserror(errno));
323 return -1;
324 }
325
326 /*
327 * And send it on it's way.
328 *
329 * No need to call fr_socket_addr_swap as apparently
330 * the address is already inverted.
331 */
332 return udp_send(&packet->socket, 0, packet->data, packet->data_len);
333}
334
335void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line)
336{
337 uint8_t const *attr, *end;
338 char buffer[1024];
339
340 if (!packet->data) return;
341
342 fr_log(log, L_DBG, file, line, " Socket : %d", packet->socket.fd);
343 fr_log(log, L_DBG, file, line, " Proto : %d", (packet->socket.type == SOCK_STREAM) ? IPPROTO_TCP : IPPROTO_UDP);
344
345 if ((packet->socket.inet.src_ipaddr.af == AF_INET) || (packet->socket.inet.src_ipaddr.af == AF_INET6)) {
346 fr_log(log, L_DBG, file, line, " Src IP : %pV", fr_box_ipaddr(packet->socket.inet.src_ipaddr));
347 fr_log(log, L_DBG, file, line, " Src Port : %u", packet->socket.inet.src_port);
348 fr_log(log, L_DBG, file, line, " Dst IP : %pV", fr_box_ipaddr(packet->socket.inet.dst_ipaddr));
349 fr_log(log, L_DBG, file, line, " Dst Port : %u", packet->socket.inet.dst_port);
350 }
351
352 if ((packet->data[0] > 0) && (packet->data[0] < FR_RADIUS_CODE_MAX)) {
353 fr_log(log, L_DBG, file, line, " Code : %s", fr_radius_packet_name[packet->data[0]]);
354 } else {
355 fr_log(log, L_DBG, file, line, " Code : %u", packet->data[0]);
356 }
357
358 fr_log(log, L_DBG, file, line, " Id : %u", packet->data[1]);
359 fr_log(log, L_DBG, file, line, " Length : %u", fr_nbo_to_uint16(packet->data + 2));
360 fr_log(log, L_DBG, file, line, " Vector : %pH", fr_box_octets(packet->data + 4, RADIUS_AUTH_VECTOR_LENGTH));
361
362 if (packet->data_len <= 20) return;
363
364 for (attr = packet->data + 20, end = packet->data + packet->data_len;
365 attr < end;
366 attr += attr[1]) {
367 int i, len, offset = 2;
368 unsigned int vendor = 0;
369 char *p;
370 char const *truncated = "";
371
372#ifndef NDEBUG
373 if (attr[1] < 2) break; /* Coverity */
374#endif
375
376 snprintf(buffer, sizeof(buffer), "%02x %02x ", attr[0], attr[1]);
377 p = buffer + strlen(buffer);
378 if ((attr[0] == FR_VENDOR_SPECIFIC) &&
379 (attr[1] > 6)) {
380 vendor = fr_nbo_to_uint32(attr + 2);
381
382 snprintf(p, buffer + sizeof(buffer) - p, "%02x%02x%02x%02x (%u) ",
383 attr[2], attr[3], attr[4], attr[5], vendor);
384 offset = 6;
385 p += strlen(p);
386 }
387
388 len = attr[1] - offset;
389 if (len > 15) {
390 len = 15;
391 truncated = "...";
392 }
393
394 for (i = 0; i < len; i++) {
395 snprintf(p, buffer + sizeof(buffer) - p, "%02x ", attr[offset + i]);
396 p += 3;
397 }
398
399 fr_log(log, L_DBG, file, line, " %s%s\n", buffer, truncated);
400 }
401}
402
403/*
404 * Debug the packet if requested.
405 */
406void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received)
407{
408 char src_ipaddr[FR_IPADDR_STRLEN];
409 char dst_ipaddr[FR_IPADDR_STRLEN];
410#ifdef WITH_IFINDEX_NAME_RESOLUTION
411 char if_name[IFNAMSIZ];
412#endif
413
414 if (!log) return;
415 if (!packet) return;
416
417 /*
418 * Client-specific debugging re-prints the input
419 * packet into the client log.
420 *
421 * This really belongs in a utility library
422 */
423 if (FR_RADIUS_PACKET_CODE_VALID(packet->code)) {
424 fr_log(log, L_DBG, __FILE__, __LINE__,
425 "%s %s Id %i from %s%s%s:%i to %s%s%s:%i "
426#ifdef WITH_IFINDEX_NAME_RESOLUTION
427 "%s%s%s"
428#endif
429 "length %zu\n",
430 received ? "Received" : "Sent",
432 packet->id,
433 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
434 fr_inet_ntop(src_ipaddr, sizeof(src_ipaddr), &packet->socket.inet.src_ipaddr),
435 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
436 packet->socket.inet.src_port,
437 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
438 fr_inet_ntop(dst_ipaddr, sizeof(dst_ipaddr), &packet->socket.inet.dst_ipaddr),
439 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
440 packet->socket.inet.dst_port,
441#ifdef WITH_IFINDEX_NAME_RESOLUTION
442 received ? "via " : "",
443 received ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
444 received ? " " : "",
445#endif
446 packet->data_len);
447 } else {
448 fr_log(log, L_DBG, __FILE__, __LINE__,
449 "%s code %u Id %i from %s%s%s:%i to %s%s%s:%i "
450#ifdef WITH_IFINDEX_NAME_RESOLUTION
451 "%s%s%s"
452#endif
453 "length %zu\n",
454 received ? "Received" : "Sent",
455 packet->code,
456 packet->id,
457 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "[" : "",
458 fr_inet_ntop(src_ipaddr, sizeof(src_ipaddr), &packet->socket.inet.src_ipaddr),
459 packet->socket.inet.src_ipaddr.af == AF_INET6 ? "]" : "",
460 packet->socket.inet.src_port,
461 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "[" : "",
462 fr_inet_ntop(dst_ipaddr, sizeof(dst_ipaddr), &packet->socket.inet.dst_ipaddr),
463 packet->socket.inet.dst_ipaddr.af == AF_INET6 ? "]" : "",
464 packet->socket.inet.dst_port,
465#ifdef WITH_IFINDEX_NAME_RESOLUTION
466 received ? "via " : "",
467 received ? fr_ifname_from_ifindex(if_name, packet->socket.inet.ifindex) : "",
468 received ? " " : "",
469#endif
470 packet->data_len);
471 }
472}
473
474/*
475 * Debug the packet header and all attributes. This function is only called by the client code.
476 */
477void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received)
478{
479 fr_radius_packet_header_log(log, packet, received);
480
481 if (!fr_debug_lvl) return;
482
483 /*
484 * If we're auto-adding Message Authenticator, then print
485 * out that we're auto-adding it.
486 */
487 if (!received) switch (packet->code) {
491 fr_log(log, L_DBG, __FILE__, __LINE__, "\tMessage-Authenticator = 0x\n");
492 }
493 break;
494
495 default:
496 break;
497 }
498
499 fr_pair_list_log(log, 4, list);
500#ifndef NDEBUG
501 if (fr_debug_lvl >= L_DBG_LVL_4) fr_packet_log_hex(log, packet);
502#endif
503}
static int const char char buffer[256]
Definition acutest.h:578
int const char * file
Definition acutest.h:704
int const char int line
Definition acutest.h:704
#define RCSID(id)
Definition build.h:487
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:524
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
Definition defs.h:33
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
Definition defs.h:53
@ FR_RADIUS_CODE_STATUS_SERVER
RFC2865/RFC5997 - Status Server (request)
Definition defs.h:44
#define MAX_PACKET_LEN
Definition defs.h:68
static int sockfd
Definition dhcpclient.c:56
char * fr_inet_ntop(char out[static FR_IPADDR_STRLEN], size_t outlen, fr_ipaddr_t const *addr)
Print the address portion of a fr_ipaddr_t.
Definition inet.c:1022
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
Definition inet.h:89
int fr_debug_lvl
Definition log.c:40
fr_log_t default_log
Definition log.c:288
void fr_log(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination.
Definition log.c:577
@ L_DBG_LVL_4
4th highest priority debug messages (-xxxx | -Xxx).
Definition log.h:73
@ L_DBG
Only displayed when debugging is enabled.
Definition log.h:59
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
Definition packet.c:38
void fr_packet_free(fr_packet_t **packet_p)
Free a fr_packet_t.
Definition packet.c:89
ssize_t udp_recv(int sockfd, int flags, fr_socket_t *socket_out, void *data, size_t data_len, fr_time_t *when)
Read a UDP packet.
Definition udp.c:144
int udp_send(fr_socket_t const *sock, int flags, void *data, size_t data_len)
Send a packet via a UDP socket.
Definition udp.c:42
bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_message_authenticator, decode_fail_t *reason)
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
unsigned long int size_t
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
Definition missing.c:443
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
Definition nbo.h:146
static uint32_t fr_nbo_to_uint32(uint8_t const data[static sizeof(uint32_t)])
Read an unsigned 32bit integer from wire format (big endian)
Definition nbo.h:167
#define RADIUS_AUTH_VECTOR_LENGTH
Definition net.h:89
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:704
int fr_radius_sign(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len)
Sign a previously encoded packet.
Definition base.c:362
int fr_radius_verify(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len, bool require_message_authenticator, bool limit_proxy_state)
Verify a request / response packet.
Definition base.c:800
ssize_t fr_radius_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encode_ctx_t *packet_ctx)
Definition base.c:954
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
Definition base.c:116
ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code)
Basic validation of RADIUS packet header.
Definition base.c:289
int fr_packet_verify(fr_packet_t *packet, fr_packet_t *original, char const *secret)
Verify the Request/Response Authenticator (and Message-Authenticator if present) of a packet.
Definition packet.c:129
static ssize_t rad_recvfrom(int sockfd, fr_packet_t *packet, int flags)
Wrapper for recvfrom, which handles recvfromto, IPv6, and all possible combinations.
Definition packet.c:167
int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret)
Sign a previously encoded packet.
Definition packet.c:150
bool fr_packet_ok(fr_packet_t *packet, uint32_t max_attributes, bool require_message_authenticator, fr_radius_decode_fail_t *reason)
See if the data pointed to by PTR is a valid RADIUS packet.
Definition packet.c:110
void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received)
Definition packet.c:406
void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line)
Definition packet.c:335
ssize_t fr_packet_encode(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret)
Encode a packet.
Definition packet.c:43
#define FR_DEBUG_STRERROR_PRINTF
Definition packet.c:37
fr_packet_t * fr_packet_recv(TALLOC_CTX *ctx, int fd, int flags, uint32_t max_attributes, bool require_message_authenticator)
Receive UDP client requests, and fill in the basics of a fr_packet_t structure.
Definition packet.c:191
int fr_packet_send(fr_packet_t *packet, fr_pair_list_t *list, fr_packet_t const *original, char const *secret)
Reply to the request.
Definition packet.c:277
void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received)
Definition packet.c:477
static char * secret
fr_radius_ctx_t const * common
Definition radius.h:136
fr_radius_decode_fail_t
Failure reasons.
Definition radius.h:90
char const * secret
Definition radius.h:127
#define fr_packet_log_hex(_log, _packet)
Definition radius.h:285
size_t secret_length
Definition radius.h:128
#define FR_RADIUS_PACKET_CODE_VALID(_x)
Definition radius.h:52
static fr_dict_attr_t const * attr_message_authenticator
Definition radsnmp.c:114
uint32_t fr_rand(void)
Return a 32-bit random number.
Definition rand.c:105
Smaller fast random number generator.
Definition rand.h:54
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
Definition log.h:96
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
unsigned int code
Packet code (type).
Definition packet.h:61
fr_socket_t socket
This packet was received on.
Definition packet.h:57
int id
Packet ID (used to link requests/responses).
Definition packet.h:60
uint8_t * data
Packet data (body).
Definition packet.h:63
size_t data_len
Length of packet data.
Definition packet.h:64
uint8_t vector[RADIUS_AUTH_VECTOR_LENGTH]
RADIUS authentication vector.
Definition packet.h:69
fr_time_t timestamp
When we received the packet.
Definition packet.h:58
#define fr_pair_list_log(_log, _lvl, _list)
Definition pair.h:865
int af
AF_INET, AF_INET6, or AF_UNIX.
Definition socket.h:78
int fd
File descriptor if this is a live socket.
Definition socket.h:81
int type
SOCK_STREAM, SOCK_DGRAM, etc.
Definition socket.h:79
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
Definition strerror.h:84
#define fr_strerror_const(_msg)
Definition strerror.h:223
#define fr_box_ipaddr(_val)
Definition value.h:317
static fr_slen_t data
Definition value.h:1334
#define fr_box_octets(_val, _len)
Definition value.h:311