2 * Acess2 Networking Toolkit
3 * By John Hodge (thePowersGang)
14 static inline uint32_t htonl(uint32_t v)
16 return (((v >> 24) & 0xFF) << 0)
17 | (((v >> 16) & 0xFF) << 8)
18 | (((v >> 8) & 0xFF) << 16)
19 | (((v >> 0) & 0xFF) << 24);
21 static inline uint16_t htons(uint16_t v)
23 return (((v >> 8) & 0xFF) << 0)
24 | (((v >> 0) & 0xFF) << 8);
27 #define ntohl(v) htonl(v)
28 #define ntohs(v) htons(v)
31 #define __thread // Disable TLS
34 * \brief Read an IPv4 Address
35 * \param String IPv4 dotted decimal address
36 * \param Addr Output 32-bit representation of IP address
37 * \return Boolean success
39 static int Net_ParseIPv4Addr(const char *String, uint8_t *Addr)
42 const char *pos = String;
44 for( j = 0; *pos && j < 4; j ++ )
47 unsigned long val = strtoul(pos, &end, 10);
48 if( *end && *end != '.' ) {
50 _SysDebug("%s: Unexpected character, '%c' found", __func__, *end);
56 _SysDebug("%s: Two dots in a row", __func__);
62 _SysDebug("%s: val > 255 (%i)", __func__, val);
67 _SysDebug("%s: Comp '%.*s' = %lu", __func__, end - pos, pos, val);
78 _SysDebug("%s: 4 parts expected, %i found", __func__, j);
84 _SysDebug("%s: EOS != '\\0', '%c'", __func__, *pos);
92 * \brief Read an IPv6 Address
93 * \param String IPv6 colon-hex representation
94 * \param Addr Output 128-bit representation of IP address
95 * \return Boolean success
97 static int Net_ParseIPv6Addr(const char *String, uint8_t *Addr)
101 int val, split = -1, end;
102 uint16_t hi[8], low[8];
104 for( j = 0; String[i] && j < 8; j ++ )
106 if(String[i] == ':') {
109 printf("Two '::'s\n");
119 for( k = 0; String[i] && String[i] != ':'; i++, k++ )
122 if('0' <= String[i] && String[i] <= '9')
123 val += String[i] - '0';
124 else if('A' <= String[i] && String[i] <= 'F')
125 val += String[i] - 'A' + 10;
126 else if('a' <= String[i] && String[i] <= 'f')
127 val += String[i] - 'a' + 10;
130 printf("%c unexpected\n", String[i]);
138 printf("val (0x%x) > 0xFFFF\n", val);
148 if( String[i] == ':' ) {
154 // Create final address
156 for( j = 0; j < split; j ++ )
158 Addr[j*2] = hi[j]>>8;
159 Addr[j*2+1] = hi[j]&0xFF;
162 for( ; j < 8 - (end - split); j++ )
169 for( ; j < 8; j ++, k++)
171 Addr[j*2] = low[k]>>8;
172 Addr[j*2+1] = low[k]&0xFF;
179 * \brief Parse an address from a string
180 * \param String String containing an IPv4/IPv6 address
181 * \param Addr Buffer for the address (must be >= 16 bytes)
182 * \return Address type
183 * \retval 0 Unknown address type
184 * \retval 4 IPv4 Address
185 * \retval 6 IPv6 Address
187 int Net_ParseAddress(const char *String, void *Addr)
189 if( Net_ParseIPv4Addr(String, Addr) )
192 if( Net_ParseIPv6Addr(String, Addr) )
198 static const char *Net_PrintIPv4Address(const uint8_t *Address)
200 static __thread char ret[4*3+3+1]; // '255.255.255.255\0'
202 sprintf(ret, "%i.%i.%i.%i", Address[0], Address[1], Address[2], Address[3]);
207 static const char *Net_PrintIPv6Address(const uint16_t *Address)
209 static __thread char ret[8*4+7+1]; // 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF\0'
211 // TODO: Zero compression
212 int zeroStart = 0, zeroEnd = 8;
213 for( i = 0; i < 8; i ++ ) {
218 sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x",
219 ntohs(Address[0]), ntohs(Address[1]), ntohs(Address[2]), ntohs(Address[3]),
220 ntohs(Address[4]), ntohs(Address[5]), ntohs(Address[6]), ntohs(Address[7])
226 const char *Net_PrintAddress(int AddressType, const void *Address)
228 switch( AddressType )
233 return Net_PrintIPv4Address(Address);
236 return Net_PrintIPv6Address(Address);