~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/type/ipv6.h

  • Committer: Muhammad Umair
  • Date: 2011-08-16 11:47:29 UTC
  • mto: This revision was merged to the branch mainline in revision 2402.
  • Revision ID: umair@remotedesk-20110816114729-w6x88fj0sow4g3z9
mergeĀ lp:~mumair/drizzle/drizzle-IPv6Address

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
47
            char *ptr_src ;
 
48
 
 
49
            char ipv4_map_ipv6[20],ipv4[16], octet_1[5],octet_2[5],concat_octets[20];
 
50
            int octet[4],octet_index = 0;
 
51
 
 
52
            memset(ipv4_map_ipv6, NULL, sizeof(ipv4_map_ipv6));
 
53
            strcpy(ipv4_map_ipv6,src);
 
54
 
 
55
            memset(octet, NULL, sizeof(octet));
 
56
            memset(ipv4, NULL, sizeof(ipv4));
 
57
            memset(octet_1, NULL, sizeof(octet_1));
 
58
            memset(octet_2, NULL, sizeof(octet_2));
 
59
            memset(concat_octets, NULL, sizeof(concat_octets));
 
60
 
 
61
            ptr_src = strtok(ipv4_map_ipv6,"::");
 
62
 
 
63
            strcpy(ipv4,ptr_src);
 
64
 
 
65
            ptr_src = strtok(ipv4,".");
 
66
 
 
67
            while (ptr_src != '\0')
 
68
            {
 
69
 
 
70
                sscanf( ptr_src,"%d", &octet[octet_index]);
 
71
 
 
72
                 if(octet[octet_index++] > 255)
 
73
                 {
 
74
                    return 0; // Invalid IP Address
 
75
                 }
 
76
 
 
77
                ptr_src = strtok (NULL, ".");
 
78
 
 
79
            }// end of main while loop
 
80
 
 
81
 
 
82
            if(octet_index < 4 || octet_index > 4)
 
83
            {
 
84
                return 0; // Invalid IP Address
 
85
            }
 
86
 
 
87
 
 
88
            octet_index = 0;
 
89
 
 
90
            str.ip6[0] = str.ip6[1] = str.ip6[2] = str.ip6[3] = str.ip6[4] = str.ip6[5] = 0;
 
91
 
 
92
            for (int i=6 ; i <= 7; i++)
 
93
            {
 
94
                if (i == 7)
 
95
                {
 
96
                    ++octet_index;
 
97
                }
 
98
 
 
99
                sprintf(octet_1, "%02x", octet[octet_index]);
 
100
 
 
101
                sprintf(octet_2, "%02x", octet[++octet_index]);
 
102
 
 
103
                strcpy(concat_octets,octet_1);
 
104
 
 
105
                strcat(concat_octets,octet_2);
 
106
 
 
107
                sscanf(concat_octets,"%x",(unsigned int *)&str.ip6[i]);
 
108
 
 
109
                memset(octet_1, NULL, sizeof(octet_1));
 
110
 
 
111
                memset(octet_2, NULL, sizeof(octet_2));
 
112
 
 
113
                memset(concat_octets, NULL, sizeof(concat_octets));
 
114
            }
 
115
 
 
116
            return 1;
 
117
    }//end of ipv4_inet_pton() function
 
118
 
 
119
    //Function to retain the IPv4 address from IPv6 Data Structure
 
120
    char * ipv4_inet_ntop(char *destination)
 
121
    {
 
122
 
 
123
            memset(destination,NULL,sizeof(destination));
 
124
 
 
125
            snprintf( destination ,IPV6_BUFFER_LENGTH, "%03x:%03x:%03x:%03x:%03x:%03x:%03d.%03d.%03d.%03d" ,
 
126
            str.ip6[0],str.ip6[1],str.ip6[2],str.ip6[3],str.ip6[4],str.ip6[5],
 
127
            (((unsigned int )str.ip6[6]>>8) & 0xFF),
 
128
            ((unsigned int )str.ip6[6] & 0xFF),
 
129
            (((unsigned int )str.ip6[7]>>8) & 0xFF),
 
130
            ((unsigned int )str.ip6[7] & 0xFF));
 
131
 
 
132
            return destination;
 
133
 
 
134
     }// end of ipv4_inet_ntop function
 
135
 
 
136
 
 
137
    //Function to store the IPv6 address in IPv6 Data Structure
 
138
    int ipv6_inet_pton(const char *src)
 
