radius: Use IPv6 for communication

IPv4 now only supported via IPv6-mapped addresses.
This commit is contained in:
Tassilo Schweyer 2025-10-13 16:53:35 +02:00
parent e9c8c172b9
commit 7081b7aaac
3 changed files with 50 additions and 24 deletions

View file

@ -56,7 +56,7 @@ void initrad(void)
uint16_t min = config->radius_bind_min;
uint16_t max = config->radius_bind_max;
int inc = 1;
struct sockaddr_in addr;
struct sockaddr_in6 addr;
if (min)
{
@ -76,7 +76,7 @@ void initrad(void)
for (i = 0; i < RADIUS_FDS; i++)
{
int flags;
radfds[i] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
radfds[i] = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
flags = fcntl(radfds[i], F_GETFL, 0);
fcntl(radfds[i], F_SETFL, flags | O_NONBLOCK);
@ -85,11 +85,11 @@ void initrad(void)
int b;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin6_family = AF_INET6;
addr.sin6_addr = in6addr_any;
do {
addr.sin_port = htons(port);
addr.sin6_port = htons(port);
if ((b = bind(radfds[i], (struct sockaddr *) &addr, sizeof(addr))) < 0)
{
if ((port += inc) < min || port > max)
@ -163,7 +163,7 @@ uint16_t radiusnew(sessionidt s)
// Send a RADIUS request
void radiussend(uint16_t r, uint8_t state)
{
struct sockaddr_in addr;
struct sockaddr_in6 addr;
uint8_t b[4096]; // RADIUS packet
char pass[129];
int pl;
@ -471,9 +471,16 @@ void radiussend(uint16_t r, uint8_t state)
}
// NAS-IP-Address
*p = 4;
p[1] = 6;
*(uint32_t *)(p + 2) = config->bind_address;
//*p = 4;
//p[1] = 6;
//*(uint32_t *)(p + 2) = config->bind_address;
//p += p[1];
// NAS-IPv6-Address
*p = 95;
p[1] = 18;
//*(uint32_t *)(p + 2) = config->bind_address;
memcpy(&p[2], (char*) &config->radius_nas_addr, 16);
p += p[1];
// All AVpairs added
@ -491,13 +498,13 @@ void radiussend(uint16_t r, uint8_t state)
MD5_Hmac(ma, b, p-b, config->radiussecret, strlen(config->radiussecret));
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
*(uint32_t *) & addr.sin_addr = config->radiusserver[(radius[r].try - 1) % config->numradiusservers];
addr.sin6_family = AF_INET6;
addr.sin6_addr = config->radiusserver[(radius[r].try - 1) % config->numradiusservers];
{
// get radius port
uint16_t port = config->radiusport[(radius[r].try - 1) % config->numradiusservers];
// assume RADIUS accounting port is the authentication port +1
addr.sin_port = htons((state == RADIUSAUTH || state == RADIUSJUSTAUTH) ? port : port+1);
addr.sin6_port = htons((state == RADIUSAUTH || state == RADIUSJUSTAUTH) ? port : port+1);
}
LOG_HEX(5, "RADIUS Send", b, (p - b));