9 #define TCP_MIN_DYNPORT 0x1000
10 #define TCP_MAX_HALFOPEN 1024 // Should be enough
13 void TCP_Initialise();
14 void TCP_StartConnection(tTCPConnection *Conn);
15 void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
16 void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header);
17 Uint16 TCP_GetUnusedPort();
18 int TCP_AllocatePort(Uint16 Port);
19 int TCP_DeallocatePort(Uint16 Port);
21 tVFS_Node *TCP_Server_Init(tInterface *Interface);
22 char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos);
23 tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name);
24 int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data);
25 void TCP_Server_Close(tVFS_Node *Node);
27 tVFS_Node *TCP_Client_Init(tInterface *Interface);
28 Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
29 Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
30 int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data);
31 void TCP_Client_Close(tVFS_Node *Node);
34 tSocketFile gTCP_ServerFile = {NULL, "tcps", TCP_Server_Init};
35 tSocketFile gTCP_ClientFile = {NULL, "tcpc", TCP_Client_Init};
38 int giTCP_NumHalfopen = 0;
39 tSpinlock glTCP_Listeners;
40 tTCPListener *gTCP_Listeners;
41 tSpinlock glTCP_OutbountCons;
42 tTCPConnection *gTCP_OutbountCons;
43 Uint32 gaTCP_PortBitmap[0x800];
44 int giTCP_NextOutPort = TCP_MIN_DYNPORT;
48 * \fn void TCP_Initialise()
49 * \brief Initialise the TCP Layer
53 IPStack_AddFile(&gTCP_ServerFile);
54 IPStack_AddFile(&gTCP_ClientFile);
55 IPv4_RegisterCallback(IP4PROT_TCP, TCP_GetPacket);
59 * \brief Open a connection to another host using TCP
61 void TCP_StartConnection(tTCPConnection *Conn)
64 // Send a TCP SYN to the target to open the connection
69 * \fn void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
70 * \brief Handles a packet from the IP Layer
72 void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
74 tTCPHeader *hdr = Buffer;
78 Log("[TCP ] sizeof(tTCPHeader) = %i", sizeof(tTCPHeader));
79 Log("[TCP ] DestPort = %i", ntohs(hdr->DestPort));
80 Log("[TCP ] DestPort = %i", ntohs(hdr->DestPort));
81 Log("[TCP ] SequenceNumber = %i", ntohl(hdr->SequenceNumber));
82 Log("[TCP ] AcknowlegementNumber = %i", ntohl(hdr->AcknowlegementNumber));
83 Log("[TCP ] DataOffset = %i", hdr->DataOffset >> 4);
84 Log("[TCP ] Flags = {");
85 Log("[TCP ] CWR = %B", !!(hdr->Flags & TCP_FLAG_CWR));
86 Log("[TCP ] ECE = %B", !!(hdr->Flags & TCP_FLAG_ECE));
87 Log("[TCP ] URG = %B", !!(hdr->Flags & TCP_FLAG_URG));
88 Log("[TCP ] ACK = %B", !!(hdr->Flags & TCP_FLAG_ACK));
89 Log("[TCP ] PSH = %B", !!(hdr->Flags & TCP_FLAG_PSH));
90 Log("[TCP ] RST = %B", !!(hdr->Flags & TCP_FLAG_RST));
91 Log("[TCP ] SYN = %B", !!(hdr->Flags & TCP_FLAG_SYN));
92 Log("[TCP ] FIN = %B", !!(hdr->Flags & TCP_FLAG_FIN));
94 Log("[TCP ] WindowSize = %i", htons(hdr->WindowSize));
95 Log("[TCP ] Checksum = 0x%x", htons(hdr->Checksum));
96 Log("[TCP ] UrgentPointer = 0x%x", htons(hdr->UrgentPointer));
100 for( srv = gTCP_Listeners; srv; srv = srv->Next )
102 // Check the interface
103 if(srv->Interface && srv->Interface != Interface) continue;
104 // Check the destination port
105 if(srv->Port != hdr->DestPort) continue;
107 // Is this in an established connection?
108 for( conn = srv->Connections; conn; conn = conn->Next )
110 // Check that it is coming in on the same interface
111 if(conn->Interface != Interface) continue;
114 if(conn->RemotePort != hdr->SourcePort) continue;
117 if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
119 if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
122 // We have a response!
123 TCP_INT_HandleConnectionPacket(conn, hdr)
128 // Open a new connection (well, check that it's a SYN)
136 // Check Open Connections
138 for( conn = gTCP_OutbountCons; conn; conn = conn->Next )
140 // Check that it is coming in on the same interface
141 if(conn->Interface != Interface) continue;
144 if(conn->RemotePort != hdr->SourcePort) continue;
147 if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
149 if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
152 TCP_INT_HandleConnectionPacket(conn, hdr)
158 * \brief Handles a packet sent to a specific connection
160 void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header)
166 * \fn Uint16 TCP_GetUnusedPort()
167 * \brief Gets an unused port and allocates it
169 Uint16 TCP_GetUnusedPort()
173 // Get Next outbound port
174 ret = giTCP_NextOutPort++;
175 while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) )
179 if(giTCP_NextOutPort == 0x10000) {
180 ret = giTCP_NextOutPort = TCP_MIN_DYNPORT;
184 // Mark the new port as used
185 gaTCP_PortBitmap[ret/32] |= 1 << (ret%32);
191 * \fn int TCP_AllocatePort(Uint16 Port)
192 * \brief Marks a port as used
194 int TCP_AllocatePort(Uint16 Port)
196 // Check if the port has already been allocated
197 if( gaTCP_PortBitmap[Port/32] & (1 << (Port%32)) )
201 gaTCP_PortBitmap[Port/32] |= 1 << (Port%32);
207 * \fn int TCP_DeallocatePort(Uint16 Port)
208 * \brief Marks a port as unused
210 int TCP_DeallocatePort(Uint16 Port)
212 // Check if the port has already been allocated
213 if( !(gaTCP_PortBitmap[Port/32] & (1 << (Port%32))) )
217 gaTCP_PortBitmap[Port/32] &= ~(1 << (Port%32));
223 tVFS_Node *TCP_Server_Init(tInterface *Interface)
225 tTCPListener *srv = malloc( sizeof(tTCPListener) );
227 srv->Interface = Interface;
229 srv->Connections = NULL;
231 srv->Node.ImplPtr = srv;
232 srv->Node.NumACLs = 1;
233 srv->Node.ACLs = &gVFS_ACL_EveryoneRW;
234 srv->Node.ReadDir = TCP_Server_ReadDir;
235 srv->Node.FindDir = TCP_Server_FindDir;
236 srv->Node.IOCtl = TCP_Server_IOCtl;
237 srv->Node.Close = TCP_Server_Close;
239 LOCK(&glTCP_Listeners);
240 srv->Next = gTCP_Listeners;
241 gTCP_Listeners = srv;
242 RELEASE(&glTCP_Listeners);
247 char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
252 tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, char *Name)
257 int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data)
259 tTCPListener *srv = Node->ImplPtr;
263 case 4: // Get/Set Port
270 if(!CheckMem(Data, sizeof(Uint16)))
273 if(Threads_GetUID() != 0 && *(Uint16*)Data < 1024)
276 srv->Port = *(Uint16*)Data;
278 srv->Port = TCP_GetUnusedPort();
280 TCP_AllocatePort(srv->Port);
286 void TCP_Server_Close(tVFS_Node *Node)
292 tVFS_Node *TCP_Client_Init(tInterface *Interface)
294 tTCPConnection *conn = malloc( sizeof(tTCPConnection) );
296 conn->State = TCP_ST_CLOSED;
297 conn->Interface = Interface;
299 conn->RemotePort = 0;
300 memset( &conn->RemoteIP, 0, sizeof(conn->RemoteIP) );
302 conn->Node.ImplPtr = conn;
303 conn->Node.NumACLs = 1;
304 conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
305 conn->Node.Read = TCP_Client_Read;
306 conn->Node.Write = TCP_Client_Write;
307 conn->Node.IOCtl = TCP_Client_IOCtl;
308 conn->Node.Close = TCP_Client_Close;
310 LOCK(&glTCP_OutbountCons);
311 conn->Next = gTCP_OutbountCons;
312 gTCP_OutbountCons = conn;
313 RELEASE(&glTCP_OutbountCons);
318 Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
323 Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
328 int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
330 tTCPConnection *conn = Node->ImplPtr;
334 case 4: // Get/Set local port
336 return conn->LocalPort;
337 if(conn->State != TCP_ST_CLOSED)
339 if(!CheckMem(Data, sizeof(Uint16)))
342 if(Threads_GetUID() != 0 && *(Uint16*)Data < 1024)
345 conn->LocalPort = *(Uint16*)Data;
348 case 5: // Get/Set remote port
349 if(!Data) return conn->RemotePort;
350 if(conn->State != TCP_ST_CLOSED) return -1;
351 if(!CheckMem(Data, sizeof(Uint16))) return -1;
352 conn->RemotePort = *(Uint16*)Data;
355 case 6: // Set Remote IP
356 if( conn->State != TCP_ST_CLOSED )
358 if( conn->Interface->Type == 4 )
360 if(!CheckMem(Data, sizeof(tIPv4))) return -1;
361 conn->RemoteIP.v4 = *(tIPv4*)Data;
363 else if( conn->Interface->Type == 6 )
365 if(!CheckMem(Data, sizeof(tIPv6))) return -1;
366 conn->RemoteIP.v6 = *(tIPv6*)Data;
371 if(conn->LocalPort == -1)
372 conn->LocalPort = TCP_GetUnusedPort();
373 if(conn->RemotePort == -1)
376 TCP_StartConnection(conn);
383 void TCP_Client_Close(tVFS_Node *Node)