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