Radiotap.c
Function ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_iterator *iterator,
struct ieee80211_radiotap_header *radiotap_header,
int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
ieee80211_radiotap_iterator_init: The function of ieee80211_radiotap_iterator_init is to initialize a radiotap iterator for traversing radiotap headers.
parameters: The parameters of this Function. · iterator: A pointer to the ieee80211_radiotap_iterator structure that will be initialized. · radiotap_header: A pointer to the ieee80211_radiotap_header structure that contains the radiotap header information. · max_length: An integer representing the maximum length of the radiotap data. · vns: A pointer to the ieee80211_radiotap_vendor_namespaces structure that contains vendor-specific namespaces.
Code Description: The ieee80211_radiotap_iterator_init function performs several critical checks and initializations to set up the iterator for processing radiotap headers.
Initially, the function checks if the provided max_length is less than the size of the ieee80211_radiotap_header structure. If it is, the function returns an error code -EINVAL, indicating that the radiotap header cannot be present. Next, it verifies that the radiotap header version is zero, as Linux only supports version 0 of the radiotap format. If the version is not zero, it again returns -EINVAL.
The function then checks if the max_length is less than the length specified in the radiotap header. If this condition is met, it returns -EINVAL, indicating an inconsistency in the provided data.
Upon passing these checks, the function initializes various fields in the iterator structure. It sets the _rtheader field to the provided radiotap_header, and the _max_length field to the length specified in the header. The _arg_index is initialized to zero, and the _bitmap_shifter is set to the present bitmap of the radiotap header, converted from little-endian to CPU format.
The function also sets the _arg field to point to the start of the payload data, which follows the radiotap header. It initializes the _reset_on_ext field to zero and prepares to handle extended bitmaps by setting the _next_bitmap pointer.
If the _bitmap_shifter indicates the presence of extended bitmaps, the function enters a loop to process these extensions. It checks that the iterator's argument pointer does not exceed the maximum length specified. If it does, the function returns -EINVAL. The loop continues to adjust the _arg pointer until no further extensions are indicated.
Finally, the function sets the this_arg field to the current argument pointer and returns 0, indicating successful initialization of the iterator.
Note: It is essential to ensure that the radiotap header and its associated data are correctly formatted and that the maximum length is accurately specified to avoid errors during initialization.
Output Example: A successful call to ieee80211_radiotap_iterator_init might return 0, indicating that the iterator has been initialized correctly and is ready for use. If an error occurs, the function may return -EINVAL, indicating an invalid argument or inconsistency in the provided data.
activityDiagram
start
:Initialize iterator and parameters;
:Check if max_length is less than size of radiotap header;
if (max_length < sizeof(radiotap_header)) then (yes)
:Return -EINVAL;
stop
else (no)
endif
:Check if radiotap_header version is not zero;
if (radiotap_header->it_version != 0) then (yes)
:Return -EINVAL;
stop
else (no)
endif
:Check if max_length is less than radiotap length;
if (max_length < get_unaligned_le16(&radiotap_header->it_len)) then (yes)
:Return -EINVAL;
stop
else (no)
endif
:Set iterator parameters;
:Calculate bitmap shifter;
:Set argument pointer to start of payload;
:Initialize reset and next bitmap;
:Set current namespace and is_radiotap_ns;
:Check if bitmap shifter indicates extended bitmap;
if (iterator->_bitmap_shifter & (1 << IEEE80211_RADIOTAP_EXT)) then (yes)
:Check if argument exceeds max_length;
if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + sizeof(uint32_t) > (unsigned long)iterator->_max_length) then (yes)
:Return -EINVAL;
stop
else (no)
endif
:Iterate through extended bitmaps;
while (le32_to_cpu(*((u32 *)iterator->_arg)) & (1 << IEEE80211_RADIOTAP_EXT)) {
:Increment argument pointer;
:Check if argument exceeds max_length;
if ((unsigned long)iterator->_arg - (unsigned long)iterator->_rtheader + sizeof(uint32_t) > (unsigned long)iterator->_max_length) then (yes)
:Return -EINVAL;
stop
else (no)
endif
}
:Increment argument pointer;
else (no)
endif
:Set this_arg to current argument;
:Return 0;
stop
Function find_ns(struct ieee80211_radiotap_iterator *iterator,
uint32_t oui, uint8_t subns)
find_ns: The function of find_ns is to locate a specific namespace within a radiotap iterator based on a given Organizationally Unique Identifier (OUI) and a subnamespace identifier.
parameters: The parameters of this Function. · parameter1: struct ieee80211_radiotap_iterator *iterator - A pointer to the radiotap iterator structure that contains the current state and data for iterating over radiotap namespaces. · parameter2: uint32_t oui - The Organizationally Unique Identifier that identifies the organization associated with the namespace. · parameter3: uint8_t subns - The subnamespace identifier that specifies a particular subnamespace within the organization.
Code Description: The find_ns function begins by initializing the current_namespace pointer in the iterator to NULL, indicating that no namespace has been found yet. It then checks if the _vns member of the iterator is NULL. If it is, the function returns immediately, as there are no namespaces to search through.
If _vns is not NULL, the function enters a loop that iterates over all namespaces present in the _vns structure. The loop runs from 0 to n_ns, which is the total number of namespaces. For each namespace, the function checks if the OUI of the current namespace matches the provided oui parameter. If they do not match, the loop continues to the next iteration.
If the OUI matches, the function then checks if the subns of the current namespace matches the provided subns parameter. If both the OUI and subns match, the current_namespace pointer in the iterator is set to point to the current namespace, and the loop is exited. If no matching namespace is found after checking all namespaces, the current_namespace remains NULL.
Note: It is important to ensure that the iterator's _vns member is properly initialized before calling this function. Additionally, the function does not handle cases where multiple namespaces could match the provided OUI and subns; it will only set the current_namespace to the first match found.
Output Example: If the function is called with a valid iterator that contains namespaces, a matching OUI of 0x001A11 and a subns of 0x01, and if such a namespace exists, the current_namespace in the iterator will point to that specific namespace structure. If no match is found, current_namespace will remain NULL.
graph TD
A[Start find_ns function] --> B[Set current_namespace to NULL]
B --> C[Check if _vns is NULL]
C -->|Yes| D[Return from function]
C -->|No| E[Initialize loop variable i]
E --> F[Check if i < n_ns]
F -->|Yes| G[Check if oui matches]
G -->|No| H[Increment i]
H --> F
G -->|Yes| I[Check if subns matches]
I -->|No| J[Increment i]
J --> F
I -->|Yes| K[Set current_namespace to matching ns]
K --> L[Break loop]
L --> M[End find_ns function]
F -->|No| M
Function ieee80211_radiotap_iterator_next(
struct ieee80211_radiotap_iterator *iterator)
ieee80211_radiotap_iterator_next: The function of ieee80211_radiotap_iterator_next is to iterate through the radiotap header fields and retrieve the next available argument based on the current iterator state.
parameters: The parameters of this Function. · iterator: A pointer to a struct ieee80211_radiotap_iterator that maintains the state of the iteration over the radiotap header.
Code Description: The ieee80211_radiotap_iterator_next function is designed to traverse the fields of a radiotap header, which is a data structure used in wireless networking to convey information about the physical layer of the transmitted packets. The function operates in a loop, continuously checking for the presence of arguments in the radiotap header until it either finds a valid argument or determines that there are no more arguments to process.
The function begins by checking if there are any remaining extended bits in the bitmap that indicates the presence of arguments. If no more arguments are available, it returns -ENOENT, signaling the end of the iteration. If the current argument is not present, it proceeds to the next entry.
The function determines the alignment and size of the data based on the current argument index. Different cases are handled depending on whether the argument is part of the standard radiotap namespace, a vendor namespace, or an extension. If the argument is not aligned properly, padding is applied to ensure correct alignment before accessing the data.
In the case of a vendor namespace, the function retrieves the Organizationally Unique Identifier (OUI) and the subnamespace, which are used to identify the vendor-specific data structure. It also calculates the length of the vendor namespace data and updates the iterator's state accordingly.
The function updates the iterator's current argument index and the argument data pointer, ensuring that the next call to the function will have the correct state to continue iterating. It also checks for any inconsistencies, such as exceeding the maximum length of the radiotap section, returning -EINVAL if such a condition is detected.
Special cases for the argument types are handled, including resetting the iterator state when encountering vendor namespaces or the radiotap namespace. If a valid argument is found, the function returns 0, indicating success.
Note: It is important to ensure that the iterator is properly initialized before calling this function. The function assumes that the radiotap header is correctly formatted and that the iterator's state is consistent with the data being processed.
Output Example: A successful call to ieee80211_radiotap_iterator_next may return 0, indicating that a valid argument has been found, and the iterator's state will be updated to reflect the current argument's index and size. If there are no more arguments to process, the function will return -ENOENT.
activityDiagram
title ieee80211_radiotap_iterator_next Flow
start
:Initialize hit to 0;
:Initialize pad, align, size, subns, oui;
repeat
if (Check for no more EXT bits?) then (yes)
:Return -ENOENT;
else (no)
if (Check if arg is present?) then (no)
:Go to next entry;
else (yes)
:Get alignment and size of data;
switch (arg index % 32)
case (RADIOTAP_NAMESPACE or EXT)
:Set align to 1;
:Set size to 0;
case (VENDOR_NAMESPACE)
:Set align to 2;
:Set size to 6;
else
if (Check current namespace and arg index) then (no)
if (current namespace is radiotap_ns) then (yes)
:Return -ENOENT;
else
:Set align to 0;
else (yes)
:Set align and size from current namespace;
if (Check if align is 0) then (yes)
:Skip all subsequent data;
:Give up on this namespace;
:Go to next entry;
end
end
:Calculate padding;
if (Check if arg index is VENDOR_NAMESPACE) then (yes)
if (Check for max length) then (no)
:Return -EINVAL;
end
:Extract oui and subns;
:Find namespace;
:Get vnslen;
:Update next ns data;
if (Check if current namespace is NULL) then (yes)
:Increase size by vnslen;
end
end
:Set this_arg_index, this_arg, and this_arg_size;
:Move arg pointer by size;
if (Check for insanity in bitmap) then (yes)
:Return -EINVAL;
end
switch (arg index % 32)
case (VENDOR_NAMESPACE)
:Set reset_on_ext to 1;
:Set is_radiotap_ns to 0;
:Set this_arg_index to VENDOR_NAMESPACE;
if (Check if current namespace is NULL) then (yes)
:Set hit to 1;
end
:Go to next entry;
case (RADIOTAP_NAMESPACE)
:Set reset_on_ext to 1;
:Set current_namespace to radiotap_ns;
:Set is_radiotap_ns to 1;
:Go to next entry;
case (EXT)
:Update bitmap shifter;
if (Check reset_on_ext) then (yes)
:Reset arg index to 0;
else (no)
:Increment arg index;
end
:Reset reset_on_ext to 0;
default
:Set hit to 1;
:Go to next entry;
end
if (Check if hit is true) then (yes)
:Return 0;
end
end
end
repeat while (true)
end