Massive change to add foundational support for IPv6.
authoraland <aland>
Tue, 19 Apr 2005 21:21:12 +0000 (21:21 +0000)
committeraland <aland>
Tue, 19 Apr 2005 21:21:12 +0000 (21:21 +0000)
Most of the code is still hard-coded to use IPv6, and there are
assertions sprinkled throughout which will cause the server to
die if IPv6 is used.  However, the data structures are there,
and most of the support functions.  The next step is updating
the client code to look for IPv6 clients, and to listen on IPv6
sockets.

radiusd & radclient work.  radrelay & radsqlrelay build.

Most of the modules work.  rlm_sql doesn't (as yet).

29 files changed:
src/include/libradius.h
src/include/radiusd.h
src/lib/misc.c
src/lib/print.c
src/lib/radius.c
src/lib/valuepair.c
src/main/auth.c
src/main/client.c
src/main/files.c
src/main/mainconfig.c
src/main/nas.c
src/main/proxy.c
src/main/radclient.c
src/main/radiusd.c
src/main/radrelay.c
src/main/radsqlrelay.c
src/main/request_list.c
src/main/session.c
src/main/util.c
src/main/xlat.c
src/modules/rlm_detail/rlm_detail.c
src/modules/rlm_eap/eap.c
src/modules/rlm_eap/eap.h
src/modules/rlm_eap/radeapclient.c
src/modules/rlm_eap/rlm_eap.c
src/modules/rlm_preprocess/rlm_preprocess.c
src/modules/rlm_radutmp/rlm_radutmp.c
src/modules/rlm_realm/rlm_realm.c
src/modules/rlm_unix/rlm_unix.c

index b49c5cd..42a50a8 100644 (file)
 #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>
 
 /*
@@ -141,6 +153,18 @@ typedef struct value_pair {
        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
@@ -151,11 +175,11 @@ typedef struct value_pair {
  *     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];
@@ -291,8 +315,6 @@ const char *        ip_ntoa(char *, uint32_t);
 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);
@@ -301,6 +323,16 @@ int                rad_lockfd_nonblock(int fd, int lock_len);
 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 */
index 1459add..b8526da 100644 (file)
@@ -106,7 +106,7 @@ typedef struct auth_req {
 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];
