Fixed implementation of ChRoot
[tpg/acess2.git] / Modules / IPStack / tcp.c
1 /*
2  * Acess2 IP Stack
3  * - TCP Handling
4  */
5 #include "ipstack.h"
6 #include "tcp.h"
7
8 #define TCP_MIN_DYNPORT 0x1000
9
10 // === PROTOTYPES ===
11 void    TCP_Initialise();
12 void    *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port);
13 void    TCP_GetPacket(tInterface *Interface, int Length, void *Buffer);
14 Uint16  TCP_GetUnusedPort();
15  int    TCP_AllocatePort(Uint16 Port);
16  int    TCP_DeallocatePort(Uint16 Port);
17
18 // === GLOBALS ===
19  int    giTCP_NumHalfopen = 0;
20 tTCPListener    *gTCP_Listeners;
21 tTCPConnection  *gTCP_OutbountCons;
22 Uint32  gaTCP_PortBitmap[0x800];
23  int    giTCP_NextOutPort = TCP_MIN_DYNPORT;
24
25 // === CODE ===
26 /**
27  * \fn void TCP_Initialise()
28  * \brief Initialise the TCP Layer
29  */
30 void TCP_Initialise()
31 {
32         
33 }
34
35 /**
36  * \fn void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port)
37  * \brief Open a connection to another host using TCP
38  */
39 void *TCP_Open(tInterface *Interface, Uint16 LocalPort, void *Address, Uint16 Port)
40 {
41         tTCPConnection  *ret = malloc( sizeof(tTCPConnection) );
42         
43         ret->State = TCP_ST_CLOSED;
44         if(LocalPort == 0)
45                 ret->LocalPort = TCP_GetUnusedPort();
46         else
47                 ret->LocalPort = LocalPort;
48         ret->RemotePort = Port;
49         
50         ret->LocalInterface = Interface;
51         
52         if(Interface->Type == 6)
53                 ret->RemoteIP.v6 = *(tIPv6*)Address;
54         else
55                 ret->RemoteIP.v4 = *(tIPv4*)Address;
56         
57         // SEND PACKET
58         
59         return ret;
60 }
61
62 /**
63  * \fn void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
64  * \brief Handles a packet from the IP Layer
65  */
66 void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer)
67 {
68         tTCPHeader      *hdr = Buffer;
69         tTCPListener    *srv;
70         tTCPConnection  *conn;
71         
72         // Check Servers
73         {
74                 for( srv = gTCP_Listeners; srv; srv = srv->Next )
75                 {
76                         // Check the interface
77                         if(srv->Interface && srv->Interface != Interface)       continue;
78                         // Check the destination port
79                         if(srv->Port != hdr->DestPort)  continue;
80                         
81                         // Is this in an established connection?
82                         for( conn = srv->Connections; conn; conn = conn->Next )
83                         {
84                                 // Check that it is coming in on the same interface
85                                 if(conn->Interface != Interface)        continue;
86                                 
87                                 // Check Source Port
88                                 if(conn->RemotePort != hdr->SourcePort) continue;
89                                 
90                                 // Check Source IP
91                                 if(conn->Interface->Type == 6 && !IP6_EQU(conn->RemoteIP.v6, *(tIPv6*)Address))
92                                         continue;
93                                 if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
94                                         continue;
95                                 
96                                 // We have a response!
97                                 //TODO
98                                 
99                                 return;
100                         }
101                         
102                         // Open a new connection
103                         //TODO
104                         
105                         break;
106                 }
107         }
108         
109         
110         // Check Open Connections
111         {
112                 for( conn = gTCP_OutbountCons; conn; conn = conn->Next )
113                 {
114                         // TODO
115                 }
116         }
117 }
118
119 /**
120  * \fn Uint16 TCP_GetUnusedPort()
121  * \brief Gets an unused port and allocates it
122  */
123 Uint16 TCP_GetUnusedPort()
124 {
125         Uint16  ret;
126         
127         // Get Next outbound port
128         ret = giTCP_NextOutPort++;
129         while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) )
130         {
131                 ret ++;
132                 giTCP_NextOutPort++;
133                 if(giTCP_NextOutPort == 0x10000) {
134                         ret = giTCP_NextOutPort = TCP_MIN_DYNPORT;
135                 }
136         }
137         
138         // Mark the new port as used
139         gaTCP_PortBitmap[ret/32] |= 1 << (ret%32);
140         
141         return ret;
142 }
143
144 /**
145  * \fn int TCP_AllocatePort(Uint16 Port)
146  * \brief Marks a port as used
147  */
148 int TCP_AllocatePort(Uint16 Port)
149 {
150         // Check if the port has already been allocated
151         if( gaTCP_PortBitmap[Port/32] & (1 << (Port%32)) )
152                 return 0;
153         
154         // Allocate
155         gaTCP_PortBitmap[Port/32] |= 1 << (Port%32);
156         
157         return 1;
158 }
159
160 /**
161  * \fn int TCP_DeallocatePort(Uint16 Port)
162  * \brief Marks a port as unused
163  */
164 int TCP_DeallocatePort(Uint16 Port)
165 {
166         // Check if the port has already been allocated
167         if( !(gaTCP_PortBitmap[Port/32] & (1 << (Port%32))) )
168                 return 0;
169         
170         // Allocate
171         gaTCP_PortBitmap[Port/32] &= ~(1 << (Port%32));
172         
173         return 1;
174 }
175

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