1 /*
2 NETWIB
3 Network library
4 Copyright(c) 1999-2010 Laurent Constantin
5 -----
6
7 Main server : http://www.laurentconstantin.com/
8 Backup server : http://laurentconstantin.free.fr/
9 [my current email address is on the web servers]
10
11 -----
12 This file is part of Netwib.
13
14 Netwib is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License version 3
16 as published by the Free Software Foundation.
17
18 Netwib is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details (http://www.gnu.org/).
22
23 ------------------------------------------------------------------------
24 */
25
26 #include <netwib/inc/maininc.h>
27
28 /*-------------------------------------------------------------*/
netwib_ports_init(netwib_ports_inittype inittype,netwib_ports ** ppports)29 netwib_err netwib_ports_init(netwib_ports_inittype inittype,
30 netwib_ports **ppports)
31 {
32 netwib_ports *pports;
33 netwib_err ret;
34
35 /* parameter verification */
36 if (ppports == NULL) {
37 return(NETWIB_ERR_PANULLPTR);
38 }
39
40 /* allocate needed memory to store pports */
41 netwib_er(netwib_ptr_malloc(sizeof(netwib_ports), (netwib_ptr*)&pports));
42 *ppports = pports;
43
44 ret = netwib_priv_ranges_init(inittype, NETWIB_PORT_LEN, &pports->ranges);
45 if (ret != NETWIB_ERR_OK) {
46 netwib_er(netwib_ptr_free((netwib_ptr*)&pports));
47 return(ret);
48 }
49
50 #if NETWIB_DEBUG_LEAK==1
51 netwib_er(netwib_debug_leak_add_ports(pports));
52 #endif
53
54 return(NETWIB_ERR_OK);
55 }
56
57 /*-------------------------------------------------------------*/
netwib_ports_close(netwib_ports ** ppports)58 netwib_err netwib_ports_close(netwib_ports **ppports)
59 {
60 netwib_ports *pports;
61
62 /* parameter verification */
63 if (ppports == NULL) {
64 return(NETWIB_ERR_PANULLPTR);
65 }
66 pports = *ppports;
67
68 /* remove items */
69 netwib_er(netwib_priv_ranges_close(&pports->ranges));
70
71 #if NETWIB_DEBUG_LEAK==1
72 netwib_er(netwib_debug_leak_del_ports(pports));
73 #endif
74
75 /* free memory */
76 netwib_er(netwib_ptr_free((netwib_ptr*)&pports));
77
78 return(NETWIB_ERR_OK);
79 }
80
81 /*-------------------------------------------------------------*/
netwib_ports_add_port(netwib_ports * pports,netwib_port port)82 netwib_err netwib_ports_add_port(netwib_ports *pports,
83 netwib_port port)
84 {
85 netwib_byte portarray[NETWIB_PORT_LEN];
86
87 /* parameter verification */
88 if (pports == NULL) {
89 return(NETWIB_ERR_PANULLPTR);
90 }
91 #if NETWIB_DEBUG_LEAK==1
92 netwib_er(netwib_debug_leak_valid_ports(pports));
93 #endif
94
95 /* add item */
96 portarray[0] = netwib_c2_uint16_0(port);
97 portarray[1] = netwib_c2_uint16_1(port);
98 netwib_er(netwib_priv_ranges_add(&pports->ranges, portarray));
99
100 return(NETWIB_ERR_OK);
101 }
102
103 /*-------------------------------------------------------------*/
netwib_ports_add_portrange(netwib_ports * pports,netwib_port infport,netwib_port support)104 netwib_err netwib_ports_add_portrange(netwib_ports *pports,
105 netwib_port infport,
106 netwib_port support)
107 {
108 netwib_byte infportarray[NETWIB_PORT_LEN], supportarray[NETWIB_PORT_LEN];
109
110 /* parameter verification */
111 if (pports == NULL) {
112 return(NETWIB_ERR_PANULLPTR);
113 }
114 #if NETWIB_DEBUG_LEAK==1
115 netwib_er(netwib_debug_leak_valid_ports(pports));
116 #endif
117
118 /* add item */
119 infportarray[0] = netwib_c2_uint16_0(infport);
120 infportarray[1] = netwib_c2_uint16_1(infport);
121 supportarray[0] = netwib_c2_uint16_0(support);
122 supportarray[1] = netwib_c2_uint16_1(support);
123 netwib_er(netwib_priv_ranges_add_range(&pports->ranges, infportarray,
124 supportarray));
125
126 return(NETWIB_ERR_OK);
127 }
128
129 /*-------------------------------------------------------------*/
netwib_ports_add_ports(netwib_ports * pports,netwib_constports * pportstoadd)130 netwib_err netwib_ports_add_ports(netwib_ports *pports,
131 netwib_constports *pportstoadd)
132 {
133 netwib_priv_ranges_index rangesindex;
134 netwib_byte infportarray[NETWIB_PORT_LEN], supportarray[NETWIB_PORT_LEN];
135 netwib_err ret;
136
137 /* parameter verification */
138 if (pports == NULL) {
139 return(NETWIB_ERR_PANULLPTR);
140 }
141 #if NETWIB_DEBUG_LEAK==1
142 netwib_er(netwib_debug_leak_valid_ports(pports));
143 netwib_er(netwib_debug_leak_valid_ports(pportstoadd));
144 #endif
145
146 netwib_er(netwib_priv_ranges_index_init(&pportstoadd->ranges, &rangesindex));
147 ret = NETWIB_ERR_OK;
148 while(NETWIB_TRUE) {
149 ret = netwib_priv_ranges_index_next_range(&rangesindex, infportarray,
150 supportarray);
151 if (ret != NETWIB_ERR_OK) {
152 if (ret == NETWIB_ERR_DATAEND) ret = NETWIB_ERR_OK;
153 break;
154 }
155 netwib_er(netwib_priv_ranges_add_range(&pports->ranges, infportarray,
156 supportarray));
157 }
158 netwib_er(netwib_priv_ranges_index_close(&rangesindex));
159
160 return(ret);
161 }
162
163 /*-------------------------------------------------------------*/
netwib_priv_ports_add_buf(netwib_conststring str,netwib_data array,netwib_priv_ranges_separator * pseparator)164 static netwib_err netwib_priv_ports_add_buf(netwib_conststring str,
165 netwib_data array,
166 netwib_priv_ranges_separator
167 *pseparator)
168 {
169 netwib_conststring pc;
170 netwib_uint32 infport, support, numdigitfound, *pport;
171 netwib_priv_ranges_separator separator;
172 netwib_char c;
173
174 pc = str;
175 numdigitfound = 0;
176 separator = NETWIB_PRIV_RANGES_SEPARATOR_NONE;
177 infport = 0;
178 support = 0;
179 pport = &infport;
180 while(NETWIB_TRUE) {
181 c = *pc;
182 if (c == '\0') {
183 if (numdigitfound == 0) return(NETWIB_ERR_NOTCONVERTED);
184 break;
185 } else if (c == '-') {
186 if (separator == NETWIB_PRIV_RANGES_SEPARATOR_DASH) {
187 return(NETWIB_ERR_NOTCONVERTED); /* forbid two separators */
188 }
189 separator = NETWIB_PRIV_RANGES_SEPARATOR_DASH;
190 numdigitfound = 0;
191 pport = &support;
192 } else if (netwib_c2_isdigit(c)) {
193 if (numdigitfound == 5) return(NETWIB_ERR_NOTCONVERTED);
194 numdigitfound++;
195 *pport = 10*(*pport) + netwib_c2_cto9(c);
196 if (*pport > 0xFFFF) return(NETWIB_ERR_NOTCONVERTED);
197 } else {
198 return(NETWIB_ERR_NOTCONVERTED);
199 }
200 pc++;
201 }
202
203 array[0] = netwib_c2_uint16_0(infport);
204 array[1] = netwib_c2_uint16_1(infport);
205 *pseparator = separator;
206 if (separator == NETWIB_PRIV_RANGES_SEPARATOR_DASH) {
207 if (infport > support) return(NETWIB_ERR_NOTCONVERTED);
208 array[2] = netwib_c2_uint16_0(support);
209 array[3] = netwib_c2_uint16_1(support);
210 }
211
212 return(NETWIB_ERR_OK);
213 }
214
215 /*-------------------------------------------------------------*/
netwib_ports_add_buf(netwib_ports * pports,netwib_constbuf * pbuf)216 netwib_err netwib_ports_add_buf(netwib_ports *pports,
217 netwib_constbuf *pbuf)
218 {
219 netwib_err ret;
220
221 ret = netwib_priv_ranges_add_buf(&pports->ranges, pbuf,
222 &netwib_priv_ports_add_buf);
223 if (ret != NETWIB_ERR_OK) {
224 netwib_er(netwib_priv_errmsg_string("bad port list: "));
225 netwib_er(netwib_priv_errmsg_append_buf(pbuf));
226 }
227 return(ret);
228 }
229
230 /*-------------------------------------------------------------*/
netwib_ports_add_kbd(netwib_ports * pports,netwib_constbuf * pmessage,netwib_constbuf * pdefaultlist)231 netwib_err netwib_ports_add_kbd(netwib_ports *pports,
232 netwib_constbuf *pmessage,
233 netwib_constbuf *pdefaultlist)
234 {
235 netwib_buf buf;
236 netwib_ports *plocalports;
237 netwib_char prompt;
238 netwib_err ret;
239
240 netwib_er(netwib_ports_init(pports->ranges.inittype, &plocalports));
241 if (pdefaultlist != NULL) {
242 ret = netwib_ports_add_buf(plocalports, pdefaultlist);
243 if (ret != NETWIB_ERR_OK) {
244 netwib_er(netwib_ports_close(&plocalports));
245 return(ret);
246 }
247 netwib_er(netwib_priv_ranges_del_all(&plocalports->ranges));
248 }
249
250 netwib_er(netwib_buf_init_mallocdefault(&buf));
251 prompt = ':';
252 while (NETWIB_TRUE) {
253 netwib_er(netwib_priv_kbd_buf_append(pmessage, pdefaultlist,
254 NETWIB_TRUE, prompt, NETWIB_FALSE,
255 &buf));
256 if (netwib__buf_ref_data_size(&buf) == 0) {
257 if (pdefaultlist != NULL) {
258 netwib_er(netwib_ports_add_buf(pports, pdefaultlist));
259 break;
260 }
261 }
262 ret = netwib_ports_add_buf(plocalports, &buf);
263 if (ret == NETWIB_ERR_OK) {
264 netwib_er(netwib_ports_add_ports(pports, plocalports));
265 break;
266 }
267 netwib_er(netwib_priv_ranges_del_all(&plocalports->ranges));
268 netwib__buf_reinit(&buf);
269 prompt = '>';
270 }
271
272 netwib_er(netwib_buf_close(&buf));
273 netwib_er(netwib_ports_close(&plocalports));
274
275 return(NETWIB_ERR_OK);
276 }
277
278 /*-------------------------------------------------------------*/
netwib_ports_del_port(netwib_ports * pports,netwib_port port)279 netwib_err netwib_ports_del_port(netwib_ports *pports,
280 netwib_port port)
281 {
282 netwib_byte portarray[NETWIB_PORT_LEN];
283
284 /* parameter verification */
285 if (pports == NULL) {
286 return(NETWIB_ERR_PANULLPTR);
287 }
288 #if NETWIB_DEBUG_LEAK==1
289 netwib_er(netwib_debug_leak_valid_ports(pports));
290 #endif
291
292 /* add item */
293 portarray[0] = netwib_c2_uint16_0(port);
294 portarray[1] = netwib_c2_uint16_1(port);
295 netwib_er(netwib_priv_ranges_del(&pports->ranges, portarray));
296
297 return(NETWIB_ERR_OK);
298 }
299
300 /*-------------------------------------------------------------*/
netwib_ports_del_portrange(netwib_ports * pports,netwib_port infport,netwib_port support)301 netwib_err netwib_ports_del_portrange(netwib_ports *pports,
302 netwib_port infport,
303 netwib_port support)
304 {
305 netwib_byte infportarray[NETWIB_PORT_LEN], supportarray[NETWIB_PORT_LEN];
306
307 /* parameter verification */
308 if (pports == NULL) {
309 return(NETWIB_ERR_PANULLPTR);
310 }
311 #if NETWIB_DEBUG_LEAK==1
312 netwib_er(netwib_debug_leak_valid_ports(pports));
313 #endif
314
315 /* add item */
316 infportarray[0] = netwib_c2_uint16_0(infport);
317 infportarray[1] = netwib_c2_uint16_1(infport);
318 supportarray[0] = netwib_c2_uint16_0(support);
319 supportarray[1] = netwib_c2_uint16_1(support);
320 netwib_er(netwib_priv_ranges_del_range(&pports->ranges, infportarray,
321 supportarray));
322
323 return(NETWIB_ERR_OK);
324 }
325
326 /*-------------------------------------------------------------*/
netwib_ports_del_ports(netwib_ports * pports,netwib_constports * pportstodel)327 netwib_err netwib_ports_del_ports(netwib_ports *pports,
328 netwib_constports *pportstodel)
329 {
330 netwib_priv_ranges_index rangesindex;
331 netwib_byte infportarray[NETWIB_PORT_LEN], supportarray[NETWIB_PORT_LEN];
332 netwib_err ret;
333
334 /* parameter verification */
335 if (pports == NULL) {
336 return(NETWIB_ERR_PANULLPTR);
337 }
338 #if NETWIB_DEBUG_LEAK==1
339 netwib_er(netwib_debug_leak_valid_ports(pports));
340 netwib_er(netwib_debug_leak_valid_ports(pportstodel));
341 #endif
342
343 netwib_er(netwib_priv_ranges_index_init(&pportstodel->ranges, &rangesindex));
344 ret = NETWIB_ERR_OK;
345 while(NETWIB_TRUE) {
346 ret = netwib_priv_ranges_index_next_range(&rangesindex, infportarray,
347 supportarray);
348 if (ret != NETWIB_ERR_OK) {
349 if (ret == NETWIB_ERR_DATAEND) ret = NETWIB_ERR_OK;
350 break;
351 }
352 netwib_er(netwib_priv_ranges_del_range(&pports->ranges, infportarray,
353 supportarray));
354 }
355 netwib_er(netwib_priv_ranges_index_close(&rangesindex));
356
357 return(ret);
358 }
359
360 /*-------------------------------------------------------------*/
netwib_ports_contains_port(netwib_constports * pports,netwib_port port,netwib_bool * pyes)361 netwib_err netwib_ports_contains_port(netwib_constports *pports,
362 netwib_port port,
363 netwib_bool *pyes)
364 {
365 netwib_byte portarray[NETWIB_PORT_LEN];
366
367 /* parameter verification */
368 if (pports == NULL) {
369 return(NETWIB_ERR_PANULLPTR);
370 }
371 #if NETWIB_DEBUG_LEAK==1
372 netwib_er(netwib_debug_leak_valid_ports(pports));
373 #endif
374
375 /* add item */
376 portarray[0] = netwib_c2_uint16_0(port);
377 portarray[1] = netwib_c2_uint16_1(port);
378 netwib_er(netwib_priv_ranges_contains(&pports->ranges, portarray, pyes));
379
380 return(NETWIB_ERR_OK);
381 }
382
383 /*-------------------------------------------------------------*/
netwib_ports_contains_portrange(netwib_constports * pports,netwib_port infport,netwib_port support,netwib_bool * pyes)384 netwib_err netwib_ports_contains_portrange(netwib_constports *pports,
385 netwib_port infport,
386 netwib_port support,
387 netwib_bool *pyes)
388 {
389 netwib_byte infportarray[NETWIB_PORT_LEN], supportarray[NETWIB_PORT_LEN];
390
391 /* parameter verification */
392 if (pports == NULL) {
393 return(NETWIB_ERR_PANULLPTR);
394 }
395 #if NETWIB_DEBUG_LEAK==1
396 netwib_er(netwib_debug_leak_valid_ports(pports));
397 #endif
398
399 /* add item */
400 infportarray[0] = netwib_c2_uint16_0(infport);
401 infportarray[1] = netwib_c2_uint16_1(infport);
402 supportarray[0] = netwib_c2_uint16_0(support);
403 supportarray[1] = netwib_c2_uint16_1(support);
404 netwib_er(netwib_priv_ranges_contains_range(&pports->ranges, infportarray,
405 supportarray, pyes));
406
407 return(NETWIB_ERR_OK);
408 }
409
410 /*-------------------------------------------------------------*/
netwib_buf_append_ports(netwib_constports * pports,netwib_buf * pbuf)411 netwib_err netwib_buf_append_ports(netwib_constports *pports,
412 netwib_buf *pbuf)
413 {
414 netwib_priv_ranges_index rangesindex;
415 netwib_byte infportarray[NETWIB_PORT_LEN], supportarray[NETWIB_PORT_LEN];
416 netwib_port infport, support;
417 netwib_bool needcomma;
418 netwib_uint32 savedsize=0;
419 netwib_err ret;
420
421 /* parameter verification */
422 if (pports == NULL) {
423 return(NETWIB_ERR_PANULLPTR);
424 }
425 #if NETWIB_DEBUG_LEAK==1
426 netwib_er(netwib_debug_leak_valid_ports(pports));
427 #endif
428
429 /* save position in case of error */
430 if (pbuf != NULL) {
431 savedsize = netwib__buf_ref_data_size(pbuf);
432 }
433
434 netwib_er(netwib_priv_ranges_index_init(&pports->ranges, &rangesindex));
435 ret = NETWIB_ERR_OK;
436 needcomma = NETWIB_FALSE;
437 while(NETWIB_TRUE) {
438 ret = netwib_priv_ranges_index_next_range(&rangesindex, infportarray,
439 supportarray);
440 if (ret != NETWIB_ERR_OK) {
441 if (ret == NETWIB_ERR_DATAEND) ret = NETWIB_ERR_OK;
442 break;
443 }
444 if (needcomma) {
445 ret = netwib_buf_append_byte(',', pbuf);
446 if (ret != NETWIB_ERR_OK) {
447 break;
448 }
449 } else {
450 needcomma = NETWIB_TRUE;
451 }
452 infport = netwib_c2_uint16_2(infportarray[0], infportarray[1]);
453 support = netwib_c2_uint16_2(supportarray[0], supportarray[1]);
454 ret = netwib_buf_append_port(infport, pbuf);
455 if (ret != NETWIB_ERR_OK) {
456 break;
457 }
458 if (infport != support) {
459 ret = netwib_buf_append_byte('-', pbuf);
460 if (ret != NETWIB_ERR_OK) {
461 break;
462 }
463 ret = netwib_buf_append_port(support, pbuf);
464 if (ret != NETWIB_ERR_OK) {
465 break;
466 }
467 }
468 }
469 netwib_er(netwib_priv_ranges_index_close(&rangesindex));
470
471 /* on space error, restore first pos */
472 if (ret != NETWIB_ERR_OK) {
473 if (pbuf != NULL) {
474 pbuf->endoffset = pbuf->beginoffset + savedsize;
475 }
476 }
477 return(ret);
478 }
479