@@ -129,8 +129,8 @@ typedef struct _realm {
        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;
@@ -344,9 +344,8 @@ void                rfc_clean(RADIUS_PACKET *packet);
 
 /* 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 */
@@ -362,10 +361,6 @@ int                read_realms_file(const char *file);
 /* 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);
index 417bf3d..d4c5425 100644 (file)
@@ -50,7 +50,7 @@ int           librad_debug = 0;
  *     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
@@ -148,6 +148,8 @@ uint32_t ip_getaddr(const char *host)
 
 /*
  *     Return an IP address in standard dot notation
+ *
+ *     FIXME: DELETE THIS
  */
 const char *ip_ntoa(char *buffer, uint32_t ipaddr)
 {
@@ -165,6 +167,8 @@ 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)
 {
@@ -346,87 +350,161 @@ uint8_t *ifid_aton(const char *ifid_str, uint8_t *ifid)
        }
        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";
 
index fda82df..82f77d4 100644 (file)
@@ -104,7 +104,7 @@ int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
 {
        DICT_VALUE  *v;
        char        buf[1024];
-       char        *a;
+       const char  *a;
        time_t      t;
        struct tm   s_tm;
 
@@ -179,20 +179,19 @@ int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
                        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:
@@ -200,7 +199,25 @@ int vp_prints_value(char * out, int outlen, VALUE_PAIR *vp, int delimitst)
                        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:
index f66b65d..5cbe931 100644 (file)
@@ -40,10 +40,6 @@ static const char rcsid[] = "$Id$";
 #include       "udpfromto.h"
 #endif
 
-#ifdef HAVE_NETINET_IN_H
-#include       <netinet/in.h>
-#endif
-
 #include       <sys/socket.h>
 
 #ifdef HAVE_ARPA_INET_H
@@ -86,6 +82,7 @@ typedef struct radius_packet_t {
 
 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[] = {
   "",
@@ -148,6 +145,208 @@ 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.
@@ -156,10 +355,8 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
             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.
@@ -236,7 +433,9 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
 
                  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;
@@ -638,7 +837,9 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
                   */
        } 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) {
@@ -650,26 +851,9 @@ int rad_send(RADIUS_PACKET *packet, const RADIUS_PACKET *original,
        /*
         *      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);
 }
 
 
@@ -767,13 +951,11 @@ static int calc_replydigest(RADIUS_PACKET *packet, RADIUS_PACKET *original,
 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;
@@ -781,33 +963,15 @@ RADIUS_PACKET *rad_recv(int fd)
        /*
         *      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.
@@ -823,8 +987,6 @@ RADIUS_PACKET *rad_recv(int fd)
         *      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
@@ -846,7 +1008,9 @@ RADIUS_PACKET *rad_recv(int fd)
         */
        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;
@@ -859,7 +1023,9 @@ RADIUS_PACKET *rad_recv(int fd)
         */
        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;
@@ -880,7 +1046,9 @@ RADIUS_PACKET *rad_recv(int fd)
        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;
@@ -899,7 +1067,9 @@ RADIUS_PACKET *rad_recv(int fd)
         */
        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;
@@ -914,7 +1084,9 @@ RADIUS_PACKET *rad_recv(int fd)
         */
        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;
@@ -930,7 +1102,9 @@ RADIUS_PACKET *rad_recv(int fd)
         */
        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;
@@ -974,7 +1148,9 @@ RADIUS_PACKET *rad_recv(int fd)
                 */
                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;
                }
@@ -985,7 +1161,9 @@ RADIUS_PACKET *rad_recv(int fd)
                 */
                        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;
@@ -1005,7 +1183,9 @@ RADIUS_PACKET *rad_recv(int fd)
                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;
@@ -1016,7 +1196,9 @@ RADIUS_PACKET *rad_recv(int fd)
                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;
@@ -1028,7 +1210,9 @@ RADIUS_PACKET *rad_recv(int fd)
                        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;
                        }
@@ -1059,7 +1243,9 @@ RADIUS_PACKET *rad_recv(int fd)
         */
        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;
        }
@@ -1072,7 +1258,9 @@ RADIUS_PACKET *rad_recv(int fd)
        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;
@@ -1090,19 +1278,27 @@ RADIUS_PACKET *rad_recv(int fd)
            (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);
@@ -1195,10 +1391,12 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        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 */
@@ -1234,8 +1432,10 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        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;
@@ -1248,9 +1448,11 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        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;
@@ -1565,6 +1767,8 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                        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
@@ -1572,7 +1776,13 @@ int rad_decode(RADIUS_PACKET *packet, RADIUS_PACKET *original,
                                  *  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);
+                               
+                               
                        }
 
                        /*
@@ -2092,7 +2302,6 @@ static void random_vector(uint8_t *vector)
 uint32_t lrad_rand(void)
 {
        uint32_t answer;
-       static int rand_index = 0;
 
        /*
         *      Ensure that the pool is initialized.
@@ -2106,18 +2315,18 @@ uint32_t lrad_rand(void)
        /*
         *      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);
        }
 
index 8479931..472aebd 100644 (file)
@@ -674,6 +674,64 @@ static int gettime(const char *valstr, time_t *lvalue)
        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
  *
index 882912d..e85d482 100644 (file)
@@ -37,6 +37,7 @@ static const char rcsid[] = "$Id$";
 
 #include "radiusd.h"
 #include "modules.h"
+#include "rad_assert.h"
 
 /*
  *     Return a short string showing the terminal server, port
@@ -53,7 +54,7 @@ char *auth_name(char *buf, size_t buflen, REQUEST *request, int do_cli) {
                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;
@@ -589,7 +590,8 @@ autz_redo:
                 *      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 {
                        /*
index 49157cf..0596699 100644 (file)
@@ -41,6 +41,8 @@ static const char rcsid[] = "$Id$";
 
 #include "radiusd.h"
 #include "conffile.h"
+#include "rad_assert.h"
+
 
 /*
  *     Free a RADCLIENT list.
@@ -172,14 +174,13 @@ int read_clients_file(const char *file)
                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);
@@ -189,28 +190,7 @@ int read_clients_file(const char *file)
                 *      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));
@@ -232,13 +212,17 @@ int read_clients_file(const char *file)
 /*
  *     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;
@@ -249,28 +233,17 @@ RADCLIENT *client_find(uint32_t ipaddr)
        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])
@@ -287,7 +260,7 @@ const char *client_name(uint32_t ipaddr)
         * 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";
 }
index 78b1b38..4257b1d 100644 (file)
@@ -40,8 +40,7 @@ static const char rcsid[] = "$Id$";
 #include <fcntl.h>
 
 #include "radiusd.h"
-
-int maximum_proxies;
+#include "rad_assert.h"
 
 /*
  *     Free a PAIR_LIST
@@ -379,27 +378,27 @@ int read_realms_file(const char *file)
                         *      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);
@@ -475,7 +474,10 @@ void realm_disable(uint32_t ipaddr, int port)
 
        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
@@ -490,7 +492,8 @@ void realm_disable(uint32_t ipaddr, int port)
                        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;
                        }
@@ -639,10 +642,14 @@ REALM *realm_findbyaddr(uint32_t ipaddr, int port)
         *      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;
                }
        }
index 5127977..790c267 100644 (file)
@@ -257,7 +257,6 @@ static int xlat_config(void *instance, REQUEST *request,
        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];
@@ -626,7 +625,8 @@ static int generate_realms(const char *filename)
                 *      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) {
@@ -640,11 +640,12 @@ static int generate_realms(const char *filename)
                                 *      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);
@@ -668,7 +669,8 @@ static int generate_realms(const char *filename)
                 *      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) {
@@ -682,11 +684,12 @@ static int generate_realms(const char *filename)
                                 *      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);
@@ -720,8 +723,10 @@ static int generate_realms(const char *filename)
                 *      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);
@@ -795,9 +800,11 @@ static int generate_realms(const char *filename)
                 *      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);
@@ -910,7 +917,7 @@ static RADCLIENT *generate_clients(const char *filename, CONF_SECTION *section)
                        }
                }
 
-               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),
@@ -951,24 +958,23 @@ static RADCLIENT *generate_clients(const char *filename, CONF_SECTION *section)
                        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);
index 024df2f..277ccb5 100644 (file)
@@ -167,85 +167,3 @@ NAS *nas_find(uint32_t ipaddr)
 
        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;
-}
-
-
index c308df1..71b64f4 100644 (file)
@@ -290,14 +290,17 @@ int proxy_send(REQUEST *request)
        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;
index 9e64e46..4121999 100644 (file)
@@ -250,7 +250,8 @@ static radclient_t *radclient_init(const char *filename)
                                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:
@@ -300,13 +301,14 @@ static int radclient_sane(radclient_t *radclient)
        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) {
@@ -374,6 +376,7 @@ static int filename_walk(void *context, void *data)
  */
 static int request_cmp(const void *one, const void *two)
 {
+       int rcode;
        const radclient_t *a = one;
        const radclient_t *b = two;
 
@@ -384,8 +387,30 @@ static int request_cmp(const void *one, const void *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;
@@ -620,7 +645,8 @@ static int recv_one_packet(int wait_time)
         */
        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 */
        }
 
@@ -679,6 +705,7 @@ static int recv_one_packet(int wait_time)
        return 0;
 }
 
