IPStack - Cleaned up userland 'ip' tool, and fixed some little bugs
[tpg/acess2.git] / Usermode / Applications / ip_src / main.c
1 /*
2  * Acess2 ip command
3  * - By John Hodge (thePowersGang)
4  */
5 #include "common.h"
6
7 // === CONSTANTS ===
8
9 // === PROTOTYPES ===
10 void    PrintUsage(const char *ProgName);
11  int    ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits);
12
13 // === CODE ===
14 /**
15  * \brief Program entrypoint
16  */
17 int main(int argc, char *argv[])
18 {
19         // No args, dump interfaces
20         if(argc == 1) {
21 //              DumpInterfaces();
22                 return 0;
23         }
24         
25         // Routes
26         if( strcmp(argv[1], "route") == 0 )
27         {
28                 Routes_main(argc-1, argv+1);
29                 return 0;
30         }
31         else if( strcmp(argv[1], "addr") == 0 )
32         {
33                 Addr_main(argc-1, argv+1);
34                 return 0;
35         }
36         else if( strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 )
37         {
38                 PrintUsage(argv[0]);
39                 return 0;
40         }
41         
42         return 0;
43 }
44
45 /**
46  * \brief Print usage instructions
47  */
48 void PrintUsage(const char *ProgName)
49 {
50         fprintf(stderr, "Usage:\n");
51         fprintf(stderr, "    %s addr add <device> <ip>/<prefix>\n", ProgName);
52         fprintf(stderr, "        Add a new interface listening on <device> with the specified\n");
53         fprintf(stderr, "        address.\n");
54         fprintf(stderr, "    %s addr del <interface>\n", ProgName);
55         fprintf(stderr, "        Delete an interface\n");
56         fprintf(stderr, "    %s addr [<interface>]\n", ProgName);
57         fprintf(stderr, "        Print the current interfaces (or only <interface> if passed)\n");
58         fprintf(stderr, "\n");
59         fprintf(stderr, "    %s route\n", ProgName);
60         fprintf(stderr, "        Print the routing tables\n");
61         fprintf(stderr, "    %s route add <host>[/<prefix>] [<nexthop> OR <iface>] [<metric>]\n", ProgName);
62         fprintf(stderr, "        Add a new route\n");
63         fprintf(stderr, "    %s route del <host>[/<prefix>]\n", ProgName);
64         fprintf(stderr, "    %s route del <routenum>\n", ProgName);
65         fprintf(stderr, "        Add a new route\n");
66         fprintf(stderr, "\n");
67         fprintf(stderr, "A note on Acess's IP Stack:\n");
68         fprintf(stderr, "    Each interface corresponds to only one IP address (either IPv4\n");
69         fprintf(stderr, "    or IPv6). A network device can have multiple interfaces bound\n");
70         fprintf(stderr, "    to it, allowing multiple addresses for one network connection\n");
71         fprintf(stderr, "\n");
72 }
73
74
75 /**
76  * \brief Parse an IP Address
77  * \return 0 for unknown, 4 for IPv4 and 6 for IPv6
78  */
79 int ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits)
80 {
81         const char      *p = Address;
82         
83         // Check first block
84         while(*p && *p >= '0' && *p <= '9')     p ++;
85         
86         // IPv4?
87         if(*p == '.')
88         {
89                  int    i = 0, j;
90                  int    val;
91                 
92                 for( j = 0; Address[i] && j < 4; j ++ )
93                 {
94                         val = 0;
95                         for( ; '0' <= Address[i] && Address[i] <= '9'; i++ )
96                         {
97                                 val = val*10 + Address[i] - '0';
98                         }
99                         if(val > 255) {
100                                 //printf("val > 255 (%i)\n", val);
101                                 return 0;
102                         }
103                         Dest[j] = val;
104                         
105                         if(Address[i] == '.')
106                                 i ++;
107                 }
108                 if( j != 4 ) {
109                         //printf("4 parts expected, %i found\n", j);
110                         return 0;
111                 }
112                 // Parse subnet size
113                 if(Address[i] == '/') {
114                         val = 0;
115                         i ++;
116                         while('0' <= Address[i] && Address[i] <= '9') {
117                                 val *= 10;
118                                 val += Address[i] - '0';
119                                 i ++;
120                         }
121                         if(val > 32) {
122                                 printf("Notice: Subnet size >32 (%i)\n", val);
123                         }
124                         if(SubnetBits)  *SubnetBits = val;
125                 }
126                 if(Address[i] != '\0') {
127                         //printf("EOS != '\\0', '%c'\n", Address[i]);
128                         return 0;
129                 }
130                 return 4;
131         }
132         
133         // IPv6
134         if(*p == ':' || ('a' <= *p && *p <= 'f') || ('A' <= *p && *p <= 'F'))
135         {
136                  int    i = 0;
137                  int    j, k;
138                  int    val, split = -1, end;
139                 uint16_t        hi[8], low[8];
140                 
141                 for( j = 0; Address[i] && j < 8; j ++ )
142                 {
143                         if(Address[i] == '/')
144                                 break;
145                         
146                         if(Address[i] == ':') {
147                                 if(split != -1) {
148                                         printf("Two '::'s\n");
149                                         return 0;
150                                 }
151                                 split = j;
152                                 i ++;
153                                 continue;
154                         }
155                         
156                         val = 0;
157                         for( k = 0; Address[i] && Address[i] != ':' && Address[i] != '/'; i++, k++ )
158                         {
159                                 val *= 16;
160                                 if('0' <= Address[i] && Address[i] <= '9')
161                                         val += Address[i] - '0';
162                                 else if('A' <= Address[i] && Address[i] <= 'F')
163                                         val += Address[i] - 'A' + 10;
164                                 else if('a' <= Address[i] && Address[i] <= 'f')
165                                         val += Address[i] - 'a' + 10;
166                                 else {
167                                         printf("%c unexpected\n", Address[i]);
168                                         return 0;
169                                 }
170                         }
171                         
172                         if(val > 0xFFFF) {
173                                 printf("val (0x%x) > 0xFFFF\n", val);
174                                 return 0;
175                         }
176                         
177                         if(split == -1)
178                                 hi[j] = val;
179                         else
180                                 low[j-split] = val;
181                         
182                         if( Address[i] == ':' ) {
183                                 i ++;
184                         }
185                 }
186                 end = j;
187                 
188                 // Parse subnet size
189                 if(Address[i] == '/') {
190                         val = 0;
191                         while('0' <= Address[i] && Address[i] <= '9') {
192                                 val *= 10;
193                                 val += Address[i] - '0';
194                                 i ++;
195                         }
196                         if(val > 128) {
197                                 printf("Notice: Subnet size >128 (%i)\n", val);
198                         }
199                         if(SubnetBits)  *SubnetBits = val;
200                 }
201                 
202                 for( j = 0; j < split; j ++ )
203                 {
204                         //printf("%04x:", hi[j]);
205                         Dest[j*2] = hi[j]>>8;
206                         Dest[j*2+1] = hi[j]&0xFF;
207                 }
208                 for( ; j < 8 - (end - split); j++ )
209                 {
210                         //printf("0000:", hi[j]);
211                         Dest[j*2] = 0;
212                         Dest[j*2+1] = 0;
213                 }
214                 for( k = 0; j < 8; j ++, k++)
215                 {
216                         //printf("%04x:", low[k]);
217                         Dest[j*2] = low[k]>>8;
218                         Dest[j*2+1] = low[k]&0xFF;
219                 }
220                 return 6;
221         }
222         // Unknown type
223         return 0;
224 }

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