Commit 821a8e46 authored by Bruno Randolf's avatar Bruno Randolf

reworked filtering

parent e9a32e6a
......@@ -4,9 +4,6 @@ TODO:
* batman support
* IP auswertung
* pause/run glitches
* filter eingabe (pkt types, readline?)
* filter per command line (zumindest olsr only)
* dump info into file
* remote client
* timed out nodes are never reclaimed!
......
......@@ -33,7 +33,8 @@
static void show_window(char which);
static void show_sort_win(void);
static void show_filter_win(void);
static void update_filter_win(void);
static void update_dump_win(struct packet_info* pkt);
static void update_stat_win(struct packet_info* pkt, int node_number);
......@@ -107,7 +108,7 @@ init_display(void)
keypad(stdscr, TRUE);
nonl(); /* tell curses not to do NL->CR/NL on output */
cbreak(); /* take input chars one at a time, no wait for \n */
noecho(); /* echo input - in color */
noecho();
nodelay(stdscr,TRUE);
init_pair(1, COLOR_WHITE, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
......@@ -182,36 +183,72 @@ finish_display(int sig)
void
filter_input(int c)
{
static int pos = 0;
static char buffer[18];
char buf[18];
int i;
switch(c) {
case 'q': case '\r': case KEY_ENTER:
buffer[18] = '\0';
convert_string_to_mac(buffer, conf.filtermac);
if (conf.filtermac[0] || conf.filtermac[1] || conf.filtermac[2] ||
conf.filtermac[3] || conf.filtermac[4] || conf.filtermac[5])
conf.do_filter = 1;
else
conf.do_filter = 0;
conf.paused = 0;
delwin(filter_win);
filter_win = NULL;
pos = 0;
update_display(NULL,-1);
break;
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':case '0':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case ':':
if (pos<18) {
buffer[pos] = c;
pos++;
wechochar(filter_win, c);
}
break;
case KEY_BACKSPACE:
break;
switch (c) {
case 'm':
TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_MGMT);
conf.filter_pkt |= PKT_TYPE_ALL_MGMT;
break;
case 'b': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_BEACON); break;
case 'p': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_PROBE); break;
case 'a': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_ASSOC); break;
case 'u': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_AUTH); break;
case 'c':
TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_CTRL);
conf.filter_pkt |= PKT_TYPE_ALL_CTRL;
break;
case 'r': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_CTS | PKT_TYPE_RTS); break;
case 'k': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_ACK); break;
case 'd':
TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_DATA);
conf.filter_pkt |= PKT_TYPE_ALL_DATA;
break;
case 'n': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_NULL); break;
case 'R': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_ARP); break;
case 'P': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_ICMP); break;
case 'I': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_IP); break;
case 'U': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_UDP); break;
case 'T': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_TCP); break;
case 'O': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_OLSR); break;
case 'B': TOGGLE_BIT(conf.filter_pkt, PKT_TYPE_BATMAN); break;
case 'q': case 'Q':
finish_all(0);
case '\r': case KEY_ENTER:
conf.paused = 0;
delwin(filter_win);
filter_win = NULL;
update_display(NULL, -1);
return;
case '1': case '2': case '3': case '4': case '5': case '6':
i = c - '1';
echo();
mvwprintw(filter_win, 34, 2, "[ Enter new MAC %d and ENTER ]", i+1);
mvwgetnstr(filter_win, 26 + i, 9, buf, 17);
noecho();
convert_string_to_mac(buf, conf.filtermac[i]);
}
/* sanity checks */
/* if one of the individual mgmt frames is deselected we dont want to see all mgmt frames */
if ((conf.filter_pkt & PKT_TYPE_ALL_MGMT) != PKT_TYPE_ALL_MGMT)
conf.filter_pkt = conf.filter_pkt & ~PKT_TYPE_MGMT;
/* same for ctl */
if ((conf.filter_pkt & PKT_TYPE_ALL_CTRL) != PKT_TYPE_ALL_CTRL)
conf.filter_pkt = conf.filter_pkt & ~PKT_TYPE_CTRL;
/* same for data */
if ((conf.filter_pkt & PKT_TYPE_ALL_DATA) != PKT_TYPE_ALL_DATA)
conf.filter_pkt = conf.filter_pkt & ~PKT_TYPE_DATA;
/* recalculate filter flag */
conf.do_macfilter = 0;
for (i = 0; i < MAX_FILTERMAC; i++) {
if (MAC_NOT_EMPTY(conf.filtermac[i]))
conf.do_macfilter = 1;
}
update_filter_win();
}
......@@ -271,8 +308,12 @@ handle_user_input()
show_window(tolower(key));
break;
case 'f': case 'F':
if (filter_win == NULL)
show_filter_win();
if (filter_win == NULL) {
conf.paused = 1;
filter_win = newwin(35, 35, LINES/2-15, COLS/2-15);
scrollok(filter_win, FALSE);
update_filter_win();
}
break;
case KEY_RESIZE: /* xterm window resize event */
endwin();
......@@ -316,30 +357,58 @@ show_sort_win(void)
}
#define CHECKED(_x) (conf.filter_pkt & (_x)) ? '*' : ' '
#define CHECK_ETHER(_mac) MAC_NOT_EMPTY(_mac) ? '*' : ' '
static void
show_filter_win()
update_filter_win()
{
//char buf[255];
conf.paused = 1;
filter_win = newwin(7, 25, LINES/2-2, COLS/2-15);
int l, i;
box(filter_win, 0 , 0);
mvwprintw(filter_win,0,2," Enter Filter MAC ");
if (conf.do_filter)
mvwprintw(filter_win,2,2, "%s", ether_sprintf(conf.filtermac));
else
mvwprintw(filter_win,2,2, " : : : : : ");
wmove(filter_win,2,2);
print_centered(filter_win, 0, 35, " Edit Packet Filter ");
mvwprintw(filter_win, 2, 2, "Show these Packet Types");
l = 4;
wattron(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "m: [%c] MANAGEMENT FRAMES", CHECKED(PKT_TYPE_MGMT));
wattroff(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "b: [%c] Beacons", CHECKED(PKT_TYPE_BEACON));
mvwprintw(filter_win, l++, 2, "p: [%c] Probe Request/Response", CHECKED(PKT_TYPE_PROBE));
mvwprintw(filter_win, l++, 2, "a: [%c] Association", CHECKED(PKT_TYPE_ASSOC));
mvwprintw(filter_win, l++, 2, "u: [%c] Authentication", CHECKED(PKT_TYPE_AUTH));
l++;
wattron(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "c: [%c] CONTROL FRAMES", CHECKED(PKT_TYPE_CTRL));
wattroff(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "r: [%c] CTS/RTS", CHECKED(PKT_TYPE_CTS | PKT_TYPE_RTS));
mvwprintw(filter_win, l++, 2, "k: [%c] ACK", CHECKED(PKT_TYPE_ACK));
l++;
wattron(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "d: [%c] DATA FRAMES", CHECKED(PKT_TYPE_DATA));
wattroff(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "n: [%c] Null Data", CHECKED(PKT_TYPE_NULL));
mvwprintw(filter_win, l++, 2, "R: [%c] ARP", CHECKED(PKT_TYPE_ARP));
mvwprintw(filter_win, l++, 2, "P: [%c] ICMP/PING", CHECKED(PKT_TYPE_ICMP));
mvwprintw(filter_win, l++, 2, "I: [%c] IP", CHECKED(PKT_TYPE_IP));
mvwprintw(filter_win, l++, 2, "U: [%c] UDP", CHECKED(PKT_TYPE_UDP));
mvwprintw(filter_win, l++, 2, "T: [%c] TCP", CHECKED(PKT_TYPE_TCP));
mvwprintw(filter_win, l++, 2, "O: [%c] OLSR", CHECKED(PKT_TYPE_OLSR));
mvwprintw(filter_win, l++, 2, "B: [%c] BATMAN", CHECKED(PKT_TYPE_BATMAN));
l++;
mvwprintw(filter_win, l++, 2, "Show only these");
wattron(filter_win, A_BOLD);
mvwprintw(filter_win, l++, 2, "Source MAC ADDRESSES");
wattroff(filter_win, A_BOLD);
for (i = 0; i < MAX_FILTERMAC; i++) {
mvwprintw(filter_win, l++, 2, "%d: [%c] %s", i+1,
CHECK_ETHER(conf.filtermac[i]), ether_sprintf(conf.filtermac[i]));
}
scrollok(filter_win,FALSE);
print_centered(filter_win, 34, 35, "[ Press key or ENTER ]");
#if 0
echo();
nodelay(filter_win,FALSE);
getnstr(buf,255);
mvwprintw(filter_win,1,20,"%s",buf);
nodelay(filter_win,TRUE);
noecho();
#endif
wrefresh(filter_win);
}
......@@ -363,6 +432,8 @@ update_display(struct packet_info* pkt, int node_number)
update_show_win();
else if (small_win != NULL)
wnoutrefresh(small_win);
else if (filter_win != NULL)
wnoutrefresh(filter_win);
else {
update_list_win();
update_stat_win(pkt, node_number);
......
......@@ -64,6 +64,7 @@ struct config conf = {
.ifname = "wlan0",
.display_interval = DISPLAY_UPDATE_INTERVAL,
.sleep_time = SLEEP_TIME,
.filter_pkt = 0xffffff,
};
static int mon; /* monitoring socket */
......@@ -282,9 +283,9 @@ get_options(int argc, char** argv)
conf.sleep_time = atoi(optarg);
break;
case 'e':
conf.do_filter = 1;
convert_string_to_mac(optarg, conf.filtermac);
printf("%s\n", ether_sprintf(conf.filtermac));
conf.do_macfilter = 1;
convert_string_to_mac(optarg, conf.filtermac[0]);
printf("%s\n", ether_sprintf(conf.filtermac[0]));
break;
case 'h':
default:
......@@ -479,8 +480,18 @@ check_ibss_split(struct packet_info* pkt, int pkt_node)
static int
filter_packet(struct packet_info* pkt)
{
//TODO add filter for packet types: OLSR, BEACON, CONTROL
return (conf.do_filter && memcmp(current_packet.wlan_src, conf.filtermac, sizeof(conf.filtermac)) != 0);
int i;
if (!(pkt->pkt_types & conf.filter_pkt))
return 1;
if (conf.do_macfilter) {
for (i = 0; i < MAX_FILTERMAC; i++) {
if (memcmp(current_packet.wlan_src, conf.filtermac[i], MAC_LEN) == 0)
return 0;
}
}
return 1;
}
......
......@@ -26,6 +26,8 @@
#define DO_DEBUG 0
#endif
#define MAC_LEN 6
#define MAX_NODES 255
#define MAX_ESSIDS 255
#define MAX_BSSIDS 255
......@@ -33,16 +35,36 @@
#define MAX_ESSID_LEN 255
#define MAX_RATES 55 /* 54M + 1 for array index */
#define MAX_FSTYPE 0xff
#define PKT_TYPE_ARP 0x001
#define PKT_TYPE_IP 0x002
#define PKT_TYPE_ICMP 0x004
#define PKT_TYPE_UDP 0x008
#define PKT_TYPE_TCP 0x010
#define PKT_TYPE_OLSR 0x020
#define PKT_TYPE_OLSR_LQ 0x040
#define PKT_TYPE_OLSR_GW 0x080
#define PKT_TYPE_BATMAN 0x100
#define MAX_FILTERMAC 6
/* packet types we actually care about, e.g filter */
#define PKT_TYPE_CTRL 0x000001
#define PKT_TYPE_MGMT 0x000002
#define PKT_TYPE_DATA 0x000004
#define PKT_TYPE_BEACON 0x000010
#define PKT_TYPE_PROBE 0x000020
#define PKT_TYPE_ASSOC 0x000040
#define PKT_TYPE_AUTH 0x000080
#define PKT_TYPE_RTS 0x000100
#define PKT_TYPE_CTS 0x000200
#define PKT_TYPE_ACK 0x000400
#define PKT_TYPE_NULL 0x000800
#define PKT_TYPE_ARP 0x001000
#define PKT_TYPE_IP 0x002000
#define PKT_TYPE_ICMP 0x004000
#define PKT_TYPE_UDP 0x008000
#define PKT_TYPE_TCP 0x010000
#define PKT_TYPE_OLSR 0x020000
#define PKT_TYPE_OLSR_LQ 0x040000
#define PKT_TYPE_OLSR_GW 0x080000
#define PKT_TYPE_BATMAN 0x100000
#define PKT_TYPE_ALL_MGMT (PKT_TYPE_BEACON | PKT_TYPE_PROBE | PKT_TYPE_ASSOC | PKT_TYPE_AUTH)
#define PKT_TYPE_ALL_CTRL (PKT_TYPE_RTS | PKT_TYPE_CTS | PKT_TYPE_ACK)
#define PKT_TYPE_ALL_DATA (PKT_TYPE_NULL | PKT_TYPE_ARP | PKT_TYPE_ICMP | PKT_TYPE_IP | \
PKT_TYPE_UDP | PKT_TYPE_TCP | PKT_TYPE_OLSR | PKT_TYPE_BATMAN)
#define WLAN_MODE_AP 0x01
#define WLAN_MODE_IBSS 0x02
......@@ -153,12 +175,13 @@ struct config {
int node_timeout;
int display_interval;
int sleep_time;
unsigned char filtermac[6];
unsigned char filtermac[MAX_FILTERMAC][6];
int filter_pkt;
/* this isn't exactly config, but wtf... */
int arphrd; // the device ARP type
int paused;
int do_filter;
int do_macfilter;
};
extern struct config conf;
......
......@@ -283,6 +283,12 @@ parse_80211_header(unsigned char** buf, int len)
switch (current_packet.wlan_type & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_DATA:
current_packet.pkt_types = PKT_TYPE_DATA;
switch (current_packet.wlan_type & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_NULLFUNC:
current_packet.pkt_types |= PKT_TYPE_NULL;
break;
}
sa = ieee80211_get_SA(wh);
da = ieee80211_get_DA(wh);
/* AP, STA or IBSS */
......@@ -299,18 +305,28 @@ parse_80211_header(unsigned char** buf, int len)
break;
case IEEE80211_FTYPE_CTL:
current_packet.pkt_types = PKT_TYPE_CTRL;
switch (current_packet.wlan_type & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_RTS:
current_packet.pkt_types |= PKT_TYPE_RTS;
sa = wh->addr2;
da = wh->addr1;
break;
case IEEE80211_STYPE_CTS:
current_packet.pkt_types |= PKT_TYPE_CTS;
da = wh->addr1;
break;
case IEEE80211_STYPE_ACK:
current_packet.pkt_types |= PKT_TYPE_ACK;
da = wh->addr1;
break;
case IEEE80211_STYPE_PSPOLL:
sa = wh->addr2;
break;
case IEEE80211_STYPE_CFEND:
case IEEE80211_STYPE_CFENDACK:
/* dont know, dont care */
......@@ -319,13 +335,29 @@ parse_80211_header(unsigned char** buf, int len)
break;
case IEEE80211_FTYPE_MGMT:
current_packet.pkt_types = PKT_TYPE_MGMT;
whm = (struct ieee80211_mgmt*)*buf;
sa = whm->sa;
da = whm->da;
switch (current_packet.wlan_type & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_BEACON:
current_packet.pkt_types |= PKT_TYPE_BEACON;
memcpy(current_packet.wlan_tsf, &whm->u.beacon.timestamp, 8);
ieee802_11_parse_elems(whm->u.beacon.variable,
len - sizeof(struct ieee80211_mgmt) - 4 /* FCS */, &current_packet);
DEBUG("ESSID %s \n", current_packet.wlan_essid );
DEBUG("CHAN %d \n", current_packet.wlan_channel );
if (whm->u.beacon.capab_info & WLAN_CAPABILITY_IBSS)
current_packet.wlan_mode = WLAN_MODE_IBSS;
else if (whm->u.beacon.capab_info & WLAN_CAPABILITY_ESS)
current_packet.wlan_mode = WLAN_MODE_AP;
if (whm->u.beacon.capab_info & WLAN_CAPABILITY_PRIVACY)
current_packet.wlan_wep = 1;
break;
case IEEE80211_STYPE_PROBE_RESP:
current_packet.pkt_types |= PKT_TYPE_PROBE;
memcpy(current_packet.wlan_tsf, &whm->u.beacon.timestamp, 8);
ieee802_11_parse_elems(whm->u.beacon.variable,
len - sizeof(struct ieee80211_mgmt) - 4 /* FCS */, &current_packet);
......@@ -338,12 +370,27 @@ parse_80211_header(unsigned char** buf, int len)
if (whm->u.beacon.capab_info & WLAN_CAPABILITY_PRIVACY)
current_packet.wlan_wep = 1;
break;
case IEEE80211_STYPE_PROBE_REQ:
current_packet.pkt_types |= PKT_TYPE_PROBE;
ieee802_11_parse_elems(whm->u.probe_req.variable,
len - 24 - 4 /* FCS */,
&current_packet);
current_packet.wlan_mode |= WLAN_MODE_PROBE;
break;
case IEEE80211_STYPE_ASSOC_REQ:
case IEEE80211_STYPE_ASSOC_RESP:
case IEEE80211_STYPE_REASSOC_REQ:
case IEEE80211_STYPE_REASSOC_RESP:
case IEEE80211_STYPE_DISASSOC:
current_packet.pkt_types |= PKT_TYPE_ASSOC;
break;
case IEEE80211_STYPE_AUTH:
case IEEE80211_STYPE_DEAUTH:
current_packet.pkt_types |= PKT_TYPE_AUTH;
break;
}
break;
}
......
......@@ -53,4 +53,8 @@ get_packet_type_name(int type);
const char*
kilo_mega_ize(unsigned int val);
#define MAC_NOT_EMPTY(_mac) (_mac[0] || _mac[1] || _mac[2] || _mac[3] || _mac[4] || _mac[5])
#define TOGGLE_BIT(_x, _m) (_x) = (_x) & (_m) ? (_x) & ~(_m) : (_x) | (_m)
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment