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