]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Main.c
1 /** @file
2
3 Copyright (c) 2005 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Tcp4Main.c
15
16 Abstract:
17
18 Implementation of TCP4 protocol services.
19
20
21 **/
22
23 #include "Tcp4Main.h"
24
25
26 /**
27 Check the integrity of the data buffer.
28
29 @param DataLen The total length of the data buffer.
30 @param FragmentCount The fragment count of the fragment table.
31 @param FragmentTable Pointer to the fragment table of the data
32 buffer.
33
34 @retval EFI_SUCCESS The integrity check is passed.
35 @retval EFI_INVALID_PARAMETER The integrity check is failed.
36
37 **/
38 EFI_STATUS
39 Tcp4ChkDataBuf (
40 IN UINT32 DataLen,
41 IN UINT32 FragmentCount,
42 IN EFI_TCP4_FRAGMENT_DATA *FragmentTable
43 )
44 {
45 UINT32 Index;
46
47 UINT32 Len;
48
49 for (Index = 0, Len = 0; Index < FragmentCount; Index++) {
50 Len = Len + (UINT32) FragmentTable[Index].FragmentLength;
51 }
52
53 if (DataLen != Len) {
54 return EFI_INVALID_PARAMETER;
55 }
56
57 return EFI_SUCCESS;
58 }
59
60
61 /**
62 Get the current operational status.
63
64 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
65 @param Tcp4State Pointer to the buffer to receive the current TCP
66 state.
67 @param Tcp4ConfigData Pointer to the buffer to receive the current TCP
68 configuration.
69 @param Ip4ModeData Pointer to the buffer to receive the current
70 IPv4 configuration.
71 @param MnpConfigData Pointer to the buffer to receive the current MNP
72 configuration data indirectly used by the TCPv4
73 Instance.
74 @param SnpModeData Pointer to the buffer to receive the current SNP
75 configuration data indirectly used by the TCPv4
76 Instance.
77
78 @retval EFI_SUCCESS The mode data was read.
79 @retval EFI_NOT_STARTED No configuration data is available because this
80 instance hasn't been started.
81 @retval EFI_INVALID_PARAMETER This is NULL.
82
83 **/
84 EFI_STATUS
85 EFIAPI
86 Tcp4GetModeData (
87 IN CONST EFI_TCP4_PROTOCOL * This,
88 OUT EFI_TCP4_CONNECTION_STATE * Tcp4State OPTIONAL,
89 OUT EFI_TCP4_CONFIG_DATA * Tcp4ConfigData OPTIONAL,
90 OUT EFI_IP4_MODE_DATA * Ip4ModeData OPTIONAL,
91 OUT EFI_MANAGED_NETWORK_CONFIG_DATA * MnpConfigData OPTIONAL,
92 OUT EFI_SIMPLE_NETWORK_MODE * SnpModeData OPTIONAL
93 )
94 {
95 TCP4_MODE_DATA TcpMode;
96 SOCKET *Sock;
97
98 if (NULL == This) {
99 return EFI_INVALID_PARAMETER;
100 }
101
102 Sock = SOCK_FROM_THIS (This);
103
104 TcpMode.Tcp4State = Tcp4State;
105 TcpMode.Tcp4ConfigData = Tcp4ConfigData;
106 TcpMode.Ip4ModeData = Ip4ModeData;
107 TcpMode.MnpConfigData = MnpConfigData;
108 TcpMode.SnpModeData = SnpModeData;
109
110 return SockGetMode (Sock, &TcpMode);
111 }
112
113
114 /**
115 Initialize or brutally reset the operational parameters for
116 this EFI TCPv4 instance.
117
118 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
119 @param TcpConfigData Pointer to the configure data to configure the
120 instance.
121
122 @retval EFI_SUCCESS The operational settings are set, changed, or
123 reset successfully.
124 @retval EFI_NO_MAPPING When using a default address, configuration
125 (through DHCP, BOOTP, RARP, etc.) is not
126 finished.
127 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
128 @retval EFI_ACCESS_DENIED Configuring TCP instance when it is already
129 configured.
130 @retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
131 @retval EFI_UNSUPPORTED One or more of the control options are not
132 supported in the implementation.
133 @retval EFI_OUT_OF_RESOURCES Could not allocate enough system resources.
134
135 **/
136 EFI_STATUS
137 EFIAPI
138 Tcp4Configure (
139 IN EFI_TCP4_PROTOCOL * This,
140 IN EFI_TCP4_CONFIG_DATA * TcpConfigData OPTIONAL
141 )
142 {
143 EFI_TCP4_OPTION *Option;
144 SOCKET *Sock;
145 EFI_STATUS Status;
146 IP4_ADDR Ip;
147 IP4_ADDR SubnetMask;
148
149 if (NULL == This) {
150 return EFI_INVALID_PARAMETER;
151 }
152
153 //
154 // Tcp protocol related parameter check will be conducted here
155 //
156 if (NULL != TcpConfigData) {
157
158 CopyMem (&Ip, &TcpConfigData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
159 if ((Ip != 0) && !Ip4IsUnicast (NTOHL (Ip), 0)) {
160 return EFI_INVALID_PARAMETER;
161 }
162
163 if (TcpConfigData->AccessPoint.ActiveFlag &&
164 (0 == TcpConfigData->AccessPoint.RemotePort || (Ip == 0))) {
165 return EFI_INVALID_PARAMETER;
166 }
167
168 if (!TcpConfigData->AccessPoint.UseDefaultAddress) {
169
170 CopyMem (&Ip, &TcpConfigData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
171 CopyMem (&SubnetMask, &TcpConfigData->AccessPoint.SubnetMask, sizeof (IP4_ADDR));
172 if (!Ip4IsUnicast (NTOHL (Ip), 0) || !IP4_IS_VALID_NETMASK (NTOHL (SubnetMask))) {
173 return EFI_INVALID_PARAMETER;
174 }
175 }
176
177 Option = TcpConfigData->ControlOption;
178 if ((NULL != Option) &&
179 (Option->EnableSelectiveAck || Option->EnablePathMtuDiscovery)) {
180 return EFI_UNSUPPORTED;
181 }
182 }
183
184 Sock = SOCK_FROM_THIS (This);
185
186 if (NULL == TcpConfigData) {
187 return SockFlush (Sock);
188 }
189
190 Status = SockConfigure (Sock, TcpConfigData);
191
192 if (EFI_NO_MAPPING == Status) {
193 Sock->ConfigureState = SO_NO_MAPPING;
194 }
195
196 return Status;
197 }
198
199
200 /**
201 Add or delete routing entries.
202
203 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
204 @param DeleteRoute If TRUE, delete the specified route from routing
205 table; if FALSE, add the specified route to
206 routing table.
207 @param SubnetAddress The destination network.
208 @param SubnetMask The subnet mask for the destination network.
209 @param GatewayAddress The gateway address for this route.
210
211 @retval EFI_SUCCESS The operation completed successfully.
212 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance has not been
213 configured.
214 @retval EFI_NO_MAPPING When using a default address, configuration
215 (through DHCP, BOOTP, RARP, etc.) is not
216 finished.
217 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
218 @retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the
219 entry to the routing table.
220 @retval EFI_NOT_FOUND This route is not in the routing table.
221 @retval EFI_ACCESS_DENIED This route is already in the routing table.
222 @retval EFI_UNSUPPORTED The TCP driver does not support this operation.
223
224 **/
225 EFI_STATUS
226 EFIAPI
227 Tcp4Routes (
228 IN EFI_TCP4_PROTOCOL *This,
229 IN BOOLEAN DeleteRoute,
230 IN EFI_IPv4_ADDRESS *SubnetAddress,
231 IN EFI_IPv4_ADDRESS *SubnetMask,
232 IN EFI_IPv4_ADDRESS *GatewayAddress
233 )
234 {
235 SOCKET *Sock;
236 TCP4_ROUTE_INFO RouteInfo;
237
238 if (NULL == This) {
239 return EFI_INVALID_PARAMETER;
240 }
241
242 Sock = SOCK_FROM_THIS (This);
243
244 RouteInfo.DeleteRoute = DeleteRoute;
245 RouteInfo.SubnetAddress = SubnetAddress;
246 RouteInfo.SubnetMask = SubnetMask;
247 RouteInfo.GatewayAddress = GatewayAddress;
248
249 return SockRoute (Sock, &RouteInfo);
250 }
251
252
253 /**
254 Initiate a nonblocking TCP connection request for an active TCP instance.
255
256 @param This Pointer to the EFI_TCP4_PROTOCOL instance
257 @param ConnectionToken Pointer to the connection token to return when
258 the TCP three way handshake finishes.
259
260 @retval EFI_SUCCESS The connection request is successfully
261 initiated.
262 @retval EFI_NOT_STARTED This EFI_TCP4_PROTOCOL instance hasn't been
263 configured.
264 @retval EFI_ACCESS_DENIED The instance is not configured as an active one
265 or it is not in Tcp4StateClosed state.
266 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
267 @retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to
268 initiate the active open.
269 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
270
271 **/
272 EFI_STATUS
273 EFIAPI
274 Tcp4Connect (
275 IN EFI_TCP4_PROTOCOL *This,
276 IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
277 )
278 {
279 SOCKET *Sock;
280
281 if (NULL == This ||
282 NULL == ConnectionToken ||
283 NULL == ConnectionToken->CompletionToken.Event) {
284 return EFI_INVALID_PARAMETER;
285 }
286
287 Sock = SOCK_FROM_THIS (This);
288
289 return SockConnect (Sock, ConnectionToken);
290 }
291
292
293 /**
294 Listen on the passive instance to accept an incoming connection request.
295
296 @param This Pointer to the EFI_TCP4_PROTOCOL instance
297 @param ListenToken Pointer to the listen token to return when
298 operation finishes.
299
300 @retval EFI_SUCCESS The listen token has been queued successfully.
301 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
302 configured.
303 @retval EFI_ACCESS_DENIED The instatnce is not a passive one or it is not
304 in Tcp4StateListen state or a same listen token
305 has already existed in the listen token queue of
306 this TCP instance.
307 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
308 @retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to finish
309 the operation.
310 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
311
312 **/
313 EFI_STATUS
314 EFIAPI
315 Tcp4Accept (
316 IN EFI_TCP4_PROTOCOL *This,
317 IN EFI_TCP4_LISTEN_TOKEN *ListenToken
318 )
319 {
320 SOCKET *Sock;
321
322 if (NULL == This ||
323 NULL == ListenToken ||
324 NULL == ListenToken->CompletionToken.Event) {
325 return EFI_INVALID_PARAMETER;
326 }
327
328 Sock = SOCK_FROM_THIS (This);
329
330 return SockAccept (Sock, ListenToken);
331 }
332
333
334 /**
335 Queues outgoing data into the transmit queue
336
337 @param This Pointer to the EFI_TCP4_PROTOCOL instance
338 @param Token Pointer to the completion token to queue to the
339 transmit queue
340
341 @retval EFI_SUCCESS The data has been queued for transmission
342 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
343 configured.
344 @retval EFI_NO_MAPPING When using a default address, configuration
345 (DHCP, BOOTP, RARP, etc.) is not finished yet.
346 @retval EFI_INVALID_PARAMETER One or more parameters are invalid
347 @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
348 * A transmit completion token with the same
349 Token-> CompletionToken.Event was already in the
350 transmission queue. * The current instance is in
351 Tcp4StateClosed state * The current instance is
352 a passive one and it is in Tcp4StateListen
353 state. * User has called Close() to disconnect
354 this connection.
355 @retval EFI_NOT_READY The completion token could not be queued because
356 the transmit queue is full.
357 @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of
358 resource shortage.
359 @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or
360 address.
361
362 **/
363 EFI_STATUS
364 EFIAPI
365 Tcp4Transmit (
366 IN EFI_TCP4_PROTOCOL *This,
367 IN EFI_TCP4_IO_TOKEN *Token
368 )
369 {
370 SOCKET *Sock;
371 EFI_STATUS Status;
372
373 if (NULL == This ||
374 NULL == Token ||
375 NULL == Token->CompletionToken.Event ||
376 NULL == Token->Packet.TxData ||
377 0 == Token->Packet.TxData->FragmentCount ||
378 0 == Token->Packet.TxData->DataLength
379 ) {
380 return EFI_INVALID_PARAMETER;
381 }
382
383 Status = Tcp4ChkDataBuf (
384 (UINT32) Token->Packet.TxData->DataLength,
385 (UINT32) Token->Packet.TxData->FragmentCount,
386 Token->Packet.TxData->FragmentTable
387 );
388 if (EFI_ERROR (Status)) {
389 return Status;
390 }
391
392 Sock = SOCK_FROM_THIS (This);
393
394 return SockSend (Sock, Token);
395
396 }
397
398
399 /**
400 Place an asynchronous receive request into the receiving queue.
401
402 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
403 @param Token Pointer to a token that is associated with the
404 receive data descriptor.
405
406 @retval EFI_SUCCESS The receive completion token was cached
407 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
408 configured.
409 @retval EFI_NO_MAPPING When using a default address, configuration
410 (DHCP, BOOTP, RARP, etc.) is not finished yet.
411 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
412 @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
413 due to a lack of system resources.
414 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
415 @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
416 * A receive completion token with the same
417 Token->CompletionToken.Event was already in the
418 receive queue. * The current instance is in
419 Tcp4StateClosed state. * The current instance is
420 a passive one and it is in Tcp4StateListen
421 state. * User has called Close() to disconnect
422 this connection.
423 @retval EFI_CONNECTION_FIN The communication peer has closed the connection
424 and there is no any buffered data in the receive
425 buffer of this instance.
426 @retval EFI_NOT_READY The receive request could not be queued because
427 the receive queue is full.
428
429 **/
430 EFI_STATUS
431 EFIAPI
432 Tcp4Receive (
433 IN EFI_TCP4_PROTOCOL *This,
434 IN EFI_TCP4_IO_TOKEN *Token
435 )
436 {
437 SOCKET *Sock;
438 EFI_STATUS Status;
439
440 if (NULL == This ||
441 NULL == Token ||
442 NULL == Token->CompletionToken.Event ||
443 NULL == Token->Packet.RxData ||
444 0 == Token->Packet.RxData->FragmentCount ||
445 0 == Token->Packet.RxData->DataLength
446 ) {
447 return EFI_INVALID_PARAMETER;
448 }
449
450 Status = Tcp4ChkDataBuf (
451 (UINT32) Token->Packet.RxData->DataLength,
452 (UINT32) Token->Packet.RxData->FragmentCount,
453 Token->Packet.RxData->FragmentTable
454 );
455 if (EFI_ERROR (Status)) {
456 return Status;
457 }
458
459 Sock = SOCK_FROM_THIS (This);
460
461 return SockRcv (Sock, Token);
462
463 }
464
465
466 /**
467 Disconnecting a TCP connection gracefully or reset a TCP connection.
468
469 @param This Pointer to the EFI_TCP4_PROTOCOL instance
470 @param CloseToken Pointer to the close token to return when
471 operation finishes.
472
473 @retval EFI_SUCCESS The operation completed successfully
474 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
475 configured.
476 @retval EFI_ACCESS_DENIED One or more of the following are TRUE: *
477 Configure() has been called with TcpConfigData
478 set to NULL and this function has not returned.
479 * Previous Close() call on this instance has not
480 finished.
481 @retval EFI_INVALID_PARAMETER One ore more parameters are invalid
482 @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the
483 operation
484 @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above
485 category error.
486
487 **/
488 EFI_STATUS
489 EFIAPI
490 Tcp4Close (
491 IN EFI_TCP4_PROTOCOL *This,
492 IN EFI_TCP4_CLOSE_TOKEN *CloseToken
493 )
494 {
495 SOCKET *Sock;
496
497 if (NULL == This ||
498 NULL == CloseToken ||
499 NULL == CloseToken->CompletionToken.Event) {
500 return EFI_INVALID_PARAMETER;
501 }
502
503 Sock = SOCK_FROM_THIS (This);
504
505 return SockClose (Sock, CloseToken, CloseToken->AbortOnClose);
506 }
507
508
509 /**
510 Abort an asynchronous connection, listen, transmission or receive request.
511
512 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
513 @param Token Pointer to a token that has been issued by
514 Connect(), Accept(), Transmit() or Receive(). If
515 NULL, all pending tokens issued by above four
516 functions will be aborted.
517
518 @retval EFI_UNSUPPORTED The operation is not supported in current
519 implementation.
520
521 **/
522 EFI_STATUS
523 EFIAPI
524 Tcp4Cancel (
525 IN EFI_TCP4_PROTOCOL * This,
526 IN EFI_TCP4_COMPLETION_TOKEN * Token OPTIONAL
527 )
528 {
529 return EFI_UNSUPPORTED;
530 }
531
532
533 /**
534 Poll to receive incoming data and transmit outgoing segments.
535
536 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
537
538 @retval EFI_SUCCESS Incoming or outgoing data was processed.
539 @retval EFI_INVALID_PARAMETER This is NULL.
540 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
541 @retval EFI_NOT_READY No incoming or outgoing data was processed.
542 @retval EFI_TIMEOUT Data was dropped out of the transmission or
543 receive queue. Consider increasing the polling
544 rate.
545
546 **/
547 EFI_STATUS
548 EFIAPI
549 Tcp4Poll (
550 IN EFI_TCP4_PROTOCOL *This
551 )
552 {
553 SOCKET *Sock;
554 EFI_STATUS Status;
555
556 if (NULL == This) {
557 return EFI_INVALID_PARAMETER;
558 }
559
560 Sock = SOCK_FROM_THIS (This);
561
562 Status = Sock->ProtoHandler (Sock, SOCK_POLL, NULL);
563
564 return Status;
565 }