Drizzled Public API Documentation

ipv6.h
1 /*
2  Original copyright header listed below. This comes via rsync.
3  Any additional changes are provided via the same license as the original.
4 
5  Copyright (C) 2011 Muhammad Umair
6 
7 */
8 /*
9  * Copyright (C) 1996-2001 Internet Software Consortium.
10  *
11  * Permission to use, copy, modify, and distribute this software for any
12  * purpose with or without fee is hereby granted, provided that the above
13  * copyright notice and this permission notice appear in all copies.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
16  * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
18  * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
19  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
20  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
22  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24 
25 #pragma once
26 
27 #include <cstdio>
28 #include <cstring>
29 #include <iostream>
30 
31 namespace drizzled
32 {
33 namespace type
34 {
35 
36 class IPv6 {
37 
38  struct ipv6_ds
39  {
40  unsigned short ip6[8];
41  } str;
42 
43  //Function to store the IPv4 address in IPv6 Data Structure
44  int ipv4_inet_pton(const char *src)
45  {
46  char *ptr_src ;
47  char ipv4_map_ipv6[20], ipv4[16], octet_1[5], octet_2[5], concat_octets[20];
48  int octet[4], octet_index = 0 , dot_count = 0;
49 
50  static const char hex[] = "0123456789";
51  const char * char_ptr_src;
52 
53  memset(ipv4_map_ipv6, 0, sizeof(ipv4_map_ipv6));
54  strcpy(ipv4_map_ipv6, src);
55 
56  memset(octet, 0, sizeof(octet));
57  memset(ipv4, 0, sizeof(ipv4));
58  memset(octet_1, 0, sizeof(octet_1));
59  memset(octet_2, 0, sizeof(octet_2));
60  memset(concat_octets, 0, sizeof(concat_octets));
61 
62  ptr_src = ipv4_map_ipv6;
63 
64  if (*ptr_src == ':' && *++ptr_src != ':')
65  return 0; // Invalid IP Address
66 
67  if (*ptr_src == ':' && *++ptr_src == ':')
68  ++ptr_src;
69 
70  strcpy(ipv4,ptr_src);
71 
72  ptr_src = ipv4;
73 
74  while(*ptr_src != '\0')
75  {
76  dot_count++;
77 
78  if (*ptr_src == '.' && *++ptr_src != '.')
79  {
80  if (dot_count == 1)
81  return 0; // Invalid IP Address
82  }
83 
84  char_ptr_src = strchr (hex, *ptr_src);
85 
86  if(char_ptr_src == NULL)
87  {
88  return 0; // Invalid IP Address
89  }
90  ++ptr_src;
91  }
92 
93  ptr_src = ipv4;
94 
95  while(*ptr_src != '\0')
96  {
97  if ( *ptr_src == ':' && *++ptr_src == '\0')
98  {
99  return 0; // Invalid IP Address
100  }
101 
102  if ( *ptr_src == '.' && *++ptr_src == '\0')
103  {
104  return 0; // Invalid IP Address
105  }
106  ++ptr_src;
107  }
108 
109  ptr_src = strtok(ipv4,".");
110 
111  while (ptr_src != '\0')
112  {
113  sscanf(ptr_src, "%d", &octet[octet_index]);
114 
115  if(octet[octet_index++] > 255)
116  {
117  return 0; // Invalid IP Address
118  }
119 
120  ptr_src = strtok (NULL, ".");
121  }// end of main while loop
122 
123  if(octet[3] == 0)
124  {
125  octet[3] = octet[2];
126  octet[2] = octet[1];
127  octet[1] = octet[0];
128  octet[0] = 0;
129  }
130 
131  if(octet_index < 3 || octet_index > 4)
132  {
133  return 0; // Invalid IP Address
134  }
135 
136  octet_index = 0;
137 
138  str.ip6[0] = str.ip6[1] = str.ip6[2] = str.ip6[3] = str.ip6[4] = str.ip6[5] = 0;
139 
140  for (int i=6 ; i <= 7; i++)
141  {
142  if (i == 7)
143  {
144  ++octet_index;
145  }
146 
147  sprintf(octet_1, "%02x", octet[octet_index]);
148 
149  sprintf(octet_2, "%02x", octet[++octet_index]);
150 
151  strcpy(concat_octets,octet_1);
152 
153  strcat(concat_octets,octet_2);
154 
155  sscanf(concat_octets,"%x",(unsigned int *)&str.ip6[i]);
156 
157  memset(octet_1, 0, sizeof(octet_1));
158 
159  memset(octet_2, 0, sizeof(octet_2));
160 
161  memset(concat_octets, 0, sizeof(concat_octets));
162  }
163 
164  return 1;
165  }//end of ipv4_inet_pton() function
166 
167  //Function to retain the IPv4 address from IPv6 Data Structure
168  char * ipv4_inet_ntop(char *destination)
169  {
170  memset(destination, 0, sizeof(destination));
171 
172  snprintf(destination, IPV6_BUFFER_LENGTH, "%03x:%03x:%03x:%03x:%03x:%03x:%03d.%03d.%03d.%03d" ,
173  str.ip6[0],str.ip6[1],str.ip6[2],str.ip6[3],str.ip6[4],str.ip6[5],
174  (((unsigned int )str.ip6[6]>>8) & 0xFF),
175  ((unsigned int )str.ip6[6] & 0xFF),
176  (((unsigned int )str.ip6[7]>>8) & 0xFF),
177  ((unsigned int )str.ip6[7] & 0xFF));
178 
179  return destination;
180 
181  }// end of ipv4_inet_ntop function
182 
183 
184  //Function to store the IPv6 address in IPv6 Data Structure
185  int ipv6_inet_pton(const char *src)
186  {
187  if (strlen(src)> IPV6_DISPLAY_LENGTH)
188  {
189  return 0; //Invalid IPaddress
190  }
191 
192  //Local variables
193  char ipv6[IPV6_BUFFER_LENGTH];
194 
195  memset(ipv6, 0, IPV6_BUFFER_LENGTH);
196 
197  strcpy(ipv6,src);
198 
199  char ipv6_temp[IPV6_BUFFER_LENGTH], ipv6_temp1[IPV6_BUFFER_LENGTH], ipv6_temp2[IPV6_BUFFER_LENGTH];
200 
201  memset(ipv6_temp, 0, IPV6_BUFFER_LENGTH);
202 
203  strcpy(ipv6_temp, ipv6);
204 
205  memset(ipv6_temp1, 0, IPV6_BUFFER_LENGTH);
206 
207  strcpy(ipv6_temp1, ipv6);
208 
209  memset(ipv6_temp2, 0, IPV6_BUFFER_LENGTH);
210 
211  strcpy(ipv6_temp2,ipv6);
212 
213 
214  static const char hex[] = "0123456789abcdef";
215  char temp[IPV6_BUFFER_LENGTH];
216  char *ptr_src ,*ptr_char, *ptr_src1;
217  const char *char_ptr_src; // get the src char
218  int char_int = 0, index_ip6 = 0, octet_count = 0, not_colon = 0, colon = 0, count_colon = 0;
219  char temp_first[IPV6_BUFFER_LENGTH],temp_end[IPV6_BUFFER_LENGTH];
220 
221  memset(temp_first, 0, IPV6_BUFFER_LENGTH);
222 
223  memset(temp_end, 0, IPV6_BUFFER_LENGTH);
224 
225  ptr_src = ipv6;
226  //while loop check three consective colons
227  while (*ptr_src != '\0')
228  {
229 
230  if (*ptr_src == ':' && *++ptr_src == ':' && *++ptr_src == ':')
231  {
232  return 0; // Invalid IP Address
233  }
234 
235  ++ptr_src;
236  }
237 
238  ptr_src = ipv6;
239 
240  //Check first colon position
241  while (*ptr_src != '\0')
242  {
243  count_colon++;
244 
245  if (*ptr_src == ':' && *++ptr_src != ':')
246  {
247  if (count_colon == 1)
248  return 0; // Invalid IP Address
249  }
250 
251  ++ptr_src;
252  }
253 
254  ptr_src = ipv6;
255 
256  //Check last colon position
257  while (*ptr_src != '\0')
258  {
259  if ( *ptr_src == ':' && *++ptr_src == '\0')
260  {
261  return 0; // Invalid IP Address
262  }
263 
264  ++ptr_src;
265  }
266 
267  count_colon = 0;
268 
269  //while loop count the total number of octets
270  ptr_src = strtok (ipv6_temp2,":");
271 
272 
273  while (ptr_src != NULL)
274  {
275  octet_count++;
276 
277  ptr_src = strtok (NULL, ":");
278  }
279  //Retrun zero if total number of octets are greater than 8
280  if(octet_count > 8)
281  {
282  return 0 ; // Invalid IP Address
283  }
284 
285  bool colon_flag = true;
286  ptr_src = ipv6;
287 
288  //Check the existance of consective two colons
289  while (*ptr_src != '\0')
290  {
291  if (*ptr_src == ':' && *++ptr_src == ':')
292  {
293  colon_flag = false;
294  }
295  ++ptr_src;
296  }
297 
298  if (colon_flag == true && octet_count < 8)
299  {
300  return 0;
301  }
302 
303  int num_miss_octet =0;
304 
305  num_miss_octet = 8 - octet_count;
306 #if 0
307  size = 2*num_miss_octet +1;
308 #endif
309 
310  std::string zero_append;
311 
312  ptr_src = ipv6_temp;
313 
314  //while loop locate the "::" position (start,middle or end)
315  while(*ptr_src != '\0')
316  {
317  if(*ptr_src == ':' && *++ptr_src == ':')
318  {
319  if (*++ptr_src=='\0')
320  {
321  colon =2;
322  }
323  else if (not_colon == 0)
324  {
325  colon=1;
326  }
327  else
328  {
329  colon=3;
330  }
331 
332  count_colon++;
333 
334  if(count_colon == 2)
335  {
336  return 0; // Invalid IP Address. Ther must be single time double colon '::'
337  }
338  }
339 
340  ptr_src++;
341  not_colon++;
342  }// end of while loop
343 
344  // if colon = 0 means the IPv6 Address string is in presffered form otherwise first it covert it into prefeered form
345  if(colon>0)
346  {
347  //zero padding format according to the '::' position
348  zero_append+= "";
349 
350  for (int i= 0; i < num_miss_octet; i++)
351  {
352  if(colon==1) // start
353  {
354  zero_append+= "0:";
355  }
356 
357  if(colon==2 || colon==3) //middle or end colon =2 shows at end
358  {
359  zero_append+= ":0";
360  }
361  }
362 
363  if(colon==3)
364  {
365  zero_append+= ":";
366  }
367 
368  ptr_src = temp_end;
369 
370  if(colon==1 || colon==3)
371  { //only for start and middle
372 
373  ptr_src1 = strstr (ipv6_temp,"::");
374 
375  ptr_src1 = ptr_src1+2;
376 
377  while(*ptr_src1 != '\0')
378  {
379  *ptr_src++ = *ptr_src1++;
380 
381  if(*ptr_src1 == '\0')
382  {
383  *ptr_src ='\0';
384  }
385  }
386  }
387 
388  //copy the input IPv6 string before and after '::'
389  ptr_src1 = strstr (ipv6_temp1,"::");
390 
391  *ptr_src1 ='\0';
392 
393  strcpy(temp_first,ipv6_temp1);
394 
395  if(colon==2) // end
396  {
397  strcat(temp_first, zero_append.c_str());
398  }
399  else
400  {
401  strcat(temp_first, zero_append.c_str());
402 
403  strcat(temp_first,temp_end);
404  }
405 
406  memset(ipv6, 0, IPV6_BUFFER_LENGTH);
407 
408  strcpy(ipv6,temp_first);
409  }// end of main if statement
410 
411 
412 
413  //while loop store each octet on ipv6 struture in decimal value of hexadecimal digits
414  ptr_char = temp;
415 
416  ptr_src = strtok (ipv6,":");
417 
418 
419  while (ptr_src != NULL)
420  {
421  strcpy(temp, ptr_src);
422 
423  ptr_char = temp;
424 
425  int octet_length = strlen(ptr_char);
426 
427  *(ptr_char + octet_length) = '\0';
428 
429 
430  while(*ptr_char != '\0')
431  {
432  char_int = tolower(*ptr_char);
433 
434  char_ptr_src = strchr (hex, char_int);
435 
436  if(char_ptr_src == NULL)
437  {
438  return 0; // Invalid IP Address
439 
440  }
441 
442  *ptr_char = *char_ptr_src;
443  ptr_char++;
444  }//end of inner while loop
445 
446  ptr_char -= octet_length;
447 
448  unsigned int ptr_char_val = 0;
449 
450  sscanf(ptr_char, "%x", (unsigned int *)&ptr_char_val);
451 
452  //check if "xxxx" value greater than "ffff=65535"
453  if (ptr_char_val > 65535)
454  {
455  str.ip6[0] = str.ip6[1] = str.ip6[2] = str.ip6[3] = str.ip6[4] = str.ip6[5] = str.ip6[6] = str.ip6[7] = 0;
456  return 0;
457  }
458 
459  unsigned int *ptr = (unsigned int *)&(str.ip6[index_ip6++]);
460 
461  sscanf(ptr_char, "%x", ptr);
462 
463  memset(temp, 0, IPV6_BUFFER_LENGTH);
464 
465  ptr_src = strtok (NULL, ":");
466  }// end of main while loop
467 
468  return 1;
469  }// end of Ipv6_Inet_pton function
470 
471  //Function to retain the IPv6 address from IPv6 Data Structure
472  char* ipv6_inet_ntop(char *destination)
473  {
474  char temp[10];
475 
476  memset(temp, 0, sizeof(temp));
477 
478  memset(destination, 0, IPV6_BUFFER_LENGTH);
479 
480 
481  for (int i= 0; i <= 7; i++)
482  {
483  if(i==7)
484  {
485  sprintf(temp,"%04x",str.ip6[i]);
486 
487  strcat(destination,temp);
488  }
489  else
490  {
491  sprintf(temp,"%04x:",str.ip6[i]);
492 
493  strcat(destination,temp);
494  }
495 
496  memset(temp, 0, sizeof(temp));
497  }
498 
499 
500  return destination;
501  }// end of Ipv6_Inet_ntop function
502 
503 
504  public:
505 
506  IPv6()
507  {
508  str.ip6[0] = str.ip6[1] = str.ip6[2] = str.ip6[3] = str.ip6[4] = str.ip6[5] = str.ip6[6] = str.ip6[7] = 0;
509  }
510 
511 
512  void store_object(unsigned char *out)
513  {
514  memcpy(out, (unsigned char *)&str, sizeof(str));
515  }
516 
517  void restore_object(const unsigned char * in)
518  {
519  memcpy(&str, (struct ipv6_ds *)in, sizeof(str));
520  }
521 
522  int inet_pton(const char *ip)
523  {
524  char * pch;
525 
526  pch=strchr((char *)ip,'.');
527 
528  if(pch == NULL)
529  {
530  return ipv6_inet_pton(ip);
531  }
532  else
533  {
534  return ipv4_inet_pton(ip);
535  }
536  }
537 
538  char * inet_ntop(char *dest)
539  {
540  if (str.ip6[0]==0 && str.ip6[1]==0 && str.ip6[2]==0 && str.ip6[3]==0 && str.ip6[4]==0 && str.ip6[5]==0 && str.ip6[6]!=0)
541  {
542  return ipv4_inet_ntop(dest);
543  }
544  else
545  {
546  return ipv6_inet_ntop(dest);
547  }
548  }
549 
550  static const size_t LENGTH= 16;
551  static const size_t IPV6_DISPLAY_LENGTH= 39;
552  static const size_t IPV6_BUFFER_LENGTH= IPV6_DISPLAY_LENGTH+1;
553 
554 }; // endof class
555 
556 } /* namespace type */
557 } /* namespace drizzled */
558 
TODO: Rename this file - func.h is stupid.