]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Sockets/SetSockOpt/SetSockOpt.c
0df143a5144783ce9d8150725e13d938cc35bf7a
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
) {
107 case DATA_TYPE_UNKNOWN
:
108 Print ( L
"%a:", pOption
->pOptionName
);
109 pEnd
= &Value
.u8
[ LengthInBytes
];
110 while ( pEnd
> Value
.u8
) {
111 Print ( L
" %02x", *Value
.u8
);
116 case DATA_TYPE_INT32_DECIMAL
:
117 if ( 4 == LengthInBytes
) {
118 Print ( L
"%d", *Value
.i32
);
121 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
122 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
126 case DATA_TYPE_SOCKET_TYPE
:
127 if ( 4 == LengthInBytes
) {
128 if (( SOCK_STREAM
<= *Value
.i32
) && ( SOCK_SEQPACKET
>= *Value
.i32
)) {
129 pString
= mSocketType
[ *Value
.i32
- SOCK_STREAM
];
130 Print ( L
"%a", pString
);
133 Print ( L
"%08x (unknown type)", *Value
.i32
);
137 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
138 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
142 case DATA_TYPE_TIMEVAL
:
143 if ( sizeof ( *Value
.TimeVal
) == LengthInBytes
) {
144 if (( 0 == Value
.TimeVal
->tv_sec
)
145 && ( 0 == Value
.TimeVal
->tv_usec
)) {
146 Print ( L
"Infinite" );
149 Print ( L
"%d.%06d sec",
150 Value
.TimeVal
->tv_sec
,
151 Value
.TimeVal
->tv_usec
);
155 errno
= ( 4 > LengthInBytes
) ? EBUFSIZE
: ERANGE
;
156 Print ( L
"\r\nERROR - Invalid length, errno: %d\r\n", errno
);
162 // Terminate the line
164 if ( bDisplayCrLf
) {
171 CONST OPTIONS
* pOption
,
175 socklen_t BytesToWrite
;
179 struct timeval
* TimeVal
;
190 // Determine the type of parameter
192 if ( pOption
->bSetAllowed
) {
193 Value
.u8
= &mValue
[0];
194 switch ( pOption
->DataType
) {
198 case DATA_TYPE_INT32_DECIMAL
:
199 Values
= sscanf ( pValue
, "%d", Value
.i32
);
201 BytesToWrite
= sizeof ( *Value
.i32
);
206 case DATA_TYPE_TIMEVAL
:
207 Values
= sscanf ( pValue
, "%d.%d",
208 &Value
.TimeVal
->tv_sec
,
209 &Value
.TimeVal
->tv_usec
);
211 && ( 0 <= Value
.TimeVal
->tv_sec
)
212 && ( 0 <= Value
.TimeVal
->tv_usec
)
213 && ( 1000000 > Value
.TimeVal
->tv_usec
)){
214 BytesToWrite
= sizeof ( *Value
.TimeVal
);
223 if ( 0 == BytesToWrite
) {
224 Print ( L
"ERROR - Invalid value!\r\n" );
228 // Return the number of bytes to be written
235 Set the socket options
237 @param [in] Argc The number of arguments
238 @param [in] Argv The argument value array
240 @retval 0 The application exited normally.
241 @retval Other An error occurred.
249 socklen_t BytesToWrite
;
250 socklen_t LengthInBytes
;
251 CONST OPTIONS
* pEnd
;
252 CONST OPTIONS
* pOption
;
261 // Parse the socket option
263 pOption
= &mOptions
[0];
264 pEnd
= &pOption
[sizeof ( mOptions
) / sizeof ( mOptions
[0])];
266 while ( pEnd
> pOption
) {
267 if ( 0 == strcmp ( Argv
[1], pOption
->pOptionName
)) {
272 if ( pEnd
<= pOption
) {
273 Print ( L
"ERROR: Invalid option: %a\r\n", Argv
[1]);
279 // Display the help if necessary
281 if (( 2 > Argc
) || ( 3 < Argc
)) {
282 Print ( L
"%a <option>\r\n", Argv
[0]);
284 Print ( L
"Option one of:\r\n" );
285 pOption
= &mOptions
[0];
286 while ( pEnd
> pOption
) {
287 Print ( L
" %a: %a\r\n",
288 pOption
->pOptionName
,
289 pOption
->bSetAllowed
? "get/set" : "get" );
296 // Determine if the value is to be set
300 || ( 0 < ( BytesToWrite
= GetOptionValue ( pOption
, Argv
[2])))) {
304 s
= socket ( AF_INET
, 0, 0 );
306 Print ( L
"ERROR - Unable to open the socket, errno: %d\r\n", errno
);
310 // Display the option value
312 LengthInBytes
= sizeof ( mBuffer
);
313 Status
= getsockopt ( s
,
314 pOption
->OptionLevel
,
315 pOption
->OptionValue
,
318 if ( -1 == Status
) {
319 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
322 DisplayOption ( pOption
,
325 (BOOLEAN
)( 0 == BytesToWrite
));
328 // Determine if the value is to be set
330 if (( 0 < BytesToWrite
)
331 && ( BytesToWrite
== LengthInBytes
)) {
333 // Set the option value
335 Status
= setsockopt ( s
,
336 pOption
->OptionLevel
,
337 pOption
->OptionValue
,
340 if ( -1 == Status
) {
341 Print ( L
"ERROR - setsockopt failed, errno: %d\r\n", errno
);
345 // Display the updated option value
347 Status
= getsockopt ( s
,
348 pOption
->OptionLevel
,
349 pOption
->OptionValue
,
352 if ( -1 == Status
) {
353 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
356 DisplayOption ( pOption
,
366 // Done with the socket
377 "%a exiting, errno: %d\r\n",