6 files changed, 134 insertions, 33 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,86 +1,75 @@ /* * 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)) - { - wl_logerr("Cannot initialize the wireless-card, 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) + /* 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("pcap_open_live() failed: %s", strerror(errno)); + wl_logerr("daemon, start_sniff did not return proper, aborting"); 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); } 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,35 +1,35 @@ /* * 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); @@ -131,48 +131,93 @@ int card_into_monitormode (pcap_t **orighandle, const char *device, int cardtype } 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; } @@ -194,58 +239,48 @@ int card_set_promisc_up (const char *device) } 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) { 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 @@ -17,78 +17,80 @@ /* 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 */ 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,36 +1,107 @@ /* * 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; 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 @@ -19,52 +19,55 @@ extern "C" #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 @@ -17,26 +17,27 @@ /* 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 */ |