libwifi 0.0.3
An 802.11 Frame Parsing and Generation library in C
frame.c
Go to the documentation of this file.
1/* Copyright 2021 The libwifi Authors
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "frame.h"
17#include "../../parse/misc/radiotap.h"
18#include "../misc/byteswap.h"
19#include "../radiotap/radiotap.h"
20
21#include <errno.h>
22#include <stdlib.h>
23#include <string.h>
24
25/*
26 * Turn sniffed data into a libwifi_frame struct for use with other libwifi functions.
27 *
28 * Supported frames:
29 * - Management Frames (Ordered)
30 * - Management Frames (Unordered)
31 * - Data Frames
32 * - QoS Data Frames
33 * - Control Frames
34 */
35int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len,
36 int radiotap) {
37 union libwifi_frame_header fh = {0};
38 size_t header_len = 0;
39 size_t frame_data_len = frame_len;
40 unsigned char *frame_data = malloc(frame_data_len);
41 memcpy(frame_data, (unsigned char *) frame, frame_data_len);
42
43 if (radiotap) {
44 struct libwifi_radiotap_info rtap_info = {0};
45 libwifi_parse_radiotap_info(&rtap_info, frame_data, frame_len);
46
47 // Skip forward by the length of the radiotap header
48 frame_data_len -= rtap_info.length;
49 unsigned char *new_data = malloc(frame_data_len);
50 memcpy(new_data, frame_data + rtap_info.length, frame_data_len);
51 free(frame_data);
52 frame_data = new_data;
53
54 // Remove the FCS from the end of the frame data, if present
55 if (rtap_info.flags & IEEE80211_RADIOTAP_F_FCS) {
57 frame_data_len -= sizeof(uint32_t); // FCS is 4 bytes wide
58 frame_data = realloc(frame_data, frame_data_len);
59 if (frame_data == NULL) {
60 return -ENOMEM;
61 }
62 }
63 }
64
65 struct libwifi_frame_ctrl *frame_control = (struct libwifi_frame_ctrl *) frame_data;
66
67 switch (frame_control->type) {
68 case TYPE_DATA:
69 switch (frame_control->subtype) {
78 break;
79 }
80
81 if (fi->flags & LIBWIFI_FLAGS_IS_QOS) {
82 header_len = sizeof(struct libwifi_data_qos_frame_header);
83 } else {
84 header_len = sizeof(struct libwifi_data_frame_header);
85 }
86
87 if (frame_data_len < header_len) {
88 free(frame_data);
89 return -EINVAL;
90 }
91
92 if (fi->flags & LIBWIFI_FLAGS_IS_QOS) {
93 memset(&fh.data_qos, 0, sizeof(struct libwifi_data_qos_frame_header));
94 memcpy(&fh.data_qos, frame_data, sizeof(struct libwifi_data_qos_frame_header));
95 } else {
96 memset(&fh.data, 0, sizeof(struct libwifi_data_frame_header));
97 memcpy(&fh.data, frame_data, sizeof(struct libwifi_data_frame_header));
98 }
99 break;
100 case TYPE_MANAGEMENT:
103 header_len = sizeof(struct libwifi_mgmt_ordered_frame_header);
104 if (frame_data_len < header_len) {
105 free(frame_data);
106 return -EINVAL;
107 }
108 memcpy(&fh.mgmt_ordered, frame_data, header_len);
109 } else {
110 header_len = sizeof(struct libwifi_mgmt_unordered_frame_header);
111 if (frame_data_len < header_len) {
112 free(frame_data);
113 return -EINVAL;
114 }
115 memcpy(&fh.mgmt_unordered, frame_data, header_len);
116 }
117 break;
118 case TYPE_CONTROL:
119 header_len = sizeof(struct libwifi_ctrl_frame_header);
120 if (frame_data_len < header_len) {
121 free(frame_data);
122 return -EINVAL;
123 }
124 memcpy(&fh.ctrl, frame_data, sizeof(struct libwifi_ctrl_frame_header));
125 break;
126 default:
127 free(frame_data);
128 return -EINVAL;
129 }
130
131 fi->len = frame_data_len;
132 fi->header = fh;
133 fi->header_len = header_len;
134 memcpy(&fi->frame_control, frame_control, sizeof(struct libwifi_frame_ctrl));
135
136 fi->body = malloc(fi->len - fi->header_len);
137 memcpy(fi->body, frame_data + header_len, (fi->len - fi->header_len));
138
139 free(frame_data);
140
141 return 0;
142}
143
145 free(fi->body);
146}
@ IEEE80211_RADIOTAP_F_FCS
Definition: radiotap.h:106
void libwifi_free_wifi_frame(struct libwifi_frame *fi)
Free any dynamically allocated data inside a libwifi_frame.
Definition: frame.c:144
int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, size_t frame_len, int radiotap)
Convert a sniffed 802.11 frame into a libwifi_frame.
Definition: frame.c:35
@ SUBTYPE_DATA_QOS_CF_ACK_CF_POLL
Definition: frame.h:95
@ SUBTYPE_DATA_QOS_CF_POLL
Definition: frame.h:94
@ SUBTYPE_DATA_QOS_DATA_CF_POLL
Definition: frame.h:90
@ SUBTYPE_DATA_QOS_NULL
Definition: frame.h:92
@ SUBTYPE_DATA_QOS_DATA_CF_ACK
Definition: frame.h:89
@ SUBTYPE_DATA_QOS_DATA
Definition: frame.h:88
@ SUBTYPE_DATA_QOS_DATA_CF_ACK_CF_POLL
Definition: frame.h:91
#define LIBWIFI_FLAGS_IS_ORDERED
Definition: frame.h:27
@ TYPE_DATA
Definition: frame.h:33
@ TYPE_MANAGEMENT
Definition: frame.h:31
@ TYPE_CONTROL
Definition: frame.h:32
struct libwifi_frame_ctrl frame_control
Definition: frame.h:0
#define LIBWIFI_FLAGS_FCS_PRESENT
Definition: frame.h:25
#define LIBWIFI_FLAGS_IS_QOS
Definition: frame.h:26
int libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame, size_t frame_len)
The libwifi radiotap parser uses the usual ieee80211_radiotap_iterator to parse incoming radiotap hea...
Definition: radiotap.c:27
unsigned int ordered
Definition: frame.h:115
unsigned int type
Definition: frame.h:123
struct libwifi_frame_ctrl_flags flags
Definition: frame.h:125
unsigned int subtype
Definition: frame.h:124
union libwifi_frame_header header
Definition: frame.h:312
uint16_t flags
Definition: frame.h:309
unsigned char * body
Definition: frame.h:314
size_t len
Definition: frame.h:311
struct libwifi_frame_ctrl frame_control
Definition: frame.h:310
size_t header_len
Definition: frame.h:313
struct libwifi_ctrl_frame_header ctrl
Definition: frame.h:291
struct libwifi_mgmt_unordered_frame_header mgmt_unordered
Definition: frame.h:290
struct libwifi_mgmt_ordered_frame_header mgmt_ordered
Definition: frame.h:289
struct libwifi_data_qos_frame_header data_qos
Definition: frame.h:293
struct libwifi_data_frame_header data
Definition: frame.h:292