3 HTTP processing for the web server.
5 Copyright (c) 2011-2012, Intel Corporation. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <WebServer.h>
14 Get a UTF-8 character from the buffer
16 @param [in] pData The address of the buffer containing the character
17 @param [out] ppData The address to receive the next character address
19 @return The character value
34 // Verify that there is some data left
36 if ( NULL
== pData
) {
45 // Get the first portion of the character
52 // Append the rest of the character
54 if ( 0 != ( Control
& 0x80 )) {
55 while ( 0 != ( Control
& 0x40 )) {
60 Data
= *pData
++ & 0x3f;
61 if ( 0x80 != ( Data
& 0xc0 )) {
69 Character
|= Data
& 0x3f;
75 // Return the next character location and the character
83 Transmit a portion of the HTTP response
85 @param [in] SocketFD The socket's file descriptor to add to the list.
86 @param [in] pPort The WSDT_PORT structure address
88 @retval EFI_SUCCESS The request was successfully processed
106 Status
= EFI_SUCCESS
;
107 pBuffer
= &pPort
->TxBuffer
[0];
110 // Attempt to send the data
112 LengthInBytes
= send ( SocketFD
,
116 if ( -1 != LengthInBytes
) {
118 // Account for the data sent
120 pBuffer
+= LengthInBytes
;
121 pPort
->TxBytes
-= LengthInBytes
;
127 Status
= EFI_DEVICE_ERROR
;
130 } while ( 0 < pPort
->TxBytes
);
133 // Return the operation status
135 DBG_EXIT_STATUS ( Status
);
141 Convert the ANSI character to lower case
143 @param [in] Character The character to convert to lower case.
145 @return The lower case character
154 // Determine if the character is upper case
156 if (( 'A' <= Character
) && ( 'Z' >= Character
)) {
157 Character
+= 'a' - 'A';
161 // Return the lower case value of the character
168 Match a Unicode string against a UTF-8 string
170 @param [in] pString A zero terminated Unicode string
171 @param [in] pData A zero terminated UTF-8 string
172 @param [in] bIgnoreCase TRUE if case is to be ignored
174 @return The difference between the last two characters tested.
175 Returns -1 for error.
182 IN BOOLEAN bIgnoreCase
191 // Get the character from the comparison string
193 Character1
= *pString
++;
196 // Convert the character to lower case
199 Character1
= HttpLowerCase ( Character1
);
203 // Get the character from the request
205 Character2
= HttpCharGet ( pData
, &pData
);
206 if ( NULL
== pData
) {
208 // Error getting character
215 // Convert the character to lower case
218 Character2
= HttpLowerCase ( Character2
);
222 // Compare the characters
224 Difference
= Character1
- Character2
;
225 if ( 0 != Difference
) {
228 } while ( 0 != Character1
);
231 // Return the difference
238 Buffer the HTTP page header
240 @param [in] SocketFD The socket's file descriptor to add to the list.
241 @param [in] pPort The WSDT_PORT structure address
242 @param [in] pTitle A zero terminated Unicode title string
244 @retval EFI_SUCCESS The request was successfully processed
250 IN WSDT_PORT
* pPort
,
251 IN CONST CHAR16
* pTitle
259 // Build the page header
262 Status
= HttpSendAnsiString ( SocketFD
,
267 "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
268 "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );
269 if ( EFI_ERROR ( Status
)) {
272 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "<html lang=\"en-US\">\r\n" );
273 if ( EFI_ERROR ( Status
)) {
276 if ( NULL
!= pTitle
) {
277 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <head>\r\n" );
278 if ( EFI_ERROR ( Status
)) {
281 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <title>" );
282 if ( EFI_ERROR ( Status
)) {
285 Status
= HttpSendUnicodeString ( SocketFD
, pPort
, pTitle
);
286 if ( EFI_ERROR ( Status
)) {
289 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</title>\r\n" );
290 if ( EFI_ERROR ( Status
)) {
293 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </head>\r\n" );
294 if ( EFI_ERROR ( Status
)) {
298 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <body>\r\n" );
303 // Return the operation status
305 DBG_EXIT_STATUS ( Status
);
311 Respond with an error indicating that the page was not found
313 @param [in] SocketFD The socket's file descriptor to add to the list.
314 @param [in] pPort The WSDT_PORT structure address
315 @param [out] pbDone Address to receive the request completion status
317 @retval EFI_SUCCESS The request was successfully processed
323 IN WSDT_PORT
* pPort
,
332 // Send the page not found
336 // Send the page header
338 Status
= HttpPageHeader ( SocketFD
, pPort
, L
"404 Not found" );
339 if ( EFI_ERROR ( Status
)) {
344 // Send the page body
346 Status
= HttpSendAnsiString ( SocketFD
,
348 "ERROR <b>404</b><br />"
349 "Requested page is not available\r\n" );
350 if ( EFI_ERROR ( Status
)) {
355 // Send the page trailer
357 Status
= HttpPageTrailer ( SocketFD
, pPort
, pbDone
);
362 // Return the operation status
364 DBG_EXIT_STATUS ( Status
);
370 Buffer and send the HTTP page trailer
372 @param [in] SocketFD The socket's file descriptor to add to the list.
373 @param [in] pPort The WSDT_PORT structure address
374 @param [out] pbDone Address to receive the request completion status
376 @retval EFI_SUCCESS The request was successfully processed
382 IN WSDT_PORT
* pPort
,
388 socklen_t LengthInBytes
;
389 struct sockaddr_in6 LocalAddress
;
390 struct sockaddr_in6 RemoteAddress
;
395 // Build the page header
398 LengthInBytes
= sizeof ( LocalAddress
);
399 RetVal
= getsockname ( SocketFD
, (struct sockaddr
*)&LocalAddress
, &LengthInBytes
);
401 LengthInBytes
= sizeof ( LocalAddress
);
402 RetVal
= getpeername ( SocketFD
, (struct sockaddr
*)&RemoteAddress
, &LengthInBytes
);
405 // Seperate the body from the trailer
407 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <hr>\r\n<code>" );
408 if ( EFI_ERROR ( Status
)) {
413 // Display the system addresses and the page transfer direction
415 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &LocalAddress
);
416 if ( EFI_ERROR ( Status
)) {
419 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " --> " );
420 if ( EFI_ERROR ( Status
)) {
423 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &RemoteAddress
);
424 if ( EFI_ERROR ( Status
)) {
427 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</code>\r\n" );
428 if ( EFI_ERROR ( Status
)) {
435 // Terminate the page
437 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </body>\r\n" );
438 if ( EFI_ERROR ( Status
)) {
441 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </html>\r\n" );
442 if ( EFI_ERROR ( Status
)) {
447 // Send the page trailer
449 Status
= HttpFlush ( SocketFD
, pPort
);
450 if ( EFI_ERROR ( Status
)) {
455 // Mark the page as complete
462 // Return the operation status
464 DBG_EXIT_STATUS ( Status
);
470 Replace a space with a zero
472 @param [in] pData The request buffer address
473 @param [in] pEnd End of buffer address
475 @return The next character location
488 while ( pEnd
> pData
) {
490 // Get the character from the request
492 Character
= HttpCharGet ( pData
, &pData
);
493 if ( ' ' == Character
) {
500 // Replace the space character with zero
502 ZeroMem ( pSpace
, pData
- pSpace
);
505 // Return the next character location
512 Process an HTTP request
514 @param [in] SocketFD The socket's file descriptor to add to the list.
515 @param [in] pPort The WSDT_PORT structure address
516 @param [out] pbDone Address to receive the request completion status
518 @retval EFI_SUCCESS The request was successfully processed
524 IN WSDT_PORT
* pPort
,
530 CONST DT_PAGE
* pPage
;
531 CONST DT_PAGE
* pPageEnd
;
540 // Assume the request is not finished
543 Status
= EFI_SUCCESS
;
547 // Attempt to parse the command
549 pData
= &pPort
->Request
[0];
550 pEnd
= &pData
[ pPort
->RequestLength
];
552 pWebPage
= HttpReplaceSpace ( pVerb
, pEnd
);
553 if ( pEnd
<= pWebPage
) {
556 pVersion
= HttpReplaceSpace ( pWebPage
, pEnd
);
557 if ( pEnd
<= pVersion
) {
562 // Validate the request
564 if ( 0 != HttpMatch ( L
"GET", pVerb
, TRUE
)) {
566 // Invalid request type
568 DEBUG (( DEBUG_REQUEST
,
569 "HTTP: Invalid verb\r\n" ));
570 Status
= EFI_NOT_FOUND
;
575 // Walk the page table
577 pPage
= &mPageList
[0];
578 pPageEnd
= &pPage
[ mPageCount
];
579 while ( pPageEnd
> pPage
) {
581 // Determine if the page was located
583 if ( 0 == HttpMatch ( pPage
->pPageName
, pWebPage
, FALSE
)) {
592 if ( pPageEnd
<= pPage
) {
594 // The page was not found
596 DEBUG (( DEBUG_REQUEST
,
597 "HTTP: Page not found in page table\r\n" ));
598 Status
= EFI_NOT_FOUND
;
603 // Respond with the page contents
605 Status
= pPage
->pfnResponse ( SocketFD
, pPort
, pbDone
);
610 // Return page not found if necessary
612 if ( EFI_NOT_FOUND
== Status
) {
613 Status
= HttpPageNotFound ( SocketFD
, pPort
, pbDone
);
617 // Return the operation status
619 DBG_EXIT_STATUS ( Status
);
625 Buffer data for sending
627 @param [in] SocketFD The socket's file descriptor to add to the list.
628 @param [in] pPort The WSDT_PORT structure address
629 @param [in] LengthInBytes Length of valid data in the buffer
630 @param [in] pBuffer Buffer of data to send
632 @retval EFI_SUCCESS The request was successfully processed
638 IN WSDT_PORT
* pPort
,
639 IN
size_t LengthInBytes
,
640 IN CONST UINT8
* pBuffer
650 Status
= EFI_SUCCESS
;
653 // Determine how much data fits into the buffer
655 MaxBytes
= sizeof ( pPort
->TxBuffer
);
656 DataBytes
= MaxBytes
- pPort
->TxBytes
;
657 if ( DataBytes
> LengthInBytes
) {
658 DataBytes
= LengthInBytes
;
662 // Copy the data into the buffer
664 CopyMem ( &pPort
->TxBuffer
[ pPort
->TxBytes
],
669 // Account for the data copied
671 pPort
->TxBytes
+= DataBytes
;
672 LengthInBytes
-= DataBytes
;
675 // Transmit the buffer if it is full
677 if ( MaxBytes
<= pPort
->TxBytes
) {
678 Status
= HttpFlush ( SocketFD
, pPort
);
680 } while (( EFI_SUCCESS
== Status
) && ( 0 < LengthInBytes
));
683 // Return the operation status
692 @param [in] SocketFD The socket's file descriptor to add to the list.
693 @param [in] pPort The WSDT_PORT structure address
694 @param [in] pString A zero terminated Unicode string
696 @retval EFI_SUCCESS The request was successfully processed
702 IN WSDT_PORT
* pPort
,
703 IN CONST
char * pString
712 Status
= EFI_SUCCESS
;
715 // Walk the characters in he string
718 while ( 0 != *pData
) {
725 Status
= HttpSend ( SocketFD
,
728 (CONST UINT8
*)pString
);
731 // Return the operation status
740 @param [in] SocketFD The socket's file descriptor to add to the list.
741 @param [in] pPort The WSDT_PORT structure address
742 @param [in] Data The data byte to send
744 @retval EFI_SUCCESS The request was successfully processed
750 IN WSDT_PORT
* pPort
,
757 // Send the data byte
759 Status
= HttpSend ( SocketFD
,
765 // Return the operation status
774 @param [in] SocketFD The socket's file descriptor to add to the list.
775 @param [in] pPort The WSDT_PORT structure address
776 @param [in] Character Character to display
777 @param [in] pReplacement Replacement character string
779 @retval EFI_SUCCESS The request was successfully processed
785 IN WSDT_PORT
* pPort
,
787 IN CHAR8
* pReplacement
793 // Determine if this is a printable character
795 if (( 0x20 <= Character
) && ( 0x7f > Character
)) {
796 if ( '<' == Character
) {
798 // Replace with HTML equivalent
800 Status
= HttpSendAnsiString ( SocketFD
,
804 else if ( '>' == Character
) {
806 // Replace with HTML equivalent
808 Status
= HttpSendAnsiString ( SocketFD
,
812 else if ( '&' == Character
) {
814 // Replace with HTML equivalent
816 Status
= HttpSendAnsiString ( SocketFD
,
820 else if ( '\"' == Character
) {
822 // Replace with HTML equivalent
824 Status
= HttpSendAnsiString ( SocketFD
,
830 // Display the character
832 Status
= HttpSendByte ( SocketFD
,
839 // Not a displayable character
841 Status
= HttpSendAnsiString ( SocketFD
,
847 // Return the operation status
856 @param [in] SocketFD The socket's file descriptor to add to the list.
857 @param [in] pPort The WSDT_PORT structure address
858 @param [in] ByteCount The number of bytes to display
859 @param [in] pData Address of the byte array
861 @retval EFI_SUCCESS The request was successfully processed
867 IN WSDT_PORT
* pPort
,
869 IN CONST UINT8
* pData
876 CONST UINT8
* pDataEnd
;
882 // Use for/break instead of goto
886 // Start the field value
888 Status
= HttpSendAnsiString ( SocketFD
,
891 if ( EFI_ERROR ( Status
)) {
896 // Walk the bytes to be displayed
898 pEnd
= &pData
[ ByteCount
];
899 while ( pEnd
> pData
) {
901 // Display the address
903 Status
= HttpSendHexBits ( SocketFD
,
905 sizeof ( pData
) * 8,
906 (UINT64
)(UINTN
)pData
);
907 if ( EFI_ERROR ( Status
)) {
912 // Separate the address and data
914 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
915 if ( EFI_ERROR ( Status
)) {
920 // Position the starting data correctly
922 InitialSpaces
= (UINTN
)pData
;
923 InitialSpaces
&= BYTES_ON_A_LINE
- 1;
924 for ( Index
= SPACES_ADDRESS_TO_DATA
925 + (( 2 + SPACES_BETWEEN_BYTES
)
927 0 < Index
; Index
-- ) {
928 Status
= HttpSendAnsiString ( SocketFD
,
931 if ( EFI_ERROR ( Status
)) {
935 if ( EFI_ERROR ( Status
)) {
942 BytesToDisplay
= pEnd
- pData
;
943 if (( BYTES_ON_A_LINE
- InitialSpaces
) < BytesToDisplay
) {
944 BytesToDisplay
= BYTES_ON_A_LINE
- InitialSpaces
;
946 pDataEnd
= &pData
[ BytesToDisplay
];
948 while ( pDataEnd
> pTemp
) {
949 Status
= HttpSendHexBits ( SocketFD
,
953 if ( EFI_ERROR ( Status
)) {
958 // Separate the data bytes
960 for ( Index
= SPACES_BETWEEN_BYTES
; 0 < Index
; Index
-- ) {
961 Status
= HttpSendAnsiString ( SocketFD
,
964 if ( EFI_ERROR ( Status
)) {
968 if ( EFI_ERROR ( Status
)) {
972 if ( EFI_ERROR ( Status
)) {
977 // Separate the data from the ASCII display
979 for ( Index
= (( 2 + SPACES_BETWEEN_BYTES
)
980 * ( BYTES_ON_A_LINE
- BytesToDisplay
- InitialSpaces
))
981 - SPACES_BETWEEN_BYTES
982 + SPACES_DATA_TO_ASCII
984 0 < Index
; Index
-- ) {
985 Status
= HttpSendAnsiString ( SocketFD
,
988 if ( EFI_ERROR ( Status
)) {
992 if ( EFI_ERROR ( Status
)) {
997 // Display the ASCII data
999 while ( pDataEnd
> pData
) {
1000 Character
= *pData
++;
1001 Status
= HttpSendCharacter ( SocketFD
,
1005 if ( EFI_ERROR ( Status
)) {
1009 if ( EFI_ERROR ( Status
)) {
1014 // Terminate the line
1016 Status
= HttpSendAnsiString ( SocketFD
,
1019 if ( EFI_ERROR ( Status
)) {
1025 // Terminate the field value and row
1027 Status
= HttpSendAnsiString ( SocketFD
,
1034 // Return the operation status
1041 Display a row containing a GUID value
1043 @param [in] SocketFD The socket's file descriptor to add to the list.
1044 @param [in] pPort The WSDT_PORT structure address
1045 @param [in] pGuid Address of the GUID to display
1047 @retval EFI_SUCCESS The request was successfully processed
1053 IN WSDT_PORT
* pPort
,
1054 IN CONST EFI_GUID
* pGuid
1063 // Use for/break instead of goto
1067 // Display the GUID in a form found in the code
1069 // E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
1073 // Display the first 32 bits
1075 Status
= HttpSendAnsiString ( SocketFD
,
1078 if ( EFI_ERROR ( Status
)) {
1081 Status
= HttpSendHexBits ( SocketFD
,
1085 if ( EFI_ERROR ( Status
)) {
1090 // Display the second 16 bits
1092 Status
= HttpSendAnsiString ( SocketFD
,
1095 if ( EFI_ERROR ( Status
)) {
1098 Status
= HttpSendHexBits ( SocketFD
,
1102 if ( EFI_ERROR ( Status
)) {
1107 // Display the thrid 16 bits
1109 Status
= HttpSendAnsiString ( SocketFD
,
1112 if ( EFI_ERROR ( Status
)) {
1115 Status
= HttpSendHexBits ( SocketFD
,
1119 if ( EFI_ERROR ( Status
)) {
1124 // Place the last 64 bits in braces
1126 Status
= HttpSendAnsiString ( SocketFD
,
1129 if ( EFI_ERROR ( Status
)) {
1132 for ( Index
= 0; 7 >= Index
; Index
++ ) {
1134 // Display the next 8 bits
1136 Status
= HttpSendHexBits ( SocketFD
,
1139 pGuid
->Data4
[ Index
]);
1140 if ( EFI_ERROR ( Status
)) {
1145 // Separate the bytes
1147 Status
= HttpSendAnsiString ( SocketFD
,
1149 ( 7 != Index
) ? ", 0x" : " }" );
1150 if ( EFI_ERROR ( Status
)) {
1158 // Return the operation status
1160 DBG_EXIT_STATUS ( Status
);
1166 Output a hex value to the HTML page
1168 @param [in] SocketFD Socket file descriptor
1169 @param [in] pPort The WSDT_PORT structure address
1170 @param [in] Bits Number of bits to display
1171 @param [in] Value Value to display
1173 @retval EFI_SUCCESS Successfully displayed the address
1178 IN WSDT_PORT
* pPort
,
1190 Status
= EFI_SUCCESS
;
1193 // Walk the list of divisors
1195 Shift
= (( Bits
+ 3 ) & ( ~3 )) - 4;
1196 while ( 0 <= Shift
) {
1198 // Determine the next digit
1200 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1201 if ( 10 <= Digit
) {
1202 Digit
+= 'a' - '0' - 10;
1206 // Display the digit
1208 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1209 if ( EFI_ERROR ( Status
)) {
1214 // Set the next shift
1220 // Return the operation status
1227 Output a hex value to the HTML page
1229 @param [in] SocketFD Socket file descriptor
1230 @param [in] pPort The WSDT_PORT structure address
1231 @param [in] Value Value to display
1233 @retval EFI_SUCCESS Successfully displayed the address
1238 IN WSDT_PORT
* pPort
,
1242 BOOLEAN bDisplayZeros
;
1250 Status
= EFI_SUCCESS
;
1253 // Walk the list of divisors
1255 bDisplayZeros
= FALSE
;
1259 // Determine the next digit
1261 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1262 if ( 10 <= Digit
) {
1263 Digit
+= 'a' - '0' - 10;
1267 // Suppress leading zeros
1269 if (( 0 != Digit
) || bDisplayZeros
|| ( 0 == Shift
)) {
1270 bDisplayZeros
= TRUE
;
1273 // Display the digit
1275 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1276 if ( EFI_ERROR ( Status
)) {
1282 // Set the next shift
1285 } while ( 0 <= Shift
);
1288 // Return the operation status
1295 Output an IP6 address value to the HTML page
1297 @param [in] SocketFD Socket file descriptor
1298 @param [in] pPort The WSDT_PORT structure address
1299 @param [in] Value Value to display
1300 @param [in] bFirstValue TRUE if first value
1301 @param [in] bLastValue TRUE if last value
1302 @param [in] bZeroSuppression TRUE while zeros are being suppressed
1303 @param [in] pbZeroSuppression Address to receive TRUE when zero suppression
1304 has started, use NULL if next colon value not
1307 @retval EFI_SUCCESS Successfully displayed the address
1312 IN WSDT_PORT
* pPort
,
1314 IN BOOLEAN bFirstValue
,
1315 IN BOOLEAN bLastValue
,
1316 IN BOOLEAN bZeroSuppression
,
1317 IN BOOLEAN
* pbZeroSuppression
1320 BOOLEAN bZeroSuppressionStarting
;
1325 // Use break instead of goto
1327 bZeroSuppressionStarting
= FALSE
;
1328 Status
= EFI_SUCCESS
;
1331 // Display the leading colon if necessary
1333 if ( bZeroSuppression
&& ( bLastValue
|| ( 0 != Value
))) {
1334 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1335 if ( EFI_ERROR ( Status
)) {
1341 // Skip over a series of zero values
1343 bZeroSuppressionStarting
= (BOOLEAN
)( 0 == Value
);
1344 if ( !bZeroSuppressionStarting
) {
1346 // Display the value
1348 Digit
= ( Value
>> 4 ) & 0xf;
1349 Status
= HttpSendHexValue ( SocketFD
,
1352 if ( EFI_ERROR ( Status
)) {
1355 Digit
= Value
& 0xf;
1356 Status
= HttpSendHexValue ( SocketFD
,
1359 if ( EFI_ERROR ( Status
)) {
1362 Digit
= ( Value
>> 12 ) & 0xf;
1363 Status
= HttpSendHexValue ( SocketFD
,
1366 if ( EFI_ERROR ( Status
)) {
1369 Digit
= ( Value
>> 8 ) & 0xf;
1370 Status
= HttpSendHexValue ( SocketFD
,
1373 if ( EFI_ERROR ( Status
)) {
1379 // Display the trailing colon if necessary
1381 if (( !bLastValue
) && ( bFirstValue
|| ( 0 != Value
))) {
1382 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1388 // Return the next colon display
1389 if ( NULL
!= pbZeroSuppression
) {
1390 *pbZeroSuppression
= bZeroSuppressionStarting
;
1394 // Return the operation status
1401 Output an IP address to the HTML page
1403 @param [in] SocketFD Socket file descriptor
1404 @param [in] pPort The WSDT_PORT structure address
1405 @param [in] pAddress Address of the socket address
1407 @retval EFI_SUCCESS Successfully displayed the address
1412 IN WSDT_PORT
* pPort
,
1413 IN
struct sockaddr_in6
* pAddress
1416 BOOLEAN bZeroSuppression
;
1418 struct sockaddr_in
* pIpv4
;
1419 struct sockaddr_in6
* pIpv6
;
1424 // Use break instead of goto
1428 // Determine the type of address
1430 if ( AF_INET6
== pAddress
->sin6_family
) {
1434 // Display the address in RFC2732 format
1436 bZeroSuppression
= FALSE
;
1437 Status
= HttpSendByte ( SocketFD
, pPort
, '[' );
1438 if ( EFI_ERROR ( Status
)) {
1441 for ( Index
= 0; 8 > Index
; Index
++ ) {
1442 Status
= HttpSendIp6Value ( SocketFD
,
1444 pIpv6
->sin6_addr
.__u6_addr
.__u6_addr16
[ Index
],
1445 (BOOLEAN
)( 0 == Index
),
1446 (BOOLEAN
)( 7 == Index
),
1448 &bZeroSuppression
);
1449 if ( EFI_ERROR ( Status
)) {
1453 if ( EFI_ERROR ( Status
)) {
1458 // Separate the port number
1460 Status
= HttpSendByte ( SocketFD
, pPort
, ']' );
1463 // Get the port number
1465 PortNumber
= pIpv6
->sin6_port
;
1469 // Output the IPv4 address
1471 pIpv4
= (struct sockaddr_in
*)pAddress
;
1472 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)pIpv4
->sin_addr
.s_addr
);
1473 if ( EFI_ERROR ( Status
)) {
1476 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1477 if ( EFI_ERROR ( Status
)) {
1480 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 8 ));
1481 if ( EFI_ERROR ( Status
)) {
1484 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1485 if ( EFI_ERROR ( Status
)) {
1488 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 16 ));
1489 if ( EFI_ERROR ( Status
)) {
1492 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1493 if ( EFI_ERROR ( Status
)) {
1496 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 24 ));
1499 // Get the port number
1501 PortNumber
= pIpv4
->sin_port
;
1503 if ( EFI_ERROR ( Status
)) {
1508 // Display the port number
1510 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1511 if ( EFI_ERROR ( Status
)) {
1514 Status
= HttpSendValue ( SocketFD
, pPort
, htons ( PortNumber
));
1519 // Return the operation status
1526 Send a Unicode string
1528 @param [in] SocketFD The socket's file descriptor to add to the list.
1529 @param [in] pPort The WSDT_PORT structure address
1530 @param [in] pString A zero terminated Unicode string
1532 @retval EFI_SUCCESS The request was successfully processed
1536 HttpSendUnicodeString (
1538 IN WSDT_PORT
* pPort
,
1539 IN CONST UINT16
* pString
1549 Status
= EFI_SUCCESS
;
1552 // Walk the characters in he string
1554 while ( 0 != ( Character
= *pString
++ )) {
1556 // Convert the character to UTF-8
1558 if ( 0 != ( Character
& 0xf800 )) {
1560 // Send the upper 4 bits
1562 Data
= (UINT8
)(( Character
>> 12 ) & 0xf );
1564 Status
= HttpSendByte ( SocketFD
,
1567 if ( EFI_ERROR ( Status
)) {
1572 // Send the next 6 bits
1574 Data
= (UINT8
)(( Character
>> 6 ) & 0x3f );
1576 Status
= HttpSendByte ( SocketFD
,
1579 if ( EFI_ERROR ( Status
)) {
1584 // Send the last 6 bits
1586 Data
= (UINT8
)( Character
& 0x3f );
1589 else if ( 0 != ( Character
& 0x0780 )) {
1591 // Send the upper 5 bits
1593 Data
= (UINT8
)(( Character
>> 6 ) & 0x1f );
1595 Status
= HttpSendByte ( SocketFD
,
1598 if ( EFI_ERROR ( Status
)) {
1603 // Send the last 6 bits
1605 Data
= (UINT8
)( Character
& 0x3f );
1609 Data
= (UINT8
)( Character
& 0x7f );
1613 // Send the last data byte
1615 Status
= HttpSendByte ( SocketFD
,
1618 if ( EFI_ERROR ( Status
)) {
1624 // Return the operation status
1631 Output a value to the HTML page
1633 @param [in] SocketFD Socket file descriptor
1634 @param [in] pPort The WSDT_PORT structure address
1635 @param [in] Value Value to display
1637 @retval EFI_SUCCESS Successfully displayed the address
1642 IN WSDT_PORT
* pPort
,
1646 BOOLEAN bDisplayZeros
;
1648 CONST UINT64
* pEnd
;
1649 CONST UINT64
* pDivisor
;
1650 CONST UINT64 pDivisors
[ ] = {
1651 10000000000000000000ULL,
1652 1000000000000000000ULL,
1653 100000000000000000ULL,
1654 10000000000000000ULL,
1655 1000000000000000ULL,
1677 Status
= EFI_SUCCESS
;
1680 // Walk the list of divisors
1682 bDisplayZeros
= FALSE
;
1683 pDivisor
= &pDivisors
[0];
1684 pEnd
= &pDivisor
[ sizeof ( pDivisors
) / sizeof ( pDivisors
[0])];
1685 while ( pEnd
> pDivisor
) {
1687 // Determine the next digit
1689 Digit
= Value
/ *pDivisor
;
1692 // Suppress leading zeros
1694 if (( 0 != Digit
) || bDisplayZeros
) {
1695 bDisplayZeros
= TRUE
;
1698 // Display the digit
1700 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1701 if ( EFI_ERROR ( Status
)) {
1706 // Determine the remainder
1708 Temp
= *pDivisor
* Digit
;
1713 // Set the next divisor
1719 // Display the final digit
1721 if ( !EFI_ERROR ( Status
)) {
1722 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Value
));
1726 // Return the operation status