summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/wellenreiter/daemon/source/daemon.cc27
-rw-r--r--noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc59
-rw-r--r--noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh6
-rw-r--r--noncore/net/wellenreiter/libwellenreiter/source/sniff.cc71
-rw-r--r--noncore/net/wellenreiter/libwellenreiter/source/sniff.hh5
-rw-r--r--noncore/net/wellenreiter/libwellenreiter/source/wl_types.hh1
6 files changed, 135 insertions, 34 deletions
diff --git a/noncore/net/wellenreiter/daemon/source/daemon.cc b/noncore/net/wellenreiter/daemon/source/daemon.cc
index 3a28217..b840f17 100644
--- a/noncore/net/wellenreiter/daemon/source/daemon.cc
+++ b/noncore/net/wellenreiter/daemon/source/daemon.cc
@@ -1,206 +1,195 @@
/*
* Startup functions of wellenreiter
*
* $Id$
*/
#include "config.hh"
#include "daemon.hh"
/* should be parsed from cfg-file */
#define MAXCHANNEL 13
#define CHANINTERVAL 500000
+
/* Main function of wellenreiterd */
int main(int argc, char **argv)
{
int sock, maxfd, retval;
char buffer[WL_SOCKBUF];
struct pcap_pkthdr header;
struct sockaddr_in saddr;
- pcap_t *handletopcap;
+// pcap_t *handletopcap;
wl_cardtype_t cardtype;
pthread_t sub;
const unsigned char *packet;
fd_set rset;
fprintf(stderr, "wellenreiterd %s\n\n", VERSION);
fprintf(stderr, "(c) 2002 by M-M-M\n\n");
if(argc < 3)
usage();
/* Set sniffer device */
memset(cardtype.iface, 0, sizeof(cardtype.iface));
strncpy(cardtype.iface, (char *)argv[1], sizeof(cardtype.iface) - 1);
/* Set card type */
cardtype.type = atoi(argv[2]);
if(cardtype.type < 1 || cardtype.type > 4)
usage();
- /* set card into monitor mode */
- if(!card_into_monitormode(&handletopcap, cardtype.iface,
- cardtype.type))
+ /* Until we do not act as a read daemon, it starts the sniffer
+ right after startup */
+ if (!start_sniffer(cardtype.iface,cardtype.type))
{
- wl_logerr("Cannot initialize the wireless-card, aborting");
- exit(EXIT_FAILURE);
+ wl_logerr("daemon, start_sniff did not return proper, aborting");
+ exit(EXIT_FAILURE);
}
- wl_loginfo("Set card into monitor mode");
-
- /* setup pcap */
- if((handletopcap = pcap_open_live(cardtype.iface,
- BUFSIZ, 1, 0, NULL)) == NULL)
- {
- wl_logerr("pcap_open_live() failed: %s", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
-#ifdef HAVE_PCAP_NONBLOCK
- pcap_setnonblock(handletopcap, 1, NULL);
-#endif
+ wl_loginfo ("daemon, wireless card prepared for sniffing");
/* Setup socket for incoming commands */
if((sock=wl_setupsock(DAEMONADDR, DAEMONPORT, saddr)) < 0)
{
wl_logerr("Cannot setup socket");
exit(EXIT_FAILURE);
}
wl_loginfo("Set up socket '%d' for GUI communication", sock);
/* Create channelswitching thread */
if(pthread_create(&sub, NULL, channel_switcher,
(void *)&cardtype) != 0)
{
wl_logerr("Cannot create thread: %s", strerror(errno));
close(sock);
exit(EXIT_FAILURE);
}
if(pthread_detach(sub))
{
wl_logerr("Error detaching thread");
close(sock);
pthread_exit((pthread_t *)sub);
exit(EXIT_FAILURE);
}
wl_loginfo("Created and detached channel switching thread");
FD_ZERO(&rset);
/* Start main loop */
wl_loginfo("Starting main loop");
while(1)
{
FD_SET(sock, &rset);
FD_SET(pcap_fileno(handletopcap), &rset);
/* maxfd = biggest filefd */
maxfd = (sock > pcap_fileno(handletopcap) ?
sock + 1 : pcap_fileno(handletopcap)) + 1;
if(select(maxfd, &rset, NULL, NULL, NULL) < 0)
{
wl_logerr("Error calling select: %s", strerror(errno));
break;
}
/* Got data on local socket from GUI */
if(FD_ISSET(sock, &rset))
{
/* Receive data from socket */
if((retval=wl_recv(&sock, saddr, buffer, sizeof(buffer))) < 0)
{
wl_logerr("Error trying to read: %s", strerror(errno));
break;
}
else
{
/* check type of packet and start function according to it */
switch(retval)
{
case STARTSNIFF:
wl_loginfo("Received STARTSNIFF command");
if(!send_ok(GUIADDR, GUIPORT, STARTSNIFF))
wl_logerr("Cannot set OK_CMD to GUI");
break;
case STOPSNIFF:
wl_loginfo("Received STOPSNIFF command");
if(!send_ok(GUIADDR, GUIPORT, STOPSNIFF))
wl_logerr("Cannot set FAIL_CMD to GUI");
break;
default:
wl_logerr("Received unknown command: %d", retval);
break;
}
}
} /* FD_ISSET */
/* Check pcap lib for packets */
if(FD_ISSET(pcap_fileno(handletopcap), &rset))
{
/* Grab one single packet */
packet = pcap_next(handletopcap, &header);
/* process the packet */
process_packets(&header,*&packet, GUIADDR, GUIPORT);
}
} /* while(1) */
close(sock);
exit(EXIT_SUCCESS);
}
void
usage(void)
{
fprintf(stderr, "Usage: wellenreiter <device> <cardtype>\n" \
"\t<device> = Wirelessdevice (e.g. wlan0)\n" \
"\t<cardtype> = Cardtype:\tCisco\t= 1\n" \
"\t\t\t\tNG\t= 2\n" \
"\t\t\t\tHOSTAP\t= 3\n" \
"\t\t\t\tLUCENT\t= 4\n");
exit(EXIT_FAILURE);
}
void *
channel_switcher(void *cardtypeptr)
{
wl_cardtype_t *cardtype;
int maxchan=0;
int channel=1;
/* Get card info struct */
cardtype = (wl_cardtype_t *)cardtypeptr;
/* Get from the wireless extension the amount of available channels
this prevents a fail in switching on us cards */
maxchan = card_detect_channels(cardtype->iface);
if (maxchan < MAXCHANNEL)
{
#undef MAXCHANNEL
#define MAXCHANNEL maxchan
}
while(1)
{
/* If channel bigger than maxchannel, set to 1 */
if(channel > MAXCHANNEL)
channel=1;
/* Set channel */
if(!card_set_channel(cardtype->iface, channel, cardtype->type))
{
wl_logerr("Cannot set channel, thread exiting");
pthread_exit(NULL);
}
/* sleep */
usleep(CHANINTERVAL);
channel++;
} /* while */
}
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc
index 7c9fbc4..4f187c0 100644
--- a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc
+++ b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc
@@ -1,416 +1,451 @@
/*
* Set card modes for sniffing
*
* $Id$
*/
#include "cardmode.hh"
#include "wl_log.hh"
-
+pcap_t *handletopcap;
/* main card into monitor function */
-int card_into_monitormode (pcap_t **orighandle, const char *device, int cardtype)
+int card_into_monitormode (const char *device, int cardtype)
{
char CiscoRFMON[35] = "/proc/driver/aironet/";
FILE *CISCO_CONFIG_FILE;
/* Checks if we have a device to sniff on */
if(device == NULL)
{
wl_logerr("No device given");
return 0;
}
/* Setting the promiscous and up flag to the interface */
if (!card_set_promisc_up(device))
{
wl_logerr("Cannot set interface to promisc mode");
return 0;
}
wl_loginfo("Interface set to promisc mode");
/* Check the cardtype and executes the commands to go into monitor mode */
if (cardtype == CARD_TYPE_CISCO)
{
/* bring the sniffer into rfmon mode */
snprintf(CiscoRFMON, sizeof(CiscoRFMON) - 1, DEFAULT_PATH, device);
if((CISCO_CONFIG_FILE = fopen(CiscoRFMON,"w")) == NULL)
{
wl_logerr("Cannot open config file: %s", strerror(errno));
return 0;
}
fputs ("Mode: r",CISCO_CONFIG_FILE);
fputs ("Mode: y",CISCO_CONFIG_FILE);
fputs ("XmitPower: 1",CISCO_CONFIG_FILE);
fclose(CISCO_CONFIG_FILE);
}
else if (cardtype == CARD_TYPE_NG)
{
char wlanngcmd[80];
snprintf(wlanngcmd, sizeof(wlanngcmd) - 1, "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=true", device, 1);
if (system(wlanngcmd) != 0)
{
wl_logerr("Could not set %s in raw mode, check cardtype", device);
return 0;
}
}
else if (cardtype == CARD_TYPE_HOSTAP)
{
#if WIRELESS_EXT > 14
// IW_MODE_MONITOR was implemented in Wireless Extensions Version 15
int skfd;
skfd = socket(AF_INET, SOCK_STREAM, 0);
struct iwreq wrq;
wrq.u.mode = IW_MODE_MONITOR;
if(iw_set_ext(skfd,(char *) device,SIOCSIWMODE,&wrq)<0)
{
wl_logerr("Could not set hostap card %s to raw mode, check cardtype", device);
return 0;
}
else
{
wl_loginfo("Successfully set hostap card %s into raw mode",device);
return 1;
}
return 1;
#else
// Wireless Extensions < Version 15 need iwpriv commandos for monitoring
int fd;
//Wireless tools structure for the iocalls
struct iwreq ireq;
int *ptr;
/* Socket needed to use the iocall to */
fd = socket(AF_INET, SOCK_STREAM, 0);
if ( fd == -1 ) {
return -1;
}
ptr = (int *) ireq.u.name;
// This is the monitor mode for 802.11 non-prism header
ptr[0] = 2;
strcpy(ireq.ifr_ifrn.ifrn_name, device);
if (ioctl( fd, SIOCDEVPRIVATE, &ireq)==0)
{
/* All was fine... */
close(fd);
wl_loginfo("Set hostap card %s into monitormode",device);
return 1;
}
else
{
/* iocall does not work */
close(fd);
wl_logerr("Could not set hostap card %s into monitormode, check cardtype",device);
return 0;
}
#endif
}
else if (cardtype == CARD_TYPE_ORINOCCO )
{
if (!card_set_channel (device, 1, CARD_TYPE_ORINOCCO))
{
wl_logerr("Could not set %s in raw mode, check cardtype", device);
return 0;
}
else
{
wl_loginfo("Successfully set %s into raw mode",device);
}
}
/* Setting the promiscous and up flag to the interface */
if (!card_check_rfmon_datalink(device))
{
wl_logerr("Cannot set interface to rfmon mode");
return 0;
}
else
{
wl_loginfo("Interface set to rfmon mode");
}
return 1;
}
/* Check card is in the rfmon mode */
int card_check_rfmon_datalink (const char *device)
{
int datalinktype=0;
pcap_t *phandle;
phandle = pcap_open_live((char *)device, 65,0,0,NULL);
datalinktype = pcap_datalink (phandle);
pcap_close(phandle);
if (datalinktype != DLT_IEEE802_11) /* Rawmode is IEEE802_11 */
{
return 0;
}
else
{
wl_loginfo("Your successfully listen on %s in 802.11 raw mode", device);
return 1;
}
}
+/* Ipaq running familiar does not have a loopback device, we need one */
+int check_loopback()
+{
+ /* Checking for a loopback interface with 127.0.0.1, otherwise the other stuff seems to fail on
+ familiar linux on ipaq's */
+ int err;
+ /* First generate a socket to use with iocalls */
+ int fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ {
+ /* In case of an error */
+ wl_logerr("check_loopback, generation of a socket failed, cannot continue");
+ return 0;
+ }
+ /* Fill an empty an interface structure with the right flags (UP and Promsic) */
+ struct ifreq ifr;
+ strncpy(ifr.ifr_name, "lo",3);
+
+ /* Get the interface flags, loopback interfaces can be detected that way */
+ err = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ if (err < 0)
+ {
+ wl_logerr("check_loopback, could not get the flags of lo, check if you got a lo loopback interface, cannot continue");
+ close(fd);
+ return 0;
+ }
+ /* Checking the flags for IFF_LOOPBACK flags */
+ if(ifr.ifr_flags && IFF_LOOPBACK)
+ {
+ /* Yes, we do have a loopback interface....sup! */
+ close(fd);
+ wl_loginfo ("check_loopback, check for loopback interface lo successful");
+ return 1;
+ }
+ else
+ {
+ wl_logerr("check_loopback, did not found an interface lo with the IFF_LOOPBACK flag set, cannot continue");
+ close(fd);
+ return 0;
+ }
+ /* Should never be reached */
+ return 0;
+} /*check_loopback */
+
+
/* Set card into promisc mode */
int card_set_promisc_up (const char *device)
{
int err;
/* First generate a socket to use with iocalls */
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
/* In case of an error */
perror("socket");
return 0;
}
/* Fill an empty an interface structure with the right flags (UP and Promsic) */
struct ifreq ifr;
strncpy(ifr.ifr_name, device,10);
ifr.ifr_flags = IFF_UP + IFF_PROMISC;
err = ioctl(fd, SIOCSIFFLAGS, &ifr);
if (err < 0)
{
perror("Could not access the interface, ");
close(fd);
return 0;
}
/* Get the informations back from the interface to check if the flags are correct */
strncpy(ifr.ifr_name, device,10);
err = ioctl(fd, SIOCGIFFLAGS, &ifr);
if (err < 0)
{
perror("Could not access the interface, ");
close(fd);
return 0;
}
if(ifr.ifr_flags && IFF_UP)
{
close(fd);
return 1;
}
else
{
wl_logerr("Could not set promisc flag on %d", device);
close(fd);
return 0;
}
}
/* Remove card from promisc mode */
int card_remove_promisc (const char *device)
{
int err;
/* First generate a socket to use with iocalls */
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
/* In case of an error */
perror("socket");
return 0;
}
/* Fill an empty an interface structure with the right flags (UP and Promsic) */
struct ifreq ifr;
-/* strncpy(ifr.ifr_name, device,10);
- ifr.ifr_flags = IFF_UP + IFF_PROMISC;
- err = ioctl(fd, SIOCSIFFLAGS, &ifr);
- if (err < 0)
- {
- perror("Could not access the interface, ");
- close(fd);
- return 0;
- }
- */
/* Get the flags from the interface*/
strncpy(ifr.ifr_name, device,10);
err = ioctl(fd, SIOCGIFFLAGS, &ifr);
if (err < 0)
{
perror("Could not access the interface, ");
close(fd);
return 0;
}
/* Remove the IFF_PROMISC flag */
ifr.ifr_flags = ifr.ifr_flags - IFF_PROMISC;
/*Set the new flags to the interface*/
err = ioctl(fd, SIOCSIFFLAGS, &ifr);
if (err < 0)
{
perror("Could not access the interface, ");
close(fd);
return 0;
}
/* Get the flags again to check if IFF_PROMISC is removed */
err = ioctl(fd, SIOCGIFFLAGS, &ifr);
if (err < 0)
{
perror("Could not access the interface, ");
close(fd);
return 0;
}
if(ifr.ifr_flags && IFF_PROMISC)
{
wl_logerr("Could not remove the promisc flag on %d", device);
close(fd);
return 0;
}
else
{
/* Successfully removed the promisc flags */
close(fd);
return 1;
}
}
/* Set channel (Wireless frequency) of the device */
int card_set_channel (const char *device, int channel, int cardtype)
{
if (cardtype == CARD_TYPE_CISCO || cardtype == CARD_TYPE_NG)
{
/* Cisco and wlan-ng drivers don't need channelswitching */
return 1;
}
/* If it is a lucent orinocco card */
else if (cardtype == CARD_TYPE_ORINOCCO)
{
int fd;
//Wireless tools structure for the iocalls
struct iwreq ireq;
int *ptr;
/* Socket needed to use the iocall to */
fd = socket(AF_INET, SOCK_STREAM, 0);
if ( fd == -1 ) {
return -1;
}
ptr = (int *) ireq.u.name;
// This is the monitor mode for 802.11 non-prism header
ptr[0] = 2;
ptr[1] = channel;
strcpy(ireq.ifr_ifrn.ifrn_name, device);
if (ioctl( fd, SIOCIWFIRSTPRIV + 0x8, &ireq)==0)
{
/* All was fine... */
close(fd);
wl_loginfo("Set channel %d on interface %s",channel, device);
return 1;
}
else
{
/* iocall does not work */
close(fd);
wl_logerr("Could not set channel %d on %s, check cardtype",channel, device);
return 0;
}
}
/* when it is an hostap card you need another iocall for channel switching */
else if (cardtype == CARD_TYPE_HOSTAP)
{
int skfd;
skfd = socket(AF_INET, SOCK_STREAM, 0);
struct iwreq wrq;
iw_float2freq((double) channel, &wrq.u.freq);
if(iw_set_ext(skfd,(char *) device,SIOCSIWFREQ,&wrq)<0)
{
wl_logerr("Could not set hostap card %s to channel %d", device, channel);
return 0;
}
else
{
wl_loginfo("Successfully set hostap card %s to channel %d", device, channel);
return 1;
}
}
/* For undefined situations */
return 0;
}
int card_detect_channels (char * device)
{
int skfd;
skfd = socket(AF_INET, SOCK_STREAM, 0);
struct iw_range range;
/* Get list of frequencies / channels */
printf ("\n hostap card get the frequencies");
/* Get list of frequencies / channels */
if(iw_get_range_info(skfd, device, &range) < 0)
{ /* We are failsave if something went wrong, asume only 11 channels */
return 11;
}
else
{
if(range.num_frequency > 0)
{
return range.num_frequency;
}
else
{ /* We are failsave asume only 11 channels */
return 11;
}
}
} /* End of card_detect_channels */
int iw_get_range_info(int skfd, const char * ifname, iw_range * range)
{
struct iwreq wrq2;
char buffer[sizeof(iw_range) * 2]; /* Large enough */
/* Cleanup */
memset(buffer, 0, sizeof(buffer));
wrq2.u.data.pointer = (caddr_t) buffer;
wrq2.u.data.length = sizeof(buffer);
wrq2.u.data.flags = 0;
if(iw_get_ext(skfd, (char *)ifname, SIOCGIWRANGE, &wrq2) < 0)
{
wl_logerr("Could not get the range from the interface");
return(-1);
}
else
{
/* Copy stuff at the right place, ignore extra */
memcpy((char *) range, buffer, sizeof(iw_range));
return 0;
}
}
/*------------------------------------------------------------------*/
/*
* Convert our internal representation of frequencies to a floating point.
*/
double iw_freq2float(iw_freq * in)
{
int i;
double res = (double) in->m;
for(i = 0; i < in->e; i++)
res *= 10;
return(res);
}
void iw_float2freq(double in, iw_freq * out)
{
/* Version without libm : slower */
out->e = 0;
while(in > 1e9)
{
in /= 10;
out->e++;
}
out->m = (long) in;
}
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh
index 58e99ac..73e0ae1 100644
--- a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh
+++ b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh
@@ -1,105 +1,107 @@
/* $Id$ */
#ifndef CARDMODE_HH
#define CARDMODE_HH
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/if.h>
/* Following typedefs are needed here, because linux/wireless.h
includes linux/ethertool.h which is using them */
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
#include <linux/wireless.h>
#ifndef SIOCIWFIRSTPRIV
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
#endif
extern "C"
{
#include <net/bpf.h>
#include <pcap.h>
}
+extern pcap_t *handletopcap;
+
/* Defines, used for the card setup */
#define DEFAULT_PATH "/proc/driver/aironet/%s/Config"
#define CISCO_STATUS "/proc/driver/aironet/%s/Status"
#define CARD_TYPE_CISCO 1
#define CARD_TYPE_NG 2
#define CARD_TYPE_HOSTAP 3
#define CARD_TYPE_ORINOCCO 4
/* Some usefull constants for frequencies */
#define KILO 1e3
#define MEGA 1e6
#define GIGA 1e9
/* only for now, until we have the daemon running */
/*the config file should provide these information */
#define CARD_TYPE CARD_TYPE_HOSTAP
/* Prototypes */
int card_check_rfmon_datalink (const char *device);
-int card_into_monitormode (pcap_t **, const char *, int);
+int card_into_monitormode (const char *, int);
+int check_loopback();
int card_set_promisc_up (const char *device);
int card_remove_promisc (const char *device);
int card_set_channel (const char *device, int channel,int cardtype);
int iw_get_range_info(int skfd, const char * ifname, struct iw_range * range);
double iw_freq2float(iw_freq * in);
void iw_float2freq(double in, iw_freq * out);
int card_detect_channels (char * device);
-
/*------------------------------------------------------------------*/
/*
* Wrapper to push some Wireless Parameter in the driver
*/
static inline int
iw_set_ext(int skfd, /* Socket to the kernel */
char * ifname, /* Device name */
int request, /* WE ID */
struct iwreq * pwrq) /* Fixed part of the request */
{
/* Set device name */
strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
/* Do the request */
return(ioctl(skfd, request, pwrq));
}
/*------------------------------------------------------------------*/
/*
* Wrapper to extract some Wireless Parameter out of the driver
*/
static inline int
iw_get_ext(int skfd, /* Socket to the kernel */
char * ifname, /* Device name */
int request, /* WE ID */
struct iwreq * pwrq) /* Fixed part of the request */
{
/* Set device name */
strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
/* Do the request */
return(ioctl(skfd, request, pwrq));
}
#endif /* CARDMODE_HH */
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc b/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc
index 6e512c4..0616a7e 100644
--- a/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc
+++ b/noncore/net/wellenreiter/libwellenreiter/source/sniff.cc
@@ -1,268 +1,339 @@
/*
* rfmon mode sniffer
*
* $Id$
*/
#include "sniff.hh"
#include "ieee802_11.hh"
#include "extract.hh"
#include "wl_log.hh"
#include "wl_types.hh"
#include "wl_proto.hh"
+#include "cardmode.hh"
+
+int start_sniffer(const char *device, int cardtype )
+{
+
+ /* This function initialize the sniffing
+ 1. Check for lo interface
+ 2. bring it into promsicous mode and UP
+ 3. bring device into rfmon mode
+ start the pcap sniffing process.
+ */
+
+ /* Do we have the device name ? */
+ if(device == NULL)
+ {
+ wl_logerr("start_sniffer, parameter \"device\" is empty, please check your config");
+ return 0;
+ }
+
+ /* Some Linux System does not have a loopback device lo with 127.0.0.1 so sockets could
+ not made correctly, let the proggie check that and proceed only if it exists. */
+ if (!check_loopback())
+ {
+ wl_logerr("start_sniffer, check_loopback failed, cannot continue without a loopback");
+ return 0;
+ }
+
+ /* Set the card into regulary promiscous mode first and set the UP flag, in case no ip
+ was given. It would work without the promisc flags but i dont like this */
+ if (!card_set_promisc_up(device))
+ {
+ wl_logerr("start_sniffer, card_set_promisc_up failed, cannot continue");
+ return 0;
+ }
+
+ /* Set card into the rfmon/monitoring mode */
+ if (!card_into_monitormode(device,cardtype))
+ {
+ wl_logerr("start_sniffer, cannot put wireless card into monitoring mode, aborting");
+ return 0;
+ }
+
+ /* setup pcap handle, used for the packet decoding etc. */
+ if((handletopcap = pcap_open_live((char *) device, BUFSIZ, 1, 0, NULL)) == NULL)
+ {
+ wl_logerr("pcap_open_live() failed: %s", strerror(errno));
+ return 0;
+ }
+
+#ifdef HAVE_PCAP_NONBLOCK
+ pcap_setnonblock(handletopcap, 1, NULL);
+#endif
+ return 1;
+}
+
+
+int stop_sniffer(const char *device, int cardtype)
+{
+ /* This function terminates the sniffing
+ 1. get the device state
+ 2. remove the rfmon state
+ 3. Remove the promisc state
+ start the pcap sniffing process.
+
+ */
+
+ /* Do we really have at least a lo interface with the 127.0.0.1 ? */
+ return 0;
+
+}
+
/* Main function, checks packets */
void process_packets(const struct pcap_pkthdr *pkthdr,
const unsigned char *packet,
char *guihost,
int guiport)
{
unsigned int caplen = pkthdr->caplen;
unsigned int length = pkthdr->len;
u_int16_t fc;
unsigned int HEADER_LENGTH;
/* pinfo holds all interresting information for us */
struct packetinfo pinfo;
struct packetinfo *pinfoptr;
/* wl_network_t will finally be set and send to the ui */
wl_network_t wl_net;
pinfoptr=&pinfo;
pinfoptr->isvalid = 0;
pinfoptr->pktlen = pkthdr->len;
if (caplen < IEEE802_11_FC_LEN)
{
/* This is a garbage packet, because is does not long enough
to hold a 802.11b header */
pinfoptr->isvalid = 0;
return;
}
/* Gets the framecontrol bits (2bytes long) */
fc = EXTRACT_LE_16BITS(packet);
HEADER_LENGTH = GetHeaderLength(fc);
if (caplen < HEADER_LENGTH)
{
/* This is a garbage packet, because it is not long enough
to hold a correct header of its type */
pinfoptr->isvalid = 0;
return;
}
/* Decode 802.11b header out of the packet */
if (decode_80211b_hdr(packet,pinfoptr) == 0)
{
/* Justification of the ofset to further process the packet */
length -= HEADER_LENGTH;
caplen -= HEADER_LENGTH;
packet += HEADER_LENGTH;
}
else /* Something is wrong,could not be a correct packet */
return;
switch (FC_TYPE(fc))
{
/* Is it a managemnet frame? */
case T_MGMT:
switch (FC_SUBTYPE(fc))
{
case ST_BEACON:
if (handle_beacon(fc, packet,pinfoptr) ==0)
{
if (!strcmp(pinfoptr->desthwaddr,"ff:ff:ff:ff:ff:ff") == 0)
{
/* Every beacon must have the broadcast as destination
so it must be a shitti packet */
pinfoptr->isvalid = 0;
return;
}
if (pinfoptr->cap_ESS == pinfoptr->cap_IBSS)
{
/* Only one of both are possible, so must be
a noise packet, if this comes up */
pinfoptr->isvalid = 0;
return;
}
if (pinfoptr->channel < 1 || pinfoptr->channel > 14)
{
/* Only channels between 1 and 14 are possible
others must be noise packets */
pinfoptr->isvalid = 0;
return;
}
/* Here should be the infos to the gui issued */
if (pinfoptr->cap_ESS == 1 && pinfoptr->cap_IBSS ==0)
{
wl_loginfo("Found an access point");
wl_net.net_type=1;
}
else if(pinfoptr->cap_ESS == 0 && pinfoptr->cap_IBSS == 2)
{
wl_loginfo("Found an ad-hoc network");
wl_net.net_type=2;
}
if (strcmp (pinfoptr->ssid,NONBROADCASTING) ==0)
wl_loginfo("Net is a non-broadcasting network");
else
wl_loginfo("SSID is: %s", pinfoptr->ssid);
wl_loginfo("SSID is: %s", pinfoptr->ssid);
memset(wl_net.bssid, 0, sizeof(wl_net.bssid));
memcpy(wl_net.bssid, pinfoptr->ssid, sizeof(wl_net.bssid)-1);
wl_loginfo("SSID length is: %d", pinfoptr->ssid_len);
wl_net.ssid_len=pinfoptr->ssid_len;
wl_loginfo("Channel is: %d", pinfoptr->channel);
wl_net.channel=pinfoptr->channel;
wl_net.wep=pinfoptr->cap_WEP;
wl_loginfo("Mac is: %s", pinfoptr->sndhwaddr);
memset(wl_net.mac, 0, sizeof(wl_net.mac));
memcpy(wl_net.mac, pinfoptr->sndhwaddr, sizeof(wl_net.mac)-1);
if(!send_network_found((char *)guihost, guiport, &wl_net))
{
wl_logerr("Error sending data to UI: %s", strerror(errno));
break;
}
wl_loginfo("Sent network to GUI '%s:%d'", guihost, guiport);
}
break;
default:
wl_logerr("Unknown IEEE802.11 frame subtype (%d)", FC_SUBTYPE(fc));
break;
} /* End of switch over different mgt frame types */
break;
case T_CTRL:
wl_loginfo("Received control frame, not implemented yet");
break;
case T_DATA:
wl_loginfo("Received date frame, not implemented yet");
break;
default:
wl_logerr("Unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
break;
}
}
/* This decodes the 802.11b frame header out of the 802.11b packet
all the infos is placed into the packetinfo structure */
int decode_80211b_hdr(const u_char *p,struct packetinfo *ppinfo)
{
const struct mgmt_header_t *mgthdr = (const struct mgmt_header_t *) p;
ppinfo->fcsubtype = FC_SUBTYPE(mgthdr->fc);
/* Get the sender, bssid and dest mac address */
etheraddr_string(mgthdr->bssid,ppinfo->bssid);
etheraddr_string(mgthdr->da,ppinfo->desthwaddr);
etheraddr_string(mgthdr->sa,ppinfo->sndhwaddr);
ppinfo->fc_wep = FC_WEP(mgthdr->fc);
return 0;
}
void etheraddr_string(register const u_char *ep, char *text)
{
static char hex[] = "0123456789abcdef";
register unsigned int i, j;
register char *cp;
char buf[sizeof("00:00:00:00:00:00\0")];
cp = buf;
if ((j = *ep >> 4) != 0)
{
*cp++ = hex[j];
}
else
{
*cp++ = '0';
}
*cp++ = hex[*ep++ & 0xf];
for (i = 5; (int)--i >= 0;)
{
*cp++ = ':';
if ((j = *ep >> 4) != 0)
{
*cp++ = hex[j];
}
else
{
*cp++ = '0';
}
*cp++ = hex[*ep++ & 0xf];
}
*cp = '\0';
strcpy(text,buf);
}
/* beacon handler */
int handle_beacon(u_int16_t fc, const u_char *p,struct packetinfo *ppinfo)
{
struct mgmt_body_t pbody;
int offset = 0;
/* Get the static informations out of the packet */
memset(&pbody, 0, sizeof(pbody));
memcpy(&pbody.timestamp, p, 8);
offset += 8;
pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
offset += 2;
pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
offset += 2;
/* Gets the different flags out of the capabilities */
ppinfo->cap_ESS = CAPABILITY_ESS(pbody.capability_info);
ppinfo->cap_IBSS = CAPABILITY_IBSS(pbody.capability_info);
ppinfo->cap_WEP = CAPABILITY_PRIVACY(pbody.capability_info);
/* Gets the tagged elements out of the packets */
while (offset + 1 < ppinfo->pktlen)
{
switch (*(p + offset))
{
case E_SSID:
memcpy(&(pbody.ssid),p+offset,2); offset += 2;
if (pbody.ssid.length > 0)
{
memcpy(&(pbody.ssid.ssid),p+offset,pbody.ssid.length);
offset += pbody.ssid.length;
pbody.ssid.ssid[pbody.ssid.length]='\0';
if (strcmp((char *)pbody.ssid.ssid,"")==0)
memcpy(ppinfo->ssid, NONBROADCASTING, sizeof(ppinfo->ssid));
else
memcpy(ppinfo->ssid, pbody.ssid.ssid, sizeof(ppinfo->ssid));
ppinfo->ssid_len = pbody.ssid.length;
}
break;
case E_CHALLENGE:
memcpy(&(pbody.challenge),p+offset,2); offset += 2;
if (pbody.challenge.length > 0)
{
memcpy(&(pbody.challenge.text),p+offset,pbody.challenge.length);
offset += pbody.challenge.length;
pbody.challenge.text[pbody.challenge.length]='\0';
}
break;
case E_RATES:
memcpy(&(pbody.rates),p+offset,2); offset += 2;
if (pbody.rates.length > 0)
{
memcpy(&(pbody.rates.rate),p+offset,pbody.rates.length);
offset += pbody.rates.length;
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/sniff.hh b/noncore/net/wellenreiter/libwellenreiter/source/sniff.hh
index c7108ac..a4cf4b7 100644
--- a/noncore/net/wellenreiter/libwellenreiter/source/sniff.hh
+++ b/noncore/net/wellenreiter/libwellenreiter/source/sniff.hh
@@ -1,70 +1,73 @@
/* $Id$ */
#ifndef SNIFF_HH
#define SNIFF_HH
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
extern "C"
{
#include <net/bpf.h>
#include <pcap.h>
}
#define NONBROADCASTING "non-broadcasting"
/* holds all the interresting data */
struct packetinfo
{
int isvalid;
int pktlen;
int fctype;
int fcsubtype;
int fc_wep;
int cap_WEP;
int cap_IBSS;
int cap_ESS;
int channel;
char bssid[sizeof("00:00:00:00:00:00") + 1];
char desthwaddr[sizeof("00:00:00:00:00:00") + 1];
char sndhwaddr[sizeof("00:00:00:00:00:00") + 1];
char ssid[128];
int ssid_len;
};
+/* Function definitions */
+/* Used for stoping and starting the sniffer process */
+int start_sniffer(const char *device, int cardtype);
+int stop_sniffer(const char *device, int cardtype);
void process_packets(const struct pcap_pkthdr* pkthdr,const u_char* packet, char *, int);
int decode_80211b_hdr(const u_char *p,struct packetinfo *ppinfo);
void etheraddr_string(register const u_char *ep,char * text);
int handle_beacon(u_int16_t fc, const u_char *p,struct packetinfo *ppinfo);
-
int GetHeaderLength(u_int16_t fc);
/*
* True if "l" bytes of "var" were captured.
*
* The "snapend - (l) <= snapend" checks to make sure "l" isn't so large
* that "snapend - (l)" underflows.
*
* The check is for <= rather than < because "l" might be 0.
*/
#define TTEST2(var, l) (snapend - (l) <= snapend && \
(const u_char *)&(var) <= snapend - (l))
/* True if "var" was captured */
#define TTEST(var) TTEST2(var, sizeof(var))
/* Bail if "l" bytes of "var" were not captured */
#define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc
/* Bail if "var" was not captured */
#define TCHECK(var) TCHECK2(var, sizeof(var))
#endif /* SNIFF_HH */
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/wl_types.hh b/noncore/net/wellenreiter/libwellenreiter/source/wl_types.hh
index cd482fe..afc105c 100644
--- a/noncore/net/wellenreiter/libwellenreiter/source/wl_types.hh
+++ b/noncore/net/wellenreiter/libwellenreiter/source/wl_types.hh
@@ -1,42 +1,43 @@
/*
* Global bufffer size and type definitions
*
* $Id$
*
*/
#ifndef WL_TYPES_HH
#define WL_TYPES_HH
/* Type definitions, to be continued */
#define WL_NETFOUND 01
#define WL_NETLOST 02
#define WL_STARTSNIFF 98
#define WL_STOPSNIFF 99
/* Socket specific */
#define WL_SOCKBUF 512 /* Buffer for wl_send and wl_recv calls */
/* Channelswitching */
typedef struct {
int type; /* Type of card (chip) */
char iface[6]; /* Interface of card */
} wl_cardtype_t;
/* WL network structure */
typedef struct {
int net_type; /* 1 = Accesspoint ; 2 = Ad-Hoc */
int ssid_len; /* Length of SSID */
int channel; /* Channel */
int wep; /* 1 = WEP enabled ; 0 = disabled */
char mac[64]; /* MAC address of Accesspoint */
char bssid[128]; /* BSSID of Net */
} wl_network_t;
/* Config specific */
#define WL_CONFFILE "sample.conf"
#define WL_CONFBUFF 128
+
#endif /* WL_TYPES_HH */