8 #define TCP_MIN_DYNPORT 0x1000
11 void TCP_Initialise();
12 void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port);
13 void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
14 Uint16 TCP_GetUnusedPort();
15 int TCP_AllocatePort(Uint16 Port);
16 int TCP_DeallocatePort(Uint16 Port);
18 tVFS_Node *TCP_Server_Init(tInterface *Interface);
19 char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos);
20 tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name);
21 int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data);
22 void TCP_Server_Close(tVFS_Node *Node);
24 tVFS_Node *TCP_Client_Init(tInterface *Interface);
25 Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
26 Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
27 int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data);
28 void TCP_Client_Close(tVFS_Node *Node);
31 tSocketFile gTCP_ServerFile = {NULL, "tcps", TCP_Server_Init};
32 tSocketFile gTCP_ClientFile = {NULL, "tcpc", TCP_Client_Init};
35 int giTCP_NumHalfopen = 0;
36 tTCPListener *gTCP_Listeners;
37 tTCPConnection *gTCP_OutbountCons;
38 Uint32 gaTCP_PortBitmap[0x800];
39 int giTCP_NextOutPort = TCP_MIN_DYNPORT;
43 * \fn void TCP_Initialise()
44 * \brief Initialise the TCP Layer
48 IPStack_AddFile(&gTCP_ServerFile);
49 IPStack_AddFile(&gTCP_ClientFile);
53 * \fn void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port)
54 * \brief Open a connection to another host using TCP
56 void TCP_StartConnection(tTCPConnection *Conn)
59 // Send a TCP SYN to the target to open the connection
64 * \fn void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
65 * \brief Handles a packet from the IP Layer
67 void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
69 tTCPHeader *hdr = Buffer;
75 for( srv = gTCP_Listeners; srv; srv = srv->Next )
77 // Check the interface
78 if(srv->Interface && srv->Interface != Interface) continue;
79 // Check the destination port
80 if(srv->Port != hdr->DestPort) continue;
82 // Is this in an established connection?
83 for( conn = srv->Connections; conn; conn = conn->Next )
85 // Check that it is coming in on the same interface
86 if(conn->Interface != Interface) continue;
89 if(conn->RemotePort != hdr->SourcePort) continue;
92 if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
94 if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
97 // We have a response!
103 // Open a new connection (well, check that it's a SYN)
111 // Check Open Connections
113 for( conn = gTCP_OutbountCons; conn; conn = conn->Next )
121 * \fn Uint16 TCP_GetUnusedPort()
122 * \brief Gets an unused port and allocates it
124 Uint16 TCP_GetUnusedPort()
128 // Get Next outbound port
129 ret = giTCP_NextOutPort++;
130 while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) )
134 if(giTCP_NextOutPort == 0x10000) {
135 ret = giTCP_NextOutPort = TCP_MIN_DYNPORT;
139 // Mark the new port as used
140 gaTCP_PortBitmap[ret/32] |= 1 << (ret%32);
146 * \fn int TCP_AllocatePort(Uint16 Port)
147 * \brief Marks a port as used
149 int TCP_AllocatePort(Uint16 Port)
151 // Check if the port has already been allocated
152 if( gaTCP_PortBitmap[Port/32] & (1 << (Port%32)) )
156 gaTCP_PortBitmap[Port/32] |= 1 << (Port%32);
162 * \fn int TCP_DeallocatePort(Uint16 Port)
163 * \brief Marks a port as unused
165 int TCP_DeallocatePort(Uint16 Port)
167 // Check if the port has already been allocated
168 if( !(gaTCP_PortBitmap[Port/32] & (1 << (Port%32))) )
172 gaTCP_PortBitmap[Port/32] &= ~(1 << (Port%32));
178 tVFS_Node *TCP_Server_Init(tInterface *Interface)
183 char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
188 tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name)
193 int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data)
199 tVFS_Node *TCP_Client_Init(tInterface *Interface)
201 tTCPConnection *conn = malloc( sizeof(tTCPConnection) );
203 conn->State = TCP_ST_CLOSED;
204 conn->Interface = Interface;
206 conn->RemotePort = 0;
207 memset( &conn->RemoteIP, 0, sizeof(conn->RemoteIP) );
209 conn->Node.ImplPtr = conn;
210 conn->Node.NumACLs = 1;
211 conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
212 conn->Node.Read = TCP_Client_Read;
213 conn->Node.Write = TCP_Client_Write;
214 conn->Node.IOCtl = TCP_Client_IOCtl;
215 conn->Node.Close = TCP_Client_Close;
220 Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
225 Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
230 int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
232 tTCPConnection *conn = Node->ImplPtr;
236 case 5: // Get/Set local port
238 return conn->LocalPort;
239 if(conn->State != TCP_ST_CLOSED)
241 if(!CheckMem(Data, sizeof(Uint16)))
244 if(Threads_GetUID() != 0 && *(Uint16*)Data < 1024)
247 conn->LocalPort = *(Uint16*)Data;
250 case 6: // Get/Set remote port
251 if(!Data) return conn->RemotePort;
252 if(conn->State != TCP_ST_CLOSED) return -1;
253 if(!CheckMem(Data, sizeof(Uint16))) return -1;
254 conn->RemotePort = *(Uint16*)Data;
257 case 7: // Set Remote IP
258 if( conn->State != TCP_ST_CLOSED )
260 if( conn->Interface->Type == 4 )
262 if(!CheckMem(Data, sizeof(tIPv4))) return -1;
263 conn->RemoteIP.v4 = *(tIPv4*)Data;
265 else if( conn->Interface->Type == 6 )
267 if(!CheckMem(Data, sizeof(tIPv6))) return -1;
268 conn->RemoteIP.v6 = *(tIPv6*)Data;
273 if(conn->LocalPort == -1)
274 conn->LocalPort = TCP_GetUnusedPort();
275 if(conn->RemotePort == -1)
278 TCP_StartConnection(conn);
285 void TCP_Client_Close(tVFS_Node *Node)