Sdrctl.c
Function nl_socket_free(struct nl_sock *h)
nl_socket_free: The function of nl_socket_free is to free the resources associated with a netlink socket.
parameters: The parameters of this Function. · h: A pointer to a struct nl_sock, which represents the netlink socket to be freed.
Code Description: The nl_socket_free function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. The function takes a single parameter, h, which is a pointer to a nl_sock structure. This structure typically contains information about the netlink socket, including its state and associated resources.
Inside the function, the nl_handle_destroy function is called with the parameter h. This function is responsible for properly releasing all resources associated with the netlink socket represented by h. It ensures that any memory allocated for the socket is freed, and any other necessary cleanup operations are performed. By encapsulating this cleanup operation within nl_socket_free, the code promotes better resource management and helps prevent memory leaks.
Note: It is important to ensure that the nl_socket_free function is called only after the netlink socket is no longer needed. Calling this function on an active socket may lead to undefined behavior or application crashes. Additionally, users should ensure that the nl_sock pointer passed to the function is valid and has been previously allocated.
graph TD
A[nl_socket_free function called] --> B[nl_handle_destroy called]
B --> C[nl_socket_free execution completed]
Function nl_socket_set_buffer_size(struct nl_sock *sk,
int rxbuf, int txbuf)
nl_socket_set_buffer_size: The function of nl_socket_set_buffer_size is to set the receive and transmit buffer sizes for a Netlink socket.
parameters: The parameters of this Function.
· sk: A pointer to the nl_sock structure representing the Netlink socket for which the buffer sizes are being set.
· rxbuf: An integer specifying the desired size of the receive buffer in bytes.
· txbuf: An integer specifying the desired size of the transmit buffer in bytes.
Code Description: The nl_socket_set_buffer_size function is defined as a static inline function, which means it is intended for use only within the file it is defined in and may be optimized by the compiler for performance. This function takes three parameters: a pointer to a nl_sock structure (sk), an integer for the receive buffer size (rxbuf), and an integer for the transmit buffer size (txbuf). The function calls nl_set_buffer_size, passing the same parameters to it. The nl_set_buffer_size function is responsible for actually setting the buffer sizes for the specified Netlink socket. The return value of nl_socket_set_buffer_size is the same as that of nl_set_buffer_size, which typically indicates success or failure of the operation.
Note: It is important to ensure that the values provided for rxbuf and txbuf are appropriate for the intended use of the socket, as setting them to excessively large or small values may lead to performance issues or errors.
Output Example: A possible return value of the function could be 0, indicating that the buffer sizes were set successfully, or a negative integer indicating an error occurred during the operation.
graph TD
A[Start nl_socket_set_buffer_size] --> B[Receive socket sk]
B --> C[Receive buffer sizes rxbuf and txbuf]
C --> D[Call nl_set_buffer_size with sk, rxbuf, txbuf]
D --> E[Return result from nl_set_buffer_size]
E --> F[End nl_socket_set_buffer_size]
Function nl80211_init(struct nl80211_state *state)
nl80211_init: The function of nl80211_init is to initialize the netlink socket for communication with the nl80211 subsystem.
parameters: The parameters of this Function. · state: A pointer to a struct nl80211_state that holds the state information for the nl80211 connection.
Code Description: The nl80211_init function is responsible for setting up a netlink socket that will be used to communicate with the nl80211 subsystem in the Linux kernel. The function begins by allocating a new netlink socket using nl_socket_alloc. If the allocation fails, an error message is printed to stderr, and the function returns -ENOMEM, indicating that there is not enough memory available.
Once the socket is successfully allocated, the function sets the buffer size for the socket to 8192 bytes for both sending and receiving data using nl_socket_set_buffer_size. This ensures that the socket has sufficient buffer space for the communication.
The next step is to connect the allocated socket to the generic netlink protocol using genl_connect. If this connection fails, an error message is printed, and the function sets the error code to -ENOLINK before jumping to the cleanup section.
After establishing the connection, the function attempts to resolve the identifier for the nl80211 family using genl_ctrl_resolve. If the identifier cannot be found, an error message is printed, and the function sets the error code to -ENOENT, again jumping to the cleanup section.
If all operations are successful, the function returns 0, indicating that the initialization was successful. In the cleanup section, if any errors occurred, the function frees the allocated netlink socket using nl_socket_free before returning the error code.
Note: It is important to ensure that the nl80211_state structure is properly initialized before calling this function. Additionally, the caller should handle the returned error codes appropriately to manage any issues that arise during the initialization process.
Output Example: A successful call to nl80211_init might return 0, while a failure due to a memory allocation issue might return -ENOMEM, and a failure to connect to the generic netlink might return -ENOLINK.
graph TD
A[nl80211_init function called] --> B[Allocate netlink socket]
B --> C{Socket allocation successful?}
C -->|Yes| D[Set socket buffer size]
C -->|No| E[Print error message and return -ENOMEM]
D --> F[Connect to generic netlink]
F --> G{Connection successful?}
G -->|Yes| H[Resolve nl80211 ID]
G -->|No| I[Print error message and set err to -ENOLINK]
H --> J{nl80211 ID found?}
J -->|Yes| K[Return 0]
J -->|No| L[Print error message and set err to -ENOENT]
I --> M[Free netlink socket]
L --> M
E --> M
M --> N[Return err]
Function nl80211_cleanup(struct nl80211_state *state)
nl80211_cleanup: The function of nl80211_cleanup is to clean up and free resources associated with the nl80211 state.
parameters: The parameters of this Function. · state: A pointer to a struct nl80211_state that contains the state information for the nl80211 interface.
Code Description: The nl80211_cleanup function is a static function designed to release resources associated with the nl80211 state. It takes a single parameter, which is a pointer to a struct nl80211_state. This structure typically holds information about the current state of the nl80211 interface, including a socket used for communication. The function specifically calls nl_socket_free, passing the nl_sock member of the state structure. This effectively deallocates the memory and resources associated with the network socket, ensuring that there are no memory leaks or dangling pointers when the nl80211 state is no longer needed. The use of static indicates that this function is limited in scope to the file it is defined in, promoting encapsulation and preventing external access.
Note: It is important to ensure that the nl80211_cleanup function is called when the nl80211 state is no longer required to prevent resource leaks. Additionally, the state parameter should not be NULL when passed to this function, as this could lead to undefined behavior.
graph TD
A[Start nl80211_cleanup function] --> B[Free nl_socket associated with state]
B --> C[End nl80211_cleanup function]
Function __usage_cmd(const struct cmd cmd, char indent, bool full)
__usage_cmd: The function of __usage_cmd is to display the usage information for a command, including its arguments and help text.
parameters: The parameters of this Function. · parameter1: const struct cmd cmd - A pointer to a command structure that contains information about the command to be displayed. · parameter2: char indent - A string used for indentation in the output, allowing for formatted display. · parameter3: bool full - A boolean flag indicating whether to display the full help text associated with the command.
Code Description: The __usage_cmd function is designed to print the usage information of a command in a formatted manner. It begins by printing the provided indentation string. The function then uses a switch statement to determine the type of command based on the idby
field of the cmd
structure. Depending on the command type, it prints a corresponding prefix (e.g., "phy
If the command has a parent and the parent's name is available, it prints the parent's name before the command name. The command name itself is printed next. If the command has associated arguments, the function processes these arguments line by line. It uses string manipulation functions to locate newline characters and print each line with appropriate indentation and prefixes.
If the full
parameter is true and the command has help text, the function prints the help text in a similar line-by-line manner, applying indentation as necessary. The function ensures that the output is well-formatted and easy to read, providing clear guidance on how to use the command.
Note: It is important to ensure that the cmd
structure is properly initialized before calling this function. The args
and help
fields should be properly populated to provide meaningful output. The indentation string should be carefully managed to achieve the desired formatting in the output.
Output Example: Assuming a command structure with the following properties: - idby: CIB_NETDEV - parent: NULL - name: "start" - args: "arg1\narg2\narg3" - help: "This command starts the device.\nIt requires specific arguments."
The output of the function might look like this:
dev <devname> start arg1
arg2
arg3
This command starts the device.
It requires specific arguments.
graph TD
A[Start] --> B[Print indent]
B --> C{Check cmd idby}
C -->|CIB_NONE| D[Do nothing]
C -->|CIB_PHY| E[Print phy ]
C -->|CIB_NETDEV| F[Print dev ]
C -->|CIB_WDEV| G[Print wdev ]
D --> H{Check cmd parent}
E --> H
F --> H
G --> H
H -->|Has parent| I[Print parent name]
H -->|No parent| J[Print cmd name]
I --> J
J --> K{Check cmd args}
K -->|Has args| L[Print args line by line]
K -->|No args| M[Print newline]
L --> N{Check for end of args}
N -->|Not end| O[Print args line]
O --> N
N -->|End| P{Check full and cmd help}
M --> P
P -->|Not full or no help| Q[Return]
P -->|Full and has help| R[Print help line by line]
R --> S[Print help line]
S --> R
R --> T[Print newline]
Q --> U[End]
Function usage_options(void)
usage_options: The function of usage_options is to display the available command-line options for the application.
parameters: The parameters of this Function. · There are no parameters for this function.
Code Description: The usage_options function is a static function that outputs a list of command-line options available for the application. It utilizes the printf function to print formatted text to the standard output. The first line printed is "Options:", which serves as a header for the subsequent list of options. Following this, the function prints a specific option: "--debug", which is described as enabling netlink debugging. This indicates that when the user runs the application with the --debug flag, it will activate debugging features related to netlink communication. The function does not return any value and is intended solely for informational purposes.
Note: This function is static, meaning it is limited in scope to the file in which it is defined (sdrctl.c). It does not accept any parameters and does not return any values. It is important to call this function when the user requests help or information about the command-line options available for the application.
graph TD
A[Start usage_options function] --> B[Print Options header]
B --> C[Print debug option]
C --> D[End usage_options function]
Function usage(int argc, char **argv)
usage: The function of usage is to display the usage information and command options for the application.
parameters: The parameters of this Function. · parameter1: int argc - The count of command-line arguments passed to the function. · parameter2: char **argv - An array of command-line argument strings.
Code Description: The usage function is designed to provide users with information on how to use the application, including available commands and options. It begins by initializing local variables to determine if any filters for sections or commands have been provided through the command-line arguments. The first argument, if present, is treated as a section filter, while the second argument is treated as a command filter.
The function then prints a general usage message, including the name of the application and a call to another function, usage_options(), which presumably lists available options. It also displays the version of the application.
Next, the function iterates over command sections using a macro, for_each_cmd, which likely traverses a predefined list of command structures. For each section, it checks if it has a parent (indicating it is a sub-section) and skips it if so. If a section filter is provided, it compares the section name against the filter and continues only if they match.
For each valid section, the function checks if it has a handler and is not marked as hidden. If these conditions are met, it calls another function, __usage_cmd, to print the usage information for that section. The function then iterates over commands within the section, applying similar checks for validity, visibility, and filtering based on the command filter.
After listing the commands, the function provides additional notes about device identification, indicating that users can use either 'dev' or 'wdev' to specify devices. It also mentions that users can omit certain identifiers if they are unique, providing examples for clarity. Finally, it warns users against screenscraping the tool's output, emphasizing that the output is not guaranteed to be stable.
Note: It is important to ensure that the command-line arguments are correctly passed to the function to utilize the filtering capabilities effectively. Users should be aware that the output format may change, and reliance on it for scripting purposes is discouraged.
graph TD
A[Start usage function] --> B[Check argc value]
B -->|argc > 0| C[Set sect_filt to argv[0]]
B -->|argc <= 0| D[Skip sect_filt assignment]
C --> E[Check argc value]
E -->|argc > 1| F[Set cmd_filt to argv[1]]
E -->|argc <= 1| G[Skip cmd_filt assignment]
F --> H[Print usage header]
G --> H
H --> I[Call usage_options function]
I --> J[Print version information]
J --> K[Print Commands header]
K --> L[Iterate through each section]
L --> M[Check if section has a parent]
M -->|Has parent| L
M -->|No parent| N[Check sect_filt]
N -->|sect_filt matches section name| O[Check if section is not hidden]
O -->|Not hidden| P[Call __usage_cmd for section]
P --> Q[Iterate through each command]
Q --> R[Check if command's parent matches section]
R -->|Matches| S[Check if command is not hidden]
S -->|Not hidden| T[Check cmd_filt]
T -->|cmd_filt matches command name| U[Call __usage_cmd for command]
U --> Q
S -->|Hidden| Q
R -->|Does not match| Q
N -->|sect_filt does not match| L
L --> V[Print additional usage information]
V --> W[End usage function]
Function print_help(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv,
enum id_input id)
print_help: The function of print_help is to terminate the program with a specific exit status.
parameters: The parameters of this Function. · state: A pointer to a struct nl80211_state, which holds the state information for the nl80211 protocol. · cb: A pointer to a struct nl_cb, which is used for callback functions in netlink communication. · msg: A pointer to a struct nl_msg, representing a netlink message. · argc: An integer representing the count of command-line arguments. · argv: An array of character pointers (strings) representing the command-line arguments. · id: An enumeration value of type id_input, which indicates the type of input being processed.
Code Description: The print_help function is defined as a static function, meaning it is limited in scope to the file in which it is declared. The function takes several parameters related to the nl80211 protocol and command-line input but does not utilize them in its implementation. The sole action performed by this function is to call the exit function with an argument of 3. This indicates that when print_help is invoked, the program will terminate immediately with an exit status of 3. The exit status can be used by the operating system or calling process to determine the reason for the program's termination.
Note: It is important to understand that this function does not provide any help or output to the user; it simply exits the program. Therefore, it may be used as a placeholder or a signal for an error state, but it does not fulfill the typical expectations associated with a help function.
graph TD
A[Start print_help function] --> B[Receive parameters state, cb, msg, argc, argv, id]
B --> C[Execute exit with code 3]
C --> D[End print_help function]
Function usage_cmd(const struct cmd *cmd)
usage_cmd: The function of usage_cmd is to display the usage information for a command along with its options.
parameters: The parameters of this Function. · parameter1: const struct cmd *cmd - A pointer to a command structure that contains details about the command for which usage information is being displayed.
Code Description: The usage_cmd function is a static function that outputs the usage information for a specific command. It begins by printing a usage message that includes the program name, which is referenced by the variable argv0. This variable typically holds the name of the executable being run. Following this, the function calls __usage_cmd, passing the command structure cmd, an empty string, and a boolean value true. The __usage_cmd function is expected to format and display the usage details specific to the command provided. Finally, the function calls usage_options, which is likely responsible for displaying additional options or flags that can be used with the command. This structured approach ensures that users receive comprehensive guidance on how to utilize the command effectively.
Note: It is important to ensure that the argv0 variable is correctly initialized with the program name before calling this function. Additionally, the cmd structure should be properly populated with relevant command details to ensure accurate usage information is displayed.
graph TD
A[Start usage_cmd function] --> B[Print usage message with argv0]
B --> C[Call __usage_cmd with cmd, empty string, and true]
C --> D[Call usage_options]
D --> E[End usage_cmd function]
Function version(void)
version: The function of version is to print the current version of the software.
parameters: The parameters of this Function. · There are no parameters for this function.
Code Description: The version function is a static function that outputs the version information of the software to the standard output. It utilizes the printf function to format the output string. The string "iw version %s\n" is used, where %s is a placeholder that will be replaced by the value of the variable sdrctl_version. The sdrctl_version variable is expected to hold the version string of the software. When this function is called, it will display a message in the format "iw version [version_string]", where [version_string] is the actual version number or identifier stored in sdrctl_version. The use of the static keyword indicates that this function has internal linkage, meaning it can only be called within the same source file.
Note: It is important to ensure that the sdrctl_version variable is properly defined and initialized before calling this function, as an uninitialized variable may lead to undefined behavior or incorrect output. Additionally, since this function does not take any parameters, it does not require any input from the user or other parts of the program.
graph TD
A[Start version function] --> B[Print iw version with sdrctl_version]
B --> C[End version function]
Function phy_lookup(char *name)
phy_lookup: The function of phy_lookup is to retrieve the index of a specified IEEE 802.11 device.
parameters: The parameters of this Function. · parameter1: char *name - A string representing the name of the IEEE 802.11 device whose index is to be looked up.
Code Description: The phy_lookup function begins by declaring a buffer of 200 characters to hold the file path and the read data. It constructs a file path to the index of the specified IEEE 802.11 device by using the snprintf function, which formats the string and stores it in the buffer. The path is constructed as "/sys/class/ieee80211/{name}/index", where {name} is replaced by the value of the parameter 'name'.
Next, the function attempts to open the file located at the constructed path in read-only mode using the open function. If the file descriptor (fd) returned by open is less than 0, it indicates that the file could not be opened, and the function returns -1 to signal an error.
If the file is successfully opened, the function proceeds to read the contents of the file into the buffer. The read function is called with the file descriptor and the size of the buffer minus one (to leave space for the null terminator). If the read operation fails (indicated by a return value less than 0), the function closes the file descriptor and returns -1.
After successfully reading from the file, the function ensures that the buffer is null-terminated by setting the character at the position 'pos' (the number of bytes read) to '\0'. The file descriptor is then closed, and the function returns the integer value obtained by converting the contents of the buffer to an integer using the atoi function. This integer represents the index of the specified IEEE 802.11 device.
Note: It is important to ensure that the 'name' parameter corresponds to a valid IEEE 802.11 device in the system, as an invalid name will result in the function returning -1. Additionally, the function does not handle potential errors from the atoi function, which may lead to unexpected results if the contents of the file are not a valid integer.
Output Example: If the function is called with a valid device name, such as "wlan0", and the contents of the file "/sys/class/ieee80211/wlan0/index" is "1", the function would return the integer value 1. If the device does not exist or cannot be accessed, the function would return -1.
graph TD
A[Start phy_lookup function] --> B[Create buffer of size 200]
A --> C[Format path using name]
C --> D[Open file at path]
D --> E{Check if file descriptor is valid}
E -- Yes --> F[Read from file into buffer]
E -- No --> G[Return -1]
F --> H{Check if read was successful}
H -- Yes --> I[Null-terminate buffer]
H -- No --> J[Close file descriptor]
J --> G
I --> K[Convert buffer to integer]
K --> L[Return integer value]
G --> M[End phy_lookup function]
L --> M
Function error_handler(struct sockaddr_nl nla, struct nlmsgerr err,
void *arg)
error_handler: The function of error_handler is to handle error messages received from the netlink socket.
parameters: The parameters of this Function. · parameter1: struct sockaddr_nl nla - A pointer to a netlink address structure that contains the address of the sender of the message. · parameter2: struct nlmsgerr err - A pointer to a netlink message error structure that contains the error information. · parameter3: void *arg - A pointer to user-defined data that can be used to pass additional information to the function.
Code Description: The error_handler function is designed to process error messages received through a netlink socket. It takes three parameters: a pointer to a netlink address structure (nla), a pointer to a netlink message error structure (err), and a pointer to user-defined data (arg).
Inside the function, the pointer arg is cast to an integer pointer, allowing the function to modify the integer value it points to. The function retrieves the error code from the nlmsgerr structure using err->error and assigns this value to the integer pointed to by ret. This effectively communicates the error code back to the caller. The function then returns NL_STOP, which indicates that no further processing of the netlink message should occur.
This function is typically used in scenarios where error handling is necessary, such as when dealing with communication failures or unexpected conditions in netlink messaging.
Note: It is important to ensure that the pointer passed as the arg parameter is valid and points to an integer variable that can store the error code. Additionally, the function should be used in the context of a netlink socket communication where error handling is required.
Output Example: If the error_handler function is called with an error code of -5, and the arg parameter points to an integer variable initialized to 0, after execution, the integer variable will hold the value -5, indicating the specific error encountered.
graph TD
A[Start error_handler function] --> B[Receive sockaddr_nl pointer]
B --> C[Receive nlmsgerr pointer]
C --> D[Receive argument pointer]
D --> E[Dereference argument pointer]
E --> F[Assign error value from nlmsgerr to dereferenced argument]
F --> G[Return NL_STOP]
G --> H[End error_handler function]
Function finish_handler(struct nl_msg msg, void arg)
finish_handler: The function of finish_handler is to handle the completion of a message processing operation.
parameters: The parameters of this Function. · parameter1: struct nl_msg msg - A pointer to the netlink message that is being processed. · parameter2: void arg - A pointer to user-defined data that is passed to the handler, typically used to store a return value.
Code Description: The finish_handler function is defined as a static function, meaning it is limited in scope to the file in which it is declared. It takes two parameters: a pointer to a netlink message (nl_msg) and a pointer to a user-defined argument (arg). Inside the function, the argument is cast to an integer pointer, allowing the function to manipulate the value it points to. The function sets the value pointed to by ret (the integer pointer) to 0, indicating a successful completion of the operation. Finally, the function returns NL_SKIP, which is a constant used in netlink programming to indicate that the message should be skipped in further processing.
Note: It is important to ensure that the argument passed to the finish_handler function is a valid pointer to an integer. This function is typically used as a callback in netlink message handling, and proper initialization of the ret variable is necessary before invoking this handler.
Output Example: If the finish_handler function is called with a valid message and an integer pointer initialized to a non-zero value, the expected behavior would be that the integer value is set to 0, and the function returns NL_SKIP, indicating that no further processing of the message should occur.
activityDiagram
start
:Receive message msg;
:Receive argument arg;
:Set ret to arg;
:Set value pointed by ret to 0;
:Return NL_SKIP;
end
Function ack_handler(struct nl_msg msg, void arg)
ack_handler: The function of ack_handler is to handle acknowledgment messages and set a return value.
parameters: The parameters of this Function. · parameter1: struct nl_msg msg - A pointer to the netlink message that is being processed. · parameter2: void arg - A pointer to an integer that will be used to store the return value.
Code Description: The ack_handler function is a static function designed to process acknowledgment messages received via netlink communication. It takes two parameters: a pointer to a netlink message (msg) and a pointer to a void type (arg). The function begins by casting the void pointer arg to an integer pointer and assigns it to the variable ret. It then dereferences ret to set the value it points to as 0, indicating successful handling of the acknowledgment. Finally, the function returns NL_STOP, which is a constant that signals to the netlink library to stop processing further messages in the current batch. This function is typically used in scenarios where the application needs to confirm that a message has been acknowledged by the kernel or another component in the system.
Note: It is important to ensure that the argument passed as arg is a valid pointer to an integer before invoking this function, as dereferencing a null or invalid pointer can lead to undefined behavior.
Output Example: If the ack_handler function is called with a valid netlink message and a pointer to an integer, the expected behavior would be that the integer pointed to by arg is set to 0, and the function returns NL_STOP, indicating that no further messages should be processed.
graph TD
A[Start ack_handler function] --> B[Receive nl_msg pointer msg]
B --> C[Receive void pointer arg]
C --> D[Cast arg to int pointer ret]
D --> E[Set value at ret to 0]
E --> F[Return NL_STOP]
F --> G[End ack_handler function]
Function __handle_cmd(struct nl80211_state *state, enum id_input idby,
int argc, char **argv, const struct cmd **cmdout)
__handle_cmd: The function of __handle_cmd is to process command-line arguments and execute the corresponding command in the context of a wireless networking state.
parameters: The parameters of this Function. · state: A pointer to the nl80211_state structure that holds the state of the netlink communication. · idby: An enumeration value indicating how the command is identified (e.g., by physical index, name, network device, or wireless device). · argc: An integer representing the number of command-line arguments. · argv: An array of strings containing the command-line arguments. · cmdout: A pointer to a pointer that will be set to the matched command structure.
Code Description: The __handle_cmd function begins by checking if the number of arguments is valid based on the identification method. It initializes variables for command matching and device indexing. Depending on the value of idby, it determines the command identification method and retrieves the corresponding device index. The function then attempts to match the provided section and command against predefined command structures. If a match is found, it prepares to execute the command.
If the command requires a netlink message, the function allocates a netlink message and sets up callbacks for handling responses. It populates the message with the appropriate attributes based on the command identification method. The command handler is then called to execute the command, and the function waits for the response using the netlink socket. The function ensures proper cleanup of allocated resources before returning the result of the command execution.
Note: It is important to ensure that the command and section names provided in the arguments match those defined in the command structures. Additionally, the function handles various command identification methods, so the input should be consistent with the expected format for successful execution.
Output Example: A possible return value of the function could be: - 0: Indicating successful command execution. - 1: Indicating that the command was not found or arguments were invalid. - 2: Indicating an error in allocating resources or sending the netlink message.
graph TD
A[Start] --> B[Check argc and idby]
B -->|argc <= 1 and idby != II_NONE| C[Return 1]
B -->|else| D[Set o_argc and o_argv]
D --> E[Switch idby]
E -->|II_PHY_IDX| F[Set command_idby to CIB_PHY]
F --> G[Parse devidx from argv]
G -->|if tmp is not empty| C
G --> H[Decrement argc and argv]
E -->|II_PHY_NAME| I[Set command_idby to CIB_PHY]
I --> J[Lookup devidx from phy_lookup]
J --> H
E -->|II_NETDEV| K[Set command_idby to CIB_NETDEV]
K --> L[Lookup devidx from if_nametoindex]
L -->|if devidx is 0| M[Set devidx to -1]
L --> H
E -->|II_WDEV| N[Set command_idby to CIB_WDEV]
N --> O[Parse devidx from argv]
O -->|if tmp is not empty| C
O --> H
H --> P[Check if devidx < 0]
P -->|true| Q[Return -errno]
P -->|false| R[Set section from argv]
R --> S[Decrement argc and argv]
S --> T[For each sectcmd]
T -->|if sectcmd->parent| U[Continue]
T -->|if match and sectcmd->idby != command_idby| U
T -->|if sectcmd->name matches section| V[Set match to sectcmd]
V --> W[Check if argc > 0]
W -->|true| X[Set command from argv]
X --> Y[For each cmd]
Y -->|if !cmd->handler| Z[Continue]
Y -->|if cmd->parent != sectcmd| Z
Y -->|if cmd->idby mismatch| Z
Y -->|if cmd->name matches command| AA[Set match to cmd]
AA -->|if match| AB[Decrement argc and argv]
AB -->|else| AC[Set cmd to sectcmd]
AC -->|if argc and !cmd->args| C
AC -->|if cmd->idby mismatch| C
AC -->|if !cmd->handler| C
AC --> AD[Check if cmd->selector exists]
AD -->|true| AE[Set cmd from cmd->selector]
AE -->|if !cmd| C
AD -->|false| AF[Check if cmdout is not null]
AF -->|true| AG[Set *cmdout to cmd]
AG --> AH[Check if cmd->cmd is null]
AH -->|true| AI[Set argc and argv to original]
AI --> AJ[Call cmd->handler]
AH -->|false| AK[nlmsg_alloc]
AK -->|if !msg| AL[Print error and return 2]
AL --> AM[nl_cb_alloc for cb]
AM -->|if !cb| AL
AM --> AN[nl_cb_alloc for s_cb]
AN -->|if !s_cb| AL
AN --> AO[Prepare netlink message]
AO --> AP[Switch command_idby]
AP -->|CIB_PHY| AQ[NLA_PUT_U32 for NL80211_ATTR_WIPHY]
AP -->|CIB_NETDEV| AR[NLA_PUT_U32 for NL80211_ATTR_IFINDEX]
AP -->|CIB_WDEV| AS[NLA_PUT_U64 for NL80211_ATTR_WDEV]
AO --> AT[Call cmd->handler]
AT -->|if err| AU[Go to out]
AU --> AV[nl_socket_set_cb]
AV --> AW[nl_send_auto_complete]
AW -->|if err < 0| AU
AW --> AX[Set up callbacks for nl_cb]
AX --> AY[While err > 0]
AY --> AZ[nl_recvmsgs]
AZ --> BA[out]
BA --> BB[nl_cb_put]
BB --> BC[out_free_msg]
BC --> BD[nlmsg_free]
BD --> BE[Return err]
BE -->|if nla_put_failure| BF[Print building message failed and return 2]
BF --> C
Function handle_cmd(struct nl80211_state *state, enum id_input idby,
int argc, char **argv)
handle_cmd: The function of handle_cmd is to process command-line input by delegating the task to another function, __handle_cmd.
parameters: The parameters of this Function. · state: A pointer to a struct nl80211_state that holds the state information for the nl80211 interface. · idby: An enumeration value of type id_input that indicates the source of the input command. · argc: An integer representing the number of command-line arguments passed to the function. · argv: An array of character pointers (strings) that contains the command-line arguments.
Code Description: The handle_cmd function serves as a wrapper that simplifies the command handling process. It takes four parameters: a pointer to the nl80211_state structure, an enumeration indicating the input source, the count of command-line arguments, and the actual command-line arguments themselves. The function then calls __handle_cmd, passing along these parameters along with a NULL value for an additional parameter that is not utilized in this instance. This design allows for a clean separation of concerns, where handle_cmd focuses on parameter preparation and __handle_cmd handles the core logic of command processing.
Note: It is important to ensure that the nl80211_state structure is properly initialized before calling handle_cmd, as it is essential for the command processing to function correctly. Additionally, the id_input enumeration should be valid to avoid unexpected behavior during command handling.
Output Example: A possible return value of the handle_cmd function could be an integer indicating success (e.g., 0) or an error code (e.g., -1) depending on the outcome of the command processing performed by __handle_cmd.
graph TD
A[Start handle_cmd function] --> B[Receive parameters state, idby, argc, argv]
B --> C[Call __handle_cmd with parameters state, idby, argc, argv, NULL]
C --> D[Return result from __handle_cmd]
D --> E[End handle_cmd function]
Function main(int argc, char **argv)
main: The function of main is to serve as the entry point for the application, handling command-line arguments and executing the appropriate commands based on user input.
parameters: The parameters of this Function. · parameter1: int argc - The count of command-line arguments passed to the program. · parameter2: char **argv - An array of strings representing the command-line arguments.
Code Description: The main function begins by declaring a structure nl80211_state
to hold the state for the nl80211 interface and an integer err
for error handling. It initializes a pointer cmd
to NULL, which will later point to the command structure.
The function calculates the command size by determining the absolute difference between two section addresses, __section_set
and __section_get
. It then decrements argc
to strip off the program name and advances argv
to point to the first argument.
The function checks if the first argument is --debug
, setting a debug flag if true, and similarly checks for --version
, calling the version()
function and returning 0 if found.
If no arguments are provided or if the first argument is help
, it calls the usage()
function to display usage information and returns 0.
The function then initializes the nl80211_state
structure by calling nl80211_init()
. If initialization fails, it returns 1.
The function processes commands based on the first argument. If the command is dev
, phy
, or wdev
, it handles them accordingly by calling __handle_cmd()
with the appropriate parameters. If the command does not match these, it attempts to detect the command type by checking if the first argument corresponds to a network device name or a physical device name.
After executing the command, the function checks the return value err
. If err
is 1, it indicates a failure, and it calls usage_cmd()
if a command was recognized, or usage()
if not. If err
is less than 0, it prints an error message to standard error.
Finally, the function cleans up the nl80211_state
by calling nl80211_cleanup()
and returns the error code err
.
Note: It is important to ensure that the command-line arguments are valid and that the necessary initialization for the nl80211 state is successful before proceeding with command execution. Proper error handling is crucial to provide feedback to the user.
Output Example:
- If the user runs the program with the command ./sdrctl --version
, the output might be:
sdrctl version 1.0.0
command failed: No such device (-19)
graph TD
A[Start main function] --> B[Initialize nl80211_state]
A --> C[Calculate command size]
A --> D[Decrement argc and set argv0]
D --> E{Check if argc > 0}
E -->|Yes| F{Check if argv equals --debug}
E -->|No| G{Check if argc equals 0 or argv equals help}
F -->|Yes| H[Set iw_debug to 1]
F -->|No| I{Check if argv equals --version}
I -->|Yes| J[Call version function]
J --> K[Return 0]
I -->|No| G
G -->|Yes| L[Call usage function]
L --> M[Return 0]
G -->|No| N[Initialize nl80211]
N --> O{Check if err is not 0}
O -->|Yes| P[Return 1]
O -->|No| Q{Check if argv equals dev}
Q -->|Yes| R[Decrement argc and increment argv]
R --> S[Call __handle_cmd with II_NETDEV]
Q -->|No| T{Check if argv starts with phy}
T -->|Yes| U{Check if argv length equals 3}
U -->|Yes| V[Decrement argc and increment argv]
V --> W[Call __handle_cmd with II_PHY_NAME]
U -->|No| X{Check if argv[3] equals #}
X -->|Yes| Y[Call __handle_cmd with II_PHY_IDX]
X -->|No| Z[Go to detect]
Q -->|No| AA{Check if argv equals wdev}
AA -->|Yes| AB[Decrement argc and increment argv]
AB --> AC[Call __handle_cmd with II_WDEV]
AA -->|No| AD[Set idby to II_NONE]
AD --> AE[Detect index using if_nametoindex]
AE --> AF{Check if idx is not 0}
AF -->|Yes| AG[Set idby to II_NETDEV]
AF -->|No| AH[Detect index using phy_lookup]
AH --> AI{Check if idx >= 0}
AI -->|Yes| AJ[Set idby to II_PHY_NAME]
AI -->|No| B[Call __handle_cmd with idby]
B --> AK{Check if err equals 1}
AK -->|Yes| AL{Check if cmd is not null}
AL -->|Yes| AM[Call usage_cmd with cmd]
AL -->|No| AN[Call usage with 0 and NULL]
AK -->|No| AO{Check if err < 0}
AO -->|Yes| AP[Print error message]
AP --> AQ[Call nl80211_cleanup]
AQ --> AR[Return err]
AR --> AS[End main function]