From 2bdb445efbe8a5440c5ed27acfccd32626bd67e7 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 20 Nov 2010 10:09:03 +0800 Subject: [PATCH] ifconfig - routes - Slight change to route ioctl API (added get_type) - Added IP->Text to libnet - Added route listing to ifconfig - Added libnet to `make all` --- Makefile | 2 +- Modules/IPStack/routing.c | 21 ++-- Usermode/Applications/ifconfig_src/Makefile | 2 + Usermode/Applications/ifconfig_src/main.c | 115 +++++++++++++++++++- Usermode/Libraries/libnet.so_src/address.c | 48 ++++++++ Usermode/Libraries/libnet.so_src/net.h | 7 ++ 6 files changed, 183 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index bb2a9307..0db9855a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SUBMAKE = $(MAKE) --no-print-directory -USRLIBS := crt0.o acess.ld ld-acess.so libacess.so libgcc.so libc.so +USRLIBS := crt0.o acess.ld ld-acess.so libacess.so libgcc.so libc.so libnet.so USRAPPS := init login CLIShell cat ls mount ifconfig ALL_DYNMODS = $(addprefix all-,$(DYNMODS)) diff --git a/Modules/IPStack/routing.c b/Modules/IPStack/routing.c index 381ddf7a..cae3b986 100644 --- a/Modules/IPStack/routing.c +++ b/Modules/IPStack/routing.c @@ -236,6 +236,7 @@ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address) */ static const char *casIOCtls_Route[] = { DRV_IOCTLNAMES, + "get_type", // Get address type - (void), returns integer type "get_network", // Get network - (void *Data), returns boolean success "set_network", // Set network - (void *Data), returns boolean success "get_nexthop", // Get next hop - (void *Data), returns boolean success @@ -277,30 +278,34 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) LEAVE('i', tmp); return tmp; - // Get Network + // Get address type case 4: + return rt->AddressType; + + // Get Network + case 5: if( !CheckMem(Data, addrSize) ) return -1; memcpy(Data, rt->Network, addrSize); return 1; // Set Network - case 5: + case 6: if( !CheckMem(Data, addrSize) ) return -1; memcpy(rt->Network, Data, addrSize); return 1; // Get Next Hop - case 6: + case 7: if( !CheckMem(Data, addrSize) ) return -1; memcpy(Data, rt->NextHop, addrSize); return 1; // Set Next Hop - case 7: + case 8: if( !CheckMem(Data, addrSize) ) return -1; memcpy(rt->NextHop, Data, addrSize); return 1; // Get/Set Subnet Bits - case 8: + case 9: if( Data ) { if( !CheckMem(Data, sizeof(int)) ) return -1; if( *iData < 0 || *iData > addrSize*8 ) @@ -310,7 +315,7 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) return rt->SubnetBits; // Get/Set Metric - case 9: + case 10: if( Data ) { if( !CheckMem(Data, sizeof(int)) ) return -1; if( *iData < 0 ) return -1; @@ -319,7 +324,7 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) return rt->Metric; // Get interface name - case 10: + case 11: if( Data ) { if( !CheckMem(Data, strlen(rt->Interface->Name) + 1) ) return -1; @@ -328,6 +333,6 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) return strlen(rt->Interface->Name); default: - return 0; + return -1; } } diff --git a/Usermode/Applications/ifconfig_src/Makefile b/Usermode/Applications/ifconfig_src/Makefile index a7035213..c742c250 100644 --- a/Usermode/Applications/ifconfig_src/Makefile +++ b/Usermode/Applications/ifconfig_src/Makefile @@ -2,6 +2,8 @@ -include ../Makefile.cfg +LDFLAGS += -lnet + OBJ = main.o BIN = ../ifconfig diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c index b80f6fa7..7a7fd07a 100644 --- a/Usermode/Applications/ifconfig_src/main.c +++ b/Usermode/Applications/ifconfig_src/main.c @@ -6,6 +6,7 @@ #include #include #include +#include // === CONSTANTS === #define FILENAME_MAX 255 @@ -17,8 +18,11 @@ // === 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, void *Dest, int MaskBits, void *NextHop); int DoAutoConfig(const char *Device); int SetAddress(int IFNum, const char *Address); int ParseIPAddres(const char *Address, uint8_t *Dest, int *SubnetBits); @@ -30,12 +34,18 @@ void DumpInterface(const char *Name); int main(int argc, char *argv[]) { int ret; + // No args, dump interfaces if(argc == 1) { DumpInterfaces(); return 0; } + if( strcmp(argv[1], "routes") == 0 ) { + DumpRoutes(); + return 0; + } + // Add a new interface if( strcmp(argv[1], "add") == 0 ) { if( argc < 4 ) { @@ -115,6 +125,25 @@ void DumpInterfaces(void) close(dp); } +/** + * \brief Dump all interfaces + */ +void DumpRoutes(void) +{ + int dp; + char filename[FILENAME_MAX+1]; + + dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ); + + while( readdir(dp, filename) ) + { + if(filename[0] == '.') continue; + DumpRoute(filename); + } + + close(dp); +} + /** * \brief Dump an interface */ @@ -162,8 +191,6 @@ void DumpInterface(const char *Name) ioctl(fd, 5, ip); // Get IP Address subnet = ioctl(fd, 7, NULL); // Get Subnet Bits printf("\tAddress: %i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet); - ioctl(fd, 8, ip); // Get Gateway - printf("\tGateway: %i.%i.%i.%i\n", ip[0], ip[1], ip[2], ip[3]); } break; case 6: // IPv6 @@ -188,6 +215,84 @@ void DumpInterface(const char *Name) close(fd); } + +/** + * \brief Dump a route + */ +void DumpRoute(const char *Name) +{ + int fd; + int type; + char path[sizeof(IPSTACK_ROOT)+7+FILENAME_MAX+1] = IPSTACK_ROOT"/route/"; + + strcat(path, Name); + + fd = open(path, OPENFLAG_READ); + if(fd == -1) { + printf("%s:\tUnable to open ('%s')\n", Name, path); + return ; + } + + type = ioctl(fd, 4, NULL); + + // Ignore -1 values + if( type == -1 ) { + return ; + } + + printf("%s:\t", Name); + { + int call_num = ioctl(fd, 3, "get_interface"); + int len = ioctl(fd, call_num, NULL); + char *buf = malloc(len+1); + ioctl(fd, call_num, buf); + printf("'%s'\t", buf); + free(buf); + } + + // Get the address type + switch(type) + { + case 0: // Disabled/Unset + printf("DISABLED\n"); + break; + case 4: // IPv4 + { + uint8_t net[4], addr[4]; + int subnet, metric; + printf("IPv4\n"); + ioctl(fd, ioctl(fd, 3, "get_network"), net); // Get Network + ioctl(fd, ioctl(fd, 3, "get_nexthop"), addr); // Get Gateway/NextHop + subnet = ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), NULL); // Get Subnet Bits + metric = ioctl(fd, ioctl(fd, 3, "getset_metric"), NULL); // Get Subnet Bits + printf("\tNetwork: %s/%i\n", Net_PrintAddress(4, net), subnet); + printf("\tGateway: %s\n", Net_PrintAddress(4, addr)); + printf("\tMetric: %i\n", metric); + } + break; + case 6: // IPv6 + { + uint16_t net[8], addr[8]; + int subnet, metric; + printf("IPv6\n"); + ioctl(fd, ioctl(fd, 3, "get_network"), net); // Get Network + ioctl(fd, ioctl(fd, 3, "get_nexthop"), addr); // Get Gateway/NextHop + subnet = ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), NULL); // Get Subnet Bits + metric = ioctl(fd, ioctl(fd, 3, "getset_metric"), NULL); // Get Subnet Bits + printf("\tNetwork: %s/%i\n", Net_PrintAddress(6, net), subnet); + printf("\tGateway: %s\n", Net_PrintAddress(6, addr)); + printf("\tMetric: %i\n", metric); + } + break; + default: // Unknow + printf("UNKNOWN (%i)\n", type); + break; + } + printf("\n"); + + close(fd); +} + /** * \brief Create a new interface using the passed device * \param Device Network device to bind to @@ -267,8 +372,12 @@ int DoAutoConfig(const char *Device) ioctl(fd, ioctl(fd, 3, "set_address"), addr); // Set Subnet ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet); + // Set Gateway - ioctl(fd, ioctl(fd, 3, "set_gateway"), gw); + { + uint8_t net[4] = {0,0,0,0}; + AddRoute(path + sizeof(IPSTACK_ROOT) + 1, net, 0, gw); + } close(fd); diff --git a/Usermode/Libraries/libnet.so_src/address.c b/Usermode/Libraries/libnet.so_src/address.c index 2b58444d..31b23e51 100644 --- a/Usermode/Libraries/libnet.so_src/address.c +++ b/Usermode/Libraries/libnet.so_src/address.c @@ -7,8 +7,11 @@ */ #include #include +#include #define DEBUG 0 +#define __thread // Disable TLS + /** * \brief Read an IPv4 Address * \param String IPv4 dotted decimal address @@ -166,3 +169,48 @@ int Net_ParseAddress(const char *String, void *Addr) return 0; } + +static const char *Net_PrintIPv4Address(uint8_t *Address) +{ + static __thread char ret[4*3+3+1]; // '255.255.255.255\0' + + sprintf(ret, "%i.%i.%i.%i", Address[0], Address[1], Address[2], Address[3]); + + return ret; +} + +static const char *Net_PrintIPv6Address(uint16_t *Address) +{ + static __thread char ret[8*4+7+1]; // 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF\0' + #if 0 + // TODO: Zero compression + int zeroStart = 0, zeroEnd = 8; + for( i = 0; i < 8; i ++ ) { + if( + } + #endif + + sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x", + Address[0], Address[1], Address[2], Address[3], + Address[4], Address[5], Address[6], Address[7] + ); + + return ret; +} + +const char *Net_PrintAddress(int AddressType, void *Address) +{ + switch( AddressType ) + { + case 0: return ""; + + case 4: + return Net_PrintIPv4Address(Address); + + case 6: + return Net_PrintIPv6Address(Address); + + default: + return "BAD"; + } +} diff --git a/Usermode/Libraries/libnet.so_src/net.h b/Usermode/Libraries/libnet.so_src/net.h index 7c7a9b5a..f45646f3 100644 --- a/Usermode/Libraries/libnet.so_src/net.h +++ b/Usermode/Libraries/libnet.so_src/net.h @@ -14,6 +14,13 @@ */ extern int Net_ParseAddress(const char *String, void *Addr); +/** + * \brief Convert a network address into a string + * \param AddressType Address family as returned by Net_ParseAddress + * \param Address Address data + */ +extern const char *Net_PrintAddress(int AddressType, void *Address); + /** * \brief Get the interface required to reach \a Addr * \param AddrType Addresss Family (4: IPv4, 6: IPv6) -- 2.20.1