31b23e513e2348eb15fc6c7c354f62442e9a52bb
[tpg/acess2.git] / Usermode / Libraries / libnet.so_src / address.c
1 /*
2  * Acess2 Networking Toolkit
3  * By John Hodge (thePowersGang)
4  * 
5  * address.c
6  * - Address Parsing
7  */
8 #include <net.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #define DEBUG   0
12
13 #define __thread                // Disable TLS
14
15 /**
16  * \brief Read an IPv4 Address
17  * \param String        IPv4 dotted decimal address
18  * \param Addr  Output 32-bit representation of IP address
19  * \return Boolean success
20  */
21 static int Net_ParseIPv4Addr(const char *String, uint8_t *Addr)
22 {
23          int    i = 0;
24          int    j;
25          int    val;
26         
27         for( j = 0; String[i] && j < 4; j ++ )
28         {
29                 val = 0;
30                 for( ; String[i] && String[i] != '.'; i++ )
31                 {
32                         if('0' > String[i] || String[i] > '9') {
33                                 #if DEBUG
34                                 printf("0<c<9 expected, '%c' found\n", String[i]);
35                                 #endif
36                                 return 0;
37                         }
38                         val = val*10 + String[i] - '0';
39                 }
40                 if(val > 255) {
41                         #if DEBUG
42                         printf("val > 255 (%i)\n", val);
43                         #endif
44                         return 0;
45                 }
46                 Addr[j] = val;
47                 
48                 if(String[i] == '.')
49                         i ++;
50         }
51         if( j != 4 ) {
52                 #if DEBUG
53                 printf("4 parts expected, %i found\n", j);
54                 #endif
55                 return 0;
56         }
57         if(String[i] != '\0') {
58                 #if DEBUG
59                 printf("EOS != '\\0', '%c'\n", String[i]);
60                 #endif
61                 return 0;
62         }
63         return 1;
64 }
65
66 /**
67  * \brief Read an IPv6 Address
68  * \param String        IPv6 colon-hex representation
69  * \param Addr  Output 128-bit representation of IP address
70  * \return Boolean success
71  */
72 static int Net_ParseIPv6Addr(const char *String, uint8_t *Addr)
73 {
74          int    i = 0;
75          int    j, k;
76          int    val, split = -1, end;
77         uint16_t        hi[8], low[8];
78         
79         for( j = 0; String[i] && j < 8; j ++ )
80         {
81                 if(String[i] == ':') {
82                         if(split != -1) {
83                                 #if DEBUG
84                                 printf("Two '::'s\n");
85                                 #endif
86                                 return 0;
87                         }
88                         split = j;
89                         i ++;
90                         continue;
91                 }
92                 
93                 val = 0;
94                 for( k = 0; String[i] && String[i] != ':'; i++, k++ )
95                 {
96                         val *= 16;
97                         if('0' <= String[i] && String[i] <= '9')
98                                 val += String[i] - '0';
99                         else if('A' <= String[i] && String[i] <= 'F')
100                                 val += String[i] - 'A' + 10;
101                         else if('a' <= String[i] && String[i] <= 'f')
102                                 val += String[i] - 'a' + 10;
103                         else {
104                                 #if DEBUG
105                                 printf("%c unexpected\n", String[i]);
106                                 #endif
107                                 return 0;
108                         }
109                 }
110                 
111                 if(val > 0xFFFF) {
112                         #if DEBUG
113                         printf("val (0x%x) > 0xFFFF\n", val);
114                         #endif
115                         return 0;
116                 }
117                 
118                 if(split == -1)
119                         hi[j] = val;
120                 else
121                         low[j-split] = val;
122                 
123                 if( String[i] == ':' ) {
124                         i ++;
125                 }
126         }
127         end = j;
128         
129         // Create final address
130         // - First section
131         for( j = 0; j < split; j ++ )
132         {
133                 Addr[j*2] = hi[j]>>8;
134                 Addr[j*2+1] = hi[j]&0xFF;
135         }
136         // - Zero region
137         for( ; j < 8 - (end - split); j++ )
138         {
139                 Addr[j*2] = 0;
140                 Addr[j*2+1] = 0;
141         }
142         // - Tail section
143         k = 0;
144         for( ; j < 8; j ++, k++)
145         {
146                 Addr[j*2] = hi[k]>>8;
147                 Addr[j*2+1] = hi[k]&0xFF;
148         }
149         
150         return 1;
151 }
152
153 /**
154  * \brief Parse an address from a string
155  * \param String        String containing an IPv4/IPv6 address
156  * \param Addr  Buffer for the address (must be >= 16 bytes)
157  * \return Address type
158  * \retval 0    Unknown address type
159  * \retval 4    IPv4 Address
160  * \retval 6    IPv6 Address
161  */
162 int Net_ParseAddress(const char *String, void *Addr)
163 {
164         if( Net_ParseIPv4Addr(String, Addr) )
165                 return 4;
166         
167         if( Net_ParseIPv6Addr(String, Addr) )
168                 return 6;
169         
170         return 0;
171 }
172
173 static const char *Net_PrintIPv4Address(uint8_t *Address)
174 {
175         static __thread char    ret[4*3+3+1];   // '255.255.255.255\0'
176         
177         sprintf(ret, "%i.%i.%i.%i", Address[0], Address[1], Address[2], Address[3]);
178         
179         return ret;
180 }
181
182 static const char *Net_PrintIPv6Address(uint16_t *Address)
183 {
184         static __thread char    ret[8*4+7+1];   // 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF\0'
185         #if 0
186         // TODO: Zero compression
187          int    zeroStart = 0, zeroEnd = 8;
188         for( i = 0; i < 8; i ++ ) {
189                 if( 
190         }
191         #endif
192         
193         sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x",
194                 Address[0], Address[1], Address[2], Address[3],
195                 Address[4], Address[5], Address[6], Address[7]
196                 );
197         
198         return ret;
199 }
200
201 const char *Net_PrintAddress(int AddressType, void *Address)
202 {
203         switch( AddressType )
204         {
205         case 0: return "";
206         
207         case 4:
208                 return Net_PrintIPv4Address(Address);
209         
210         case 6:
211                 return Net_PrintIPv6Address(Address);
212                 
213         default:
214                 return "BAD";
215         }
216 }

UCC git Repository :: git.ucc.asn.au