summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Eshenko <dmitriy.eshenko@accel-ppp.org>2023-12-07 12:55:22 +0300
committerGitHub <noreply@github.com>2023-12-07 12:55:22 +0300
commitc08e87e11b1e0b013ddb8b0773621a2b666db461 (patch)
tree9feadcb7932de1896befdbcce5e188d6760d48a2
parentdd95fc214d280e532236a65aba5ddf4b24086333 (diff)
parent962070cd52fe589514e2ef67325b09a1cfa9e6de (diff)
downloadaccel-ppp-c08e87e11b1e0b013ddb8b0773621a2b666db461.tar.gz
accel-ppp-c08e87e11b1e0b013ddb8b0773621a2b666db461.zip
Merge pull request #115 from leonardomeres/radius_server_ipv6
Adding support to Radius IPV6 address
-rw-r--r--accel-pppd/radius/radius_p.h4
-rw-r--r--accel-pppd/radius/req.c85
-rw-r--r--accel-pppd/radius/serv.c40
3 files changed, 94 insertions, 35 deletions
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index cd9a0ab..8761362 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -95,6 +95,7 @@ struct rad_req_t {
struct rad_server_t *serv;
in_addr_t server_addr;
+ struct in6_addr server_ipv6_addr;
int server_port;
int type;
@@ -120,6 +121,7 @@ struct rad_server_t {
struct triton_timer_t timer;
int id;
in_addr_t addr;
+ struct in6_addr addr6;
char *secret;
int auth_port;
int acct_port;
@@ -165,6 +167,8 @@ struct rad_server_t {
unsigned int acct_on:1;
unsigned int need_free:1;
unsigned int need_close:1;
+ //Flag to set radius ip version
+ unsigned int ipv4:1;
};
#define RAD_SERV_AUTH 0
diff --git a/accel-pppd/radius/req.c b/accel-pppd/radius/req.c
index 11abf8c..be74f04 100644
--- a/accel-pppd/radius/req.c
+++ b/accel-pppd/radius/req.c
@@ -53,6 +53,7 @@ static struct rad_req_t *__rad_req_alloc(struct radius_pd_t *rpd, int code, cons
goto out_err;
req->server_addr = req->serv->addr;
+ req->server_ipv6_addr = req->serv->addr6;
req->server_port = req->serv->auth_port;
while (1) {
@@ -268,47 +269,71 @@ void rad_req_free(struct rad_req_t *req)
static int make_socket(struct rad_req_t *req)
{
- struct sockaddr_in addr;
+ if (req->serv->ipv4) {
+ struct sockaddr_in addr;
- req->hnd.fd = socket(PF_INET, SOCK_DGRAM, 0);
- if (req->hnd.fd < 0) {
- log_ppp_error("radius:socket: %s\n", strerror(errno));
- return -1;
- }
+ req->hnd.fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (req->hnd.fd < 0) {
+ log_ppp_error("radius:socket: %s\n", strerror(errno));
+ return -1;
+ }
- fcntl(req->hnd.fd, F_SETFD, fcntl(req->hnd.fd, F_GETFD) | FD_CLOEXEC);
+ fcntl(req->hnd.fd, F_SETFD, fcntl(req->hnd.fd, F_GETFD) | FD_CLOEXEC);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+
+ if (conf_bind) {
+ addr.sin_addr.s_addr = conf_bind;
+ if (bind(req->hnd.fd, (struct sockaddr *) &addr, sizeof(addr))) {
+ log_ppp_error("radius:bind: %s\n", strerror(errno));
+ goto out_err;
+ }
+ }
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = req->server_addr;
+ addr.sin_port = htons(req->server_port);
- if (conf_bind) {
- addr.sin_addr.s_addr = conf_bind;
- if (bind(req->hnd.fd, (struct sockaddr *) &addr, sizeof(addr))) {
- log_ppp_error("radius:bind: %s\n", strerror(errno));
+ if ( req->serv && !req->serv->bind_default && ( 0 > setsockopt(req->hnd.fd, SOL_SOCKET, SO_BINDTODEVICE, req->serv->bind_device, strlen(req->serv->bind_device)) ) )
+ {
+ log_ppp_error("radius:setsockopt: %s\n", strerror(errno));
goto out_err;
}
- }
- addr.sin_addr.s_addr = req->server_addr;
- addr.sin_port = htons(req->server_port);
+ if (connect(req->hnd.fd, (struct sockaddr *) &addr, sizeof(addr))) {
+ log_ppp_error("radius:connect: %s\n", strerror(errno));
+ goto out_err;
+ }
- if ( req->serv && !req->serv->bind_default && ( 0 > setsockopt(req->hnd.fd, SOL_SOCKET, SO_BINDTODEVICE, req->serv->bind_device, strlen(req->serv->bind_device)) ) )
- {
- log_ppp_error("radius:setsockopt: %s\n", strerror(errno));
- goto out_err;
- }
+ if (fcntl(req->hnd.fd, F_SETFL, O_NONBLOCK)) {
+ log_ppp_error("radius: failed to set nonblocking mode: %s\n", strerror(errno));
+ goto out_err;
+ }
- if (connect(req->hnd.fd, (struct sockaddr *) &addr, sizeof(addr))) {
- log_ppp_error("radius:connect: %s\n", strerror(errno));
- goto out_err;
- }
+ return 0;
- if (fcntl(req->hnd.fd, F_SETFL, O_NONBLOCK)) {
- log_ppp_error("radius: failed to set nonblocking mode: %s\n", strerror(errno));
- goto out_err;
- }
+ }else {//ipv6 address
+ struct sockaddr_in6 addr6;
- return 0;
+ req->hnd.fd = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (req->hnd.fd < 0) {
+ log_ppp_error("radius:socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+ fcntl(req->hnd.fd, F_SETFD, fcntl(req->hnd.fd, F_GETFD) | FD_CLOEXEC);
+
+ memset(&addr6, 0, sizeof(addr6));
+ addr6.sin6_family = AF_INET6;
+ addr6.sin6_addr = req->server_ipv6_addr;
+ addr6.sin6_port = htons(req->server_port);
+
+ if (connect(req->hnd.fd, (struct sockaddr *) &addr6, sizeof(addr6))) {
+ log_ppp_error("radius:connect: %s\n", strerror(errno));
+ goto out_err;
+ }
+ return 0;
+ }
out_err:
if (req->hnd.tpd)
diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c
index 4339d30..4af6a67 100644
--- a/accel-pppd/radius/serv.c
+++ b/accel-pppd/radius/serv.c
@@ -485,10 +485,15 @@ static void serv_ctx_close(struct triton_context_t *ctx)
static void show_stat(struct rad_server_t *s, void *client)
{
- char addr[17];
+ char addr[INET6_ADDRSTRLEN]; // Sufficient size for both IPv4 and IPv6 addresses
struct timespec ts;
- u_inet_ntoa(s->addr, addr);
+ if (s->ipv4) {
+ u_inet_ntoa(s->addr, addr);
+ } else {
+ inet_ntop(AF_INET6, &s->addr6, addr, sizeof(addr));
+ }
+
clock_gettime(CLOCK_MONOTONIC, &ts);
cli_sendv(client, "radius(%i, %s):\r\n", s->id, addr);
@@ -725,7 +730,20 @@ static int parse_server1(const char *_opt, struct rad_server_t *s)
if (ptr3)
*ptr3 = 0;
- s->addr = inet_addr(opt);
+ struct in_addr addr4;
+ if (inet_pton(AF_INET, opt, &addr4) == 1) {
+ s->ipv4 = 1;
+ s->addr = addr4.s_addr;
+ }else {
+ struct in6_addr addr6;
+ if (inet_pton(AF_INET6, opt, &addr6) == 1) {
+ s->ipv4 = 0;
+ s->addr6 = addr6;
+ } else {
+ log_error("Invalid server address");
+ goto out;
+ }
+ }
if (ptr2) {
if (ptr2[1]) {
@@ -774,8 +792,20 @@ static int parse_server2(const char *_opt, struct rad_server_t *s)
*ptr1 = 0;
- s->addr = inet_addr(opt);
-
+ struct in_addr addr4;
+ if (inet_pton(AF_INET, opt, &addr4) == 1) {
+ s->ipv4 = 1;
+ s->addr = addr4.s_addr;
+ }else {
+ struct in6_addr addr6;
+ if (inet_pton(AF_INET6, opt, &addr6) == 1) {
+ s->ipv4 = 0;
+ s->addr6 = addr6;
+ } else {
+ log_error("Invalid server address");
+ goto out;
+ }
+ }
ptr3 = strstr(ptr2, ",auth-port=");
if (ptr3) {
s->auth_port = strtol(ptr3 + 11, &endptr, 10);