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