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