]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
4 Copyright (c) 2011, 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.
21 #include <Library/DebugLib.h>
22 #include <Library/UefiLib.h>
24 #include <sys/socket.h>
27 typedef enum _DATA_TYPE
{
28 DATA_TYPE_UNKNOWN
= 0,
29 DATA_TYPE_INT32_DECIMAL
,
30 DATA_TYPE_SOCKET_TYPE
,
42 CONST OPTIONS mOptions
[] = {
43 { "SO_ACCEPTCONN", SO_ACCEPTCONN
, SOL_SOCKET
, FALSE
, DATA_TYPE_UNKNOWN
},
44 { "SO_BROADCAST", SO_BROADCAST
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
45 { "SO_DEBUG", SO_DEBUG
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
46 { "SO_DONTROUTE", SO_DONTROUTE
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
47 { "SO_ERROR", SO_ERROR
, SOL_SOCKET
, FALSE
, DATA_TYPE_UNKNOWN
},
48 { "SO_KEEPALIVE", SO_KEEPALIVE
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
49 { "SO_OOBINLINE", SO_OOBINLINE
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
50 { "SO_OVERFLOWED", SO_OVERFLOWED
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
51 { "SO_RCVBUF", SO_RCVBUF
, SOL_SOCKET
, TRUE
, DATA_TYPE_INT32_DECIMAL
},
52 { "SO_RCVLOWAT", SO_RCVLOWAT
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
53 { "SO_RCVTIMEO", SO_RCVTIMEO
, SOL_SOCKET
, TRUE
, DATA_TYPE_TIMEVAL
},
54 { "SO_REUSEADDR", SO_REUSEADDR
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
55 { "SO_REUSEPORT", SO_REUSEPORT
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
56 { "SO_SNDBUF", SO_SNDBUF
, SOL_SOCKET
, TRUE
, DATA_TYPE_INT32_DECIMAL
},
57 { "SO_SNDLOWAT", SO_SNDLOWAT
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
58 { "SO_SNDTIMEO", SO_SNDTIMEO
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
59 { "SO_TIMESTAMP", SO_TIMESTAMP
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
60 { "SO_TYPE", SO_TYPE
, SOL_SOCKET
, FALSE
, DATA_TYPE_SOCKET_TYPE
},
61 { "SO_USELOOPBACK", SO_USELOOPBACK
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
}
65 UINT8 mBuffer
[ 65536 ];
66 UINT8 mValue
[ 65536 ];
67 char * mSocketType
[] = {
77 CONST OPTIONS
* pOption
,
78 socklen_t LengthInBytes
,
79 BOOLEAN bDisplayUpdate
,
88 struct timeval
* TimeVal
;
92 // Display the value length
94 if ( !bDisplayUpdate
) {
95 Print ( L
"LengthInBytes: %d\r\n", LengthInBytes
);
96 Print ( L
"%a: ", pOption
->pOptionName
);
105 Value
.u8
= &mBuffer
[0];
106 switch ( pOption
->DataType
)
108 case DATA_TYPE_UNKNOWN
:
109 Print ( L
"%a:", pOption
->pOptionName
);
110 pEnd
= &Value
.u8
[ LengthInBytes
];
111 while ( pEnd
> Value
.u8
) {
112 Print ( L
" %02x", *Value
.u8
);
117 case DATA_TYPE_INT32_DECIMAL
:
118 if ( 4 == LengthInBytes
) {
119 Print ( L
"%d", *Value
.i32
);
122 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
123 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
127 case DATA_TYPE_SOCKET_TYPE
:
128 if ( 4 == LengthInBytes
) {
129 if (( SOCK_STREAM
<= *Value
.i32
) && ( SOCK_SEQPACKET
>= *Value
.i32
)) {
130 pString
= mSocketType
[ *Value
.i32
- SOCK_STREAM
];
131 Print ( L
"%a", pString
);
134 Print ( L
"%08x (unknown type)", *Value
.i32
);
138 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
139 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
143 case DATA_TYPE_TIMEVAL
:
144 if ( sizeof ( *Value
.TimeVal
) == LengthInBytes
) {
145 if (( 0 == Value
.TimeVal
->tv_sec
)
146 && ( 0 == Value
.TimeVal
->tv_usec
)) {
147 Print ( L
"Infinite" );
150 Print ( L
"%d.%06d sec",
151 Value
.TimeVal
->tv_sec
,
152 Value
.TimeVal
->tv_usec
);
156 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
157 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
163 // Terminate the line
165 if ( bDisplayCrLf
) {
172 CONST OPTIONS
* pOption
,
176 socklen_t BytesToWrite
;
180 struct timeval
* TimeVal
;
191 // Determine the type of parameter
193 if ( pOption
->bSetAllowed
) {
194 Value
.u8
= &mValue
[0];
195 switch ( pOption
->DataType
) {
196 case DATA_TYPE_INT32_DECIMAL
:
197 Values
= sscanf ( pValue
, "%d", Value
.i32
);
199 BytesToWrite
= sizeof ( *Value
.i32
);
204 case DATA_TYPE_TIMEVAL
:
205 Values
= sscanf ( pValue
, "%d.%0d",
206 &Value
.TimeVal
->tv_sec
,
207 &Value
.TimeVal
->tv_usec
);
209 && ( 0 <= Value
.TimeVal
->tv_sec
)
210 && ( 0 <= Value
.TimeVal
->tv_usec
)
211 && ( 1000000 > Value
.TimeVal
->tv_usec
)){
212 BytesToWrite
= sizeof ( *Value
.TimeVal
);
221 if ( 0 == BytesToWrite
) {
222 Print ( L
"ERROR - Invalid value!\r\n" );
226 // Return the number of bytes to be written
233 Set the socket options
235 @param [in] Argc The number of arguments
236 @param [in] Argv The argument value array
238 @retval 0 The application exited normally.
239 @retval Other An error occurred.
247 socklen_t BytesToWrite
;
248 socklen_t LengthInBytes
;
249 CONST OPTIONS
* pEnd
;
250 CONST OPTIONS
* pOption
;
259 // Parse the socket option
261 pOption
= &mOptions
[0];
262 pEnd
= &pOption
[sizeof ( mOptions
) / sizeof ( mOptions
[0])];
264 while ( pEnd
> pOption
) {
265 if ( 0 == strcmp ( Argv
[1], pOption
->pOptionName
)) {
270 if ( pEnd
<= pOption
) {
271 Print ( L
"ERROR: Invalid option: %a\r\n", Argv
[1]);
277 // Display the help if necessary
279 if (( 2 > Argc
) || ( 3 < Argc
)) {
280 Print ( L
"%a <option>\r\n", Argv
[0]);
282 Print ( L
"Option one of:\r\n" );
283 pOption
= &mOptions
[0];
284 while ( pEnd
> pOption
) {
285 Print ( L
" %a: %a\r\n",
286 pOption
->pOptionName
,
287 pOption
->bSetAllowed
? "get/set" : "get" );
294 // Determine if the value is to be set
298 || ( 0 < ( BytesToWrite
= GetOptionValue ( pOption
, Argv
[2])))) {
302 s
= socket ( AF_INET
, 0, 0 );
304 Print ( L
"ERROR - Unable to open the socket, errno: %d\r\n", errno
);
308 // Display the option value
310 LengthInBytes
= sizeof ( mBuffer
);
311 Status
= getsockopt ( s
,
312 pOption
->OptionLevel
,
313 pOption
->OptionValue
,
316 if ( -1 == Status
) {
317 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
320 DisplayOption ( pOption
,
323 (BOOLEAN
)( 0 == BytesToWrite
));
326 // Determine if the value is to be set
328 if (( 0 < BytesToWrite
)
329 && ( BytesToWrite
== LengthInBytes
)) {
331 // Set the option value
333 Status
= setsockopt ( s
,
334 pOption
->OptionLevel
,
335 pOption
->OptionValue
,
338 if ( -1 == Status
) {
339 Print ( L
"ERROR - setsockopt failed, errno: %d\r\n", errno
);
343 // Display the updated option value
345 Status
= getsockopt ( s
,
346 pOption
->OptionLevel
,
347 pOption
->OptionValue
,
350 if ( -1 == Status
) {
351 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
354 DisplayOption ( pOption
,
364 // Done with the socket
375 "%a exiting, errno: %d\r\n",