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(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[3], dest, &subnetBits);
54 if( subnetBits == -1 ) {
55 subnetBits = Net_GetAddressSize(addrType)*8;
57 // Interface Name / Next Hop
58 if( (nextHopType = ParseIPAddress(argv[4], 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[5]);
82 if( metric == 0 && argv[5][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 = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
119 printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
121 while( readdir(dp, filename) )
123 if(filename[0] == '.') continue;
131 * \brief Dump a route
133 void DumpRoute(const char *Name)
137 char path[sizeof(IPSTACK_ROOT)+8+FILENAME_MAX+1] = IPSTACK_ROOT"/routes/";
141 fd = open(path, OPENFLAG_READ);
143 printf("%s:\tUnable to open ('%s')\n", Name, path);
151 int len = Net_GetAddressSize(type);
152 uint8_t net[len], gw[len];
154 for( i = 0; i < len; i ++ ) {
155 char tmp[5] = "0x00";
156 tmp[2] = Name[ofs++];
157 tmp[3] = Name[ofs++];
161 subnet = atoi(Name+ofs);
163 metric = atoi(Name+ofs);
164 ioctl(fd, ioctl(fd, 3, "get_nexthop"), gw); // Get Gateway/NextHop
166 // Get the address type
169 case 0: // Disabled/Unset
170 printf("DISABLED\n");
179 printf("UNKNOWN (%i)\n", type);
182 printf("%s/%i\t", Net_PrintAddress(type, net), subnet);
183 printf("%s \t", Net_PrintAddress(type, gw));
184 printf("%i\t", metric);
188 int call_num = ioctl(fd, 3, "get_interface");
189 int len = ioctl(fd, call_num, NULL);
190 char *buf = malloc(len+1);
191 ioctl(fd, call_num, buf);
192 printf("'%s'\t", buf);
201 void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
205 char *ifaceToFree = NULL;
207 // Get interface name
212 "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
213 "Only one should be NULL\n"
218 // Query for the interface name
219 Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
221 // Check address type (if the interface was passed)
222 // - If we got the interface name, then it should be correct
225 char ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
228 strcpy(ifacePath, IPSTACK_ROOT"/");
229 strcat(ifacePath, Interface);
230 fd = open(ifacePath, 0);
232 fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
235 // Get and check type
236 num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
237 if( num != AddressType ) {
238 fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
247 int addrsize = Net_GetAddressSize(AddressType);
248 int len = snprintf(NULL, 0, "/Devices/ip/routes/%i::%i:%i", AddressType, MaskBits, Metric) + addrsize*2;
252 ofs = sprintf(path, "/Devices/ip/routes/%i:", AddressType);
253 for( i = 0; i < addrsize; i ++ )
254 sprintf(path+ofs+i*2, "%02x", ((uint8_t*)Dest)[i]);
256 sprintf(path+ofs, ":%i:%i", MaskBits, Metric);
262 fprintf(stderr, "Unable to create route '%s', already exists\n", path);
265 fd = open(path, OPENFLAG_CREATE, 0);
267 fprintf(stderr, "Unable to create '%s'\n", path);
272 ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
273 ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
277 // Check if the interface name was allocated by us