2 Data source for network testing.
4 Copyright (c) 2011-2012, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
24 #include <netinet/in.h>
26 #include <sys/EfiSysCall.h>
28 #include <sys/socket.h>
31 #define DATA_SAMPLE_SHIFT 5 ///< Shift for number of samples
32 #define MAX_CONNECTIONS ( 1 + 16 ) ///< Maximum number of client connections
33 #define RANGE_SWITCH ( 1024 * 1024 ) ///< Switch display ranges
34 #define DATA_RATE_UPDATE_SHIFT 2 ///< 2n seconds between updates
35 #define AVERAGE_SHIFT_COUNT ( 6 - DATA_RATE_UPDATE_SHIFT ) ///< 2n samples in average
36 #define DATA_SAMPLES ( 1 << DATA_SAMPLE_SHIFT ) ///< Number of samples
38 #define TPL_DATASINK TPL_CALLBACK ///< Synchronization TPL
40 #define PACKET_SIZE 1448 ///< Size of data packets
41 #define DATA_BUFFER_SIZE (( 65536 / PACKET_SIZE ) * PACKET_SIZE ) ///< Buffer size in bytes
43 typedef struct _DT_PORT
{
45 struct sockaddr_in6 IpAddress
;
48 UINT64 BytesReceived
[ DATA_SAMPLES
];
51 volatile BOOLEAN bTick
;
52 BOOLEAN bTimerRunning
;
53 struct sockaddr_in6 LocalAddress
;
56 UINT8 Buffer
[ DATA_BUFFER_SIZE
];
57 struct pollfd PollFd
[ MAX_CONNECTIONS
];
58 DT_PORT Port
[ MAX_CONNECTIONS
];
63 // Forward routine declarations
65 EFI_STATUS
TimerStart ( UINTN Milliseconds
);
69 Check for control C entered at console
71 @retval EFI_SUCCESS Control C not entered
72 @retval EFI_ABORTED Control C entered
81 // Assume no user intervention
86 // Display user stop request
88 if ( EFI_ERROR ( Status
)) {
90 "User stop request!\r\n" ));
94 // Return the check status
101 Accept a socket connection
103 @retval EFI_SUCCESS The application is running normally
104 @retval EFI_NOT_STARTED Error with the listen socket
105 @retval Other The user stopped the application
118 Status
= EFI_DEVICE_ERROR
;
121 // Bind to the local address
123 SocketStatus
= bind ( ListenSocket
,
124 (struct sockaddr
*) &LocalAddress
,
125 LocalAddress
.sin6_len
);
126 if ( 0 == SocketStatus
) {
128 // Start listening on the local socket
130 SocketStatus
= listen ( ListenSocket
, 5 );
131 if ( 0 == SocketStatus
) {
133 // Local socket in the listen state
135 Status
= EFI_SUCCESS
;
141 PollFd
[ Index
].fd
= ListenSocket
;
142 PollFd
[ Index
].events
= POLLRDNORM
| POLLHUP
;
143 PollFd
[ Index
].revents
= 0;
144 ZeroMem ( &Port
[ Index
], sizeof ( Port
[ Index
]));
149 // Return the operation status
158 @retval EFI_SUCCESS The application is running normally
159 @retval Other The user stopped the application
169 // Determine if the socket is open
171 Status
= EFI_DEVICE_ERROR
;
172 if ( -1 != ListenSocket
) {
174 // Attempt to close the socket
176 CloseStatus
= close ( ListenSocket
);
177 if ( 0 == CloseStatus
) {
179 "0x%08x: Socket closed\r\n",
182 Status
= EFI_SUCCESS
;
185 DEBUG (( DEBUG_ERROR
,
186 "ERROR: Failed to close socket, errno: %d\r\n",
192 // Return the operation status
201 @param [in] Family Network family, AF_INET or AF_INET6
203 @retval EFI_SUCCESS The application is running normally
204 @retval Other The user stopped the application
214 // Get the port number
216 ZeroMem ( &LocalAddress
, sizeof ( LocalAddress
));
217 LocalAddress
.sin6_len
= sizeof ( LocalAddress
);
218 LocalAddress
.sin6_family
= Family
;
219 LocalAddress
.sin6_port
= htons ( PcdGet16 ( DataSource_Port
));
222 // Loop creating the socket
225 "Creating the socket\r\n" ));
228 // Check for user stop request
230 Status
= ControlCCheck ( );
231 if ( !EFI_ERROR ( Status
)) {
233 // Attempt to create the socket
235 ListenSocket
= socket ( LocalAddress
.sin6_family
,
238 if ( -1 != ListenSocket
) {
240 "0x%08x: Socket created\r\n",
244 Status
= EFI_NOT_STARTED
;
249 // Return the operation status
256 Poll the socket for more work
258 @retval EFI_SUCCESS The application is running normally
259 @retval EFI_NOT_STARTED Listen socket error
260 @retval Other The user stopped the application
266 BOOLEAN bRemoveSocket
;
267 BOOLEAN bListenError
;
268 size_t BytesReceived
;
274 socklen_t LengthInBytes
;
275 struct sockaddr_in
* pPortIpAddress4
;
276 struct sockaddr_in6
* pPortIpAddress6
;
277 struct sockaddr_in
* pRemoteAddress4
;
278 struct sockaddr_in6
* pRemoteAddress6
;
279 struct sockaddr_in6 RemoteAddress
;
285 // Check for control-C
287 pRemoteAddress4
= (struct sockaddr_in
*)&RemoteAddress
;
288 pRemoteAddress6
= (struct sockaddr_in6
*)&RemoteAddress
;
289 bListenError
= FALSE
;
290 Status
= ControlCCheck ( );
291 if ( !EFI_ERROR ( Status
)) {
295 FdCount
= poll ( &PollFd
[0],
298 if ( -1 == FdCount
) {
302 DEBUG (( DEBUG_ERROR
,
303 "ERROR - Poll error, errno: %d\r\n",
305 Status
= EFI_DEVICE_ERROR
;
309 // Process the poll output
313 bRemoveSocket
= FALSE
;
316 // Account for this descriptor
318 pPortIpAddress4
= (struct sockaddr_in
*)&Port
[ Index
].IpAddress
;
319 pPortIpAddress6
= (struct sockaddr_in6
*)&Port
[ Index
].IpAddress
;
320 if ( 0 != PollFd
[ Index
].revents
) {
325 // Check for a broken connection
327 if ( 0 != ( PollFd
[ Index
].revents
& POLLHUP
)) {
328 bRemoveSocket
= TRUE
;
329 if ( ListenSocket
== PollFd
[ Index
].fd
) {
331 DEBUG (( DEBUG_ERROR
,
332 "ERROR - Network closed on listen socket, errno: %d\r\n",
336 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
337 DEBUG (( DEBUG_ERROR
,
338 "ERROR - Network closed on socket %d.%d.%d.%d:%d, errno: %d\r\n",
339 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
340 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
341 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
342 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
343 htons ( pPortIpAddress4
->sin_port
),
347 DEBUG (( DEBUG_ERROR
,
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",
349 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
350 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
351 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
352 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
353 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
354 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
355 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
356 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
357 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
358 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
359 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
360 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
361 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
362 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
363 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
364 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
365 htons ( pPortIpAddress6
->sin6_port
),
372 CloseStatus
= close ( PollFd
[ Index
].fd
);
373 if ( 0 == CloseStatus
) {
374 bRemoveSocket
= TRUE
;
375 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
377 "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
379 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
380 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
381 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
382 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
383 htons ( pPortIpAddress4
->sin_port
)));
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",
389 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
390 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
391 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
392 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
393 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
394 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
395 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
396 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
397 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
398 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
399 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
400 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
401 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
402 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
403 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
404 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
405 htons ( pPortIpAddress6
->sin6_port
)));
409 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
410 DEBUG (( DEBUG_ERROR
,
411 "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
413 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
414 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
415 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
416 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
417 htons ( pPortIpAddress4
->sin_port
),
421 DEBUG (( DEBUG_ERROR
,
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",
424 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
425 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
426 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
427 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
428 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
429 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
430 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
431 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
432 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
433 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
434 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
435 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
436 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
437 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
438 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
439 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
440 htons ( pPortIpAddress6
->sin6_port
),
448 // Check for a connection or read data
450 if ( 0 != ( PollFd
[ Index
].revents
& POLLRDNORM
)) {
452 // Check for a connection
454 if ( ListenSocket
== PollFd
[ Index
].fd
) {
456 // Another client connection was received
458 LengthInBytes
= sizeof ( RemoteAddress
);
459 Socket
= accept ( ListenSocket
,
460 (struct sockaddr
*) &RemoteAddress
,
462 if ( -1 == Socket
) {
464 // Listen socket error
467 bRemoveSocket
= TRUE
;
468 DEBUG (( DEBUG_ERROR
,
469 "ERROR - Listen socket failure, errno: %d\r\n",
474 // Determine if there is room for this connection
476 if (( MAX_CONNECTIONS
<= MaxPort
)
477 || ((( MAX_CONNECTIONS
- 1 ) == MaxPort
) && ( -1 == ListenSocket
))) {
479 // Display the connection
481 if ( AF_INET
== pRemoteAddress4
->sin_family
) {
482 Print ( L
"Rejecting connection to remote system %d.%d.%d.%d:%d\r\n",
483 pRemoteAddress4
->sin_addr
.s_addr
& 0xff,
484 ( pRemoteAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
485 ( pRemoteAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
486 ( pRemoteAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
487 htons ( pRemoteAddress4
->sin_port
));
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",
491 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
492 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
493 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
494 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
495 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
496 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
497 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
498 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
499 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
500 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
501 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
502 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
503 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
504 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
505 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
506 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
507 htons ( pRemoteAddress6
->sin6_port
));
511 // No room for this connection
512 // Close the connection
514 CloseStatus
= close ( Socket
);
515 if ( 0 == CloseStatus
) {
516 bRemoveSocket
= TRUE
;
517 if ( AF_INET
== pRemoteAddress4
->sin_family
) {
519 "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
521 pRemoteAddress4
->sin_addr
.s_addr
& 0xff,
522 ( pRemoteAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
523 ( pRemoteAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
524 ( pRemoteAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
525 htons ( pRemoteAddress4
->sin_port
)));
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",
531 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
532 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
533 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
534 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
535 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
536 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
537 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
538 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
539 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
540 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
541 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
542 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
543 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
544 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
545 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
546 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
547 htons ( pRemoteAddress6
->sin6_port
)));
551 DEBUG (( DEBUG_ERROR
,
552 "ERROR - Failed to close socket 0x%08x, errno: %d\r\n",
558 // Keep the application running
559 // No issue with the listen socket
561 Status
= EFI_SUCCESS
;
565 // Display the connection
567 if ( AF_INET
== pRemoteAddress4
->sin_family
) {
568 Print ( L
"Connected to remote system %d.%d.%d.%d:%d\r\n",
569 pRemoteAddress4
->sin_addr
.s_addr
& 0xff,
570 ( pRemoteAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
571 ( pRemoteAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
572 ( pRemoteAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
573 htons ( pRemoteAddress4
->sin_port
));
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",
577 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
578 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
579 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
580 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
581 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
582 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
583 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
584 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
585 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
586 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
587 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
588 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
589 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
590 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
591 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
592 pRemoteAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
593 htons ( pRemoteAddress6
->sin6_port
));
597 // Allocate the client connection
600 ZeroMem ( &Port
[ Index
], sizeof ( Port
[ Index
]));
601 CopyMem ( pPortIpAddress6
, pRemoteAddress6
, sizeof ( *pRemoteAddress6
));
602 PollFd
[ Index
].fd
= Socket
;
603 PollFd
[ Index
].events
= POLLRDNORM
| POLLHUP
;
604 PollFd
[ Index
].revents
= 0;
612 BytesReceived
= read ( PollFd
[ Index
].fd
,
615 if ( 0 < BytesReceived
) {
617 // Display the amount of data received
619 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
621 "0x%08x: Socket received 0x%08x bytes from %d.%d.%d.%d:%d\r\n",
624 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
625 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
626 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
627 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
628 htons ( pPortIpAddress4
->sin_port
)));
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",
635 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
636 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
637 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
638 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
639 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
640 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
641 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
642 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
643 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
644 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
645 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
646 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
647 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
648 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
649 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
650 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
651 htons ( pPortIpAddress6
->sin6_port
)));
655 // Synchronize with the TimerCallback routine
657 TplPrevious
= gBS
->RaiseTPL ( TPL_DATASINK
);
660 // Account for the data received
662 Port
[ Index
].BytesTotal
+= BytesReceived
;
665 // Release the synchronization with the TimerCallback routine
667 gBS
->RestoreTPL ( TplPrevious
);
669 else if ( -1 == BytesReceived
) {
673 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
675 "ERROR - Receive failure for %d.%d.%d.%d:%d, errno: %d\r\n",
676 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
677 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
678 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
679 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
680 htons ( pPortIpAddress4
->sin_port
),
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",
686 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
687 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
688 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
689 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
690 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
691 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
692 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
693 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
694 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
695 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
696 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
697 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
698 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
699 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
700 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
701 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
702 htons ( pPortIpAddress6
->sin6_port
),
705 CloseStatus
= close ( PollFd
[ Index
].fd
);
706 if ( 0 == CloseStatus
) {
707 bRemoveSocket
= TRUE
;
708 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
710 "0x%08x: Socket closed for %d.%d.%d.%d:%d\r\n",
712 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
713 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
714 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
715 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
716 htons ( pPortIpAddress4
->sin_port
)));
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",
722 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
723 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
724 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
725 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
726 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
727 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
728 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
729 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
730 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
731 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
732 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
733 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
734 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
735 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
736 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
737 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
738 htons ( pPortIpAddress6
->sin6_port
)));
742 if ( AF_INET
== pPortIpAddress4
->sin_family
) {
743 DEBUG (( DEBUG_ERROR
,
744 "ERROR - Failed to close socket 0x%08x for %d.%d.%d.%d:%d, errno: %d\r\n",
746 pPortIpAddress4
->sin_addr
.s_addr
& 0xff,
747 ( pPortIpAddress4
->sin_addr
.s_addr
>> 8 ) & 0xff,
748 ( pPortIpAddress4
->sin_addr
.s_addr
>> 16 ) & 0xff,
749 ( pPortIpAddress4
->sin_addr
.s_addr
>> 24 ) & 0xff,
750 htons ( pPortIpAddress4
->sin_port
),
754 DEBUG (( DEBUG_ERROR
,
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",
757 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 0 ],
758 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 1 ],
759 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 2 ],
760 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 3 ],
761 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 4 ],
762 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 5 ],
763 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 6 ],
764 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 7 ],
765 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 8 ],
766 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 9 ],
767 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 10 ],
768 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 11 ],
769 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 12 ],
770 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 13 ],
771 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 14 ],
772 pPortIpAddress6
->sin6_addr
.__u6_addr
.__u6_addr8
[ 15 ],
773 htons ( pPortIpAddress6
->sin6_port
),
780 // Keep the application running
781 // No issue with the listen socket
783 Status
= EFI_SUCCESS
;
788 // Remove the socket if necessary
790 if ( bRemoveSocket
) {
792 "0x%08x: Socket removed from polling\r\n",
793 PollFd
[ Index
].fd
));
795 for ( Entry
= Index
+ 1; MaxPort
>= Entry
; Entry
++ ) {
796 EntryPrevious
= Entry
;
797 CopyMem ( &Port
[ EntryPrevious
],
799 sizeof ( Port
[ Entry
]));
800 PollFd
[ EntryPrevious
].events
= PollFd
[ Entry
].events
;
801 PollFd
[ EntryPrevious
].fd
= PollFd
[ Entry
].fd
;
802 PollFd
[ EntryPrevious
].revents
= PollFd
[ Entry
].revents
;
804 PollFd
[ MaxPort
].fd
= -1;
809 // Account for this socket
817 // Return the listen failure if necessary
819 if (( !EFI_ERROR ( Status
)) && bListenError
) {
820 Status
= EFI_NOT_STARTED
;
824 // Return the poll status
831 Handle the timer callback
833 @param [in] Event Event that caused this callback
834 @param [in] pContext Context for this routine
844 UINT64 BitsPerSecond
;
845 UINT64 BytesReceived
;
851 // Notify the other code of the timer tick
856 // Walk the list of ports
858 for ( Index
= 0; MaxPort
> Index
; Index
++ ) {
860 // Determine if any data was received
862 BytesReceived
= Port
[ Index
].BytesTotal
;
863 if (( ListenSocket
!= PollFd
[ Index
].fd
)
864 && ( 0 != BytesReceived
)) {
866 // Update the received data samples
868 Port
[ Index
].BytesTotal
= 0;
869 Port
[ Index
].BytesReceived
[ Port
[ Index
].In
] = BytesReceived
;
870 Port
[ Index
].In
+= 1;
871 if ( DATA_SAMPLES
<= Port
[ Index
].In
) {
872 Port
[ Index
].In
= 0;
876 // Separate the samples
878 if ( DATA_SAMPLES
== Port
[ Index
].Samples
) {
879 Print ( L
"---------- Stable average ----------\r\n" );
881 Port
[ Index
].Samples
+= 1;
884 // Compute the data rate
887 for ( Count
= 0; DATA_SAMPLES
> Count
; Count
++ )
889 TotalBytes
+= Port
[ Index
].BytesReceived
[ Count
];
891 Average
= (UINT32
)RShiftU64 ( TotalBytes
, DATA_SAMPLE_SHIFT
);
892 BitsPerSecond
= Average
* 8;
895 // Display the data rate
897 if (( RANGE_SWITCH
>> 10 ) > Average
) {
898 Print ( L
"Ave: %d Bytes/Sec, %Ld Bits/sec\r\n",
903 BitsPerSecond
/= 1000;
904 if ( RANGE_SWITCH
> Average
) {
905 Print ( L
"Ave: %d.%03d KiBytes/Sec, %Ld KBits/sec\r\n",
907 (( Average
& 0x3ff ) * 1000 ) >> 10,
911 BitsPerSecond
/= 1000;
913 if ( RANGE_SWITCH
> Average
) {
914 Print ( L
"Ave: %d.%03d MiBytes/Sec, %Ld MBits/sec\r\n",
916 (( Average
& 0x3ff ) * 1000 ) >> 10,
920 BitsPerSecond
/= 1000;
922 if ( RANGE_SWITCH
> Average
) {
923 Print ( L
"Ave: %d.%03d GiBytes/Sec, %Ld GBits/sec\r\n",
925 (( Average
& 0x3ff ) * 1000 ) >> 10,
929 BitsPerSecond
/= 1000;
931 if ( RANGE_SWITCH
> Average
) {
932 Print ( L
"Ave: %d.%03d TiBytes/Sec, %Ld TBits/sec\r\n",
934 (( Average
& 0x3ff ) * 1000 ) >> 10,
938 BitsPerSecond
/= 1000;
940 Print ( L
"Ave: %d.%03d PiBytes/Sec, %Ld PBits/sec\r\n",
942 (( Average
& 0x3ff ) * 1000 ) >> 10,
957 @retval EFI_SUCCESS The timer was successfully created
958 @retval Other Timer initialization failed
969 Status
= gBS
->CreateEvent ( EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
974 if ( EFI_ERROR ( Status
)) {
975 DEBUG (( DEBUG_ERROR
,
976 "ERROR - Failed to allocate the timer event, Status: %r\r\n",
981 "0x%08x: Timer created\r\n",
986 // Return the operation status
995 @retval EFI_SUCCESS The timer was stopped successfully
996 @retval Other The timer failed to stop
1007 Status
= EFI_SUCCESS
;
1010 // Determine if the timer is running
1012 if ( bTimerRunning
) {
1016 Status
= gBS
->SetTimer ( pTimer
,
1019 if ( EFI_ERROR ( Status
)) {
1020 DEBUG (( DEBUG_ERROR
,
1021 "ERROR - Failed to stop the timer, Status: %r\r\n",
1026 // Timer timer is now stopped
1028 bTimerRunning
= FALSE
;
1029 DEBUG (( DEBUG_INFO
,
1030 "0x%08x: Timer stopped\r\n",
1036 // Return the operation status
1045 @param [in] Milliseconds The number of milliseconds between timer callbacks
1047 @retval EFI_SUCCESS The timer was successfully created
1048 @retval Other Timer initialization failed
1059 // Stop the timer if necessary
1061 Status
= EFI_SUCCESS
;
1062 if ( bTimerRunning
) {
1063 Status
= TimerStop ( );
1065 if ( !EFI_ERROR ( Status
)) {
1067 // Compute the new delay
1069 TimeDelay
= Milliseconds
;
1070 TimeDelay
*= 1000 * 10;
1075 Status
= gBS
->SetTimer ( pTimer
,
1078 if ( EFI_ERROR ( Status
)) {
1079 DEBUG (( DEBUG_ERROR
,
1080 "ERROR - Failed to start the timer, Status: %r\r\n",
1085 // The timer is now running
1087 bTimerRunning
= TRUE
;
1088 DEBUG (( DEBUG_INFO
,
1089 "0x%08x: Timer running\r\n",
1095 // Return the operation status
1104 @retval EFI_SUCCESS The timer was destroyed successfully
1105 @retval Other Failed to destroy the timer
1116 Status
= EFI_SUCCESS
;
1119 // Determine if the timer is running
1121 if ( bTimerRunning
) {
1125 Status
= TimerStop ( );
1127 if (( !EFI_ERROR ( Status
)) && ( NULL
!= pTimer
)) {
1129 // Done with this timer
1131 Status
= gBS
->CloseEvent ( pTimer
);
1132 if ( EFI_ERROR ( Status
)) {
1133 DEBUG (( DEBUG_ERROR
,
1134 "ERROR - Failed to free the timer event, Status: %r\r\n",
1138 DEBUG (( DEBUG_INFO
,
1139 "0x%08x: Timer Destroyed\r\n",
1146 // Return the operation status
1153 Receive data from the DataSource program to test a network's bandwidth.
1155 @param [in] Argc The number of arguments
1156 @param [in] Argv The argument value array
1158 @retval 0 The application exited normally.
1159 @retval Other An error occurred.
1170 DEBUG (( DEBUG_INFO
,
1171 "DataSink starting\r\n" ));
1174 // Determine the family to use
1176 Family
= ( 1 < Argc
) ? AF_INET6
: AF_INET
;
1179 // Use for/break instead of goto
1186 Status
= TimerCreate ( );
1187 if ( EFI_ERROR ( Status
)) {
1192 // Start a timer to perform network polling and display updates
1194 Status
= TimerStart ( 1 * 1000 );
1195 if ( EFI_ERROR ( Status
)) {
1200 // Loop forever waiting for abuse
1206 // Complete any client operations
1208 Status
= SocketPoll ( );
1209 if ( EFI_ERROR ( Status
)) {
1220 if ( EFI_ERROR ( Status
)) {
1228 // Wait for the network layer to initialize
1230 Status
= SocketNew ( Family
);
1231 if ( EFI_ERROR ( Status
)) {
1236 // Wait for the remote network application to start
1238 Status
= SocketAccept ( );
1239 if ( EFI_NOT_STARTED
== Status
) {
1240 Status
= SocketClose ( );
1243 else if ( EFI_SUCCESS
!= Status
) {
1251 // Receive data until the connection breaks
1254 Status
= SocketPoll ( );
1255 } while ( !EFI_ERROR ( Status
));
1258 // Done with the socket
1260 Status
= SocketClose ( );
1261 } while ( !EFI_ERROR ( Status
));
1264 // Close the socket if necessary
1275 // Stop the timer if necessary
1281 // Return the operation status
1283 DEBUG (( DEBUG_INFO
,
1284 "DataSink exiting, Status: %r\r\n",