+
 static int getport(const char *name)
 {
        struct  servent         *svp;
index 6f39c1b..7422049 100644 (file)
@@ -86,7 +86,6 @@ int log_stripped_names;
 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;
@@ -95,9 +94,7 @@ static pid_t radius_pid;
 /*
  *  Configuration items.
  */
-static int dont_fork = FALSE;
 static time_t start_time = 0;
-static int spawn_flag = TRUE;
 static int do_exit = 0;
 
 /*
@@ -135,8 +132,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                        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;
                        }
@@ -151,8 +148,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                        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;
                        }
@@ -170,9 +167,9 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                        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;
                        }
@@ -188,9 +185,9 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                        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;
                        }
@@ -211,8 +208,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                        /*
                         *  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;
@@ -222,7 +219,7 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
 
                        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;
@@ -258,7 +255,7 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                        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");
@@ -322,7 +319,7 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
 
                                        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;
@@ -338,11 +335,12 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                                         *      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);
                                }
@@ -357,8 +355,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                         *      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;
@@ -373,8 +371,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                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;
@@ -419,8 +417,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                 */
                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;
@@ -432,8 +430,8 @@ static RAD_REQUEST_FUNP packet_ok(RADIUS_PACKET *packet,
                 *
                 *      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. */
@@ -465,7 +463,7 @@ static REQUEST *proxy_ok(RADIUS_PACKET *packet)
 {
        REALM *cl;
        REQUEST *oldreq;
-       char buffer[32];
+       char buffer[128];
 
        /*
         *      Find the original request in the request list
@@ -478,8 +476,10 @@ static REQUEST *proxy_ok(RADIUS_PACKET *packet)
         *      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;
        }
@@ -493,8 +493,10 @@ static REQUEST *proxy_ok(RADIUS_PACKET *packet)
         */
        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;
@@ -508,8 +510,10 @@ static REQUEST *proxy_ok(RADIUS_PACKET *packet)
                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 {
@@ -556,7 +560,10 @@ static REQUEST *proxy_ok(RADIUS_PACKET *packet)
         *      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;
@@ -674,6 +681,10 @@ int main(int argc, char *argv[])
        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
@@ -1096,9 +1107,9 @@ int main(int argc, char *argv[])
                                 */
                                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++;
@@ -1200,7 +1211,7 @@ int main(int argc, char *argv[])
                         *  Receive the packet.
                         */
                        if (sig_hup_block != FALSE) {
-                         continue;
+                               continue;
                        }
                        packet = rad_recv(listener->fd);
                        if (packet == NULL) {
@@ -1208,21 +1219,6 @@ int main(int argc, char *argv[])
                                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);
 
                        /*
@@ -1241,11 +1237,13 @@ int main(int argc, char *argv[])
                         */
                        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;
@@ -1253,10 +1251,18 @@ int main(int argc, char *argv[])
                                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;
                                }
index bca125d..06070e2 100644 (file)
@@ -96,15 +96,16 @@ struct relay_request {
        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 */
@@ -288,7 +289,7 @@ redo:
                                        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"))
@@ -334,7 +335,7 @@ redo:
                        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)
@@ -424,7 +425,7 @@ int do_recv(struct relay_misc *r_args)
                        r->retrans = 0;
                        r->retrans_num = 0;
                        r->timestamp = 0;
-                       r->client_ip = 0;
+                       memset(&r->client_ip, 0, sizeof(r->client_ip));
                        break;
                }
        }
@@ -445,8 +446,12 @@ int do_send(struct relay_request *r, char *secret)
        /*
         *      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) {
@@ -461,7 +466,7 @@ int do_send(struct relay_request *r, char *secret)
                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;
        }
 
@@ -585,7 +590,7 @@ void loop(struct relay_misc *r_args)
                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;
@@ -837,9 +842,9 @@ int main(int argc, char **argv)
        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;
@@ -941,7 +946,7 @@ int main(int argc, char **argv)
                        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);
@@ -995,8 +1000,7 @@ int main(int argc, char **argv)
        } 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);
index 211e9cd..c3527e8 100644 (file)
@@ -71,7 +71,6 @@ const char *radacct_dir = NULL;
 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
@@ -97,7 +96,7 @@ void *rad_malloc(size_t size);
  */
 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 */
 };
 
