X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Fifconfig_src%2Fmain.c;h=334ea1370d53c06775a36565e3df5b12e3e981fb;hb=c95a4a86afd477a8d6dc6949e0ce6175a41553d1;hp=ca9b73be9087b00762498792b2799118874c9a4a;hpb=c0078bf13fa69e05235341a2863c873b7a76180a;p=tpg%2Facess2.git diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c index ca9b73be..334ea137 100644 --- a/Usermode/Applications/ifconfig_src/main.c +++ b/Usermode/Applications/ifconfig_src/main.c @@ -3,19 +3,30 @@ */ #include #include +#include #include #include +#include // === CONSTANTS === #define FILENAME_MAX 255 #define IPSTACK_ROOT "/Devices/ip" +#define DEFAULT_METRIC 30 + +// TODO: Move this to a header +#define ntohs(v) (((v&0xFF)<<8)|((v>>8)&0xFF)) // === PROTOTYPES === void PrintUsage(const char *ProgName); void DumpInterfaces(void); +void DumpRoutes(void); void DumpInterface(const char *Name); +void DumpRoute(const char *Name); int AddInterface(const char *Device); +void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop); int DoAutoConfig(const char *Device); + int SetAddress(int IFNum, const char *Address); + int ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits); // === CODE === /** @@ -23,32 +34,137 @@ void DumpInterface(const char *Name); */ int main(int argc, char *argv[]) { + int ret; + // No args, dump interfaces if(argc == 1) { DumpInterfaces(); return 0; } + // Routes + if( strcmp(argv[1], "route") == 0 ) + { + // Add new route + if( argc > 2 && strcmp(argv[2], "add") == 0 ) + { + uint8_t dest[16] = {0}; + uint8_t nextHop[16] = {0}; + int addrType, subnetBits = -1; + int nextHopType, nextHopBits=-1; + char *ifaceName = NULL; + int metric = DEFAULT_METRIC; + // Usage: + // ifconfig route add [/] [] + // ifconfig route add [/] [] + if( argc - 3 < 2 ) { + fprintf(stderr, "ERROR: '%s route add' takes at least two arguments, %i passed\n", + argv[0], argc-3); + PrintUsage(argv[0]); + return -1; + } + + if( argc - 3 > 3 ) { + fprintf(stderr, "ERROR: '%s route add' takes at most three arguments, %i passed\n", + argv[0], argc-3); + PrintUsage(argv[0]); + return -1; + } + + // Destination IP + addrType = ParseIPAddress(argv[3], dest, &subnetBits); + if( subnetBits == -1 ) { + subnetBits = Net_GetAddressSize(addrType)*8; + } + // Interface Name / Next Hop + if( (nextHopType = ParseIPAddress(argv[4], nextHop, &nextHopBits)) == 0 ) + { + // Interface name + ifaceName = argv[4]; + } + else + { + // Next Hop + // - Check if it's the same type as the network/destination + if( nextHopType != addrType ) { + fprintf(stderr, "ERROR: Address type mismatch\n"); + return -1; + } + // - Make sure there's no mask + if( nextHopBits != -1 ) { + fprintf(stderr, "Error: Next hop cannot be masked\n"); + return -1; + } + } + + // Metric + if( argc - 3 >= 3 ) + { + metric = atoi(argv[5]); + if( metric == 0 && argv[5][0] != '0' ) { + fprintf(stderr, "ERROR: Metric should be a number\n"); + return -1; + } + } + + // Make the route! + AddRoute(ifaceName, addrType, dest, subnetBits, metric, nextHop); + + return 0; + } + // Delete a route + else if( argc > 2 && strcmp(argv[2], "del") == 0 ) + { + // Usage: + // ifconfig route del + // ifconfig route del [/] + } + else + { + // List routes + DumpRoutes(); + } + return 0; + } // Add a new interface - if( strcmp(argv[1], "add") == 0 ) { + else if( strcmp(argv[1], "add") == 0 ) + { if( argc < 4 ) { - fprintf(stderr, "ERROR: %s add require two arguments, %i passed\n", argv[0], argc-2); + fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2); PrintUsage(argv[0]); - return 0; + return -1; } // TODO: Also set the IP address as the usage says it does - return AddInterface( argv[2] ); + ret = AddInterface( argv[2] ); + if(ret < 0) return ret; + ret = SetAddress( ret, argv[3] ); + return ret; + } + // Delete an interface + else if( strcmp(argv[1], "del") == 0 ) + { + if( argc < 3 ) { + fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]); + PrintUsage(argv[0]); + return -1; + } + // TODO: } - // Autoconfigure an interface // NOTE: Debugging hack (see the function for more details) - if( strcmp(argv[1], "autoconf") == 0 ) { + else if( strcmp(argv[1], "autoconf") == 0 ) + { DoAutoConfig(argv[2]); return 0; } + else if( strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 ) + { + PrintUsage(argv[0]); + return 0; + } - // Print usage instructions - PrintUsage(argv[0]); + // Dump a named interface + DumpInterface(argv[1]); return 0; } @@ -63,12 +179,18 @@ void PrintUsage(const char *ProgName) fprintf(stderr, " Add a new interface listening on with the specified\n"); fprintf(stderr, " address.\n"); fprintf(stderr, " %s del \n", ProgName); - fprintf(stderr, " %s set