#include <pthread.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include "capture/common.h"
#include "capture/osdep.h"
#include "utils/utils.h"
#include "utils/wifi_scan.h"
#include "airkiss.h"
#define MAX_CHANNELS 13
#define DEBUG 0
static airkiss_context_t akcontex = {{0},{0}};
const airkiss_config_t akconf = {
(airkiss_memset_fn)&memset,
(airkiss_memcpy_fn)&memcpy,
(airkiss_memcmp_fn)&memcmp,
(airkiss_printf_fn)&printf };
airkiss_result_t ak_result;
struct itimerval my_timer;
char *wifi_if = NULL;
struct wif *wi = NULL;
int g_channel = 0;
unsigned char g_buf[RECV_BUFSIZE] = {0};
int second = 0;
int startTimer(struct itimerval *timer);
int stopTimer(struct itimerval *timer);
static char *getIP(void)
{
int sock_get_ip;
char ipaddr[50];
struct sockaddr_in *sin;
struct ifreq ifr_ip;
if ((sock_get_ip=socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
LOG_TRACE("socket create failse...GetLocalIp!/n");
return NULL;
}
memset(&ifr_ip, 0, sizeof(ifr_ip));
strncpy(ifr_ip.ifr_name, "wlan0", sizeof(ifr_ip.ifr_name) - 1);
if( ioctl( sock_get_ip, SIOCGIFADDR, &ifr_ip) < 0 )
{
close( sock_get_ip );
return NULL;
}
sin = (struct sockaddr_in *)&ifr_ip.ifr_addr;
strcpy(ipaddr,inet_ntoa(sin->sin_addr));
LOG_TRACE("local ip:%s /n",ipaddr);
close( sock_get_ip );
return ipaddr;
}
static void Connect_wifi(char *ssid,char *password)
{
/*1.退出混杂模式*/
system((char *)"iwconfig wlan0 mode auto");
usleep( 10000 ); /* madwifi needs a second chance */
/*2.添加配置文件*/
sprintf((char *)g_buf,"wpa_passphrase \"%s\" \"%s\" > /etc/ssidpwd.conf",ssid,password);
LOG_TRACE("%s \r\n",g_buf);
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*3.执行配置文件*/
sprintf((char *)g_buf,"wpa_supplicant -B -iwlan0 -Dwext -c /etc/ssidpwd.conf");
LOG_TRACE("%s \r\n",g_buf);
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*开启DHCP*/
system((char *)"udhcpc -iwlan0");
usleep( 10000 ); /* madwifi needs a second chance */
do{
LOG_TRACE("I have no IP,wait...\r\n");
usleep(200000);
} while(!getIP());
}
int udp_broadcast(unsigned char random, int port);
void switch_channel_callback(void)
{
if(g_channel >= MAX_CHANNELS)
{
g_channel = 1;
}else
g_channel++;
wi->wi_set_channel(wi,g_channel);
airkiss_change_channel(&akcontex);
}
int process_airkiss(const unsigned char *packet, int size)
{
int ret;
int num = 0;
ret = airkiss_recv(&akcontex, (void *)packet, size);
if(ret == AIRKISS_STATUS_CONTINUE)
{
//LOG_TRACE("wi_get_channel = %d\r\n", wi->wi_get_channel(wi));
;
}
else if(ret == AIRKISS_STATUS_CHANNEL_LOCKED)
{
LOG_TRACE("\r\n*****************Lock channel in %d*****************\r\n", g_channel);
stopTimer(&my_timer);
}
else if(ret == AIRKISS_STATUS_COMPLETE)
{
airkiss_get_result(&akcontex, &ak_result);
LOG_TRACE("******************Airkiss Complete******************\r\n"
"reserved:[%x]\npwd:[%s]\nssid:[%s]\nrandom:[0x%02x]",
ak_result.reserved,
ak_result.pwd,
ak_result.ssid,
ak_result.random);
//TODO: scan and connect to wifi
Connect_wifi(ak_result.ssid,ak_result.pwd);
udp_broadcast(ak_result.random, 10000);
}
#if DEBUG
if(1) {
/* print header */
printf("len:%4d, airkiss ret:%d [ ", size, ret);
int i;
unsigned char ch;
for(i=0; i<24; i++)
{
ch = (unsigned char)*(packet + i);
printf("%02x ", ch);
}
printf("]\n");
}
#endif
return ret;
}
int startTimer(struct itimerval *timer)
{
if(second == 0)
{
second = 200;
}
timer->it_interval.tv_sec = 0;
timer->it_interval.tv_usec = second*1000;
timer->it_value.tv_sec = 0;
timer->it_value.tv_usec = second*1000;
if(setitimer(ITIMER_REAL, timer, NULL) < 0)
LOG_TRACE("Set timer failed!\n");
return 0;
}
int stopTimer(struct itimerval *timer)
{
timer->it_interval.tv_sec = 0;
timer->it_interval.tv_usec = 0;
timer->it_value.tv_sec = 0;
timer->it_value.tv_usec = 0;
if(setitimer(ITIMER_REAL, timer, NULL) < 0)
LOG_TRACE("Set timer failed!\n");
return 0;
}
int udp_broadcast(unsigned char random, int port)
{
int fd;
int enabled = 1;
int err;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_BROADCAST;
addr.sin_port = htons(port);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
LOG_TRACE("Error to create socket, reason: %s\r\n", strerror(errno));
return 1;
}
err = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *) &enabled, sizeof(enabled));
if(err == -1)
{
close(fd);
LOG_TRACE("setsockopt socket SO_BROADCAST, reason: %s\r\n", strerror(errno));
return 1;
}
LOG_TRACE("Sending random to broadcast..\r\n");
int i;
useconds_t usecs = 1000*20;
for(i=0;i<50;i++)
{
sendto(fd, (unsigned char *)&random, 1, 0, (struct sockaddr*)&addr, sizeof(struct sockaddr));
usleep(usecs);
}
close(fd);
return 0;
}
int main(int argc, char *argv[])
{
int read_size;
if(argc!=3)
{
LOG_ERROR("Usage: %s <device-name> <change-channel-ZZZZZtime>", argv[0]);
return 1;
}
wifi_if = argv[1];
/*设置网卡模式*/
second = atoi(argv[2]);
LOG_ERROR("second = %d \r\n", second);
strcpy((char *)g_buf,"iwconfig wlan0 mode auto");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*禁止网络服务*/
strcpy((char *)g_buf,"killall wpa_supplicant");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*关闭dhcp服务*/
strcpy((char *)g_buf," killall udhcpc");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*卸载网卡*/
strcpy((char *)g_buf,"rmmod 8723bu.ko");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*装载网卡*/
strcpy((char *)g_buf,"insmod /lib/modules/3.14.38-6UL_ga\+ge4944a5/kernel/drivers/net/wireless/realtek/rtl8723BU/8723bu.ko");
//strcpy((char *)g_buf,"insmod 8723bu.ko");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
/*使能网卡*/
strcpy((char *)g_buf,"ifconfig wlan0 up");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
#if 0
/*扫描周围热点,非必须,都为可见热点可以减少扫描信道的时间,遇到非可见热点就行不通了!!!!*/
wireless_scan_head head;
wireless_scan *presult = NULL;
LOG_TRACE("Scanning accesss point...");
if(wifi_scan(wifi_if, &head) == 0)
{
LOG_TRACE("Scan success.");
presult = head.result;
while(presult != NULL) {
char essid[MAX_ESSID_SIZE];
char bssid[MAX_BSSID_SIZE];
unsigned int freq;
int channel,power;
unsigned char essid_crc;
get_essid(presult, essid, MAX_ESSID_SIZE);
get_bssid(presult, bssid, MAX_BSSID_SIZE);
freq = get_freq_mhz(presult);
power = get_strength_dbm(presult);
channel = getChannelFromFrequency(freq);
LOG_TRACE("bssid:[%s], channel:[%2d], pow:[%d dBm], essid_crc:[%02x], essid:[%s]",
bssid, channel, power, essid_crc, essid);
presult = presult->next;
}
}
else
{
LOG_ERROR("ERROR to scan AP, init with all %d channels", MAX_CHANNELS);
}
#endif
/* Open the interface and set mode monitor */
/*设置网卡速率*/
//strcpy((char *)g_buf,"iwconfig wlan0 rate 11M");
strcpy((char *)g_buf,"iwconfig wlan0 rate auto");
system((char *)g_buf);
memset(g_buf,0x00,RECV_BUFSIZE);
usleep( 10000 ); /* madwifi needs a second chance */
wi = wi_open(wifi_if);
if (!wi) {
LOG_ERROR("cannot init interface %s", wifi_if);
return 1;
}
/* airkiss setup */
int result;
result = airkiss_init(&akcontex, &akconf);
if(result != 0)
{
LOG_ERROR("Airkiss init failed!!");
return 1;
}
LOG_TRACE("Airkiss version: %s", airkiss_version());
/* Setup channel switch timer */
startTimer(&my_timer);
signal(SIGALRM,(__sighandler_t)&switch_channel_callback);
for(;;)
{
read_size = wi->wi_read(wi, g_buf, RECV_BUFSIZE, NULL);
if (read_size < 0) {
LOG_ERROR("recv failed, ret %d", read_size);
break;
}
if((read_size >= 24) && (AIRKISS_STATUS_COMPLETE==process_airkiss(g_buf, read_size)))
break;
}
return 0;
}
|