From: Frédéric Marchal Date: Sat, 25 Jun 2011 12:49:04 +0000 (+0000) Subject: Add support for IPv6 in the aliasing of host names X-Git-Tag: v2.3.2~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0ec4b48125e0e9282ca382870e1cc19674e15955;p=thirdparty%2Fsarg.git Add support for IPv6 in the aliasing of host names 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. --- diff --git a/url.c b/url.c index c41c117..5545ccc 100644 --- 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 00d9206..6b52b03 100644 --- 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