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