/*
* Some messages get printed out only in debugging mode.
*/
-#define FR_STRERROR_PRINTF if (fr_debug_lvl) fr_strerror_printf
+#define FR_DEBUG_STRERROR_PRINTF if (fr_debug_lvl) fr_strerror_printf
#if 0
#define VP_TRACE printf
(struct sockaddr *)&src, &sizeof_src);
}
-
+/** Basic validation of RADIUS packet header
+ *
+ * @note fr_strerror errors are only available if fr_debug_lvl > 0. This is to reduce CPU time
+ * consumed when discarding malformed packet.
+ *
+ * @param[in] sockfd we're reading from.
+ * @param[out] src_ipaddr of the packet.
+ * @param[out] src_port of the packet.
+ * @param[out] code Pointer to where to write the packet code.
+ * @return
+ * - -1 on failure.
+ * - 1 on decode error.
+ * - >= RADIUS_HDR_LEN on success. This is the packet length as specified in the header.
+ */
ssize_t rad_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, int *code)
{
ssize_t data_len, packet_len;
* Too little data is available, discard the packet.
*/
if (data_len < 4) {
- FR_STRERROR_PRINTF("Expected at least 4 bytes of header data, got %zu bytes", data_len);
+ FR_DEBUG_STRERROR_PRINTF("Expected at least 4 bytes of header data, got %zu bytes", data_len);
rad_recv_discard(sockfd);
return 1;
* a RADIUS header length: discard it.
*/
if (packet_len < RADIUS_HDR_LEN) {
- FR_STRERROR_PRINTF("Expected at least " STRINGIFY(RADIUS_HDR_LEN) " bytes of packet "
- "data, got %zu bytes", packet_len);
+ FR_DEBUG_STRERROR_PRINTF("Expected at least " STRINGIFY(RADIUS_HDR_LEN) " bytes of packet "
+ "data, got %zu bytes", packet_len);
rad_recv_discard(sockfd);
return 1;
* Anything after 4k will be discarded.
*/
} else if (packet_len > MAX_PACKET_LEN) {
- FR_STRERROR_PRINTF("Length field value too large, expected maximum of "
- STRINGIFY(MAX_PACKET_LEN) " bytes, got %zu bytes", packet_len);
+ FR_DEBUG_STRERROR_PRINTF("Length field value too large, expected maximum of "
+ STRINGIFY(MAX_PACKET_LEN) " bytes, got %zu bytes", packet_len);
rad_recv_discard(sockfd);
return 1;
* Convert AF. If unknown, discard packet.
*/
if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, src_port)) {
- FR_STRERROR_PRINTF("Unkown address family");
+ FR_DEBUG_STRERROR_PRINTF("Unkown address family");
rad_recv_discard(sockfd);
return 1;
* "The minimum length is 20 ..."
*/
if (packet->data_len < RADIUS_HDR_LEN) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: too short (received %zu < minimum %d)",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: too short (received %zu < minimum %d)",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
*/
if ((hdr->code == 0) ||
(hdr->code >= FR_MAX_PACKET_CODE)) {
- FR_STRERROR_PRINTF("Bad RADIUS packet from host %s: unknown packet code %d",
+ FR_DEBUG_STRERROR_PRINTF("Bad RADIUS packet from host %s: unknown packet code %d",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
* "The minimum length is 20 ..."
*/
if (totallen < RADIUS_HDR_LEN) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: too short (length %zu < minimum %d)",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: too short (length %zu < minimum %d)",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
* i.e. No response to the NAS.
*/
if (packet->data_len < totallen) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: received %zu octets, packet length says %zu",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: received %zu octets, packet length says %zu",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
* attribute header.
*/
if (count < 2) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: attribute header overflows the packet",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: attribute header overflows the packet",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)));
* Attribute number zero is NOT defined.
*/
if (attr[0] == 0) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: Invalid attribute 0",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: Invalid attribute 0",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)));
* fields. Anything shorter is an invalid attribute.
*/
if (attr[1] < 2) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: attribute %u too short",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: attribute %u too short",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
* attribute, it's a bad packet.
*/
if (count < attr[1]) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: attribute %u data overflows the packet",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: attribute %u data overflows the packet",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
case PW_MESSAGE_AUTHENTICATOR:
if (attr[1] != 2 + AUTH_VECTOR_LEN) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
* If not, we complain, and throw the packet away.
*/
if (count != 0) {
- FR_STRERROR_PRINTF("Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
+ FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)));
*/
if ((fr_max_attributes > 0) &&
(num_attributes > fr_max_attributes)) {
- FR_STRERROR_PRINTF("Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
+ FR_DEBUG_STRERROR_PRINTF("Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)),
* Message-Authenticator attributes.
*/
if (require_ma && !seen_ma) {
- FR_STRERROR_PRINTF("Insecure packet from host %s: Packet does not contain required Message-Authenticator attribute",
+ FR_DEBUG_STRERROR_PRINTF("Insecure packet from host %s: Packet does not contain required Message-Authenticator attribute",
inet_ntop(packet->src_ipaddr.af,
&packet->src_ipaddr.ipaddr,
host_ipaddr, sizeof(host_ipaddr)));
* Check for socket errors.
*/
if (data_len < 0) {
- FR_STRERROR_PRINTF("Error receiving packet: %s", fr_syserror(errno));
+ FR_DEBUG_STRERROR_PRINTF("Error receiving packet: %s", fr_syserror(errno));
/* packet->data is NULL */
rad_free(&packet);
return NULL;
* packet.
*/
if (packet->data_len > MAX_PACKET_LEN) {
- FR_STRERROR_PRINTF("Discarding packet: Larger than RFC limitation of 4096 bytes");
+ FR_DEBUG_STRERROR_PRINTF("Discarding packet: Larger than RFC limitation of 4096 bytes");
/* packet->data is NULL */
rad_free(&packet);
return NULL;
* packet->data == NULL
*/
if ((packet->data_len == 0) || !packet->data) {
- FR_STRERROR_PRINTF("Empty packet: Socket is not ready");
+ FR_DEBUG_STRERROR_PRINTF("Empty packet: Socket is not ready");
rad_free(&packet);
return NULL;
}