1 | #include <machine/rtems-bsd-kernel-space.h> |
---|
2 | |
---|
3 | /*- |
---|
4 | * Copyright (c) 2009 Sam Leffler, Errno Consulting |
---|
5 | * All rights reserved. |
---|
6 | * |
---|
7 | * Redistribution and use in source and binary forms, with or without |
---|
8 | * modification, are permitted provided that the following conditions |
---|
9 | * are met: |
---|
10 | * 1. Redistributions of source code must retain the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer. |
---|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer in the |
---|
14 | * documentation and/or other materials provided with the distribution. |
---|
15 | * |
---|
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
---|
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
---|
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
---|
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
---|
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
---|
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
---|
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
---|
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
---|
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
---|
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
26 | */ |
---|
27 | |
---|
28 | #include <sys/cdefs.h> |
---|
29 | #ifdef __FreeBSD__ |
---|
30 | __FBSDID("$FreeBSD$"); |
---|
31 | #endif |
---|
32 | |
---|
33 | /* |
---|
34 | * IEEE 802.11 send/recv action frame support. |
---|
35 | */ |
---|
36 | |
---|
37 | #include <rtems/bsd/local/opt_inet.h> |
---|
38 | #include <rtems/bsd/local/opt_wlan.h> |
---|
39 | |
---|
40 | #include <rtems/bsd/sys/param.h> |
---|
41 | #include <sys/kernel.h> |
---|
42 | #include <sys/systm.h> |
---|
43 | |
---|
44 | #include <sys/socket.h> |
---|
45 | |
---|
46 | #include <net/if.h> |
---|
47 | #include <net/if_media.h> |
---|
48 | #include <net/ethernet.h> |
---|
49 | |
---|
50 | #include <net80211/ieee80211_var.h> |
---|
51 | #include <net80211/ieee80211_action.h> |
---|
52 | #include <net80211/ieee80211_mesh.h> |
---|
53 | |
---|
54 | static int |
---|
55 | send_inval(struct ieee80211_node *ni, int cat, int act, void *sa) |
---|
56 | { |
---|
57 | return EINVAL; |
---|
58 | } |
---|
59 | |
---|
60 | static ieee80211_send_action_func *ba_send_action[8] = { |
---|
61 | send_inval, send_inval, send_inval, send_inval, |
---|
62 | send_inval, send_inval, send_inval, send_inval, |
---|
63 | }; |
---|
64 | static ieee80211_send_action_func *ht_send_action[8] = { |
---|
65 | send_inval, send_inval, send_inval, send_inval, |
---|
66 | send_inval, send_inval, send_inval, send_inval, |
---|
67 | }; |
---|
68 | static ieee80211_send_action_func *meshpl_send_action[8] = { |
---|
69 | send_inval, send_inval, send_inval, send_inval, |
---|
70 | send_inval, send_inval, send_inval, send_inval, |
---|
71 | }; |
---|
72 | static ieee80211_send_action_func *meshlm_send_action[4] = { |
---|
73 | send_inval, send_inval, send_inval, send_inval, |
---|
74 | }; |
---|
75 | static ieee80211_send_action_func *hwmp_send_action[8] = { |
---|
76 | send_inval, send_inval, send_inval, send_inval, |
---|
77 | send_inval, send_inval, send_inval, send_inval, |
---|
78 | }; |
---|
79 | static ieee80211_send_action_func *vendor_send_action[8] = { |
---|
80 | send_inval, send_inval, send_inval, send_inval, |
---|
81 | send_inval, send_inval, send_inval, send_inval, |
---|
82 | }; |
---|
83 | |
---|
84 | int |
---|
85 | ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f) |
---|
86 | { |
---|
87 | #define N(a) (sizeof(a) / sizeof(a[0])) |
---|
88 | switch (cat) { |
---|
89 | case IEEE80211_ACTION_CAT_BA: |
---|
90 | if (act >= N(ba_send_action)) |
---|
91 | break; |
---|
92 | ba_send_action[act] = f; |
---|
93 | return 0; |
---|
94 | case IEEE80211_ACTION_CAT_HT: |
---|
95 | if (act >= N(ht_send_action)) |
---|
96 | break; |
---|
97 | ht_send_action[act] = f; |
---|
98 | return 0; |
---|
99 | case IEEE80211_ACTION_CAT_MESHPEERING: |
---|
100 | if (act >= N(meshpl_send_action)) |
---|
101 | break; |
---|
102 | meshpl_send_action[act] = f; |
---|
103 | return 0; |
---|
104 | case IEEE80211_ACTION_CAT_MESHLMETRIC: |
---|
105 | if (act >= N(meshlm_send_action)) |
---|
106 | break; |
---|
107 | meshlm_send_action[act] = f; |
---|
108 | return 0; |
---|
109 | case IEEE80211_ACTION_CAT_MESHPATH: |
---|
110 | if (act >= N(hwmp_send_action)) |
---|
111 | break; |
---|
112 | hwmp_send_action[act] = f; |
---|
113 | return 0; |
---|
114 | case IEEE80211_ACTION_CAT_VENDOR: |
---|
115 | if (act >= N(vendor_send_action)) |
---|
116 | break; |
---|
117 | vendor_send_action[act] = f; |
---|
118 | return 0; |
---|
119 | } |
---|
120 | return EINVAL; |
---|
121 | #undef N |
---|
122 | } |
---|
123 | |
---|
124 | void |
---|
125 | ieee80211_send_action_unregister(int cat, int act) |
---|
126 | { |
---|
127 | ieee80211_send_action_register(cat, act, send_inval); |
---|
128 | } |
---|
129 | |
---|
130 | int |
---|
131 | ieee80211_send_action(struct ieee80211_node *ni, int cat, int act, void *sa) |
---|
132 | { |
---|
133 | #define N(a) (sizeof(a) / sizeof(a[0])) |
---|
134 | ieee80211_send_action_func *f = send_inval; |
---|
135 | |
---|
136 | switch (cat) { |
---|
137 | case IEEE80211_ACTION_CAT_BA: |
---|
138 | if (act < N(ba_send_action)) |
---|
139 | f = ba_send_action[act]; |
---|
140 | break; |
---|
141 | case IEEE80211_ACTION_CAT_HT: |
---|
142 | if (act < N(ht_send_action)) |
---|
143 | f = ht_send_action[act]; |
---|
144 | break; |
---|
145 | case IEEE80211_ACTION_CAT_MESHPEERING: |
---|
146 | if (act < N(meshpl_send_action)) |
---|
147 | f = meshpl_send_action[act]; |
---|
148 | break; |
---|
149 | case IEEE80211_ACTION_CAT_MESHLMETRIC: |
---|
150 | if (act < N(meshlm_send_action)) |
---|
151 | f = meshlm_send_action[act]; |
---|
152 | break; |
---|
153 | case IEEE80211_ACTION_CAT_MESHPATH: |
---|
154 | if (act < N(hwmp_send_action)) |
---|
155 | f = hwmp_send_action[act]; |
---|
156 | break; |
---|
157 | case IEEE80211_ACTION_CAT_VENDOR: |
---|
158 | if (act < N(vendor_send_action)) |
---|
159 | f = vendor_send_action[act]; |
---|
160 | break; |
---|
161 | } |
---|
162 | return f(ni, cat, act, sa); |
---|
163 | #undef N |
---|
164 | } |
---|
165 | |
---|
166 | static int |
---|
167 | recv_inval(struct ieee80211_node *ni, const struct ieee80211_frame *wh, |
---|
168 | const uint8_t *frm, const uint8_t *efrm) |
---|
169 | { |
---|
170 | return EINVAL; |
---|
171 | } |
---|
172 | |
---|
173 | static ieee80211_recv_action_func *ba_recv_action[8] = { |
---|
174 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
175 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
176 | }; |
---|
177 | static ieee80211_recv_action_func *ht_recv_action[8] = { |
---|
178 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
179 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
180 | }; |
---|
181 | static ieee80211_recv_action_func *meshpl_recv_action[8] = { |
---|
182 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
183 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
184 | }; |
---|
185 | static ieee80211_recv_action_func *meshlm_recv_action[4] = { |
---|
186 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
187 | }; |
---|
188 | static ieee80211_recv_action_func *hwmp_recv_action[8] = { |
---|
189 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
190 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
191 | }; |
---|
192 | static ieee80211_recv_action_func *vendor_recv_action[8] = { |
---|
193 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
194 | recv_inval, recv_inval, recv_inval, recv_inval, |
---|
195 | }; |
---|
196 | |
---|
197 | int |
---|
198 | ieee80211_recv_action_register(int cat, int act, ieee80211_recv_action_func *f) |
---|
199 | { |
---|
200 | #define N(a) (sizeof(a) / sizeof(a[0])) |
---|
201 | switch (cat) { |
---|
202 | case IEEE80211_ACTION_CAT_BA: |
---|
203 | if (act >= N(ba_recv_action)) |
---|
204 | break; |
---|
205 | ba_recv_action[act] = f; |
---|
206 | return 0; |
---|
207 | case IEEE80211_ACTION_CAT_HT: |
---|
208 | if (act >= N(ht_recv_action)) |
---|
209 | break; |
---|
210 | ht_recv_action[act] = f; |
---|
211 | return 0; |
---|
212 | case IEEE80211_ACTION_CAT_MESHPEERING: |
---|
213 | if (act >= N(meshpl_recv_action)) |
---|
214 | break; |
---|
215 | meshpl_recv_action[act] = f; |
---|
216 | return 0; |
---|
217 | case IEEE80211_ACTION_CAT_MESHLMETRIC: |
---|
218 | if (act >= N(meshlm_recv_action)) |
---|
219 | break; |
---|
220 | meshlm_recv_action[act] = f; |
---|
221 | return 0; |
---|
222 | case IEEE80211_ACTION_CAT_MESHPATH: |
---|
223 | if (act >= N(hwmp_recv_action)) |
---|
224 | break; |
---|
225 | hwmp_recv_action[act] = f; |
---|
226 | return 0; |
---|
227 | case IEEE80211_ACTION_CAT_VENDOR: |
---|
228 | if (act >= N(vendor_recv_action)) |
---|
229 | break; |
---|
230 | vendor_recv_action[act] = f; |
---|
231 | return 0; |
---|
232 | } |
---|
233 | return EINVAL; |
---|
234 | #undef N |
---|
235 | } |
---|
236 | |
---|
237 | void |
---|
238 | ieee80211_recv_action_unregister(int cat, int act) |
---|
239 | { |
---|
240 | ieee80211_recv_action_register(cat, act, recv_inval); |
---|
241 | } |
---|
242 | |
---|
243 | int |
---|
244 | ieee80211_recv_action(struct ieee80211_node *ni, |
---|
245 | const struct ieee80211_frame *wh, |
---|
246 | const uint8_t *frm, const uint8_t *efrm) |
---|
247 | { |
---|
248 | #define N(a) (sizeof(a) / sizeof(a[0])) |
---|
249 | ieee80211_recv_action_func *f = recv_inval; |
---|
250 | const struct ieee80211_action *ia = |
---|
251 | (const struct ieee80211_action *) frm; |
---|
252 | |
---|
253 | switch (ia->ia_category) { |
---|
254 | case IEEE80211_ACTION_CAT_BA: |
---|
255 | if (ia->ia_action < N(ba_recv_action)) |
---|
256 | f = ba_recv_action[ia->ia_action]; |
---|
257 | break; |
---|
258 | case IEEE80211_ACTION_CAT_HT: |
---|
259 | if (ia->ia_action < N(ht_recv_action)) |
---|
260 | f = ht_recv_action[ia->ia_action]; |
---|
261 | break; |
---|
262 | case IEEE80211_ACTION_CAT_MESHPEERING: |
---|
263 | if (ia->ia_action < N(meshpl_recv_action)) |
---|
264 | f = meshpl_recv_action[ia->ia_action]; |
---|
265 | break; |
---|
266 | case IEEE80211_ACTION_CAT_MESHLMETRIC: |
---|
267 | if (ia->ia_action < N(meshlm_recv_action)) |
---|
268 | f = meshlm_recv_action[ia->ia_action]; |
---|
269 | break; |
---|
270 | case IEEE80211_ACTION_CAT_MESHPATH: |
---|
271 | if (ia->ia_action < N(hwmp_recv_action)) |
---|
272 | f = hwmp_recv_action[ia->ia_action]; |
---|
273 | break; |
---|
274 | case IEEE80211_ACTION_CAT_VENDOR: |
---|
275 | if (ia->ia_action < N(vendor_recv_action)) |
---|
276 | f = vendor_recv_action[ia->ia_action]; |
---|
277 | break; |
---|
278 | } |
---|
279 | return f(ni, wh, frm, efrm); |
---|
280 | #undef N |
---|
281 | } |
---|