* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
+
+/* \summary: Radius protocol printer */
+
/*
* Radius printer routines as specified on:
*
* RFC 2869:
* "RADIUS Extensions"
*
+ * RFC 3162:
+ * "RADIUS and IPv6"
+ *
+ * RFC 3580:
+ * "IEEE 802.1X Remote Authentication Dial In User Service (RADIUS)"
+ * "Usage Guidelines"
+ *
+ * RFC 4072:
+ * "Diameter Extensible Authentication Protocol (EAP) Application"
+ *
* RFC 4675:
* "RADIUS Attributes for Virtual LAN and Priority Support"
*
+ * RFC 4818:
+ * "RADIUS Delegated-IPv6-Prefix Attribute"
+ *
+ * RFC 4849:
+ * "RADIUS Filter Rule Attribute"
+ *
+ * RFC 5090:
+ * "RADIUS Extension for Digest Authentication"
+ *
* RFC 5176:
* "Dynamic Authorization Extensions to RADIUS"
*
+ * RFC 5580:
+ * "Carrying Location Objects in RADIUS and Diameter"
+ *
+ * RFC 7155:
+ * "Diameter Network Access Server Application"
+ *
*
* TODO: Among other things to print ok MacIntosh and Vendor values
*/
-#define NETDISSECT_REWORKED
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <tcpdump-stdinc.h>
+#include <netdissect-stdinc.h>
#include <string.h>
-#include "interface.h"
+#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
#include "oui.h"
#define TUNNEL_CLIENT_AUTH 90
#define TUNNEL_SERVER_AUTH 91
+
+#define ERROR_CAUSE 101
/********************************/
/* End Radius Attribute types */
/********************************/
};
-static void print_attr_string(netdissect_options *, register u_char *, u_int, u_short );
-static void print_attr_num(netdissect_options *, register u_char *, u_int, u_short );
-static void print_vendor_attr(netdissect_options *, register u_char *, u_int, u_short );
-static void print_attr_address(netdissect_options *, register u_char *, u_int, u_short);
-static void print_attr_time(netdissect_options *, register u_char *, u_int, u_short);
-static void print_attr_strange(netdissect_options *, register u_char *, u_int, u_short);
+static void print_attr_string(netdissect_options *, register const u_char *, u_int, u_short );
+static void print_attr_num(netdissect_options *, register const u_char *, u_int, u_short );
+static void print_vendor_attr(netdissect_options *, register const u_char *, u_int, u_short );
+static void print_attr_address(netdissect_options *, register const u_char *, u_int, u_short);
+static void print_attr_address6(netdissect_options *, register const u_char *, u_int, u_short);
+static void print_attr_netmask6(netdissect_options *, register const u_char *, u_int, u_short);
+static void print_attr_time(netdissect_options *, register const u_char *, u_int, u_short);
+static void print_attr_strange(netdissect_options *, register const u_char *, u_int, u_short);
struct radius_hdr { uint8_t code; /* Radius packet code */
"GRE",
"DVS",
"IP-in-IP Tunneling",
+ "VLAN",
};
/* Tunnel-Medium-Type Attribute standard values */
"Echo",
};
+/* Error-Cause standard values */
+#define ERROR_CAUSE_RESIDUAL_CONTEXT_REMOVED 201
+#define ERROR_CAUSE_INVALID_EAP_PACKET 202
+#define ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE 401
+#define ERROR_CAUSE_MISSING_ATTRIBUTE 402
+#define ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH 403
+#define ERROR_CAUSE_INVALID_REQUEST 404
+#define ERROR_CAUSE_UNSUPPORTED_SERVICE 405
+#define ERROR_CAUSE_UNSUPPORTED_EXTENSION 406
+#define ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE 407
+#define ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED 501
+#define ERROR_CAUSE_PROXY_REQUEST_NOT_ROUTABLE 502
+#define ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND 503
+#define ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE 504
+#define ERROR_CAUSE_PROXY_PROCESSING_ERROR 505
+#define ERROR_CAUSE_RESOURCES_UNAVAILABLE 506
+#define ERROR_CAUSE_REQUEST_INITIATED 507
+#define ERROR_CAUSE_MULTIPLE_SESSION_SELECTION_UNSUPPORTED 508
+#define ERROR_CAUSE_LOCATION_INFO_REQUIRED 509
+static const struct tok errorcausetype[] = {
+ { ERROR_CAUSE_RESIDUAL_CONTEXT_REMOVED, "Residual Session Context Removed" },
+ { ERROR_CAUSE_INVALID_EAP_PACKET, "Invalid EAP Packet (Ignored)" },
+ { ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE, "Unsupported Attribute" },
+ { ERROR_CAUSE_MISSING_ATTRIBUTE, "Missing Attribute" },
+ { ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH, "NAS Identification Mismatch" },
+ { ERROR_CAUSE_INVALID_REQUEST, "Invalid Request" },
+ { ERROR_CAUSE_UNSUPPORTED_SERVICE, "Unsupported Service" },
+ { ERROR_CAUSE_UNSUPPORTED_EXTENSION, "Unsupported Extension" },
+ { ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE, "Invalid Attribute Value" },
+ { ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED, "Administratively Prohibited" },
+ { ERROR_CAUSE_PROXY_REQUEST_NOT_ROUTABLE, "Request Not Routable (Proxy)" },
+ { ERROR_CAUSE_SESSION_CONTEXT_NOT_FOUND, "Session Context Not Found" },
+ { ERROR_CAUSE_SESSION_CONTEXT_NOT_REMOVABLE, "Session Context Not Removable" },
+ { ERROR_CAUSE_PROXY_PROCESSING_ERROR, "Other Proxy Processing Error" },
+ { ERROR_CAUSE_RESOURCES_UNAVAILABLE, "Resources Unavailable" },
+ { ERROR_CAUSE_REQUEST_INITIATED, "Request Initiated" },
+ { ERROR_CAUSE_MULTIPLE_SESSION_SELECTION_UNSUPPORTED, "Multiple Session Selection Unsupported" },
+ { ERROR_CAUSE_LOCATION_INFO_REQUIRED, "Location Info Required" },
+ { 0, NULL }
+ };
-struct attrtype { const char *name; /* Attribute name */
+
+static struct attrtype {
+ const char *name; /* Attribute name */
const char **subtypes; /* Standard Values (if any) */
u_char siz_subtypes; /* Size of total standard values */
u_char first_subtype; /* First standard value is 0 or 1 */
- void (*print_func)(netdissect_options *, register u_char *, u_int, u_short);
+ void (*print_func)(netdissect_options *, register const u_char *, u_int, u_short);
} attr_type[]=
{
{ NULL, NULL, 0, 0, NULL },
{ "Login-Service", login_serv, TAM_SIZE(login_serv), 0, print_attr_num },
{ "Login-TCP-Port", NULL, 0, 0, print_attr_num },
{ "Unassigned", NULL, 0, 0, NULL }, /*17*/
- { "Reply-Message", NULL, 0, 0, print_attr_string },
+ { "Reply-Message", NULL, 0, 0, print_attr_string },
{ "Callback-Number", NULL, 0, 0, print_attr_string },
{ "Callback-Id", NULL, 0, 0, print_attr_string },
{ "Unassigned", NULL, 0, 0, NULL }, /*21*/
{ "CUI", NULL, 0, 0, print_attr_string },
{ "Tunnel-Client-Auth-ID", NULL, 0, 0, print_attr_string },
{ "Tunnel-Server-Auth-ID", NULL, 0, 0, print_attr_string },
- { "Unassigned", NULL, 0, 0, NULL }, /*92*/
- { "Unassigned", NULL, 0, 0, NULL } /*93*/
+ { "NAS-Filter-Rule", NULL, 0, 0, print_attr_string },
+ { "Unassigned", NULL, 0, 0, NULL }, /*93*/
+ { "Originating-Line-Info", NULL, 0, 0, NULL },
+ { "NAS-IPv6-Address", NULL, 0, 0, print_attr_address6 },
+ { "Framed-Interface-ID", NULL, 0, 0, NULL },
+ { "Framed-IPv6-Prefix", NULL, 0, 0, print_attr_netmask6 },
+ { "Login-IPv6-Host", NULL, 0, 0, print_attr_address6 },
+ { "Framed-IPv6-Route", NULL, 0, 0, print_attr_string },
+ { "Framed-IPv6-Pool", NULL, 0, 0, print_attr_string },
+ { "Error-Cause", NULL, 0, 0, print_attr_strange },
+ { "EAP-Key-Name", NULL, 0, 0, NULL },
+ { "Digest-Response", NULL, 0, 0, print_attr_string },
+ { "Digest-Realm", NULL, 0, 0, print_attr_string },
+ { "Digest-Nonce", NULL, 0, 0, print_attr_string },
+ { "Digest-Response-Auth", NULL, 0, 0, print_attr_string },
+ { "Digest-Nextnonce", NULL, 0, 0, print_attr_string },
+ { "Digest-Method", NULL, 0, 0, print_attr_string },
+ { "Digest-URI", NULL, 0, 0, print_attr_string },
+ { "Digest-Qop", NULL, 0, 0, print_attr_string },
+ { "Digest-Algorithm", NULL, 0, 0, print_attr_string },
+ { "Digest-Entity-Body-Hash", NULL, 0, 0, print_attr_string },
+ { "Digest-CNonce", NULL, 0, 0, print_attr_string },
+ { "Digest-Nonce-Count", NULL, 0, 0, print_attr_string },
+ { "Digest-Username", NULL, 0, 0, print_attr_string },
+ { "Digest-Opaque", NULL, 0, 0, print_attr_string },
+ { "Digest-Auth-Param", NULL, 0, 0, print_attr_string },
+ { "Digest-AKA-Auts", NULL, 0, 0, print_attr_string },
+ { "Digest-Domain", NULL, 0, 0, print_attr_string },
+ { "Digest-Stale", NULL, 0, 0, print_attr_string },
+ { "Digest-HA1", NULL, 0, 0, print_attr_string },
+ { "SIP-AOR", NULL, 0, 0, print_attr_string },
+ { "Delegated-IPv6-Prefix", NULL, 0, 0, print_attr_netmask6 },
};
/*****************************/
static void
print_attr_string(netdissect_options *ndo,
- register u_char *data, u_int length, u_short attr_code)
+ register const u_char *data, u_int length, u_short attr_code)
{
register u_int i;
{
case TUNNEL_PASS:
if (length < 3)
- {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ goto trunc;
if (*data && (*data <=0x1F) )
- ND_PRINT((ndo, "Tag[%u] ", *data));
+ ND_PRINT((ndo, "Tag[%u] ", EXTRACT_U_1(data)));
else
ND_PRINT((ndo, "Tag[Unused] "));
data++;
length--;
- ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data)));
+ ND_PRINT((ndo, "Salt %u ", EXTRACT_BE_U_2(data)));
data+=2;
length-=2;
break;
if (*data <= 0x1F)
{
if (length < 1)
- {
- ND_PRINT((ndo, "%s", tstr));
- return;
- }
+ goto trunc;
if (*data)
- ND_PRINT((ndo, "Tag[%u] ", *data));
+ ND_PRINT((ndo, "Tag[%u] ", EXTRACT_U_1(data)));
else
ND_PRINT((ndo, "Tag[Unused] "));
data++;
}
break;
case EGRESS_VLAN_NAME:
+ if (length < 1)
+ goto trunc;
ND_PRINT((ndo, "%s (0x%02x) ",
- tok2str(rfc4675_tagged,"Unknown tag",*data),
- *data));
+ tok2str(rfc4675_tagged,"Unknown tag",EXTRACT_U_1(data)),
+ EXTRACT_U_1(data)));
data++;
length--;
break;
}
- for (i=0; *data && i < length ; i++, data++)
- ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data));
+ for (i=0; i < length && EXTRACT_U_1(data); i++, data++)
+ ND_PRINT((ndo, "%c", ND_ISPRINT(EXTRACT_U_1(data)) ? EXTRACT_U_1(data) : '.'));
return;
*/
static void
print_vendor_attr(netdissect_options *ndo,
- register u_char *data, u_int length, u_short attr_code _U_)
+ register const u_char *data, u_int length, u_short attr_code _U_)
{
u_int idx;
u_int vendor_id;
if (length < 4)
goto trunc;
- ND_TCHECK2(*data, 4);
- vendor_id = EXTRACT_32BITS(data);
+ ND_TCHECK_4(data);
+ vendor_id = EXTRACT_BE_U_4(data);
data+=4;
length-=4;
vendor_id));
while (length >= 2) {
- ND_TCHECK2(*data, 2);
+ ND_TCHECK_2(data);
vendor_type = *(data);
- vendor_length = *(data+1);
+ vendor_length = EXTRACT_U_1(data + 1);
if (vendor_length < 2)
{
vendor_type,
vendor_length));
for (idx = 0; idx < vendor_length ; idx++, data++)
- ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data));
+ ND_PRINT((ndo, "%c", ND_ISPRINT(EXTRACT_U_1(data)) ? EXTRACT_U_1(data) : '.'));
length-=vendor_length;
}
return;
/******************************/
static void
print_attr_num(netdissect_options *ndo,
- register u_char *data, u_int length, u_short attr_code)
+ register const u_char *data, u_int length, u_short attr_code)
{
uint32_t timeout;
return;
}
- ND_TCHECK2(data[0],4);
+ ND_TCHECK_4(data);
/* This attribute has standard values */
if (attr_type[attr_code].siz_subtypes)
{
if (!*data)
ND_PRINT((ndo, "Tag[Unused] "));
else
- ND_PRINT((ndo, "Tag[%d] ", *data));
+ ND_PRINT((ndo, "Tag[%d] ", EXTRACT_U_1(data)));
data++;
- data_value = EXTRACT_24BITS(data);
+ data_value = EXTRACT_BE_U_3(data);
}
else
{
- data_value = EXTRACT_32BITS(data);
+ data_value = EXTRACT_BE_U_4(data);
}
if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 +
attr_type[attr_code].first_subtype) &&
switch(attr_code) /* Be aware of special cases... */
{
case FRM_IPX:
- if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
+ if (EXTRACT_BE_U_4(data) == 0xFFFFFFFE )
ND_PRINT((ndo, "NAS Select"));
else
- ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
+ ND_PRINT((ndo, "%d", EXTRACT_BE_U_4(data)));
break;
case SESSION_TIMEOUT:
case ACCT_DELAY:
case ACCT_SESSION_TIME:
case ACCT_INT_INTERVAL:
- timeout = EXTRACT_32BITS( data);
+ timeout = EXTRACT_BE_U_4(data);
if ( timeout < 60 )
ND_PRINT((ndo, "%02d secs", timeout));
else
break;
case FRM_ATALK_LINK:
- if (EXTRACT_32BITS(data) )
- ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
+ if (EXTRACT_BE_U_4(data))
+ ND_PRINT((ndo, "%d", EXTRACT_BE_U_4(data)));
else
ND_PRINT((ndo, "Unnumbered"));
break;
case FRM_ATALK_NETWORK:
- if (EXTRACT_32BITS(data) )
- ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
+ if (EXTRACT_BE_U_4(data))
+ ND_PRINT((ndo, "%d", EXTRACT_BE_U_4(data)));
else
ND_PRINT((ndo, "NAS assigned"));
break;
case TUNNEL_PREFERENCE:
if (*data)
- ND_PRINT((ndo, "Tag[%d] ", *data));
+ ND_PRINT((ndo, "Tag[%d] ", EXTRACT_U_1(data)));
else
ND_PRINT((ndo, "Tag[Unused] "));
data++;
- ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
+ ND_PRINT((ndo, "%d", EXTRACT_BE_U_3(data)));
break;
case EGRESS_VLAN_ID:
ND_PRINT((ndo, "%s (0x%02x) ",
- tok2str(rfc4675_tagged,"Unknown tag",*data),
- *data));
+ tok2str(rfc4675_tagged,"Unknown tag",EXTRACT_U_1(data)),
+ EXTRACT_U_1(data)));
data++;
- ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
+ ND_PRINT((ndo, "%d", EXTRACT_BE_U_3(data)));
break;
default:
- ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
+ ND_PRINT((ndo, "%d", EXTRACT_BE_U_4(data)));
break;
} /* switch */
/*****************************/
static void
print_attr_address(netdissect_options *ndo,
- register u_char *data, u_int length, u_short attr_code)
+ register const u_char *data, u_int length, u_short attr_code)
{
if (length != 4)
{
return;
}
- ND_TCHECK2(data[0],4);
+ ND_TCHECK_4(data);
switch(attr_code)
{
case FRM_IPADDR:
case LOG_IPHOST:
- if (EXTRACT_32BITS(data) == 0xFFFFFFFF )
+ if (EXTRACT_BE_U_4(data) == 0xFFFFFFFF )
ND_PRINT((ndo, "User Selected"));
else
- if (EXTRACT_32BITS(data) == 0xFFFFFFFE )
+ if (EXTRACT_BE_U_4(data) == 0xFFFFFFFE )
ND_PRINT((ndo, "NAS Select"));
else
ND_PRINT((ndo, "%s",ipaddr_string(ndo, data)));
ND_PRINT((ndo, "%s", tstr));
}
+/*****************************/
+/* Print an attribute IPv6 */
+/* address value pointed by */
+/* 'data' and 'length' size. */
+/*****************************/
+/* Returns nothing. */
+/*****************************/
+static void
+print_attr_address6(netdissect_options *ndo,
+ register const u_char *data, u_int length, u_short attr_code _U_)
+{
+ if (length != 16)
+ {
+ ND_PRINT((ndo, "ERROR: length %u != 16", length));
+ return;
+ }
+
+ ND_TCHECK_16(data);
+
+ ND_PRINT((ndo, "%s", ip6addr_string(ndo, data)));
+
+ return;
+
+ trunc:
+ ND_PRINT((ndo, "%s", tstr));
+}
+
+static void
+print_attr_netmask6(netdissect_options *ndo,
+ register const u_char *data, u_int length, u_short attr_code _U_)
+{
+ u_char data2[16];
+
+ if (length < 2 || length > 18)
+ {
+ ND_PRINT((ndo, "ERROR: length %u not in range (2..18)", length));
+ return;
+ }
+ ND_TCHECK2(data[0], length);
+ if (data[1] > 128)
+ {
+ ND_PRINT((ndo, "ERROR: netmask %u not in range (0..128)", EXTRACT_U_1(data + 1)));
+ return;
+ }
+
+ memset(data2, 0, sizeof(data2));
+ if (length > 2)
+ memcpy(data2, data+2, length-2);
+
+ ND_PRINT((ndo, "%s/%u", ip6addr_string(ndo, data2), EXTRACT_U_1(data + 1)));
+
+ if (data[1] > 8 * (length - 2))
+ ND_PRINT((ndo, " (inconsistent prefix length)"));
+
+ return;
+
+ trunc:
+ ND_PRINT((ndo, "%s", tstr));
+}
+
/*************************************/
/* Print an attribute of 'secs since */
/* January 1, 1970 00:00 UTC' value */
/*************************************/
static void
print_attr_time(netdissect_options *ndo,
- register u_char *data, u_int length, u_short attr_code _U_)
+ register const u_char *data, u_int length, u_short attr_code _U_)
{
time_t attr_time;
char string[26];
return;
}
- ND_TCHECK2(data[0],4);
+ ND_TCHECK_4(data);
- attr_time = EXTRACT_32BITS(data);
+ attr_time = EXTRACT_BE_U_4(data);
strlcpy(string, ctime(&attr_time), sizeof(string));
/* Get rid of the newline */
string[24] = '\0';
/***********************************/
static void
print_attr_strange(netdissect_options *ndo,
- register u_char *data, u_int length, u_short attr_code)
+ register const u_char *data, u_int length, u_short attr_code)
{
u_short len_data;
+ u_int error_cause_value;
switch(attr_code)
{
return;
}
ND_PRINT((ndo, "User_challenge ("));
- ND_TCHECK2(data[0],8);
+ ND_TCHECK_8(data);
len_data = 8;
PRINT_HEX(len_data, data);
ND_PRINT((ndo, ") User_resp("));
- ND_TCHECK2(data[0],8);
+ ND_TCHECK_8(data);
len_data = 8;
PRINT_HEX(len_data, data);
ND_PRINT((ndo, ")"));
ND_PRINT((ndo, "ERROR: length %u != 14", length));
return;
}
- ND_TCHECK2(data[0],1);
+ ND_TCHECK_1(data);
if (*data)
ND_PRINT((ndo, "User can change password"));
else
ND_PRINT((ndo, "User cannot change password"));
data++;
- ND_TCHECK2(data[0],1);
- ND_PRINT((ndo, ", Min password length: %d", *data));
+ ND_TCHECK_1(data);
+ ND_PRINT((ndo, ", Min password length: %d", EXTRACT_U_1(data)));
data++;
ND_PRINT((ndo, ", created at: "));
- ND_TCHECK2(data[0],4);
+ ND_TCHECK_4(data);
len_data = 4;
PRINT_HEX(len_data, data);
ND_PRINT((ndo, ", expires in: "));
- ND_TCHECK2(data[0],4);
+ ND_TCHECK_4(data);
len_data = 4;
PRINT_HEX(len_data, data);
ND_PRINT((ndo, ", Current Time: "));
- ND_TCHECK2(data[0],4);
+ ND_TCHECK_4(data);
len_data = 4;
PRINT_HEX(len_data, data);
break;
ND_PRINT((ndo, "ERROR: length %u != 8", length));
return;
}
- ND_TCHECK2(data[0],8);
+ ND_TCHECK_8(data);
len_data = 8;
PRINT_HEX(len_data, data);
break;
+
+ case ERROR_CAUSE:
+ if (length != 4)
+ {
+ ND_PRINT((ndo, "Error: length %u != 4", length));
+ return;
+ }
+ ND_TCHECK_4(data);
+
+ error_cause_value = EXTRACT_BE_U_4(data);
+ ND_PRINT((ndo, "Error cause %u: %s", error_cause_value, tok2str(errorcausetype, "Error-Cause %u not known", error_cause_value)));
+ break;
}
return;
radius_attrs_print(netdissect_options *ndo,
register const u_char *attr, u_int length)
{
- register const struct radius_attr *rad_attr = (struct radius_attr *)attr;
+ register const struct radius_attr *rad_attr = (const struct radius_attr *)attr;
const char *attr_string;
while (length > 0)
{
if ( attr_type[rad_attr->type].print_func )
(*attr_type[rad_attr->type].print_func)(
- ndo, ((u_char *)(rad_attr+1)),
+ ndo, ((const u_char *)(rad_attr+1)),
rad_attr->len - 2, rad_attr->type);
}
}
/* do we also want to see a hex dump ? */
if (ndo->ndo_vflag> 1)
- print_unknown_data(ndo, (u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2);
+ print_unknown_data(ndo, (const u_char *)rad_attr+2, "\n\t ", (rad_attr->len)-2);
length-=(rad_attr->len);
- rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len);
+ rad_attr = (const struct radius_attr *)( ((const char *)(rad_attr))+rad_attr->len);
}
return;
u_int len, auth_idx;
ND_TCHECK2(*dat, MIN_RADIUS_LEN);
- rad = (struct radius_hdr *)dat;
- len = EXTRACT_16BITS(&rad->len);
+ rad = (const struct radius_hdr *)dat;
+ len = EXTRACT_BE_U_2(&rad->len);
if (len < MIN_RADIUS_LEN)
{