IPStack - Cleaned up userland 'ip' tool, and fixed some little bugs
authorJohn Hodge <[email protected]>
Sat, 12 May 2012 13:17:26 +0000 (21:17 +0800)
committerJohn Hodge <[email protected]>
Sat, 12 May 2012 13:17:26 +0000 (21:17 +0800)
13 files changed:
KernelLand/Modules/IPStack/adapters.c
KernelLand/Modules/IPStack/include/adapters.h
KernelLand/Modules/IPStack/interface.c
Makefile
Usermode/Applications/ifconfig_src/Makefile [deleted file]
Usermode/Applications/ifconfig_src/main.c [deleted file]
Usermode/Applications/ifconfig_src/rules.mk [deleted file]
Usermode/Applications/ip_src/Makefile [new file with mode: 0644]
Usermode/Applications/ip_src/addr.c [new file with mode: 0644]
Usermode/Applications/ip_src/common.h [new file with mode: 0644]
Usermode/Applications/ip_src/main.c [new file with mode: 0644]
Usermode/Applications/ip_src/routes.c [new file with mode: 0644]
Usermode/Applications/ip_src/rules.mk [new file with mode: 0644]

index f4b99be..8289455 100644 (file)
@@ -143,9 +143,7 @@ char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
                tAdapter *a;  int i;\
                for(i=0,a=list; i < Pos && a; i ++, a = a->Next ); \
                if( a ) { \
-                       char    buf[sizeof(type)+10]; \
-                       sprintf(buf, type"%i", a->Index); \
-                       return strdup(buf); \
+                       return Adapter_GetName(a);\
                } \
                Pos -= i; \
        } while(0);
@@ -229,6 +227,21 @@ tAdapter *Adapter_GetByName(const char *Name)
        return NULL;
 }
 
+char *Adapter_GetName(tAdapter *Adapter)
+{
+       if( Adapter == &gIP_LoopAdapter )
+       {
+               return strdup("lo");
+       }
+       else
+       {
+               // TODO: Support multiple adapter types
+               char    buf[sizeof("eth")+10];
+               sprintf(buf, "eth%i", Adapter->Index);
+               return strdup(buf);
+       }
+}
+
 void Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer)
 {
        if( Handle->Type == NULL )
index 768fd9e..e0b13ff 100644 (file)
@@ -11,6 +11,7 @@
 #include "adapters_api.h"
 
 extern tAdapter        *Adapter_GetByName(const char *Name);
+extern char    *Adapter_GetName(tAdapter *Adapter);
 extern void    Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer);
 
 
index 9ff3f17..8fe0a43 100644 (file)
@@ -440,15 +440,19 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
         * - Gets the name of the attached device
         */
        case 8:
-               Log_Error("IPStack", "TODO: Reimplement interface.ioctl(get_device)");
-//             if( iface->Adapter == NULL )
+               if( iface->Adapter == NULL )
                        LEAVE_RET('i', 0);
