From 0255883b3e68d607b8250006927575fe15a7f23b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 5 Feb 2010 16:42:50 +0800 Subject: [PATCH] More work on IPStack, TCP and UDP slowly moving along --- Kernel/Makefile.BuildNum | 2 +- Modules/IPStack/Makefile | 2 +- Modules/IPStack/ipstack.h | 14 ++++ Modules/IPStack/main.c | 74 ++++++++++++++---- Modules/IPStack/tcp.c | 159 ++++++++++++++++++++++++++++++++------ Modules/IPStack/tcp.h | 3 +- Modules/IPStack/udp.c | 6 ++ 7 files changed, 221 insertions(+), 39 deletions(-) diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index be8bd603..717df107 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1423 +BUILD_NUM = 1430 diff --git a/Modules/IPStack/Makefile b/Modules/IPStack/Makefile index 6c26f2d3..a79f09aa 100644 --- a/Modules/IPStack/Makefile +++ b/Modules/IPStack/Makefile @@ -4,7 +4,7 @@ OBJ = main.o link.o arp.o OBJ += ipv4.o icmp.o OBJ += ipv6.o -OBJ += udp.o +OBJ += udp.o tcp.o NAME = IPStack -include ../Makefile.tpl diff --git a/Modules/IPStack/ipstack.h b/Modules/IPStack/ipstack.h index faf8cb8c..54d8fb82 100644 --- a/Modules/IPStack/ipstack.h +++ b/Modules/IPStack/ipstack.h @@ -13,6 +13,7 @@ typedef union uIPv6 tIPv6; typedef struct sMacAddr tMacAddr; typedef struct sAdapter tAdapter; typedef struct sInterface tInterface; +typedef struct sSocketFile tSocketFile; typedef void (*tIPCallback)(tInterface *Interface, void *Address, int Length, void *Buffer); @@ -63,6 +64,17 @@ struct sAdapter { char Device[]; }; +/** + * \brief Describes a socket file definition + */ +struct sSocketFile +{ + struct sSocketFile *Next; + const char *Name; + + tVFS_Node *(*Init)(tInterface *Interface); +}; + static const tMacAddr cMAC_BROADCAST = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; #define MAC_SET(t,v) memcpy(&(t),&(v),sizeof(tMacAddr)) @@ -81,4 +93,6 @@ static const tMacAddr cMAC_BROADCAST = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; #define ntohs(in) BigEndian16(in) #define ntohl(in) BigEndian32(in) +extern int IPStack_AddFile(tSocketFile *File); + #endif diff --git a/Modules/IPStack/main.c b/Modules/IPStack/main.c index e899cc4d..60bc787d 100644 --- a/Modules/IPStack/main.c +++ b/Modules/IPStack/main.c @@ -23,11 +23,14 @@ extern int IPv4_Ping(tInterface *Iface, tIPv4 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, 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, char *Name); + int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data); // === GLOBALS === MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL); @@ -38,9 +41,9 @@ 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; @@ -49,6 +52,7 @@ tInterface *gIP_Interfaces_Last = NULL; int giIP_NextIfaceId = 1; tSpinlock glIP_Adapters = 0; tAdapter *gIP_Adapters = NULL; +tSocketFile *gIP_FileTemplates; // === CODE === /** @@ -79,10 +83,20 @@ int IPStack_Install(char **Arguments) return 1; } +/** + * \brief Adds a file to the socket list + */ +int IPStack_AddFile(tSocketFile *File) +{ + 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; @@ -127,7 +141,7 @@ 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, char *Name) { int i, num; tInterface *iface; @@ -167,7 +181,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); @@ -207,6 +221,40 @@ 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, 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", @@ -219,7 +267,7 @@ static const char *casIOCtls_Iface[] = { /** * \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; @@ -464,9 +512,9 @@ int IPStack_AddInterface(char *Device) iface->Node.Size = 0; 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; // Set Defaults iface->TimeoutDelay = DEFAULT_TIMEOUT; diff --git a/Modules/IPStack/tcp.c b/Modules/IPStack/tcp.c index b8c17584..cfc3efc0 100644 --- a/Modules/IPStack/tcp.c +++ b/Modules/IPStack/tcp.c @@ -10,10 +10,26 @@ // === PROTOTYPES === void TCP_Initialise(); void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port); -void TCP_GetPacket(tInterface *Interface, int Length, void *Buffer); +void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer); Uint16 TCP_GetUnusedPort(); int TCP_AllocatePort(Uint16 Port); int TCP_DeallocatePort(Uint16 Port); +// --- Server +tVFS_Node *TCP_Server_Init(tInterface *Interface); +char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos); +tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name); + int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data); +void TCP_Server_Close(tVFS_Node *Node); +// --- Client +tVFS_Node *TCP_Client_Init(tInterface *Interface); +Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); +Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); + int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data); +void TCP_Client_Close(tVFS_Node *Node); + +// === TEMPLATES === +tSocketFile gTCP_ServerFile = {NULL, "tcps", TCP_Server_Init}; +tSocketFile gTCP_ClientFile = {NULL, "tcpc", TCP_Client_Init}; // === GLOBALS === int giTCP_NumHalfopen = 0; @@ -29,34 +45,19 @@ Uint32 gaTCP_PortBitmap[0x800]; */ void TCP_Initialise() { - + IPStack_AddFile(&gTCP_ServerFile); + IPStack_AddFile(&gTCP_ClientFile); } /** * \fn void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port) * \brief Open a connection to another host using TCP */ -void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port) -{ - tTCPConnection *ret = malloc( sizeof(tTCPConnection) ); - - ret->State = TCP_ST_CLOSED; - if(LocalPort == 0) - ret->LocalPort = TCP_GetUnusedPort(); - else - ret->LocalPort = LocalPort; - ret->RemotePort = Port; - - ret->LocalInterface = Interface; - - if(Interface->Type == 6) - ret->RemoteIP.v6 = *(tIPv6*)Address; - else - ret->RemoteIP.v4 = *(tIPv4*)Address; - +void TCP_StartConnection(tTCPConnection *Conn) +{ // SEND PACKET - - return ret; + // Send a TCP SYN to the target to open the connection + return ; } /** @@ -99,7 +100,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe return; } - // Open a new connection + // Open a new connection (well, check that it's a SYN) //TODO break; @@ -173,3 +174,115 @@ int TCP_DeallocatePort(Uint16 Port) return 1; } +// --- Server +tVFS_Node *TCP_Server_Init(tInterface *Interface) +{ + return NULL; +} + +char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos) +{ + return NULL; +} + +tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name) +{ + return NULL; +} + +int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + return 0; +} + +// --- Client +tVFS_Node *TCP_Client_Init(tInterface *Interface) +{ + tTCPConnection *conn = malloc( sizeof(tTCPConnection) ); + + conn->State = TCP_ST_CLOSED; + conn->Interface = Interface; + conn->LocalPort = 0; + conn->RemotePort = 0; + memset( &conn->RemoteIP, 0, sizeof(conn->RemoteIP) ); + + conn->Node.ImplPtr = conn; + conn->Node.NumACLs = 1; + conn->Node.ACLs = &gVFS_ACL_EveryoneRW; + conn->Node.Read = TCP_Client_Read; + conn->Node.Write = TCP_Client_Write; + conn->Node.IOCtl = TCP_Client_IOCtl; + conn->Node.Close = TCP_Client_Close; + + return &conn->Node; +} + +Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + return 0; +} + +Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + return 0; +} + +int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data) +{ + tTCPConnection *conn = Node->ImplPtr; + + switch(ID) + { + case 5: // Get/Set local port + if(!Data) + return conn->LocalPort; + if(conn->State != TCP_ST_CLOSED) + return -1; + if(!CheckMem(Data, sizeof(Uint16))) + return -1; + + if(Threads_GetUID() != 0 && *(Uint16*)Data < 1024) + return -1; + + conn->LocalPort = *(Uint16*)Data; + return 0; + + case 6: // Get/Set remote port + if(!Data) return conn->RemotePort; + if(conn->State != TCP_ST_CLOSED) return -1; + if(!CheckMem(Data, sizeof(Uint16))) return -1; + conn->RemotePort = *(Uint16*)Data; + return 0; + + case 7: // Set Remote IP + if( conn->State != TCP_ST_CLOSED ) + return -1; + if( conn->Interface->Type == 4 ) + { + if(!CheckMem(Data, sizeof(tIPv4))) return -1; + conn->RemoteIP.v4 = *(tIPv4*)Data; + } + else if( conn->Interface->Type == 6 ) + { + if(!CheckMem(Data, sizeof(tIPv6))) return -1; + conn->RemoteIP.v6 = *(tIPv6*)Data; + } + return 0; + + case 8: // Connect + if(conn->LocalPort == -1) + conn->LocalPort = TCP_GetUnusedPort(); + if(conn->RemotePort == -1) + return 0; + + TCP_StartConnection(conn); + return 1; + } + + return 0; +} + +void TCP_Client_Close(tVFS_Node *Node) +{ + free(Node->ImplPtr); +} diff --git a/Modules/IPStack/tcp.h b/Modules/IPStack/tcp.h index fb515acb..0b641950 100644 --- a/Modules/IPStack/tcp.h +++ b/Modules/IPStack/tcp.h @@ -53,8 +53,9 @@ struct sTCPConnection int State; Uint16 LocalPort; Uint16 RemotePort; + tVFS_Node Node; - tInterface *LocalInterface; + tInterface *Interface; union { tIPv4 v4; tIPv6 v6; diff --git a/Modules/IPStack/udp.c b/Modules/IPStack/udp.c index c57f284c..194c62b2 100644 --- a/Modules/IPStack/udp.c +++ b/Modules/IPStack/udp.c @@ -8,6 +8,12 @@ // === PROTOTYPES === void UDP_Initialise(); void UDP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer); +// --- Channel +tVFS_Node *UDP_Channel_Init(tInterface *Interface); +Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); +Uint64 UDP_Channel_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); + int UDP_Channel_IOCtl(tVFS_Node *Node, int ID, void *Data); +void UDP_Channel_Close(tVFS_Node *Node); // === GLOBALS === -- 2.20.1