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