-b Boot mode
[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
296d0585 16extern int found_code;\r
1c9cae56 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
bf59a20b 28 ip->name = "";\r
29 ip->addr = ipaddr;\r
30 ip->sharing = NULL;\r
31 ip->prio = highest_priority+1;\r
296d0585 32 ip->code = "-----";\r
bf59a20b 33 ip->fixedprio = \\r
34 ip->aggregated = \\r
35 ip->mark = \\r
36 ip->min = \\r
37 ip->max = \\r
38 ip->desired = \\r
39 ip->credit = \\r
40 ip->upload = \\r
41 ip->proxy = \\r
42 ip->direct = \\r
43 ip->traffic = \\r
44 ip->traffic_down = \\r
45 ip->traffic_up = \\r
46 ip->pktsup = \\r
47 ip->pps_limit = \\r
48 ip->pktsdown = 0;\r
49 ip->keyword = keywords;\r
50 ip->v6 = (strchr(ip->addr,':')!=NULL);\r
51 ip->mask = ((ip->v6)?64:32);\r
af37be1d 52 if(is_network)\r
53 {\r
54 push(ip, networks);\r
55 }\r
56 else\r
57 {\r
58 push(ip, ips); \r
59 }\r
47b5fd64 60#ifdef MONITORINGTRHU_CTU\r
61 ip->technology_str = NULL;\r
62 ip->ruian_id_str = NULL;\r
63#endif\r
64\r
14e28c6f 65 ip_count++;\r
a1204fc9 66}\r
1c9cae56 67\r
47b5fd64 68#ifdef MONITORINGTRHU_CTU\r
69struct Technology *technologies = NULL, *technology = NULL;\r
70#endif\r
64b2d125 71struct IP *lastIP6range, *lastIP6uplink;\r
14e28c6f 72\r
1c9cae56 73/* == This function strips extra characters after IPv4 address and stores it = */\r
af37be1d 74void parse_and_append_ip(char *str, struct IP *listhead)\r
1c9cae56 75{\r
64b2d125 76 char *ptr, *ipaddr, *nextip6, *ip6buf; \r
296d0585 77 char *ip6uplink = NULL, *ip6range = NULL, *ipname = NULL, *code = NULL;\r
f64d5431 78\r
b1a5c883 79 if(ip6prefix) /* Try this only if IPv6 subsystem is active... */\r
f64d5431 80 {\r
81 ptr = strstr(str, "::");\r
64b2d125 82 while(ptr && ptr-str > 4)\r
f64d5431 83 {\r
64b2d125 84 nextip6 = strstr(ptr + 2, "::");\r
85 ptr -= 4;\r
86 duplicate(ptr, ip6buf);\r
87 ptr = strstr(ip6buf, "::");\r
f64d5431 88 if(ptr)\r
89 {\r
64b2d125 90 if(*(ptr+2) == '+')\r
91 {\r
92 *(ptr+3) = 0; /* ends with ::+ */\r
93 ip6uplink = ip6buf;\r
94 }\r
95 else\r
96 {\r
97 *(ptr+2) = 0; /* ends with :: */\r
98 ip6range = ip6buf;\r
99 } \r
f64d5431 100 }\r
64b2d125 101 ptr = nextip6;\r
f64d5431 102 }\r
103 }\r
1c9cae56 104\r
105 ptr = strchr(str, '{');\r
106 if(ptr)\r
107 {\r
296d0585 108 code = ++ptr;\r
1c9cae56 109 while(*ptr and *ptr != '}')\r
110 {\r
111 ptr++;\r
112 }\r
113 *ptr = 0;\r
114 }\r
115 \r
116 ptr = str;\r
117 while(*ptr and *ptr!=' ' and *ptr!=9)\r
118 {\r
119 ptr++;\r
120 }\r
121 \r
122 *ptr = 0;\r
123 ipaddr = str;\r
124 ptr++;\r
125 while(*ptr and (*ptr==' ' or *ptr==9))\r
126 {\r
127 ptr++;\r
128 }\r
64b2d125 129 ipname = ptr; \r
1c9cae56 130 while(*ptr and *ptr!=' ' and *ptr!=9)\r
131 {\r
132 ptr++;\r
133 }\r
134 *ptr=0;\r
135\r
f64d5431 136 if(ip6range)\r
137 {\r
138 concatenate(ip6prefix,ip6range,ptr);\r
0b9c3c19 139 ip6range=ptr;\r
67120c62 140 if_exists(ip, ips, eq(ip->addr,ip6range)); /* check - allocated range must be unique */\r
f64d5431 141 else\r
142 {\r
af37be1d 143 TheIP(ip6range, FALSE);\r
f64d5431 144 }\r
0b9c3c19 145 ip->name = ip6range;\r
14e28c6f 146 ip->keyword = defaultkeyword; /* settings for default keyword */\r
296d0585 147 if(code)\r
f64d5431 148 {\r
296d0585 149 ip->code = code;\r
f64d5431 150 }\r
64b2d125 151 lastIP6range = ip;\r
152 }\r
153 else\r
154 {\r
155 lastIP6range = NULL;\r
156 }\r
157\r
158 /* it is ugly to copy+paste and search+replace, but... */\r
159 if(ip6uplink)\r
160 {\r
161 concatenate(ip6prefix,ip6uplink,ptr);\r
162 ip6uplink=ptr;\r
67120c62 163 TheIP(ip6uplink, FALSE); /* always new IP - more IPs in single uplink network */\r
64b2d125 164 ip->name = ip6uplink;\r
165 ip->keyword = defaultkeyword; /* settings for default keyword */\r
296d0585 166 if(code)\r
64b2d125 167 {\r
296d0585 168 ip->code = code;\r
64b2d125 169 }\r
170 lastIP6uplink = ip;\r
14e28c6f 171 }\r
172 else\r
173 {\r
64b2d125 174 lastIP6uplink = NULL;\r
f64d5431 175 }\r
176\r
af37be1d 177 if_exists(ip, listhead, eq(ip->addr,ipaddr));\r
1c9cae56 178 else\r
179 {\r
af37be1d 180 TheIP(ipaddr, (listhead==networks));\r
1c9cae56 181 }\r
1c9cae56 182 ip->name = ipname;\r
296d0585 183 if(code)\r
1c9cae56 184 {\r
296d0585 185 ip->code = code;\r
186 found_code = TRUE;\r
1c9cae56 187 }\r
188}\r
189\r
190/* == This function parses hosts style main configuration file == */\r
191void parse_hosts(char *hosts)\r
192{\r
193 int groupidx = FIRSTGROUPID;\r
194 char *str, *ptr;\r
195 char *substring;\r
af37be1d 196 struct IP *network;\r
73cf6e9d 197 int pktratio;\r
1c9cae56 198\r
199 parse(hosts)\r
200 {\r
bb5e7385 201 str = _;\r
1c9cae56 202\r
203 if(*str < '0' or *str > '9')\r
204 {\r
205 /* any line starting with non-number is comment ...*/\r
206 continue;\r
207 }\r
8dcd2b4c 208\r
209 ptr = strchr(str,'\r'); /* fore unix-style end of line */\r
210 if(ptr)\r
211 {\r
212 *ptr = 0;\r
213 }\r
214 \r
bb5e7385 215 /* first, expand (rewrite) any predefined macros, if found*/\r
216 for_each(macro, macros)\r
217 {\r
218 substring = strstr(str, macro->rewrite_from);\r
8dcd2b4c 219 if(substring)\r
bb5e7385 220 {\r
221 int l1, l3;\r
222 *substring = 0;\r
223 substring += strlen(macro->rewrite_from);\r
224 l1 = strlen(str);\r
225 l3 = strlen(substring);\r
8dcd2b4c 226 string(ptr, l1 + strlen(macro->rewrite_to) + l3 + 1);\r
bb5e7385 227 strcpy(ptr, str);\r
228 strcat(ptr, macro->rewrite_to);\r
229 strcat(ptr, substring);\r
230 str = ptr;\r
8dcd2b4c 231 /* printf("REWRITE: %s -> %s\n",_,str); */\r
bb5e7385 232 }\r
233 }\r
234\r
1c9cae56 235 /* Does this IP share QoS class with some other ? */\r
236 substring = strstr(str, "sharing-");\r
237 if(substring)\r
238 { \r
239 substring += 8; /* "sharing-" */\r
af37be1d 240 parse_and_append_ip(str, ips);\r
1c9cae56 241 ip->sharing = substring;\r
242 ip->keyword = defaultkeyword; /* settings for default keyword */\r
64b2d125 243 if(lastIP6range)\r
244 {\r
245 lastIP6range->sharing = substring;\r
246 lastIP6range = NULL;\r
247 }\r
248 if(lastIP6uplink)\r
14e28c6f 249 {\r
64b2d125 250 lastIP6uplink->sharing = substring;\r
251 lastIP6uplink = NULL;\r
14e28c6f 252 }\r
1c9cae56 253 while(*substring and *substring != '\n')\r
254 {\r
255 substring++;\r
256 }\r
257 *substring = 0; \r
258 }\r
259 else\r
260 {\r
af37be1d 261 substring = strstr(str, "#255.");\r
47b5fd64 262 if(substring and not strstr(str, "#255.255.255.255")) /* ignore /32 subnets */\r
1c9cae56 263 {\r
af37be1d 264 /* netmask detected - save network*/\r
265 unsigned bit;\r
266 unsigned num, mask = 8;\r
267 substring += 5;\r
268 while(substring && *substring)\r
1c9cae56 269 {\r
af37be1d 270 ptr = substring;\r
271 substring = strchr(substring, '.');\r
272 if(substring)\r
273 {\r
274 *substring = 0;\r
275 substring += 1;\r
276 }\r
277 num = atoi(ptr);\r
278 for(bit = 1; bit <=128 ; bit<<=1)\r
1c9cae56 279 {\r
af37be1d 280 if(bit & num)\r
281 {\r
282 mask++;\r
283 }\r
1c9cae56 284 }\r
af37be1d 285 } \r
286 parse_and_append_ip(str, networks);\r
287 ip->mask = mask;\r
288 }\r
289 else\r
290 {\r
47b5fd64 291 /* Main branch - most IP addresses go here */\r
af37be1d 292 /*Do we have to create new QoS class for this IP ? */\r
293 if_exists(keyword,keywords,(substring=strstr(str,keyword->key)))\r
1c9cae56 294 {\r
47b5fd64 295#ifdef MONITORINGTRHU_CTU\r
296//special hack only to generate certain required CSV statistics for www.ctu.cz (regulation body)\r
297 char *found_at = strchr(str, '@');\r
298 char *ruian_id_str = NULL;\r
299 technology = NULL;\r
300 if(found_at)\r
301 {\r
302 int len;\r
303 char *found_ruian_end = strchr(found_at, ' ');\r
304 char *found_tech_str = found_at;\r
305 while(found_tech_str-- > str && *found_tech_str != ' ' && *found_tech_str != '#');\r
306 if(found_tech_str > str)\r
307 {\r
308 len = found_at - found_tech_str - 1;\r
309 for_each(technology, technologies)\r
364980f0 310 if(strlen(technology->filename)==len && !strncmp(technology->filename, found_tech_str + 1, len))\r
47b5fd64 311 break;\r
312 if(!technology)\r
313 {\r
314 create(technology,Technology);\r
315 string(technology->filename, len + 1);\r
316 strncpy(technology->filename, found_tech_str + 1, len);\r
317 technology->filename[len] = 0;\r
318 push(technology, technologies);\r
319 }\r
320 if(found_ruian_end)\r
321 {\r
322 len = found_ruian_end - found_at - 1;\r
323 string(ruian_id_str, len + 1);\r
324 strncpy(ruian_id_str, found_at + 1, len);\r
325 ruian_id_str[len] = 0;\r
326 }\r
327 }\r
328 }\r
329#endif\r
af37be1d 330 parse_and_append_ip(str, ips);\r
64b2d125 331 if(lastIP6range)\r
332 {\r
333 lastIP6range->sharing = ip->name;\r
334 lastIP6range = NULL;\r
335 }\r
336 if(lastIP6uplink)\r
af37be1d 337 {\r
64b2d125 338 lastIP6uplink->sharing = ip->name;\r
339 lastIP6uplink = NULL;\r
af37be1d 340 }\r
341 ip->keyword = keyword;\r
342 keyword->ip_count++;\r
343 ip->prio = keyword->default_prio;\r
344 substring += strlen(keyword->key)+1;\r
345 ptr = substring;\r
346 while(*ptr and *ptr != '-')\r
347 {\r
348 ptr++;\r
349 }\r
350 if(*ptr == '-')\r
351 {\r
352 *ptr=0;\r
353 ip->max = ip->desired = atoi(ptr+1);\r
354 }\r
9694a8ec 355\r
af37be1d 356 ip->min = atoi(substring);\r
357 if(ip->min <= 0)\r
358 {\r
359 printf(" %s: Illegal value of minimum bandwidth 0 kbps, using %d kb/s\n",\r
360 str, free_min);\r
361 ip->min = free_min;\r
362 }\r
9694a8ec 363\r
af37be1d 364 if(ip->max <= ip->min)\r
365 {\r
366 ip->fixedprio = TRUE;\r
367 ip->max = ip->min + ip->keyword->reserve_min;\r
368 }\r
369 else \r
370 {\r
371 ip->max -= ip->keyword->reserve_max;\r
c38473c1 372 if(ip->max < ip->min)\r
af37be1d 373 {\r
c38473c1 374 ip->max = ip->min;\r
af37be1d 375 }\r
376 }\r
06733b88 377\r
296d0585 378 if(ip->keyword->allowed_avgmtu)\r
06733b88 379 {\r
296d0585 380 /* avg MTU bytes * 8 >> 10 = in bits, max is in kb/s */\r
381 pktratio = (ip->keyword->allowed_avgmtu*8) >> 10;\r
382 if(pktratio > 0)\r
73cf6e9d 383 {\r
296d0585 384 ip->pps_limit = ip->max/pktratio;\r
385 if(ip->pps_limit > 10000) /* this limit seems to be hardcoded in iptables */\r
386 {\r
387 ip->pps_limit = 0; /* do not apply packet limits */\r
388 }\r
73cf6e9d 389 }\r
06733b88 390 }\r
391\r
4deb2d6f 392 ip->mark = FIRSTIPCLASS+1+class_count++; \r
2b460b72 393 update_network(ip->addr, ip);\r
af37be1d 394\r
47b5fd64 395#ifdef MONITORINGTRHU_CTU\r
396 if(technology)\r
397 {\r
398 ip->technology_str = technology->filename;\r
399 ip->ruian_id_str = ruian_id_str;\r
400 /* debug printf("[%s,%d,%s,%d]\n", ip->technology_str,ip->lmsid, ip->ruian_id_str, ip->max); */\r
401 }\r
402#endif\r
403\r
af37be1d 404 if_exists(group,groups,(group->min == ip->min)) \r
405 { \r
406 group->count++; \r
407 group->desired += ip->min;\r
408 ip->group = group->id; \r
409 }\r
410 else\r
411 {\r
412 create(group,Group);\r
413 group->min = ip->min;\r
414 group->id = groupidx++;\r
415 ip->group = group->id;\r
416\r
417 if(group->min < 8) group->min = 8;\r
418 /* Warning - this is maybe because of primitive tc namespace, can be fixed */\r
419 /* it is because class IDs are derived from min. bandwidth. - xCh */\r
420 //if(group->min>MAX_GUARANTED_KBPS) group->min=MAX_GUARANTED_KBPS;\r
421 \r
422 group->count = 1;\r
423 group->desired = ip->min; \r
424 insert(group, groups, desc_order_by,min);\r
425 }\r
47b5fd64 426 }//endif keyword- \r
af37be1d 427 }//endif netmask\r
1c9cae56 428 }//endif sharing-\r
429 }\r
430 fail\r
431 {\r
432 perror(hosts);\r
433 exit(-1);\r
434 }\r
435 done; /* ugly macro end */\r
9694a8ec 436// TheIP("0.0.0.0", TRUE);\r
437// ip->name = "TOTAL";\r
438// ip->mask = 0;\r
47b5fd64 439}
This page took 0.513822 seconds and 4 git commands to generate.