]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Main.c
Import ArpDxe, Dhcp4Dxe, Ip4Dxe, Mtftp4Dxe, PxeBcDxe and PxeDhcp4Dxe.
[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
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 NetCopyMem (&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 NetCopyMem (&Ip, &TcpConfigData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
171 if (!Ip4IsUnicast (NTOHL (Ip), 0) || !IP4_IS_VALID_NETMASK (NTOHL (Ip))) {
172 return EFI_INVALID_PARAMETER;
173 }
174 }
175
176 Option = TcpConfigData->ControlOption;
177 if ((NULL != Option) &&
178 (Option->EnableSelectiveAck || Option->EnablePathMtuDiscovery)) {
179 return EFI_UNSUPPORTED;
180 }
181 }
182
183 Sock = SOCK_FROM_THIS (This);
184
185 if (NULL == TcpConfigData) {
186 return SockFlush (Sock);
187 }
188
189 Status = SockConfigure (Sock, TcpConfigData);
190
191 if (EFI_NO_MAPPING == Status) {
192 Sock->ConfigureState = SO_NO_MAPPING;
193 }
194
195 return Status;
196 }
197
198
199 /**
200 Add or delete routing entries.
201
202 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
203 @param DeleteRoute If TRUE, delete the specified route from routing
204 table; if FALSE, add the specified route to
205 routing table.
206 @param SubnetAddress The destination network.
207 @param SubnetMask The subnet mask for the destination network.
208 @param GatewayAddress The gateway address for this route.
209
210 @retval EFI_SUCCESS The operation completed successfully.
211 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance has not been
212 configured.
213 @retval EFI_NO_MAPPING When using a default address, configuration
214 (through DHCP, BOOTP, RARP, etc.) is not
215 finished.
216 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
217 @retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to add the
218 entry to the routing table.
219 @retval EFI_NOT_FOUND This route is not in the routing table.
220 @retval EFI_ACCESS_DENIED This route is already in the routing table.
221 @retval EFI_UNSUPPORTED The TCP driver does not support this operation.
222
223 **/
224 EFI_STATUS
225 EFIAPI
226 Tcp4Routes (
227 IN EFI_TCP4_PROTOCOL *This,
228 IN BOOLEAN DeleteRoute,
229 IN EFI_IPv4_ADDRESS *SubnetAddress,
230 IN EFI_IPv4_ADDRESS *SubnetMask,
231 IN EFI_IPv4_ADDRESS *GatewayAddress
232 )
233 {
234 SOCKET *Sock;
235 TCP4_ROUTE_INFO RouteInfo;
236
237 if (NULL == This) {
238 return EFI_INVALID_PARAMETER;
239 }
240
241 Sock = SOCK_FROM_THIS (This);
242
243 RouteInfo.DeleteRoute = DeleteRoute;
244 RouteInfo.SubnetAddress = SubnetAddress;
245 RouteInfo.SubnetMask = SubnetMask;
246 RouteInfo.GatewayAddress = GatewayAddress;
247
248 return SockRoute (Sock, &RouteInfo);
249 }
250
251
252 /**
253 Initiate a nonblocking TCP connection request for an active TCP instance.
254
255 @param This Pointer to the EFI_TCP4_PROTOCOL instance
256 @param ConnectionToken Pointer to the connection token to return when
257 the TCP three way handshake finishes.
258
259 @retval EFI_SUCCESS The connection request is successfully
260 initiated.
261 @retval EFI_NOT_STARTED This EFI_TCP4_PROTOCOL instance hasn't been
262 configured.
263 @retval EFI_ACCESS_DENIED The instance is not configured as an active one
264 or it is not in Tcp4StateClosed state.
265 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
266 @retval EFI_OUT_OF_RESOURCES The driver can't allocate enough resource to
267 initiate the active open.
268 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
269
270 **/
271 EFI_STATUS
272 EFIAPI
273 Tcp4Connect (
274 IN EFI_TCP4_PROTOCOL *This,
275 IN EFI_TCP4_CONNECTION_TOKEN *ConnectionToken
276 )
277 {
278 SOCKET *Sock;
279
280 if (NULL == This ||
281 NULL == ConnectionToken ||
282 NULL == ConnectionToken->CompletionToken.Event) {
283 return EFI_INVALID_PARAMETER;
284 }
285
286 Sock = SOCK_FROM_THIS (This);
287
288 return SockConnect (Sock, ConnectionToken);
289 }
290
291
292 /**
293 Listen on the passive instance to accept an incoming connection request.
294
295 @param This Pointer to the EFI_TCP4_PROTOCOL instance
296 @param ListenToken Pointer to the listen token to return when
297 operation finishes.
298
299 @retval EFI_SUCCESS The listen token has been queued successfully.
300 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
301 configured.
302 @retval EFI_ACCESS_DENIED The instatnce is not a passive one or it is not
303 in Tcp4StateListen state or a same listen token
304 has already existed in the listen token queue of
305 this TCP instance.
306 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
307 @retval EFI_OUT_OF_RESOURCES Could not allocate enough resources to finish
308 the operation.
309 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
310
311 **/
312 EFI_STATUS
313 EFIAPI
314 Tcp4Accept (
315 IN EFI_TCP4_PROTOCOL *This,
316 IN EFI_TCP4_LISTEN_TOKEN *ListenToken
317 )
318 {
319 SOCKET *Sock;
320
321 if (NULL == This ||
322 NULL == ListenToken ||
323 NULL == ListenToken->CompletionToken.Event) {
324 return EFI_INVALID_PARAMETER;
325 }
326
327 Sock = SOCK_FROM_THIS (This);
328
329 return SockAccept (Sock, ListenToken);
330 }
331
332
333 /**
334 Queues outgoing data into the transmit queue
335
336 @param This Pointer to the EFI_TCP4_PROTOCOL instance
337 @param Token Pointer to the completion token to queue to the
338 transmit queue
339
340 @retval EFI_SUCCESS The data has been queued for transmission
341 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
342 configured.
343 @retval EFI_NO_MAPPING When using a default address, configuration
344 (DHCP, BOOTP, RARP, etc.) is not finished yet.
345 @retval EFI_INVALID_PARAMETER One or more parameters are invalid
346 @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
347 * A transmit completion token with the same
348 Token-> CompletionToken.Event was already in the
349 transmission queue. * The current instance is in
350 Tcp4StateClosed state * The current instance is
351 a passive one and it is in Tcp4StateListen
352 state. * User has called Close() to disconnect
353 this connection.
354 @retval EFI_NOT_READY The completion token could not be queued because
355 the transmit queue is full.
356 @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data because of
357 resource shortage.
358 @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or
359 address.
360
361 **/
362 EFI_STATUS
363 EFIAPI
364 Tcp4Transmit (
365 IN EFI_TCP4_PROTOCOL *This,
366 IN EFI_TCP4_IO_TOKEN *Token
367 )
368 {
369 SOCKET *Sock;
370 EFI_STATUS Status;
371
372 if (NULL == This ||
373 NULL == Token ||
374 NULL == Token->CompletionToken.Event ||
375 NULL == Token->Packet.TxData ||
376 0 == Token->Packet.TxData->FragmentCount ||
377 0 == Token->Packet.TxData->DataLength
378 ) {
379 return EFI_INVALID_PARAMETER;
380 }
381
382 Status = Tcp4ChkDataBuf (
383 (UINT32) Token->Packet.TxData->DataLength,
384 (UINT32) Token->Packet.TxData->FragmentCount,
385 Token->Packet.TxData->FragmentTable
386 );
387 if (EFI_ERROR (Status)) {
388 return Status;
389 }
390
391 Sock = SOCK_FROM_THIS (This);
392
393 return SockSend (Sock, Token);
394
395 }
396
397
398 /**
399 Place an asynchronous receive request into the receiving queue.
400
401 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
402 @param Token Pointer to a token that is associated with the
403 receive data descriptor.
404
405 @retval EFI_SUCCESS The receive completion token was cached
406 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
407 configured.
408 @retval EFI_NO_MAPPING When using a default address, configuration
409 (DHCP, BOOTP, RARP, etc.) is not finished yet.
410 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
411 @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued
412 due to a lack of system resources.
413 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
414 @retval EFI_ACCESS_DENIED One or more of the following conditions is TRUE:
415 * A receive completion token with the same
416 Token->CompletionToken.Event was already in the
417 receive queue. * The current instance is in
418 Tcp4StateClosed state. * The current instance is
419 a passive one and it is in Tcp4StateListen
420 state. * User has called Close() to disconnect
421 this connection.
422 @retval EFI_CONNECTION_FIN The communication peer has closed the connection
423 and there is no any buffered data in the receive
424 buffer of this instance.
425 @retval EFI_NOT_READY The receive request could not be queued because
426 the receive queue is full.
427
428 **/
429 EFI_STATUS
430 EFIAPI
431 Tcp4Receive (
432 IN EFI_TCP4_PROTOCOL *This,
433 IN EFI_TCP4_IO_TOKEN *Token
434 )
435 {
436 SOCKET *Sock;
437 EFI_STATUS Status;
438
439 if (NULL == This ||
440 NULL == Token ||
441 NULL == Token->CompletionToken.Event ||
442 NULL == Token->Packet.RxData ||
443 0 == Token->Packet.RxData->FragmentCount ||
444 0 == Token->Packet.RxData->DataLength
445 ) {
446 return EFI_INVALID_PARAMETER;
447 }
448
449 Status = Tcp4ChkDataBuf (
450 (UINT32) Token->Packet.RxData->DataLength,
451 (UINT32) Token->Packet.RxData->FragmentCount,
452 Token->Packet.RxData->FragmentTable
453 );
454 if (EFI_ERROR (Status)) {
455 return Status;
456 }
457
458 Sock = SOCK_FROM_THIS (This);
459
460 return SockRcv (Sock, Token);
461
462 }
463
464
465 /**
466 Disconnecting a TCP connection gracefully or reset a TCP connection.
467
468 @param This Pointer to the EFI_TCP4_PROTOCOL instance
469 @param CloseToken Pointer to the close token to return when
470 operation finishes.
471
472 @retval EFI_SUCCESS The operation completed successfully
473 @retval EFI_NOT_STARTED The EFI_TCP4_PROTOCOL instance hasn't been
474 configured.
475 @retval EFI_ACCESS_DENIED One or more of the following are TRUE: *
476 Configure() has been called with TcpConfigData
477 set to NULL and this function has not returned.
478 * Previous Close() call on this instance has not
479 finished.
480 @retval EFI_INVALID_PARAMETER One ore more parameters are invalid
481 @retval EFI_OUT_OF_RESOURCES Could not allocate enough resource to finish the
482 operation
483 @retval EFI_DEVICE_ERROR Any unexpected and not belonged to above
484 category error.
485
486 **/
487 EFI_STATUS
488 EFIAPI
489 Tcp4Close (
490 IN EFI_TCP4_PROTOCOL *This,
491 IN EFI_TCP4_CLOSE_TOKEN *CloseToken
492 )
493 {
494 SOCKET *Sock;
495
496 if (NULL == This ||
497 NULL == CloseToken ||
498 NULL == CloseToken->CompletionToken.Event) {
499 return EFI_INVALID_PARAMETER;
500 }
501
502 Sock = SOCK_FROM_THIS (This);
503
504 return SockClose (Sock, CloseToken, CloseToken->AbortOnClose);
505 }
506
507
508 /**
509 Abort an asynchronous connection, listen, transmission or receive request.
510
511 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
512 @param Token Pointer to a token that has been issued by
513 Connect(), Accept(), Transmit() or Receive(). If
514 NULL, all pending tokens issued by above four
515 functions will be aborted.
516
517 @retval EFI_UNSUPPORTED The operation is not supported in current
518 implementation.
519
520 **/
521 EFI_STATUS
522 EFIAPI
523 Tcp4Cancel (
524 IN EFI_TCP4_PROTOCOL * This,
525 IN EFI_TCP4_COMPLETION_TOKEN * Token OPTIONAL
526 )
527 {
528 return EFI_UNSUPPORTED;
529 }
530
531
532 /**
533 Poll to receive incoming data and transmit outgoing segments.
534
535 @param This Pointer to the EFI_TCP4_PROTOCOL instance.
536
537 @retval EFI_SUCCESS Incoming or outgoing data was processed.
538 @retval EFI_INVALID_PARAMETER This is NULL.
539 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
540 @retval EFI_NOT_READY No incoming or outgoing data was processed.
541 @retval EFI_TIMEOUT Data was dropped out of the transmission or
542 receive queue. Consider increasing the polling
543 rate.
544
545 **/
546 EFI_STATUS
547 EFIAPI
548 Tcp4Poll (
549 IN EFI_TCP4_PROTOCOL *This
550 )
551 {
552 SOCKET *Sock;
553 EFI_STATUS Status;
554
555 if (NULL == This) {
556 return EFI_INVALID_PARAMETER;
557 }
558
559 Sock = SOCK_FROM_THIS (This);
560
561 Status = Sock->ProtoHandler (Sock, SOCK_POLL, NULL);
562
563 return Status;
564 }