139
    {
 
140
        //Local variables
 
141
        char ipv6[IPV6_BUFFER_LENGTH];
 
142
        
 
143
        memset(ipv6,NULL,IPV6_BUFFER_LENGTH);
 
144
        
 
145
        strcpy(ipv6,src);
 
146
        
 
147
        char ipv6_temp[IPV6_BUFFER_LENGTH], ipv6_temp1[IPV6_BUFFER_LENGTH], ipv6_temp2[IPV6_BUFFER_LENGTH];
 
148
 
 
149
        memset(ipv6_temp,NULL,IPV6_BUFFER_LENGTH);
 
150
 
 
151
        strcpy(ipv6_temp,ipv6);
 
152
 
 
153
        memset(ipv6_temp1,NULL,IPV6_BUFFER_LENGTH);
 
154
 
 
155
        strcpy(ipv6_temp1,ipv6);
 
156
 
 
157
        memset(ipv6_temp2,NULL,IPV6_BUFFER_LENGTH);
 
158
 
 
159
        strcpy(ipv6_temp2,ipv6);
 
160
 
 
161
 
 
162
        static const char hex[] = "0123456789abcdef";
 
163
        char temp[IPV6_BUFFER_LENGTH];
 
164
        char *ptr_src ,*ptr_char, *ptr_src1;
 
165
        const char *char_ptr_src;  // get the src char
 
166
        int char_int = NULL, index_ip6 = 0 ,octet_count=0, not_colon = 0, colon =0, count_colon = 0;
 
167
        char temp_first[IPV6_BUFFER_LENGTH],temp_end[IPV6_BUFFER_LENGTH];
 
168
 
 
169
        memset(temp_first, NULL,IPV6_BUFFER_LENGTH);
 
170
 
 
171
        memset(temp_end, NULL,IPV6_BUFFER_LENGTH);
 
172
 
 
173
        ptr_src = ipv6;
 
174
        //while loop check three consective colons
 
175
         while (*ptr_src != '\0')
 
176
         {
 
177
 
 
178
            if (*ptr_src == ':' && *++ptr_src == ':' && *++ptr_src == ':')
 
179
            {
 
180
                return 0; // Invalid IP Address
 
181
            }
 
182
 
 
183
            ++ptr_src;
 
184
          }
 
185
 
 
186
        //while loop count the total number of octets
 
187
        ptr_src = strtok (ipv6_temp2,":");
 
188
 
 
189
 
 
190
        while (ptr_src != NULL)
 
191
        {
 
192
            octet_count++;
 
193
 
 
194
            ptr_src = strtok (NULL, ":");
 
195
        }
 
196
 
 
197
        //Retrun zero if total number of octets are greater than 8
 
198
        if(octet_count > 8)
 
199
        {
 
200
            return 0 ; // Invalid IP Address
 
201
        }
 
202
 
 
203
        int num_miss_octet =0, size =0; 
 
204
 
 
205
        num_miss_octet = 8 - octet_count;
 
206
        size = 2*num_miss_octet +1;
 
207
        
 
208
        char * zero_append = new char[size];
 
209
 
 
210
        memset(zero_append,NULL,sizeof(zero_append));
 
211
 
 
212
 
 
213
        ptr_src = ipv6_temp;
 
214
 
 
215
        //while loop locate the "::" position (start,middle or end)
 
216
        while(*ptr_src != '\0')
 
217
        {
 
218
            if(*ptr_src == ':' && *++ptr_src == ':')
 
219
            {
 
220
                if (*++ptr_src=='\0')
 
221
                {
 
222
                    colon =2;
 
223
                }
 
224
                else if (not_colon == 0)
 
225
                {
 
226
                    colon=1;
 
227
                }
 
228
                else
 
229
                {
 
230
                    colon=3;
 
231
                }
 
232
 
 
233
                count_colon++;
 
234
 
 
235
                if(count_colon == 2)
 
236
                {
 
237
                    return 0; // Invalid IP Address. Ther must be single time double  colon '::'
 
238
                }
 
239
            }
 
240
 
 
241
            ptr_src++;
 
242
            not_colon++;
 
243
        }// end of while loop
 
244
 
 
245
        // if colon = 0 means the IPv6 Address string is in presffered form otherwise first it covert it into prefeered form
 
246
        if(colon>0)
 
247
        {
 
248
            //zero padding format according to the '::' position
 
249
            strcpy(zero_append,"");
 
250
 
 
251
 
 
252
            for (int i= 0; i < num_miss_octet; i++)
 
253
            {
 
254
                if(colon==1) // start
 
255
                {
 
256
                    strcat(zero_append,"0:");
 
257
                }
 
258
                if(colon==2 || colon==3)  //middle or end colon =2 shows at end
 
259
                {
 
260
                    strcat(zero_append,":0");
 
261
                }
 
262
            }
 
263
            if(colon==3)
 
264
            {
 
265
                strcat(zero_append,":");
 
266
            }
 
267
 
 
268
            ptr_src = temp_end;
 
269
 
 
270
            if(colon==1 || colon==3)
 
271
            {  //only for start and middle
 
272
 
 
273
              ptr_src1 = strstr (ipv6_temp,"::");
 
274
 
 
275
              ptr_src1 = ptr_src1+2;
 
276
 
 
277
              while(*ptr_src1 != '\0')
 
278
              {
 
279
                *ptr_src++ = *ptr_src1++;
 
280
 
 
281
                if(*ptr_src1 == '\0')
 
282
                {
 
283
                    *ptr_src ='\0';
 
284
                }
 
285
              }
 
286
            }
 
287
 
 
288
            //copy the input IPv6 string before and after '::'
 
289
            ptr_src1 = strstr (ipv6_temp1,"::");
 
290
 
 
291
            *ptr_src1 ='\0';
 
292
 
 
293
 
 
294
            strcpy(temp_first,ipv6_temp1);
 
295
 
 
296
            if(colon==2) // end
 
297
            {
 
298
                strcat(temp_first,zero_append);
 
299
            }
 
300
            else
 
301
            {
 
302
                strcat(temp_first,zero_append);
 
303
 
 
304
                strcat(temp_first,temp_end);
 
305
            }
 
306
 
 
307
            memset(ipv6,NULL,IPV6_BUFFER_LENGTH);
 
308
 
 
309
            strcpy(ipv6,temp_first);
 
310
        }// end of main if statement
 
311
 
 
312
 
 
313
 
 
314
        //while loop store each octet on ipv6 struture in decimal value of hexadecimal digits
 
315
        ptr_char = temp;
 
316
 
 
317
        ptr_src = strtok (ipv6,":");
 
318
 
 
319
 
 
320
        while (ptr_src != NULL)
 
321
        {
 
322
                strcpy(temp, ptr_src);
 
323
 
 
324
                ptr_char = temp;
 
325
 
 
326
                int octet_length = strlen(ptr_char);
 
327
 
 
328
                *(ptr_char + octet_length) = '\0';
 
329
 
 
330
 
 
331
                while(*ptr_char != '\0')
 
332
                {
 
333
                    char_int = tolower(*ptr_char);
 
334
 
 
335
                    char_ptr_src = strchr (hex, char_int);
 
336
 
 
337
                    if(char_ptr_src == NULL)
 
338
                    {
 
339
                        return 0; // Invalid IP Address
 
340
 
 
341
                    }
 
342
 
 
343
                        *ptr_char = *char_ptr_src;
 
344
                        ptr_char++;
 
345
                }//end of inner while loop
 
346
 
 
347
                ptr_char-= octet_length;
 
348
 
 
349
 
 
350
                unsigned int  *ptr  =  (unsigned int *)&(str.ip6[index_ip6++]);
 
351
 
 
352
                sscanf( ptr_char,"%x", ptr);
 
353
 
 
354
 
 
355
                memset(temp,NULL,IPV6_BUFFER_LENGTH);
 
356
 
 
357
 
 
358
                ptr_src = strtok (NULL, ":");
 
359
        }// end of main while loop
 
360
        
 
361
        delete [] zero_append;
 
362
 
 
363
        return 1;
 
364
    }// end of Ipv6_Inet_pton function
 
