]>
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
) {
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
) {
195 case DATA_TYPE_INT32_DECIMAL
:
196 Values
= sscanf ( pValue
, "%d", Value
.i32
);
198 BytesToWrite
= sizeof ( *Value
.i32
);
203 case DATA_TYPE_TIMEVAL
:
204 Values
= sscanf ( pValue
, "%d.%0d",
205 &Value
.TimeVal
->tv_sec
,
206 &Value
.TimeVal
->tv_usec
);
208 && ( 0 <= Value
.TimeVal
->tv_sec
)
209 && ( 0 <= Value
.TimeVal
->tv_usec
)
210 && ( 1000000 > Value
.TimeVal
->tv_usec
)){
211 BytesToWrite
= sizeof ( *Value
.TimeVal
);
220 if ( 0 == BytesToWrite
) {
221 Print ( L
"ERROR - Invalid value!\r\n" );
225 // Return the number of bytes to be written
232 Set the socket options
234 @param [in] Argc The number of arguments
235 @param [in] Argv The argument value array
237 @retval 0 The application exited normally.
238 @retval Other An error occurred.
246 socklen_t BytesToWrite
;
247 socklen_t LengthInBytes
;
248 CONST OPTIONS
* pEnd
;
249 CONST OPTIONS
* pOption
;
258 // Parse the socket option
260 pOption
= &mOptions
[0];
261 pEnd
= &pOption
[sizeof ( mOptions
) / sizeof ( mOptions
[0])];
263 while ( pEnd
> pOption
) {
264 if ( 0 == strcmp ( Argv
[1], pOption
->pOptionName
)) {
269 if ( pEnd
<= pOption
) {
270 Print ( L
"ERROR: Invalid option: %a\r\n", Argv
[1]);
276 // Display the help if necessary
278 if (( 2 > Argc
) || ( 3 < Argc
)) {
279 Print ( L
"%a <option>\r\n", Argv
[0]);
281 Print ( L
"Option one of:\r\n" );
282 pOption
= &mOptions
[0];
283 while ( pEnd
> pOption
) {
284 Print ( L
" %a: %a\r\n",
285 pOption
->pOptionName
,
286 pOption
->bSetAllowed
? "get/set" : "get" );
293 // Determine if the value is to be set
297 || ( 0 < ( BytesToWrite
= GetOptionValue ( pOption
, Argv
[2])))) {
301 s
= socket ( AF_INET
, 0, 0 );
303 Print ( L
"ERROR - Unable to open the socket, errno: %d\r\n", errno
);
307 // Display the option value
309 LengthInBytes
= sizeof ( mBuffer
);
310 Status
= getsockopt ( s
,
311 pOption
->OptionLevel
,
312 pOption
->OptionValue
,
315 if ( -1 == Status
) {
316 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
319 DisplayOption ( pOption
,
322 (BOOLEAN
)( 0 == BytesToWrite
));
325 // Determine if the value is to be set
327 if (( 0 < BytesToWrite
)
328 && ( BytesToWrite
== LengthInBytes
)) {
330 // Set the option value
332 Status
= setsockopt ( s
,
333 pOption
->OptionLevel
,
334 pOption
->OptionValue
,
337 if ( -1 == Status
) {
338 Print ( L
"ERROR - setsockopt failed, errno: %d\r\n", errno
);
342 // Display the updated option value
344 Status
= getsockopt ( s
,
345 pOption
->OptionLevel
,
346 pOption
->OptionValue
,
349 if ( -1 == Status
) {
350 Print ( L
"ERROR - getsockopt failed, errno: %d\r\n", errno
);
353 DisplayOption ( pOption
,
363 // Done with the socket
374 "%a exiting, errno: %d\r\n",