]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Add support for IPv6 in the aliasing of host names
authorFrédéric Marchal <fmarchal@users.sourceforge.net>
Sat, 25 Jun 2011 12:49:04 +0000 (12:49 +0000)
committerFrédéric Marchal <fmarchal@users.sourceforge.net>
Sat, 25 Jun 2011 12:49:04 +0000 (12:49 +0000)
IPv6 addresses can be defined in the hostalias file and accept the CIDR
notation.

Squares brackets are not required around the IP address in the hostalias
file but the log file should enclose the IPv6 address between square
brackets to avoid confusion with the port number.

url.c
util.c

diff --git a/url.c b/url.c
index c41c117402f19782f367d06718a35ec2b671a2b0..5545cccaca393c1ddb716dddacea8a193e790db4 100644 (file)
--- a/url.c
+++ b/url.c
@@ -347,7 +347,7 @@ static int Alias_StoreIpv6(unsigned short *ipv6,int nbits,char *next)
                debuga(_("Not enough memory to store the host name aliasing directives"));
                return(-1);
        }
-       memcpy(new_alias->Ip,ipv6,8);
+       memcpy(new_alias->Ip,ipv6,8*sizeof(unsigned short int));
        new_alias->NBits=nbits;
        if (Replace) {
                tmp=malloc(strlen(Replace)+2);
@@ -359,7 +359,7 @@ static int Alias_StoreIpv6(unsigned short *ipv6,int nbits,char *next)
                strcpy(tmp+1,Replace);
                new_alias->Alias=tmp;
        } else {
-               tmp=malloc(5*4+1);
+               tmp=malloc(5*8+5);
                if (!tmp) {
                        debuga(_("Not enough memory to store the host name aliasing directives"));
                        return(-1);
@@ -540,6 +540,32 @@ const char *alias_url_ipv4(const char *url,unsigned char *ipv4)
        return(url);
 }
 
+/*!
+Replace the IPv6 address by its alias if it is in our list.
+
+\param url The host name.
+\param ipv6 The address.
+
+\return The pointer to the host name or its alias.
+*/
+const char *alias_url_ipv6(const char *url,unsigned short int *ipv6)
+{
+       struct hostalias_ipv6 *alias;
+       int len;
+       int i;
+
+       for (alias=FirstAliasIpv6 ; alias ; alias=alias->Next) {
+               len=alias->NBits;
+               for (i=len/16-1 ; i>=0 && ipv6[i]==alias->Ip[i] ; i--);
+               if (i>=0) continue;
+               i=len/16;
+               if (i>=8 || len%16==0 || ((ipv6[i] ^ alias->Ip[i]) & (0xFFFF<<(len-i*16)))==0) {
+                       return(alias->Alias);
+               }
+       }
+       return(url);
+}
+
 /*!
 Get the part of the URL necessary to generate the report.
 
@@ -578,6 +604,9 @@ const char *process_url(char *url,bool full_url)
                } else if (type==2) {
                        if (FirstAliasIpv4)
                                start=alias_url_ipv4(start,ipv4);
+               } else if (type==3) {
+                       if (FirstAliasIpv6)
+                               start=alias_url_ipv6(start,ipv6);
                }
        }
        return(start);
diff --git a/util.c b/util.c
index 00d92064d6c8e8f76360cefeaac7a297c6eee667..6b52b03e8d19340ddda30711ae34df81c7a195e7 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1793,20 +1793,28 @@ int extract_address_mask(char *buf,char **text,unsigned char *ipv4,unsigned shor
        unsigned int value4, value6;
        unsigned short int addr[8];
        int addr_len;
+       int nibble6_len;
        int mask, max_mask;
        int pad_pos;
        int pad_len;
+       int bracket=false;
 
        // skip leading spaces and tabs
        while (*buf && (*buf==' ' || *buf=='\t')) buf++;
        
        // find out the nature of the pattern
        ip_size=0x60  | 0x04;
+       if (*buf=='[') {
+               bracket=true;
+               ip_size=0x60;
+               buf++;
+       }
        value4=0U;
        value6=0U;
        addr_len=0;
+       nibble6_len=0;
        pad_pos=-1;
-       for (i=0 ; (unsigned char)buf[i]>' ' && buf[i]!='/' && ip_size ; i++) {
+       for (i=0 ; (unsigned char)buf[i]>' ' && buf[i]!='/' && (!bracket || buf[i]!=']') && ip_size ; i++) {
                if (ip_size & 0x04) {
                        if (isdigit(buf[i])) {
                                value4=value4*10+(buf[i]-'0');
@@ -1821,14 +1829,22 @@ int extract_address_mask(char *buf,char **text,unsigned char *ipv4,unsigned shor
                if (ip_size & 0x60) {
                        if (isdigit(buf[i])) {
                                value6=(value6<<4)+(buf[i]-'0');
+                               nibble6_len++;
                                if (value6>0xFFFFU) ip_size&=~0x60;
                        } else if (toupper(buf[i])>='A' && toupper(buf[i])<='F') {
                                value6=(value6<<4)+(toupper(buf[i])-'A'+10);
+                               nibble6_len++;
                                if (value6>0xFFFFU) ip_size&=~0x60;
                        } else if (buf[i]==':' && addr_len<8) {
-                               addr[addr_len++]=(unsigned short)(value6 & 0xFFFFU);
+                               if (nibble6_len>0) {
+                                       addr[addr_len++]=(unsigned short)(value6 & 0xFFFFU);
+                                       nibble6_len=0;
+                               }
                                value6=0U;
-                               if (buf[i+1]==':') pad_pos=addr_len++;
+                               if (buf[i+1]==':') {
+                                       pad_pos=addr_len;
+                                       i++;
+                               }
                        } else {
                                ip_size&=~0x60;
                        }
@@ -1846,11 +1862,12 @@ int extract_address_mask(char *buf,char **text,unsigned char *ipv4,unsigned shor
                        ip_size&=~0x60;
                } else if (pad_pos>=0 && addr_len>=7)
                        ip_size&=~0x60;
-               else
+               else if (nibble6_len>0)
                        addr[addr_len++]=(unsigned short)(value6 & 0xFFFFU);
        }
        if (!ip_size) {
                *text=buf;
+               if (bracket) (*text)--;
                while ((unsigned char)buf[i]>' ') i++;
                *next=buf+i;
                return(1);
@@ -1863,6 +1880,7 @@ int extract_address_mask(char *buf,char **text,unsigned char *ipv4,unsigned shor
                if (mask<0 || mask>max_mask) mask=max_mask;
        } else
                mask=max_mask;
+       if (ip_size & 0x60 && bracket && buf[i]==']') i++;
        *next=buf+i;
        if (ip_size & 0x04) {
                if (nbits) *nbits=mask;
@@ -1879,7 +1897,7 @@ int extract_address_mask(char *buf,char **text,unsigned char *ipv4,unsigned shor
                while (i<pad_pos)
                        ipv6[j++]=(unsigned short int)addr[i++];
                pad_len=8-addr_len;
-               while (i<pad_pos+pad_len)
+               while (j<pad_pos+pad_len)
                        ipv6[j++]=0;
        }
        while (i<addr_len)