-//             if( Data == NULL )
-//                     LEAVE_RET('i', iface->Adapter->DeviceLen);
-//             if( !CheckMem( Data, iface->Adapter->DeviceLen+1 ) )
-//                     LEAVE_RET('i', -1);
-//             strcpy( Data, iface->Adapter->Device );
-//             LEAVE_RET('i', iface->Adapter->DeviceLen);
+               char *name = Adapter_GetName(iface->Adapter);
+                int len = strlen(name);
+               if( Data ) {
+                       if( !CheckMem( Data, len+1 ) ) {
+                               free(name);
+                               LEAVE_RET('i', -1);
+                       }
+                       strcpy( Data, name );
+               }
+               free(name);
+               LEAVE_RET('i', len);
        
        /*
         * ping
index faa0ab3..54d0e16 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ USRLIBS += libimage_sif.so
 
 USRAPPS := init login CLIShell cat ls mount
 USRAPPS += bomb dhcpclient
-USRAPPS += ifconfig ping telnet irc
+USRAPPS += ip ping telnet irc
 USRAPPS += axwin3
 
 ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
diff --git a/Usermode/Applications/ifconfig_src/Makefile b/Usermode/Applications/ifconfig_src/Makefile
deleted file mode 100644 (file)
index e914e2b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# Project: ifconfig
-
--include ../Makefile.cfg
-
-LDFLAGS += -lnet
-
-OBJ = main.o
-BIN = ifconfig
-
--include ../Makefile.tpl
-
diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c
deleted file mode 100644 (file)
index bbb8666..0000000
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * Acess2 IFCONFIG command
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <acess/sys.h>
-#include <net.h>
-
-// === 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 ===
-/**
- * \brief Program entrypoint
- */
-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 <host>[/<prefix>] <interface> [<metric>]
-                       // ifconfig route add <host>[/<prefix>] <next hop> [<metric>]
-                       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 <routenum>
-                       // ifconfig route del <host>[/<prefix>]
-               }
-               else
-               {
-                       // List routes
-                       DumpRoutes();
-               }
-               return 0;
-       }
-       // Add a new interface
-       else if( strcmp(argv[1], "add") == 0 )
-       {
-               if( argc < 4 ) {
-                       fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2);
-                       PrintUsage(argv[0]);
-                       return -1;
-               }
-               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)
-       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;
-       }
-       
-       // Dump a named interface
-       DumpInterface(argv[1]);
-       
-       return 0;
-}
-
-/**
- * \brief Print usage instructions
- */
-void PrintUsage(const char *ProgName)
-{
-       fprintf(stderr, "Usage:\n");
-       fprintf(stderr, "    %s add <device> <ip>/<prefix>\n", ProgName);
-       fprintf(stderr, "        Add a new interface listening on <device> with the specified\n");
-       fprintf(stderr, "        address.\n");
-       fprintf(stderr, "    %s del <interface>\n", ProgName);
-       fprintf(stderr, "        Delete an interface\n");
-       fprintf(stderr, "    %s [<interface>]\n", ProgName);
-       fprintf(stderr, "        Print the current interfaces (or only <interface> if passed)\n");
-       fprintf(stderr, "\n");
-       fprintf(stderr, "    %s route\n", ProgName);
-       fprintf(stderr, "        Print the routing tables\n");
-       fprintf(stderr, "    %s route add <host>[/<prefix>] [<nexthop> OR <iface>] [<metric>]\n", ProgName);
-       fprintf(stderr, "        Add a new route\n");
-       fprintf(stderr, "    %s route del <host>[/<prefix>]\n", ProgName);
-       fprintf(stderr, "    %s route del <routenum>\n", ProgName);
-       fprintf(stderr, "        Add a new route\n");
-       fprintf(stderr, "\n");
-       fprintf(stderr, "A note on Acess's IP Stack:\n");
-       fprintf(stderr, "    Each interface corresponds to only one IP address (either IPv4\n");
-       fprintf(stderr, "    or IPv6). A network device can have multiple interfaces bound\n");
-       fprintf(stderr, "    to it, allowing multiple addresses for one network connection\n");
-       fprintf(stderr, "\n");
-}
-
-/**
- * \brief Dump all interfaces
- */
-void DumpInterfaces(void)
-{
-        int    dp;
-       char    filename[FILENAME_MAX+1];
-       
-       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
-       
-       while( readdir(dp, filename) )
-       {
-               if(filename[0] == '.')  continue;
-               DumpInterface(filename);
-       }
-       
-       close(dp);
-}
-
-/**
- * \brief Dump all interfaces
- */
-void DumpRoutes(void)
-{
-        int    dp;
-       char    filename[FILENAME_MAX+1];
-       
-       dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
-       
-       printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
-       
-       while( readdir(dp, filename) )
-       {
-               if(filename[0] == '.')  continue;
-               DumpRoute(filename);
-       }
-       
-       close(dp);
-}
-
-/**
- * \brief Dump an interface
- */
-void DumpInterface(const char *Name)
-{
-        int    fd;
-        int    type;
-       char    path[sizeof(IPSTACK_ROOT)+1+FILENAME_MAX+1] = IPSTACK_ROOT"/";
-       
-       strcat(path, Name);
-       
-       fd = open(path, OPENFLAG_READ);
-       if(fd == -1) {
-               fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t", 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_device");
-                int    len = ioctl(fd, call_num, NULL);
-               char    *buf = malloc(len+1);
-               ioctl(fd, call_num, buf);
-               printf("'%s'\n", buf);
-               free(buf);
-       }
-       printf("\t");
-       // Get the address type
-       switch(type)
-       {
-       case 0: // Disabled/Unset
-               printf("DISABLED\n");
-               break;
-       case 4: // IPv4
-               {
-               uint8_t ip[4];
-                int    subnet;
-               printf("IPv4\t");
-               ioctl(fd, 5, ip);       // Get IP Address
-               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
-               printf("%i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
-               }
-               break;
-       case 6: // IPv6
-               {
-               uint16_t        ip[8];
-                int    subnet;
-               printf("IPv6\t");
-               ioctl(fd, 5, ip);       // Get IP Address
-               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
-               printf("%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
-                       ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]),
-                       ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]),
-                       subnet);
-               }
-               break;
-       default:        // Unknow
-               printf("UNKNOWN (%i)\n", type);
-               break;
-       }
-                       
-       close(fd);
-}
-
-
-/**
- * \brief Dump a route
- */
-void DumpRoute(const char *Name)
-{
-        int    fd;
-        int    type;
-       char    path[sizeof(IPSTACK_ROOT)+8+FILENAME_MAX+1] = IPSTACK_ROOT"/routes/";
-       
-       strcat(path, Name);
-       
-       fd = open(path, OPENFLAG_READ);
-       if(fd == -1) {
-               printf("%s:\tUnable to open ('%s')\n", Name, path);
-               return ;
-       }
-       
-        int    ofs = 2;
-       type = atoi(Name);
-       
-        int    i;
-        int    len = Net_GetAddressSize(type);
-       uint8_t net[len], gw[len];
-        int    subnet, metric;
-       for( i = 0; i < len; i ++ ) {
-               char tmp[5] = "0x00";
-               tmp[2] = Name[ofs++];
-               tmp[3] = Name[ofs++];
-               net[i] = atoi(tmp);
-       }
-       ofs ++;
-       subnet = atoi(Name+ofs);
-       ofs ++;
-       metric = atoi(Name+ofs);
-       ioctl(fd, ioctl(fd, 3, "get_nexthop"), gw);     // Get Gateway/NextHop
-       
-       // Get the address type
-       switch(type)
-       {
-       case 0: // Disabled/Unset
-               printf("DISABLED\n");
-               break;
-       case 4: // IPv4
-               printf("IPv4\t");
-               break;
-       case 6: // IPv6
-               printf("IPv6\t");
-               break;
-       default:        // Unknow
-               printf("UNKNOWN (%i)\n", type);
-               break;
-       }
-       printf("%s/%i\t", Net_PrintAddress(type, net), subnet);
-       printf("%s \t", Net_PrintAddress(type, gw));
-       printf("%i\t", metric);
-       
-       // Interface
-       {
-                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);
-       }
-       
-       printf("\n");
-                       
-       close(fd);
-}
-
-/**
- * \brief Create a new interface using the passed device
- * \param Device       Network device to bind to
- */
-int AddInterface(const char *Device)
-{
-        int    dp, ret;
-       
-       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
-       ret = ioctl(dp, 4, (void*)Device);
-       close(dp);
-       
-       if( ret < 0 ) {
-               fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
-               return -1;
-       }
-       
-       printf("-- Added '"IPSTACK_ROOT"/%i' using device %s\n", ret, Device);
-       
-       return ret;
-}
-
-void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
-{
-        int    fd;
-        int    num;
-       char    *ifaceToFree = NULL;
-       
-       // Get interface name
-       if( !Interface )
-       {
-               if( !NextHop ) {
-                       fprintf(stderr,
-                               "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
-                               "Only one should be NULL\n"
-                               );
-                       return ;
-               }
-               
-               // Query for the interface name
-               Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
-       }
-       // Check address type (if the interface was passed)
-       // - If we got the interface name, then it should be correct
-       else
-       {
-               char    ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
-               
-               // Open interface
-               strcpy(ifacePath, IPSTACK_ROOT"/");
-               strcat(ifacePath, Interface);
-               fd = open(ifacePath, 0);
-               if( fd == -1 ) {
-                       fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
-                       return ;
-               }
-               // Get and check type
-               num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
-               if( num != AddressType ) {
-                       fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
-                               AddressType, num);
-                       return ;
-               }
-               
-               close(fd);
-       }
-       
-       // Create route
-        int    addrsize = Net_GetAddressSize(AddressType);
-        int    len = snprintf(NULL, 0, "/Devices/ip/routes/%i::%i:%i", AddressType, MaskBits, Metric) + addrsize*2;
-       char    path[len+1];
-       {
-                int    i, ofs;
-               ofs = sprintf(path, "/Devices/ip/routes/%i:", AddressType);
-               for( i = 0; i < addrsize; i ++ )
-                       sprintf(path+ofs+i*2, "%02x", ((uint8_t*)Dest)[i]);
-               ofs += addrsize*2;
-               sprintf(path+ofs, ":%i:%i", MaskBits, Metric);
-       }
-
-       fd = open(path, 0);
-       if( fd != -1 ) {
-               close(fd);
-               fprintf(stderr, "Unable to create route '%s', already exists\n", path);
-               return ;
-       }
-       fd = open(path, OPENFLAG_CREATE, 0);
-       if( fd == -1 ) {
-               fprintf(stderr, "Unable to create '%s'\n", path);
-               return ;
-       }
-       
-       if( NextHop )
-               ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
-       ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
-       
-       close(fd);
-       
-       // Check if the interface name was allocated by us
-       if( ifaceToFree )
-               free(ifaceToFree);
-}
-
-/**
- * \note Debugging HACK!
- * \brief Autoconfigure the specified device to 10.0.2.55/24 using
- *        10.0.2.2 as the gateway.
- */
-int DoAutoConfig(const char *Device)
-{
-        int    tmp, fd;
-       char    path[sizeof(IPSTACK_ROOT)+1+4+1];       // /0000
-       uint8_t addr[4] = {10,0,2,55};
-       uint8_t gw[4] = {10,0,2,2};
-        int    subnet = 24;
-       
-       tmp = AddInterface(Device);
-       if( tmp < 0 )   return tmp;
-       
-       sprintf(path, IPSTACK_ROOT"/%i", tmp);
-       
-       fd = open(path, OPENFLAG_READ);
-       if( fd == -1 ) {
-               fprintf(stderr, "Unable to open '%s'\n", path);
-               return -1;
-       }
-       
-       tmp = 4;        // IPv4
-       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
-       if( tmp != 4 ) {
-               fprintf(stderr, "Error in setting address type (got %i, expected 4)\n", tmp);
-               return -1;
-       }
-       // Set Address
-       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
-       // Set Subnet
-       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
-       
-       // Set routes
-       {
-               uint8_t net[4] = {0,0,0,0};
-               AddRoute(path + sizeof(IPSTACK_ROOT), 4, addr, subnet, DEFAULT_METRIC, net);    // This interface
-               AddRoute(path + sizeof(IPSTACK_ROOT), 4, net, 0, DEFAULT_METRIC, gw);   // Gateway
-       }
-       
-       close(fd);
-       
-       printf("Set address to %i.%i.%i.%i/%i (GW: %i.%i.%i.%i)\n",
-               addr[0], addr[1], addr[2], addr[3],
-               subnet,
-               gw[0], gw[1], gw[2], gw[3]);
-       
-       return 0;
-}
-
-/**
- * \brief Set the address on an interface from a textual IP address
- */
-int    SetAddress(int IFNum, const char *Address)
-{
-       uint8_t addr[16];
-        int    type;
-       char    path[sizeof(IPSTACK_ROOT)+1+5+1];       // ip000
-        int    tmp, fd, subnet;
-       
-       // Parse IP Address
-       type = ParseIPAddress(Address, addr, &subnet);
-       if(type == 0) {
-               fprintf(stderr, "'%s' cannot be parsed as an IP address\n", Address);
-               return -1;
-       }
-       
-       // Open file
-       sprintf(path, IPSTACK_ROOT"/%i", IFNum);
-       fd = open(path, OPENFLAG_READ);
-       if( fd == -1 ) {
-               fprintf(stderr, "Unable to open '%s'\n", path);
-               return -1;
-       }
-       
-       tmp = type;
-       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
-       if( tmp != type ) {
-               fprintf(stderr, "Error in setting address type (got %i, expected %i)\n", tmp, type);
-               close(fd);
-               return -1;
-       }
-       // Set Address
-       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
-       
-       // Set Subnet
-       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
-       
-       close(fd);
-       
-       // Dump!
-       //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 );
-       
-       return 0;
-}
-
-/**
- * \brief Parse an IP Address
- * \return 0 for unknown, 4 for IPv4 and 6 for IPv6
- */
-int ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits)
-{
-       const char      *p = Address;
-       
-       // Check first block
-       while(*p && *p >= '0' && *p <= '9')     p ++;
-       
-       // IPv4?
-       if(*p == '.')
-       {
-                int    i = 0, j;
-                int    val;
-               
-               for( j = 0; Address[i] && j < 4; j ++ )
-               {
-                       val = 0;
-                       for( ; '0' <= Address[i] && Address[i] <= '9'; i++ )
-                       {
-                               val = val*10 + Address[i] - '0';
-                       }
-                       if(val > 255) {
-                               //printf("val > 255 (%i)\n", val);
-                               return 0;
-                       }
-                       Dest[j] = val;
-                       
-                       if(Address[i] == '.')
-                               i ++;
-               }
-               if( j != 4 ) {
-                       //printf("4 parts expected, %i found\n", j);
-                       return 0;
-               }
-               // Parse subnet size
-               if(Address[i] == '/') {
-                       val = 0;
-                       i ++;
-                       while('0' <= Address[i] && Address[i] <= '9') {
-                               val *= 10;
-                               val += Address[i] - '0';
-                               i ++;
-                       }
-                       if(val > 32) {
-                               printf("Notice: Subnet size >32 (%i)\n", val);
-                       }
-                       if(SubnetBits)  *SubnetBits = val;
-               }
-               if(Address[i] != '\0') {
-                       //printf("EOS != '\\0', '%c'\n", Address[i]);
-                       return 0;
-               }
-               return 4;
-       }
-       
-       // IPv6
-       if(*p == ':' || ('a' <= *p && *p <= 'f') || ('A' <= *p && *p <= 'F'))
-       {
-                int    i = 0;
-                int    j, k;
-                int    val, split = -1, end;
-               uint16_t        hi[8], low[8];
-               
-               for( j = 0; Address[i] && j < 8; j ++ )
-               {
-                       if(Address[i] == '/')
-                               break;
-                       
-                       if(Address[i] == ':') {
-                               if(split != -1) {
-                                       printf("Two '::'s\n");
-                                       return 0;
-                               }
-                               split = j;
-                               i ++;
-                               continue;
-                       }
-                       
-                       val = 0;
-                       for( k = 0; Address[i] && Address[i] != ':' && Address[i] != '/'; i++, k++ )
-                       {
-                               val *= 16;
-                               if('0' <= Address[i] && Address[i] <= '9')
-                                       val += Address[i] - '0';
-                               else if('A' <= Address[i] && Address[i] <= 'F')
-                                       val += Address[i] - 'A' + 10;
-                               else if('a' <= Address[i] && Address[i] <= 'f')
-                                       val += Address[i] - 'a' + 10;
-                               else {
-                                       printf("%c unexpected\n", Address[i]);
-                                       return 0;
-                               }
-                       }
-                       
-                       if(val > 0xFFFF) {
-                               printf("val (0x%x) > 0xFFFF\n", val);
-                               return 0;
-                       }
-                       
-                       if(split == -1)
-                               hi[j] = val;
-                       else
-                               low[j-split] = val;
-                       
-                       if( Address[i] == ':' ) {
-                               i ++;
-                       }
-               }
-               end = j;
-               
-               // Parse subnet size
-               if(Address[i] == '/') {
-                       val = 0;
-                       while('0' <= Address[i] && Address[i] <= '9') {
-                               val *= 10;
-                               val += Address[i] - '0';
-                               i ++;
-                       }
-                       if(val > 128) {
-                               printf("Notice: Subnet size >128 (%i)\n", val);
-                       }
-                       if(SubnetBits)  *SubnetBits = val;
-               }
-               
-               for( j = 0; j < split; j ++ )
-               {
-                       //printf("%04x:", hi[j]);
-                       Dest[j*2] = hi[j]>>8;
-                       Dest[j*2+1] = hi[j]&0xFF;
-               }
-               for( ; j < 8 - (end - split); j++ )
-               {
-                       //printf("0000:", hi[j]);
-                       Dest[j*2] = 0;
-                       Dest[j*2+1] = 0;
-               }
-               for( k = 0; j < 8; j ++, k++)
-               {
-                       //printf("%04x:", low[k]);
-                       Dest[j*2] = low[k]>>8;
-                       Dest[j*2+1] = low[k]&0xFF;
-               }
-               return 6;
-       }
-       // Unknown type
-       return 0;
-}
diff --git a/Usermode/Applications/ifconfig_src/rules.mk b/Usermode/Applications/ifconfig_src/rules.mk
deleted file mode 100644 (file)
index f420eb8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# ifconfig
-
-include $(BASE)header.mk
-
-# Variables
-SRCS := main.c
-BIN  := $(OUTPUTDIR)Bin/ifconfig
-
-LDFLAGS-$(DIR) += -lnet
-
-include $(BASE)body.mk
-
-include $(BASE)footer.mk
-
diff --git a/Usermode/Applications/ip_src/Makefile b/Usermode/Applications/ip_src/Makefile
new file mode 100644 (file)
index 0000000..1c976b5
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: ip
+
+-include ../Makefile.cfg
+
+LDFLAGS += -lnet
+
+OBJ = main.o addr.o routes.o
+BIN = ip
+
+-include ../Makefile.tpl
+
diff --git a/Usermode/Applications/ip_src/addr.c b/Usermode/Applications/ip_src/addr.c
new file mode 100644 (file)
index 0000000..579aa47
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ * 
+ * addr.c
+ * - `ip addr` sub command
+ */
+#include "common.h"
+
+// === PROTOTYPES ===
+ int   Addr_main(int argc, char *argv[]);
+ int   AddInterface(const char *Device);
+ int   SetAddress(int IFNum, const char *Address);
+void   DumpInterfaces(void);
+void   DumpInterface(const char *Name);
+void   DumpRoute(const char *Name);
+
+// === CODE ===
+int Addr_main(int argc, char *argv[])
+{
+        int    ret;
+       if( argc <= 1 )
+       {
+               // No action
+               DumpInterfaces();
+       }
+       else if( strcmp(argv[1], "add") == 0 )
+       {
+               if( argc - 2 < 2 ) {
+                       fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2);
+                       PrintUsage(argv[0]);
+                       return -1;
+               }
+               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 - 2 < 1 ) {
+                       fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]);
+                       PrintUsage(argv[0]);
+                       return -1;
+               }
+       }
+       else
+       {
+               // Show named iface?
+               DumpInterface(argv[1]);
+       }
+       return 0;
+}
+
+/**
+ * \brief Create a new interface using the passed device
+ * \param Device       Network device to bind to
+ */
+int AddInterface(const char *Device)
+{
+        int    dp, ret;
+       
+       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
+       ret = ioctl(dp, 4, (void*)Device);
+       close(dp);
+       
+       if( ret < 0 ) {
+               fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
+               return -1;
+       }
+       
+       printf("-- Added '"IPSTACK_ROOT"/%i' using device %s\n", ret, Device);
+       
+       return ret;
+}
+
+/**
+ * \brief Set the address on an interface from a textual IP address
+ */
+int SetAddress(int IFNum, const char *Address)
+{
+       uint8_t addr[16];
+        int    type;
+       char    path[sizeof(IPSTACK_ROOT)+1+5+1];       // ip000
+        int    tmp, fd, subnet;
+       
+       // Parse IP Address
+       type = ParseIPAddress(Address, addr, &subnet);
+       if(type == 0) {
+               fprintf(stderr, "'%s' cannot be parsed as an IP address\n", Address);
+               return -1;
+       }
+       
+       // Open file
+       sprintf(path, IPSTACK_ROOT"/%i", IFNum);
+       fd = open(path, OPENFLAG_READ);
+       if( fd == -1 ) {
+               fprintf(stderr, "Unable to open '%s'\n", path);
+               return -1;
+       }
+       
+       tmp = type;
+       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
+       if( tmp != type ) {
+               fprintf(stderr, "Error in setting address type (got %i, expected %i)\n", tmp, type);
+               close(fd);
+               return -1;
+       }
+       // Set Address
+       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
+       
+       // Set Subnet
+       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
+       
+       close(fd);
+       
+       // Dump!
+       //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 );
+       
+       return 0;
+}
+
+/**
+ * \brief Dump all interfaces
+ */
+void DumpInterfaces(void)
+{
+        int    dp;
+       char    filename[FILENAME_MAX+1];
+       
+       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
+       
+       while( readdir(dp, filename) )
+       {
+               if(filename[0] == '.')  continue;
+               DumpInterface(filename);
+       }
+       
+       close(dp);
+}
+
+/**
+ * \brief Dump an interface
+ */
+void DumpInterface(const char *Name)
+{
+        int    fd;
+        int    type;
+       char    path[sizeof(IPSTACK_ROOT)+1+FILENAME_MAX+1] = IPSTACK_ROOT"/";
+       
+       strcat(path, Name);
+       
+       fd = open(path, OPENFLAG_READ);
+       if(fd == -1) {
+               fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t", 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_device");
+                int    len = ioctl(fd, call_num, NULL);
+               char    *buf = malloc(len+1);
+               ioctl(fd, call_num, buf);
+               printf("'%s'\n", buf);
+               free(buf);
+       }
+       printf("\t");
+       // Get the address type
+       switch(type)
+       {
+       case 0: // Disabled/Unset
+               printf("DISABLED\n");
+               break;
+       case 4: // IPv4
+               {
+               uint8_t ip[4];
+                int    subnet;
+               printf("IPv4\t");
+               ioctl(fd, 5, ip);       // Get IP Address
+               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
+               printf("%i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
+               }
+               break;
+       case 6: // IPv6
+               {
+               uint16_t        ip[8];
+                int    subnet;
+               printf("IPv6\t");
+               ioctl(fd, 5, ip);       // Get IP Address
+               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
+               printf("%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
+                       ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]),
+                       ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]),
+                       subnet);
+               }
+               break;
+       default:        // Unknow
+               printf("UNKNOWN (%i)\n", type);
+               break;
+       }
+                       
+       close(fd);
+}
+
diff --git a/Usermode/Applications/ip_src/common.h b/Usermode/Applications/ip_src/common.h
new file mode 100644 (file)
index 0000000..f4aa373
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ * 
+ * common.h
+ * - Shared header
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <net.h>
+#include <acess/sys.h>
+
+#define FILENAME_MAX   255
+#define IPSTACK_ROOT   "/Devices/ip"
+
+#define ntohs(v)       (((v&0xFF)<<8)|((v>>8)&0xFF))
+
+extern void    PrintUsage(const char *ProgName);
+extern int     ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits);
+extern int     Addr_main(int argc, char *argv[]);
+extern int     Routes_main(int argc, char *argv[]);
+
+#endif
+
diff --git a/Usermode/Applications/ip_src/main.c b/Usermode/Applications/ip_src/main.c
new file mode 100644 (file)
index 0000000..580fb4e
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ */
+#include "common.h"
+
+// === CONSTANTS ===
+
+// === PROTOTYPES ===
+void   PrintUsage(const char *ProgName);
+ int   ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits);
+
+// === CODE ===
+/**
+ * \brief Program entrypoint
+ */
+int main(int argc, char *argv[])
+{
+       // No args, dump interfaces
+       if(argc == 1) {
+//             DumpInterfaces();
+               return 0;
+       }
+       
+       // Routes
+       if( strcmp(argv[1], "route") == 0 )
+       {
+               Routes_main(argc-1, argv+1);
+               return 0;
+       }
+       else if( strcmp(argv[1], "addr") == 0 )
+       {
+               Addr_main(argc-1, argv+1);
+               return 0;
+       }
+       else if( strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 )
+       {
+               PrintUsage(argv[0]);
+               return 0;
+       }
+       
+       return 0;
+}
+
+/**
+ * \brief Print usage instructions
+ */
+void PrintUsage(const char *ProgName)
+{
+       fprintf(stderr, "Usage:\n");
+       fprintf(stderr, "    %s addr add <device> <ip>/<prefix>\n", ProgName);
+       fprintf(stderr, "        Add a new interface listening on <device> with the specified\n");
+       fprintf(stderr, "        address.\n");
+       fprintf(stderr, "    %s addr del <interface>\n", ProgName);
+       fprintf(stderr, "        Delete an interface\n");
+       fprintf(stderr, "    %s addr [<interface>]\n", ProgName);
+       fprintf(stderr, "        Print the current interfaces (or only <interface> if passed)\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "    %s route\n", ProgName);
+       fprintf(stderr, "        Print the routing tables\n");
+       fprintf(stderr, "    %s route add <host>[/<prefix>] [<nexthop> OR <iface>] [<metric>]\n", ProgName);
+       fprintf(stderr, "        Add a new route\n");
+       fprintf(stderr, "    %s route del <host>[/<prefix>]\n", ProgName);
+       fprintf(stderr, "    %s route del <routenum>\n", ProgName);
+       fprintf(stderr, "        Add a new route\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "A note on Acess's IP Stack:\n");
+       fprintf(stderr, "    Each interface corresponds to only one IP address (either IPv4\n");
+       fprintf(stderr, "    or IPv6). A network device can have multiple interfaces bound\n");
+       fprintf(stderr, "    to it, allowing multiple addresses for one network connection\n");
+       fprintf(stderr, "\n");
+}
+
+
+/**
+ * \brief Parse an IP Address
+ * \return 0 for unknown, 4 for IPv4 and 6 for IPv6
+ */
+int ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits)
+{
+       const char      *p = Address;
+       
+       // Check first block
+       while(*p && *p >= '0' && *p <= '9')     p ++;
+       
+       // IPv4?
+       if(*p == '.')
+       {
+                int    i = 0, j;
+                int    val;
+               
+               for( j = 0; Address[i] && j < 4; j ++ )
+               {
+                       val = 0;
+                       for( ; '0' <= Address[i] && Address[i] <= '9'; i++ )
+                       {
+                               val = val*10 + Address[i] - '0';
+                       }
+                       if(val > 255) {
+                               //printf("val > 255 (%i)\n", val);
+                               return 0;
+                       }
+                       Dest[j] = val;
+                       
+                       if(Address[i] == '.')
+                               i ++;
+               }
+               if( j != 4 ) {
+                       //printf("4 parts expected, %i found\n", j);
+                       return 0;
+               }
+               // Parse subnet size
+               if(Address[i] == '/') {
+                       val = 0;
+                       i ++;
+                       while('0' <= Address[i] && Address[i] <= '9') {
+                               val *= 10;
+                               val += Address[i] - '0';
+                               i ++;
+                       }
+                       if(val > 32) {
+                               printf("Notice: Subnet size >32 (%i)\n", val);
+                       }
+                       if(SubnetBits)  *SubnetBits = val;
+               }
+               if(Address[i] != '\0') {
+                       //printf("EOS != '\\0', '%c'\n", Address[i]);
+                       return 0;
+               }
+               return 4;
+       }
+       
+       // IPv6
+       if(*p == ':' || ('a' <= *p && *p <= 'f') || ('A' <= *p && *p <= 'F'))
+       {
+                int    i = 0;
+                int    j, k;
+                int    val, split = -1, end;
+               uint16_t        hi[8], low[8];
+               
+               for( j = 0; Address[i] && j < 8; j ++ )
+               {
+                       if(Address[i] == '/')
+                               break;
+                       
+                       if(Address[i] == ':') {
+                               if(split != -1) {
+                                       printf("Two '::'s\n");
+                                       return 0;
+                               }
+                               split = j;
+                               i ++;
+                               continue;
+                       }
+                       
+                       val = 0;
+                       for( k = 0; Address[i] && Address[i] != ':' && Address[i] != '/'; i++, k++ )
+                       {
+                               val *= 16;
+                               if('0' <= Address[i] && Address[i] <= '9')
+                                       val += Address[i] - '0';
+                               else if('A' <= Address[i] && Address[i] <= 'F')
+                                       val += Address[i] - 'A' + 10;
+                               else if('a' <= Address[i] && Address[i] <= 'f')
+                                       val += Address[i] - 'a' + 10;
+                               else {
+                                       printf("%c unexpected\n", Address[i]);
+                                       return 0;
+                               }
+                       }
+                       
+                       if(val > 0xFFFF) {
+                               printf("val (0x%x) > 0xFFFF\n", val);
+                               return 0;
+                       }
+                       
+                       if(split == -1)
+                               hi[j] = val;
+                       else
+                               low[j-split] = val;
+                       
+                       if( Address[i] == ':' ) {
+                               i ++;
+                       }
+               }
+               end = j;
+               
+               // Parse subnet size
+               if(Address[i] == '/') {
+                       val = 0;
+                       while('0' <= Address[i] && Address[i] <= '9') {
+                               val *= 10;
+                               val += Address[i] - '0';
+                               i ++;
+                       }
+                       if(val > 128) {
+                               printf("Notice: Subnet size >128 (%i)\n", val);
+                       }
+                       if(SubnetBits)  *SubnetBits = val;
+               }
+               
+               for( j = 0; j < split; j ++ )
+               {
+                       //printf("%04x:", hi[j]);
+                       Dest[j*2] = hi[j]>>8;
+                       Dest[j*2+1] = hi[j]&0xFF;
+               }
+               for( ; j < 8 - (end - split); j++ )
+               {
+                       //printf("0000:", hi[j]);
+                       Dest[j*2] = 0;
+                       Dest[j*2+1] = 0;
+               }
+               for( k = 0; j < 8; j ++, k++)
+               {
+                       //printf("%04x:", low[k]);
+                       Dest[j*2] = low[k]>>8;
+                       Dest[j*2+1] = low[k]&0xFF;
+               }
+               return 6;
+       }
+       // Unknown type
+       return 0;
+}
diff --git a/Usermode/Applications/ip_src/routes.c b/Usermode/Applications/ip_src/routes.c
new file mode 100644 (file)
index 0000000..1d60fbc
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ * 
+ * routes.c
+ * - `ip route` sub-command
+ */
+#include "common.h"
+
+#define DEFAULT_METRIC 30
+
+// === PROTOTYPES ===
+ int   Routes_main(int argc, char *argv[]);
+void   DumpRoutes(void);
+void   DumpRoute(const char *Name);
+void   AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop);
+
+// === CODE ===
+int Routes_main(int argc, char *argv[])
+{
+       if( argc <= 1 )
+       {
+               // Show routes
+               DumpRoutes();
+       }
+       // Add new route
+       else if( strcmp(argv[1], "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 <host>[/<prefix>] <interface> [<metric>]
+               // ifconfig route add <host>[/<prefix>] <next hop> [<metric>]
+               if( argc - 2 < 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 - 2 > 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( strcmp(argv[2], "del") == 0 )
+       {
+               // Usage:
+               // ifconfig route del <routenum>
+               // ifconfig route del <host>[/<prefix>]
+       }
+       else
+       {
+               // List routes
+               DumpRoutes();
+       }
+       
+       return 0;
+}
+
+/**
+ * \brief Dump all interfaces
+ */
+void DumpRoutes(void)
+{
+        int    dp;
+       char    filename[FILENAME_MAX+1];
+       
+       dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
+       
+       printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
+       
+       while( readdir(dp, filename) )
+       {
+               if(filename[0] == '.')  continue;
+               DumpRoute(filename);
+       }
+       
+       close(dp);
+}
+
+/**
+ * \brief Dump a route
+ */
+void DumpRoute(const char *Name)
+{
+        int    fd;
+        int    type;
+       char    path[sizeof(IPSTACK_ROOT)+8+FILENAME_MAX+1] = IPSTACK_ROOT"/routes/";
+       
+       strcat(path, Name);
+       
+       fd = open(path, OPENFLAG_READ);
+       if(fd == -1) {
+               printf("%s:\tUnable to open ('%s')\n", Name, path);
+               return ;
+       }
+       
+        int    ofs = 2;
+       type = atoi(Name);
+       
+        int    i;
+        int    len = Net_GetAddressSize(type);
+       uint8_t net[len], gw[len];
+        int    subnet, metric;
+       for( i = 0; i < len; i ++ ) {
+               char tmp[5] = "0x00";
+               tmp[2] = Name[ofs++];
+               tmp[3] = Name[ofs++];
+               net[i] = atoi(tmp);
+       }
+       ofs ++;
+       subnet = atoi(Name+ofs);
+       ofs ++;
+       metric = atoi(Name+ofs);
+       ioctl(fd, ioctl(fd, 3, "get_nexthop"), gw);     // Get Gateway/NextHop
+       
+       // Get the address type
+       switch(type)
+       {
+       case 0: // Disabled/Unset
+               printf("DISABLED\n");
+               break;
+       case 4: // IPv4
+               printf("IPv4\t");
+               break;
+       case 6: // IPv6
+               printf("IPv6\t");
+               break;
+       default:        // Unknow
+               printf("UNKNOWN (%i)\n", type);
+               break;
+       }
+       printf("%s/%i\t", Net_PrintAddress(type, net), subnet);
+       printf("%s \t", Net_PrintAddress(type, gw));
+       printf("%i\t", metric);
+       
+       // Interface
+       {
+                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);
+       }
+       
+       printf("\n");
+                       
+       close(fd);
+}
+
+void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
+{
+        int    fd;
+        int    num;
+       char    *ifaceToFree = NULL;
+       
+       // Get interface name
+       if( !Interface )
+       {
+               if( !NextHop ) {
+                       fprintf(stderr,
+                               "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
+                               "Only one should be NULL\n"
+                               );
+                       return ;
+               }
+               
+               // Query for the interface name
+               Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
+       }
+       // Check address type (if the interface was passed)
+       // - If we got the interface name, then it should be correct
+       else
+       {
+               char    ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
+               
+               // Open interface
+               strcpy(ifacePath, IPSTACK_ROOT"/");
+               strcat(ifacePath, Interface);
+               fd = open(ifacePath, 0);
+               if( fd == -1 ) {
+                       fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
+                       return ;
+               }
+               // Get and check type
+               num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
+               if( num != AddressType ) {
+                       fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
+                               AddressType, num);
+                       return ;
+               }
+               
+               close(fd);
+       }
+       
+       // Create route
+        int    addrsize = Net_GetAddressSize(AddressType);
+        int    len = snprintf(NULL, 0, "/Devices/ip/routes/%i::%i:%i", AddressType, MaskBits, Metric) + addrsize*2;
+       char    path[len+1];
+       {
+                int    i, ofs;
+               ofs = sprintf(path, "/Devices/ip/routes/%i:", AddressType);
+               for( i = 0; i < addrsize; i ++ )
+                       sprintf(path+ofs+i*2, "%02x", ((uint8_t*)Dest)[i]);
+               ofs += addrsize*2;
+               sprintf(path+ofs, ":%i:%i", MaskBits, Metric);
+       }
+
+       fd = open(path, 0);
+       if( fd != -1 ) {
+               close(fd);
+               fprintf(stderr, "Unable to create route '%s', already exists\n", path);
+               return ;
+       }
+       fd = open(path, OPENFLAG_CREATE, 0);
+       if( fd == -1 ) {
+               fprintf(stderr, "Unable to create '%s'\n", path);
+               return ;
+       }
+       
+       if( NextHop )
+               ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
+       ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
+       
+       close(fd);
+       
+       // Check if the interface name was allocated by us
+       if( ifaceToFree )
+               free(ifaceToFree);
+}
+
diff --git a/Usermode/Applications/ip_src/rules.mk b/Usermode/Applications/ip_src/rules.mk
new file mode 100644 (file)
index 0000000..f420eb8
--- /dev/null
@@ -0,0 +1,14 @@
+# ifconfig
+
+include $(BASE)header.mk
+
+# Variables
+SRCS := main.c
+BIN  := $(OUTPUTDIR)Bin/ifconfig
+
+LDFLAGS-$(DIR) += -lnet
+
+include $(BASE)body.mk
+
+include $(BASE)footer.mk
+

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