- //if(strcmp(Arguments[i], "Device") == '=') {
- //
- //}
- }
- }
-
- DevFS_AddDevice( &gIP_DriverInfo );
-
- return 1;
-}
-
-/**
- * \brief Read from the IP Stack's Device Directory
- */
-char *IPStack_ReadDir(tVFS_Node *Node, int Pos)
-{
- tInterface *iface;
- char *name;
- ENTER("pNode iPos", Node, Pos);
-
- // Traverse the list
- for( iface = gIP_Interfaces; iface && Pos--; iface = iface->Next ) ;
-
- // Did we run off the end?
- if(!iface) {
- LEAVE('n');
- return NULL;
- }
-
- name = malloc(6);
- name[0] = 'i';
- name[1] = 'p';
-
- // Create the name
- Pos = iface->Node.ImplInt;
- if(Pos < 10) {
- name[2] = '0' + Pos;
- name[3] = '\0';
- }
- else if(Pos < 100) {
- name[2] = '0' + Pos/10;
- name[3] = '0' + Pos%10;
- name[4] = '\0';
- }
- else {
- name[2] = '0' + Pos/100;
- name[3] = '0' + (Pos/10)%10;
- name[4] = '0' + Pos%10;
- name[5] = '\0';
- }
-
- LEAVE('s', name);
- // Return the pre-generated name
- return name;
-}
-
-/**
- * \brief Get the node of an interface
- */
-tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name)
-{
- int i, num;
- tInterface *iface;
-
- ENTER("pNode sName", Node, Name);
-
- if(Name[0] != 'i' || Name[1] != 'p') {
- LEAVE('n');
- return NULL;
- }
-
- i = 2; num = 0;
- while('0' <= Name[i] && Name[i] <= '9')
- {
- num *= 10;
- num += Name[i] - '0';
- i ++;
- }
- if(Name[i] != '\0') {
- LEAVE('n');
- return NULL;
- }
-
- for( iface = gIP_Interfaces; iface; iface = iface->Next )
- {
- if( iface->Node.ImplInt == num )
- {
- LEAVE('p', &iface->Node);
- return &iface->Node;
- }
- }
- LEAVE('p', NULL);
- return NULL;
-}
-
-static const char *casIOCtls_Root[] = { DRV_IOCTLNAMES, "add_interface", NULL };
-static const char *casIOCtls_Iface[] = {
- DRV_IOCTLNAMES,
- "getset_type",
- "get_address", "set_address",
- "getset_subnet",
- "get_gateway", "set_gateway",
- NULL
- };
-/**
- * \brief Handles IOCtls for the IPStack root/interfaces
- */
-int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data)
-{
- int tmp;
- ENTER("pNode iID pData", Node, ID, Data);
-
- switch(ID)
- {
- // --- Standard IOCtls (0-3) ---
- case DRV_IOCTL_TYPE:
- LEAVE('i', DRV_TYPE_MISC);
- return DRV_TYPE_MISC;
-
- case DRV_IOCTL_IDENT:
- if( !CheckMem( Data, 4 ) ) LEAVE_RET('i', -1);
- memcpy(Data, "IP\0\0", 4);
- LEAVE('i', 1);
- return 1;
-
- case DRV_IOCTL_VERSION:
- LEAVE('x', VERSION);
- return VERSION;
-
- case DRV_IOCTL_LOOKUP:
- if( !CheckString( Data ) ) LEAVE_RET('i', -1);
- LOG("Lookup '%s'", Data);
- if( Node == &gIP_DriverInfo.RootNode )
- tmp = LookupString( (char**)casIOCtls_Root, (char*)Data );
- else
- tmp = LookupString( (char**)casIOCtls_Iface, (char*)Data );
- LEAVE('i', tmp);
- return tmp;
- }
-
- if(Node == &gIP_DriverInfo.RootNode)
- {
- switch(ID)
- {
- /*
- * add_interface
- * - Adds a new IP interface and binds it to a device
- */
- case 4:
- if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1);
- if( !CheckString( Data ) ) LEAVE_RET('i', -1);
- tmp = IPStack_AddInterface(Data);
- LEAVE_RET('i', tmp);
- }
- LEAVE('i', 0);
- return 0;
- }
- else
- {
- tInterface *iface = (tInterface*)Node->ImplPtr;
- switch(ID)
- {
- /*
- * getset_type
- * - Get/Set the interface type
- */
- case 4:
- // Set Type?
- if( Data )
- {
- // Ok, it's set type
- if( Threads_GetUID() != 0 ) {
- LOG("Attempt by non-root to alter an interface (%i)", Threads_GetUID());
- LEAVE('i', -1);
- return -1;
+ // TODO:
+ // Define interfaces by <Device>:<Type>:<HexStreamAddress>:<Bits>
+ // Where:
+ // - <Device> is the device path (E.g. /Devices/ne2k/0)
+ // - <Type> is a number (e.g. 4) or symbol (e.g. AF_INET4)
+ // - <HexStreamAddress> is a condensed hexadecimal stream (in big endian)
+ // (E.g. 0A000201 for 10.0.2.1 IPv4)
+ // - <Bits> is the number of subnet bits (E.g. 24 for an IPv4 Class C)
+ // Example: /Devices/ne2k/0:4:0A00020A:24
+ // would define an interface with the address 10.0.2.10/24
+ if( Arguments[i][0] == '/' ) {
+ // Define Interface
+ char *dev, *type, *addr, *bits;
+
+ // Read definition
+ dev = Arguments[i];
+ type = strchr(dev, ':');
+ if( !type ) {
+ Log_Warning("IPStack", "<Device>:<Type>:<HexStreamAddress>:<Bits>");
+ continue;