1 #if !defined(CONFIG_MBED_ENABLED) && !defined(CONFIG_PLATFOMR_CUSTOMER_RTOS)
2 #include "main.h"
3 #include "lwip/tcpip.h"
4 #endif
5 #include <osdep_service.h>
6 #include "wifi/wifi_conf.h"
7 #include "k_api.h"
8 #ifndef CONFIG_WLAN
9 #define CONFIG_WLAN 1
10 #endif
11 
12 #if CONFIG_WLAN
13 #include <platform/platform_stdlib.h>
14 
15 extern void _promisc_deinit(void *padapter);
16 extern int _promisc_recv_func(void *padapter, void *rframe);
17 extern int _promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used);
18 extern unsigned char _is_promisc_enabled(void);
19 extern int _promisc_get_fixed_channel(void * fixed_bssid, u8 *ssid, int * ssid_length);
20 extern void _promisc_filter_by_ap_and_phone_mac(u8 enable, void *ap_mac, void *phone_mac);
21 // Add extra interfaces to make release sdk able to determine promisc API linking
promisc_deinit(void * padapter)22 void promisc_deinit(void *padapter)
23 {
24 #ifdef CONFIG_PROMISC
25 	_promisc_deinit(padapter);
26 #endif
27 }
28 
promisc_recv_func(void * padapter,void * rframe)29 int promisc_recv_func(void *padapter, void *rframe)
30 {
31 	// Never reach here if not define CONFIG_PROMISC
32 #ifdef CONFIG_PROMISC
33 	return _promisc_recv_func(padapter, rframe);
34 #else
35 	return 0;
36 #endif
37 }
38 
promisc_recv_lens_func(void * padapter,u8 * payload,u8 plen)39 int promisc_recv_lens_func(void *padapter, u8 *payload, u8 plen)
40 {
41 	/* To avoid gcc warnings */
42 	( void ) padapter;
43 	( void ) payload;
44 	( void ) plen;
45 
46 	// Never reach here if not define CONFIG_PROMISC
47 #ifdef CONFIG_PROMISC
48 	#if defined(CONFIG_UNSUPPORT_PLCPHDR_RPT) && CONFIG_UNSUPPORT_PLCPHDR_RPT
49 		return _promisc_recv_lens_func(padapter, payload, plen);
50 	#else
51 		return 0;
52 	#endif
53 #else
54 	return 0;
55 #endif
56 }
57 
promisc_filter_with_len(u16 len)58 int promisc_filter_with_len(u16 len)
59 {
60 	/* To avoid gcc warnings */
61 	( void ) len;
62 
63 	// Never reach here if not define CONFIG_PROMISC
64 #ifdef CONFIG_PROMISC
65 	#if defined(CONFIG_UNSUPPORT_PLCPHDR_RPT) && CONFIG_UNSUPPORT_PLCPHDR_RPT
66 		return _promisc_filter_with_len(len);
67 	#else
68 		return -1;
69 	#endif
70 #else
71 	return -1;
72 #endif
73 }
74 
promisc_set(rtw_rcr_level_t enabled,void (* callback)(unsigned char *,unsigned int,void *),unsigned char len_used)75 int promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used)
76 {
77 #ifdef CONFIG_PROMISC
78 	return _promisc_set(enabled, callback, len_used);
79 #else
80 	return -1;
81 #endif
82 }
83 
is_promisc_enabled(void)84 unsigned char is_promisc_enabled(void)
85 {
86 #ifdef CONFIG_PROMISC
87 	return _is_promisc_enabled();
88 #else
89 	return 0;
90 #endif
91 }
92 
promisc_get_fixed_channel(void * fixed_bssid,u8 * ssid,int * ssid_length)93 int promisc_get_fixed_channel(void *fixed_bssid, u8 *ssid, int *ssid_length)
94 {
95 #ifdef CONFIG_PROMISC
96 	return _promisc_get_fixed_channel(fixed_bssid, ssid, ssid_length);
97 #else
98 	return 0;
99 #endif
100 }
101 
promisc_filter_by_ap_and_phone_mac(u8 enable,void * ap_mac,void * phone_mac)102 void promisc_filter_by_ap_and_phone_mac(u8 enable, void *ap_mac, void *phone_mac)
103 {
104 #ifdef CONFIG_PROMISC
105 	_promisc_filter_by_ap_and_phone_mac(enable, ap_mac, phone_mac);
106 #endif
107 }
108 
109 // End of Add extra interfaces
110 
111 struct eth_frame {
112 	struct eth_frame *prev;
113 	struct eth_frame *next;
114 	unsigned char da[6];
115 	unsigned char sa[6];
116 	unsigned int len;
117 	unsigned char type;
118 	signed char rssi;
119 };
120 
121 #ifndef CONFIG_INIC_CMD_RSP
122 #define CONFIG_INIC_CMD_RSP	0
123 #endif
124 
125 #if CONFIG_INIC_CMD_RSP
126 #if defined(__IAR_SYSTEMS_ICC__) || defined (__GNUC__)
127 #pragma pack(1)
128 #endif
129 struct inic_eth_frame {
130 	unsigned char da[6];
131 	unsigned char sa[6];
132 	unsigned int len;
133 	unsigned char type;
134 };
135 #if defined(__IAR_SYSTEMS_ICC__) || defined (__GNUC__)
136 #pragma pack()
137 #endif
138 
139 static struct inic_eth_frame *inic_frame, *inic_frame_tail = NULL;
140 static int inic_frame_cnt = 0;
141 #define MAX_INIC_FRAME_NUM 50 //maximum packets for each channel
142 extern void inic_c2h_msg(const char *atcmd, char status, char *msg, u16 msg_len);
143 #endif
144 
145 struct eth_buffer {
146 	struct eth_frame *head;
147 	struct eth_frame *tail;
148 };
149 
150 static struct eth_buffer eth_buffer;
151 
152 #ifdef CONFIG_PROMISC
153 #define MAX_PACKET_FILTER_INFO 5
154 #define FILTER_ID_INIT_VALUE 10
155 rtw_packet_filter_info_t paff_array[MAX_PACKET_FILTER_INFO]={0};
156 static u8 packet_filter_enable_num = 0;
157 
promisc_init_packet_filter(void)158 void promisc_init_packet_filter(void)
159 {
160 	int i = 0;
161 	for(i=0; i<MAX_PACKET_FILTER_INFO; i++){
162 		paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
163 		paff_array[i].enable = 0;
164 		paff_array[i].patt.mask_size = 0;
165 		paff_array[i].rule = RTW_POSITIVE_MATCHING;
166 		paff_array[i].patt.mask = NULL;
167 		paff_array[i].patt.pattern = NULL;
168 	}
169 	packet_filter_enable_num = 0;
170 }
171 
promisc_add_packet_filter(u8 filter_id,rtw_packet_filter_pattern_t * patt,rtw_packet_filter_rule_t rule)172 int promisc_add_packet_filter(u8 filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_t rule)
173 {
174 	int i = 0;
175 	while(i < MAX_PACKET_FILTER_INFO){
176 		if(paff_array[i].filter_id == FILTER_ID_INIT_VALUE){
177 			break;
178 		}
179 		i++;
180 	}
181 
182 	if(i == MAX_PACKET_FILTER_INFO)
183 		return -1;
184 
185 	paff_array[i].filter_id = filter_id;
186 
187 	paff_array[i].patt.offset= patt->offset;
188 	paff_array[i].patt.mask_size = patt->mask_size;
189 	paff_array[i].patt.mask = rtw_malloc(patt->mask_size);
190 	memcpy(paff_array[i].patt.mask, patt->mask, patt->mask_size);
191 	paff_array[i].patt.pattern= rtw_malloc(patt->mask_size);
192 	memcpy(paff_array[i].patt.pattern, patt->pattern, patt->mask_size);
193 
194 	paff_array[i].rule = rule;
195 	paff_array[i].enable = 0;
196 
197 	return 0;
198 }
199 
promisc_enable_packet_filter(u8 filter_id)200 int promisc_enable_packet_filter(u8 filter_id)
201 {
202 	int i = 0;
203 	while(i < MAX_PACKET_FILTER_INFO){
204 		if(paff_array[i].filter_id == filter_id)
205 			break;
206 		i++;
207 	}
208 
209 	if(i == MAX_PACKET_FILTER_INFO)
210 		return -1;
211 
212 	paff_array[i].enable = 1;
213 	packet_filter_enable_num++;
214 	return 0;
215 }
216 
promisc_disable_packet_filter(u8 filter_id)217 int promisc_disable_packet_filter(u8 filter_id)
218 {
219 	int i = 0;
220 	while(i < MAX_PACKET_FILTER_INFO){
221 		if(paff_array[i].filter_id == filter_id)
222 			break;
223 		i++;
224 	}
225 
226 	if(i == MAX_PACKET_FILTER_INFO)
227 		return -1;
228 
229 	paff_array[i].enable = 0;
230 	packet_filter_enable_num--;
231 	return 0;
232 }
233 
promisc_remove_packet_filter(u8 filter_id)234 int promisc_remove_packet_filter(u8 filter_id)
235 {
236 	int i = 0;
237 	while(i < MAX_PACKET_FILTER_INFO){
238 		if(paff_array[i].filter_id == filter_id)
239 			break;
240 		i++;
241 	}
242 
243 	if(i == MAX_PACKET_FILTER_INFO)
244 		return -1;
245 
246 	paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
247 	paff_array[i].enable = 0;
248 	paff_array[i].patt.mask_size = 0;
249 	paff_array[i].rule = 0;
250 	if(paff_array[i].patt.mask){
251 		rtw_free(paff_array[i].patt.mask);
252 		paff_array[i].patt.mask = NULL;
253 	}
254 
255 	if(paff_array[i].patt.pattern){
256 		rtw_free(paff_array[i].patt.pattern);
257 		paff_array[i].patt.pattern = NULL;
258 	}
259 	return 0;
260 }
261 #endif
262 
263 /*	Make callback simple to prevent latency to wlan rx when promiscuous mode */
promisc_callback(unsigned char * buf,unsigned int len,void * userdata)264 static void promisc_callback(unsigned char *buf, unsigned int len, void* userdata)
265 {
266 	struct eth_frame *frame = (struct eth_frame *) rtw_malloc(sizeof(struct eth_frame));
267 	_lock lock;
268 	_irqL irqL;
269 
270 	if(frame) {
271 		frame->prev = NULL;
272 		frame->next = NULL;
273 		memcpy(frame->da, buf, 6);
274 		memcpy(frame->sa, buf+6, 6);
275 		frame->len = len;
276 		frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
277 
278 		rtw_enter_critical(&lock, &irqL);
279 
280 		if(eth_buffer.tail) {
281 			eth_buffer.tail->next = frame;
282 			frame->prev = eth_buffer.tail;
283 			eth_buffer.tail = frame;
284 		}
285 		else {
286 			eth_buffer.head = frame;
287 			eth_buffer.tail = frame;
288 		}
289 
290 		rtw_exit_critical(&lock, &irqL);
291 	}
292 }
293 
retrieve_frame(void)294 struct eth_frame* retrieve_frame(void)
295 {
296 	struct eth_frame *frame = NULL;
297 	_lock lock;
298 	_irqL irqL;
299 
300 	rtw_enter_critical(&lock, &irqL);
301 
302 	if(eth_buffer.head) {
303 		frame = eth_buffer.head;
304 
305 		if(eth_buffer.head->next) {
306 			eth_buffer.head = eth_buffer.head->next;
307 			eth_buffer.head->prev = NULL;
308 		}
309 		else {
310 			eth_buffer.head = NULL;
311 			eth_buffer.tail = NULL;
312 		}
313 	}
314 
315 	rtw_exit_critical(&lock, &irqL);
316 
317 	return frame;
318 }
319 
promisc_test(int duration,unsigned char len_used)320 static void promisc_test(int duration, unsigned char len_used)
321 {
322 	int ch;
323 	unsigned int start_time;
324 	struct eth_frame *frame;
325 	eth_buffer.head = NULL;
326 	eth_buffer.tail = NULL;
327 
328 	wifi_enter_promisc_mode();
329 	wifi_set_promisc(RTW_PROMISC_ENABLE, promisc_callback, len_used);
330 
331 	for(ch = 1; ch <= 13; ch ++) {
332 		if(wifi_set_channel(ch) == 0)
333 			printf("\n\n\rSwitch to channel(%d)", ch);
334 
335 		start_time = rtw_get_current_time();
336 
337 		while(1) {
338 			unsigned int current_time = rtw_get_current_time();
339 
340 			if(rtw_systime_to_ms(current_time - start_time) < (unsigned int)duration) {
341 				frame = retrieve_frame();
342 
343 				if(frame) {
344 					int i;
345 					printf("\n\rDA:");
346 					for(i = 0; i < 6; i ++)
347 						printf(" %02x", frame->da[i]);
348 					printf(", SA:");
349 					for(i = 0; i < 6; i ++)
350 						printf(" %02x", frame->sa[i]);
351 					printf(", len=%d", frame->len);
352 					printf(", RSSI=%d", frame->rssi);
353 #if CONFIG_INIC_CMD_RSP
354 					if(inic_frame_tail){
355 						if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
356 							memcpy(inic_frame_tail->da, frame->da, 6);
357 							memcpy(inic_frame_tail->sa, frame->sa, 6);
358 							inic_frame_tail->len = frame->len;
359 							inic_frame_tail++;
360 							inic_frame_cnt++;
361 						}
362 					}
363 #endif
364 					rtw_free((void *) frame);
365 				}
366 				else
367 					rtw_mdelay_os(1);	//delay 1 tick
368 			}
369 			else
370 				break;
371 		}
372 #if CONFIG_INIC_CMD_RSP
373 		if(inic_frame){
374 			inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
375 			memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
376 				inic_frame_tail = inic_frame;
377 				inic_frame_cnt = 0;
378 			rtw_msleep_os(10);
379 		}
380 #endif
381 	}
382 
383 	wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
384 
385 	while((frame = retrieve_frame()) != NULL)
386 		rtw_free((void *) frame);
387 }
388 
promisc_callback_all(unsigned char * buf,unsigned int len,void * userdata)389 static void promisc_callback_all(unsigned char *buf, unsigned int len, void* userdata)
390 {
391 	struct eth_frame *frame = (struct eth_frame *) rtw_malloc(sizeof(struct eth_frame));
392 	_lock lock;
393 	_irqL irqL;
394 
395 	if(frame) {
396 		frame->prev = NULL;
397 		frame->next = NULL;
398 #if defined(CONFIG_UNSUPPORT_PLCPHDR_RPT) && CONFIG_UNSUPPORT_PLCPHDR_RPT
399 		if(((ieee80211_frame_info_t *)userdata)->type == RTW_RX_UNSUPPORT){
400 			//NOTICE: buf structure now is rtw_rx_info_t.
401 			frame->type = 0xFF;
402 			memset(frame->da, 0, 6);
403 			memset(frame->sa, 0, 6);
404 		}
405 		else
406 #endif
407 		{
408 			memcpy(frame->da, buf+4, 6);
409 			memcpy(frame->sa, buf+10, 6);
410 			frame->type = *buf;
411 		}
412 
413 		frame->len = len;
414 		/*
415 		* type is the first byte of Frame Control Field of 802.11 frame
416 		* If the from/to ds information is needed, type could be reused as follows:
417 		* frame->type = ((((ieee80211_frame_info_t *)userdata)->i_fc & 0x0100) == 0x0100) ? 2 : 1;
418 		* 1: from ds; 2: to ds
419 		*/
420 
421 		frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
422 
423 		rtw_enter_critical(&lock, &irqL);
424 
425 		if(eth_buffer.tail) {
426 			eth_buffer.tail->next = frame;
427 			frame->prev = eth_buffer.tail;
428 			eth_buffer.tail = frame;
429 		}
430 		else {
431 			eth_buffer.head = frame;
432 			eth_buffer.tail = frame;
433 		}
434 
435 		rtw_exit_critical(&lock, &irqL);
436 	}
437 }
promisc_test_all(int duration,unsigned char len_used)438 static void promisc_test_all(int duration, unsigned char len_used)
439 {
440 	int ch;
441 	unsigned int start_time;
442 	struct eth_frame *frame;
443 	eth_buffer.head = NULL;
444 	eth_buffer.tail = NULL;
445 
446 	wifi_enter_promisc_mode();
447 	wifi_set_promisc(RTW_PROMISC_ENABLE_2, promisc_callback_all, len_used);
448 
449 	for(ch = 1; ch <= 13; ch ++) {
450 		if(wifi_set_channel(ch) == 0)
451 			printf("\n\n\rSwitch to channel(%d)", ch);
452 
453 		start_time = rtw_get_current_time();
454 
455 		while(1) {
456 			unsigned int current_time = rtw_get_current_time();
457 
458 			if(rtw_systime_to_ms(current_time - start_time) < (unsigned int)duration) {
459 				frame = retrieve_frame();
460 
461 				if(frame) {
462 					int i;
463 					printf("\n\rTYPE: 0x%x, ", frame->type);
464 					printf("DA:");
465 					for(i = 0; i < 6; i ++)
466 						printf(" %02x", frame->da[i]);
467 					printf(", SA:");
468 					for(i = 0; i < 6; i ++)
469 						printf(" %02x", frame->sa[i]);
470 					printf(", len=%d", frame->len);
471 					printf(", RSSI=%d", frame->rssi);
472 #if CONFIG_INIC_CMD_RSP
473 					if(inic_frame_tail){
474 						if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
475 							memcpy(inic_frame_tail->da, frame->da, 6);
476 							memcpy(inic_frame_tail->sa, frame->sa, 6);
477 							inic_frame_tail->len = frame->len;
478 							inic_frame_tail->type = frame->type;
479 							inic_frame_tail++;
480 							inic_frame_cnt++;
481 						}
482 					}
483 #endif
484 					rtw_free((void *) frame);
485 				}
486 				else
487 					rtw_mdelay_os(1);	//delay 1 tick
488 			}
489 			else
490 				break;
491 		}
492 #if CONFIG_INIC_CMD_RSP
493 		if(inic_frame){
494 			inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
495 			memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
496 				inic_frame_tail = inic_frame;
497 				inic_frame_cnt = 0;
498 			rtw_msleep_os(10);
499 		}
500 #endif
501 	}
502 
503 	wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
504 
505 	while((frame = retrieve_frame()) != NULL)
506 		rtw_free((void *) frame);
507 }
508 
cmd_promisc(int argc,char ** argv)509 void cmd_promisc(int argc, char **argv)
510 {
511 	int duration;
512 #if CONFIG_INIC_CMD_RSP
513 	inic_frame_tail = inic_frame = rtw_malloc(sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
514 	if(inic_frame == NULL){
515 		inic_c2h_msg("ATWM", RTW_BUFFER_UNAVAILABLE_TEMPORARY, NULL, 0);
516 		return;
517 	}
518 #endif
519 	#ifdef CONFIG_PROMISC
520 	wifi_init_packet_filter();
521 	#endif
522 	if((argc == 2) && ((duration = atoi(argv[1])) > 0))
523 		//promisc_test(duration, 0);
524 		promisc_test_all(duration, 0);
525 	else if((argc == 3) && ((duration = atoi(argv[1])) > 0) && (strcmp(argv[2], "with_len") == 0))
526 		promisc_test(duration, 1);
527 	else
528 		printf("\n\rUsage: %s DURATION_SECONDS [with_len]", argv[0]);
529 #if CONFIG_INIC_CMD_RSP
530 	if(inic_frame)
531 		rtw_free(inic_frame);
532 	inic_frame_tail = NULL;
533 	inic_frame_cnt = 0;
534 #endif
535 }
536 #endif	//#if CONFIG_WLAN
537