Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Tools / NetTest / helpers.c
1 /*
2  * Acess2 Networking Test Suite (NetTest)
3  * - By John Hodge (thePowersGang)
4  *
5  * helpers.c
6  * - General purpose helper functions
7  */
8 #include <acess.h>
9 #include <vfs.h>
10 #include <IPStack/ipstack.h>
11 #include <IPStack/interface.h>
12
13 // === IMPORTS ===
14 //extern tInterface     *IPStack_AddInterface(const char *Device, int Type, const char *Name);
15 extern tVFS_Node        *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
16
17 // === PROTOTYES ===
18  int    Net_ParseAddress(const char *String, void *Addr);
19
20 // === CODE ===
21 int NetTest_AddAddress(char *SetAddrString)
22 {
23         uint8_t addr[16];
24          int    addrtype, netmask;
25         char    *ifend, *addrend, *end;
26
27         // SetAddrString:
28         // <interface>,<ip>/<netmask>
29         ifend = strchr(SetAddrString, ',');
30         *ifend = '\0';
31         addrend = strchr(ifend+1, '/');
32         *addrend = '\0';
33
34         addrtype = Net_ParseAddress(ifend+1, addr);
35         netmask = strtol(addrend+1, &end, 10);
36
37         *ifend = ',';
38         *addrend = '/';
39
40         if( *end != '\0' || addrtype == 0 )
41                 return 1;
42
43         // Create interface
44         *ifend = '\0';
45         tInterface *iface = IPStack_AddInterface(SetAddrString, addrtype, "");
46         *ifend = ',';
47         if( !iface ) {
48                 return 1;
49         }
50
51         // Set interface address
52         iface->Node.Type->IOCtl(&iface->Node, 6, addr);
53         iface->Node.Type->IOCtl(&iface->Node, 7, &netmask);
54 //      iface->Node.Type->Close(&iface->Node);
55
56         return 0;
57 }
58
59 // ----------------------------------
60 // Copy-pasta'd from userland libnet
61 // ----------------------------------
62 /**
63  * \brief Read an IPv4 Address
64  * \param String        IPv4 dotted decimal address
65  * \param Addr  Output 32-bit representation of IP address
66  * \return Boolean success
67  */
68 static int Net_ParseIPv4Addr(const char *String, uint8_t *Addr)
69 {
70          int    i = 0;
71          int    j;
72          int    val;
73         
74         for( j = 0; String[i] && j < 4; j ++ )
75         {
76                 val = 0;
77                 for( ; String[i] && String[i] != '.'; i++ )
78                 {
79                         if('0' > String[i] || String[i] > '9') {
80                                 return 0;
81                         }
82                         val = val*10 + String[i] - '0';
83                 }
84                 if(val > 255) {
85                         return 0;
86                 }
87                 Addr[j] = val;
88                 
89                 if(String[i] == '.')
90                         i ++;
91         }
92         if( j != 4 ) {
93                 return 0;
94         }
95         if(String[i] != '\0') {
96                 return 0;
97         }
98         return 1;
99 }
100
101 /**
102  * \brief Read an IPv6 Address
103  * \param String        IPv6 colon-hex representation
104  * \param Addr  Output 128-bit representation of IP address
105  * \return Boolean success
106  */
107 static int Net_ParseIPv6Addr(const char *String, uint8_t *Addr)
108 {
109          int    i = 0;
110          int    j, k;
111          int    val, split = -1, end;
112         uint16_t        hi[8], low[8];
113         
114         for( j = 0; String[i] && j < 8; j ++ )
115         {
116                 if(String[i] == ':') {
117                         if(split != -1) {
118                                 return 0;
119                         }
120                         split = j;
121                         i ++;
122                         continue;
123                 }
124                 
125                 val = 0;
126                 for( k = 0; String[i] && String[i] != ':'; i++, k++ )
127                 {
128                         val *= 16;
129                         if('0' <= String[i] && String[i] <= '9')
130                                 val += String[i] - '0';
131                         else if('A' <= String[i] && String[i] <= 'F')
132                                 val += String[i] - 'A' + 10;
133                         else if('a' <= String[i] && String[i] <= 'f')
134                                 val += String[i] - 'a' + 10;
135                         else {
136                                 return 0;
137                         }
138                 }
139                 
140                 if(val > 0xFFFF) {
141                         return 0;
142                 }
143                 
144                 if(split == -1)
145                         hi[j] = val;
146                 else
147                         low[j-split] = val;
148                 
149                 if( String[i] == ':' ) {
150                         i ++;
151                 }
152         }
153         end = j;
154         
155         // Create final address
156         // - First section
157         for( j = 0; j < split; j ++ )
158         {
159                 Addr[j*2] = hi[j]>>8;
160                 Addr[j*2+1] = hi[j]&0xFF;
161         }
162         // - Zero region
163         for( ; j < 8 - (end - split); j++ )
164         {
165                 Addr[j*2] = 0;
166                 Addr[j*2+1] = 0;
167         }
168         // - Tail section
169         k = 0;
170         for( ; j < 8; j ++, k++)
171         {
172                 Addr[j*2] = low[k]>>8;
173                 Addr[j*2+1] = low[k]&0xFF;
174         }
175         
176         return 1;
177 }
178
179 /**
180  * \brief Parse an address from a string
181  * \param String        String containing an IPv4/IPv6 address
182  * \param Addr  Buffer for the address (must be >= 16 bytes)
183  * \return Address type
184  * \retval 0    Unknown address type
185  * \retval 4    IPv4 Address
186  * \retval 6    IPv6 Address
187  */
188 int Net_ParseAddress(const char *String, void *Addr)
189 {
190         if( Net_ParseIPv4Addr(String, Addr) )
191                 return 4;
192         
193         if( Net_ParseIPv6Addr(String, Addr) )
194                 return 6;
195         
196         return 0;
197 }
198
199 int Net_OpenSocket(int AddrType, void *Addr, const char *Filename)
200 {
201          int    addrLen = IPStack_GetAddressSize(AddrType);
202          int    i;
203         uint8_t *addrBuffer = Addr;
204         char    hexAddr[addrLen*2+1];
205         
206         for( i = 0; i < addrLen; i ++ )
207                 sprintf(hexAddr+i*2, "%02x", addrBuffer[i]);
208         
209         if(Filename)
210         {
211                  int    len = snprintf(NULL, 0, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename);
212                 char    path[len+1];
213                 snprintf(path, 100, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename);
214                 return VFS_Open(path, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
215         }
216         else
217         {
218                  int    len = snprintf(NULL, 0, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr);
219                 char    path[len+1];
220                 snprintf(path, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr);
221                 return VFS_Open(path, VFS_OPENFLAG_READ);
222         }
223 }
224
225 int Net_OpenSocket_TCPC(int AddrType, void *Addr, int Port)
226 {
227         int fd = Net_OpenSocket(AddrType, Addr, "tcpc");
228         if( fd == -1 )  return -1;
229         
230         VFS_IOCtl(fd, 5, &Port);        // Remote Port
231         VFS_IOCtl(fd, 6, Addr); // Remote address
232         VFS_IOCtl(fd, 7, NULL); // connect
233         return fd;
234 }
235

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