Composite commit (GUI / Networking)
[tpg/acess2.git] / Usermode / Libraries / libnet.so_src / address.c
diff --git a/Usermode/Libraries/libnet.so_src/address.c b/Usermode/Libraries/libnet.so_src/address.c
new file mode 100644 (file)
index 0000000..2b58444
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Acess2 Networking Toolkit
+ * By John Hodge (thePowersGang)
+ * 
+ * address.c
+ * - Address Parsing
+ */
+#include <net.h>
+#include <stdint.h>
+#define DEBUG  0
+
+/**
+ * \brief Read an IPv4 Address
+ * \param String       IPv4 dotted decimal address
+ * \param Addr Output 32-bit representation of IP address
+ * \return Boolean success
+ */
+static int Net_ParseIPv4Addr(const char *String, uint8_t *Addr)
+{
+        int    i = 0;
+        int    j;
+        int    val;
+       
+       for( j = 0; String[i] && j < 4; j ++ )
+       {
+               val = 0;
+               for( ; String[i] && String[i] != '.'; i++ )
+               {
+                       if('0' > String[i] || String[i] > '9') {
+                               #if DEBUG
+                               printf("0<c<9 expected, '%c' found\n", String[i]);
+                               #endif
+                               return 0;
+                       }
+                       val = val*10 + String[i] - '0';
+               }
+               if(val > 255) {
+                       #if DEBUG
+                       printf("val > 255 (%i)\n", val);
+                       #endif
+                       return 0;
+               }
+               Addr[j] = val;
+               
+               if(String[i] == '.')
+                       i ++;
+       }
+       if( j != 4 ) {
+               #if DEBUG
+               printf("4 parts expected, %i found\n", j);
+               #endif
+               return 0;
+       }
+       if(String[i] != '\0') {
+               #if DEBUG
+               printf("EOS != '\\0', '%c'\n", String[i]);
+               #endif
+               return 0;
+       }
+       return 1;
+}
+
+/**
+ * \brief Read an IPv6 Address
+ * \param String       IPv6 colon-hex representation
+ * \param Addr Output 128-bit representation of IP address
+ * \return Boolean success
+ */
+static int Net_ParseIPv6Addr(const char *String, uint8_t *Addr)
+{
+        int    i = 0;
+        int    j, k;
+        int    val, split = -1, end;
+       uint16_t        hi[8], low[8];
+       
+       for( j = 0; String[i] && j < 8; j ++ )
+       {
+               if(String[i] == ':') {
+                       if(split != -1) {
+                               #if DEBUG
+                               printf("Two '::'s\n");
+                               #endif
+                               return 0;
+                       }
+                       split = j;
+                       i ++;
+                       continue;
+               }
+               
+               val = 0;
+               for( k = 0; String[i] && String[i] != ':'; i++, k++ )
+               {
+                       val *= 16;
+                       if('0' <= String[i] && String[i] <= '9')
+                               val += String[i] - '0';
+                       else if('A' <= String[i] && String[i] <= 'F')
+                               val += String[i] - 'A' + 10;
+                       else if('a' <= String[i] && String[i] <= 'f')
+                               val += String[i] - 'a' + 10;
+                       else {
+                               #if DEBUG
+                               printf("%c unexpected\n", String[i]);
+                               #endif
+                               return 0;
+                       }
+               }
+               
+               if(val > 0xFFFF) {
+                       #if DEBUG
+                       printf("val (0x%x) > 0xFFFF\n", val);
+                       #endif
+                       return 0;
+               }
+               
+               if(split == -1)
+                       hi[j] = val;
+               else
+                       low[j-split] = val;
+               
+               if( String[i] == ':' ) {
+                       i ++;
+               }
+       }
+       end = j;
+       
+       // Create final address
+       // - First section
+       for( j = 0; j < split; j ++ )
+       {
+               Addr[j*2] = hi[j]>>8;
+               Addr[j*2+1] = hi[j]&0xFF;
+       }
+       // - Zero region
+       for( ; j < 8 - (end - split); j++ )
+       {
+               Addr[j*2] = 0;
+               Addr[j*2+1] = 0;
+       }
+       // - Tail section
+       k = 0;
+       for( ; j < 8; j ++, k++)
+       {
+               Addr[j*2] = hi[k]>>8;
+               Addr[j*2+1] = hi[k]&0xFF;
+       }
+       
+       return 1;
+}
+
+/**
+ * \brief Parse an address from a string
+ * \param String       String containing an IPv4/IPv6 address
+ * \param Addr Buffer for the address (must be >= 16 bytes)
+ * \return Address type
+ * \retval 0   Unknown address type
+ * \retval 4   IPv4 Address
+ * \retval 6   IPv6 Address
+ */
+int Net_ParseAddress(const char *String, void *Addr)
+{
+       if( Net_ParseIPv4Addr(String, Addr) )
+               return 4;
+       
+       if( Net_ParseIPv6Addr(String, Addr) )
+               return 6;
+       
+       return 0;
+}

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