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