From d883b2dbafeed3ebd9d7a56ab1469373bd001a3b Mon Sep 17 00:00:00 2001 From: Adrian Ban Date: Wed, 3 Apr 2013 23:19:52 +0300 Subject: [PATCH 1/1] plugins/radius: Handle bindaddr keyword in radiusclient.conf This adds code to the radius plugin to handle the bindaddr keyword in /etc/radiusclient/radiusclient.conf, thus allowing the administrator to specify which local IP address to use when sending packets to the radius server. This is very common for setups where the router has multiple interfaces for upstream and you don't know which connection is active. In this case sometimes the packet uses the IP of interface 1 and sometimes uses the IP of interface 2. With this patch (adapted from radiusclient-ng) you can specify the IP of the loopback address, and the plugin will bind to that IP and send the packet with a fixed IP every time. Slimmed a little bit at James Carlson's suggestion. Signed-off-by: Paul Mackerras --- pppd/plugins/radius/ip_util.c | 28 ++++++++++++++++++++++++++++ pppd/plugins/radius/options.h | 1 + pppd/plugins/radius/sendserver.c | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pppd/plugins/radius/ip_util.c b/pppd/plugins/radius/ip_util.c index cd59e7b..1f6a76e 100644 --- a/pppd/plugins/radius/ip_util.c +++ b/pppd/plugins/radius/ip_util.c @@ -135,3 +135,31 @@ UINT4 rc_own_ipaddress(void) return this_host_ipaddr; } + +/* + * Function: rc_own_bind_ipaddress + * + * Purpose: get the IP address to be used as a source address + * for sending requests in host order + * + * Returns: IP address + * + */ + +UINT4 rc_own_bind_ipaddress(void) +{ + char *bindaddr; + UINT4 rval = 0; + + if ((bindaddr = rc_conf_str("bindaddr")) == NULL || + strcmp(rc_conf_str("bindaddr"), "*") == 0) { + rval = INADDR_ANY; + } else { + if ((rval = rc_get_ipaddr(bindaddr)) == 0) { + error("rc_own_bind_ipaddress: couldn't get IP address from bindaddr"); + rval = INADDR_ANY; + } + } + + return rval; +} diff --git a/pppd/plugins/radius/options.h b/pppd/plugins/radius/options.h index aa55305..f4ad986 100644 --- a/pppd/plugins/radius/options.h +++ b/pppd/plugins/radius/options.h @@ -55,6 +55,7 @@ static OPTION config_options[] = { {"radius_timeout", OT_INT, ST_UNDEF, NULL}, {"radius_retries", OT_INT, ST_UNDEF, NULL}, {"nas_identifier", OT_STR, ST_UNDEF, ""}, +{"bindaddr", OT_STR, ST_UNDEF, NULL}, /* local options */ {"login_local", OT_STR, ST_UNDEF, NULL}, }; diff --git a/pppd/plugins/radius/sendserver.c b/pppd/plugins/radius/sendserver.c index 3612b8d..f68aa67 100644 --- a/pppd/plugins/radius/sendserver.c +++ b/pppd/plugins/radius/sendserver.c @@ -244,7 +244,7 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info) sin = (struct sockaddr_in *) & salocal; memset ((char *) sin, '\0', (size_t) length); sin->sin_family = AF_INET; - sin->sin_addr.s_addr = htonl(INADDR_ANY); + sin->sin_addr.s_addr = htonl(rc_own_bind_ipaddress()); sin->sin_port = htons ((unsigned short) 0); if (bind (sockfd, (struct sockaddr *) sin, length) < 0 || getsockname (sockfd, (struct sockaddr *) sin, &length) < 0) -- 2.39.2