]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/TcpDxe/TcpIo.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / NetworkPkg / TcpDxe / TcpIo.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 Implementation of I/O interfaces between TCP and IpIoLib.\r
3\r
9119637c 4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
a3bcde70
HT
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "TcpMain.h"\r
17\r
18/**\r
19 Packet receive callback function provided to IP_IO, used to call\r
20 the proper function to handle the packet received by IP.\r
21\r
22 @param[in] Status Result of the receive request.\r
23 @param[in] IcmpErr Valid when Status is EFI_ICMP_ERROR.\r
24 @param[in] NetSession The IP session for the received packet.\r
25 @param[in] Pkt Packet received.\r
26 @param[in] Context The data provided by the user for the received packet when\r
27 the callback is registered in IP_IO_OPEN_DATA::RcvdContext.\r
28 This is an optional parameter that may be NULL.\r
29\r
30**/\r
31VOID\r
32EFIAPI\r
33TcpRxCallback (\r
34 IN EFI_STATUS Status,\r
35 IN UINT8 IcmpErr,\r
36 IN EFI_NET_SESSION_DATA *NetSession,\r
37 IN NET_BUF *Pkt,\r
38 IN VOID *Context OPTIONAL\r
39 )\r
40{\r
41 if (EFI_SUCCESS == Status) {\r
42 TcpInput (Pkt, &NetSession->Source, &NetSession->Dest, NetSession->IpVersion);\r
43 } else {\r
44 TcpIcmpInput (\r
45 Pkt,\r
46 IcmpErr,\r
47 &NetSession->Source,\r
48 &NetSession->Dest,\r
49 NetSession->IpVersion\r
50 );\r
51 }\r
52}\r
53\r
54/**\r
55 Send the segment to IP via IpIo function.\r
56\r
57 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r
58 @param[in] Nbuf Pointer to the TCP segment to be sent.\r
59 @param[in] Src Source address of the TCP segment.\r
60 @param[in] Dest Destination address of the TCP segment.\r
61 @param[in] Version IP_VERSION_4 or IP_VERSION_6\r
62\r
63 @retval 0 The segment was sent out successfully.\r
64 @retval -1 The segment failed to send.\r
65\r
66**/\r
67INTN\r
68TcpSendIpPacket (\r
69 IN TCP_CB *Tcb,\r
70 IN NET_BUF *Nbuf,\r
71 IN EFI_IP_ADDRESS *Src,\r
72 IN EFI_IP_ADDRESS *Dest,\r
73 IN UINT8 Version\r
74 )\r
75{\r
76 EFI_STATUS Status;\r
77 IP_IO *IpIo;\r
78 IP_IO_OVERRIDE Override;\r
79 SOCKET *Sock;\r
80 VOID *IpSender;\r
81 TCP_PROTO_DATA *TcpProto;\r
82\r
83 if (NULL == Tcb) {\r
84\r
85 IpIo = NULL;\r
86 IpSender = IpIoFindSender (&IpIo, Version, Src);\r
87\r
88 if (IpSender == NULL) {\r
89 DEBUG ((EFI_D_WARN, "TcpSendIpPacket: No appropriate IpSender.\n"));\r
90 return -1;\r
91 }\r
92\r
93 if (Version == IP_VERSION_6) {\r
94 //\r
95 // It's tricky here. EFI IPv6 Spec don't allow an instance overriding the\r
96 // destination address if the dest is already specified through the\r
97 // configuration data. Here we get the IpIo we need and use the default IP\r
98 // instance in this IpIo to send the packet. The dest address is configured\r
99 // to be the unspecified address for the default IP instance.\r
100 //\r
101 IpSender = NULL;\r
102 }\r
103 } else {\r
104\r
105 Sock = Tcb->Sk;\r
106 TcpProto = (TCP_PROTO_DATA *) Sock->ProtoReserved;\r
107 IpIo = TcpProto->TcpService->IpIo;\r
108 IpSender = Tcb->IpInfo;\r
109\r
110 if (Version == IP_VERSION_6) {\r
111 //\r
112 // It's IPv6 and this TCP segment belongs to a solid TCB, in such case\r
113 // the destination address can't be overridden, so reset the Dest to NULL.\r
114 //\r
9119637c 115 if (!Tcb->RemoteIpZero) {\r
116 Dest = NULL;\r
117 }\r
a3bcde70
HT
118 }\r
119 }\r
120\r
121 ASSERT (Version == IpIo->IpVersion);\r
122\r
123 if (Version == IP_VERSION_4) {\r
124 Override.Ip4OverrideData.TypeOfService = 0;\r
125 Override.Ip4OverrideData.TimeToLive = 255;\r
126 Override.Ip4OverrideData.DoNotFragment = FALSE;\r
127 Override.Ip4OverrideData.Protocol = EFI_IP_PROTO_TCP;\r
128 ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
129 CopyMem (&Override.Ip4OverrideData.SourceAddress, Src, sizeof (EFI_IPv4_ADDRESS));\r
130 } else {\r
131 Override.Ip6OverrideData.Protocol = EFI_IP_PROTO_TCP;\r
132 Override.Ip6OverrideData.HopLimit = 255;\r
133 Override.Ip6OverrideData.FlowLabel = 0;\r
134 }\r
135\r
136 Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, Dest, &Override);\r
137\r
138 if (EFI_ERROR (Status)) {\r
139 DEBUG ((EFI_D_ERROR, "TcpSendIpPacket: return %r error\n", Status));\r
140 return -1;\r
141 }\r
142\r
143 return 0;\r
144}\r
145\r
146/**\r
147 Refresh the remote peer's Neighbor Cache State if already exists.\r
148\r
149 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.\r
150 @param[in] Neighbor Source address of the TCP segment.\r
151 @param[in] Timeout Time in 100-ns units that this entry will remain\r
152 in the neighbor cache. A value of zero means that\r
153 the entry is permanent. A value of non-zero means\r
154 that the entry is dynamic and will be deleted\r
155 after Timeout.\r
156\r
157 @retval EFI_SUCCESS Successfully updated the neighbor relationship.\r
158 @retval EFI_NOT_STARTED The IpIo is not configured.\r
159 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
160 @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.\r
161 @retval EFI_NOT_FOUND This entry is not in the neighbor table.\r
162\r
163**/\r
164EFI_STATUS\r
165Tcp6RefreshNeighbor (\r
166 IN TCP_CB *Tcb,\r
167 IN EFI_IP_ADDRESS *Neighbor,\r
168 IN UINT32 Timeout\r
169 )\r
170{\r
171 IP_IO *IpIo;\r
172 SOCKET *Sock;\r
173 TCP_PROTO_DATA *TcpProto;\r
174\r
175 if (NULL == Tcb) {\r
176 IpIo = NULL;\r
177 IpIoFindSender (&IpIo, IP_VERSION_6, Neighbor);\r
178\r
179 if (IpIo == NULL) {\r
180 DEBUG ((EFI_D_WARN, "Tcp6AddNeighbor: No appropriate IpIo.\n"));\r
181 return EFI_NOT_STARTED;\r
182 }\r
183\r
184 } else {\r
185 Sock = Tcb->Sk;\r
186 TcpProto = (TCP_PROTO_DATA *) Sock->ProtoReserved;\r
187 IpIo = TcpProto->TcpService->IpIo;\r
188 }\r
189\r
190 return IpIoRefreshNeighbor (IpIo, Neighbor, Timeout);\r
191}\r
192\r