From 64b2d1255780905c78973df33145c93ee5613c9c Mon Sep 17 00:00:00 2001 From: xchaos Date: Thu, 14 Aug 2014 17:52:50 +0000 Subject: [PATCH] added IPv6 support for single /128 addresses of routers (based on IPv4 address) git-svn-id: https://dev.arachne.cz/repos/prometheus/trunk@246 251d49ef-1d17-4917-a970-b30cf55b089b --- cll1-0.6.2.h | 1 + htmlandlogs.c | 4 +-- ipstruct.h | 2 +- parsehosts.c | 79 ++++++++++++++++++++++++++++++++++++++++----------- prometheus.c | 39 ++++++++++++++++++------- 5 files changed, 94 insertions(+), 31 deletions(-) diff --git a/cll1-0.6.2.h b/cll1-0.6.2.h index d3456ce..6edbd83 100644 --- a/cll1-0.6.2.h +++ b/cll1-0.6.2.h @@ -120,6 +120,7 @@ #define option(STR,SETVAR) if(_){char *_K,*_V,*_O,*_Q; duplicate(_,_Q); _O=_Q; tr(_O,'\t',' '); prefix(_K,_O,' '); if(eq(STR,_K)) {skipspaces(_O); prefix(_V,_O,'#'); cutspaces(_V); SETVAR=_V; _=NULL;} else free(_Q);} #define ioption(STR,SETVAR) if(_){char *_K,*_V,*_O,*_Q; duplicate(_,_Q); _O=_Q; tr(_O,'\t',' '); prefix(_K,_O,' '); if(eq(STR,_K)) {skipspaces(_O); prefix(_V,_O,'#'); cutspaces(_V); SETVAR=atoi(_V); _=NULL;} free(_Q);} #define loption(STR,SETVAR) if(_){char *_K,*_V,*_O,*_Q; duplicate(_,_Q); _O=_Q; tr(_O,'\t',' '); prefix(_K,_O,' '); if(eq(STR,_K)) {skipspaces(_O); prefix(_V,_O,'#'); cutspaces(_V); SETVAR=atol(_V); _=NULL;} free(_Q);} +#define foption(STR,SETVAR) if(_){char *_K,*_V,*_O,*_Q; duplicate(_,_Q); _O=_Q; tr(_O,'\t',' '); prefix(_K,_O,' '); if(eq(STR,_K)) {skipspaces(_O); prefix(_V,_O,'#'); cutspaces(_V); SETVAR=atof(_V); _=NULL;} free(_Q);} #define lloption(STR,SETVAR) if(_){char *_K,*_V,*_O,*_Q; duplicate(_,_Q); _O=_Q; tr(_O,'\t',' '); prefix(_K,_O,' '); if(eq(STR,_K)) {skipspaces(_O); prefix(_V,_O,'#'); cutspaces(_V); SETVAR=atoll(_V); _=NULL;} free(_Q);} /* Dynamic list advanced I/O, updated 2003-05-30 by xCh. */ diff --git a/htmlandlogs.c b/htmlandlogs.c index 39a4286..3820ae4 100644 --- a/htmlandlogs.c +++ b/htmlandlogs.c @@ -232,8 +232,8 @@ $(\'#pktsup_\'+n).show();\ for_each(sharedip, ips) if(eq(ip->name, sharedip->sharing) && sharedip->v6) /* IPv6 only */ { - fprintf(f, "
%s/64\n", - log_url, sharedip->addr, sharedip->addr); + fprintf(f, "
%s/%d\n", + log_url, sharedip->addr, sharedip->addr, sharedip->mask); popup_button++; } diff --git a/ipstruct.h b/ipstruct.h index 797fb7b..6f0e569 100644 --- a/ipstruct.h +++ b/ipstruct.h @@ -42,7 +42,7 @@ struct Keyword { char *key; - int asymetry_ratio; /* ratio for ADSL-like upload */ + float asymetry_ratio; /* ratio for ADSL-like upload */ int asymetry_fixed; /* fixed treshold for ADSL-like upload */ int data_limit; /* hard shaping: apply magic_treshold if max*data_limit MB exceeded */ int data_prio; /* soft shaping (qos): reduce HTB prio if max*data_prio MB exceeded */ diff --git a/parsehosts.c b/parsehosts.c index ecb956a..27d378e 100644 --- a/parsehosts.c +++ b/parsehosts.c @@ -57,25 +57,37 @@ void TheIP(char *ipaddr, int is_network) ip_count++; } -struct IP *lastIP6; +struct IP *lastIP6range, *lastIP6uplink; /* == This function strips extra characters after IPv4 address and stores it = */ void parse_and_append_ip(char *str, struct IP *listhead) { - char *ptr, *ipaddr, *ip6range = NULL, *ipname = NULL, *lmsid = NULL; + char *ptr, *ipaddr, *nextip6, *ip6buf; + char *ip6uplink = NULL, *ip6range = NULL, *ipname = NULL, *lmsid = NULL; if(ip6prefix) /* Try this only if IPv6 subsystem is active... */ { ptr = strstr(str, "::"); - if(ptr && ptr-str > 4) + while(ptr && ptr-str > 4) { - ptr -= 4; - duplicate(ptr, ip6range); - ptr = strstr(ip6range, "::"); + nextip6 = strstr(ptr + 2, "::"); + ptr -= 4; + duplicate(ptr, ip6buf); + ptr = strstr(ip6buf, "::"); if(ptr) { - *(ptr+2) = 0; + if(*(ptr+2) == '+') + { + *(ptr+3) = 0; /* ends with ::+ */ + ip6uplink = ip6buf; + } + else + { + *(ptr+2) = 0; /* ends with :: */ + ip6range = ip6buf; + } } + ptr = nextip6; } } @@ -103,7 +115,7 @@ void parse_and_append_ip(char *str, struct IP *listhead) { ptr++; } - ipname=ptr; + ipname = ptr; while(*ptr and *ptr!=' ' and *ptr!=9) { ptr++; @@ -125,11 +137,34 @@ void parse_and_append_ip(char *str, struct IP *listhead) { ip->lmsid = atoi(lmsid); } - lastIP6 = ip; + lastIP6range = ip; + } + else + { + lastIP6range = NULL; + } + + /* it is ugly to copy+paste and search+replace, but... */ + if(ip6uplink) + { + concatenate(ip6prefix,ip6uplink,ptr); + ip6uplink=ptr; + if_exists(ip, ips, eq(ip->addr,ip6uplink)); + else + { + TheIP(ip6uplink, FALSE); + } + ip->name = ip6uplink; + ip->keyword = defaultkeyword; /* settings for default keyword */ + if(lmsid) + { + ip->lmsid = atoi(lmsid); + } + lastIP6uplink = ip; } else { - lastIP6 = NULL; + lastIP6uplink = NULL; } if_exists(ip, listhead, eq(ip->addr,ipaddr)); @@ -198,10 +233,15 @@ void parse_hosts(char *hosts) parse_and_append_ip(str, ips); ip->sharing = substring; ip->keyword = defaultkeyword; /* settings for default keyword */ - if(lastIP6) + if(lastIP6range) + { + lastIP6range->sharing = substring; + lastIP6range = NULL; + } + if(lastIP6uplink) { - lastIP6->sharing = substring; - lastIP6 = NULL; + lastIP6uplink->sharing = substring; + lastIP6uplink = NULL; } while(*substring and *substring != '\n') { @@ -212,7 +252,7 @@ void parse_hosts(char *hosts) else { substring = strstr(str, "#255."); - if(substring and not strstr(str, "#255.255.255.255")) /* do not ping /32 ranges */ + if(substring and not strstr(str, "#255.255.255.255")) /* do not ping /32 uplinks */ { /* netmask detected - save network*/ unsigned bit; @@ -245,10 +285,15 @@ void parse_hosts(char *hosts) if_exists(keyword,keywords,(substring=strstr(str,keyword->key))) { parse_and_append_ip(str, ips); - if(lastIP6) + if(lastIP6range) + { + lastIP6range->sharing = ip->name; + lastIP6range = NULL; + } + if(lastIP6uplink) { - lastIP6->sharing = ip->name; - lastIP6 = NULL; + lastIP6uplink->sharing = ip->name; + lastIP6uplink = NULL; } ip->keyword = keyword; keyword->ip_count++; diff --git a/prometheus.c b/prometheus.c index 49fa5e2..03b7554 100644 --- a/prometheus.c +++ b/prometheus.c @@ -258,7 +258,7 @@ void get_config(char *config_filename) { char *tmptr=_; /* <---- l+1 ----> */ _+=l+1; /* via-prometheus-asymetry-ratio, etc. */ - ioption("asymetry-ratio", keyword->asymetry_ratio); + foption("asymetry-ratio", keyword->asymetry_ratio); ioption("asymetry-treshold", keyword->asymetry_fixed); ioption("magic-relative-limit", keyword->data_limit); ioption("magic-relative-prio", keyword->data_prio); @@ -503,7 +503,7 @@ program printf("\n\ Prometheus QoS - \"fair-per-IP\" Quality of Service setup utility.\n\ -Version %s - Copyright (C)2005-2013 Michael Polak, Arachne Labs\n\ +Version %s - Copyright (C)2005-2014 Michael Polak, Arachne Labs\n\ iptables-restore & burst tunning & classify modification by Ludva\n\ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); @@ -620,6 +620,23 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); ip->mark = sharedip->mark; ip->lmsid = sharedip->lmsid; ip->pps_limit = sharedip->pps_limit; /* no other way to do this */ + + /* Ugly hack: append IPv4 addresses of sharedip to IPv6 uplinks */ + ptr = strchr(ip->addr, '+'); + if(ptr && ptr-ip->addr > 1 && !sharedip->v6) + { + *(--ptr) = 0; + concatenate(ip->addr, sharedip->addr, ptr); + ip->name = ip->addr = ptr; + ptr = strchr(ip->addr, '.'); + while(ptr && *ptr) + { + *ptr = ':'; + ptr = strchr(ptr, '.'); + } + ip->mask += 64; + } + break; } if(not sharedip) @@ -1183,7 +1200,7 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); /* -------------------------------------------------------- mark download */ sprintf(str, "-A %s -d %s/%d -o %s -j %s%d", - chain_postrouting, ip->addr, 32*(1+ip->v6), + chain_postrouting, ip->addr, ip->mask, lan, mark_iptables, ip->mark); iptables_save_line(str, ip->v6); @@ -1192,40 +1209,40 @@ Credit: CZFree.Net, Martin Devera, Netdave, Aquarius, Gandalf\n\n",version); { sprintf(str, "-A %s -s %s -p tcp --sport %d -d %s/%d -o %s -j %s%d", chain_postrouting, proxy_ip, proxy_port, ip->addr, - 32*(1+ip->v6), lan, mark_iptables, ip->mark); + ip->mask, lan, mark_iptables, ip->mark); iptables_save_line(str, ip->v6); } */ sprintf(str, "-A %s -d %s/%d -o %s %s-j ACCEPT", - chain_postrouting, ip->addr, 32*(1+ip->v6), lan, limit_pkts); + chain_postrouting, ip->addr, ip->mask, lan, limit_pkts); iptables_save_line(str, ip->v6); /* classify overlimit packets to separate overlimit class */ sprintf(str, "-A %s -d %s/%d -o %s -j %s%d", - chain_postrouting, ip->addr, 32*(1+ip->v6), + chain_postrouting, ip->addr, ip->mask, lan, mark_iptables, OVERLIMIT_CLASS); iptables_save_line(str, ip->v6); sprintf(str, "-A %s -d %s/%d -o %s -j ACCEPT", - chain_postrouting, ip->addr, 32*(1+ip->v6), lan); + chain_postrouting, ip->addr, ip->mask, lan); iptables_save_line(str, ip->v6); /* -------------------------------------------------------- mark upload */ sprintf(str, "-A %s -s %s/%d -o %s -j %s%d", - chain_forward, ip->addr, 32*(1+ip->v6), wan, mark_iptables, ip->mark); + chain_forward, ip->addr, ip->mask, wan, mark_iptables, ip->mark); iptables_save_line(str, ip->v6); sprintf(str, "-A %s -s %s/%d -o %s %s-j ACCEPT", - chain_forward, ip->addr, 32*(1+ip->v6), wan, limit_pkts); + chain_forward, ip->addr, ip->mask, wan, limit_pkts); iptables_save_line(str, ip->v6); /* classify overlimit packets to separate overlimit class */ sprintf(str, "-A %s -s %s/%d -o %s -j %s%d", - chain_forward, ip->addr, 32*(1+ip->v6), wan, mark_iptables, OVERLIMIT_CLASS); + chain_forward, ip->addr, ip->mask, wan, mark_iptables, OVERLIMIT_CLASS); iptables_save_line(str, ip->v6); sprintf(str, "-A %s -s %s/%d -o %s -j ACCEPT", - chain_forward, ip->addr, 32*(1+ip->v6), wan); + chain_forward, ip->addr, ip->mask, wan); iptables_save_line(str, ip->v6); if(ip->min) -- 2.30.2