-rw-r--r-- | noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc | 134 | ||||
-rw-r--r-- | noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh | 49 |
2 files changed, 167 insertions, 16 deletions
diff --git a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc index 8c94cb1..cf50d8c 100644 --- a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc +++ b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.cc @@ -1,23 +1,23 @@ /* * Set card modes for sniffing * * $Id$ */ #include "cardmode.hh" #include "wl_log.hh" /* main card into monitor function */ -int card_into_monitormode (pcap_t **orighandle, char *device, int cardtype) +int card_into_monitormode (pcap_t **orighandle, 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 */ @@ -38,43 +38,50 @@ int card_into_monitormode (pcap_t **orighandle, char *device, int cardtype) 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); - printf ("\n %s",wlanngcmd); if (system(wlanngcmd) != 0) { wl_logerr("Could not set %s in raw mode, check cardtype", device); return 0; } } else if (cardtype == CARD_TYPE_HOSTAP) { - wl_logerr("Got a host-ap card, nothing is implemented now"); - char hostapcmd[250]; - snprintf(hostapcmd, sizeof(hostapcmd) -1, "$(which iwpriv) %s monitor 2 %d", device,1); - if (system(hostapcmd) !=0) - { - wl_logerr("Could not set %s in raw mode, check cardtype", device); - return 0; - } + int skfd; + skfd = socket(AF_INET, SOCK_STREAM, 0); + struct iwreq wrq; + wrq.u.mode = IW_MODE_MONITOR; + + if(iw_set_ext(skfd,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 if (cardtype == CARD_TYPE_ORINOCCO || cardtype == CARD_TYPE_HOSTAP) + 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); } } @@ -83,25 +90,25 @@ int card_into_monitormode (pcap_t **orighandle, char *device, int cardtype) { 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 (char *device) +int card_check_rfmon_datalink (const char *device) { int datalinktype=0; pcap_t *phandle; phandle = pcap_open_live(device, 65,0,0,NULL); datalinktype = pcap_datalink (phandle); pcap_close(phandle); if (datalinktype != DLT_IEEE802_11) /* Rawmode is IEEE802_11 */ { return 0; } else @@ -129,25 +136,25 @@ int card_set_promisc_up (const char *device) 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); - ioctl(fd, SIOCGIFFLAGS, &ifr); + 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; } @@ -159,48 +166,147 @@ int card_set_promisc_up (const char *device) } } /* 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 || cardtype == CARD_TYPE_HOSTAP) + 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,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, 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 4a95956..b35dddd 100644 --- a/noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh +++ b/noncore/net/wellenreiter/libwellenreiter/source/cardmode.hh @@ -26,23 +26,68 @@ extern "C" #include <net/bpf.h> #include <pcap.h> } /* 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 (char *device); -int card_into_monitormode (pcap_t **, char *, int); +int card_check_rfmon_datalink (const char *device); +int card_into_monitormode (pcap_t **, const char *, int); int card_set_promisc_up (const char *); 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 */ |