diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e648b3..76b0e24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,12 +161,7 @@ add_subdirectory(owlps-client) ## Listener ## -if (${CMAKE_SYSTEM_NAME} STREQUAL Linux) - add_subdirectory(owlps-listener) -else() - message(WARNING - "OwlPS Listener can be built only for Linux systems") -endif() +add_subdirectory(owlps-listener) ## Positioner ## diff --git a/INSTALL.t2t b/INSTALL.t2t index 047a4e4..d07d8a8 100644 --- a/INSTALL.t2t +++ b/INSTALL.t2t @@ -3,8 +3,9 @@ Compiling and installing OwlPS = Basics = -To fully build OwlPS, you need a GNU/Linux system (see “Compiling on BSD -systems” below) with the following development libraries installed: +The preferred platform to build and run OwlPS is a GNU/Linux system (see +“Compiling on BSD systems” below) with the following development +libraries installed: - //confuse// - //pcap// @@ -95,15 +96,14 @@ configuration as explained in the previous section. = Compiling on BSD systems = -The procedure is the same as on GNU/Linux systems, but keep in mind that -OwlPS Listener is deactivated on BSD, since it still contains some -Linux-specific code. (The positive effect is that you won't have to -install libpcap, heh.) +We try to write portable code and support BSD systems as much as +possible, but OwlPS is primarily developed and tested on GNU/Linux so +there can be more bugs on BSD (please report them!). -You may also need to edit the configuration (cf. “Tweaking” above), for -example to force a specific GCC version to be used. On OpenBSD, you need -to have the CXX variable set with the ``-fPIE`` flag when calling -``cmake``: +The building procedure is the same as on GNU/Linux systems, but you may +need to edit the configuration (cf. “Tweaking” above), for example to +force a specific GCC version to be used. On OpenBSD, you need to have +the CXX variable set with the ``-fPIE`` flag when calling ``cmake``: ``` CXX="eg++ -fPIE" cmake ../owlps diff --git a/TODO.t2t b/TODO.t2t index 92137fd..e9f1986 100644 --- a/TODO.t2t +++ b/TODO.t2t @@ -141,10 +141,6 @@ Work to do in OwlPS Currently the size is corrected only for data packets. -- BSD port - - http://www.unixgarden.com/index.php/programmation/introduction-a-la-programmation-wifi-en-c-sous-netbsd - diff --git a/doc/owlps.t2t b/doc/owlps.t2t index eeca411..2fe38f3 100644 --- a/doc/owlps.t2t +++ b/doc/owlps.t2t @@ -24,10 +24,11 @@ June 2013 **OwlPS** (//Owl Positioning System//) is a positioning (localization) system based on the IEEE 802.11 radio network (Wi-Fi). It targets mainly -UNIX-like operating systems and is currently fully usable only on -GNU/Linux. Originally developped at the University of Franche-Comté -(Université de Franche-Comté, France), it is released under the terms of -the CeCILL free software license (GNU GPL-compatible). +UNIX-like operating systems and is developed and tested primarily on +GNU/Linux, but it should work on BSD platforms as well. Originally +developed at the University of Franche-Comté (Université de +Franche-Comté, France), it is released under the terms of the CeCILL +free software license (GNU GPL-compatible). OwlPS uses an infrastructure-centred architecture, which means the infrastructure does the measurements and computes the mobile terminals' @@ -127,7 +128,7 @@ revision number is not mandatory, but it is allowed. For example: - owlps-positionerd.t2t -++ Developping with OwlPS libraries ++ +++ Developing with OwlPS libraries ++ - owlps.h (Doxygen-generated documentation) - owlps-client.h (Doxygen-generated documentation) diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index ea3632a..ecec872 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -50,6 +50,11 @@ #include #include +#ifndef __GLIBC__ +# include +# include +#endif // __GLIBC__ + #include @@ -881,6 +886,14 @@ void* keep_mode_monitor(void *iface) /* * Switches the IEEE 802.11 interface 'iface' to Monitor mode. + * + * This function uses iwlib, which is Linux-specific. In case we want + * this on BSD, there is some example code there: + * http://www.unixgarden.com/index.php/gnu-linux-magazine-hs/introduction-a-la-programmation-wifi-en-c-sous-netbsd#7-exemple-n°4-activer-et-utiliser-le-monitoring-aka-rf_mon + * The thing is that we would have to switch the interface down and up + * each time, so let's hope we will never need that. But even on Linux, + * this function was only needed with the buggy ipw2200 driver (for Intel + * BG2200 chips) and it hopefully won't be needed any more. */ int iface_mode_monitor(const char *const iface) { @@ -1103,6 +1116,13 @@ void read_packet(const struct pcap_pkthdr *pkt_header, memcpy(request.cp_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ; // Capture time is in the pcap header (host-endian): owl_timeval_to_timestamp(&pkt_header->ts, &request.capture_time) ; + /* Note on the line above: on OpenBSD, the ts field of struct + * pcap_pkthdr (defined in ) is a struct bpf_timeval* instead + * of a struct timeval*. struct bpf_timeval is defined in + * /usr/include/net/bpf.h and is a clone of struct timeval with + * fixed-size fields (u_int32_t). We *could* override the warning by + * casting, but I prefer to leave it as a reminder in case something + * went wrong at some point. */ owl_hton_timestamp(&request.capture_time) ; /* Active mode */ @@ -1240,6 +1260,9 @@ void extract_packet_numbers(const u_char *pkt_data, * header of 'pkt_data'. * Returns true if the antenna signal radiotap field was found, false * otherwhise. + * + * Ideas of improvement: + * http://www.unixgarden.com/index.php/gnu-linux-magazine-hs/introduction-a-la-programmation-wifi-en-c-sous-netbsd#8-exemple-n°5-radiotap */ bool extract_radiotap_ss(const u_char *pkt_data, owl_captured_request *request) @@ -1383,6 +1406,7 @@ void display_captured_request(owl_captured_request *request, */ void get_mac_addr(const char *const iface, uint8_t mac_bytes[ETHER_ADDR_LEN]) +#ifdef linux { struct ifreq ifr; int sockfd ; @@ -1399,6 +1423,7 @@ void get_mac_addr(const char *const iface, strncpy(ifr.ifr_name, iface, IFNAMSIZ) ; + // Note: the SIOCGIFHWADDR ioctl is Linux-specific if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl(SIOCGIFHWADDR) error getting MAC address") ; @@ -1407,7 +1432,63 @@ void get_mac_addr(const char *const iface, memcpy(mac_bytes, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN) ; } +#else // linux +{ + #define HWADDR_MIB_SIZE 6 + int mib[HWADDR_MIB_SIZE] ; + int ifindex ; // iface's index + char *buf = NULL ; + size_t buflen = 0 ; + // Empty mac_bytes: + memset(mac_bytes, 0, sizeof(uint8_t) * ETHER_ADDR_LEN) ; + + ifindex = if_nametoindex(iface) ; + if (ifindex == 0) + { + perror("Cannot get interface's index to get its MAC address") ; + return ; + } + + // See sysctl(7) for more information + mib[0] = CTL_NET ; // First level = the net subtree + mib[1] = PF_ROUTE ; // Second level = route + mib[2] = 0 ; // Third level = protocol (always 0) + mib[3] = AF_LINK ; // Fourth level = address family + mib[4] = NET_RT_IFLIST ; // Fifth level = type of info + mib[5] = ifindex ; /* sysctl(7) says there is no sixth level with + * NET_RT_IFLIST, but actually it has to be the + * interface's index */ + + // Get the size of the available data + if (sysctl(mib, HWADDR_MIB_SIZE, NULL, &buflen, NULL, 0)) + { + perror("sysctl() error getting MAC address") ; + return ; + } + + buf = malloc(buflen) ; + if (! buf) + { + perror("Cannot allocate memory") ; + return ; + } + + if (sysctl(mib, HWADDR_MIB_SIZE, buf, &buflen, NULL, 0)) + perror("sysctl() error getting MAC address") ; + else + { + struct if_msghdr *ifm = (struct if_msghdr*)buf ; + struct sockaddr_dl *sdl = (struct sockaddr_dl*)(ifm + 1) ; + unsigned char *hwaddr = (unsigned char*)(LLADDR(sdl)) ; + int i ; + for (i = 0 ; i < 6 ; ++i) + mac_bytes[i] = (uint8_t)hwaddr[i] ; + } + + free(buf) ; +} +#endif // linux /*