365
 
 
366
    //Function to retain the IPv6 address from IPv6 Data Structure
 
367
    char* ipv6_inet_ntop(char *destination)
 
368
    {
 
369
        char temp[10];
 
370
 
 
371
        memset(temp,NULL,sizeof(temp));
 
372
 
 
373
        memset(destination,NULL,IPV6_BUFFER_LENGTH);
 
374
        
 
375
    
 
376
        for (int i= 0; i <= 7; i++)
 
377
        {
 
378
            if(i==7)
 
379
            {
 
380
                sprintf(temp,"%04x",str.ip6[i]);
 
381
 
 
382
                strcat(destination,temp);
 
383
            }
 
384
            else
 
385
            {
 
386
                sprintf(temp,"%04x:",str.ip6[i]);
 
387
 
 
388
                strcat(destination,temp);
 
389
            }
 
390
 
 
391
            memset(temp,NULL,sizeof(temp));
 
392
        }
 
393
 
 
394
 
 
395
        return destination;
 
396
    }// end of Ipv6_Inet_ntop function
 
397
 
 
398
 
 
399
    public:
 
400
 
 
401
    IPv6()
 
402
    {
 
403
        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;    
 
404
    }
 
405
 
 
406
 
 
407
    void store_object(unsigned char *out)
 
408
    {
 
409
        memcpy(out, (unsigned char *)&str, sizeof(str));
 
410
    }
 
411
 
 
412
    void restore_object(const unsigned char * in)
 
413
    {
 
414
        memcpy(&str, (struct ipv6_ds *)in,  sizeof(str));
 
415
    } 
 
416
 
 
417
    int inet_pton(const char *ip)
 
418
    {
 
419
         char * pch;
 
420
 
 
421
         pch=strchr((char *)ip,'.');
 
422
 
 
423
         if(pch == NULL)
 
424
         {
 
425
            return ipv6_inet_pton(ip);
 
426
         }
 
427
         else
 
428
         {
 
429
            return ipv4_inet_pton(ip);
 
430
         }
 
431
    }
 
432
 
 
433
    char * inet_ntop(char *dest)
 
434
    {
 
435
        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)
 
436
        {
 
437
            return ipv4_inet_ntop(dest);
 
438
        }
 
439
        else
 
440
        {
 
441
            return ipv6_inet_ntop(dest);
 
442
        }
 
443
    }
 
444
    
 
445
    static const size_t LENGTH= 16;
 
446
    static const size_t IPV6_DISPLAY_LENGTH= 39;
 
447
    static const size_t IPV6_BUFFER_LENGTH= IPV6_DISPLAY_LENGTH+1;
 
448
 
 
449
};  // endof class
 
450
 
 
451
} /* namespace type */
 
452
} /* namespace drizzled */
 
453
 
 
454