some bugfixes
[svn/Prometheus-QoS/.git] / parsehosts.c
CommitLineData
8dcd2b4c 1/* Modified by: xChaos, 20131220 */\r
1c9cae56 2\r
3#include "cll1-0.6.2.h"\r
4#include "ipstruct.h"\r
5\r
6#define FIRSTGROUPID 1024\r
7#define FIRSTIPCLASS 2048\r
8\r
9/* globals declared in prometheus.c */\r
af37be1d 10extern struct IP *ips, *ip, *sharedip, *networks;\r
1c9cae56 11extern struct Group *groups, *group;\r
12extern struct Keyword *keyword, *defaultkeyword, *keywords;\r
bb5e7385 13extern struct Macro *macro, *macros;\r
1c9cae56 14extern int class_count;\r
15extern int ip_count;\r
16extern int found_lmsid;\r
17extern int free_min;\r
a1204fc9 18extern const int highest_priority;\r
f64d5431 19extern char *ip6prefix;\r
1c9cae56 20\r
2b460b72 21void update_network(char *look_for, struct IP* ip);\r
af37be1d 22/* implemented in networks.c */\r
23\r
a1204fc9 24/* This must be object oriented! This looks almost like constructor ;-) */\r
af37be1d 25void TheIP(char *ipaddr, int is_network)\r
a1204fc9 26{\r
27 create(ip,IP);\r
28 ip->name = "";\r
f19d3cd0 29 ip->addr = ipaddr;\r
a1204fc9 30 ip->sharing = NULL;\r
31 ip->prio = highest_priority+1;\r
32 ip->lmsid = -1;\r
33 ip->fixedprio = \\r
34 ip->mark = \\r
35 ip->min = \\r
36 ip->max = \\r
37 ip->desired = \\r
38 ip->credit = \\r
39 ip->upload = \\r
40 ip->proxy = \\r
41 ip->direct = \\r
42 ip->traffic = \\r
43 ip->pktsup = \\r
c38473c1 44 ip->pps_limit = \\r
a1204fc9 45 ip->pktsdown = 0;\r
46 ip->keyword = keywords;\r
0b9c3c19 47 ip->v6 = (strchr(ip->addr,':')!=NULL);\r
af37be1d 48 ip->mask = ((ip->v6)?64:32);\r
49 if(is_network)\r
50 {\r
51 push(ip, networks);\r
52 }\r
53 else\r
54 {\r
55 push(ip, ips); \r
56 }\r
14e28c6f 57 ip_count++;\r
a1204fc9 58}\r
1c9cae56 59\r
14e28c6f 60struct IP *lastIP6;\r
61\r
1c9cae56 62/* == This function strips extra characters after IPv4 address and stores it = */\r
af37be1d 63void parse_and_append_ip(char *str, struct IP *listhead)\r
1c9cae56 64{\r
f64d5431 65 char *ptr, *ipaddr, *ip6range = NULL, *ipname = NULL, *lmsid = NULL;\r
66\r
b1a5c883 67 if(ip6prefix) /* Try this only if IPv6 subsystem is active... */\r
f64d5431 68 {\r
69 ptr = strstr(str, "::");\r
70 if(ptr && ptr-str > 4)\r
71 {\r
72 ptr -= 4; \r
ca6f7e80 73 duplicate(ptr, ip6range);\r
f64d5431 74 ptr = strstr(ip6range, "::");\r
75 if(ptr)\r
76 {\r
77 *(ptr+2) = 0;\r
78 }\r
79 }\r
80 }\r
1c9cae56 81\r
82 ptr = strchr(str, '{');\r
83 if(ptr)\r
84 {\r
85 lmsid = ++ptr;\r
86 while(*ptr and *ptr != '}')\r
87 {\r
88 ptr++;\r
89 }\r
90 *ptr = 0;\r
91 }\r
92 \r
93 ptr = str;\r
94 while(*ptr and *ptr!=' ' and *ptr!=9)\r
95 {\r
96 ptr++;\r
97 }\r
98 \r
99 *ptr = 0;\r
100 ipaddr = str;\r
101 ptr++;\r
102 while(*ptr and (*ptr==' ' or *ptr==9))\r
103 {\r
104 ptr++;\r
105 }\r
106 ipname=ptr; \r
107 while(*ptr and *ptr!=' ' and *ptr!=9)\r
108 {\r
109 ptr++;\r
110 }\r
111 *ptr=0;\r
112\r
f64d5431 113 if(ip6range)\r
114 {\r
115 concatenate(ip6prefix,ip6range,ptr);\r
0b9c3c19 116 ip6range=ptr;\r
f64d5431 117 if_exists(ip, ips, eq(ip->addr,ip6range));\r
118 else\r
119 {\r
af37be1d 120 TheIP(ip6range, FALSE);\r
f64d5431 121 }\r
0b9c3c19 122 ip->name = ip6range;\r
14e28c6f 123 ip->keyword = defaultkeyword; /* settings for default keyword */\r
f64d5431 124 if(lmsid)\r
125 {\r
126 ip->lmsid = atoi(lmsid);\r
127 }\r
14e28c6f 128 lastIP6 = ip;\r
129 }\r
130 else\r
131 {\r
132 lastIP6 = NULL;\r
f64d5431 133 }\r
134\r
af37be1d 135 if_exists(ip, listhead, eq(ip->addr,ipaddr));\r
1c9cae56 136 else\r
137 {\r
af37be1d 138 TheIP(ipaddr, (listhead==networks));\r
1c9cae56 139 }\r
1c9cae56 140 ip->name = ipname;\r
141 if(lmsid)\r
142 {\r
143 ip->lmsid = atoi(lmsid);\r
144 found_lmsid = TRUE;\r
145 }\r
146}\r
147\r
148/* == This function parses hosts style main configuration file == */\r
149void parse_hosts(char *hosts)\r
150{\r
151 int groupidx = FIRSTGROUPID;\r
152 char *str, *ptr;\r
153 char *substring;\r
af37be1d 154 struct IP *network;\r
73cf6e9d 155 int pktratio;\r
1c9cae56 156\r
157 parse(hosts)\r
158 {\r
bb5e7385 159 str = _;\r
1c9cae56 160\r
161 if(*str < '0' or *str > '9')\r
162 {\r
163 /* any line starting with non-number is comment ...*/\r
164 continue;\r
165 }\r
8dcd2b4c 166\r
167 ptr = strchr(str,'\r'); /* fore unix-style end of line */\r
168 if(ptr)\r
169 {\r
170 *ptr = 0;\r
171 }\r
172 \r
bb5e7385 173 /* first, expand (rewrite) any predefined macros, if found*/\r
174 for_each(macro, macros)\r
175 {\r
176 substring = strstr(str, macro->rewrite_from);\r
8dcd2b4c 177 if(substring)\r
bb5e7385 178 {\r
179 int l1, l3;\r
180 *substring = 0;\r
181 substring += strlen(macro->rewrite_from);\r
182 l1 = strlen(str);\r
183 l3 = strlen(substring);\r
8dcd2b4c 184 string(ptr, l1 + strlen(macro->rewrite_to) + l3 + 1);\r
bb5e7385 185 strcpy(ptr, str);\r
186 strcat(ptr, macro->rewrite_to);\r
187 strcat(ptr, substring);\r
188 str = ptr;\r
8dcd2b4c 189 /* printf("REWRITE: %s -> %s\n",_,str); */\r
bb5e7385 190 }\r
191 }\r
192\r
1c9cae56 193 /* Does this IP share QoS class with some other ? */\r
194 substring = strstr(str, "sharing-");\r
195 if(substring)\r
196 { \r
197 substring += 8; /* "sharing-" */\r
af37be1d 198 parse_and_append_ip(str, ips);\r
1c9cae56 199 ip->sharing = substring;\r
200 ip->keyword = defaultkeyword; /* settings for default keyword */\r
14e28c6f 201 if(lastIP6)\r
202 {\r
203 lastIP6->sharing = substring;\r
b1a5c883 204 lastIP6 = NULL;\r
14e28c6f 205 }\r
1c9cae56 206 while(*substring and *substring != '\n')\r
207 {\r
208 substring++;\r
209 }\r
210 *substring = 0; \r
211 }\r
212 else\r
213 {\r
af37be1d 214 substring = strstr(str, "#255.");\r
215 if(substring and not strstr(str, "#255.255.255.255")) /* do not ping /32 ranges */\r
1c9cae56 216 {\r
af37be1d 217 /* netmask detected - save network*/\r
218 unsigned bit;\r
219 unsigned num, mask = 8;\r
220 substring += 5;\r
221 while(substring && *substring)\r
1c9cae56 222 {\r
af37be1d 223 ptr = substring;\r
224 substring = strchr(substring, '.');\r
225 if(substring)\r
226 {\r
227 *substring = 0;\r
228 substring += 1;\r
229 }\r
230 num = atoi(ptr);\r
231 for(bit = 1; bit <=128 ; bit<<=1)\r
1c9cae56 232 {\r
af37be1d 233 if(bit & num)\r
234 {\r
235 mask++;\r
236 }\r
1c9cae56 237 }\r
af37be1d 238 } \r
239 parse_and_append_ip(str, networks);\r
240 ip->mask = mask;\r
241 }\r
242 else\r
243 {\r
244 /*Do we have to create new QoS class for this IP ? */\r
245 if_exists(keyword,keywords,(substring=strstr(str,keyword->key)))\r
1c9cae56 246 {\r
af37be1d 247 parse_and_append_ip(str, ips);\r
248 if(lastIP6)\r
249 {\r
250 lastIP6->sharing = ip->name;\r
251 lastIP6 = NULL;\r
252 }\r
253 ip->keyword = keyword;\r
254 keyword->ip_count++;\r
255 ip->prio = keyword->default_prio;\r
256 substring += strlen(keyword->key)+1;\r
257 ptr = substring;\r
258 while(*ptr and *ptr != '-')\r
259 {\r
260 ptr++;\r
261 }\r
262 if(*ptr == '-')\r
263 {\r
264 *ptr=0;\r
265 ip->max = ip->desired = atoi(ptr+1);\r
266 }\r
9694a8ec 267\r
af37be1d 268 ip->min = atoi(substring);\r
269 if(ip->min <= 0)\r
270 {\r
271 printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kb/s\n",\r
272 str, free_min);\r
273 ip->min = free_min;\r
274 }\r
9694a8ec 275\r
af37be1d 276 if(ip->max <= ip->min)\r
277 {\r
278 ip->fixedprio = TRUE;\r
279 ip->max = ip->min + ip->keyword->reserve_min;\r
280 }\r
281 else \r
282 {\r
283 ip->max -= ip->keyword->reserve_max;\r
c38473c1 284 if(ip->max < ip->min)\r
af37be1d 285 {\r
c38473c1 286 ip->max = ip->min;\r
af37be1d 287 }\r
288 }\r
06733b88 289\r
73cf6e9d 290 /* avg MTU bytes * 8 >> 10 = in bits, max is in kb/s */\r
291 pktratio = (ip->keyword->allowed_avgmtu*8) >> 10;\r
292 if(pktratio > 0)\r
06733b88 293 {\r
73cf6e9d 294 ip->pps_limit = ip->max/pktratio;\r
295 if(ip->pps_limit > 10000) /* this limit seems to be hardcoded in iptables */\r
296 {\r
297 ip->pps_limit = 0; /* do not apply packet limits */\r
298 }\r
06733b88 299 }\r
300\r
301 ip->mark = FIRSTIPCLASS+1+class_count++; \r
2b460b72 302 update_network(ip->addr, ip);\r
af37be1d 303\r
304 if_exists(group,groups,(group->min == ip->min)) \r
305 { \r
306 group->count++; \r
307 group->desired += ip->min;\r
308 ip->group = group->id; \r
309 }\r
310 else\r
311 {\r
312 create(group,Group);\r
313 group->min = ip->min;\r
314 group->id = groupidx++;\r
315 ip->group = group->id;\r
316\r
317 if(group->min < 8) group->min = 8;\r
318 /* Warning - this is maybe because of primitive tc namespace, can be fixed */\r
319 /* it is because class IDs are derived from min. bandwidth. - xCh */\r
320 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;\r
321 \r
322 group->count = 1;\r
323 group->desired = ip->min; \r
324 insert(group, groups, desc_order_by,min);\r
325 }\r
326 }//endif keyword-\r
327 }//endif netmask\r
1c9cae56 328 }//endif sharing-\r
329 }\r
330 fail\r
331 {\r
332 perror(hosts);\r
333 exit(-1);\r
334 }\r
335 done; /* ugly macro end */\r
9694a8ec 336// TheIP("0.0.0.0", TRUE);\r
337// ip->name = "TOTAL";\r
338// ip->mask = 0;\r
8dcd2b4c 339}\r
This page took 1.541988 seconds and 4 git commands to generate.