source: ReferenceDesigns/w3_802.11/c/wlan_mac_high_framework/wlan_mac_addr_filter.c

Last change on this file was 6319, checked in by chunter, 5 years ago

1.8.0 release wlan-mac-se

File size: 7.6 KB
Line 
1/** @file wlan_mac_addr_mac_filter.c
2 *  @brief Address Filter
3 *
4 *  This contains code for the filtering MAC addresses
5 *
6 *  @copyright Copyright 2014-2019, Mango Communications. All rights reserved.
7 *          Distributed under the Mango Communications Reference Design License
8 *              See LICENSE.txt included in the design archive or
9 *              at http://mangocomm.com/802.11/license
10 *
11 *  This file is part of the Mango 802.11 Reference Design (https://mangocomm.com/802.11)
12 */
13
14/***************************** Include Files *********************************/
15
16#include "wlan_mac_high_sw_config.h"
17
18#include "stdio.h"
19#include "stdlib.h"
20#include "string.h"
21#include "xil_types.h"
22#include "wlan_mac_addr_filter.h"
23#include "wlan_mac_dl_list.h"
24#include "wlan_mac_high.h"
25#include "wlan_mac_network_info.h"
26
27
28/*************************** Constant Definitions ****************************/
29
30
31/*********************** Global Variable Definitions *************************/
32
33
34/*************************** Variable Definitions ****************************/
35
36
37// **********************************************************************
38// White-list for address ranges
39//
40// For the mask, bits that are 0 are treated as "any" and bits that are 1 are treated as "must equal"
41// For the compare, locations of one bits in the mask must match whitelist_range_compare for incoming addresses
42//
43
44dl_list addr_filter;
45
46// Defines for Mango Hardware
47static u8 mango_range_mask[MAC_ADDR_LEN]    = { 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00 };
48static u8 mango_range_compare[MAC_ADDR_LEN] = { 0x40, 0xD8, 0x55, 0x04, 0x20, 0x00 };
49
50
51/*************************** Functions Prototypes ****************************/
52
53u8 addr_is_allowed(u8* addr, u8* mask, u8* compare);
54
55/******************************** Functions **********************************/
56
57/*****************************************************************************/
58/**
59 * @brief Initialize the Address Filter
60 *
61 * This function will initialize the address filter
62 *
63 * @param    None.
64 * @return   None.
65 */
66void wlan_mac_addr_filter_init() {
67    // Setup the address filter
68    dl_list_init(&addr_filter);
69}
70
71
72
73/*****************************************************************************/
74/**
75 * @brief Reset the Address Filter
76 *
77 * This function will reset the address filter back to the default state of
78 * "allow all" (ie mask = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, range =
79 * { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) and free all memory associated
80 * with the white-list ranges.
81 *
82 * @param    None.
83 * @return   None.
84 */
85void wlan_mac_addr_filter_reset() {
86    int iter;
87    whitelist_range* curr_range;
88    dl_entry* next_range_dl_entry;
89    dl_entry* curr_range_dl_entry;
90
91    iter = addr_filter.length;
92    next_range_dl_entry = addr_filter.first;
93
94    // Remove all ranges from the address filter
95    while ((next_range_dl_entry != NULL) && (iter-- > 0)) {
96        curr_range_dl_entry = next_range_dl_entry;
97        next_range_dl_entry = dl_entry_next(curr_range_dl_entry);
98
99        curr_range = (whitelist_range*)(curr_range_dl_entry->data);
100
101        dl_entry_remove(&addr_filter, curr_range_dl_entry);
102
103        // Free allocated memory
104        wlan_mac_high_free(curr_range_dl_entry);
105        wlan_mac_high_free(curr_range);
106    }
107
108    if (addr_filter.length != 0) {
109        xil_printf("ERROR:  Could not fully reset address filter.");
110    }
111}
112
113
114
115/*****************************************************************************/
116/**
117 * @brief Add a white-list range to the Address Filter
118 *
119 * This function will allocate memory for a white-list range and add that to
120 * the current list being used to filter addresses.
121 *
122 * @param    u8 * mask    - Mask for the white-list range
123 * @param    u8 * compare - Compare address for the white-list range
124 * @return   int  - Was this filter added successfully
125 *      - nonzero if error
126 */
127int wlan_mac_addr_filter_add(u8* mask, u8* compare) {
128    whitelist_range* range;
129    dl_entry* entry;
130
131    // Allocate memory for the entry and the white-list range
132    entry = wlan_mac_high_malloc(sizeof(dl_entry));
133
134    if (entry == NULL) {
135        return WLAN_FAILURE;
136    }
137
138    range = wlan_mac_high_malloc(sizeof(whitelist_range));
139
140    if (range == NULL) {
141        wlan_mac_high_free(entry);
142        return WLAN_FAILURE;
143    }
144
145    entry->data = (void*)range;
146
147    // Copy the mask and compare address to the new range
148    memcpy(&(range->mask[0]), mask, MAC_ADDR_LEN);
149    memcpy(&(range->compare[0]), compare, MAC_ADDR_LEN);
150
151    // Add this range at the end of the address filter
152    dl_entry_insertEnd(&addr_filter, entry);
153
154    return WLAN_SUCCESS;
155}
156
157
158
159/*****************************************************************************/
160/**
161 * @brief Is the given address allowed?
162 *
163 * This function will apply the filter to the given address and return whether
164 * the address passed the filter.
165 *
166 * @param    u8 * addr  - Address to check against the filter
167 * @return   u8
168 *      - ADDR_FILTER_ADDR_NOT_ALLOWED if address is not allowed
169 *      - ADDR_FILTER_ADDR_ALLOWED if address is allowed
170 */
171u8 wlan_mac_addr_filter_is_allowed(u8* addr){
172    int iter;
173    u32 list_len = addr_filter.length;
174    whitelist_range* curr_range;
175    dl_entry* curr_range_dl_entry;
176
177    // Check if the list is empty
178    //     - By default, we allow all addresses
179    //
180    if (list_len == 0) { return ADDR_FILTER_ADDR_ALLOWED; }
181
182
183    // Check if the incoming address is within the allowable range of addresses
184    iter                = addr_filter.length;
185    curr_range_dl_entry = addr_filter.first;
186
187    while ((curr_range_dl_entry != NULL) && (iter-- > 0)) {
188
189        curr_range = (whitelist_range*)(curr_range_dl_entry->data);
190
191        if (addr_is_allowed(addr, (curr_range->mask), (curr_range->compare)) == ADDR_FILTER_ADDR_ALLOWED) {
192            return ADDR_FILTER_ADDR_ALLOWED;
193        }
194
195        curr_range_dl_entry = dl_entry_next(curr_range_dl_entry);
196    }
197
198    // If the code made it this far, we aren't allowing this address to join the network.
199    return ADDR_FILTER_ADDR_NOT_ALLOWED;
200}
201
202/*****************************************************************************/
203/**
204 * @brief Is the given address a Mango node?
205 *
206 * This function will check if the given address is in the Mango address range.
207 *
208 * @param    u8 * addr  - Address to check against the filter
209 * @return   u8
210 *      - ADDR_FILTER_ADDR_NOT_ALLOWED if address is not a Mango address
211 *      - ADDR_FILTER_ADDR_ALLOWED if address is a Mango address
212 */
213u8 wlan_mac_addr_is_mango(u8* addr){
214    return addr_is_allowed(addr, mango_range_mask, mango_range_compare);
215}
216
217/*****************************************************************************/
218/**
219 * @brief Internal address checking method
220 *
221 * This function will check the address against the given address range.
222 *
223 * @param    u8 * addr    - Address to check against the address range
224 * @param    u8 * mask    - Mask of the address range
225 * @param    u8 * compare - Compare address of the address range
226 * @return   u8
227 *      - ADDR_FILTER_ADDR_NOT_ALLOWED if address is not in the range
228 *      - ADDR_FILTER_ADDR_ALLOWED if address is in the range
229 */
230u8 addr_is_allowed(u8* addr, u8* mask, u8* compare){
231    u32 i;
232    u32 sum;
233
234    sum = 0;
235
236    for (i = 0; i < MAC_ADDR_LEN; i++) {
237        sum += (mask[i] & compare[i]) == (mask[i] & addr[i]);
238    }
239
240    if (sum == MAC_ADDR_LEN) {
241        return ADDR_FILTER_ADDR_ALLOWED;
242    } else {
243        return ADDR_FILTER_ADDR_NOT_ALLOWED;
244    }
245}
246
247
248
249
250
Note: See TracBrowser for help on using the repository browser.