]>
Commit | Line | Data |
---|---|---|
4684b66f | 1 | /** @file\r |
2 | Data source for network testing.\r | |
3 | \r | |
9f7f5161 | 4 | Copyright (c) 2011-2012, Intel Corporation\r |
4684b66f | 5 | All rights reserved. This program and the accompanying materials\r |
6 | are licensed and made available under the terms and conditions of the BSD License\r | |
7 | which accompanies this distribution. The full text of the license may be found at\r | |
8 | http://opensource.org/licenses/bsd-license.php\r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
12 | \r | |
13 | **/\r | |
14 | \r | |
15 | #include <errno.h>\r | |
16 | #include <Uefi.h>\r | |
17 | \r | |
18 | #include <Library/BaseMemoryLib.h>\r | |
19 | #include <Library/DebugLib.h>\r | |
20 | #include <Library/PcdLib.h>\r | |
21 | #include <Library/UefiBootServicesTableLib.h>\r | |
22 | #include <Library/UefiLib.h>\r | |
23 | \r | |
24 | #include <netinet/in.h>\r | |
25 | \r | |
26 | #include <sys/EfiSysCall.h>\r | |
27 | #include <sys/poll.h>\r | |
28 | #include <sys/socket.h>\r | |
29 | \r | |
30 | \r | |
f6e5cdd5 | 31 | #define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples\r |
32 | #define MAX_CONNECTIONS ( 1 + 16 ) ///< Maximum number of client connections\r | |
33 | #define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges\r | |
34 | #define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates\r | |
4684b66f | 35 | #define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average\r |
f6e5cdd5 | 36 | #define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples\r |
4684b66f | 37 | \r |
38 | #define TPL_DATASINK TPL_CALLBACK ///< Synchronization TPL\r | |
39 | \r | |
40 | #define PACKET_SIZE 1448 ///< Size of data packets\r | |
41 | #define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes\r | |
42 | \r | |
43 | typedef struct _DT_PORT {\r | |
4684b66f | 44 | UINT64 BytesTotal;\r |
f6e5cdd5 | 45 | struct sockaddr_in6 IpAddress;\r |
46 | UINT32 In;\r | |
47 | UINT32 Samples;\r | |
48 | UINT64 BytesReceived[ DATA_SAMPLES ];\r | |
4684b66f | 49 | } DT_PORT;\r |
50 | \r | |
51 | volatile BOOLEAN bTick;\r | |
52 | BOOLEAN bTimerRunning;\r | |
f6e5cdd5 | 53 | struct sockaddr_in6 LocalAddress;\r |
4684b66f | 54 | EFI_EVENT pTimer;\r |
55 | int ListenSocket;\r | |
59bc0593 | 56 | UINT8 Buffer[ DATA_BUFFER_SIZE ];\r |
57 | struct pollfd PollFd[ MAX_CONNECTIONS ];\r | |
58 | DT_PORT Port[ MAX_CONNECTIONS ];\r | |
4684b66f | 59 | nfds_t MaxPort;\r |
60 | \r | |
61 | \r | |
62 | //\r | |
63 | // Forward routine declarations\r | |
64 | //\r | |
65 | EFI_STATUS TimerStart ( UINTN Milliseconds );\r | |
66 | \r | |
67 | \r | |
68 | /**\r | |
69 | Check for control C entered at console\r | |
70 | \r | |
71 | @retval EFI_SUCCESS Control C not entered\r | |
72 | @retval EFI_ABORTED Control C entered\r | |
73 | **/\r | |
74 | EFI_STATUS\r | |
75 | ControlCCheck (\r | |
76 | )\r | |
77 | {\r | |
78 | EFI_STATUS Status;\r | |
79 | \r | |
80 | //\r | |
81 | // Assume no user intervention\r | |
82 | //\r | |
83 | Status = EFI_SUCCESS;\r | |
84 | \r | |
85 | //\r | |
86 | // Display user stop request\r | |
87 | //\r | |
88 | if ( EFI_ERROR ( Status )) {\r | |
89 | DEBUG (( DEBUG_INFO,\r | |
90 | "User stop request!\r\n" ));\r | |
91 | }\r | |
92 | \r | |
93 | //\r | |
94 | // Return the check status\r | |
95 | //\r | |
96 | return Status;\r | |
97 | }\r | |
98 | \r | |
99 | \r | |
100 | /**\r | |
101 | Accept a socket connection\r | |
102 | \r | |
103 | @retval EFI_SUCCESS The application is running normally\r | |
104 | @retval EFI_NOT_STARTED Error with the listen socket\r | |
105 | @retval Other The user stopped the application\r | |
106 | **/\r | |
107 | EFI_STATUS\r | |
108 | SocketAccept (\r | |
109 | )\r | |
110 | {\r | |
111 | INT32 SocketStatus;\r | |
112 | EFI_STATUS Status;\r | |
113 | INTN Index;\r | |
114 | \r | |
115 | //\r | |
116 | // Assume failure\r | |
117 | //\r | |
118 | Status = EFI_DEVICE_ERROR;\r | |
119 | \r | |
120 | //\r | |
121 | // Bind to the local address\r | |
122 | //\r | |
123 | SocketStatus = bind ( ListenSocket,\r | |
124 | (struct sockaddr *) &LocalAddress,\r | |
f6e5cdd5 | 125 | LocalAddress.sin6_len );\r |
4684b66f | 126 | if ( 0 == SocketStatus ) {\r |
127 | //\r | |
128 | // Start listening on the local socket\r | |
129 | //\r | |
130 | SocketStatus = listen ( ListenSocket, 5 );\r | |
131 | if ( 0 == SocketStatus ) {\r | |
132 | //\r | |
133 | // Local socket in the listen state\r | |
134 | //\r | |
135 | Status = EFI_SUCCESS;\r | |
136 | \r | |
137 | //\r | |
138 | // Allocate a port\r | |
139 | //\r | |
140 | Index = MaxPort++;\r | |
59bc0593 | 141 | PollFd[ Index ].fd = ListenSocket;\r |
142 | PollFd[ Index ].events = POLLRDNORM | POLLHUP;\r | |
143 | PollFd[ Index ].revents = 0;\r | |
f6e5cdd5 | 144 | ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));\r |
4684b66f | 145 | }\r |
146 | }\r | |
147 | \r | |
148 | //\r | |
149 | // Return the operation status\r | |
150 | //\r | |
151 | return Status;\r | |
152 | }\r | |
153 | \r | |
154 | \r | |
155 | /**\r | |
156 | Close the socket\r | |
157 | \r | |
158 | @retval EFI_SUCCESS The application is running normally\r | |
159 | @retval Other The user stopped the application\r | |
160 | **/\r | |
161 | EFI_STATUS\r | |
162 | SocketClose (\r | |
163 | )\r | |
164 | {\r | |
165 | INT32 CloseStatus;\r | |
166 | EFI_STATUS Status;\r | |
167 | \r | |
168 | //\r | |
169 | // Determine if the socket is open\r | |
170 | //\r | |
171 | Status = EFI_DEVICE_ERROR;\r | |
172 | if ( -1 != ListenSocket ) {\r | |
173 | //\r | |
174 | // Attempt to close the socket\r | |
175 | //\r | |
176 | CloseStatus = close ( ListenSocket );\r | |
177 | if ( 0 == CloseStatus ) {\r | |
178 | DEBUG (( DEBUG_INFO,\r | |
179 | "0x%08x: Socket closed\r\n",\r | |
180 | ListenSocket ));\r | |
181 | ListenSocket = -1;\r | |
182 | Status = EFI_SUCCESS;\r | |
183 | }\r | |
184 | else {\r | |
185 | DEBUG (( DEBUG_ERROR,\r | |
186 | "ERROR: Failed to close socket, errno: %d\r\n",\r | |
187 | errno ));\r | |
188 | }\r | |
189 | }\r | |
190 | \r | |
191 | //\r | |
192 | // Return the operation status\r | |
193 | //\r | |
194 | return Status;\r | |
195 | }\r | |
196 | \r | |
197 | \r | |
198 | /**\r | |
199 | Create the socket\r | |
200 | \r | |
f6e5cdd5 | 201 | @param [in] Family Network family, AF_INET or AF_INET6\r |
202 | \r | |
4684b66f | 203 | @retval EFI_SUCCESS The application is running normally\r |
204 | @retval Other The user stopped the application\r | |
205 | **/\r | |
206 | EFI_STATUS\r | |
207 | SocketNew (\r | |
f6e5cdd5 | 208 | sa_family_t Family\r |
4684b66f | 209 | )\r |
210 | {\r | |
211 | EFI_STATUS Status;\r | |
212 | \r | |
213 | //\r | |
214 | // Get the port number\r | |
215 | //\r | |
216 | ZeroMem ( &LocalAddress, sizeof ( LocalAddress ));\r | |
f6e5cdd5 | 217 | LocalAddress.sin6_len = sizeof ( LocalAddress );\r |
218 | LocalAddress.sin6_family = Family;\r | |
219 | LocalAddress.sin6_port = htons ( PcdGet16 ( DataSource_Port ));\r | |
4684b66f | 220 | \r |
221 | //\r | |
222 | // Loop creating the socket\r | |
223 | //\r | |
224 | DEBUG (( DEBUG_INFO,\r | |
225 | "Creating the socket\r\n" ));\r | |
226 | \r | |
227 | //\r | |
228 | // Check for user stop request\r | |
229 | //\r | |
230 | Status = ControlCCheck ( );\r | |
231 | if ( !EFI_ERROR ( Status )) {\r | |
232 | //\r | |
233 | // Attempt to create the socket\r | |
234 | //\r | |
f6e5cdd5 | 235 | ListenSocket = socket ( LocalAddress.sin6_family,\r |
4684b66f | 236 | SOCK_STREAM,\r |
237 | IPPROTO_TCP );\r | |
238 | if ( -1 != ListenSocket ) {\r | |
239 | DEBUG (( DEBUG_INFO,\r | |
240 | "0x%08x: Socket created\r\n",\r | |
241 | ListenSocket ));\r | |
242 | }\r | |
59bc0593 | 243 | else {\r |
4684b66f | 244 | Status = EFI_NOT_STARTED;\r |
245 | }\r | |
246 | }\r | |
247 | \r | |
248 | //\r | |
249 | // Return the operation status\r | |
250 | //\r | |
251 | return Status;\r | |
252 | }\r | |
253 | \r | |
254 | \r | |
255 | /**\r | |
256 | Poll the socket for more work\r | |
257 | \r | |
258 | @retval EFI_SUCCESS The application is running normally\r | |
259 | @retval EFI_NOT_STARTED Listen socket error\r | |
260 | @retval Other The user stopped the application\r | |
261 | **/\r | |
262 | EFI_STATUS\r | |
263 | SocketPoll (\r | |
264 | )\r | |
265 | {\r | |
266 | BOOLEAN bRemoveSocket;\r | |
267 | BOOLEAN bListenError;\r | |
268 | size_t BytesReceived;\r | |
269 | int CloseStatus;\r | |
270 | nfds_t Entry;\r | |
271 | INTN EntryPrevious;\r | |
272 | int FdCount;\r | |
273 | nfds_t Index;\r | |
274 | socklen_t LengthInBytes;\r | |
f6e5cdd5 | 275 | struct sockaddr_in * pPortIpAddress4;\r |
276 | struct sockaddr_in6 * pPortIpAddress6;\r | |
277 | struct sockaddr_in * pRemoteAddress4;\r | |
278 | struct sockaddr_in6 * pRemoteAddress6;\r | |
279 | struct sockaddr_in6 RemoteAddress;\r | |
4684b66f | 280 | int Socket;\r |
281 | EFI_STATUS Status;\r | |
282 | EFI_TPL TplPrevious;\r | |
283 | \r | |
284 | //\r | |
285 | // Check for control-C\r | |
286 | //\r | |
f6e5cdd5 | 287 | pRemoteAddress4 = (struct sockaddr_in *)&RemoteAddress;\r |
288 | pRemoteAddress6 = (struct sockaddr_in6 *)&RemoteAddress;\r | |
4684b66f | 289 | bListenError = FALSE;\r |
290 | Status = ControlCCheck ( );\r | |
291 | if ( !EFI_ERROR ( Status )) {\r | |
292 | //\r | |
293 | // Poll the sockets\r | |
294 | //\r | |
295 | FdCount = poll ( &PollFd[0],\r | |
296 | MaxPort,\r | |
297 | 0 );\r | |
298 | if ( -1 == FdCount ) {\r | |
299 | //\r | |
300 | // Poll error\r | |
301 | //\r | |
302 | DEBUG (( DEBUG_ERROR,\r | |
303 | "ERROR - Poll error, errno: %d\r\n",\r | |
304 | errno ));\r | |
305 | Status = EFI_DEVICE_ERROR;\r | |
306 | }\r | |
307 | else {\r | |
308 | //\r | |
309 | // Process the poll output\r | |
310 | //\r | |
311 | Index = 0;\r | |
312 | while ( FdCount ) {\r | |
313 | bRemoveSocket = FALSE;\r | |
314 | \r | |
315 | //\r | |
316 | // Account for this descriptor\r | |
317 | //\r | |
f6e5cdd5 | 318 | pPortIpAddress4 = (struct sockaddr_in *)&Port[ Index ].IpAddress;\r |
319 | pPortIpAddress6 = (struct sockaddr_in6 *)&Port[ Index ].IpAddress;\r | |
59bc0593 | 320 | if ( 0 != PollFd[ Index ].revents ) {\r |
4684b66f | 321 | FdCount -= 1;\r |
322 | }\r | |
323 | \r | |
324 | //\r | |
325 | // Check for a broken connection\r | |
326 | //\r | |
59bc0593 | 327 | if ( 0 != ( PollFd[ Index ].revents & POLLHUP )) {\r |
4684b66f | 328 | bRemoveSocket = TRUE;\r |
59bc0593 | 329 | if ( ListenSocket == PollFd[ Index ].fd ) {\r |
4684b66f | 330 | bListenError = TRUE;\r |
331 | DEBUG (( DEBUG_ERROR,\r | |
332 | "ERROR - Network closed on listen socket, errno: %d\r\n",\r | |
333 | errno ));\r | |
334 | }\r | |
335 | else {\r | |
f6e5cdd5 | 336 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
337 | DEBUG (( DEBUG_ERROR,\r | |
338 | "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",\r | |
339 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
340 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
341 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
342 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 343 | ntohs ( pPortIpAddress4->sin_port ),\r |
f6e5cdd5 | 344 | errno ));\r |
345 | }\r | |
346 | else {\r | |
347 | DEBUG (( DEBUG_ERROR,\r | |
348 | "ERROR - Network closed on socket [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",\r | |
349 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
350 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
351 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
352 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
353 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
354 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
355 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
356 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
357 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
358 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
359 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
360 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
361 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
362 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
363 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
364 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 365 | ntohs ( pPortIpAddress6->sin6_port ),\r |
f6e5cdd5 | 366 | errno ));\r |
367 | }\r | |
4684b66f | 368 | \r |
369 | //\r | |
370 | // Close the socket\r | |
371 | //\r | |
59bc0593 | 372 | CloseStatus = close ( PollFd[ Index ].fd );\r |
4684b66f | 373 | if ( 0 == CloseStatus ) {\r |
374 | bRemoveSocket = TRUE;\r | |
f6e5cdd5 | 375 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
376 | DEBUG (( DEBUG_INFO,\r | |
377 | "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",\r | |
378 | PollFd[ Index ].fd,\r | |
379 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
380 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
381 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
382 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 383 | ntohs ( pPortIpAddress4->sin_port )));\r |
f6e5cdd5 | 384 | }\r |
385 | else {\r | |
386 | DEBUG (( DEBUG_INFO,\r | |
387 | "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r | |
388 | PollFd[ Index ].fd,\r | |
389 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
390 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
391 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
392 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
393 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
394 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
395 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
396 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
397 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
398 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
399 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
400 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
401 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
402 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
403 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
404 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 405 | ntohs ( pPortIpAddress6->sin6_port )));\r |
f6e5cdd5 | 406 | }\r |
4684b66f | 407 | }\r |
408 | else {\r | |
f6e5cdd5 | 409 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
410 | DEBUG (( DEBUG_ERROR,\r | |
411 | "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",\r | |
412 | PollFd[ Index ].fd,\r | |
413 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
414 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
415 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
416 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 417 | ntohs ( pPortIpAddress4->sin_port ),\r |
f6e5cdd5 | 418 | errno ));\r |
419 | }\r | |
420 | else {\r | |
421 | DEBUG (( DEBUG_ERROR,\r | |
422 | "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",\r | |
423 | PollFd[ Index ].fd,\r | |
424 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
425 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
426 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
427 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
428 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
429 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
430 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
431 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
432 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
433 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
434 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
435 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
436 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
437 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
438 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
439 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 440 | ntohs ( pPortIpAddress6->sin6_port ),\r |
f6e5cdd5 | 441 | errno ));\r |
442 | }\r | |
4684b66f | 443 | }\r |
444 | }\r | |
445 | }\r | |
446 | \r | |
447 | //\r | |
448 | // Check for a connection or read data\r | |
449 | //\r | |
59bc0593 | 450 | if ( 0 != ( PollFd[ Index ].revents & POLLRDNORM )) {\r |
4684b66f | 451 | //\r |
452 | // Check for a connection\r | |
453 | //\r | |
59bc0593 | 454 | if ( ListenSocket == PollFd[ Index ].fd ) {\r |
4684b66f | 455 | //\r |
456 | // Another client connection was received\r | |
457 | //\r | |
458 | LengthInBytes = sizeof ( RemoteAddress );\r | |
459 | Socket = accept ( ListenSocket,\r | |
460 | (struct sockaddr *) &RemoteAddress,\r | |
461 | &LengthInBytes );\r | |
462 | if ( -1 == Socket ) {\r | |
463 | //\r | |
464 | // Listen socket error\r | |
465 | //\r | |
466 | bListenError = TRUE;\r | |
467 | bRemoveSocket = TRUE;\r | |
468 | DEBUG (( DEBUG_ERROR,\r | |
469 | "ERROR - Listen socket failure, errno: %d\r\n",\r | |
470 | errno ));\r | |
471 | }\r | |
472 | else {\r | |
473 | //\r | |
474 | // Determine if there is room for this connection\r | |
475 | //\r | |
476 | if (( MAX_CONNECTIONS <= MaxPort )\r | |
477 | || ((( MAX_CONNECTIONS - 1 ) == MaxPort ) && ( -1 == ListenSocket ))) {\r | |
478 | //\r | |
479 | // Display the connection\r | |
480 | //\r | |
f6e5cdd5 | 481 | if ( AF_INET == pRemoteAddress4->sin_family ) {\r |
482 | Print ( L"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",\r | |
483 | pRemoteAddress4->sin_addr.s_addr & 0xff,\r | |
484 | ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
485 | ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
486 | ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 487 | ntohs ( pRemoteAddress4->sin_port ));\r |
f6e5cdd5 | 488 | }\r |
489 | else {\r | |
490 | Print ( L"Rejecting connection to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r | |
491 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
492 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
493 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
494 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
495 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
496 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
497 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
498 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
499 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
500 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
501 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
502 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
503 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
504 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
505 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
506 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 507 | ntohs ( pRemoteAddress6->sin6_port ));\r |
f6e5cdd5 | 508 | }\r |
4684b66f | 509 | \r |
510 | //\r | |
511 | // No room for this connection\r | |
512 | // Close the connection\r | |
513 | //\r | |
514 | CloseStatus = close ( Socket );\r | |
515 | if ( 0 == CloseStatus ) {\r | |
516 | bRemoveSocket = TRUE;\r | |
f6e5cdd5 | 517 | if ( AF_INET == pRemoteAddress4->sin_family ) {\r |
518 | DEBUG (( DEBUG_INFO,\r | |
519 | "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",\r | |
520 | PollFd[ Index ].fd,\r | |
521 | pRemoteAddress4->sin_addr.s_addr & 0xff,\r | |
522 | ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
523 | ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
524 | ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 525 | ntohs ( pRemoteAddress4->sin_port )));\r |
f6e5cdd5 | 526 | }\r |
527 | else {\r | |
528 | DEBUG (( DEBUG_INFO,\r | |
529 | "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r | |
530 | PollFd[ Index ].fd,\r | |
531 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
532 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
533 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
534 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
535 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
536 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
537 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
538 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
539 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
540 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
541 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
542 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
543 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
544 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
545 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
546 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 547 | ntohs ( pRemoteAddress6->sin6_port )));\r |
f6e5cdd5 | 548 | }\r |
4684b66f | 549 | }\r |
550 | else {\r | |
551 | DEBUG (( DEBUG_ERROR,\r | |
552 | "ERROR - Failed to close socket 0x%08x, errno: %d\r\n",\r | |
59bc0593 | 553 | PollFd[ Index ].fd,\r |
4684b66f | 554 | errno ));\r |
555 | }\r | |
556 | \r | |
557 | //\r | |
558 | // Keep the application running\r | |
559 | // No issue with the listen socket\r | |
560 | //\r | |
561 | Status = EFI_SUCCESS;\r | |
562 | }\r | |
59bc0593 | 563 | else {\r |
4684b66f | 564 | //\r |
565 | // Display the connection\r | |
566 | //\r | |
f6e5cdd5 | 567 | if ( AF_INET == pRemoteAddress4->sin_family ) {\r |
568 | Print ( L"Connected to remote system %d.%d.%d.%d:%d\r\n",\r | |
569 | pRemoteAddress4->sin_addr.s_addr & 0xff,\r | |
570 | ( pRemoteAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
571 | ( pRemoteAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
572 | ( pRemoteAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 573 | ntohs ( pRemoteAddress4->sin_port ));\r |
f6e5cdd5 | 574 | }\r |
575 | else {\r | |
576 | Print ( L"Connected to remote system [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r | |
577 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
578 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
579 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
580 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
581 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
582 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
583 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
584 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
585 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
586 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
587 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
588 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
589 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
590 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
591 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
592 | pRemoteAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 593 | ntohs ( pRemoteAddress6->sin6_port ));\r |
f6e5cdd5 | 594 | }\r |
4684b66f | 595 | \r |
596 | //\r | |
597 | // Allocate the client connection\r | |
598 | //\r | |
599 | Index = MaxPort++;\r | |
f6e5cdd5 | 600 | ZeroMem ( &Port[ Index ], sizeof ( Port[ Index ]));\r |
601 | CopyMem ( pPortIpAddress6, pRemoteAddress6, sizeof ( *pRemoteAddress6 ));\r | |
59bc0593 | 602 | PollFd[ Index ].fd = Socket;\r |
603 | PollFd[ Index ].events = POLLRDNORM | POLLHUP;\r | |
604 | PollFd[ Index ].revents = 0;\r | |
4684b66f | 605 | }\r |
606 | }\r | |
607 | }\r | |
608 | else {\r | |
609 | //\r | |
610 | // Data received\r | |
611 | //\r | |
59bc0593 | 612 | BytesReceived = read ( PollFd[ Index ].fd,\r |
4684b66f | 613 | &Buffer,\r |
614 | sizeof ( Buffer ));\r | |
615 | if ( 0 < BytesReceived ) {\r | |
616 | //\r | |
617 | // Display the amount of data received\r | |
618 | //\r | |
f6e5cdd5 | 619 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
620 | DEBUG (( DEBUG_INFO,\r | |
621 | "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",\r | |
622 | PollFd[ Index ].fd,\r | |
623 | BytesReceived,\r | |
624 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
625 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
626 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
627 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 628 | ntohs ( pPortIpAddress4->sin_port )));\r |
f6e5cdd5 | 629 | }\r |
630 | else {\r | |
631 | DEBUG (( DEBUG_INFO,\r | |
632 | "0x%08x: Socket received 0x%08x bytes from [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r | |
633 | PollFd[ Index ].fd,\r | |
634 | BytesReceived,\r | |
635 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
636 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
637 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
638 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
639 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
640 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
641 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
642 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
643 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
644 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
645 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
646 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
647 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
648 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
649 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
650 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 651 | ntohs ( pPortIpAddress6->sin6_port )));\r |
f6e5cdd5 | 652 | }\r |
4684b66f | 653 | \r |
654 | //\r | |
655 | // Synchronize with the TimerCallback routine\r | |
656 | //\r | |
657 | TplPrevious = gBS->RaiseTPL ( TPL_DATASINK );\r | |
658 | \r | |
659 | //\r | |
660 | // Account for the data received\r | |
661 | //\r | |
59bc0593 | 662 | Port[ Index ].BytesTotal += BytesReceived;\r |
4684b66f | 663 | \r |
664 | //\r | |
665 | // Release the synchronization with the TimerCallback routine\r | |
666 | //\r | |
667 | gBS->RestoreTPL ( TplPrevious );\r | |
668 | }\r | |
669 | else if ( -1 == BytesReceived ) {\r | |
670 | //\r | |
671 | // Close the socket\r | |
672 | //\r | |
f6e5cdd5 | 673 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
674 | DEBUG (( DEBUG_INFO,\r | |
675 | "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",\r | |
676 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
677 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
678 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
679 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 680 | ntohs ( pPortIpAddress4->sin_port ),\r |
f6e5cdd5 | 681 | errno ));\r |
682 | }\r | |
683 | else {\r | |
684 | DEBUG (( DEBUG_INFO,\r | |
685 | "ERROR - Receive failure for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",\r | |
686 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
687 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
688 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
689 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
690 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
691 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
692 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
693 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
694 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
695 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
696 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
697 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
698 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
699 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
700 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
701 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 702 | ntohs ( pPortIpAddress6->sin6_port ),\r |
f6e5cdd5 | 703 | errno ));\r |
704 | }\r | |
59bc0593 | 705 | CloseStatus = close ( PollFd[ Index ].fd );\r |
4684b66f | 706 | if ( 0 == CloseStatus ) {\r |
707 | bRemoveSocket = TRUE;\r | |
f6e5cdd5 | 708 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
709 | DEBUG (( DEBUG_INFO,\r | |
710 | "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",\r | |
711 | PollFd[ Index ].fd,\r | |
712 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
713 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
714 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
715 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 716 | ntohs ( pPortIpAddress4->sin_port )));\r |
f6e5cdd5 | 717 | }\r |
718 | else {\r | |
719 | DEBUG (( DEBUG_INFO,\r | |
720 | "0x%08x: Socket closed for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",\r | |
721 | PollFd[ Index ].fd,\r | |
722 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
723 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
724 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
725 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
726 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
727 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
728 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
729 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
730 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
731 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
732 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
733 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
734 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
735 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
736 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
737 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 738 | ntohs ( pPortIpAddress6->sin6_port )));\r |
f6e5cdd5 | 739 | }\r |
4684b66f | 740 | }\r |
741 | else {\r | |
f6e5cdd5 | 742 | if ( AF_INET == pPortIpAddress4->sin_family ) {\r |
743 | DEBUG (( DEBUG_ERROR,\r | |
744 | "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",\r | |
745 | PollFd[ Index ].fd,\r | |
746 | pPortIpAddress4->sin_addr.s_addr & 0xff,\r | |
747 | ( pPortIpAddress4->sin_addr.s_addr >> 8 ) & 0xff,\r | |
748 | ( pPortIpAddress4->sin_addr.s_addr >> 16 ) & 0xff,\r | |
749 | ( pPortIpAddress4->sin_addr.s_addr >> 24 ) & 0xff,\r | |
9d0e28d4 | 750 | ntohs ( pPortIpAddress4->sin_port ),\r |
f6e5cdd5 | 751 | errno ));\r |
752 | }\r | |
753 | else {\r | |
754 | DEBUG (( DEBUG_ERROR,\r | |
755 | "ERROR - Failed to close socket 0x%08x for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d, errno: %d\r\n",\r | |
756 | PollFd[ Index ].fd,\r | |
757 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 0 ],\r | |
758 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 1 ],\r | |
759 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 2 ],\r | |
760 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 3 ],\r | |
761 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 4 ],\r | |
762 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 5 ],\r | |
763 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 6 ],\r | |
764 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 7 ],\r | |
765 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 8 ],\r | |
766 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 9 ],\r | |
767 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 10 ],\r | |
768 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 11 ],\r | |
769 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 12 ],\r | |
770 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 13 ],\r | |
771 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 14 ],\r | |
772 | pPortIpAddress6->sin6_addr.__u6_addr.__u6_addr8[ 15 ],\r | |
9d0e28d4 | 773 | ntohs ( pPortIpAddress6->sin6_port ),\r |
f6e5cdd5 | 774 | errno ));\r |
775 | }\r | |
4684b66f | 776 | }\r |
777 | }\r | |
778 | \r | |
779 | //\r | |
780 | // Keep the application running\r | |
781 | // No issue with the listen socket\r | |
782 | //\r | |
783 | Status = EFI_SUCCESS;\r | |
784 | }\r | |
785 | }\r | |
786 | \r | |
787 | //\r | |
788 | // Remove the socket if necessary\r | |
789 | //\r | |
790 | if ( bRemoveSocket ) {\r | |
791 | DEBUG (( DEBUG_INFO,\r | |
792 | "0x%08x: Socket removed from polling\r\n",\r | |
59bc0593 | 793 | PollFd[ Index ].fd ));\r |
4684b66f | 794 | MaxPort -= 1;\r |
795 | for ( Entry = Index + 1; MaxPort >= Entry; Entry++ ) {\r | |
796 | EntryPrevious = Entry;\r | |
f6e5cdd5 | 797 | CopyMem ( &Port[ EntryPrevious ],\r |
798 | &Port[ Entry ],\r | |
799 | sizeof ( Port[ Entry ]));\r | |
59bc0593 | 800 | PollFd[ EntryPrevious ].events = PollFd[ Entry ].events;\r |
801 | PollFd[ EntryPrevious ].fd = PollFd[ Entry ].fd;\r | |
802 | PollFd[ EntryPrevious ].revents = PollFd[ Entry ].revents;\r | |
4684b66f | 803 | }\r |
59bc0593 | 804 | PollFd[ MaxPort ].fd = -1;\r |
4684b66f | 805 | Index -= 1;\r |
806 | }\r | |
807 | \r | |
808 | //\r | |
809 | // Account for this socket\r | |
810 | //\r | |
811 | Index += 1;\r | |
812 | }\r | |
813 | }\r | |
814 | }\r | |
815 | \r | |
816 | //\r | |
817 | // Return the listen failure if necessary\r | |
818 | //\r | |
819 | if (( !EFI_ERROR ( Status )) && bListenError ) {\r | |
820 | Status = EFI_NOT_STARTED;\r | |
821 | }\r | |
822 | \r | |
823 | //\r | |
824 | // Return the poll status\r | |
825 | //\r | |
826 | return Status;\r | |
827 | }\r | |
828 | \r | |
829 | \r | |
830 | /**\r | |
831 | Handle the timer callback\r | |
832 | \r | |
833 | @param [in] Event Event that caused this callback\r | |
834 | @param [in] pContext Context for this routine\r | |
835 | **/\r | |
836 | VOID\r | |
53c31c51 | 837 | EFIAPI\r |
4684b66f | 838 | TimerCallback (\r |
839 | IN EFI_EVENT Event,\r | |
840 | IN VOID * pContext\r | |
841 | )\r | |
842 | {\r | |
f6e5cdd5 | 843 | UINT32 Average;\r |
844 | UINT64 BitsPerSecond;\r | |
4684b66f | 845 | UINT64 BytesReceived;\r |
f6e5cdd5 | 846 | UINT32 Count;\r |
4684b66f | 847 | nfds_t Index;\r |
f6e5cdd5 | 848 | UINT64 TotalBytes;\r |
4684b66f | 849 | \r |
850 | //\r | |
851 | // Notify the other code of the timer tick\r | |
852 | //\r | |
853 | bTick = TRUE;\r | |
854 | \r | |
855 | //\r | |
856 | // Walk the list of ports\r | |
857 | //\r | |
858 | for ( Index = 0; MaxPort > Index; Index++ ) {\r | |
859 | //\r | |
860 | // Determine if any data was received\r | |
861 | //\r | |
59bc0593 | 862 | BytesReceived = Port[ Index ].BytesTotal;\r |
863 | if (( ListenSocket != PollFd[ Index ].fd )\r | |
4684b66f | 864 | && ( 0 != BytesReceived )) {\r |
865 | //\r | |
f6e5cdd5 | 866 | // Update the received data samples\r |
4684b66f | 867 | //\r |
f6e5cdd5 | 868 | Port[ Index ].BytesTotal = 0;\r |
869 | Port[ Index ].BytesReceived [ Port[ Index ].In ] = BytesReceived;\r | |
870 | Port[ Index ].In += 1;\r | |
871 | if ( DATA_SAMPLES <= Port[ Index ].In ) {\r | |
872 | Port[ Index ].In = 0;\r | |
873 | }\r | |
874 | \r | |
4684b66f | 875 | //\r |
876 | // Separate the samples\r | |
877 | //\r | |
f6e5cdd5 | 878 | if ( DATA_SAMPLES == Port[ Index ].Samples ) {\r |
4684b66f | 879 | Print ( L"---------- Stable average ----------\r\n" );\r |
880 | }\r | |
59bc0593 | 881 | Port[ Index ].Samples += 1;\r |
4684b66f | 882 | \r |
f6e5cdd5 | 883 | //\r |
884 | // Compute the data rate\r | |
885 | //\r | |
886 | TotalBytes = 0;\r | |
887 | for ( Count = 0; DATA_SAMPLES > Count; Count++ )\r | |
888 | {\r | |
889 | TotalBytes += Port[ Index ].BytesReceived[ Count ];\r | |
890 | }\r | |
891 | Average = (UINT32)RShiftU64 ( TotalBytes, DATA_SAMPLE_SHIFT );\r | |
892 | BitsPerSecond = Average * 8;\r | |
893 | \r | |
4684b66f | 894 | //\r |
895 | // Display the data rate\r | |
896 | //\r | |
f6e5cdd5 | 897 | if (( RANGE_SWITCH >> 10 ) > Average ) {\r |
898 | Print ( L"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",\r | |
899 | Average,\r | |
900 | BitsPerSecond );\r | |
4684b66f | 901 | }\r |
902 | else {\r | |
f6e5cdd5 | 903 | BitsPerSecond /= 1000;\r |
904 | if ( RANGE_SWITCH > Average ) {\r | |
905 | Print ( L"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",\r | |
906 | Average >> 10,\r | |
907 | (( Average & 0x3ff ) * 1000 ) >> 10,\r | |
908 | BitsPerSecond );\r | |
4684b66f | 909 | }\r |
910 | else {\r | |
f6e5cdd5 | 911 | BitsPerSecond /= 1000;\r |
4684b66f | 912 | Average >>= 10;\r |
f6e5cdd5 | 913 | if ( RANGE_SWITCH > Average ) {\r |
914 | Print ( L"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",\r | |
915 | Average >> 10,\r | |
916 | (( Average & 0x3ff ) * 1000 ) >> 10,\r | |
917 | BitsPerSecond );\r | |
4684b66f | 918 | }\r |
919 | else {\r | |
f6e5cdd5 | 920 | BitsPerSecond /= 1000;\r |
4684b66f | 921 | Average >>= 10;\r |
f6e5cdd5 | 922 | if ( RANGE_SWITCH > Average ) {\r |
923 | Print ( L"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",\r | |
924 | Average >> 10,\r | |
925 | (( Average & 0x3ff ) * 1000 ) >> 10,\r | |
926 | BitsPerSecond );\r | |
4684b66f | 927 | }\r |
928 | else {\r | |
f6e5cdd5 | 929 | BitsPerSecond /= 1000;\r |
4684b66f | 930 | Average >>= 10;\r |
f6e5cdd5 | 931 | if ( RANGE_SWITCH > Average ) {\r |
932 | Print ( L"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",\r | |
933 | Average >> 10,\r | |
934 | (( Average & 0x3ff ) * 1000 ) >> 10,\r | |
935 | BitsPerSecond );\r | |
4684b66f | 936 | }\r |
937 | else {\r | |
f6e5cdd5 | 938 | BitsPerSecond /= 1000;\r |
4684b66f | 939 | Average >>= 10;\r |
f6e5cdd5 | 940 | Print ( L"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",\r |
941 | Average >> 10,\r | |
942 | (( Average & 0x3ff ) * 1000 ) >> 10,\r | |
943 | BitsPerSecond );\r | |
4684b66f | 944 | }\r |
945 | }\r | |
946 | }\r | |
947 | }\r | |
948 | }\r | |
949 | }\r | |
950 | }\r | |
951 | }\r | |
952 | \r | |
953 | \r | |
954 | /**\r | |
955 | Create the timer\r | |
956 | \r | |
957 | @retval EFI_SUCCESS The timer was successfully created\r | |
958 | @retval Other Timer initialization failed\r | |
959 | **/\r | |
960 | EFI_STATUS\r | |
961 | TimerCreate (\r | |
962 | )\r | |
963 | {\r | |
964 | EFI_STATUS Status;\r | |
965 | \r | |
966 | //\r | |
967 | // Create the timer\r | |
968 | //\r | |
969 | Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL,\r | |
970 | TPL_DATASINK,\r | |
971 | TimerCallback,\r | |
972 | NULL,\r | |
973 | &pTimer );\r | |
974 | if ( EFI_ERROR ( Status )) {\r | |
975 | DEBUG (( DEBUG_ERROR,\r | |
976 | "ERROR - Failed to allocate the timer event, Status: %r\r\n",\r | |
977 | Status ));\r | |
978 | }\r | |
979 | else {\r | |
980 | DEBUG (( DEBUG_INFO,\r | |
981 | "0x%08x: Timer created\r\n",\r | |
982 | pTimer ));\r | |
983 | }\r | |
984 | \r | |
985 | //\r | |
986 | // Return the operation status\r | |
987 | //\r | |
988 | return Status;\r | |
989 | }\r | |
990 | \r | |
991 | \r | |
992 | /**\r | |
993 | Stop the timer\r | |
994 | \r | |
995 | @retval EFI_SUCCESS The timer was stopped successfully\r | |
996 | @retval Other The timer failed to stop\r | |
997 | **/\r | |
998 | EFI_STATUS\r | |
999 | TimerStop (\r | |
1000 | )\r | |
1001 | {\r | |
1002 | EFI_STATUS Status;\r | |
1003 | \r | |
1004 | //\r | |
1005 | // Assume success\r | |
1006 | //\r | |
1007 | Status = EFI_SUCCESS;\r | |
1008 | \r | |
1009 | //\r | |
1010 | // Determine if the timer is running\r | |
1011 | //\r | |
1012 | if ( bTimerRunning ) {\r | |
1013 | //\r | |
1014 | // Stop the timer\r | |
1015 | //\r | |
1016 | Status = gBS->SetTimer ( pTimer,\r | |
1017 | TimerCancel,\r | |
1018 | 0 );\r | |
1019 | if ( EFI_ERROR ( Status )) {\r | |
1020 | DEBUG (( DEBUG_ERROR,\r | |
1021 | "ERROR - Failed to stop the timer, Status: %r\r\n",\r | |
1022 | Status ));\r | |
1023 | }\r | |
1024 | else {\r | |
1025 | //\r | |
1026 | // Timer timer is now stopped\r | |
1027 | //\r | |
1028 | bTimerRunning = FALSE;\r | |
1029 | DEBUG (( DEBUG_INFO,\r | |
1030 | "0x%08x: Timer stopped\r\n",\r | |
1031 | pTimer ));\r | |
1032 | }\r | |
1033 | }\r | |
1034 | \r | |
1035 | //\r | |
1036 | // Return the operation status\r | |
1037 | //\r | |
1038 | return Status;\r | |
1039 | }\r | |
1040 | \r | |
1041 | \r | |
1042 | /**\r | |
1043 | Start the timer\r | |
1044 | \r | |
1045 | @param [in] Milliseconds The number of milliseconds between timer callbacks\r | |
1046 | \r | |
1047 | @retval EFI_SUCCESS The timer was successfully created\r | |
1048 | @retval Other Timer initialization failed\r | |
1049 | **/\r | |
1050 | EFI_STATUS\r | |
1051 | TimerStart (\r | |
1052 | UINTN Milliseconds\r | |
1053 | )\r | |
1054 | {\r | |
1055 | EFI_STATUS Status;\r | |
1056 | UINT64 TimeDelay;\r | |
1057 | \r | |
1058 | //\r | |
1059 | // Stop the timer if necessary\r | |
1060 | //\r | |
1061 | Status = EFI_SUCCESS;\r | |
1062 | if ( bTimerRunning ) {\r | |
1063 | Status = TimerStop ( );\r | |
1064 | }\r | |
1065 | if ( !EFI_ERROR ( Status )) {\r | |
1066 | //\r | |
1067 | // Compute the new delay\r | |
1068 | //\r | |
1069 | TimeDelay = Milliseconds;\r | |
1070 | TimeDelay *= 1000 * 10;\r | |
1071 | \r | |
1072 | //\r | |
1073 | // Start the timer\r | |
1074 | //\r | |
1075 | Status = gBS->SetTimer ( pTimer,\r | |
1076 | TimerPeriodic,\r | |
1077 | TimeDelay );\r | |
1078 | if ( EFI_ERROR ( Status )) {\r | |
1079 | DEBUG (( DEBUG_ERROR,\r | |
1080 | "ERROR - Failed to start the timer, Status: %r\r\n",\r | |
1081 | Status ));\r | |
1082 | }\r | |
1083 | else {\r | |
1084 | //\r | |
1085 | // The timer is now running\r | |
1086 | //\r | |
1087 | bTimerRunning = TRUE;\r | |
1088 | DEBUG (( DEBUG_INFO,\r | |
1089 | "0x%08x: Timer running\r\n",\r | |
1090 | pTimer ));\r | |
1091 | }\r | |
1092 | }\r | |
1093 | \r | |
1094 | //\r | |
1095 | // Return the operation status\r | |
1096 | //\r | |
1097 | return Status;\r | |
1098 | }\r | |
1099 | \r | |
1100 | \r | |
1101 | /**\r | |
1102 | Destroy the timer\r | |
1103 | \r | |
1104 | @retval EFI_SUCCESS The timer was destroyed successfully\r | |
1105 | @retval Other Failed to destroy the timer\r | |
1106 | **/\r | |
1107 | EFI_STATUS\r | |
1108 | TimerDestroy (\r | |
1109 | )\r | |
1110 | {\r | |
1111 | EFI_STATUS Status;\r | |
1112 | \r | |
1113 | //\r | |
1114 | // Assume success\r | |
1115 | //\r | |
1116 | Status = EFI_SUCCESS;\r | |
1117 | \r | |
1118 | //\r | |
1119 | // Determine if the timer is running\r | |
1120 | //\r | |
1121 | if ( bTimerRunning ) {\r | |
1122 | //\r | |
1123 | // Stop the timer\r | |
1124 | //\r | |
1125 | Status = TimerStop ( );\r | |
1126 | }\r | |
1127 | if (( !EFI_ERROR ( Status )) && ( NULL != pTimer )) {\r | |
1128 | //\r | |
1129 | // Done with this timer\r | |
1130 | //\r | |
1131 | Status = gBS->CloseEvent ( pTimer );\r | |
1132 | if ( EFI_ERROR ( Status )) {\r | |
1133 | DEBUG (( DEBUG_ERROR,\r | |
1134 | "ERROR - Failed to free the timer event, Status: %r\r\n",\r | |
1135 | Status ));\r | |
1136 | }\r | |
1137 | else {\r | |
1138 | DEBUG (( DEBUG_INFO,\r | |
1139 | "0x%08x: Timer Destroyed\r\n",\r | |
1140 | pTimer ));\r | |
1141 | pTimer = NULL;\r | |
1142 | }\r | |
1143 | }\r | |
1144 | \r | |
1145 | //\r | |
1146 | // Return the operation status\r | |
1147 | //\r | |
1148 | return Status;\r | |
1149 | }\r | |
1150 | \r | |
1151 | \r | |
1152 | /**\r | |
1153 | Receive data from the DataSource program to test a network's bandwidth.\r | |
1154 | \r | |
1155 | @param [in] Argc The number of arguments\r | |
1156 | @param [in] Argv The argument value array\r | |
1157 | \r | |
1158 | @retval 0 The application exited normally.\r | |
1159 | @retval Other An error occurred.\r | |
1160 | **/\r | |
1161 | int\r | |
1162 | main (\r | |
1163 | IN int Argc,\r | |
1164 | IN char **Argv\r | |
1165 | )\r | |
1166 | {\r | |
f6e5cdd5 | 1167 | sa_family_t Family;\r |
4684b66f | 1168 | EFI_STATUS Status;\r |
1169 | \r | |
1170 | DEBUG (( DEBUG_INFO,\r | |
1171 | "DataSink starting\r\n" ));\r | |
1172 | \r | |
f6e5cdd5 | 1173 | //\r |
1174 | // Determine the family to use\r | |
1175 | //\r | |
1176 | Family = ( 1 < Argc ) ? AF_INET6 : AF_INET;\r | |
1177 | \r | |
4684b66f | 1178 | //\r |
1179 | // Use for/break instead of goto\r | |
1180 | //\r | |
59bc0593 | 1181 | for ( ; ; ) {\r |
4684b66f | 1182 | //\r |
1183 | // Create the timer\r | |
1184 | //\r | |
1185 | bTick = TRUE;\r | |
1186 | Status = TimerCreate ( );\r | |
1187 | if ( EFI_ERROR ( Status )) {\r | |
1188 | break;\r | |
1189 | }\r | |
1190 | \r | |
1191 | //\r | |
1192 | // Start a timer to perform network polling and display updates\r | |
1193 | //\r | |
1194 | Status = TimerStart ( 1 * 1000 );\r | |
1195 | if ( EFI_ERROR ( Status )) {\r | |
1196 | break;\r | |
1197 | }\r | |
1198 | \r | |
1199 | //\r | |
1200 | // Loop forever waiting for abuse\r | |
1201 | //\r | |
1202 | do {\r | |
1203 | ListenSocket = -1;\r | |
1204 | do {\r | |
1205 | //\r | |
1206 | // Complete any client operations\r | |
1207 | //\r | |
1208 | Status = SocketPoll ( );\r | |
1209 | if ( EFI_ERROR ( Status )) {\r | |
1210 | //\r | |
1211 | // Control-C\r | |
1212 | //\r | |
1213 | break;\r | |
1214 | }\r | |
1215 | \r | |
1216 | //\r | |
1217 | // Wait for a while\r | |
1218 | //\r | |
1219 | } while ( !bTick );\r | |
1220 | if ( EFI_ERROR ( Status )) {\r | |
1221 | //\r | |
1222 | // Control-C\r | |
1223 | //\r | |
1224 | break;\r | |
1225 | }\r | |
1226 | \r | |
1227 | //\r | |
1228 | // Wait for the network layer to initialize\r | |
1229 | //\r | |
f6e5cdd5 | 1230 | Status = SocketNew ( Family );\r |
4684b66f | 1231 | if ( EFI_ERROR ( Status )) {\r |
1232 | continue;\r | |
1233 | }\r | |
1234 | \r | |
1235 | //\r | |
1236 | // Wait for the remote network application to start\r | |
1237 | //\r | |
1238 | Status = SocketAccept ( );\r | |
1239 | if ( EFI_NOT_STARTED == Status ) {\r | |
1240 | Status = SocketClose ( );\r | |
1241 | continue;\r | |
1242 | }\r | |
1243 | else if ( EFI_SUCCESS != Status ) {\r | |
1244 | //\r | |
1245 | // Control-C\r | |
1246 | //\r | |
1247 | break;\r | |
1248 | }\r | |
1249 | \r | |
1250 | //\r | |
f6e5cdd5 | 1251 | // Receive data until the connection breaks\r |
4684b66f | 1252 | //\r |
1253 | do {\r | |
1254 | Status = SocketPoll ( );\r | |
1255 | } while ( !EFI_ERROR ( Status ));\r | |
1256 | \r | |
1257 | //\r | |
1258 | // Done with the socket\r | |
1259 | //\r | |
1260 | Status = SocketClose ( );\r | |
1261 | } while ( !EFI_ERROR ( Status ));\r | |
1262 | \r | |
1263 | //\r | |
1264 | // Close the socket if necessary\r | |
1265 | //\r | |
1266 | SocketClose ( );\r | |
1267 | \r | |
1268 | //\r | |
1269 | // All done\r | |
1270 | //\r | |
1271 | break;\r | |
1272 | }\r | |
1273 | \r | |
1274 | //\r | |
1275 | // Stop the timer if necessary\r | |
1276 | //\r | |
1277 | TimerStop ( );\r | |
1278 | TimerDestroy ( );\r | |
1279 | \r | |
1280 | //\r | |
1281 | // Return the operation status\r | |
1282 | //\r | |
1283 | DEBUG (( DEBUG_INFO,\r | |
1284 | "DataSink exiting, Status: %r\r\n",\r | |
1285 | Status ));\r | |
1286 | return Status;\r | |
1287 | }\r |