More work on IPStack, TCP and UDP slowly moving along
authorJohn Hodge <tpg@prelude.(none)>
Fri, 5 Feb 2010 08:42:50 +0000 (16:42 +0800)
committerJohn Hodge <tpg@prelude.(none)>
Fri, 5 Feb 2010 08:42:50 +0000 (16:42 +0800)
Kernel/Makefile.BuildNum
Modules/IPStack/Makefile
Modules/IPStack/ipstack.h
Modules/IPStack/main.c
Modules/IPStack/tcp.c
Modules/IPStack/tcp.h
Modules/IPStack/udp.c

index be8bd60..717df10 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1423
+BUILD_NUM = 1430
index 6c26f2d..a79f09a 100644 (file)
@@ -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
index faf8cb8..54d8fb8 100644 (file)
@@ -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
index e899cc4..60bc787 100644 (file)
@@ -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;
index b8c1758..cfc3efc 100644 (file)
 // === 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);
+}
index fb515ac..0b64195 100644 (file)
@@ -53,8 +53,9 @@ struct sTCPConnection
         int    State;
        Uint16  LocalPort;
        Uint16  RemotePort;
+       tVFS_Node       Node;
        
-       tInterface      *LocalInterface;
+       tInterface      *Interface;
        union {
                tIPv4   v4;
                tIPv6   v6;
index c57f284..194c62b 100644 (file)
@@ -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 ===
 

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