1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/tiancj-airkiss

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
airkiss.c 5.8 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
cjtian Отправлено 17.06.2015 14:10 da25a3f
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "airkiss.h"
static uint8_t bcast_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
static uint16_t seqno = 0;
/*
* 8 7 6 5 4 3 2 1 0
* 1: data
* 0 1: sequence header
* 0 0: 0~3: magic code,
* 4~7: prefix code
*/
struct sta_info {
uint8_t mac[ETH_ALEN];
uint8_t buf[MAX_BUF_SIZE];
int cnt;
int pos;
int base_len;
};
#define MAX_STA_NUM 64
static struct sta_info info[MAX_STA_NUM] = {{{0}, {0}, 0, 0, 0},};
#define MIN_PREAMBLE_CNT 3
#define MIN_MAGIC_CNT 2
static int sta_index = 0;
int find_sta_index(uint8_t *addr)
{
int i;
for (i = 0; i < MAX_STA_NUM; i++)
if (!memcmp(info[i].mac, addr, ETH_ALEN))
return i;
// append to info
if (sta_index >= MAX_STA_NUM)
return -1;
memcpy(info[sta_index].mac, addr, ETH_ALEN);
sta_index++;
return sta_index - 1;
}
void append_sniffer_data(uint8_t *addr, int len)
{
int index;
index = find_sta_index(addr);
if (index >= 0) {
// append data
info[index].buf[info[index].pos] = len;
info[index].pos++;
info[index].pos = (info[index].pos) % MAX_BUF_SIZE;
info[index].cnt++;
} else {
printf("cannot find proper slot fot addr\n");
}
}
int find_preamble(void)
{
int i, j;
int len;
int pream_cnt = 0;
uint8_t *b;
for (i = 0; i < sta_index; i++) {
if (info[i].cnt > 32) {
// check wether have received preamble
len = info[i].cnt < MAX_BUF_SIZE ? info[i].cnt : MAX_BUF_SIZE;
b = info[i].buf;
for (j = 0; j < len; ) {
if (b[j+3] - b[j+2] == 1 &&
b[j+2] - b[j+1] == 1 &&
b[j+1] - b[j] == 1) {
j += 4;
pream_cnt++;
info[i].base_len = b[j];
if (pream_cnt > MIN_PREAMBLE_CNT)
return i; // return sta info
} else {
j++;
}
}
}
}
return -1;
}
/* ALL information are all in len */
int airkiss_recv(struct airkiss_context *ac, uint8_t *packet, int len)
{
uint8_t *p;
uint8_t *sa;
uint16_t fc; // frame control
uint16_t seq;
int i;
uint8_t cod;
int dat;
// sanity check, discard non-insteresting packets.
if (!packet || len < 24)
return 1;
fc = packet[0] << 8 | packet[1];
if (!(fc & 0x0800))
return 1; // Data
if ((fc & 0x3) != 0x2)
return 1; // FromDS: 1, ToDS: 0
p = packet + 4; // DA
if (memcmp(p, bcast_mac, ETH_ALEN))
return 1; // DA should be FF:FF:FF:FF:FF:FF
// addr 3
sa = packet + 16;
// stage1:
// try to receive PREAMBLE
// PREABLE is a sequence with ...., for example, 41, 42, 43, 44, 41, 42, 43, 44, ....
if (ac->status == 0) {
int pos;
append_sniffer_data(sa, len);
printf("preamble len %d\n", len);
pos = find_preamble();
if (pos >= 0) {
// preamble has received
ac->status |= PREAMBLE_RXD;
memcpy(ac->addr, info[pos].mac, ETH_ALEN);
ac->base_len = info[pos].base_len;
printf("rxed preamble for %02X:%02X:%02X:%02X:%02X:%02X\n",
ac->addr[0], ac->addr[1], ac->addr[2],
ac->addr[3], ac->addr[4], ac->addr[5]);
}
return 0;
}
// skip packets that mac addr not match
if (memcmp(sa, ac->addr, ETH_ALEN))
return 1;
printf("len %d\n", len);
// stage2:
if ((len & (BIT(7) | BIT(8))) == 0) {
// magic code or prefix code
cod = (len & 0x70) >> 4;
dat = len & 0xF;
if (cod <= 3) {
// MAGIC CODE
if (ac->status & MAGIC_RXD)
return 0;
ac->flag |= BIT(cod);
switch (cod) {
case 0: // length high
ac->total_len |= dat << 4;
break;
case 1:
ac->total_len |= dat;
break;
case 2:
ac->ssid_crc |= dat << 4;
break;
case 3:
ac->ssid_crc |= dat;
break;
}
if ((ac->flag & 0xF) == 0xF) {
// fully received magic code (4 packets)
// check whether it is valid
if (ac->total_len == ac->total_len_saved &&
ac->ssid_crc == ac->ssid_crc_saved) {
ac->magic_cnt++;
if (ac->magic_cnt > MIN_MAGIC_CNT) {
printf("RXD preamble magic code, length %d, ssid crc 0x%x\n",
ac->total_len, ac->ssid_crc);
ac->status |= MAGIC_RXD;
}
} else {
ac->total_len_saved = ac->total_len;
ac->ssid_crc_saved = ac->ssid_crc;
ac->magic_cnt = 0;
}
// next time
ac->flag &= ~0x0F;
}
} else {
// PREFIX CODE
if (ac->status & PREFIX_RXD)
return 0;
ac->flag |= BIT(cod);
switch (cod) {
case 4:
ac->pass_len |= dat << 4;
break;
case 5:
ac->pass_len |= dat;
break;
case 6:
ac->pass_crc |= dat << 4;
break;
case 7:
ac->pass_crc |= dat;
break;
default:
// error packet
break;
}
if ((ac->flag & 0xF0) == 0xF0) {
// check prefix code valid
ac->status |= PREFIX_RXD;
}
}
}
// stage2:
// receive prefix code
if ((len & BIT(7)) == BIT(7)) {
// seq data
if (ac->seq_step == 0) {
// seq crc8 (lower 7bits)
ac->seq_no_crc = len & 0x7F;
ac->seq_step = 1;
printf("seq no crc %d\n", ac->seq_no_crc);
} else if (ac->seq_step == 1) {
// seq index
ac->seq_no = len & (~(BIT(8) | BIT(7)));
ac->index[ac->seq_no] = 1;
ac->pos = ac->seq_no << 2; // *4
printf("seq no %d\n", ac->seq_no);
ac->seq_step = 0;
}
}
// stage 3:
// receive sequence header + data field
if (len & BIT(8)) {
//ac->buf[ac->seq_no] = len & ~(BIT(8));
ac->buf[ac->pos++] = len & ~(BIT(8));
printf("data %d\n", len & ~(BIT(8)));
//ac->pos++;
}
if (ac->pos >= ac->total_len) {
// check whether all packets are received
for (i = 0; i < ac->total_len; i++)
if (!ac->index[i])
return 0;
}
#if 0
// ok, all packets are received
{
char passwd[32];
char ssid[32];
int ssid_len = ac->total_len - ac->pass_len - 1;
uint8_t random;
strncpy(passwd, ac->buf, ac->pass_len);
passwd[ac->pass_len] = '\0';
strncpy(ssid, &ac->buf[ac->pass_len + 1], ssid_len);
ssid[ssid_len] = '\0';
random = ac->buf[ac->pass_len];
printf("ssid: %s, passwd: %s, random: %d\n", ssid, passwd, random);
}
#endif
return 0;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/tiancj-airkiss.git
git@api.gitlife.ru:oschina-mirror/tiancj-airkiss.git
oschina-mirror
tiancj-airkiss
tiancj-airkiss
master