25RCSID(
"$Id: ca50d4546c8e9efff6fb2f73a2ffbf005e9b20e7 $")
29#include <freeradius-devel/util/udp.h>
30#include <freeradius-devel/util/syserror.h>
37#define FR_DEBUG_STRERROR_PRINTF if (fr_debug_lvl) fr_strerror_printf
64 .request_authenticator = original ? original->
data + 4 : NULL,
69 .request_code = original ? original->
data[0] : 0,
75 if (slen < 0)
return slen;
112 char host_ipaddr[INET6_ADDRSTRLEN];
117 host_ipaddr,
sizeof(host_ipaddr)));
125 packet->
id = packet->
data[1];
136 char buffer[INET6_ADDRSTRLEN];
138 if (!packet->
data)
return -1;
162 if (ret < 0)
return ret;
178 if ((errno == EAGAIN) || (errno == EINTR))
return 0;
182 if (data_len == 0)
return -1;
184 packet->
data = talloc_array(packet,
uint8_t, data_len);
185 if (!packet->
data)
return -1;
217#ifdef WITH_VERIFY_PTR
221 if ((packet->
socket.inet.src_ipaddr.
af == AF_UNSPEC) ||
222 (packet->
socket.inet.src_port == 0) ||
223 (packet->
socket.inet.dst_ipaddr.
af == AF_UNSPEC) ||
224 (packet->
socket.inet.dst_port == 0)) {
259 if (!
fr_packet_ok(packet, max_attributes, require_message_authenticator, NULL)) {
325 if (ret >= 0)
return ret;
345 if (!packet->
data)
return;
350 if ((packet->
socket.inet.src_ipaddr.
af == AF_INET) || (packet->
socket.inet.src_ipaddr.
af == AF_INET6)) {
372 int i, len, offset = 2;
373 unsigned int vendor = 0;
375 char const *truncated =
"";
378 if (attr[1] < 2)
break;
383 if ((attr[0] == FR_VENDOR_SPECIFIC) &&
388 attr[2], attr[3], attr[4], attr[5], vendor);
393 len = attr[1] - offset;
399 for (i = 0; i < len; i++) {
415#ifdef WITH_IFINDEX_NAME_RESOLUTION
416 char if_name[IFNAMSIZ];
430 "%s %s Id %i from %s%s%s:%i to %s%s%s:%i "
431#ifdef WITH_IFINDEX_NAME_RESOLUTION
435 received ?
"Received" :
"Sent",
438 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"[" :
"",
440 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"]" :
"",
441 packet->
socket.inet.src_port,
442 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"[" :
"",
444 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"]" :
"",
445 packet->
socket.inet.dst_port,
446#ifdef WITH_IFINDEX_NAME_RESOLUTION
447 received ?
"via " :
"",
448 received ? fr_ifname_from_ifindex(if_name, packet->
socket.inet.ifindex) :
"",
454 "%s code %u Id %i from %s%s%s:%i to %s%s%s:%i "
455#ifdef WITH_IFINDEX_NAME_RESOLUTION
459 received ?
"Received" :
"Sent",
462 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"[" :
"",
464 packet->
socket.inet.src_ipaddr.
af == AF_INET6 ?
"]" :
"",
465 packet->
socket.inet.src_port,
466 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"[" :
"",
468 packet->
socket.inet.dst_ipaddr.
af == AF_INET6 ?
"]" :
"",
469 packet->
socket.inet.dst_port,
470#ifdef WITH_IFINDEX_NAME_RESOLUTION
471 received ?
"via " :
"",
472 received ? fr_ifname_from_ifindex(if_name, packet->
socket.inet.ifindex) :
"",
492 if (!received)
switch (packet->
code) {
496 fprintf(
fr_log_fp,
"\tMessage-Authenticator = 0x\n");
static int const char char buffer[256]
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
@ FR_RADIUS_CODE_STATUS_SERVER
RFC2865/RFC5997 - Status Server (request)
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.
#define FR_IPADDR_STRLEN
Like INET6_ADDRSTRLEN but includes space for the textual Zone ID.
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.
@ L_DBG_LVL_4
4th highest priority debug messages (-xxxx | -Xxx).
@ L_DBG
Only displayed when debugging is enabled.
fr_packet_t * fr_packet_alloc(TALLOC_CTX *ctx, bool new_vector)
Allocate a new fr_packet_t.
void fr_packet_free(fr_packet_t **packet_p)
Free a fr_packet_t.
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.
int udp_send(fr_socket_t const *sock, int flags, void *data, size_t data_len)
Send a packet via a UDP socket.
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)
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
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)
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)
#define RADIUS_AUTH_VECTOR_LENGTH
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.
int fr_radius_sign(uint8_t *packet, uint8_t const *vector, uint8_t const *secret, size_t secret_len)
Sign a previously encoded packet.
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.
ssize_t fr_radius_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encode_ctx_t *packet_ctx)
char const * fr_radius_packet_name[FR_RADIUS_CODE_MAX]
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.
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.
static ssize_t rad_recvfrom(int sockfd, fr_packet_t *packet, int flags)
Wrapper for recvfrom, which handles recvfromto, IPv6, and all possible combinations.
int fr_packet_sign(fr_packet_t *packet, fr_packet_t const *original, char const *secret)
Sign a previously encoded packet.
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.
void fr_radius_packet_header_log(fr_log_t const *log, fr_packet_t *packet, bool received)
void _fr_packet_log_hex(fr_log_t const *log, fr_packet_t const *packet, char const *file, int line)
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.
#define FR_DEBUG_STRERROR_PRINTF
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.
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.
void fr_radius_packet_log(fr_log_t const *log, fr_packet_t *packet, fr_pair_list_t *list, bool received)
fr_radius_ctx_t const * common
fr_radius_decode_fail_t
Failure reasons.
#define fr_packet_log_hex(_log, _packet)
#define FR_RADIUS_PACKET_CODE_VALID(_x)
static fr_dict_attr_t const * attr_message_authenticator
uint32_t fr_rand(void)
Return a 32-bit random number.
Smaller fast random number generator.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
unsigned int code
Packet code (type).
fr_socket_t socket
This packet was received on.
int id
Packet ID (used to link requests/responses).
uint8_t * data
Packet data (body).
size_t data_len
Length of packet data.
uint8_t vector[RADIUS_AUTH_VECTOR_LENGTH]
RADIUS authentication vector.
fr_time_t timestamp
When we received the packet.
#define fr_pair_list_log(_log, _lvl, _list)
int af
AF_INET, AF_INET6, or AF_UNIX.
int fd
File descriptor if this is a live socket.
int type
SOCK_STREAM, SOCK_DGRAM, etc.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
#define fr_strerror_const(_msg)
#define fr_box_ipaddr(_val)
#define fr_box_octets(_val, _len)