3 * - By John Hodge (thePowersGang)
6 * - `ip route` sub-command
10 #define DEFAULT_METRIC 30
13 int Routes_main(int argc, char *argv[]);
14 void DumpRoutes(void);
15 void DumpRoute(int PFD, const char *Name);
16 void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop);
19 int Routes_main(int argc, char *argv[])
27 else if( strcmp(argv[1], "add") == 0 )
29 uint8_t dest[16] = {0};
30 uint8_t nextHop[16] = {0};
31 int addrType, subnetBits = -1;
32 int nextHopType, nextHopBits=-1;
33 char *ifaceName = NULL;
34 int metric = DEFAULT_METRIC;
36 // ifconfig route add <host>[/<prefix>] <interface> [<metric>]
37 // ifconfig route add <host>[/<prefix>] <next hop> [<metric>]
39 fprintf(stderr, "ERROR: '%s route add' takes at least two arguments, %i passed\n",
46 fprintf(stderr, "ERROR: '%s route add' takes at most three arguments, %i passed\n",
53 addrType = ParseIPAddress(argv[2], dest, &subnetBits);
54 if( subnetBits == -1 ) {
55 subnetBits = Net_GetAddressSize(addrType)*8;
57 // Interface Name / Next Hop
58 if( (nextHopType = ParseIPAddress(argv[3], nextHop, &nextHopBits)) == 0 )
66 // - Check if it's the same type as the network/destination
67 if( nextHopType != addrType ) {
68 fprintf(stderr, "ERROR: Address type mismatch\n");
71 // - Make sure there's no mask
72 if( nextHopBits != -1 ) {
73 fprintf(stderr, "Error: Next hop cannot be masked\n");
81 metric = atoi(argv[4]);
82 if( metric == 0 && argv[4][0] != '0' ) {
83 fprintf(stderr, "ERROR: Metric should be a number\n");
89 AddRoute(ifaceName, addrType, dest, subnetBits, metric, nextHop);
94 else if( strcmp(argv[2], "del") == 0 )
97 // ifconfig route del <routenum>
98 // ifconfig route del <host>[/<prefix>]
110 * \brief Dump all interfaces
112 void DumpRoutes(void)
115 char filename[FILENAME_MAX+1];
117 dp = _SysOpen(IPSTACK_ROOT"/routes", OPENFLAG_READ);
119 printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
121 while( _SysReadDir(dp, filename) )
123 if(filename[0] == '.') continue;
124 DumpRoute(dp, filename);
131 * \brief Dump a route
133 void DumpRoute(int PFD, const char *Name)
138 fd = _SysOpenChild(PFD, Name, OPENFLAG_READ);
140 printf("%s:\tUnable to open\n", Name);
148 int len = Net_GetAddressSize(type);
149 uint8_t net[len], gw[len];
151 for( i = 0; i < len; i ++ ) {
152 char tmp[5] = "0x00";
153 tmp[2] = Name[ofs++];
154 tmp[3] = Name[ofs++];
158 subnet = atoi(Name+ofs);
160 metric = atoi(Name+ofs);
161 _SysIOCtl(fd, _SysIOCtl(fd, 3, "get_nexthop"), gw); // Get Gateway/NextHop
163 // Get the address type
166 case 0: // Disabled/Unset
167 printf("DISABLED\n");
176 printf("UNKNOWN (%i)\n", type);
179 printf("%s/%i\t", Net_PrintAddress(type, net), subnet);
180 printf("%s \t", Net_PrintAddress(type, gw));
181 printf("%i\t", metric);
185 int call_num = _SysIOCtl(fd, 3, "get_interface");
186 int len = _SysIOCtl(fd, call_num, NULL);
187 char *buf = malloc(len+1);
188 _SysIOCtl(fd, call_num, buf);
189 printf("'%s'\t", buf);
198 void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
202 char *ifaceToFree = NULL;
204 // Get interface name
209 "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
210 "Only one should be NULL\n"
215 // Query for the interface name
216 Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
218 // Check address type (if the interface was passed)
219 // - If we got the interface name, then it should be correct
222 char ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
225 strcpy(ifacePath, IPSTACK_ROOT"/");
226 strcat(ifacePath, Interface);
227 fd = _SysOpen(ifacePath, 0);
229 fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
232 // Get and check type
233 num = _SysIOCtl(fd, _SysIOCtl(fd, 3, "getset_type"), NULL);
234 if( num != AddressType ) {
235 fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
244 int addrsize = Net_GetAddressSize(AddressType);
245 int len = snprintf(NULL, 0, "/Devices/ip/routes/%i::%i:%i", AddressType, MaskBits, Metric) + addrsize*2;
249 ofs = sprintf(path, "/Devices/ip/routes/%i:", AddressType);
250 for( i = 0; i < addrsize; i ++ )
251 sprintf(path+ofs+i*2, "%02x", ((uint8_t*)Dest)[i]);
253 sprintf(path+ofs, ":%i:%i", MaskBits, Metric);
256 fd = _SysOpen(path, 0);
259 fprintf(stderr, "Unable to create route '%s', already exists\n", path);
262 fd = _SysOpen(path, OPENFLAG_CREATE, 0);
264 fprintf(stderr, "Unable to create '%s'\n", path);
269 _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_nexthop"), NextHop);
270 _SysIOCtl(fd, _SysIOCtl(fd, 3, "set_interface"), (void*)Interface);
274 // Check if the interface name was allocated by us