@@ -108,7 +107,7 @@ struct sql_module {
 };
 
 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 */
@@ -153,7 +152,7 @@ void sigterm_handler(int sig)
 /*
  *     Sleep a number of milli seconds
  */
-void inline ms_sleep(int msec)
+inline void ms_sleep(int msec)
 {
        if (msec){
                struct timeval tv;
@@ -169,7 +168,7 @@ void inline ms_sleep(int msec)
 /*
  *     Does this (remotely) look like "Tue Jan 23 06:55:48 2001" ?
  */
-int inline isdateline(char *d)
+inline int isdateline(char *d)
 {
        int y;
 
@@ -263,7 +262,7 @@ redo:
                                        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"))
@@ -306,7 +305,7 @@ redo:
                                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)
@@ -345,15 +344,19 @@ int do_send(struct relay_request *r, struct sql_module *sql)
        /*
         *      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;
        }
 
@@ -383,7 +386,7 @@ int do_send(struct relay_request *r, struct sql_module *sql)
                }
                r->state = STATE_EMPTY;
                r->req->timestamp = 0;
-               r->client_ip = 0;
+               memset(&r->client_ip, 0, sizeof(r->client_ip));
 
                return 1;
        }
@@ -459,7 +462,7 @@ void loop(struct relay_misc *r_args)
                        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;
@@ -675,8 +678,7 @@ struct sql_module *init_sql(struct relay_misc *r)
        }
        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;
                }
index 448027c..22e1b93 100644 (file)
@@ -114,7 +114,7 @@ static int          proxy_fds[32];
  *     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;
 
        /*
@@ -131,6 +131,7 @@ typedef struct proxy_id_t {
  */
 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;
 
@@ -138,12 +139,36 @@ static int proxy_id_cmp(const void *one, const void *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.
         */
@@ -157,6 +182,7 @@ static int proxy_id_cmp(const void *one, const void *two)
  */
 static int request_cmp(const void *one, const void *two)
 {
+       int rcode;
        const REQUEST *a = one;
        const REQUEST *b = two;
 
@@ -179,22 +205,60 @@ static int request_cmp(const void *one, const void *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.
         */
@@ -207,6 +271,7 @@ static int request_cmp(const void *one, const void *two)
  */
 static int proxy_cmp(const void *one, const void *two)
 {
+       int rcode;
        const REQUEST *a = one;
        const REQUEST *b = two;
 
@@ -230,13 +295,31 @@ static int proxy_cmp(const void *one, const void *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.
@@ -385,9 +468,11 @@ static void rl_delete_proxy(REQUEST *request, rbnode_t *node)
        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);
 
@@ -410,11 +495,14 @@ static void rl_delete_proxy(REQUEST *request, rbnode_t *node)
                        }
                } /* 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);
        }
@@ -603,6 +691,7 @@ int rl_add_proxy(REQUEST *request)
        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;
@@ -629,8 +718,9 @@ int rl_add_proxy(REQUEST *request)
                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);
                
                /*
@@ -750,8 +840,11 @@ int rl_add_proxy(REQUEST *request)
                 *      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;
                }
                
@@ -833,8 +926,9 @@ int rl_add_proxy(REQUEST *request)
        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);
        
@@ -1116,9 +1210,9 @@ static int refresh_request(REQUEST *request, void *data)
                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;
@@ -1225,7 +1319,9 @@ static int refresh_request(REQUEST *request, void *data)
        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;
        }
 
@@ -1317,7 +1413,8 @@ 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;
                        }
index 1a7ac70..0b3908e 100644 (file)
@@ -41,7 +41,6 @@
 
 #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,
@@ -130,11 +129,15 @@ int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
        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.
index 1ef1ee7..5f4b030 100644 (file)
@@ -380,8 +380,9 @@ REQUEST *request_alloc_fake(REQUEST *oldreq)
    *   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;
 
index ab4f96a..ca13c3a 100644 (file)
@@ -142,7 +142,7 @@ static int xlat_packet(void *instance, REQUEST *request,
         */
        da = dict_attrbyname(fmt);
        if (!da) {
-               int index;
+               int count;
                const char *p = strchr(fmt, '[');
                char buffer[256];
 
@@ -159,14 +159,14 @@ static int xlat_packet(void *instance, REQUEST *request,
                 *      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);
                }
 
@@ -180,11 +180,11 @@ static int xlat_packet(void *instance, REQUEST *request,
                        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';
 
@@ -194,7 +194,7 @@ static int xlat_packet(void *instance, REQUEST *request,
                        return total;
                }
                
-               index = atoi(p + 1);
+               count = atoi(p + 1);
 
                /*
                 *      Skip the numbers.
@@ -212,8 +212,8 @@ static int xlat_packet(void *instance, REQUEST *request,
                for (vp = pairfind(vps, da->attr);
                     vp != NULL;
                     vp = pairfind(vp->next, da->attr)) {
-                       if (index == 0) break;
-                       index--;
+                       if (count == 0) break;
+                       count--;
                }
 
                /*
@@ -252,12 +252,14 @@ static int xlat_packet(void *instance, REQUEST *request,
 
                        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:
@@ -934,7 +936,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                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;
index 3dd843c..693099b 100644 (file)
@@ -35,6 +35,8 @@ static const char rcsid[] = "$Id$";
 
 #include       "radiusd.h"
 #include       "modules.h"
+#include       "rad_assert.h"
+
 #define        DIRLEN  8192
 
 static const char *packet_codes[] = {
@@ -306,7 +308,12 @@ static int do_detail(void *instance, REQUEST *request, RADIUS_PACKET *packet,
                        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",
index 1b8cf07..2a7a9ba 100644 (file)
@@ -630,7 +630,8 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                 *      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;
                }
        }
index 2c0c8f9..35b9688 100644 (file)
@@ -102,7 +102,7 @@ typedef enum operation_t {
 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;
 
index c716be3..e07780a 100644 (file)
@@ -158,13 +158,18 @@ static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
                         *      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);
@@ -1070,8 +1075,7 @@ int main(int argc, char **argv)
         *      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);
        }
index 8939261..08002ca 100644 (file)
@@ -80,15 +80,41 @@ static int eap_detach(void *instance)
  */
 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));
 }
 
index 4cdf16e..e4a093a 100644 (file)
@@ -37,6 +37,7 @@ static const char rcsid[] = "$Id$";
 
 #include       "radiusd.h"
 #include       "modules.h"
+#include       "rad_assert.h"
 
 typedef struct rlm_preprocess_t {
        char            *huntgroup_file;
@@ -393,17 +394,21 @@ static int add_nas_attr(REQUEST *request)
 {
        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
@@ -421,8 +426,9 @@ static int add_nas_attr(REQUEST *request)
          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;
 }
index 35c46f9..b990947 100644 (file)
@@ -38,6 +38,7 @@
 #include       "radiusd.h"
 #include       "radutmp.h"
 #include       "modules.h"
+#include       "rad_assert.h"
 
 #define LOCK_LEN sizeof(struct radutmp)
 
@@ -207,6 +208,11 @@ static int radutmp_accounting(void *instance, REQUEST *request)
        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.
         */
@@ -320,32 +326,31 @@ static int radutmp_accounting(void *instance, REQUEST *request)
         *      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);
        }
 
        /*
index 60e05a5..8c0fb89 100644 (file)
@@ -81,6 +81,11 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
 
         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;
 
@@ -234,7 +239,7 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
                 *      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;
                }
@@ -249,7 +254,7 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
                 *      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;
                }
@@ -269,12 +274,12 @@ static int check_for_realm(void *instance, REQUEST *request, REALM **returnrealm
        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;
                        }
index 0c42c6c..3a91632 100644 (file)
@@ -430,7 +430,6 @@ static char *uue(void *in)
 static int unix_accounting(void *instance, REQUEST *request)
 {
        VALUE_PAIR      *vp;
-       RADCLIENT       *cl;
        FILE            *fp;
        struct utmp     ut;
        time_t          t;
@@ -454,6 +453,11 @@ static int unix_accounting(void *instance, REQUEST *request)
                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.
         */
@@ -522,13 +526,21 @@ static int unix_accounting(void *instance, REQUEST *request)
        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.
@@ -539,10 +551,6 @@ static int unix_accounting(void *instance, REQUEST *request)
         *      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));