#include <errno.h>
#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
#include <stdio.h>
/*
struct value_pair *next;
} VALUE_PAIR;
+
+typedef struct lrad_ipaddr_t {
+ int af; /* address family */
+ union {
+ struct in_addr ip4addr;
+#ifdef AF_INET6
+ struct in6_addr ip6addr;
+#endif
+ } ipaddr;
+} lrad_ipaddr_t;
+
+
/*
* vector: Request authenticator from access-request packet
* Put in there by rad_decode, and must be put in the
* data,data_len: Used between rad_recv and rad_decode.
*/
typedef struct radius_packet {
- int sockfd;
- uint32_t src_ipaddr;
- uint32_t dst_ipaddr;
- u_short src_port;
- u_short dst_port;
+ int sockfd;
+ lrad_ipaddr_t src_ipaddr;
+ lrad_ipaddr_t dst_ipaddr;
+ uint16_t src_port;
+ uint16_t dst_port;
int id;
unsigned int code;
uint8_t vector[AUTH_VECTOR_LEN];
uint32_t ip_addr(const char *);
char *ifid_ntoa(char *buffer, size_t size, uint8_t *ifid);
uint8_t *ifid_aton(const char *ifid_str, uint8_t *ifid);
-const char *ipv6_ntoa(char *buffer, size_t size, void *ip6addr);
-int ipv6_addr(const char *ip6_str, void *ip6addr);
char *strNcpy(char *dest, const char *src, int n);
void rad_lowercase(char *str);
void rad_rmspace(char *str);
int rad_unlockfd(int fd, int lock_len);
void lrad_bin2hex(const unsigned char *bin, unsigned char *hex, int len);
int lrad_hex2bin(const unsigned char *hex, unsigned char *bin, int len);
+#ifndef HAVE_INET_PTON
+int inet_pton(int af, const char *src, void *dst);
+#endif
+#ifndef HAVE_INET_NTOP
+const char *inet_ntop(int af, const void *src, char *dst, size_t cnt);
+#endif
+
+int ip_hton(const char *src, int af, lrad_ipaddr_t *dst);
+const char *ip_ntoh(const lrad_ipaddr_t *src, char *dst, size_t cnt);
+
#ifdef ASCEND_BINARY
/* filters.c */
typedef int (*RAD_REQUEST_FUNP)(REQUEST *);
typedef struct radclient {
- uint32_t ipaddr;
+ lrad_ipaddr_t ipaddr;
uint32_t netmask;
char longname[256];
u_char secret[32];
char realm[64];
char server[64];
char acct_server[64];
- uint32_t ipaddr; /* authentication */
- uint32_t acct_ipaddr;
+ lrad_ipaddr_t ipaddr; /* authentication */
+ lrad_ipaddr_t acct_ipaddr;
u_char secret[32];
time_t last_reply; /* last time we saw a packet */
int auth_port;
/* client.c */
int read_clients_file(const char *file);
-RADCLIENT *client_find(uint32_t ipno);
-const char *client_name(uint32_t ipno);
-void client_walk(void);
+RADCLIENT *client_find(const lrad_ipaddr_t *ipaddr);
+const char *client_name(const lrad_ipaddr_t *ipaddr);
void clients_free(RADCLIENT *cl);
/* files.c */
/* nas.c */
int read_naslist_file(char *);
NAS *nas_find(uint32_t ipno);
-const char *nas_name(uint32_t ipno);
-const char *nas_name2(RADIUS_PACKET *r);
-char * nas_name3(char *buf, size_t buflen, uint32_t ipno);
-NAS *nas_findbyname(char *nasname);
/* version.c */
void version(void);
* Return a printable host name (or IP address in dot notation)
* for the supplied IP address.
*/
-char * ip_hostname(char *buf, size_t buflen, uint32_t ipaddr)
+char *ip_hostname(char *buf, size_t buflen, uint32_t ipaddr)
{
struct hostent *hp;
#ifdef GETHOSTBYADDRRSTYLE
/*
* Return an IP address in standard dot notation
+ *
+ * FIXME: DELETE THIS
*/
const char *ip_ntoa(char *buffer, uint32_t ipaddr)
{
/*
* Return an IP address from
* one supplied in standard dot notation.
+ *
+ * FIXME: DELETE THIS
*/
uint32_t ip_addr(const char *ip_str)
{
}
return ifid;
}
+
+
+#ifndef HAVE_INET_PTON
/*
- * Return an IPv6 address in standard colon notation
+ * Utility function, so that the rest of the server doesn't
+ * have ifdef's around IPv6 support
*/
-const char *ipv6_ntoa(char *buffer, size_t size, void *ip6addr)
+int inet_pton(int af, const char *src, void *dst)
{
-#if defined(HAVE_INET_NTOP) && defined(AF_INET6)
- return inet_ntop(AF_INET6, (struct in6_addr *) ip6addr, buffer, size);
-#else
- /*
- * Do it really stupidly.
- */
- snprintf(buffer, size, "%x:%x:%x:%x:%x:%x:%x:%x",
- (((uint8_t *) ip6addr)[0] << 8) | ((uint8_t *) ip6addr)[1],
- (((uint8_t *) ip6addr)[2] << 8) | ((uint8_t *) ip6addr)[3],
- (((uint8_t *) ip6addr)[4] << 8) | ((uint8_t *) ip6addr)[5],
- (((uint8_t *) ip6addr)[6] << 8) | ((uint8_t *) ip6addr)[7],
- (((uint8_t *) ip6addr)[8] << 8) | ((uint8_t *) ip6addr)[9],
- (((uint8_t *) ip6addr)[10] << 8) | ((uint8_t *) ip6addr)[11],
- (((uint8_t *) ip6addr)[12] << 8) | ((uint8_t *) ip6addr)[13],
- (((uint8_t *) ip6addr)[14] << 8) | ((uint8_t *) ip6addr)[15]);
- return buffer;
+ if (af != AF_INET) return -1; /* unsupported */
+
+ return inet_aton(src, dst);
+}
#endif
+
+
+#ifndef HAVE_INET_NTOP
+/*
+ * Utility function, so that the rest of the server doesn't
+ * have ifdef's around IPv6 support
+ */
+const char *inet_ntop(int af, const void *src, char *dst, size_t cnt)
+{
+ if (af == AF_INET) {
+ uint32_t ipaddr;
+
+ if (cnt <= 15) return NULL;
+
+ ipaddr = *(uint32_t *) src;
+ ipaddr = ntohl(ipaddr);
+
+ snprintf(dst, cnt, "%d.%d.%d.%d",
+ (ipaddr >> 24) & 0xff,
+ (ipaddr >> 16) & 0xff,
+ (ipaddr >> 8) & 0xff,
+ (ipaddr ) & 0xff);
+ return dst;
+ }
+
+ return NULL; /* don't support IPv6 */
}
+#endif
/*
- * Return an IPv6 address from
- * one supplied in standard colon notation.
+ * Wrappers for IPv4/IPv6 host to IP address lookup.
+ * This API returns only one IP address, of the specified
+ * address family.
*/
-int ipv6_addr(const char *ip6_str, void *ip6addr)
+int ip_hton(const char *src, int af, lrad_ipaddr_t *dst)
{
-#if defined(HAVE_INET_PTON) && defined(AF_INET6)
- if (inet_pton(AF_INET6, ip6_str, (struct in6_addr *) ip6addr) != 1)
- return -1;
-#else
+ struct hostent *hp;
+#ifdef GETHOSTBYNAMERSTYLE
+#if (GETHOSTBYNAMERSTYLE == SYSVSTYLE) || (GETHOSTBYNAMERSTYLE == GNUSTYLE)
+ struct hostent result;
+ int error;
+ char buffer[2048];
+#endif
+#endif
+
+ if (af != AF_INET) return -1; /* only IPv4 for now */
+
+ dst->af = af;
+
/*
- * Copied from the 'ifid' code above, with minor edits.
+ * No DNS lookups, assume it's an IP address.
*/
- static const char xdigits[] = "0123456789abcdef";
- const char *p, *pch;
- int num_id = 0, val = 0, idx = 0;
- uint8_t *addr = ip6addr;
+ if (!librad_dodns) {
+ return inet_pton(af, src, &dst->ipaddr.ip4addr);
+ }
+
+#ifdef GETHOSTBYNAMERSTYLE
+#if GETHOSTBYNAMERSTYLE == SYSVSTYLE
+ hp = gethostbyname_r(src, &result, buffer, sizeof(buffer), &error);
+#elif GETHOSTBYNAMERSTYLE == GNUSTYLE
+ if (gethostbyname_r(src, &result, buffer, sizeof(buffer),
+ &hp, &error) != 0) {
+ return htonl(INADDR_NONE);
+ }
+#else
+ hp = gethostbyname(src);
+#endif
+#else
+ hp = gethostbyname(src);
+#endif
+ if (!hp) return -1;
- for (p = ip6_str; ; ++p) {
- if (*p == ':' || *p == '\0') {
- if (num_id <= 0)
- return -1;
+ if (hp->h_addrtype != af) return -1; /* not the right address family */
- /*
- * Drop 'val' into the array.
- */
- addr[idx] = (val >> 8) & 0xff;
- addr[idx + 1] = val & 0xff;
- if (*p == '\0') {
- /*
- * Must have all entries before
- * end of the string.
- */
- if (idx != 14)
- return -1;
- break;
- }
- val = 0;
- num_id = 0;
- if ((idx += 2) > 14)
- return -1;
- } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
- if (++num_id > 8) /* no more than 8 16-bit numbers */
- return -1;
- /*
- * Dumb version of 'scanf'
- */
- val <<= 4;
- val |= (pch - xdigits);
- } else
- return -1;
+ /*
+ * Paranoia from a Bind vulnerability. An attacker
+ * can manipulate DNS entries to change the length of the
+ * address. If the length isn't 4, something's wrong.
+ */
+ if (hp->h_length != 4) {
+ return -1;
}
-#endif
+
+ memcpy(&dst->ipaddr.ip4addr.s_addr, hp->h_addr,
+ sizeof(dst->ipaddr.ip4addr.s_addr));
return 0;
+
}
+/*
+ * Look IP addreses up, and print names (depending on DNS config)
+ */
+const char *ip_ntoh(const lrad_ipaddr_t *src, char *dst, size_t cnt)
+{
+ struct hostent *hp;
+#ifdef GETHOSTBYADDRRSTYLE
+#if (GETHOSTBYADDRRSTYLE == SYSVSTYLE) || (GETHOSTBYADDRRSTYLE == GNUSTYLE)
+ char buffer[2048];
+ struct hostent result;
+ int error;
+#endif
+#endif
+
+ /*
+ * No DNS: don't look up host names
+ */
+ if (!librad_dodns) {
+ return inet_ntop(src->af, &src->ipaddr, dst, cnt);
+ }
+
+ if (src->af != AF_INET) return NULL; /* invalid */
+
+#ifdef GETHOSTBYADDRRSTYLE
+#if GETHOSTBYADDRRSTYLE == SYSVSTYLE
+ hp = gethostbyaddr_r((const char *)&src->ipaddr.ip4addr.s_addr,
+ sizeof(src->ipaddr.ip4addr.s_addr),
+ src->af, &result, buffer, sizeof(buffer), &error);
+#elif GETHOSTBYADDRRSTYLE == GNUSTYLE
+ if (gethostbyaddr_r((const char *)&src->ipaddr.ip4addr.s_addr,
+ sizeof(src->ipaddr.ip4addr.s_addr),
+ src->af, &result, buffer, sizeof(buffer),
+ &hp, &error) != 0) {
+ hp = NULL;
+ }
+#else
+ hp = gethostbyaddr((const char *)&src->ipaddr.ip4addr.s_addr,
+ sizeof(src->ipaddr.ip4addr.s_addr), src->af);
+#endif
+#else
+ hp = gethostbyaddr((const char *)&src->ipaddr.ip4addr.s_addr,
+ sizeof(src->ipaddr.ip4addr.s_addr), src->af);
+#endif
+ if ((hp == NULL) ||
+ (strlen((char *)hp->h_name) >= cnt)) {
+ return inet_ntop(src->af, &src->ipaddr, dst, cnt);
+ }
+
+ strNcpy(dst, (char *)hp->h_name, cnt);
+ return dst;
+}
static const char *hextab = "0123456789abcdef";
{
DICT_VALUE *v;
char buf[1024];
- char *a;
+ const char *a;
time_t t;
struct tm s_tm;
break;
case PW_TYPE_ABINARY:
#ifdef ASCEND_BINARY
- a = buf;
- print_abinary(vp, (unsigned char *)buf, sizeof(buf));
- break;
+ a = buf;
+ print_abinary(vp, (unsigned char *)buf, sizeof(buf));
+ break;
#else
/* FALL THROUGH */
#endif
case PW_TYPE_OCTETS:
- strcpy(buf, "0x");
- a = buf + 2;
- for (t = 0; t < vp->length; t++) {
- sprintf(a, "%02x", vp->strvalue[t]);
- a += 2;
- }
- a = buf;
+ if (outlen <= (2 * (vp->length + 1))) return 0;
+
+ strcpy(buf, "0x");
+
+ lrad_bin2hex(vp->strvalue, buf + 2, vp->length);
+ a = buf;
break;
case PW_TYPE_IFID:
break;
case PW_TYPE_IPV6ADDR:
- a = ipv6_ntoa(buf, sizeof(buf), vp->strvalue);
+#if defined(HAVE_INET_NTOP) && defined(AF_INET6)
+ a = inet_ntop(AF_INET6,
+ (const struct in6_addr *) vp->strvalue,
+ buf, sizeof(buf));
+#else
+ /*
+ * Do it really stupidly.
+ */
+ snprintf(buf, sizeof(buf), "%x:%x:%x:%x:%x:%x:%x:%x",
+ (vp->strvalue[0] << 8) | vp->strvalue[1],
+ (vp->strvalue[2] << 8) | vp->strvalue[3],
+ (vp->strvalue[4] << 8) | vp->strvalue[5],
+ (vp->strvalue[6] << 8) | vp->strvalue[7],
+ (vp->strvalue[8] << 8) | vp->strvalue[9],
+ (vp->strvalue[10] << 8) | vp->strvalue[11],
+ (vp->strvalue[12] << 8) | vp->strvalue[13],
+ (vp->strvalue[15] << 8) | vp->strvalue[15]);
+ a = buf;
+#endif
break;
default:
#include "udpfromto.h"
#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
#include <sys/socket.h>
#ifdef HAVE_ARPA_INET_H
static lrad_randctx lrad_rand_pool; /* across multiple calls */
static int lrad_pool_initialized = 0;
+static int lrad_rand_index = 0;
static const char *packet_codes[] = {
"",
static void make_secret(unsigned char *digest, uint8_t *vector,
const char *secret, char *value);
+
+/*
+ * Wrapper for sendto which handles sendfromto, IPv6, and all
+ * possible combinations.
+ */
+static int rad_sendto(int sockfd, void *data, size_t data_len, int flags,
+ lrad_ipaddr_t *src_ipaddr, lrad_ipaddr_t *dst_ipaddr,
+ int dst_port)
+{
+ /*
+ * Hmm... we saremote/saremote6 could probably be pointers
+ * to dst.
+ */
+ const struct sockaddr *dst;
+ socklen_t sizeof_dst;
+ struct sockaddr_in saremote;
+#ifdef AF_INET6
+ struct sockaddr_in6 saremote6;
+#endif
+#ifdef WITH_UDPFROMTO
+ struct sockaddr_in salocal;
+ const struct sockaddr *src;
+ socklen_t sizeof_src;
+#ifdef AF_INET6
+ struct sockaddr_in6 salocal6;
+#endif
+#endif
+
+#ifdef WITH_UDPFROMTO
+ /*
+ * From IPv4 to IPv6 is bad, as is the opposite.
+ */
+ if (src_ipaddr->af != dst_ipaddr->af) return -1;
+#endif
+
+ /*
+ * IPv4 is supported.
+ */
+ if (dst_ipaddr->af == AF_INET) {
+ dst = (struct sockaddr *) &saremote;
+ sizeof_dst = sizeof(saremote);
+
+ /*
+ * FIXME: flow info? Scope ID?
+ * See <netinet/in.h>
+ */
+ memset(&saremote, 0, sizeof(saremote));
+ saremote.sin_family = AF_INET;
+ saremote.sin_addr = dst_ipaddr->ipaddr.ip4addr;
+ saremote.sin_port = dst_port;
+ saremote.sin_port = htons(saremote.sin_port);
+
+#ifdef WITH_UDPFROMTO
+ src = (struct sockaddr *) &salocal;
+ sizeof_src = sizeof(salocal);
+ memset (&salocal, 0, sizeof(salocal));
+ salocal.sin_family = AF_INET;
+ salocal.sin_addr.s_addr = src_ipaddr.addr.ip4addr;
+#else
+ src_ipaddr = src_ipaddr; /* -Wunused */
+#endif
+ }
+#ifdef AF_INET6
+ /*
+ * IPv6 MAY be supported.
+ */
+ else if (dst_ipaddr->af == AF_INET6) {
+ dst = (struct sockaddr *) &saremote6;
+ sizeof_dst = sizeof(saremote6);
+
+ memset(&saremote6, 0, sizeof(saremote6));
+ saremote6.sin6_family = AF_INET6;
+ saremote6.sin6_addr = dst_ipaddr->ipaddr.ip6addr;
+ saremote6.sin6_port = dst_port;
+ saremote6.sin6_port = htons(saremote6.sin6_port);
+
+#ifdef WITH_UDPFROMTO
+ return -1; /* UDPFROMTO && IPv6 is not supported */
+#endif
+ }
+#endif
+ /*
+ * Unknown address family, Die Die Die!
+ */
+ else return -1;
+
+
+#ifndef WITH_UDPFROMTO
+ return sendto(sockfd, data, data_len, flags, dst, sizeof_dst);
+#else
+ return sendfromto(sockfd, data, data_len, flags,
+ src, sizeof_src, dst, sizeof_dst);
+#endif
+}
+
+
+/*
+ * Wrapper for recvfrom, which handles recvfromto, IPv6, and all
+ * possible combinations.
+ */
+static ssize_t rad_recvfrom(int sockfd, void *buf, size_t len, int flags,
+ lrad_ipaddr_t *src_ipaddr, uint16_t *src_port,
+ lrad_ipaddr_t *dst_ipaddr, uint16_t *dst_port)
+{
+ ssize_t data_len;
+ struct sockaddr *src;
+ socklen_t sizeof_src;
+ const struct sockaddr *dst;
+ socklen_t sizeof_dst;
+ struct sockaddr_in salocal;
+ socklen_t salen;
+ struct sockaddr_in saremote;
+#ifdef AF_INET6
+ struct sockaddr_in6 saremote6;
+ struct sockaddr_in6 salocal6;
+#endif
+
+ /*
+ * First, do a hokey hack to figure out which address
+ * family, address, and port the socket is listening on.
+ */
+ if (getsockname(sockfd, (struct sockaddr *) &salocal,
+ &salen) < 0) return -1;
+
+ if (salocal.sin_family == AF_INET) {
+ dst_ipaddr->af = AF_INET;
+ dst_ipaddr->ipaddr.ip4addr = salocal.sin_addr;
+ *dst_port = ntohs(salocal.sin_port);
+
+ src = (struct sockaddr *) &saremote;
+ sizeof_src = sizeof(saremote);
+ dst = (struct sockaddr *) &salocal;
+ sizeof_dst = sizeof(salocal);
+ }
+#ifdef AF_INET6
+ /*
+ * IPv6 MAY be supported.
+ */
+ else if (salocal.sin_family == AF_INET6) {
+ memcpy(&salocal6, &salocal, sizeof(salocal6));
+
+ dst_ipaddr->af = AF_INET;
+ dst_ipaddr->ipaddr.ip6addr = salocal6.sin6_addr;
+ *dst_port = ntohs(salocal6.sin6_port);
+
+ src = (struct sockaddr *) &saremote6;
+ sizeof_src = sizeof(saremote6);
+ dst = (struct sockaddr *) &salocal6;
+ sizeof_dst = sizeof(salocal6);
+#ifdef WITH_UDPFROMTO
+ return -1; /* not supported for IPv6 */
+#endif
+ }
+#endif
+ /*
+ * Unknown address family, Die Die Die!
+ */
+ else return -1;
+
+ /*
+ * Receive the packet.
+ */
+ memset(src, 0, sizeof_src);
+#ifndef WITH_UDPFROMTO
+ data_len = recvfrom(sockfd, buf, len, flags, src, &sizeof_src);
+#else
+ memset(dst, 0, sizeof_dst);
+
+ data_len = recvfromto(sockfd, buf, len, flags,
+ src, &sizeof_src, dst, &sizeof_dst);
+#endif
+
+ /*
+ * FIXME: Check sizeof_src & sizeof_dst?
+ */
+
+ if (data_len < 0) return data_len;
+
+ if (dst_ipaddr->af == AF_INET) {
+ src_ipaddr->af = AF_INET;
+#ifdef WITH_UDPFROMTO
+ dst_ipaddr->ipaddr.ip4addr = salocal.sin_addr;
+#endif
+ src_ipaddr->ipaddr.ip4addr = saremote.sin_addr;
+ *src_port = ntohs(saremote.sin_port);
+ }
+#ifdef AF_INET6
+ else if (dst_ipaddr->af == AF_INET6) {
+#ifdef WITH_UDPFROMTO
+ src_ipaddr->af = AF_INET6;
+ return -1; /* should have been caught above */
+#endif
+ src_ipaddr->ipaddr.ip6addr = saremote6.sin6_addr;
+ *src_port = ntohs(saremote6.sin6_port);
+ }
+#endif
+ else return -1; /* should really have been caught above */
+
+ return data_len;
+}
+
+
/*
* Reply to the request. Also attach
* reply attribute value pairs and any user message provided.
const char *secret)
{
VALUE_PAIR *reply;
- struct sockaddr_in saremote;
- struct sockaddr_in *sa;
const char *what;
- uint8_t ip_buffer[16];
+ char ip_buffer[128];
/*
* Maybe it's a fake packet. Don't send it.
DEBUG("Sending %s of id %d to %s:%d\n",
what, packet->id,
- ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
+ inet_ntop(packet->dst_ipaddr.af,
+ &packet->dst_ipaddr.ipaddr,
+ ip_buffer, sizeof(ip_buffer)),
packet->dst_port);
total_length = AUTH_HDR_LEN;
*/
} else if (librad_debug) {
DEBUG("Re-sending %s of id %d to %s:%d\n", what, packet->id,
- ip_ntoa((char *)ip_buffer, packet->dst_ipaddr),
+ inet_ntop(packet->dst_ipaddr.af,
+ &packet->dst_ipaddr.ipaddr,
+ ip_buffer, sizeof(ip_buffer)),
packet->dst_port);
for (reply = packet->vps; reply; reply = reply->next) {
/*
* And send it on it's way.
*/
- sa = (struct sockaddr_in *) &saremote;
- memset ((char *) sa, '\0', sizeof (saremote));
- sa->sin_family = AF_INET;
- sa->sin_addr.s_addr = packet->dst_ipaddr;
- sa->sin_port = htons(packet->dst_port);
-#ifndef WITH_UDPFROMTO
- return sendto(packet->sockfd, packet->data, (int)packet->data_len, 0,
- (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
-#else
- {
- struct sockaddr_in salocal;
- memset ((char *) &salocal, '\0', sizeof (salocal));
- salocal.sin_family = AF_INET;
- salocal.sin_addr.s_addr = packet->src_ipaddr;
-
- return sendfromto(packet->sockfd, packet->data, (int)packet->data_len, 0,
- (struct sockaddr *)&salocal, sizeof(struct sockaddr_in),
- (struct sockaddr *)&saremote, sizeof(struct sockaddr_in));
- }
-#endif
+ return rad_sendto(packet->sockfd, packet->data, packet->data_len, 0,
+ &packet->src_ipaddr, &packet->dst_ipaddr,
+ packet->dst_port);
}
RADIUS_PACKET *rad_recv(int fd)
{
RADIUS_PACKET *packet;
- struct sockaddr_in saremote;
- int totallen;
- socklen_t salen;
uint8_t *attr;
+ int totallen;
int count;
radius_packet_t *hdr;
- char host_ipaddr[16];
+ char host_ipaddr[128];
int seen_eap;
uint8_t data[MAX_PACKET_LEN];
int num_attributes;
/*
* Allocate the new request data structure
*/
- if ((packet = malloc(sizeof(RADIUS_PACKET))) == NULL) {
+ if ((packet = malloc(sizeof(*packet))) == NULL) {
librad_log("out of memory");
return NULL;
}
- memset(packet, 0, sizeof(RADIUS_PACKET));
+ memset(packet, 0, sizeof(*packet));
- /*
- * Receive the packet.
- */
- salen = sizeof(saremote);
- memset(&saremote, 0, sizeof(saremote));
-#ifndef WITH_UDPFROMTO
- packet->data_len = recvfrom(fd, data, sizeof(data),
- 0, (struct sockaddr *)&saremote, &salen);
- packet->dst_ipaddr = htonl(INADDR_ANY); /* i.e. unknown */
-#else
- {
- socklen_t salen_local;
- struct sockaddr_in salocal;
- salen_local = sizeof(salocal);
- memset(&salocal, 0, sizeof(salocal));
- packet->data_len = recvfromto(fd, data, sizeof(data), 0,
- (struct sockaddr *)&saremote, &salen,
- (struct sockaddr *)&salocal, &salen_local);
- packet->dst_ipaddr = salocal.sin_addr.s_addr;
- }
-#endif
+ packet->data_len = rad_recvfrom(fd, data, sizeof(data), 0,
+ &packet->src_ipaddr, &packet->src_port,
+ &packet->dst_ipaddr, &packet->dst_port);
/*
* Check for socket errors.
* messages which may come later.
*/
packet->sockfd = fd;
- packet->src_ipaddr = saremote.sin_addr.s_addr;
- packet->src_port = ntohs(saremote.sin_port);
/*
* FIXME: Do even more filtering by only permitting
*/
if (packet->data_len < AUTH_HDR_LEN) {
librad_log("WARNING: Malformed RADIUS packet from host %s: too short (received %d < minimum %d)",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
packet->data_len, AUTH_HDR_LEN);
free(packet);
return NULL;
*/
if (packet->data_len > MAX_PACKET_LEN) {
librad_log("WARNING: Malformed RADIUS packet from host %s: too long (received %d > maximum %d)",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
packet->data_len, MAX_PACKET_LEN);
free(packet);
return NULL;
if ((hdr->code == 0) ||
(hdr->code >= 52)) {
librad_log("WARNING: Bad RADIUS packet from host %s: unknown packet code %d",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
hdr->code);
free(packet);
return NULL;
*/
if (totallen < AUTH_HDR_LEN) {
librad_log("WARNING: Malformed RADIUS packet from host %s: too short (length %d < minimum %d)",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
totallen, AUTH_HDR_LEN);
free(packet);
return NULL;
*/
if (totallen > MAX_PACKET_LEN) {
librad_log("WARNING: Malformed RADIUS packet from host %s: too long (length %d > maximum %d)",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
totallen, MAX_PACKET_LEN);
free(packet);
return NULL;
*/
if (packet->data_len < totallen) {
librad_log("WARNING: Malformed RADIUS packet from host %s: received %d octets, packet length says %d",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
packet->data_len, totallen);
free(packet);
return NULL;
*/
if (attr[0] == 0) {
librad_log("WARNING: Malformed RADIUS packet from host %s: Invalid attribute 0",
- ip_ntoa(host_ipaddr, packet->src_ipaddr));
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)));
free(packet);
return NULL;
}
*/
if (attr[1] < 2) {
librad_log("WARNING: Malformed RADIUS packet from host %s: attribute %d too short",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
attr[0]);
free(packet);
return NULL;
case PW_MESSAGE_AUTHENTICATOR:
if (attr[1] != 2 + AUTH_VECTOR_LEN) {
librad_log("WARNING: Malformed RADIUS packet from host %s: Message-Authenticator has invalid length %d",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
attr[1] - 2);
free(packet);
return NULL;
case PW_VENDOR_SPECIFIC:
if (attr[1] <= 6) {
librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has invalid length %d",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
attr[1] - 2);
free(packet);
return NULL;
if ((attr[2] == 0) && (attr[3] == 0) &&
(attr[4] == 0) && (attr[5] == 0)) {
librad_log("WARNING: Malformed RADIUS packet from host %s: Vendor-Specific has vendor ID of zero",
- ip_ntoa(host_ipaddr, packet->src_ipaddr));
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)));
free(packet);
return NULL;
}
*/
if (count != 0) {
librad_log("WARNING: Malformed RADIUS packet from host %s: packet attributes do NOT exactly fill the packet",
- ip_ntoa(host_ipaddr, packet->src_ipaddr));
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)));
free(packet);
return NULL;
}
if ((librad_max_attributes > 0) &&
(num_attributes > librad_max_attributes)) {
librad_log("WARNING: Possible DoS attack from host %s: Too many attributes in request (received %d, max %d are allowed).",
- ip_ntoa(host_ipaddr, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
num_attributes, librad_max_attributes);
free(packet);
return NULL;
(seen_eap != PW_MESSAGE_AUTHENTICATOR) &&
(seen_eap != (PW_EAP_MESSAGE | PW_MESSAGE_AUTHENTICATOR))) {
librad_log("WARNING: Insecure packet from host %s: Received EAP-Message with no Message-Authenticator.",
- ip_ntoa(host_ipaddr, packet->src_ipaddr));
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)));
free(packet);
return NULL;
}
if (librad_debug) {
if ((hdr->code > 0) && (hdr->code < 52)) {
- printf("rad_recv: %s packet from host %s:%d",
+ printf("rad_recv: %s packet from host %s port %d",
packet_codes[hdr->code],
- ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port);
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
+ packet->src_port);
} else {
- printf("rad_recv: Packet from host %s:%d code=%d",
- ip_ntoa(host_ipaddr, packet->src_ipaddr), packet->src_port,
+ printf("rad_recv: Packet from host %s port %d code=%d",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ host_ipaddr, sizeof(host_ipaddr)),
+ packet->src_port,
hdr->code);
}
printf(", id=%d, length=%d\n", hdr->id, totallen);
lrad_hmac_md5(packet->data, packet->data_len,
secret, strlen(secret), calc_auth_vector);
if (memcmp(calc_auth_vector, msg_auth_vector,
- sizeof(calc_auth_vector)) != 0) {
+ sizeof(calc_auth_vector)) != 0) {
char buffer[32];
librad_log("Received packet from %s with invalid Message-Authenticator! (Shared secret is incorrect.)",
- ip_ntoa(buffer, packet->src_ipaddr));
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)));
/* Silently drop packet, according to RFC 3579 */
return -2;
} /* else the message authenticator was good */
if (calc_acctdigest(packet, secret) > 1) {
char buffer[32];
librad_log("Received Accounting-Request packet "
- "from %s with invalid signature! (Shared secret is incorrect.)",
- ip_ntoa(buffer, packet->src_ipaddr));
+ "from %s with invalid signature! (Shared secret is incorrect.)",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)));
return -1;
}
break;
if (rcode > 1) {
char buffer[32];
librad_log("Received %s packet "
- "from %s:%d with invalid signature (err=%d)! (Shared secret is incorrect.)",
+ "from client %s port %d with invalid signature (err=%d)! (Shared secret is incorrect.)",
packet_codes[packet->code],
- ip_ntoa(buffer, packet->src_ipaddr),
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
packet->src_port,
rcode);
return -1;
if (pair->type != PW_TYPE_IPADDR) {
pair->lvalue = ntohl(lvalue);
} else {
+ lrad_ipaddr_t ipaddr;
+
/*
* It's an IP address, keep it in network
* byte order, and put the ASCII IP
* value.
*/
pair->lvalue = lvalue;
- ip_ntoa(pair->strvalue, pair->lvalue);
+ ipaddr.af = AF_INET;
+ ipaddr.ipaddr.ip4addr.s_addr = lvalue;
+ inet_ntop(AF_INET, &ipaddr.ipaddr,
+ pair->strvalue,
+ sizeof(pair->strvalue) - 1);
+
+
}
/*
uint32_t lrad_rand(void)
{
uint32_t answer;
- static int rand_index = 0;
/*
* Ensure that the pool is initialized.
/*
* Grab an entry from the pool.
*/
- answer = lrad_rand_pool.randrsl[rand_index];
+ answer = lrad_rand_pool.randrsl[lrad_rand_index];
/*
* Go to the next entry (wrapping around to zero).
*/
- rand_index++;
- rand_index &= 0xff;
+ lrad_rand_index++;
+ lrad_rand_index &= 0xff;
/*
* Every 256 numbers, churn the pool again.
*/
- if (rand_index == 0) {
+ if (lrad_rand_index == 0) {
lrad_isaac(&lrad_rand_pool);
}
return 0;
}
+
+/*
+ * Return an IPv6 address from
+ * one supplied in standard colon notation.
+ */
+static int ipv6_addr(const char *ip6_str, void *ip6addr)
+{
+#if defined(HAVE_INET_PTON) && defined(AF_INET6)
+ if (inet_pton(AF_INET6, ip6_str, (struct in6_addr *) ip6addr) != 1)
+ return -1;
+#else
+ /*
+ * Copied from the 'ifid' code in misc.c, with minor edits.
+ */
+ static const char xdigits[] = "0123456789abcdef";
+ const char *p, *pch;
+ int num_id = 0, val = 0, idx = 0;
+ uint8_t *addr = ip6addr;
+
+ for (p = ip6_str; ; ++p) {
+ if (*p == ':' || *p == '\0') {
+ if (num_id <= 0)
+ return -1;
+
+ /*
+ * Drop 'val' into the array.
+ */
+ addr[idx] = (val >> 8) & 0xff;
+ addr[idx + 1] = val & 0xff;
+ if (*p == '\0') {
+ /*
+ * Must have all entries before
+ * end of the string.
+ */
+ if (idx != 14)
+ return -1;
+ break;
+ }
+ val = 0;
+ num_id = 0;
+ if ((idx += 2) > 14)
+ return -1;
+ } else if ((pch = strchr(xdigits, tolower(*p))) != NULL) {
+ if (++num_id > 8) /* no more than 8 16-bit numbers */
+ return -1;
+ /*
+ * Dumb version of 'scanf'
+ */
+ val <<= 4;
+ val |= (pch - xdigits);
+ } else
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+
/*
* Parse a string value into a given VALUE_PAIR
*
#include "radiusd.h"
#include "modules.h"
+#include "rad_assert.h"
/*
* Return a short string showing the terminal server, port
port = pair->lvalue;
snprintf(buf, buflen, "from client %.128s port %u%s%.128s",
- client_name(request->packet->src_ipaddr), port,
+ client_name(&request->packet->src_ipaddr), port,
(do_cli ? " cli " : ""), (do_cli ? (char *)cli->strvalue : ""));
return buf;
* realm (sigh).
*/
realm = realm_find(tmp->strvalue, 0);
- if (realm && (realm->ipaddr == htonl(INADDR_NONE))) {
+ rad_assert(realm->ipaddr.af == AF_INET);
+ if (realm && (realm->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE))) {
DEBUG2(" WARNING: You set Proxy-To-Realm = %s, but it is a LOCAL realm! Cancelling invalid proxy request.", realm->realm);
} else {
/*
#include "radiusd.h"
#include "conffile.h"
+#include "rad_assert.h"
+
/*
* Free a RADCLIENT list.
c = rad_malloc(sizeof(RADCLIENT));
memset(c, 0, sizeof(*c));
- c->ipaddr = ip_getaddr(hostnm);
- if (c->ipaddr == INADDR_NONE) {
+ if (ip_hton(hostnm, AF_INET, &c->ipaddr) < 0) {
radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
file, lineno, hostnm);
return -1;
}
c->netmask = htonl(mask);
- c->ipaddr &= c->netmask; /* addr & mask are in network order */
+ c->ipaddr.ipaddr.ip4addr.s_addr &= c->netmask; /* addr & mask are in network order */
strcpy((char *)c->secret, secret);
strcpy(c->shortname, shortnm);
* the network as the long name.
*/
if ((~mask) == 0) {
- NAS *nas;
- ip_hostname(c->longname, sizeof(c->longname), c->ipaddr);
-
- /*
- * Pull information over from the NAS.
- */
- nas = nas_find(c->ipaddr);
- if (nas) {
- /*
- * No short name in the 'clients' file,
- * try copying one over from the
- * 'naslist' file.
- */
- if (c->shortname[0] == '\0') {
- strcpy(c->shortname, nas->shortname);
- }
-
- /*
- * Copy the nastype over, too.
- */
- strcpy(c->nastype, nas->nastype);
- }
+ ip_ntoh(&c->ipaddr, c->longname, sizeof(c->longname));
} else {
hostnm[strlen(hostnm)] = '/';
strNcpy(c->longname, hostnm, sizeof(c->longname));
/*
* Find a client in the RADCLIENTS list.
*/
-RADCLIENT *client_find(uint32_t ipaddr)
+RADCLIENT *client_find(const lrad_ipaddr_t *ipaddr)
{
RADCLIENT *cl;
RADCLIENT *match = NULL;
+ if (ipaddr->af != AF_INET) return NULL; /* FIXME! */
+
for (cl = mainconfig.clients; cl; cl = cl->next) {
- if ((ipaddr & cl->netmask) == cl->ipaddr) {
+ if (cl->ipaddr.af != ipaddr->af) continue;
+
+ if ((ipaddr->ipaddr.ip4addr.s_addr & cl->netmask) == cl->ipaddr.ipaddr.ip4addr.s_addr) {
if ((!match) ||
(ntohl(cl->netmask) > ntohl(match->netmask))) {
match = cl;
return match;
}
-/*
- * Walk the RADCLIENT list displaying the clients. This function
- * is for debugging purposes.
- */
-void client_walk(void)
-{
- RADCLIENT *cl;
- char host_ipaddr[16];
-
- for (cl = mainconfig.clients; cl != NULL; cl = cl->next)
- radlog(L_ERR, "client: client_walk: %s\n",
- ip_ntoa(host_ipaddr, cl->ipaddr));
-}
/*
* Find the name of a client (prefer short name).
*/
-const char *client_name(uint32_t ipaddr)
+const char *client_name(const lrad_ipaddr_t *ipaddr)
{
/* We don't call this unless we should know about the client. */
RADCLIENT *cl;
- char host_ipaddr[16];
+ char host_ipaddr[128];
+
+ if (ipaddr->af != AF_INET) rad_assert(0 == 1);
if ((cl = client_find(ipaddr)) != NULL) {
if (cl->shortname[0])
* If you see lots of these, then there's something wrong.
*/
radlog(L_ERR, "Trying to look up name of unknown client %s.\n",
- ip_ntoa(host_ipaddr, ipaddr));
+ ip_ntoh(ipaddr, host_ipaddr, sizeof(host_ipaddr)));
return "UNKNOWN-CLIENT";
}
#include <fcntl.h>
#include "radiusd.h"
-
-int maximum_proxies;
+#include "rad_assert.h"
/*
* Free a PAIR_LIST
* Local realms don't have an IP address,
* secret, or port.
*/
- c->acct_ipaddr = c->ipaddr = htonl(INADDR_NONE);
+ c->ipaddr.af = c->acct_ipaddr.af = AF_INET;
+ c->ipaddr.ipaddr.ip4addr.s_addr = c->acct_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
c->secret[0] = '\0';
c->auth_port = 0;
c->acct_port = 0;
} else {
RADCLIENT *client;
- c->ipaddr = ip_getaddr(hostnm);
- c->acct_ipaddr = c->ipaddr;
- if (c->ipaddr == htonl(INADDR_NONE)) {
+ if (ip_hton(hostnm, AF_INET, &c->ipaddr) < 0) {
radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
file, lineno, hostnm);
return -1;
}
+ c->acct_ipaddr = c->ipaddr;
/*
* Find the remote server in the "clients" list.
* If we can't find it, there's a big problem...
*/
- client = client_find(c->ipaddr);
+ client = client_find(&c->ipaddr);
if (client == NULL) {
radlog(L_CONS|L_ERR, "%s[%d]: Cannot find 'clients' file entry of remote server %s for realm \"%s\"",
file, lineno, hostnm, realm);
now = time(NULL);
for(cl = mainconfig.realms; cl; cl = cl->next) {
- if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
+ if (cl->ipaddr.af != AF_INET) rad_assert(0 == 1);
+
+ if ((ipaddr == cl->ipaddr.ipaddr.ip4addr.s_addr) &&
+ (port == cl->auth_port)) {
/*
* If we've received a reply (any reply)
* from the home server in the time spent
cl->wakeup = now + mainconfig.proxy_dead_time;
radlog(L_PROXY, "marking authentication server %s:%d for realm %s dead",
cl->server, port, cl->realm);
- } else if ((ipaddr == cl->acct_ipaddr) && (port == cl->acct_port)) {
+ } else if ((ipaddr == cl->acct_ipaddr.ipaddr.ip4addr.s_addr) &&
+ (port == cl->acct_port)) {
if (cl->last_reply > (( now - mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count ))) {
continue;
}
* doesn't matter if we think the realm is inactive.
*/
for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
- if ((ipaddr == cl->ipaddr) && (port == cl->auth_port)) {
+ if (cl->ipaddr.af != AF_INET) rad_assert(0 == 1);
+
+ if ((ipaddr == cl->ipaddr.ipaddr.ip4addr.s_addr) &&
+ (port == cl->auth_port)) {
return cl;
- } else if ((ipaddr == cl->acct_ipaddr) && (port == cl->acct_port)) {
+ } else if ((ipaddr == cl->acct_ipaddr.ipaddr.ip4addr.s_addr) &&
+ (port == cl->acct_port)) {
return cl;
}
}
int i, argc, left;
const char *from, *value;
char *to;
- char xlat_buffer[1024];
char myfmt[1024];
char argv_buf[1024];
char *argv[MAX_ARGV];
* No authhost means LOCAL.
*/
if ((authhost = cf_section_value_find(cs, "authhost")) == NULL) {
- c->ipaddr = htonl(INADDR_NONE);
+ c->ipaddr.af = AF_INET;
+ c->ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
c->auth_port = auth_port;
} else {
if ((s = strchr(authhost, ':')) != NULL) {
* Local realms don't have an IP address,
* secret, or port.
*/
- c->ipaddr = htonl(INADDR_NONE);
+ c->ipaddr.af = AF_INET;
+ c->ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
c->auth_port = auth_port;
} else {
- c->ipaddr = ip_getaddr(authhost);
- if (c->ipaddr == htonl(INADDR_NONE)) {
+ if (ip_hton(authhost, AF_INET,
+ &c->ipaddr) < 0) {
radlog(L_ERR, "%s[%d]: Host %s not found",
filename, cf_section_lineno(cs),
authhost);
* No accthost means LOCAL
*/
if ((accthost = cf_section_value_find(cs, "accthost")) == NULL) {
- c->acct_ipaddr = htonl(INADDR_NONE);
+ c->acct_ipaddr.af = AF_INET;
+ c->acct_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
c->acct_port = 0;
} else {
if ((s = strchr(accthost, ':')) != NULL) {
* Local realms don't have an IP address,
* secret, or port.
*/
- c->acct_ipaddr = htonl(INADDR_NONE);
+ c->acct_ipaddr.af = AF_INET;
+ c->acct_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
c->acct_port = 0;
} else {
- c->acct_ipaddr = ip_getaddr(accthost);
- if (c->acct_ipaddr == htonl(INADDR_NONE)) {
+ if (ip_hton(accthost, AF_INET,
+ &c->acct_ipaddr) < 0) {
radlog(L_ERR, "%s[%d]: Host %s not found",
filename, cf_section_lineno(cs),
accthost);
* servers is set to LOCALHOST, then don't require
* a shared secret.
*/
- if ((c->ipaddr != htonl(INADDR_NONE)) ||
- (c->acct_ipaddr != htonl(INADDR_NONE))) {
+ rad_assert(c->ipaddr.af == AF_INET);
+ rad_assert(c->acct_ipaddr.af == AF_INET);
+ if ((c->ipaddr.ipaddr.ip4addr.s_addr != htonl(INADDR_NONE)) ||
+ (c->acct_ipaddr.ipaddr.ip4addr.s_addr != htonl(INADDR_NONE))) {
if ((s = cf_section_value_find(cs, "secret")) == NULL ) {
radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s",
filename, cf_section_lineno(cs), name2);
* Check that we cannot load balance to LOCAL
* realms, as that doesn't make any sense.
*/
+ rad_assert(c->ipaddr.af == AF_INET);
+ rad_assert(c->acct_ipaddr.af == AF_INET);
if ((c->ldflag == 1) &&
- ((c->ipaddr == htonl(INADDR_NONE)) ||
- (c->acct_ipaddr == htonl(INADDR_NONE)))) {
+ ((c->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE)) ||
+ (c->acct_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE)))) {
radlog(L_ERR | L_CONS, "ERROR: Realm %s cannot be load balanced to LOCAL",
c->realm);
exit(1);
}
}
- if((password = cf_section_value_find(cs, "password")) != NULL) {
+ if ((password = cf_section_value_find(cs, "password")) != NULL) {
if(strlen(password) >= sizeof(c->password)) {
radlog(L_ERR, "%s[%d]: password of length %d longer than the allowed maximum of %d",
filename, cf_section_lineno(cs),
c->netmask = htonl(c->netmask);
}
- c->ipaddr = ip_getaddr(hostnm);
- if (c->ipaddr == INADDR_NONE) {
+ if (ip_hton(hostnm, AF_INET, &c->ipaddr) < 0) {
radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
filename, cf_section_lineno(cs), hostnm);
clients_free(list);
return NULL;
}
+ rad_assert(c->ipaddr.af == AF_INET);
/*
* Update the client name again...
*/
if (netmask) {
*netmask = '/';
- c->ipaddr &= c->netmask;
+ c->ipaddr.ipaddr.ip4addr.s_addr &= c->netmask;
strcpy(c->longname, hostnm);
} else {
- ip_hostname(c->longname, sizeof(c->longname),
- c->ipaddr);
+ ip_ntoh(&c->ipaddr, c->longname, sizeof(c->longname));
}
strcpy((char *)c->secret, secret);
return default_nas;
}
-
-
-/*
- * Find a nas by name.
- * If it can't be found, return the DEFAULT nas, instead.
- */
-NAS *nas_findbyname(char *nasname)
-{
- NAS *nas;
- NAS *default_nas;
-
- default_nas = NULL;
-
- for (nas = naslist; nas; nas = nas->next) {
- if (strcmp(nasname, nas->shortname) == 0 ||
- strcmp(nasname, nas->longname) == 0)
- return nas;
- if (strcmp(nas->longname, "DEFAULT") == 0)
- default_nas = nas;
- }
-
- return default_nas;
-}
-
-
-/*
- * Find the name of a nas (prefer short name).
- */
-const char *nas_name(uint32_t ipaddr)
-{
- NAS *nas;
-
- if ((nas = nas_find(ipaddr)) != NULL) {
- if (nas->shortname[0])
- return nas->shortname;
- else
- return nas->longname;
- }
-
- return "UNKNOWN-NAS";
-}
-
-/*
- * Find the name of a nas (prefer short name) based on the request.
- */
-const char *nas_name2(RADIUS_PACKET *packet)
-{
- NAS *nas;
-
- if ((nas = nas_find(packet->src_ipaddr)) != NULL) {
- if (nas->shortname[0])
- return nas->shortname;
- else
- return nas->longname;
- }
-
- return "UNKNOWN-NAS";
-}
-
-/*
- * Find the name of a nas (prefer short name) based on ipaddr,
- * store in passed buffer. If NAS is unknown, return dotted quad.
- */
-char * nas_name3(char *buf, size_t buflen, uint32_t ipaddr)
-{
- NAS *nas;
-
- if ((nas = nas_find(ipaddr)) != NULL) {
- if (nas->shortname[0]) {
- strNcpy(buf, (char *)nas->shortname, buflen);
- return buf;
- }
- else {
- strNcpy(buf, (char *)nas->longname, buflen);
- return buf;
- }
- }
- ip_ntoa(buf, ipaddr);
- return buf;
-}
-
-
pairadd(&request->packet->vps,
pairmake("Realm", realm->realm, T_OP_EQ));
+
+ if (realm->ipaddr.af != AF_INET) rad_assert(0 == 1);
+
/*
* Access-Request: look for LOCAL realm.
* Accounting-Request: look for LOCAL realm.
*/
if (((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
- (realm->ipaddr == htonl(INADDR_NONE))) ||
+ (realm->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE))) ||
((request->packet->code == PW_ACCOUNTING_REQUEST) &&
- (realm->acct_ipaddr == htonl(INADDR_NONE)))) {
+ (realm->acct_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE)))) {
DEBUG2(" WARNING: Cancelling proxy to Realm %s, as the realm is local.",
realm->realm);
return RLM_MODULE_NOOP;
break;
case PW_PACKET_DST_IP_ADDRESS:
- radclient->request->dst_ipaddr = vp->lvalue;
+ radclient->request->dst_ipaddr.af = AF_INET;
+ radclient->request->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->lvalue;
break;
case PW_DIGEST_REALM:
if (radclient->request->dst_port == 0) {
radclient->request->dst_port = server_port;
}
- if (radclient->request->dst_ipaddr == 0) {
+ if (radclient->request->dst_ipaddr.af == 0) {
if (server_ipaddr == INADDR_NONE) {
fprintf(stderr, "radclient: No server was given, but request %d in file %s did not contain Packet-Dst-IP-Address\n",
radclient->packet_number, radclient->filename);
return -1;
}
- radclient->request->dst_ipaddr = server_ipaddr;
+ radclient->request->dst_ipaddr.af = AF_INET;
+ radclient->request->dst_ipaddr.ipaddr.ip4addr.s_addr = server_ipaddr;
}
if (radclient->request->code == 0) {
*/
static int request_cmp(const void *one, const void *two)
{
+ int rcode;
const radclient_t *a = one;
const radclient_t *b = two;
if (a->request->id < b->request->id) return -1;
if (a->request->id > b->request->id) return +1;
- if (a->request->dst_ipaddr < b->request->dst_ipaddr) return -1;
- if (a->request->dst_ipaddr > b->request->dst_ipaddr) return +1;
+ if (a->request->dst_ipaddr.af < b->request->dst_ipaddr.af) return -1;
+ if (a->request->dst_ipaddr.af > b->request->dst_ipaddr.af) return +1;
+
+ if (a->request->dst_ipaddr.af != AF_INET) return -1; /* FIXME */
+
+ switch (a->request->dst_ipaddr.af) {
+ case AF_INET:
+ rcode = memcmp(&a->request->dst_ipaddr.ipaddr.ip4addr,
+ &b->request->dst_ipaddr.ipaddr.ip4addr,
+ sizeof(a->request->dst_ipaddr.ipaddr.ip4addr));
+ break;
+
+#ifdef AF_INET6
+ case AF_INET6:
+ rcode = memcmp(&a->request->dst_ipaddr.ipaddr.ip6addr,
+ &b->request->dst_ipaddr.ipaddr.ip6addr,
+ sizeof(a->request->dst_ipaddr.ipaddr.ip6addr));
+ break;
+#endif
+
+ default: /* FIXME: die! */
+ break;
+ }
+ if (rcode != 0) return rcode;
if (a->request->dst_port < b->request->dst_port) return -1;
if (a->request->dst_port > b->request->dst_port) return +1;
*/
reply = rad_recv(sockfd);
if (!reply) {
- fprintf(stderr, "radclient: received bad packet\n");
+ fprintf(stderr, "radclient: received bad packet: %s\n",
+ librad_errstr);
return -1; /* bad packet */
}
return 0;
}
+
static int getport(const char *name)
{
struct servent *svp;
int debug_flag = 0;
int log_auth_detail = FALSE;
int need_reload = FALSE;
-int sig_hup_block = FALSE;
const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
static time_t time_now;
/*
* Configuration items.
*/
-static int dont_fork = FALSE;
static time_t start_time = 0;
-static int spawn_flag = TRUE;
static int do_exit = 0;
/*
if (listener->type != RAD_LISTEN_AUTH) {
RAD_SNMP_INC(rad_snmp.auth.total_packets_dropped);
radlog(L_ERR, "Authentication-Request sent to a non-authentication port from "
- "client %s:%d - ID %d : IGNORED",
- client_name(packet->src_ipaddr),
+ "client %s port %d - ID %d : IGNORED",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return NULL;
}
if (listener->type != RAD_LISTEN_ACCT) {
RAD_SNMP_INC(rad_snmp.acct.total_packets_dropped);
radlog(L_ERR, "Accounting-Request packet sent to a non-accounting port from "
- "client %s:%d - ID %d : IGNORED",
- client_name(packet->src_ipaddr),
+ "client %s port %d - ID %d : IGNORED",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return NULL;
}
if (listener->type != RAD_LISTEN_PROXY) {
RAD_SNMP_INC(rad_snmp.auth.total_packets_dropped);
radlog(L_ERR, "Authentication reply packet code %d sent to a non-proxy reply port from "
- "client %s:%d - ID %d : IGNORED",
+ "client %s port %d - ID %d : IGNORED",
packet->code,
- client_name(packet->src_ipaddr),
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return NULL;
}
if (listener->type != RAD_LISTEN_PROXY) {
RAD_SNMP_INC(rad_snmp.acct.total_packets_dropped);
radlog(L_ERR, "Accounting reply packet code %d sent to a non-proxy reply port from "
- "client %s:%d - ID %d : IGNORED",
+ "client %s port %d - ID %d : IGNORED",
packet->code,
- client_name(packet->src_ipaddr),
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return 0;
}
/*
* We don't support this anymore.
*/
- radlog(L_ERR, "Deprecated password change request from client %s:%d - ID %d : IGNORED",
- client_name(packet->src_ipaddr),
+ radlog(L_ERR, "Deprecated password change request from client %s port %d - ID %d : IGNORED",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return NULL;
break;
radlog(L_ERR, "Unknown packet code %d from client %s:%d "
"- ID %d : IGNORED", packet->code,
- client_name(packet->src_ipaddr),
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return NULL;
break;
if (request_count > mainconfig.max_requests) {
radlog(L_ERR, "Dropping request (%d is too many): "
"from client %s:%d - ID: %d", request_count,
- client_name(packet->src_ipaddr),
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
radlog(L_INFO, "WARNING: Please check the radiusd.conf file.\n"
"\tThe value for 'max_requests' is probably set too low.\n");
DEBUG2("Ignoring duplicate packet from client "
"%s:%d - ID: %d, due to outstanding proxied request %d.",
- client_name(packet->src_ipaddr),
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id,
curreq->number);
return NULL;
* again.
*/
} else {
- char buffer[64];
+ char buffer[128];
- DEBUG2("Sending duplicate proxied request to home server %s:%d - ID: %d",
- ip_ntoa(buffer, curreq->proxy->dst_ipaddr),
- curreq->proxy->dst_port,
+ DEBUG2("Sending duplicate proxied request to home server %s port %d - ID: %d",
+ inet_ntop(curreq->proxy->dst_ipaddr.af,
+ &curreq->proxy->dst_ipaddr.ipaddr,
+ buffer, sizeof(buffer)), curreq->proxy->dst_port,
curreq->proxy->id);
}
* ignore the duplicate request.
*/
radlog(L_ERR, "Discarding duplicate request from "
- "client %s:%d - ID: %d due to unfinished request %d",
- client_name(packet->src_ipaddr),
+ "client %s port %d - ID: %d due to unfinished request %d",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id,
curreq->number);
return NULL;
RAD_SNMP_TYPE_INC(listener, total_packets_dropped);
radlog(L_ERR, "Dropping conflicting packet from "
- "client %s:%d - ID: %d due to unfinished request %d",
- client_name(packet->src_ipaddr),
+ "client %s port %d - ID: %d due to unfinished request %d",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id,
curreq->number);
return NULL;
*/
if (curreq->reply->code != 0) {
DEBUG2("Sending duplicate reply "
- "to client %s:%d - ID: %d",
- client_name(packet->src_ipaddr),
+ "to client %s port %d - ID: %d",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
rad_send(curreq->reply, curreq->packet, curreq->secret);
return NULL;
*
* This shouldn't happen, in general...
*/
- DEBUG2("Discarding duplicate request from client %s:%d - ID: %d",
- client_name(packet->src_ipaddr),
+ DEBUG2("Discarding duplicate request from client %s port %d - ID: %d",
+ client_name(&packet->src_ipaddr),
packet->src_port, packet->id);
return NULL;
} /* else the vectors were different, so we discard the old request. */
{
REALM *cl;
REQUEST *oldreq;
- char buffer[32];
+ char buffer[128];
/*
* Find the original request in the request list
* request, as there's no way for us to send it to a NAS.
*/
if (!oldreq) {
- radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s:%d - ID %d",
- ip_ntoa(buffer, packet->src_ipaddr),
+ radlog(L_PROXY, "No outstanding request was found for proxy reply from home server %s port %d - ID %d",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
packet->src_port, packet->id);
return NULL;
}
*/
if ((oldreq->reply->code != 0) ||
(oldreq->finished)) {
- radlog(L_ERR, "Reply from home server %s:%d - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
- ip_ntoa(buffer, packet->src_ipaddr),
+ radlog(L_ERR, "Reply from home server %s port %d - ID: %d arrived too late for request %d. Try increasing 'retry_delay' or 'max_request_time'",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
packet->src_port, packet->id,
oldreq->number);
return NULL;
if (memcmp(oldreq->proxy_reply->vector,
packet->vector,
sizeof(oldreq->proxy_reply->vector)) == 0) {
- radlog(L_ERR, "Discarding duplicate reply from home server %s:%d - ID: %d for request %d",
- ip_ntoa(buffer, packet->src_ipaddr),
+ radlog(L_ERR, "Discarding duplicate reply from home server %s port %d - ID: %d for request %d",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
packet->src_port, packet->id,
oldreq->number);
} else {
* as garbage.
*/
for (cl = mainconfig.realms; cl != NULL; cl = cl->next) {
- if (oldreq->proxy_reply->src_ipaddr == cl->ipaddr) {
+ if (oldreq->proxy_reply->src_ipaddr.af != cl->ipaddr.af) continue;
+ if (cl->ipaddr.af != AF_INET) continue; /* FIXME */
+
+ if (oldreq->proxy_reply->src_ipaddr.ipaddr.ip4addr.s_addr == cl->ipaddr.ipaddr.ip4addr.s_addr) {
if (oldreq->proxy_reply->src_port == cl->auth_port) {
cl->active = TRUE;
cl->last_reply = oldreq->timestamp;
int max_fd;
int status;
struct timeval *tv = NULL;
+ int spawn_flag = TRUE;
+ int dont_fork = FALSE;
+ int sig_hup_block = FALSE;
+
#ifdef HAVE_SIGACTION
struct sigaction act;
#endif
*/
sig_hup_block = TRUE;
if( (total_active_threads() == 0) ||
- (max_wait >= 5) ) {
- sig_hup_block = FALSE;
- break;
+ (max_wait >= 5) ) {
+ sig_hup_block = FALSE;
+ break;
}
sleep(1);
max_wait++;
* Receive the packet.
*/
if (sig_hup_block != FALSE) {
- continue;
+ continue;
}
packet = rad_recv(listener->fd);
if (packet == NULL) {
continue;
}
- /*
- * If the destination IP is unknown, check
- * if the listener has a known IP. If so,
- * use that.
- */
- if ((packet->dst_ipaddr == htonl(INADDR_ANY)) &&
- (packet->dst_ipaddr != listener->ipaddr)) {
- packet->dst_ipaddr = listener->ipaddr;
- }
-
- /*
- * Fill in the destination port.
- */
- packet->dst_port = listener->port;
-
RAD_SNMP_TYPE_INC(listener, total_requests);
/*
*/
if (listener->type != RAD_LISTEN_PROXY) {
RADCLIENT *cl;
- if ((cl = client_find(packet->src_ipaddr)) == NULL) {
+ if ((cl = client_find(&packet->src_ipaddr)) == NULL) {
RAD_SNMP_TYPE_INC(listener, total_invalid_requests);
- radlog(L_ERR, "Ignoring request from unknown client %s:%d",
- ip_ntoa((char *)buffer, packet->src_ipaddr),
+ radlog(L_ERR, "Ignoring request from unknown client %s port %d",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
packet->src_port);
rad_free(&packet);
continue;
secret = cl->secret;
} else { /* It came in on the proxy port */
REALM *rl;
- if ((rl = realm_findbyaddr(packet->src_ipaddr,packet->src_port)) == NULL) {
- radlog(L_ERR, "Ignoring request from unknown home server %s:%d",
- ip_ntoa((char *)buffer, packet->src_ipaddr),
- packet->src_port);
+
+ if (packet->src_ipaddr.af != AF_INET) {
+ rad_assert("PROXY IPV6 NOT SUPPORTED" == NULL);
+ }
+
+ if ((rl = realm_findbyaddr(packet->src_ipaddr.ipaddr.ip4addr.s_addr,
+ packet->src_port)) == NULL) {
+ radlog(L_ERR, "Ignoring request from unknown home server %s port %d",
+ inet_ntop(packet->src_ipaddr.af,
+ &packet->src_ipaddr.ipaddr,
+ buffer, sizeof(buffer)),
+ packet->src_port);
rad_free(&packet);
continue;
}
time_t retrans; /* when to retrans */
unsigned int retrans_num; /* Number of retransmissions */
time_t timestamp; /* orig recv time */
- uint32_t client_ip; /* Client-IP-Addr */
+
+ lrad_ipaddr_t client_ip; /* Client-IP-Addr */
RADIUS_PACKET *req; /* Radius request */
};
struct relay_misc {
int sockfd; /* Main socket descriptor */
- uint32_t dst_addr; /* Destination address */
+ lrad_ipaddr_t dst_addr; /* Destination address */
short dst_port; /* Destination port */
- uint32_t src_addr; /* Source address */
+ lrad_ipaddr_t src_addr; /* Source address */
char detail[1024]; /* Detail file */
char *secret; /* Secret */
char f_secret[256]; /* File secret */
skip++;
} else
if (!strcasecmp(key, "Client-IP-Address")) {
- r_req->client_ip = ip_getaddr(val);
+ ip_hton(val, AF_INET, &r_req->client_ip);
skip++;
} else
if (!strcasecmp(key, "Request-Authenticator"))
r_req->retrans = 0;
r_req->retrans_num = 0;
r_req->timestamp = 0;
- r_req->client_ip = 0;
+ memset(&r_req->client_ip, 0, sizeof(r_req->client_ip));
goto redo;
}
if (r_req->timestamp == 0)
r->retrans = 0;
r->retrans_num = 0;
r->timestamp = 0;
- r->client_ip = 0;
+ memset(&r->client_ip, 0, sizeof(r->client_ip));
break;
}
}
/*
* Prevent loops.
*/
- if (r->client_ip == r->req->dst_ipaddr) {
- fprintf(stdout, "do_send: Client-IP == Dest-IP. Droping packet.\n");
+ if ((r->client_ip.af == r->req->dst_ipaddr.af) &&
+ memcmp(&r->client_ip, &r->req->dst_ipaddr,
+ ((r->client_ip.af == AF_INET) ?
+ sizeof(r->client_ip.ipaddr.ip4addr) : /* FIXME: AF_INET6 */
+ sizeof(r->client_ip.ipaddr.ip6addr)))) {
+ fprintf(stdout, "do_send: Client-IP == Dest-IP. Dropping packet.\n");
fprintf(stdout, "do_send: Free RADIUS ID = %d\n",r->req->id);
id_map[r->req->id] = 0;
if (r->req->vps != NULL) {
r->retrans = 0;
r->retrans_num = 0;
r->timestamp = 0;
- r->client_ip = 0;
+ memset(&r->client_ip, 0, sizeof(r->client_ip));
return 0;
}
slots[i].retrans = 0;
slots[i].retrans_num = 0;
slots[i].timestamp = 0;
- slots[i].client_ip = 0;
+ memset(&slots[i].client_ip, 0, sizeof(slots[i].client_ip));
slots[i].req->sockfd = r_args->sockfd;
slots[i].req->dst_ipaddr = r_args->dst_addr;
slots[i].req->dst_port = r_args->dst_port;
progname = argv[0];
r_args.sockfd = -1;
- r_args.dst_addr = 0;
+ memset(&r_args.dst_addr, 0, sizeof(r_args.dst_addr));
r_args.dst_port = 0;
- r_args.src_addr = 0;
+ memset(&r_args.src_addr, 0, sizeof(r_args.src_addr));
memset((char *) r_args.detail, 0, 1024);
memset((char *) r_args.f_secret, 0, 256);
r_args.secret = NULL;
r_args.secret = r_args.f_secret;
break;
case 'i':
- if ((r_args.src_addr = ip_getaddr(optarg)) == 0) {
+ if (ip_hton(optarg, AF_INET, &r_args.src_addr) < 0) {
fprintf(stderr, "%s: unknown host %s\n",
progname, optarg);
exit(1);
} else {
r_args.dst_port = ntohs(r_args.dst_port);
}
- r_args.dst_addr = ip_getaddr(server_name);
- if (r_args.dst_addr == 0) {
+ if (ip_hton(server_name, AF_INET, &r_args.dst_addr) < 0) {
fprintf(stderr, "%s: unknown host\n",
server_name);
exit(1);
uint32_t myip = INADDR_ANY;
int log_stripped_names;
struct main_config_t mainconfig;
-void *rad_malloc(size_t size);
/*
* Possible states for request->state
*/
struct relay_request {
int state; /* REQ_* state */
- uint32_t client_ip; /* Client-IP-Addr */
+ lrad_ipaddr_t client_ip; /* Client-IP-Addr */
REQUEST *req; /* Radius request */
};
};
struct relay_misc {
- uint32_t dst_addr; /* Destination address */
+ lrad_ipaddr_t dst_addr; /* Destination address */
char detail[1024]; /* Detail file */
char *instance; /* SQL module instance (if needed) */
int sleep_time; /* Sleep time (ms) between calls to do_send */
/*
* Sleep a number of milli seconds
*/
-void inline ms_sleep(int msec)
+inline void ms_sleep(int msec)
{
if (msec){
struct timeval tv;
/*
* Does this (remotely) look like "Tue Jan 23 06:55:48 2001" ?
*/
-int inline isdateline(char *d)
+inline int isdateline(char *d)
{
int y;
skip++;
} else
if (!strcasecmp(key, "Client-IP-Address")) {
- r_req->client_ip = ip_getaddr(val);
+ ip_hton(val, AF_INET, &r_req->client_ip);
skip++;
} else
if (!strcasecmp(key, "Request-Authenticator"))
r_req->req->packet->vps = NULL;
}
r_req->req->timestamp = 0;
- r_req->client_ip = 0;
+ memset(&r_req->client_ip, 0, sizeof(r_req->client_ip));
goto redo;
}
if (r_req->req->timestamp == 0)
/*
* Prevent loops.
*/
- if (r->client_ip == r->req->packet->dst_ipaddr) {
- fprintf(stdout, "%s: do_send: Client-IP == Dest-IP. Droping packet.\n",progname);
+ if ((r->client_ip.af == r->req->packet->dst_ipaddr.af) &&
+ memcmp(&r->client_ip, &r->req->packet->dst_ipaddr,
+ ((r->client_ip.af == AF_INET) ?
+ sizeof(r->client_ip.ipaddr.ip4addr) : /* FIXME: AF_INET6 */
+ sizeof(r->client_ip.ipaddr.ip6addr)))) {
+ fprintf(stdout, "%s: do_send: Client-IP == Dest-IP. Dropping packet.\n",progname);
if (r->req->packet->vps != NULL) {
pairfree(&r->req->packet->vps);
r->req->packet->vps = NULL;
}
r->state = STATE_EMPTY;
r->req->timestamp = 0;
- r->client_ip = 0;
+ memset(&r->client_ip, 0, sizeof(r->client_ip));
return 0;
}
}
r->state = STATE_EMPTY;
r->req->timestamp = 0;
- r->client_ip = 0;
+ memset(&r->client_ip, 0, sizeof(r->client_ip));
return 1;
}
exit(1);
}
slots[i].state = STATE_EMPTY;
- slots[i].client_ip = 0;
+ memset(&slots[i].client_ip, 0, sizeof(slots[i].client_ip));
slots[i].req->packet->dst_ipaddr = r_args->dst_addr;
slots[i].req->packet->code = PW_ACCOUNTING_REQUEST;
slots[i].req->packet->vps = NULL;
}
server = cf_section_value_find(subcs, "server");
if (server){
- r->dst_addr = ip_getaddr(server);
- if (r->dst_addr == 0) {
+ if (ip_hton(server, AF_INET, &r->dst_addr) < 0) {
fprintf(stderr, "%s: Unknown destination host in 'server' directive.\n",progname);
return NULL;
}
* we look for a free Id from a sockfd, any sockfd.
*/
typedef struct proxy_id_t {
- uint32_t dst_ipaddr;
+ lrad_ipaddr_t dst_ipaddr;
int dst_port;
/*
*/
static int proxy_id_cmp(const void *one, const void *two)
{
+ int rcode;
const proxy_id_t *a = one;
const proxy_id_t *b = two;
* The following comparisons look weird, but it's
* the only way to make the comparisons work.
*/
- if (a->dst_ipaddr < b->dst_ipaddr) return -1;
- if (a->dst_ipaddr > b->dst_ipaddr) return +1;
-
if (a->dst_port < b->dst_port) return -1;
if (a->dst_port > b->dst_port) return +1;
+ if (a->dst_ipaddr.af < b->dst_ipaddr.af) return -1;
+ if (a->dst_ipaddr.af > b->dst_ipaddr.af) return +1;
+
+ switch (a->dst_ipaddr.af) {
+ case AF_INET:
+ rcode = memcmp(&a->dst_ipaddr.ipaddr.ip4addr,
+ &b->dst_ipaddr.ipaddr.ip4addr,
+ sizeof(a->dst_ipaddr.ipaddr.ip4addr));
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ rcode = memcmp(&a->dst_ipaddr.ipaddr.ip6addr,
+ &b->dst_ipaddr.ipaddr.ip6addr,
+ sizeof(a->dst_ipaddr.ipaddr.ip6addr));
+#endif
+ break;
+ default:
+ return -1; /* FIXME: die! */
+ break;
+ }
+ /*
+ * We could optimize this away, but the compiler should
+ * do that work for us, and this coding style helps us
+ * remember what to do if we add more checks later.
+ */
+ if (rcode != 0) return rcode;
+
/*
* Everything's equal. Say so.
*/
*/
static int request_cmp(const void *one, const void *two)
{
+ int rcode;
const REQUEST *a = one;
const REQUEST *b = two;
if (a->packet->code < b->packet->code) return -1;
if (a->packet->code > b->packet->code) return +1;
- if (a->packet->src_ipaddr < b->packet->src_ipaddr) return -1;
- if (a->packet->src_ipaddr > b->packet->src_ipaddr) return +1;
+ if (a->packet->src_ipaddr.af < b->packet->src_ipaddr.af) return -1;
+ if (a->packet->src_ipaddr.af > b->packet->src_ipaddr.af) return +1;
if (a->packet->src_port < b->packet->src_port) return -1;
if (a->packet->src_port > b->packet->src_port) return +1;
+ switch (a->packet->src_ipaddr.af) {
+ case AF_INET:
+ rcode = memcmp(&a->packet->src_ipaddr.ipaddr.ip4addr,
+ &b->packet->src_ipaddr.ipaddr.ip4addr,
+ sizeof(a->packet->src_ipaddr.ipaddr.ip4addr));
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ rcode = memcmp(&a->packet->src_ipaddr.ipaddr.ip6addr,
+ &b->packet->src_ipaddr.ipaddr.ip6addr,
+ sizeof(a->packet->src_ipaddr.ipaddr.ip6addr));
+#endif
+ break;
+ default:
+ return -1; /* FIXME: die! */
+ break;
+ }
+ if (rcode != 0) return rcode;
+
/*
* Hmm... we may be listening on IPADDR_ANY, in which case
* the destination IP is important, too.
*/
- if (a->packet->dst_ipaddr < b->packet->dst_ipaddr) return -1;
- if (a->packet->dst_ipaddr > b->packet->dst_ipaddr) return +1;
+ if (a->packet->dst_ipaddr.af < b->packet->dst_ipaddr.af) return -1;
+ if (a->packet->dst_ipaddr.af > b->packet->dst_ipaddr.af) return +1;
if (a->packet->dst_port < b->packet->dst_port) return -1;
if (a->packet->dst_port > b->packet->dst_port) return +1;
+ switch (a->packet->dst_ipaddr.af) {
+ case AF_INET:
+ rcode = memcmp(&a->packet->dst_ipaddr.ipaddr.ip4addr,
+ &b->packet->dst_ipaddr.ipaddr.ip4addr,
+ sizeof(a->packet->dst_ipaddr.ipaddr.ip4addr));
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ rcode = memcmp(&a->packet->dst_ipaddr.ipaddr.ip6addr,
+ &b->packet->dst_ipaddr.ipaddr.ip6addr,
+ sizeof(a->packet->dst_ipaddr.ipaddr.ip6addr));
+#endif
+ break;
+ default:
+ return -1; /* FIXME: die! */
+ break;
+ }
+ if (rcode != 0) return rcode;
+
/*
* Everything's equal. Say so.
*/
*/
static int proxy_cmp(const void *one, const void *two)
{
+ int rcode;
const REQUEST *a = one;
const REQUEST *b = two;
* We've got to check packet codes, too. But
* this should be done later, by someone else...
*/
-
- if (a->proxy->dst_ipaddr < b->proxy->dst_ipaddr) return -1;
- if (a->proxy->dst_ipaddr > b->proxy->dst_ipaddr) return +1;
+ if (a->proxy->dst_ipaddr.af < b->proxy->dst_ipaddr.af) return -1;
+ if (a->proxy->dst_ipaddr.af > b->proxy->dst_ipaddr.af) return +1;
if (a->proxy->dst_port < b->proxy->dst_port) return -1;
if (a->proxy->dst_port > b->proxy->dst_port) return +1;
+ switch (a->proxy->dst_ipaddr.af) {
+ case AF_INET:
+ rcode = memcmp(&a->packet->dst_ipaddr.ipaddr.ip4addr,
+ &b->proxy->dst_ipaddr.ipaddr.ip4addr,
+ sizeof(a->proxy->dst_ipaddr.ipaddr.ip4addr));
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ rcode = memcmp(&a->proxy->dst_ipaddr.ipaddr.ip6addr,
+ &b->proxy->dst_ipaddr.ipaddr.ip6addr,
+ sizeof(a->proxy->dst_ipaddr.ipaddr.ip6addr));
+#endif
+ break;
+ default:
+ return -1; /* FIXME: die! */
+ break;
+ }
+ if (rcode != 0) return rcode;
+
/*
* FIXME: Check the Proxy-State attribute, too.
* This will help cut down on duplicates.
entry = rbtree_finddata(proxy_id_tree, &myid);
if (entry) {
int i;
-
- DEBUG3(" proxy: de-allocating %08x:%d %d",
- entry->dst_ipaddr,
+ char buf[128];
+
+ DEBUG3(" proxy: de-allocating destination %s port %d - Id %d",
+ inet_ntop(entry->dst_ipaddr.af,
+ &entry->dst_ipaddr.ipaddr, buf, sizeof(buf)),
entry->dst_port,
request->proxy->id);
}
} /* else die horribly? */
} else {
+ char buf[128];
+
/*
* Hmm... not sure what to do here.
*/
- DEBUG3(" proxy: FAILED TO FIND %08x:%d %d",
- myid.dst_ipaddr,
+ DEBUG3(" proxy: FAILED TO FIND destination %s port %d - Id %d",
+ inet_ntop(myid.dst_ipaddr.af,
+ &myid.dst_ipaddr.ipaddr, buf, sizeof(buf)),
myid.dst_port,
request->proxy->id);
}
int i, found, proxy;
uint32_t mask;
proxy_id_t myid, *entry;
+ char buf[128];
myid.dst_ipaddr = request->proxy->dst_ipaddr;
myid.dst_port = request->proxy->dst_port;
entry->dst_port = request->proxy->dst_port;
entry->index = 0;
- DEBUG3(" proxy: creating %08x:%d",
- entry->dst_ipaddr,
+ DEBUG3(" proxy: creating destination %s port %d",
+ inet_ntop(entry->dst_ipaddr.af,
+ &entry->dst_ipaddr.ipaddr, buf, sizeof(buf)),
entry->dst_port);
/*
* If all Fd's are allocated, die.
*/
if (~mask == 0) {
- radlog(L_ERR|L_CONS, "ERROR: More than 8000 proxied requests outstanding for home server %08x:%d",
- ntohs(entry->dst_ipaddr), entry->dst_port);
+ radlog(L_ERR|L_CONS, "ERROR: More than 8000 proxied requests outstanding for destination %s port %d",
+ inet_ntop(entry->dst_ipaddr.af,
+ &entry->dst_ipaddr.ipaddr,
+ buf, sizeof(buf)),
+ entry->dst_port);
return 0;
}
rad_assert(proxy_fds[proxy] != -1);
request->proxy->sockfd = proxy_fds[proxy];
- DEBUG3(" proxy: allocating %08x:%d %d",
- entry->dst_ipaddr,
+ DEBUG3(" proxy: allocating destination %s port %d - Id %d",
+ inet_ntop(entry->dst_ipaddr.af,
+ &entry->dst_ipaddr.ipaddr, buf, sizeof(buf)),
entry->dst_port,
request->proxy->id);
if (request->proxy && !request->proxy_reply) {
rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
- radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s:%d",
+ radlog(L_ERR, "Rejecting request %d due to lack of any response from home server %s port %d",
request->number,
- client_name(request->packet->src_ipaddr),
+ client_name(&request->packet->src_ipaddr),
request->packet->src_port);
request_reject(request, REQUEST_FAIL_HOME_SERVER);
return RL_WALK_CONTINUE;
if (request->proxy_try_count == 0) {
rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
request_reject(request, REQUEST_FAIL_HOME_SERVER2);
- realm_disable(request->proxy->dst_ipaddr,request->proxy->dst_port);
+ rad_assert(request->proxy->dst_ipaddr.af == AF_INET);
+ realm_disable(request->proxy->dst_ipaddr.ipaddr.ip4addr.s_addr,
+ request->proxy->dst_port);
goto setup_timeout;
}
if (info->now > (request->timestamp + (mainconfig.proxy_retry_delay * mainconfig.proxy_retry_count))) {
rad_assert(request->child_pid == NO_SUCH_CHILD_PID);
request_reject(request, REQUEST_FAIL_HOME_SERVER3);
- realm_disable(request->proxy->dst_ipaddr,
+ rad_assert(request->proxy->dst_ipaddr.af == AF_INET);
+ realm_disable(request->proxy->dst_ipaddr.ipaddr.ip4addr.s_addr,
request->proxy->dst_port);
goto setup_timeout;
}
#include "radiusd.h"
#include "rad_assert.h"
-#include "modules.h"
/* End a session by faking a Stop packet to all accounting modules */
int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
char address[16];
char port[11];
RADCLIENT *cl;
+ lrad_ipaddr_t ipaddr;
+
+ ipaddr.af = AF_INET;
+ ipaddr.ipaddr.ip4addr.s_addr = nasaddr;
/*
* Find NAS type.
*/
- cl = client_find(nasaddr);
+ cl = client_find(&ipaddr);
if (!cl) {
/*
* Unknown NAS, so trusting radutmp.
* Fill in the fake request packet.
*/
request->packet->sockfd = -1;
- request->packet->src_ipaddr = htonl(INADDR_LOOPBACK);
- request->packet->dst_ipaddr = htonl(INADDR_LOOPBACK);
+ request->packet->src_ipaddr.af = AF_INET;
+ request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
+ request->packet->dst_ipaddr = request->packet->src_ipaddr;
request->packet->src_port = request->number >> 8;
request->packet->dst_port = 0;
*/
da = dict_attrbyname(fmt);
if (!da) {
- int index;
+ int count;
const char *p = strchr(fmt, '[');
char buffer[256];
* attributes of that name in the list.
*/
if ((p[1] == '#') && (p[2] == ']')) {
- index = 0;
+ count = 0;
for (vp = pairfind(vps, da->attr);
vp != NULL;
vp = pairfind(vp->next, da->attr)) {
- index++;
+ count++;
}
- snprintf(out, outlen, "%d", index);
+ snprintf(out, outlen, "%d", count);
return strlen(out);
}
for (vp = pairfind(vps, da->attr);
vp != NULL;
vp = pairfind(vp->next, da->attr)) {
- index = valuepair2str(out, outlen - 1, vp, da->type, func);
- rad_assert(index <= outlen);
- total += index + 1;
- outlen -= (index + 1);
- out += index;
+ count = valuepair2str(out, outlen - 1, vp, da->type, func);
+ rad_assert(count <= outlen);
+ total += count + 1;
+ outlen -= (count + 1);
+ out += count;
*(out++) = '\n';
return total;
}
- index = atoi(p + 1);
+ count = atoi(p + 1);
/*
* Skip the numbers.
for (vp = pairfind(vps, da->attr);
vp != NULL;
vp = pairfind(vp->next, da->attr)) {
- if (index == 0) break;
- index--;
+ if (count == 0) break;
+ count--;
}
/*
case PW_PACKET_SRC_IP_ADDRESS:
localvp.attribute = da->attr;
- localvp.lvalue = packet->src_ipaddr;
+ rad_assert(packet->src_ipaddr.af == AF_INET);
+ localvp.lvalue = packet->src_ipaddr.ipaddr.ip4addr.s_addr;
break;
case PW_PACKET_DST_IP_ADDRESS:
localvp.attribute = da->attr;
- localvp.lvalue = packet->dst_ipaddr;
+ rad_assert(packet->dst_ipaddr.af == AF_INET);
+ localvp.lvalue = packet->dst_ipaddr.ipaddr.ip4addr.s_addr;
break;
case PW_PACKET_SRC_PORT:
p++;
break;
case 'C': /* ClientName */
- strNcpy(q,client_name(request->packet->src_ipaddr),freespace-1);
+ strNcpy(q,client_name(&request->packet->src_ipaddr),freespace-1);
q += strlen(q);
p++;
break;
#include "radiusd.h"
#include "modules.h"
+#include "rad_assert.h"
+
#define DIRLEN 8192
static const char *packet_codes[] = {
proxy_realm = realm_find(pair->strvalue, TRUE);
if (proxy_realm) {
memset((char *) proxy_buffer, 0, 16);
- ip_ntoa(proxy_buffer, proxy_realm->acct_ipaddr);
+
+ rad_assert(proxy_realm->acct_ipaddr.af == AF_INET);
+
+ inet_ntop(proxy_realm->acct_ipaddr.af,
+ &proxy_realm->acct_ipaddr.ipaddr,
+ proxy_buffer, sizeof(proxy_buffer));
fprintf(outfp, "\tFreeradius-Proxied-To = %s\n",
proxy_buffer);
DEBUG("rlm_detail: Freeradius-Proxied-To set to %s",
* to it.
*/
realm = realm_find(proxy->strvalue, 0);
- if (realm && (realm->ipaddr == htonl(INADDR_NONE))) {
+ rad_assert(realm->ipaddr.af == AF_INET);
+ if (realm && (realm->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE))) {
proxy = NULL;
}
}
typedef struct _eap_handler {
struct _eap_handler *prev, *next;
uint8_t state[EAP_STATE_LEN];
- uint32_t src_ipaddr;
+ lrad_ipaddr_t src_ipaddr;
unsigned int eap_id;
unsigned int eap_type;
* which we did NOT send a request to,
* then complain.
*/
- if (((*rep)->src_ipaddr != req->dst_ipaddr) ||
+ if (((*rep)->src_ipaddr.af != req->dst_ipaddr.af) ||
+ (memcmp(&(*rep)->src_ipaddr.ipaddr,
+ &req->dst_ipaddr.ipaddr,
+ ((req->dst_ipaddr.af == AF_INET ? /* AF_INET6? */
+ sizeof(req->dst_ipaddr.ipaddr.ip4addr) : /* FIXME: AF_INET6 */
+ sizeof(req->dst_ipaddr.ipaddr.ip6addr)))) != 0) ||
((*rep)->src_port != req->dst_port)) {
- char src[64], dst[64];
+ char src[128], dst[128];
- ip_ntoa(src, (*rep)->src_ipaddr);
- ip_ntoa(dst, req->dst_ipaddr);
- fprintf(stderr, "radclient: ERROR: Sent request to host %s:%d, got response from host %s:%d\n!",
+ ip_ntoh(&(*rep)->src_ipaddr, src, sizeof(src));
+ ip_ntoh(&req->dst_ipaddr, dst, sizeof(dst));
+ fprintf(stderr, "radclient: ERROR: Sent request to host %s port %d, got response from host %s port %d\n!",
dst, req->dst_port,
src, (*rep)->src_port);
exit(1);
* Resolve hostname.
*/
req->dst_port = port;
- req->dst_ipaddr = ip_getaddr(argv[1]);
- if (req->dst_ipaddr == INADDR_NONE) {
+ if (ip_hton(argv[1], AF_INET, &req->dst_ipaddr) < 0) {
fprintf(stderr, "radclient: Failed to find IP address for host %s\n", argv[1]);
exit(1);
}
*/
static int eap_handler_cmp(const void *a, const void *b)
{
+ int rcode;
const EAP_HANDLER *one = a;
const EAP_HANDLER *two = b;
- if (one->src_ipaddr < two->src_ipaddr) return -1;
- if (one->src_ipaddr > two->src_ipaddr) return +1;
+
+ if (one->src_ipaddr.af < two->src_ipaddr.af) return -1;
+ if (one->src_ipaddr.af > two->src_ipaddr.af) return +1;
if (one->eap_id < two->eap_id) return -1;
if (one->eap_id > two->eap_id) return +1;
+ switch (one->src_ipaddr.af) {
+ case AF_INET:
+ rcode = memcmp(&one->src_ipaddr.ipaddr.ip4addr,
+ &two->src_ipaddr.ipaddr.ip4addr,
+ sizeof(one->src_ipaddr.ipaddr.ip4addr));
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ rcode = memcmp(&one->src_ipaddr.ipaddr.ip6addr,
+ &two->src_ipaddr.ipaddr.ip6addr,
+ sizeof(one->src_ipaddr.ipaddr.ip6addr));
+#endif
+ break;
+ default:
+ return -1; /* FIXME: die! */
+ break;
+ }
+ /*
+ * We could optimize this away, but the compiler should
+ * do that work for us, and this coding style helps us
+ * remember what to do if we add more checks later.
+ */
+ if (rcode != 0) return rcode;
+
return memcmp(one->state, two->state, sizeof(one->state));
}
#include "radiusd.h"
#include "modules.h"
+#include "rad_assert.h"
typedef struct rlm_preprocess_t {
char *huntgroup_file;
{
VALUE_PAIR *nas;
- nas = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS);
- if (!nas) {
- nas = paircreate(PW_NAS_IP_ADDRESS, PW_TYPE_IPADDR);
+ if (request->packet->src_ipaddr.af == AF_INET) {
+ nas = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS);
if (!nas) {
- radlog(L_ERR, "No memory");
- return -1;
+ nas = paircreate(PW_NAS_IP_ADDRESS, PW_TYPE_IPADDR);
+ if (!nas) {
+ radlog(L_ERR, "No memory");
+ return -1;
+ }
+
+ ip_ntoh(&request->packet->src_ipaddr,
+ nas->strvalue, sizeof(nas->strvalue));
+ nas->lvalue = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
+ pairadd(&request->packet->vps, nas);
}
- nas->lvalue = request->packet->src_ipaddr;
- ip_hostname(nas->strvalue, sizeof(nas->strvalue), nas->lvalue);
- pairadd(&request->packet->vps, nas);
- }
+ } else rad_assert(0 == 1); /* AF_INET6 */
/*
* Add in a Client-IP-Address, to tell the user
radlog(L_ERR, "No memory");
return -1;
}
- nas->lvalue = request->packet->src_ipaddr;
- ip_hostname(nas->strvalue, sizeof(nas->strvalue), nas->lvalue);
+ nas->lvalue = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
+ ip_ntoh(&request->packet->src_ipaddr,
+ nas->strvalue, sizeof(nas->strvalue));
pairadd(&request->packet->vps, nas);
return 0;
}
#include "radiusd.h"
#include "radutmp.h"
#include "modules.h"
+#include "rad_assert.h"
#define LOCK_LEN sizeof(struct radutmp)
NAS_PORT *cache;
int r;
+ if (request->packet->src_ipaddr.af != AF_INET) {
+ DEBUG("rlm_radutmp: IPv6 not supported!");
+ return RLM_MODULE_NOOP;
+ }
+
/*
* Which type is this.
*/
* originator's IP address.
*/
if (nas_address == 0) {
- nas_address = request->packet->src_ipaddr;
+ nas_address = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
ut.nas_address = nas_address;
- nas = client_name(nas_address); /* MUST be a valid client */
+ nas = client_name(&request->packet->src_ipaddr); /* MUST be a valid client */
- } else { /* might be a client, might not be. */
+ } else if (request->packet->src_ipaddr.ipaddr.ip4addr.s_addr == nas_address) { /* might be a client, might not be. */
RADCLIENT *cl;
-
+
/*
* Hack like 'client_name()', but with sane
* fall-back.
*/
- cl = client_find(nas_address);
- if (cl) {
- if (cl->shortname[0]) {
- nas = cl->shortname;
- } else {
- nas = cl->longname;
- }
+ cl = client_find(&request->packet->src_ipaddr);
+ if (!cl) rad_assert(0 == 1); /* WTF? */
+ if (cl->shortname[0]) {
+ nas = cl->shortname;
} else {
- /*
- * The NAS isn't a client, it's behind
- * a proxy server. In that case, just
- * get the IP address.
- */
- nas = ip_ntoa(ip_name, nas_address);
+ nas = cl->longname;
}
+ } else {
+ /*
+ * The NAS isn't a client, it's behind
+ * a proxy server. In that case, just
+ * get the IP address.
+ */
+ nas = ip_ntoa(ip_name, nas_address);
}
/*
struct realm_config_t *inst = instance;
+ if (request->packet->src_ipaddr.af != AF_INET) {
+ DEBUG2("rlm_realm: IPv6 is not supported!");
+ return 0;
+ }
+
/* initiate returnrealm */
*returnrealm = NULL;
* Perhaps accounting proxying was turned off.
*/
case PW_ACCOUNTING_REQUEST:
- if (realm->acct_ipaddr == htonl(INADDR_NONE)) {
+ if (realm->acct_ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE)) {
DEBUG2(" rlm_realm: Accounting realm is LOCAL.");
return 0;
}
* Perhaps authentication proxying was turned off.
*/
case PW_AUTHENTICATION_REQUEST:
- if (realm->ipaddr == htonl(INADDR_NONE)) {
+ if (realm->ipaddr.ipaddr.ip4addr.s_addr == htonl(INADDR_NONE)) {
DEBUG2(" rlm_realm: Authentication realm is LOCAL.");
return 0;
}
for (vp = request->packet->vps; vp; vp = vp->next) {
if (vp->attribute == PW_FREERADIUS_PROXIED_TO) {
if (request->packet->code == PW_AUTHENTICATION_REQUEST &&
- vp->lvalue == realm->ipaddr) {
+ vp->lvalue == realm->ipaddr.ipaddr.ip4addr.s_addr) {
DEBUG2(" rlm_realm: Request not proxied due to Freeradius-Proxied-To");
return 0;
}
if (request->packet->code == PW_ACCOUNTING_REQUEST &&
- vp->lvalue == realm->acct_ipaddr) {
+ vp->lvalue == realm->acct_ipaddr.ipaddr.ip4addr.s_addr) {
DEBUG2(" rlm_realm: Request not proxied due to Freeradius-Proxied-To");
return 0;
}
static int unix_accounting(void *instance, REQUEST *request)
{
VALUE_PAIR *vp;
- RADCLIENT *cl;
FILE *fp;
struct utmp ut;
time_t t;
return RLM_MODULE_NOOP;
}
+ if (request->packet->src_ipaddr.af != AF_INET) {
+ DEBUG2("rlm_unix: IPv6 is not supported!");
+ return RLM_MODULE_NOOP;
+ }
+
/*
* Which type is this.
*/
if (strncmp(ut.ut_name, "!root", sizeof(ut.ut_name)) == 0 || !port_seen)
return RLM_MODULE_NOOP;
+ s = "";
+
/*
* If we didn't find out the NAS address, use the
* originator's IP address.
*/
- if (nas_address == 0)
- nas_address = request->packet->src_ipaddr;
-
+ if (nas_address == 0) {
+ RADCLIENT *cl;
+ nas_address = request->packet->src_ipaddr.ipaddr.ip4addr.s_addr;
+
+ if ((cl = client_find(&request->packet->src_ipaddr)) != NULL)
+ s = cl->shortname;
+ }
+ if (!s || s[0] == 0) s = uue(&(nas_address));
+
#ifdef __linux__
/*
* Linux has a field for the client address.
* We use the tty field to store the terminal servers' port
* and address so that the tty field is unique.
*/
- s = "";
- if ((cl = client_find(nas_address)) != NULL)
- s = cl->shortname;
- if (s == NULL || s[0] == 0) s = uue(&(nas_address));
sprintf(buf, "%03d:%s", nas_port, s);
strNcpy(ut.ut_line, buf, sizeof(ut.ut_line));