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