]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
aeeafb5af1130a8cd1486251a18d43e0aea1538d
4 Copyright (c) 2011-2012, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
15 #include <Library/DebugLib.h>
16 #include <Library/UefiLib.h>
18 #include <sys/socket.h>
21 typedef enum _DATA_TYPE
{
22 DATA_TYPE_UNKNOWN
= 0,
23 DATA_TYPE_INT32_DECIMAL
,
24 DATA_TYPE_SOCKET_TYPE
,
36 CONST OPTIONS mOptions
[] = {
37 { "SO_ACCEPTCONN", SO_ACCEPTCONN
, SOL_SOCKET
, FALSE
, DATA_TYPE_UNKNOWN
},
38 { "SO_BROADCAST", SO_BROADCAST
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
39 { "SO_DEBUG", SO_DEBUG
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
40 { "SO_DONTROUTE", SO_DONTROUTE
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
41 { "SO_ERROR", SO_ERROR
, SOL_SOCKET
, FALSE
, DATA_TYPE_UNKNOWN
},
42 { "SO_KEEPALIVE", SO_KEEPALIVE
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
43 { "SO_OOBINLINE", SO_OOBINLINE
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
44 { "SO_OVERFLOWED", SO_OVERFLOWED
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
45 { "SO_RCVBUF", SO_RCVBUF
, SOL_SOCKET
, TRUE
, DATA_TYPE_INT32_DECIMAL
},
46 { "SO_RCVLOWAT", SO_RCVLOWAT
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
47 { "SO_RCVTIMEO", SO_RCVTIMEO
, SOL_SOCKET
, TRUE
, DATA_TYPE_TIMEVAL
},
48 { "SO_REUSEADDR", SO_REUSEADDR
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
49 { "SO_REUSEPORT", SO_REUSEPORT
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
50 { "SO_SNDBUF", SO_SNDBUF
, SOL_SOCKET
, TRUE
, DATA_TYPE_INT32_DECIMAL
},
51 { "SO_SNDLOWAT", SO_SNDLOWAT
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
52 { "SO_SNDTIMEO", SO_SNDTIMEO
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
53 { "SO_TIMESTAMP", SO_TIMESTAMP
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
},
54 { "SO_TYPE", SO_TYPE
, SOL_SOCKET
, FALSE
, DATA_TYPE_SOCKET_TYPE
},
55 { "SO_USELOOPBACK", SO_USELOOPBACK
, SOL_SOCKET
, TRUE
, DATA_TYPE_UNKNOWN
}
59 UINT8 mBuffer
[ 65536 ];
60 UINT8 mValue
[ 65536 ];
61 char * mSocketType
[] = {
71 CONST OPTIONS
* pOption
,
72 socklen_t LengthInBytes
,
73 BOOLEAN bDisplayUpdate
,
82 struct timeval
* TimeVal
;
86 // Display the value length
88 if ( !bDisplayUpdate
) {
89 Print ( L
"LengthInBytes: %d\r\n", LengthInBytes
);
90 Print ( L
"%a: ", pOption
->pOptionName
);
99 Value
.u8
= &mBuffer
[0];
100 switch ( pOption
->DataType
) {
101 case DATA_TYPE_UNKNOWN
:
102 Print ( L
"%a:", pOption
->pOptionName
);
103 pEnd
= &Value
.u8
[ LengthInBytes
];
104 while ( pEnd
> Value
.u8
) {
105 Print ( L
" %02x", *Value
.u8
);
110 case DATA_TYPE_INT32_DECIMAL
:
111 if ( 4 == LengthInBytes
) {
112 Print ( L
"%d", *Value
.i32
);
115 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
116 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
120 case DATA_TYPE_SOCKET_TYPE
:
121 if ( 4 == LengthInBytes
) {
122 if (( SOCK_STREAM
<= *Value
.i32
) && ( SOCK_SEQPACKET
>= *Value
.i32
)) {
123 pString
= mSocketType
[ *Value
.i32
- SOCK_STREAM
];
124 Print ( L
"%a", pString
);
127 Print ( L
"%08x (unknown type)", *Value
.i32
);
131 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
132 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
136 case DATA_TYPE_TIMEVAL
:
137 if ( sizeof ( *Value
.TimeVal
) == LengthInBytes
) {
138 if (( 0 == Value
.TimeVal
->tv_sec
)
139 && ( 0 == Value
.TimeVal
->tv_usec
)) {
140 Print ( L
"Infinite" );
143 Print ( L
"%d.%06d sec",
144 Value
.TimeVal
->tv_sec
,
145 Value
.TimeVal
->tv_usec
);
149 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
150 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
156 // Terminate the line
158 if ( bDisplayCrLf
) {
165 CONST OPTIONS
* pOption
,
169 socklen_t BytesToWrite
;
173 struct timeval
* TimeVal
;
184 // Determine the type of parameter
186 if ( pOption
->bSetAllowed
) {
187 Value
.u8
= &mValue
[0];
188 switch ( pOption
->DataType
) {
192 case DATA_TYPE_INT32_DECIMAL
:
193 Values
= sscanf ( pValue
, "%d", Value
.i32
);
195 BytesToWrite
= sizeof ( *Value
.i32
);
200 case DATA_TYPE_TIMEVAL
:
201 Values
= sscanf ( pValue
, "%d.%d",
202 &Value
.TimeVal
->tv_sec
,
203 &Value
.TimeVal
->tv_usec
);
205 && ( 0 <= Value
.TimeVal
->tv_sec
)
206 && ( 0 <= Value
.TimeVal
->tv_usec
)
207 && ( 1000000 > Value
.TimeVal
->tv_usec
)){
208 BytesToWrite
= sizeof ( *Value
.TimeVal
);
217 if ( 0 == BytesToWrite
) {
218 Print ( L
"ERROR - Invalid value!\r\n" );
222 // Return the number of bytes to be written
229 Set the socket options
231 @param [in] Argc The number of arguments
232 @param [in] Argv The argument value array
234 @retval 0 The application exited normally.
235 @retval Other An error occurred.
243 socklen_t BytesToWrite
;
244 socklen_t LengthInBytes
;
245 CONST OPTIONS
* pEnd
;
246 CONST OPTIONS
* pOption
;
255 // Parse the socket option
257 pOption
= &mOptions
[0];
258 pEnd
= &pOption
[sizeof ( mOptions
) / sizeof ( mOptions
[0])];
260 while ( pEnd
> pOption
) {
261 if ( 0 == strcmp ( Argv
[1], pOption
->pOptionName
)) {
266 if ( pEnd
<= pOption
) {
267 Print ( L
"ERROR: Invalid option: %a\r\n", Argv
[1]);
273 // Display the help if necessary
275 if (( 2 > Argc
) || ( 3 < Argc
)) {
276 Print ( L
"%a <option>\r\n", Argv
[0]);
278 Print ( L
"Option one of:\r\n" );
279 pOption
= &mOptions
[0];
280 while ( pEnd
> pOption
) {
281 Print ( L
" %a: %a\r\n",
282 pOption
->pOptionName
,
283 pOption
->bSetAllowed
? "get/set" : "get" );
290 // Determine if the value is to be set
294 || ( 0 < ( BytesToWrite
= GetOptionValue ( pOption
, Argv
[2])))) {
298 s
= socket ( AF_INET
, 0, 0 );
300 Print ( L
"ERROR - Unable to open the socket, errno: %d\r\n", errno
);
304 // Display the option value
306 LengthInBytes
= sizeof ( mBuffer
);
307 Status
= getsockopt ( s
,
308 pOption
->OptionLevel
,
309 pOption
->OptionValue
,
312 if ( -1 == Status
) {
313 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
316 DisplayOption ( pOption
,
319 (BOOLEAN
)( 0 == BytesToWrite
));
322 // Determine if the value is to be set
324 if (( 0 < BytesToWrite
)
325 && ( BytesToWrite
== LengthInBytes
)) {
327 // Set the option value
329 Status
= setsockopt ( s
,
330 pOption
->OptionLevel
,
331 pOption
->OptionValue
,
334 if ( -1 == Status
) {
335 Print ( L
"ERROR - setsockopt failed, errno: %d\r\n", errno
);
339 // Display the updated option value
341 Status
= getsockopt ( s
,
342 pOption
->OptionLevel
,
343 pOption
->OptionValue
,
346 if ( -1 == Status
) {
347 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
350 DisplayOption ( pOption
,
360 // Done with the socket
371 "%a exiting, errno: %d\r\n",