X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FIPStack%2Fmain.c;h=fe4bf0f685da552348884d1dce9011f7c40c006c;hb=25f7e9ab0f31ca486c0c981a406d381e160637a4;hp=01e65f901d30abc3327625b12e53168dcc77db12;hpb=6ea2f6040da80c963882f6ccfe4bf21ff048eaff;p=tpg%2Facess2.git diff --git a/Modules/IPStack/main.c b/Modules/IPStack/main.c index 01e65f90..fe4bf0f6 100644 --- a/Modules/IPStack/main.c +++ b/Modules/IPStack/main.c @@ -4,7 +4,6 @@ */ #define DEBUG 0 #define VERSION VER2(0,10) -#define IDENT IPStack #include "ipstack.h" #include "link.h" #include @@ -18,20 +17,27 @@ // === IMPORTS === extern int ARP_Initialise(); +extern void UDP_Initialise(); +extern void TCP_Initialise(); extern int IPv4_Initialise(); extern int IPv4_Ping(tInterface *Iface, tIPv4 Addr); +extern int IPv6_Initialise(); +//extern int IPv6_Ping(tInterface *Iface, tIPv6 Addr); // === PROTOTYPES === int IPStack_Install(char **Arguments); int IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data); -char *IPStack_ReadDir(tVFS_Node *Node, int Pos); -tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name); - int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data); +char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos); +tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name); + int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data); int IPStack_AddInterface(char *Device); tAdapter *IPStack_GetAdapter(char *Path); +char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos); +tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name); + int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data); // === GLOBALS === -MODULE_DEFINE(0, VERSION, IDENT, IPStack_Install, NULL, NULL); +MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL); tDevFS_Driver gIP_DriverInfo = { NULL, "ip", { @@ -39,17 +45,18 @@ tDevFS_Driver gIP_DriverInfo = { .NumACLs = 1, .ACLs = &gVFS_ACL_EveryoneRX, .Flags = VFS_FFLAG_DIRECTORY, - .ReadDir = IPStack_ReadDir, - .FindDir = IPStack_FindDir, - .IOCtl = IPStack_IOCtlRoot + .ReadDir = IPStack_Root_ReadDir, + .FindDir = IPStack_Root_FindDir, + .IOCtl = IPStack_Root_IOCtl } }; -tSpinlock glIP_Interfaces = 0; +tShortSpinlock glIP_Interfaces; tInterface *gIP_Interfaces = NULL; tInterface *gIP_Interfaces_Last = NULL; int giIP_NextIfaceId = 1; -tSpinlock glIP_Adapters = 0; +tMutex glIP_Adapters; tAdapter *gIP_Adapters = NULL; +tSocketFile *gIP_FileTemplates; // === CODE === /** @@ -60,9 +67,14 @@ int IPStack_Install(char **Arguments) { int i = 0; - // Install Handlers + // Layer 2 - Data Link Layer ARP_Initialise(); + // Layer 3 - Network Layer IPv4_Initialise(); + IPv6_Initialise(); + // Layer 4 - Transport Layer + TCP_Initialise(); + UDP_Initialise(); if(Arguments) { @@ -77,13 +89,24 @@ int IPStack_Install(char **Arguments) DevFS_AddDevice( &gIP_DriverInfo ); - return 1; + return MODULE_ERR_OK; +} + +/** + * \brief Adds a file to the socket list + */ +int IPStack_AddFile(tSocketFile *File) +{ + Log_Log("IPStack", "Added file '%s'", File->Name); + File->Next = gIP_FileTemplates; + gIP_FileTemplates = File; + return 0; } /** * \brief Read from the IP Stack's Device Directory */ -char *IPStack_ReadDir(tVFS_Node *Node, int Pos) +char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos) { tInterface *iface; char *name; @@ -98,26 +121,29 @@ char *IPStack_ReadDir(tVFS_Node *Node, int Pos) return NULL; } - name = malloc(6); - name[0] = 'i'; - name[1] = 'p'; + name = malloc(4); + if(!name) { + Log_Warning("IPStack", "IPStack_Root_ReadDir - malloc error"); + LEAVE('n'); + return NULL; + } // Create the name Pos = iface->Node.ImplInt; if(Pos < 10) { - name[2] = '0' + Pos; - name[3] = '\0'; + name[0] = '0' + Pos; + name[1] = '\0'; } else if(Pos < 100) { - name[2] = '0' + Pos/10; - name[3] = '0' + Pos%10; - name[4] = '\0'; + name[0] = '0' + Pos/10; + name[1] = '0' + Pos%10; + name[2] = '\0'; } else { - name[2] = '0' + Pos/100; - name[3] = '0' + (Pos/10)%10; - name[4] = '0' + Pos%10; - name[5] = '\0'; + name[0] = '0' + Pos/100; + name[1] = '0' + (Pos/10)%10; + name[2] = '0' + Pos%10; + name[3] = '\0'; } LEAVE('s', name); @@ -128,19 +154,14 @@ char *IPStack_ReadDir(tVFS_Node *Node, int Pos) /** * \brief Get the node of an interface */ -tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name) +tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const 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; + i = 0; num = 0; while('0' <= Name[i] && Name[i] <= '9') { num *= 10; @@ -154,7 +175,7 @@ tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name) for( iface = gIP_Interfaces; iface; iface = iface->Next ) { - if( iface->Node.ImplInt == num ) + if( (int)iface->Node.ImplInt == num ) { LEAVE('p', &iface->Node); return &iface->Node; @@ -168,7 +189,7 @@ static const char *casIOCtls_Root[] = { DRV_IOCTLNAMES, "add_interface", NULL }; /** * \brief Handles IOCtls for the IPStack root */ -int IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data) +int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data) { int tmp; ENTER("pNode iID pData", Node, ID, Data); @@ -181,7 +202,7 @@ int IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data) return DRV_TYPE_MISC; case DRV_IOCTL_IDENT: - tmp = ModUtil_SetIdent(Data, STR(IDENT)); + tmp = ModUtil_SetIdent(Data, "IPStack"); LEAVE('i', 1); return 1; @@ -208,19 +229,56 @@ int IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data) return 0; } +/** + * \brief Read from an interface's directory + */ +char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos) +{ + tSocketFile *file = gIP_FileTemplates; + while(Pos-- && file) { + file = file->Next; + } + + if(!file) return NULL; + + return strdup(file->Name); +} + +/** + * \brief Gets a named node from an interface directory + */ +tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name) +{ + tSocketFile *file = gIP_FileTemplates; + + // Get file definition + for(;file;file = file->Next) + { + if( strcmp(file->Name, Name) == 0 ) break; + } + if(!file) return NULL; + + // Pass the buck! + return file->Init(Node->ImplPtr); +} + +/** + * \brief Names for interface IOCtl Calls + */ static const char *casIOCtls_Iface[] = { DRV_IOCTLNAMES, "getset_type", "get_address", "set_address", "getset_subnet", "get_gateway", "set_gateway", + "get_device", "ping", NULL }; /** * \brief Handles IOCtls for the IPStack interfaces */ -int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data) +int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data) { int tmp; tInterface *iface = (tInterface*)Node->ImplPtr; @@ -411,11 +469,23 @@ int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data) } break; + /* + * get_device + * - Gets the name of the attached device + */ + case 10: + 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 ); + return iface->Adapter->DeviceLen; + /* * ping * - Send an ICMP Echo */ - case 10: + case 11: switch(iface->Type) { case 0: @@ -446,9 +516,12 @@ int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data) int IPStack_AddInterface(char *Device) { tInterface *iface; + tAdapter *card; ENTER("sDevice", Device); + card = IPStack_GetAdapter(Device); + iface = malloc(sizeof(tInterface)); if(!iface) { LEAVE('i', -2); @@ -460,14 +533,17 @@ int IPStack_AddInterface(char *Device) // Create Node iface->Node.ImplPtr = iface; - iface->Node.ImplInt = giIP_NextIfaceId++; iface->Node.Flags = VFS_FFLAG_DIRECTORY; - iface->Node.Size = 0; + iface->Node.Size = -1; iface->Node.NumACLs = 1; iface->Node.ACLs = &gVFS_ACL_EveryoneRX; - iface->Node.ReadDir = NULL; - iface->Node.FindDir = NULL; - iface->Node.IOCtl = IPStack_IOCtl; + iface->Node.ReadDir = IPStack_Iface_ReadDir; + iface->Node.FindDir = IPStack_Iface_FindDir; + iface->Node.IOCtl = IPStack_Iface_IOCtl; + iface->Node.MkNod = NULL; + iface->Node.Link = NULL; + iface->Node.Relink = NULL; + iface->Node.Close = NULL; // Set Defaults iface->TimeoutDelay = DEFAULT_TIMEOUT; @@ -480,8 +556,12 @@ int IPStack_AddInterface(char *Device) return -1; // Return ERR_YOUFAIL } + // Delay setting ImplInt until after the adapter is opened + // Keeps things simple + iface->Node.ImplInt = giIP_NextIfaceId++; + // Append to list - LOCK( &glIP_Interfaces ); + SHORTLOCK( &glIP_Interfaces ); if( gIP_Interfaces ) { gIP_Interfaces_Last->Next = iface; gIP_Interfaces_Last = iface; @@ -490,7 +570,7 @@ int IPStack_AddInterface(char *Device) gIP_Interfaces = iface; gIP_Interfaces_Last = iface; } - RELEASE( &glIP_Interfaces ); + SHORTREL( &glIP_Interfaces ); gIP_DriverInfo.RootNode.Size ++; @@ -510,14 +590,14 @@ tAdapter *IPStack_GetAdapter(char *Path) ENTER("sPath", Path); - LOCK( &glIP_Adapters ); + Mutex_Acquire( &glIP_Adapters ); // Check if this adapter is already open for( dev = gIP_Adapters; dev; dev = dev->Next ) { if( strcmp(dev->Device, Path) == 0 ) { dev->NRef ++; - RELEASE( &glIP_Adapters ); + Mutex_Release( &glIP_Adapters ); LEAVE('p', dev); return dev; } @@ -526,7 +606,7 @@ tAdapter *IPStack_GetAdapter(char *Path) // Ok, so let's open it dev = malloc( sizeof(tAdapter) + strlen(Path) + 1 ); if(!dev) { - RELEASE( &glIP_Adapters ); + Mutex_Release( &glIP_Adapters ); LEAVE('n'); return NULL; } @@ -534,12 +614,13 @@ tAdapter *IPStack_GetAdapter(char *Path) // Fill Structure strcpy( dev->Device, Path ); dev->NRef = 1; + dev->DeviceLen = strlen(Path); // Open Device dev->DeviceFD = VFS_Open( dev->Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE ); if( dev->DeviceFD == -1 ) { free( dev ); - RELEASE( &glIP_Adapters ); + Mutex_Release( &glIP_Adapters ); LEAVE('n'); return NULL; } @@ -551,7 +632,7 @@ tAdapter *IPStack_GetAdapter(char *Path) Warning("IPStack_GetAdapter: '%s' is not a network interface", dev->Device); VFS_Close( dev->DeviceFD ); free( dev ); - RELEASE( &glIP_Adapters ); + Mutex_Release( &glIP_Adapters ); LEAVE('n'); return NULL; } @@ -563,7 +644,7 @@ tAdapter *IPStack_GetAdapter(char *Path) dev->Next = gIP_Adapters; gIP_Adapters = dev; - RELEASE( &glIP_Adapters ); + Mutex_Release( &glIP_Adapters ); // Start watcher Link_WatchDevice( dev );