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_ip_init_ip4_fields(netwib_byte a,netwib_byte b,netwib_byte c,netwib_byte d,netwib_ip * pip)29 netwib_err netwib_ip_init_ip4_fields(netwib_byte a,
30                                      netwib_byte b,
31                                      netwib_byte c,
32                                      netwib_byte d,
33                                      netwib_ip *pip)
34 {
35 
36   if (pip != NULL) {
37     pip->iptype = NETWIB_IPTYPE_IP4;
38     pip->ipvalue.ip4 = netwib_c2_uint32_4(a, b, c, d);
39   }
40 
41   return(NETWIB_ERR_OK);
42 }
43 
44 /*-------------------------------------------------------------*/
netwib_ip_init_ip4(netwib_ip4 ip4,netwib_ip * pip)45 netwib_err netwib_ip_init_ip4(netwib_ip4 ip4,
46                               netwib_ip *pip)
47 {
48 
49   if (pip != NULL) {
50     pip->iptype = NETWIB_IPTYPE_IP4;
51     pip->ipvalue.ip4 = ip4;
52   }
53 
54   return(NETWIB_ERR_OK);
55 }
56 
57 /*-------------------------------------------------------------*/
netwib_ip4_init_ip(netwib_constip * pip,netwib_ip4 * pip4)58 netwib_err netwib_ip4_init_ip(netwib_constip *pip,
59                               netwib_ip4 *pip4)
60 {
61 
62   switch(pip->iptype) {
63     case NETWIB_IPTYPE_IP4 :
64       if (pip4 != NULL) {
65         *pip4 = pip->ipvalue.ip4;
66       }
67       break;
68     case NETWIB_IPTYPE_IP6 :
69       netwib_er(netwib_priv_ip_ip4_init_ip6(&pip->ipvalue.ip6, pip4));
70       break;
71     default :
72       return(NETWIB_ERR_PAIPTYPE);
73       break;
74   }
75 
76   return(NETWIB_ERR_OK);
77 }
78 
79 /*-------------------------------------------------------------*/
netwib_ip_init_ip6_fields(netwib_uint32 a,netwib_uint32 b,netwib_uint32 c,netwib_uint32 d,netwib_ip * pip)80 netwib_err netwib_ip_init_ip6_fields(netwib_uint32 a,
81                                      netwib_uint32 b,
82                                      netwib_uint32 c,
83                                      netwib_uint32 d,
84                                      netwib_ip *pip)
85 {
86   if (pip != NULL) {
87     pip->iptype = NETWIB_IPTYPE_IP6;
88     pip->ipvalue.ip6.b[0] = netwib_c2_uint32_0(a);
89     pip->ipvalue.ip6.b[1] = netwib_c2_uint32_1(a);
90     pip->ipvalue.ip6.b[2] = netwib_c2_uint32_2(a);
91     pip->ipvalue.ip6.b[3] = netwib_c2_uint32_3(a);
92     pip->ipvalue.ip6.b[4] = netwib_c2_uint32_0(b);
93     pip->ipvalue.ip6.b[5] = netwib_c2_uint32_1(b);
94     pip->ipvalue.ip6.b[6] = netwib_c2_uint32_2(b);
95     pip->ipvalue.ip6.b[7] = netwib_c2_uint32_3(b);
96     pip->ipvalue.ip6.b[8] = netwib_c2_uint32_0(c);
97     pip->ipvalue.ip6.b[9] = netwib_c2_uint32_1(c);
98     pip->ipvalue.ip6.b[10] = netwib_c2_uint32_2(c);
99     pip->ipvalue.ip6.b[11] = netwib_c2_uint32_3(c);
100     pip->ipvalue.ip6.b[12] = netwib_c2_uint32_0(d);
101     pip->ipvalue.ip6.b[13] = netwib_c2_uint32_1(d);
102     pip->ipvalue.ip6.b[14] = netwib_c2_uint32_2(d);
103     pip->ipvalue.ip6.b[15] = netwib_c2_uint32_3(d);
104   }
105 
106   return(NETWIB_ERR_OK);
107 }
108 
109 /*-------------------------------------------------------------*/
netwib_ip_init_ip6(netwib_constip6 * pip6,netwib_ip * pip)110 netwib_err netwib_ip_init_ip6(netwib_constip6 *pip6,
111                               netwib_ip *pip)
112 {
113 
114   if (pip != NULL) {
115     pip->iptype = NETWIB_IPTYPE_IP6;
116     pip->ipvalue.ip6 = *pip6;
117   }
118 
119   return(NETWIB_ERR_OK);
120 }
121 
122 /*-------------------------------------------------------------*/
netwib_ip6_init_ip(netwib_constip * pip,netwib_ip6 * pip6)123 netwib_err netwib_ip6_init_ip(netwib_constip *pip,
124                               netwib_ip6 *pip6)
125 {
126 
127   switch(pip->iptype) {
128     case NETWIB_IPTYPE_IP4 :
129       netwib_er(netwib_priv_ip_ip6_init_ip4(pip->ipvalue.ip4, pip6));
130       break;
131     case NETWIB_IPTYPE_IP6 :
132       if (pip6 != NULL) {
133         netwib_c_memcpy(pip6->b, pip->ipvalue.ip6.b, NETWIB_IP6_LEN);
134       }
135       break;
136     default :
137       return(NETWIB_ERR_PAIPTYPE);
138       break;
139   }
140 
141   return(NETWIB_ERR_OK);
142 }
143 
144 /*-------------------------------------------------------------*/
netwib_ip_init_buf(netwib_constbuf * pbuf,netwib_ip_decodetype decodetype,netwib_ip * pip)145 netwib_err netwib_ip_init_buf(netwib_constbuf *pbuf,
146                               netwib_ip_decodetype decodetype,
147                               netwib_ip *pip)
148 {
149   netwib_string str;
150   netwib_bool decodeip4, decodeip6, decodehn4, decodehn6;
151   netwib_err ret;
152 
153   netwib__constbuf_ref_string(pbuf, str, bufstorage,
154                               netwib_ip_init_buf(&bufstorage, decodetype, pip));
155 
156   /* decide what to decode */
157   decodeip4 = NETWIB_FALSE;
158   decodeip6 = NETWIB_FALSE;
159   decodehn4 = NETWIB_FALSE;
160   decodehn6 = NETWIB_FALSE;
161   switch(decodetype) {
162   case NETWIB_IP_DECODETYPE_IP4 :
163     decodeip4 = NETWIB_TRUE;
164     break;
165   case NETWIB_IP_DECODETYPE_IP6 :
166     decodeip6 = NETWIB_TRUE;
167     break;
168   case NETWIB_IP_DECODETYPE_IP :
169     decodeip4 = NETWIB_TRUE;
170     decodeip6 = NETWIB_TRUE;
171     break;
172   case NETWIB_IP_DECODETYPE_HN4 :
173     decodehn4 = NETWIB_TRUE;
174     break;
175   case NETWIB_IP_DECODETYPE_HN6 :
176     decodehn6 = NETWIB_TRUE;
177     break;
178   case NETWIB_IP_DECODETYPE_HN :
179     decodehn4 = NETWIB_TRUE;
180     decodehn6 = NETWIB_TRUE;
181     break;
182   case NETWIB_IP_DECODETYPE_IP4HN4 :
183     decodeip4 = NETWIB_TRUE;
184     decodehn4 = NETWIB_TRUE;
185     break;
186   case NETWIB_IP_DECODETYPE_IP6HN6 :
187     decodeip6 = NETWIB_TRUE;
188     decodehn6 = NETWIB_TRUE;
189     break;
190   case NETWIB_IP_DECODETYPE_IPHN :
191     decodeip4 = NETWIB_TRUE;
192     decodeip6 = NETWIB_TRUE;
193     decodehn4 = NETWIB_TRUE;
194     decodehn6 = NETWIB_TRUE;
195     break;
196   default :
197     return(NETWIB_ERR_PAINVALIDTYPE);
198   }
199 
200   if (decodeip4) {
201     ret = netwib_priv_ip_init_sip4(str, pip);
202     if (ret == NETWIB_ERR_OK) return(NETWIB_ERR_OK);
203   }
204 
205   if (decodeip6) {
206     ret = netwib_priv_ip_init_sip6(str, pip);
207     if (ret == NETWIB_ERR_OK) return(NETWIB_ERR_OK);
208   }
209 
210   if (decodehn4) {
211     ret = netwib_priv_ip_init_hn4(str, pip);
212     if (ret == NETWIB_ERR_OK) return(NETWIB_ERR_OK);
213   }
214 
215   if (decodehn6) {
216     ret = netwib_priv_ip_init_hn6(str, pip);
217     if (ret == NETWIB_ERR_OK) return(NETWIB_ERR_OK);
218   }
219 
220   return(NETWIB_ERR_NOTCONVERTED);
221 }
222 
223 /*-------------------------------------------------------------*/
224 #include "pieces/ip_init_eth.c"
225 
226 /*-------------------------------------------------------------*/
netwib_ip_init_kbd(netwib_constbuf * pmessage,netwib_constbuf * pdefaulthn,netwib_ip * pip)227 netwib_err netwib_ip_init_kbd(netwib_constbuf *pmessage,
228                               netwib_constbuf *pdefaulthn,
229                               netwib_ip *pip)
230 {
231   netwib_buf buf;
232   netwib_constbuf *pdef;
233   netwib_ip defaultip;
234   netwib_char prompt;
235   netwib_err ret;
236 
237   defaultip.iptype = NETWIB_IPTYPE_IP4; /* for compiler warning */
238   pdef = NETWIB_BUF_APPEND_KBD_NODEF;
239   if (pdefaulthn != NETWIB_IP_INIT_KBD_NODEF) {
240     netwib_er(netwib_ip_init_buf_best(pdefaulthn, &defaultip));
241     pdef = pdefaulthn;
242   }
243 
244   netwib_er(netwib_buf_init_mallocdefault(&buf));
245   prompt = ':';
246   while (NETWIB_TRUE) {
247     netwib_er(netwib_priv_kbd_buf_append(pmessage, pdef, NETWIB_TRUE, prompt,
248                                          NETWIB_FALSE, &buf));
249     if (netwib__buf_ref_data_size(&buf) == 0) {
250       if (pdefaulthn != NETWIB_IP_INIT_KBD_NODEF) {
251         if (pip != NULL) *pip = defaultip;
252         break;
253       }
254     }
255     ret = netwib_ip_init_buf_best(&buf, pip);
256     if (ret == NETWIB_ERR_OK) {
257       break;
258     }
259     netwib__buf_reinit(&buf);
260     prompt = '>';
261   }
262 
263   netwib_er(netwib_buf_close(&buf));
264 
265   return(NETWIB_ERR_OK);
266 }
267 
268 /*-------------------------------------------------------------*/
netwib_ip_cmp(netwib_constip * pip1,netwib_constip * pip2,netwib_cmp * pcmp)269 netwib_err netwib_ip_cmp(netwib_constip *pip1,
270                          netwib_constip *pip2,
271                          netwib_cmp *pcmp)
272 {
273   netwib_ip4 ip41=0, ip42=0;
274   netwib_err ret;
275   int reti;
276 
277   if (pcmp == NULL) {
278     return(NETWIB_ERR_OK);
279   }
280 
281   if (pip1->iptype == NETWIB_IPTYPE_IP6 && pip2->iptype == NETWIB_IPTYPE_IP6) {
282     reti = netwib_c_memcmp(pip1->ipvalue.ip6.b, pip2->ipvalue.ip6.b,
283                            NETWIB_IP6_LEN);
284     if (reti == 0) {
285       *pcmp = NETWIB_CMP_EQ;
286     } else if (reti < 0) {
287       *pcmp = NETWIB_CMP_LT;
288     } else {
289       *pcmp = NETWIB_CMP_GT;
290     }
291     return(NETWIB_ERR_OK);
292   }
293 
294   switch(pip1->iptype) {
295     case NETWIB_IPTYPE_IP4 :
296       ip41 = pip1->ipvalue.ip4;
297       break;
298     case NETWIB_IPTYPE_IP6 :
299       ret = netwib_priv_ip_ip4_init_ip6(&pip1->ipvalue.ip6, &ip41);
300       if (ret != NETWIB_ERR_OK) {
301         *pcmp = NETWIB_CMP_GT;
302         return(NETWIB_ERR_OK);
303       }
304       break;
305     default:
306       return(NETWIB_ERR_PAIPTYPE);
307   }
308 
309   switch(pip2->iptype) {
310     case NETWIB_IPTYPE_IP4 :
311       ip42 = pip2->ipvalue.ip4;
312       break;
313     case NETWIB_IPTYPE_IP6 :
314       ret = netwib_priv_ip_ip4_init_ip6(&pip2->ipvalue.ip6, &ip42);
315       if (ret != NETWIB_ERR_OK) {
316         *pcmp = NETWIB_CMP_LT;
317         return(NETWIB_ERR_OK);
318       }
319       break;
320     default:
321       return(NETWIB_ERR_PAIPTYPE);
322   }
323 
324   if (ip41 == ip42) {
325     *pcmp = NETWIB_CMP_EQ;
326   } else if (ip41 < ip42) {
327     *pcmp = NETWIB_CMP_LT;
328   } else {
329     *pcmp = NETWIB_CMP_GT;
330   }
331 
332   return(NETWIB_ERR_OK);
333 }
334 
335 /*-------------------------------------------------------------*/
netwib_buf_append_ip(netwib_constip * pip,netwib_ip_encodetype encodetype,netwib_buf * pbuf)336 netwib_err netwib_buf_append_ip(netwib_constip *pip,
337                                 netwib_ip_encodetype encodetype,
338                                 netwib_buf *pbuf)
339 {
340   netwib_uint32 savedsize;
341   netwib_err ret = NETWIB_ERR_LOINTERNALERROR;
342 
343   if (pbuf == NULL) {
344     netwib_buf buf;
345     /* we work on a fake buf, just to test error */
346     netwib_er(netwib_buf_init_mallocdefault(&buf));
347     ret = netwib_buf_append_ip(pip, encodetype, &buf);
348     netwib_er(netwib_buf_close(&buf));
349     return(ret);
350   }
351 
352   /* save position in case of error */
353   savedsize = netwib__buf_ref_data_size(pbuf);
354 
355   switch(encodetype) {
356   case NETWIB_IP_ENCODETYPE_IP :
357     switch(pip->iptype) {
358     case NETWIB_IPTYPE_IP4 :
359       ret = netwib_priv_ip_buf_append_ip4(pip, pbuf);
360       break;
361     case NETWIB_IPTYPE_IP6 :
362       ret = netwib_priv_ip_buf_append_ip6(pip, pbuf);
363       break;
364     default :
365       return(NETWIB_ERR_PAIPTYPE);
366     }
367     break;
368   case NETWIB_IP_ENCODETYPE_HN :
369     ret = netwib_priv_ip_buf_append_hn(pip, pbuf);
370     break;
371   case NETWIB_IP_ENCODETYPE_HNIP :
372     ret = netwib_priv_ip_buf_append_hn(pip, pbuf);
373     if (ret == NETWIB_ERR_NOTCONVERTED) {
374       switch(pip->iptype) {
375       case NETWIB_IPTYPE_IP4 :
376         ret = netwib_priv_ip_buf_append_ip4(pip, pbuf);
377         break;
378       case NETWIB_IPTYPE_IP6 :
379         ret = netwib_priv_ip_buf_append_ip6(pip, pbuf);
380         break;
381       default :
382         return(NETWIB_ERR_PAIPTYPE);
383       }
384     }
385     break;
386   case NETWIB_IP_ENCODETYPE_HNS :
387     ret = netwib_priv_ip_buf_append_hns(pip, pbuf);
388     break;
389   default :
390     return(NETWIB_ERR_PAINVALIDTYPE);
391   }
392 
393   /* on error, restore first pos */
394   if (ret != NETWIB_ERR_OK) {
395     pbuf->endoffset = pbuf->beginoffset + savedsize;
396   }
397   return(ret);
398 }
399 
400 /*-------------------------------------------------------------*/
netwib_buf_append_iptype(netwib_iptype type,netwib_buf * pbuf)401 netwib_err netwib_buf_append_iptype(netwib_iptype type,
402                                     netwib_buf *pbuf)
403 {
404   netwib_conststring pc=NULL;
405 
406   switch(type) {
407     case NETWIB_IPTYPE_IP4 :
408       pc = "IPv4";
409       break;
410     case NETWIB_IPTYPE_IP6 :
411       pc = "IPv6";
412       break;
413     default :
414       return(NETWIB_ERR_PAIPTYPE);
415   }
416 
417   netwib_er(netwib_buf_append_string(pc, pbuf));
418   return(NETWIB_ERR_OK);
419 }
420 
421 /*-------------------------------------------------------------*/
422 #define NETWIB_PRIV_IPTYPE_MAX 10
netwib_iptype_init_kbd(netwib_constbuf * pmessage,netwib_iptype defaulttype,netwib_iptype * ptype)423 netwib_err netwib_iptype_init_kbd(netwib_constbuf *pmessage,
424                                   netwib_iptype defaulttype,
425                                   netwib_iptype *ptype)
426 {
427   netwib_iptype array[NETWIB_PRIV_IPTYPE_MAX];
428   netwib_buf msg, buf;
429   netwib_uint32 i, choice, defaultchoice;
430 
431   netwib_er(netwib_buf_init_mallocdefault(&buf));
432   if (pmessage != NULL) {
433     netwib_er(netwib_buf_append_buf(pmessage, &buf));
434     netwib_er(netwib_buf_append_string("\n", &buf));
435   }
436 
437   i = 0;
438   defaultchoice = NETWIB_UINT32_INIT_KBD_NODEF;
439 
440 #define netwib_iptype_lih(ot) {netwib_er(netwib_buf_append_fmt(&buf, " %{r 2;uint32} - ", i)); netwib_er(netwib_buf_append_iptype(ot, &buf)); netwib_er(netwib_buf_append_fmt(&buf, "\n")); if (defaulttype == ot) defaultchoice = i; array[i++] = ot; }
441 
442   netwib_iptype_lih(NETWIB_IPTYPE_IP4);
443   netwib_iptype_lih(NETWIB_IPTYPE_IP6);
444 
445   if (i >= NETWIB_PRIV_IPTYPE_MAX) {
446     return(NETWIB_ERR_LOINTERNALERROR);
447   }
448   netwib_er(netwib_buf_display(&buf, NETWIB_ENCODETYPE_DATA));
449   netwib_er(netwib_buf_close(&buf));
450 
451   if (defaulttype == NETWIB_IPTYPE_UNKNOWN) {
452     defaultchoice = NETWIB_UINT32_INIT_KBD_NODEF;
453   }
454 
455   netwib_er(netwib_buf_init_ext_string("Your choice", &msg));
456   netwib_er(netwib_uint32_init_kbd(&msg, 0, i-1, defaultchoice,
457                                  &choice));
458 
459   if (ptype != NULL) *ptype = array[choice];
460   return(NETWIB_ERR_OK);
461 }
462