Commit 21570c9f authored by Bruno Randolf's avatar Bruno Randolf

first (buggy) version of remote network capturing. switched to select().

parent b1cf301b
......@@ -21,7 +21,7 @@ DEBUG=0
PCAP=0
OBJS=protocol_parser.o main.o capture.o display.o network.o util.o ieee80211_util.o listsort.o
LIBS=-lncurses
CFLAGS+=-Wall -DDO_DEBUG=$(DEBUG) #-g
CFLAGS+=-Wall -DDO_DEBUG=$(DEBUG) -g
ifeq ($(PCAP),1)
CFLAGS+=-DPCAP
......
......@@ -31,6 +31,7 @@
#include "capture.h"
#include "util.h"
extern fd_set fds;
#ifdef PCAP
......@@ -229,14 +230,14 @@ open_packet_socket(char* devname, size_t bufsize, int recv_buffer_size)
set_receive_buffer(mon_fd, recv_buffer_size);
return (mon_fd >= 0);
return mon_fd;
}
inline int
recv_packet(unsigned char* buffer, size_t bufsize)
recv_packet(int fd, unsigned char* buffer, size_t bufsize)
{
return recv(mon_fd, buffer, bufsize, MSG_DONTWAIT);
return recv(fd, buffer, bufsize, MSG_DONTWAIT);
}
......
......@@ -24,7 +24,7 @@ int
open_packet_socket(char* devname, size_t bufsize, int recv_buffer_size);
int
recv_packet(unsigned char* buffer, size_t bufsize);
recv_packet(int fd, unsigned char* buffer, size_t bufsize);
void
close_packet_socket(void);
......
......@@ -25,6 +25,7 @@
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <err.h>
#include "protocol_parser.h"
......@@ -67,96 +68,141 @@ static int mon; /* monitoring socket */
static FILE* DF = NULL;
static struct timeval last_nodetimeout;
unsigned char buffer[8192];
int
main(int argc, char** argv)
/* for select */
fd_set read_fds;
fd_set write_fds;
fd_set excpt_fds;
struct timeval tv;
extern int srv_fd;
extern int cli_fd;
static void
handle_packet(unsigned char* buffer, int len)
{
unsigned char buffer[8192];
int len;
struct node_info* node;
get_options(argc, argv);
if (!conf.serverip) {
#if DO_DEBUG
dump_packet(buffer, len);
#endif
memset(&current_packet, 0, sizeof(current_packet));
if (!parse_packet(buffer, len)) {
DEBUG("parsing failed\n");
return;
}
}
else {
memcpy((void*)&current_packet, buffer, sizeof(struct packet_info));
}
if (!conf.quiet)
printf("horst: using monitoring interface %s\n", conf.ifname);
if (filter_packet(&current_packet))
return;
signal(SIGINT, finish_all);
gettimeofday(&the_time, NULL);
gettimeofday(&stats.stats_time, NULL);
if (conf.dumpfile != NULL)
write_to_file(&current_packet);
mon = open_packet_socket(conf.ifname, sizeof(buffer), conf.recv_buffer_size);
if (mon < 0)
err(1, "couldn't open packet socket");
node = node_update(&current_packet);
conf.arphrd = device_get_arptype();
if (conf.arphrd != ARPHRD_IEEE80211_PRISM &&
conf.arphrd != ARPHRD_IEEE80211_RADIOTAP) {
printf("wrong monitor type. please use radiotap or prism2 headers\n");
exit(1);
}
timeout_nodes();
if (conf.dumpfile != NULL) {
DF = fopen(conf.dumpfile, "w");
if (DF == NULL)
err(1, "couldn't open dump file");
}
update_history(&current_packet);
update_statistics(&current_packet);
check_ibss_split(&current_packet, node);
INIT_LIST_HEAD(&essids.list);
INIT_LIST_HEAD(&nodes);
if (conf.rport && cli_fd)
net_send_packet(&current_packet);
if (conf.rport)
net_init_socket(conf.rport);
#if !DO_DEBUG
else {
init_display();
}
update_display(&current_packet, node);
#endif
}
while ((len = recv_packet(buffer, sizeof(buffer))))
{
void
receive_any(void)
{
int ret, len, mfd;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&excpt_fds);
FD_SET(0, &read_fds);
FD_SET(mon, &read_fds);
if (srv_fd)
FD_SET(srv_fd, &read_fds);
tv.tv_sec = 0;
tv.tv_usec = conf.sleep_time;
mfd = max(mon, srv_fd) + 1;
ret = select(mfd, &read_fds, &write_fds, &excpt_fds, &tv);
if (ret == -1 && errno == EINTR)
return;
if (ret < 0)
err(1, "select()");
if (FD_ISSET(0, &read_fds))
handle_user_input();
if (conf.paused || len == -1) {
/*
* no packet received or paused: just wait a few ms
* if we wait too long here we will loose packets
* if we don't sleep there will be 100% system load
*/
usleep(conf.sleep_time);
continue;
}
#if DO_DEBUG
dump_packet(buffer, len);
#endif
memset(&current_packet, 0, sizeof(current_packet));
if (!parse_packet(buffer, len)) {
DEBUG("parsing failed\n");
continue;
}
if (FD_ISSET(mon, &read_fds)) {
len = recv_packet(mon, buffer, sizeof(buffer));
handle_packet(buffer, len);
}
if (filter_packet(&current_packet))
continue;
if (srv_fd && FD_ISSET(srv_fd, &read_fds))
net_handle_server_conn();
}
gettimeofday(&the_time, NULL);
int
main(int argc, char** argv)
{
INIT_LIST_HEAD(&essids.list);
INIT_LIST_HEAD(&nodes);
if (conf.dumpfile != NULL)
write_to_file(&current_packet);
get_options(argc, argv);
node = node_update(&current_packet);
if (!conf.quiet)
printf("horst: using monitoring interface %s\n", conf.ifname);
timeout_nodes();
signal(SIGINT, finish_all);
update_history(&current_packet);
update_statistics(&current_packet);
check_ibss_split(&current_packet, node);
gettimeofday(&stats.stats_time, NULL);
if (conf.rport) {
net_send_packet();
continue;
if (conf.serverip)
mon = net_open_client_socket(conf.serverip, conf.rport);
else {
mon = open_packet_socket(conf.ifname, sizeof(buffer), conf.recv_buffer_size);
if (mon < 0)
err(1, "couldn't open packet socket");
conf.arphrd = device_get_arptype();
if (conf.arphrd != ARPHRD_IEEE80211_PRISM &&
conf.arphrd != ARPHRD_IEEE80211_RADIOTAP) {
printf("wrong monitor type. please use radiotap or prism2 headers\n");
exit(1);
}
}
if (conf.dumpfile != NULL) {
DF = fopen(conf.dumpfile, "w");
if (DF == NULL)
err(1, "couldn't open dump file");
}
if (!conf.serverip && conf.rport)
net_init_server_socket(conf.rport);
#if !DO_DEBUG
update_display(&current_packet, node);
init_display();
#endif
for ( /* ever*/ ;;)
{
receive_any();
}
/* will never */
return 0;
......@@ -169,7 +215,7 @@ get_options(int argc, char** argv)
int c;
static int n;
while((c = getopt(argc, argv, "hqi:t:p:e:d:w:o:b:")) > 0) {
while((c = getopt(argc, argv, "hqi:t:p:e:d:w:o:b:c:")) > 0) {
switch (c) {
case 'p':
conf.rport = atoi(optarg);
......@@ -206,6 +252,9 @@ get_options(int argc, char** argv)
printf("%s\n", ether_sprintf(conf.filtermac[n]));
n++;
break;
case 'c':
conf.serverip = 0x7F000001;
break;
case 'h':
default:
printf("usage: %s [-h] [-q] [-i interface] [-t sec] [-p port] [-e mac] [-d usec] [-w usec] [-o file]\n\n"
......@@ -256,7 +305,8 @@ finish_all(int sig)
{
free_lists();
close_packet_socket();
if (!conf.serverip)
close_packet_socket();
if (DF != NULL)
fclose(DF);
......
......@@ -224,6 +224,7 @@ struct config {
int sleep_time;
char* dumpfile;
int recv_buffer_size;
int serverip;
unsigned char filtermac[MAX_FILTERMAC][MAC_LEN];
unsigned char filterbssid[MAC_LEN];
......
......@@ -30,70 +30,67 @@
extern struct config conf;
struct sockaddr_in sock_in, cin;
socklen_t cinlen;
int srv_fd=0;
int cli_fd=0;
int i;
fd_set rs;
char line[256];
int llen;
struct timeval to={0,0};
struct timeval tr={0,100};
int on = 1;
int srv_fd = 0;
int cli_fd = 0;
static int netmon_fd;
#define CLI_BACKLOG 5
void
net_init_socket(int rport)
net_init_server_socket(int rport)
{
struct sockaddr_in sock_in;
int reuse = 1;
if (!conf.quiet)
printf("using remote port %d\n",rport);
printf("using remote port %d\n", rport);
sock_in.sin_family=AF_INET;
sock_in.sin_port=htons(rport);
sock_in.sin_addr.s_addr=htonl(INADDR_ANY);
sock_in.sin_family = AF_INET;
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
sock_in.sin_port = htons(rport);
if ((srv_fd=socket(AF_INET,SOCK_STREAM,0)) < 0) {
if ((srv_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err(1, "socket");
}
if (setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
if (setsockopt(srv_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
err(1, "setsockopt SO_REUSEADDR");
}
if (bind(srv_fd, (struct sockaddr*)&sock_in, sizeof(sock_in)) < 0) {
if (bind(srv_fd, (struct sockaddr*)&sock_in, sizeof(sock_in)) < 0)
err(1, "bind");
}
if (listen(srv_fd, 5) < 0) {
if (listen(srv_fd, CLI_BACKLOG) < 0)
err(1, "listen");
}
}
int
net_send_packet(void)
net_send_packet(struct packet_info *pkt)
{
struct node_info* n;
FD_ZERO(&rs);
FD_SET(srv_fd,&rs);
if (select(srv_fd+1,&rs,NULL,NULL,&to) && FD_ISSET(srv_fd,&rs))
{
cli_fd = accept(srv_fd,(struct sockaddr*)&cin,&cinlen);
if (!conf.quiet)
printf("horst: accepting client\n");
if (!cli_fd)
return -1;
// discard stuff which was sent to us e.g. by a http client
FD_ZERO(&rs);
FD_SET(cli_fd,&rs);
while (select(cli_fd+1,&rs,NULL,NULL,&tr) && FD_ISSET(cli_fd,&rs)) {
read(cli_fd,line,sizeof(line));
FD_ZERO(&rs);
FD_SET(cli_fd,&rs);
}
write(cli_fd, &current_packet, sizeof(struct packet_info));
return 0;
}
int net_handle_server_conn()
{
struct sockaddr_in cin;
socklen_t cinlen;
cli_fd = accept(srv_fd, (struct sockaddr*)&cin, &cinlen);
if (!cli_fd)
return -1;
if (!conf.quiet)
printf("horst: accepting client\n");
//read(cli_fd,line,sizeof(line));
return 0;
}
#if 0
// satisfy http clients (wget)
static const char hdr[]="HTTP/1.0 200 ok\r\nContent-Type: text/plain\r\n\r\n";
write (cli_fd,hdr,sizeof(hdr));
write (cli_fd,hdr,sizeof(hdr));
list_for_each_entry(n, &nodes, list) {
char src_eth[18];
strcpy(src_eth,ether_sprintf(n->last_pkt.wlan_src));
......@@ -110,13 +107,43 @@ net_send_packet(void)
n->tsf);
write(cli_fd,line,llen);
}
close(cli_fd);
}
return 0;
#endif
int
net_open_client_socket(unsigned int serverip, unsigned int rport)
{
struct sockaddr_in sock_in;
if (!conf.quiet)
printf("using server %x port %d\n", serverip, rport);
sock_in.sin_family = AF_INET;
sock_in.sin_addr.s_addr = htonl(serverip);
sock_in.sin_port = htons(rport);
if ((netmon_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err(1, "socket");
if (connect(netmon_fd, (struct sockaddr*)&sock_in, sizeof(sock_in)) < 0)
err(1, "connect");
return netmon_fd;
}
void
net_finish(void) {
close(srv_fd);
if (srv_fd) {
shutdown(srv_fd, SHUT_RDWR);
close(srv_fd);
}
if (cli_fd) {
shutdown(cli_fd, SHUT_RDWR);
close(cli_fd);
}
if (netmon_fd) {
shutdown(netmon_fd, SHUT_RDWR);
close(netmon_fd);
}
}
......@@ -20,11 +20,18 @@
#ifndef _PROTOCOL_NETWORK_H_
#define _PROTOCOL_NETWORK_H_
struct packet_info;
int
net_init_server_socket(int rport);
int net_handle_server_conn(void);
int
net_init_socket(int rport);
net_send_packet(struct packet_info *pkt);
int
net_send_packet(void);
net_open_client_socket(unsigned int serverip, unsigned int rport);
void
net_finish(void);
......
......@@ -60,4 +60,6 @@ kilo_mega_ize(unsigned int val);
#define TOGGLE_BIT(_x, _m) (_x) ^= (_m)
#define max(x,y) ((x) > (y) ? (x) : (y))
#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