functions.c

Go to the documentation of this file.
00001 /* Linux Prism II Stumbler - Utility Scan for 802_11 networks under Linux
00002  * 
00003  * File : functions.c
00004  * Project : WifiScanner (c) 2002 Hervé Schauer Consultants
00005  * Usage : This utility is written for use with IEEE 802.11 adapters based
00006  * on Intersil's PRISM II chipset (PCMCIA).
00007  * 
00008  * Base code was from prismstumbler Jan Fernquist <Jan.B.Fernquist@telia.com>
00009  * and wlanctl from www.linux-wlan.com
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  * 
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  * 
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00024  *
00025  * $Id: functions.c 177 2007-08-01 00:22:23Z poggij $
00026  */
00027 #include <include.h>
00028 #include <src/functions.h>
00029 #include <src/analyse.h>
00030 #include <src/crc-32.h>
00031 #include <src/crt_io.h>
00032 #include <src/conversion.h>
00033 #include <getopt.h>
00034 #ifdef WITH_SYSLOG
00035 #include <syslog.h>
00036 #endif
00037 #ifdef HAVE_STDINT_H
00038 #include <stdint.h>
00039 #endif
00040 #include "linux_ieee80211_radiotap.h"
00041 #include "extract.h"
00042 #include "cpack.h"
00043 
00044 static const char svnid[] = "@(#) $Header:$";
00045 
00046 /*
00047  * This two functions come from scanner.c
00048  */
00049 void HelpAndBye(void);
00050 void Bye(int ExitCode);
00051 
00052 /*
00053  * Some internal forward refs
00054  */
00055 int analyseBeacon(UINT8 * packet, int len);
00056 int analyseProbeReq(UINT8 * packet, int len);
00057 int analyseProbeRep(UINT8 * packet, int len);
00058 int analyseCTS(UINT8 * packet);
00059 int analyseRTS(UINT8 * packet);
00060 int analyseACK(UINT8 * packet);
00061 int analysePSPOLL(UINT8 * packet);
00062 int analyseData(UINT8 * packet, int len);
00063 int analyseMGMT(UINT8 * packet);        
00064 
00065 void ProcessTagBits(UINT8 * packet, int len, int FrameType);
00066 UINT8 dataIsCrypted(UINT8 * DataFrame, int len);
00067 
00068 void HexMacToASCII(char DestMac[WLAN_STR_ADDR_LEN],
00069                    UINT8 a1[WLAN_ADDR_LEN]);
00070 
00071 void IwFloat2Freq(double in_val, struct iw_freq *out_freq);
00072 
00073 /*
00074  * Use globals, ugly but efficient
00075  */
00076 extern struct sockaddr_nl nl_sk_addr;
00077 extern ScanResult_t Res;
00078 extern Statistics_t Stats;
00079 extern WINDOW *Title_WND, *Panel_WND, *Sum_WND, *RealTime_WND;
00080 
00081 //extern p80211_caphdr_t wlan_header;
00082 
00083 /************************************/
00084 
00085 /*
00086  * Same as safe_strncpy and snprintf, but always be sure the result is terminated.
00087  */
00088 
00089 char *safe_strncpy(char *dst, const char *src, int size)
00090 {
00091   dst[size - 1] = '\0';
00092   return strncpy(dst, src, size - 1);
00093 }
00094 
00095 int safe_snprintf(char *s, int size, char *fmt, ...)
00096 {
00097   va_list ap;
00098   int ret;
00099 
00100   va_start(ap, fmt);
00101   ret = vsnprintf(s, size, fmt, ap);
00102   s[size - 1] = '\0';
00103   va_end(ap);
00104 
00105   return ret;
00106 }
00107 
00108 /*
00109  * Function to copy some data to buf, but no more data ...
00110  */
00111 void *memcpy_buff(void *dest, const void *src, size_t n)
00112 {
00113   if (n > MAX_BUFFER_SIZE) {
00114     debug(1, "ERROR : Packet is TOOO BIG size=%d\n", n);
00115     //DumpHexPaquets(RealTime_WND, dest, (MAX_BUFFER_SIZE + 0x10));
00116     return NULL;
00117   } else {
00118     return memcpy(dest, src, n);
00119   }
00120 
00121 }
00122 
00123 void HexMacToASCII(char DestMac[WLAN_STR_ADDR_LEN],
00124                    UINT8 a1[WLAN_ADDR_LEN])
00125 {
00126   sprintf(DestMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00127           a1[0], a1[1], a1[2], a1[3], a1[4], a1[5]);
00128 }
00129 
00130 /*
00131  * Function to check if the interface is existant
00132  */
00133 int InterfaceIsExistant(char *devname)
00134 {
00135   if (IfconfigSetFlags(devname, 0) == NO_ERROR)
00136     return TRUE;                // Existant
00137   else
00138     return FALSE;               // Not Existant
00139 }
00140 
00141 /*
00142  * Function to change interface flags UP, DOWN, PROMISC ...
00143  * IFF_UP, IFF_PROMISC, ... cf /usr/include/linux/if.h
00144  */
00145 int IfconfigSetFlags(char *devname, short flags)
00146 {
00147   struct ifreq ifr;
00148   int skfd;
00149 
00150   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00151     debug(3, "SetIFFlags: Failed to create AF_INET "
00152           "DGRAM socket. %d:%s", errno, strerror(errno));
00153     return ERROR_CANT_CREATE_SOCKET;
00154   }
00155   // Fetch interface flags
00156   memset(&ifr, 0, sizeof ifr);
00157   strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name) - 1);
00158   ifr.ifr_flags = flags;
00159 
00160   // do the IOCTL call
00161   if (ioctl(skfd, SIOCSIFFLAGS, &ifr) < 0) {
00162     debug(3, "SetIFFlags: Unknown interface %s: %s", devname,
00163           strerror(errno));
00164     close(skfd);
00165     return ERROR_UNKNOWN_INTERFACE;
00166   }
00167   close(skfd);
00168   return NO_ERROR;
00169 }
00170 
00171 
00172 /*
00173  * Convert a channel number in a frequency data
00174  */
00175 void IwFloat2Freq(double in_val, struct iw_freq *out_freq)
00176 {
00177   if (in_val <= 165) {
00178     out_freq->m = (uint32_t) in_val;
00179     out_freq->e = 0;
00180   } else {
00181     out_freq->e = (short) (floor(log10(in_val)));
00182     if (out_freq->e > 8) {
00183       out_freq->m =
00184           ((long) (floor(in_val / pow(10, out_freq->e - 6)))) * 100;
00185       out_freq->e -= 8;
00186     } else {
00187       out_freq->m = (uint32_t) in_val;
00188       out_freq->e = 0;
00189     }
00190   }
00191 }
00192 
00193 /*
00194  * Function to define the channel of a wireless interface (like iwconfig)
00195  */
00196 int IwconfigSetChannel(char *devname, int channel)
00197 {
00198   struct iwreq wrq;
00199   int skfd;
00200 
00201   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00202     warning("Failed to create AF_INET DGRAM socket %d:%s", errno,
00203             strerror(errno));
00204     return ERROR_CANT_CREATE_SOCKET;
00205   }
00206   // Set a channel
00207   memset(&wrq, 0, sizeof(struct iwreq));
00208 
00209   strncpy(wrq.ifr_name, devname, IFNAMSIZ);
00210   wrq.u.freq.flags = IW_FREQ_FIXED;
00211   IwFloat2Freq(channel, &wrq.u.freq);
00212 
00213   // Try twice with a tiny delay, some cards (madwifi) need a second chance...
00214   if (ioctl(skfd, SIOCSIWFREQ, &wrq) < 0) {
00215     usleep(5000);
00216     if (ioctl(skfd, SIOCSIWFREQ, &wrq) < 0) {
00217       debug(3, "Failed to set channel %d %d:%s\n", channel,
00218             errno, strerror(errno));
00219       close(skfd);
00220       return ERROR_CANT_SET_CHANNEL;
00221     }
00222   }
00223 
00224   close(skfd);
00225   return NO_ERROR;
00226 }
00227 
00228 /*
00229  * Set mode of a wireless interface
00230  */
00231 int IwconfigSetMode(char *devname, __u32 mode)
00232 {
00233   // cf wireless.h
00234   struct iwreq wrq;
00235   int skfd;
00236 
00237   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00238     warning("Failed to create AF_INET DGRAM socket %d:%s\n", errno,
00239             strerror(errno));
00240     return ERROR_CANT_CREATE_SOCKET;
00241   }
00242 
00243   memset(&wrq, 0, sizeof(struct iwreq));
00244   strncpy(wrq.ifr_name, devname, IFNAMSIZ);
00245   wrq.u.mode = mode;
00246 
00247   if (ioctl(skfd, SIOCSIWMODE, &wrq) < 0) {
00248     warning("mode set ioctl failed %d:%s\n", errno, strerror(errno));
00249     close(skfd);
00250     return ERROR_CANT_SET_MODE;
00251   }
00252 
00253   close(skfd);
00254   return NO_ERROR;
00255 }
00256 
00257 /*
00258  * Clear the SSID
00259  */
00260 int IwconfigClearSSID(char *devname)
00261 {
00262   struct iwreq wrq;
00263   int skfd;
00264   char essid[1];
00265 
00266   essid[0] = '\0';
00267 
00268   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00269     warning("Failed to create AF_INET DGRAM socket %d:%s", errno,
00270             strerror(errno));
00271     return ERROR_CANT_CREATE_SOCKET;
00272   }
00273   // Zero the ssid
00274   strncpy(wrq.ifr_name, devname, IFNAMSIZ);
00275   wrq.u.essid.pointer = (caddr_t) essid;
00276   wrq.u.essid.length = 1;
00277   wrq.u.essid.flags = 1;
00278 
00279   if (ioctl(skfd, SIOCSIWESSID, &wrq) < 0) {
00280     warning("Failed to set SSID %d:%s", errno, strerror(errno));
00281     close(skfd);
00282     return ERROR_CANT_SET_SSID;
00283   }
00284 
00285   close(skfd);
00286   return 0;
00287 
00288 }
00289 
00290 /*
00291  * Do an private IOCTL
00292  * Code stolen from Kismet, that was stolen from wireless_tools ;-)
00293  */
00294 int Iwconfig_Set_IntPriv(const char *devname, const char *privcmd,
00295                          int val1, int val2)
00296 {
00297   struct iwreq wrq;
00298   int skfd;
00299   struct iw_priv_args priv[IW_MAX_PRIV_DEF];
00300   u_char buffer[4096];
00301   int subcmd = 0;
00302   int offset = 0;
00303 
00304   memset(priv, 0, sizeof(priv));
00305 
00306   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00307     return ERROR_CANT_CREATE_SOCKET;
00308   }
00309 
00310   memset(&wrq, 0, sizeof(struct iwreq));
00311   strncpy(wrq.ifr_name, devname, IFNAMSIZ);
00312 
00313   wrq.u.data.pointer = (caddr_t) priv;
00314   wrq.u.data.length = IW_MAX_PRIV_DEF;
00315   wrq.u.data.flags = 0;
00316 
00317   if (ioctl(skfd, SIOCGIWPRIV, &wrq) < 0) {
00318     close(skfd);
00319     return IWPRIV_FAILED_TO_RETREIVE_IOCTL_LIST;
00320   }
00321 
00322   int pn = -1;
00323   while ((++pn < wrq.u.data.length) && strcmp(priv[pn].name, privcmd));
00324 
00325   if (pn == wrq.u.data.length) {
00326     close(skfd);
00327     return IWPRIV_FAILED_TO_FIND_IOCTL;
00328   }
00329   // Find subcmds, as if this isn't ugly enough already
00330   if (priv[pn].cmd < SIOCDEVPRIVATE) {
00331     int j = -1;
00332 
00333     while ((++j < wrq.u.data.length) &&
00334            ((priv[j].name[0] != '\0') ||
00335             (priv[j].set_args != priv[pn].set_args) ||
00336             (priv[j].get_args != priv[pn].get_args)
00337            ));
00338 
00339     if (j == wrq.u.data.length) {
00340       close(skfd);
00341       return IWPRIV_FAILED_TO_FIND_SUBIOCTL;
00342     }
00343 
00344     subcmd = priv[pn].cmd;
00345     offset = sizeof(__u32);
00346     pn = j;
00347   }
00348   // Make sure its an iwpriv we can set
00349   if ((priv[pn].set_args & IW_PRIV_TYPE_MASK) == 0 ||
00350       (priv[pn].set_args & IW_PRIV_SIZE_MASK) == 0) {
00351     close(skfd);
00352     return IWPRIV_FAILED_TO_SET_VALUE;
00353   }
00354 
00355   if ((priv[pn].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) {
00356     close(skfd);
00357     return IWPRIV_DOES_NOT_ACCEPT_INTEGER;
00358   }
00359   // Find out how many arguments it takes and die if we can't handle it
00360   int nargs = (priv[pn].set_args & IW_PRIV_SIZE_MASK);
00361   if (nargs > 2) {
00362     close(skfd);
00363     return IWPRIV_NEED_MORE_THAN_2_ARG;
00364   }
00365   // Build the set request
00366   memset(&wrq, 0, sizeof(struct iwreq));
00367   strncpy(wrq.ifr_name, devname, IFNAMSIZ);
00368 
00369   // Assign the arguments
00370   wrq.u.data.length = nargs;
00371   ((__s32 *) buffer)[0] = (__s32) val1;
00372   if (nargs > 1) {
00373     ((__s32 *) buffer)[1] = (__s32) val2;
00374   }
00375   // This is terrible!
00376   // This is also simplified from what iwpriv.c does, because we don't
00377   // need to worry about get-no-set ioctls
00378   if ((priv[pn].set_args & IW_PRIV_SIZE_FIXED) &&
00379       ((sizeof(__u32) * nargs) + offset <= IFNAMSIZ)) {
00380     if (offset)
00381       wrq.u.mode = subcmd;
00382     memcpy(wrq.u.name + offset, buffer, IFNAMSIZ - offset);
00383   } else {
00384     wrq.u.data.pointer = (caddr_t) buffer;
00385     wrq.u.data.flags = 0;
00386   }
00387 
00388   // Actually do it.
00389   if (ioctl(skfd, priv[pn].cmd, &wrq) < 0) {
00390     close(skfd);
00391     return IWPRIV_FAILED_TO_SET_IOCTL;
00392   }
00393 
00394   close(skfd);
00395   return NO_ERROR;
00396 }
00397 
00398 
00399 
00400 
00401 
00402 /*
00403  * Function to detect if a packet is encrypted
00404  * How to detect a crypted packet ?
00405  * Take a look at airsnort ;-)
00406  */
00407 UINT8 dataIsCrypted(UINT8 * DataFrame, int len)
00408 {
00409   UINT8 ret = 0;
00410   UINT8 fc_wep = 0;
00411   FixedField_t *FixedField;
00412 
00413   p80211_hdr_t *d80211b_Header;
00414   //(UINT8 *) d80211b_Header = DataFrame;
00415   d80211b_Header = (p80211_hdr_t *) DataFrame;
00416 
00417   UINT8 IndexData = 24;
00418   //(char *) FixedField = DataFrame + sizeof(p80211_hdr_a3_t);
00419   FixedField = (FixedField_t *) DataFrame + sizeof(p80211_hdr_a3_t);
00420 
00421   // if it's a 4 MAC
00422   // ---------------
00423   if (WLAN_GET_FC_TODS(d80211b_Header->a3.fc)
00424       && WLAN_GET_FC_FROMDS(d80211b_Header->a3.fc)) {
00425     IndexData = 30;
00426   }
00427 
00428   fc_wep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00429 
00430   //                    SNAP                       NetBIOS
00431   //if ((DataFrame[IndexData] == 0xAA) || (DataFrame[IndexData] == 0xF0))
00432   //if (DataFrame[IndexData] == 0xAA)
00433   if ((fc_wep == 0) &&
00434       ((DataFrame[IndexData] == 0xAA) &&
00435        (DataFrame[IndexData + 1] == 0xAA))) {
00436     ret = 0;
00437   } else {
00438     ret = 1;
00439     Stats.CryptedPackets++;
00440 
00441     if (IS_BIT_SET(DataFrame[IndexData + 3], 5)) {
00442       debug(3, "Extended IV detected\n");
00443       ret += 2;
00444       // This is some WPA data, because bit 2 if is set it's an extended IV
00445     } else {
00446       // This is an old WEP data packet
00447       // is there some crypted data in packet ?
00448       if (len > (IndexData + 4)) {
00449         // TODO : Check if it was x86/ppc compatible code
00450         // Save IV and key number
00451         // IV:IV:IV:
00452         Res.IV[0] = DataFrame[IndexData + 0];
00453         Res.IV[1] = DataFrame[IndexData + 1];
00454         Res.IV[2] = DataFrame[IndexData + 2];
00455         Res.IV[3] = DataFrame[IndexData + 3];
00456         Stats.IV[0] = DataFrame[IndexData + 0];
00457         Stats.IV[1] = DataFrame[IndexData + 1];
00458         Stats.IV[2] = DataFrame[IndexData + 2];
00459         Stats.IV[3] = DataFrame[IndexData + 3];
00460 
00461         // Check if it's a Weak IV
00462         // For more Information take a look at :
00463         // http://www.dachb0den.com/projects/bsd-airtools/wepexp.txt
00464         // Code is Ok for x86/ppc
00465         if ((Res.IV[1] == 255 && Res.IV[0] > 2 && Res.IV[0] < 16)
00466             || ((Res.IV[0] + Res.IV[1]) == 1
00467                 && (Res.IV[2] <= 0x0A || Res.IV[2] == 0xFF))
00468             || ((Res.IV[0] + Res.IV[1]) <= 0x0C
00469                 && (Res.IV[2] >= 0xF2 && Res.IV[2] <= 0xFE
00470                     && Res.IV[2] != 0xFD)))
00471           Stats.WeakIV++;
00472 
00473       }
00474     }
00475   }
00476   return ret;
00477 }
00478 
00479 // Update Res.OtherInformation
00480 void UpdateOtherInformation(char *Buff)
00481 {
00482   char Buff2[MAXSIZE_OTHERINFORMATION + 1];
00483 
00484   safe_strncpy(Buff2, Res.OtherInformation, MAXSIZE_OTHERINFORMATION);
00485   if ((strlen(Buff) + strlen(Buff2)) > (MAXSIZE_OTHERINFORMATION - 3))
00486     snprintf(Res.OtherInformation, MAXSIZE_OTHERINFORMATION,
00487              "%s - %s", Buff2, Buff);
00488   else
00489     sprintf(Res.OtherInformation, "%s - %s", Buff2, Buff);
00490 
00491   debug(2, "--- Processing UpdateOtherInformation : %s ---\n", Buff);
00492 
00493 }
00494 
00495 /*
00496  * Get the different data from the MGMT header. Fill global struct
00497  */
00498 int processPacket(p80211_caphdr_t * wlan_header, UINT8 * packet, int len)
00499 {
00500   int ReturnCode = 0;
00501   UINT32 CRC;
00502 
00503   p80211_hdr_t *d80211b_Header;
00504 
00505   d80211b_Header = (p80211_hdr_t *) packet;
00506   Res.TypeSubtype = d80211b_Header->a3.fc;
00507 
00508   Res.Signal = wlan_header->ssi_signal;
00509   Res.Noise = wlan_header->ssi_noise;
00510   Res.Rate = wlan_header->datarate;
00511 
00512   switch (WLAN_GET_FC_FTYPE(d80211b_Header->a3.fc)) {
00513     /* Frame subtypes */
00514   case WLAN_FTYPE_MGMT:
00515     debug(1, "Process Management Frame\n");
00516     /* Management */
00517     switch (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc)) {
00518     case WLAN_FSTYPE_ASSOCREQ: // To be analyse
00519     case WLAN_FSTYPE_ASSOCRESP:
00520     case WLAN_FSTYPE_REASSOCREQ:
00521     case WLAN_FSTYPE_REASSOCRESP:
00522       ReturnCode = analyseMGMT(packet);
00523       break;
00524     case WLAN_FSTYPE_PROBEREQ:
00525       ReturnCode = analyseProbeReq(packet, len);
00526       break;
00527     case WLAN_FSTYPE_PROBERESP:
00528       ReturnCode = analyseProbeRep(packet, len);
00529       break;
00530     case WLAN_FSTYPE_BEACON:
00531       ReturnCode = analyseBeacon(packet, len);
00532       Stats.Beacon++;
00533       break;
00534     case WLAN_FSTYPE_ATIM:
00535     case WLAN_FSTYPE_DISASSOC:
00536     case WLAN_FSTYPE_AUTHEN:
00537       ReturnCode = analyseMGMT(packet);
00538       break;
00539     case WLAN_FSTYPE_DEAUTHEN:
00540       // TODO : Clear BSSID of the Deauthenticated Client
00541       ReturnCode = analyseMGMT(packet);
00542       break;
00543     case WLAN_FSTYPE_ACTION:
00544       warning("Whaooou a packet what I search ! : MANAGEMENT/ACTION\n");
00545       break;
00546     }
00547     break;
00548   case WLAN_FTYPE_CTL:
00549     debug(1, "Process Control Frame\n");
00550     switch (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc)) {
00551       /* Control */
00552     case WLAN_FSTYPE_BLOCK_ACK_REQ:
00553       warning
00554           ("Whaooou a packet what I search ! : CONTROL/BLOCK_ACK_REQ\n");
00555       break;
00556     case WLAN_FSTYPE_BLOCK_ACK:
00557       warning("Whaooou a packet what I search ! : CONTROL/BLOCK_ACK\n");
00558       break;
00559     case WLAN_FSTYPE_PSPOLL:
00560       ReturnCode = analysePSPOLL(packet);
00561       break;
00562     case WLAN_FSTYPE_RTS:
00563       ReturnCode = analyseRTS(packet);
00564       break;
00565     case WLAN_FSTYPE_CTS:
00566       ReturnCode = analyseCTS(packet);
00567       break;
00568     case WLAN_FSTYPE_ACK:
00569       ReturnCode = analyseACK(packet);
00570       break;
00571     case WLAN_FSTYPE_CFEND:
00572       break;
00573     case WLAN_FSTYPE_CFENDCFACK:
00574       break;
00575     }
00576     break;
00577   case WLAN_FTYPE_DATA:
00578     debug(1, "Process Data Frame\n");
00579     //CLEAR_TYPE_BIT_AP (Res.TypeOfClient);
00580     SET_TYPE_BIT_DATA(Res.TypeOfClient);
00581     switch (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc) & (WLAN_FSTYPE_QOS_UNMASK)) {
00582       /* Data */
00583     case WLAN_FSTYPE_DATAONLY:
00584     case WLAN_FSTYPE_DATA_CFACK:
00585     case WLAN_FSTYPE_DATA_CFPOLL:
00586     case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
00587     case WLAN_FSTYPE_NULL:
00588       ReturnCode = analyseData(packet, len);
00589       break;
00590     case WLAN_FSTYPE_CFACK:
00591       break;
00592     case WLAN_FSTYPE_CFPOLL:
00593       break;
00594     case WLAN_FSTYPE_CFACK_CFPOLL:
00595       break;
00596     }
00597     break;
00598   }
00599 
00600   memcpy(&CRC, packet + len - 4, 4);
00601 
00602 /*
00603 // Check if the packet is a good packet
00604 #ifndef LWNG_15
00605   if ((CRC == 0xFFFFFFFF)
00606       || ((unsigned) len < sizeof (p80211msg_lnxind_wlansniffrm_t))) {
00607 #else
00608   if ((unsigned) len < sizeof(p80211msg_lnxind_wlansniffrm_t)) {
00609 #endif
00610     if (DebugLevel >= 1) {
00611       debug(0, "INVALID PACKET : BAD CRC (%08X) or too short (%04X)\n",
00612             CRC, len);
00613       if ((unsigned) len > sizeof(p80211msg_lnxind_wlansniffrm_t)) {
00614         CRC =
00615             doFCS(&packet[sizeof(p80211msg_lnxind_wlansniffrm_t)],
00616                   (len - 4 - sizeof(p80211msg_lnxind_wlansniffrm_t)));
00617         debug(1, "Calculed CRC is : %08X\n", CRC);
00618       }
00619     }
00620     safe_strncpy(Res.TypeOfPacket, "INVLID", WLAN_SIZEOF_TYPEOFPACKET);
00621     Stats.INVLD++;
00622     ReturnCode = 0;
00623   } else {
00624 */
00625 
00626   // Copy type of packet (in text)
00627   safe_strncpy(Res.TypeOfPacket,
00628                TypeOfPacketToString(d80211b_Header->a3.fc),
00629                WLAN_SIZEOF_TYPEOFPACKET);
00630   //}
00631 
00632   debug(1, "FrameType=%04X (type:%X subtype:%X)\n",
00633         d80211b_Header->a3.fc,
00634         WLAN_GET_FC_FTYPE(d80211b_Header->a3.fc),
00635         WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc));
00636 
00637   return ReturnCode;
00638 }
00639 
00640 /* ***
00641  * Functions of Analyse
00642  */
00643 
00644 int analyseBeacon(UINT8 * packet, int len)
00645 {
00646   p80211_hdr_t *d80211b_Header;
00647   FixedField_t *FixedField;
00648 
00649   d80211b_Header = (p80211_hdr_t *) packet;
00650   FixedField = (UINT8 *) packet + sizeof(p80211_hdr_a3_t);
00651 
00652 #if 0
00653   debug(0, "FixedField = %0x\n", FixedField);
00654   DumpHexPaquets(RealTime_WND, packet, 0x20);
00655   DumpHexPaquets(RealTime_WND, FixedField, 0x10);
00656 #endif
00657 
00658   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
00659   HexMacToASCII(Res.SrcMac, d80211b_Header->a3.a2);
00660   HexMacToASCII(Res.BssId, d80211b_Header->a3.a3);
00661 
00662   //Res.isAp = WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info);
00663   Res.hasWep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00664   // TODO : detect if WPA is used and change the 0 by 1 or 0
00665   // it will do in the analyse of the tagged parameters
00666   Res.hasWPA = 0;
00667 
00668   /* Log */
00669   LogDetectedClient(d80211b_Header->a3.a2);
00670   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00671   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00672   // Here we know if it's an AP or an Ah-Hoc client
00673   SET_TYPE_BIT_BEACON(Res.TypeOfClient);
00674   debug(3, "IBSS = %0x - ESS = %0x\n",
00675         WLAN_GET_MGMT_CAP_INFO_IBSS(FixedField->cap_info),
00676         WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info));
00677   if (WLAN_GET_MGMT_CAP_INFO_IBSS(FixedField->cap_info)) {
00678     SET_TYPE_BIT_P2P(Res.TypeOfClient);
00679     CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00680     LogPutIsP2P(d80211b_Header->a3.a2, Res.hasWep, FixedField->bcn_int);
00681   } else {
00682     CLEAR_TYPE_BIT_P2P(Res.TypeOfClient);
00683     if (WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info)) {
00684       SET_TYPE_BIT_AP(Res.TypeOfClient);
00685       LogPutIsAP(d80211b_Header->a3.a2, Res.hasWep, Res.hasWPA,
00686                  FixedField->bcn_int);
00687     } else {
00688       CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00689     }
00690   }
00691   LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00692   LogPutTimestamp(d80211b_Header->a3.a2, FixedField->ts);
00693   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00694 
00695   debug(1,
00696         "Dst:%s Src:%s Bssid:%s\n" "Fragment number : 0x%04X\n"
00697         "Sequence number : 0x%02X\n" "Timestamp : 0x%016llX\n"
00698         "Beacon Interval : 0x%X\n" "Capabilities : 0x%X\n"
00699         "S/N : %ld/%ld\n", Res.DestMac, Res.SrcMac, Res.BssId,
00700         WLAN_GET_SEQ_FRGNUM(d80211b_Header->a3.seq),
00701         WLAN_GET_SEQ_SEQNUM(d80211b_Header->a3.seq), FixedField->ts,
00702         FixedField->bcn_int, FixedField->cap_info, Res.Signal, Res.Noise);
00703 
00704   if ((unsigned int) len <= (sizeof(p80211_hdr_t) + sizeof(FixedField_t)))
00705     return FALSE;
00706 
00707   ProcessTagBits(packet, len, WLAN_FSTYPE_BEACON);
00708 
00709   return TRUE;
00710 }
00711 
00712 /*************************/
00713 
00714 int analyseProbeReq(UINT8 * packet, int len)
00715 {
00716   p80211_hdr_t *d80211b_Header;
00717   FixedField_t *FixedField;
00718 
00719   //(UINT8 *) d80211b_Header = packet;
00720   //(char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00721   FixedField = (UINT8 *) packet + sizeof(p80211_hdr_a3_t);
00722   d80211b_Header = (p80211_hdr_t *) packet;
00723 
00724   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
00725   HexMacToASCII(Res.SrcMac, d80211b_Header->a3.a2);
00726   HexMacToASCII(Res.BssId, d80211b_Header->a3.a3);
00727 
00728   debug(1,
00729         "Dst:%s Src:%s Bssid:%s\n" "Fragment number : 0x%04X\n"
00730         "Sequence number : 0x%02X\n" "S/N : %ld/%ld\n", Res.DestMac,
00731         Res.SrcMac, Res.BssId,
00732         WLAN_GET_SEQ_FRGNUM(d80211b_Header->a3.seq),
00733         WLAN_GET_SEQ_SEQNUM(d80211b_Header->a3.seq), Res.Signal,
00734         Res.Noise);
00735 
00736   /* Log */
00737   LogDetectedClient(d80211b_Header->a3.a2);
00738   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00739   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00740   //LogPutIsAP (d80211b_Header->a3.a2, Res.hasWep, Res.hasWPA, FixedField->bcn_int);
00741   LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00742   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00743 
00744   Res.hasWep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00745   // TODO : detect if WPA is used and change the 0 by 1 or 0
00746   // it will done in the analyse of the tagged parameters
00747   Res.hasWPA = 0;
00748 
00749   ProcessTagBits(packet, len, WLAN_FSTYPE_PROBEREQ);
00750 
00751   //Res.isAp = WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info);
00752 
00753   return TRUE;                  /* All is OK */
00754 }
00755 
00756 /*************************/
00757 
00758 int analyseProbeRep(UINT8 * packet, int len)
00759 {
00760   p80211_hdr_t *d80211b_Header;
00761   FixedField_t *FixedField;
00762 
00763   //(UINT8 *) d80211b_Header = packet;
00764   //(char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00765   d80211b_Header = (p80211_hdr_t *) packet;
00766   FixedField = (UINT8 *) packet + sizeof(p80211_hdr_a3_t);
00767 
00768   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
00769   HexMacToASCII(Res.SrcMac, d80211b_Header->a3.a2);
00770   HexMacToASCII(Res.BssId, d80211b_Header->a3.a3);
00771 
00772   debug(1,
00773         "Dst:%s Src:%s Bssid:%s\n" "Fragment number : 0x%04X\n"
00774         "Sequence number : 0x%02X\n" "Timestamp : 0x%016llX\n"
00775         "Capabilities : 0x%X\n" "S/N : %ld/%ld\n", Res.DestMac,
00776         Res.SrcMac, Res.BssId,
00777         WLAN_GET_SEQ_FRGNUM(d80211b_Header->a3.seq),
00778         WLAN_GET_SEQ_SEQNUM(d80211b_Header->a3.seq), FixedField->ts,
00779         FixedField->cap_info, Res.Signal, Res.Noise);
00780 
00781   /* Log */
00782   LogDetectedClient(d80211b_Header->a3.a1);
00783   /* STA */
00784   LogDetectedClient(d80211b_Header->a3.a2);     /* AP */
00785 
00786   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00787   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00788   LogPutIsAP(d80211b_Header->a3.a2,
00789              WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info), 0,
00790              FixedField->bcn_int);
00791   LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00792   LogPutTimestamp(d80211b_Header->a3.a2, FixedField->ts);
00793   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00794 
00795   //Res.isAp = WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info);
00796   Res.hasWep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00797   // TODO : detect if WPA is used and change the 0 by 1 or 0
00798   Res.hasWPA = 0;
00799   // it will do in the analyse of the tagged parameters
00800 
00801   if (WLAN_GET_MGMT_CAP_INFO_IBSS(FixedField->cap_info)) {
00802     SET_TYPE_BIT_P2P(Res.TypeOfClient);
00803     CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00804     LogPutIsP2P(d80211b_Header->a3.a2, Res.hasWep, 0);
00805   } else {
00806     CLEAR_TYPE_BIT_P2P(Res.TypeOfClient);
00807     if (WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info)) {
00808       SET_TYPE_BIT_AP(Res.TypeOfClient);
00809       LogPutIsAP(d80211b_Header->a3.a2, Res.hasWep, Res.hasWPA, 0);
00810     } else {
00811       CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00812     }
00813   }
00814   ProcessTagBits(packet, len, WLAN_FSTYPE_PROBERESP);
00815 
00816   return TRUE;                  /* All is OK */
00817 }
00818 
00819 
00820 /**********/
00821 
00822 int analyseRTS(UINT8 * packet)
00823 {
00824   p80211_hdr_t *d80211b_Header;
00825 
00826   //(UINT8 *) d80211b_Header = packet;
00827   d80211b_Header = (p80211_hdr_t *) packet;
00828 
00829   debug(1, "FC=%X", d80211b_Header->a3.fc);
00830 
00831   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
00832   HexMacToASCII(Res.SrcMac, d80211b_Header->a3.a2);
00833   safe_strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00834   /* Log */
00835   LogDetectedClient(d80211b_Header->a3.a1);     /* STA */
00836   LogDetectedClient(d80211b_Header->a3.a2);     /* AP */
00837   LogPutSN(d80211b_Header->a3.a3, Res.Signal);
00838   LogPutRate(d80211b_Header->a3.a3, Res.Rate);
00839 
00840   return TRUE;                  /* All is OK */
00841 }
00842 
00843 int analyseCTS(UINT8 * packet)
00844 {
00845   p80211_hdr_t *d80211b_Header;
00846 
00847   //(UINT8 *) d80211b_Header = packet;
00848   d80211b_Header = (p80211_hdr_t *) packet;
00849 
00850   debug(1, "FC=%X", d80211b_Header->a3.fc);
00851 
00852   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
00853   safe_strncpy(Res.SrcMac, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00854   safe_strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00855   /* Log */
00856   LogDetectedClient(d80211b_Header->a3.a1);     /* STA */
00857 
00858   return TRUE;                  /* All is OK */
00859 }
00860 
00861 /*
00862  * Function to analyse an Acknoledge frame
00863  */ int analyseACK(
00864                     UINT8 * packet)
00865 {
00866   p80211_hdr_t *d80211b_Header;
00867 
00868   //(UINT8 *) d80211b_Header = packet;
00869   d80211b_Header = (p80211_hdr_t *) packet;
00870 
00871   debug(1, "FC=%X", d80211b_Header->a3.fc);
00872 
00873   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
00874   safe_strncpy(Res.SrcMac, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00875   safe_strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00876   /* Log */
00877   LogDetectedClient(d80211b_Header->a3.a1);     /* STA or AP */
00878 
00879   return TRUE;                  /* All is OK */
00880 }
00881 
00882 int analysePSPOLL(UINT8 * packet)
00883 {
00884   p80211_hdr_t *d80211b_Header;
00885 
00886   //(UINT8 *) d80211b_Header = packet;
00887   d80211b_Header = (p80211_hdr_t *) packet;
00888 
00889   debug(1, "FC=%X", d80211b_Header->a3.fc);
00890 
00891   HexMacToASCII(Res.SrcMac, d80211b_Header->a3.a1);
00892   safe_strncpy(Res.DestMac, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00893   HexMacToASCII(Res.BssId, d80211b_Header->a3.a2);
00894   /* Log */
00895   LogDetectedClient(d80211b_Header->a3.a1);     /* STA */
00896   LogPutSN(d80211b_Header->a3.a1, Res.Signal);
00897   LogPutRate(d80211b_Header->a3.a1, Res.Rate);
00898   LogPutSeqNum(d80211b_Header->a3.a1, Res.DestMac, d80211b_Header->a3.seq);
00899 
00900   return TRUE;                  /* All is OK */
00901 }
00902 
00903 /*
00904  * Function to analyse and parse a Data Frame
00905  */ int analyseData(
00906                      UINT8 * packet, int len)
00907 {
00908   p80211_hdr_t *d80211b_Header;
00909   char strAddresse1[WLAN_STR_ADDR_LEN];
00910   char strAddresse2[WLAN_STR_ADDR_LEN];
00911   char strAddresse3[WLAN_STR_ADDR_LEN];
00912   FixedField_t *FixedField;
00913 
00914   //(UINT8 *) d80211b_Header = packet;
00915   //(char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00916   d80211b_Header = (p80211_hdr_t *) packet;
00917 
00918   FixedField = (FixedField_t *) packet + sizeof(p80211_hdr_a3_t);
00919 
00920   if ((WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc) & WLAN_FSTYPE_QOS_MASK) != 0) {
00921     // skip the 2 bytes of QOS
00922     FixedField = FixedField + 2;
00923   }
00924 
00925   HexMacToASCII(strAddresse1, d80211b_Header->a3.a1);
00926   HexMacToASCII(strAddresse2, d80211b_Header->a3.a2);
00927   HexMacToASCII(strAddresse3, d80211b_Header->a3.a3);
00928 
00929   debug(1, "FC=%X", d80211b_Header->a3.fc);
00930   debug(1, "Packet Size=%d\n", 0);
00931 
00932   if (WLAN_GET_FC_TODS(d80211b_Header->a3.fc)) {
00933     if (WLAN_GET_FC_FROMDS(d80211b_Header->a3.fc)) {
00934       // Data From AP by AP to STA
00935       debug(2, " AP to AP");
00936 
00937       SET_TYPE_BIT_TODS(Res.TypeOfClient);
00938       SET_TYPE_BIT_FROMDS(Res.TypeOfClient);
00939 
00940       LogDetectedClient(d80211b_Header->a3.a1);
00941       LogDetectedClient(d80211b_Header->a3.a2);
00942       LogDetectedClient(d80211b_Header->a3.a3);
00943 
00944       safe_strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00945       safe_strncpy(Res.DestMac, strAddresse3, WLAN_STR_ADDR_LEN);
00946       safe_strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00947       /* Log */
00948       LogPutSN(d80211b_Header->a3.a1, Res.Signal);
00949       LogPutRate(d80211b_Header->a3.a1, Res.Rate);
00950       LogPutIsAP(d80211b_Header->a3.a2,
00951                  WLAN_GET_MGMT_CAP_INFO_PRIVACY
00952                  (FixedField->cap_info), Res.hasWPA, FixedField->bcn_int);
00953       //Res.isAp = 1;
00954       SET_TYPE_BIT_AP(Res.TypeOfClient);
00955     } else {
00956       // Data from DS to STA
00957       debug(1, " TODS");
00958       SET_TYPE_BIT_TODS(Res.TypeOfClient);
00959 
00960       safe_strncpy(Res.BssId, strAddresse1, WLAN_STR_ADDR_LEN);
00961       safe_strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00962       safe_strncpy(Res.DestMac, strAddresse3, WLAN_STR_ADDR_LEN);
00963       /* Log */
00964       LogDetectedClient(d80211b_Header->a3.a2);
00965       LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00966       LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00967       //LogPutIsAP (d80211b_Header->a3.a2, Res.hasWep, Res.hasWPA, FixedField->bcn_int);
00968       LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a1);
00969       //LogPutDS (d80211b_Header->a3.a3);
00970     }
00971   } else if (WLAN_GET_FC_FROMDS(d80211b_Header->a3.fc)) {
00972     // Data to DS to STA
00973     debug(1, " FROMDS");
00974 
00975     SET_TYPE_BIT_FROMDS(Res.TypeOfClient);
00976 
00977     safe_strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00978     safe_strncpy(Res.BssId, strAddresse2, WLAN_STR_ADDR_LEN);
00979     safe_strncpy(Res.SrcMac, strAddresse3, WLAN_STR_ADDR_LEN);
00980     /* Log */
00981     LogDetectedClient(d80211b_Header->a3.a3);
00982     LogPutSN(d80211b_Header->a3.a3, Res.Signal);
00983     LogPutRate(d80211b_Header->a3.a3, Res.Rate);
00984     LogPutBSSID(d80211b_Header->a3.a3, d80211b_Header->a3.a2);
00985     LogPutDS(d80211b_Header->a3.a3);
00986   } else {
00987     // Data from STA to STA
00988     debug(1, " STA to STA");
00989 
00990     safe_strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00991     safe_strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00992     safe_strncpy(Res.BssId, strAddresse3, WLAN_STR_ADDR_LEN);
00993     /* Log */
00994     LogDetectedClient(d80211b_Header->a3.a1);
00995     LogDetectedClient(d80211b_Header->a3.a2);
00996     LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00997     LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00998     LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00999   }
01000 
01001   debug(1, "\n");
01002 
01003   // If it's a NULL Function Packet : 
01004   //    do not fill IV and do not try to detect if it crypted
01005   if (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc) != WLAN_FSTYPE_NULL) {
01006     register UINT8 res;
01007     res = dataIsCrypted(packet, len);
01008     Res.hasWep = IS_BIT_SET(res, 0);
01009     Res.hasWPA = IS_BIT_SET(res, 1);
01010   }
01011   // TODO : put LastIV in Struct ClientInfo
01012 
01013   return TRUE;                  /* All is OK */
01014 }
01015 
01016 int analyseMGMT(UINT8 * packet)
01017 {
01018   p80211_hdr_t *d80211b_Header;
01019 
01020   //(UINT8 *) d80211b_Header = packet;
01021   d80211b_Header = (p80211_hdr_t *) packet;
01022 
01023   HexMacToASCII(Res.DestMac, d80211b_Header->a3.a1);
01024   HexMacToASCII(Res.SrcMac, d80211b_Header->a3.a2);
01025   HexMacToASCII(Res.BssId, d80211b_Header->a3.a3);
01026 
01027   debug(1, "FC=%X", d80211b_Header->a3.fc);
01028 
01029   /* Log */
01030   LogDetectedClient(d80211b_Header->a3.a1);
01031   LogDetectedClient(d80211b_Header->a3.a2);
01032   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
01033   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
01034   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
01035 
01036   return TRUE;                  /* All is OK */
01037 }
01038 
01039 // Function to filter not printable caractere in some SSID
01040 UINT8 FilterESSID(char *ESSID)
01041 {
01042   UINT8 i;
01043   UINT8 modified = FALSE;
01044 
01045   for (i = 0; i < strlen(ESSID); i++) {
01046     //if (!isprint (ESSID[i]))
01047     if (ESSID[i] < ' ') {
01048       ESSID[i] = '?';
01049       modified++;
01050     }
01051   }
01052   return modified;
01053 }
01054 
01055 void ProcessTagBits(UINT8 * packet, int len, int FrameType)
01056 {
01057   static UINT8 NbTagSSID = 0;
01058   UINT8 *varBits;
01059   p80211_hdr_t *d80211b_Header;
01060   int tagType, tagLen;
01061   char Buff[0x101];             // BAD !!!
01062   UINT8 MaxSpeed, i;
01063   UINT8 NbCarCTRL = 0;          // Number of Control char is SSID 
01064 
01065   /* Get only that we want */
01066   //(UINT8 *) d80211b_Header = packet;
01067   //(UINT8 *) varBits = packet + sizeof(p80211_hdr_a3_t);
01068   d80211b_Header = (p80211_hdr_t *) packet;
01069   varBits = packet + sizeof(p80211_hdr_a3_t);
01070 
01071   /* Do a correction on the size of the Fixed Field and fill MacAdd */
01072   switch (FrameType) {
01073   case WLAN_FSTYPE_ASSOCREQ:
01074     break;
01075   case WLAN_FSTYPE_ASSOCRESP:
01076     break;
01077   case WLAN_FSTYPE_REASSOCREQ:
01078     break;
01079   case WLAN_FSTYPE_REASSOCRESP:
01080     break;
01081   case WLAN_FSTYPE_PROBEREQ:
01082     /* Size of FixedField = 0 */
01083     break;
01084   case WLAN_FSTYPE_PROBERESP:
01085     /* Size of FixedField = 0x0C */
01086     varBits += sizeof(FixedField_t);
01087     break;
01088   case WLAN_FSTYPE_BEACON:
01089     /* Size of FixedField = 0x0C */
01090     varBits += sizeof(FixedField_t);
01091     break;
01092   case WLAN_FSTYPE_ATIM:
01093     break;
01094   }
01095   NbTagSSID = 0;
01096 
01097   /* Get the tagged values 
01098    * There is a type and a length field
01099    * Followed by tha actual data 
01100    */
01101 
01102   tagType = 0;
01103   debug(1, "TagType(len) = ");
01104 
01105   /* -4 is the CRC, I don't want CRC :-)) */
01106   while ((varBits < (packet + len - 4)) && (tagType != 0xFF)) {
01107 
01108     tagType = varBits[0];
01109     tagLen = varBits[1];
01110     varBits += 2;
01111     debug(1, "%02d(%02d),", tagType, tagLen);
01112     switch (tagType) {
01113 
01114     case WLAN_EID_SSID:        /* 0 */
01115       //safe_strncpy (Res.SSID, varBits, tagLen);
01116       //safe_strncpy (Res.SSID, varBits, (tagLen <= 32) ? taglen : 32);
01117       memcpy(Res.SSID, varBits, (tagLen <= 32) ? tagLen : 32);
01118 
01119       //warning ("0> SSID = '%s'\n", Res.SSID);
01120       FilterESSID(Res.SSID);
01121       // Catch wellenreiter probes
01122       if (!strncmp(Res.SSID, "this_is_used_for_wellenreiter", 32)) {
01123         warning
01124             ("\nWARNING : Somebody use wellenreiter to probe SomeBody!\n");
01125       }
01126       // Catch Windows XP probes
01127       // Check some two or three think to find if it's a WinXP
01128       if (tagLen == 32) {
01129         for (i = 0; i < tagLen; i++) {
01130           if (varBits[i] < 32)
01131             NbCarCTRL++;
01132         }
01133         if (NbCarCTRL >= 4) {
01134           //warning ("WARNING : Windows XP is HERE !\n");
01135           safe_strncpy(Res.SSID, "<I'm a Buggy WinXP>", WLAN_SSID_MAXLEN);
01136         }
01137       }
01138       if ((tagLen == 0)
01139           && (FrameType == WLAN_FSTYPE_BEACON)) {
01140         safe_strncpy(Res.SSID, "<Hidden SSID>", WLAN_SSID_MAXLEN);
01141       }
01142       if ((tagLen != 0) && (varBits[0] == 0)
01143           && (varBits[1] == 0)
01144           && (varBits[2] == 0)) {
01145         // CISCO has this Bug : Send a Blank SSID but the length is not zeroized
01146         safe_strncpy(Res.SSID, "<Hidden SSID of known length>",
01147                      WLAN_SSID_MAXLEN);
01148       }
01149       LogPutSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3, Res.SSID);
01150       NbTagSSID++;
01151       break;
01152 
01153     case 50:                   /* 50 - Extended Supported Rates */
01154     case WLAN_EID_SUPP_RATES:  /*  1 - Supported Rates */
01155       MaxSpeed = (*varBits) & 0x7F;
01156       for (i = 0; i < tagLen; i++) {
01157         if (MaxSpeed < (*(varBits + i) & 0x7F))
01158           MaxSpeed = *(varBits + i) & 0x7F;
01159       }
01160       LogPutMaxSpeed(d80211b_Header->a3.a2, (UINT8) MaxSpeed);
01161       break;
01162 
01163     case WLAN_EID_FH_PARMS:    /* 2 */
01164       break;
01165 
01166     case WLAN_EID_DS_PARMS:    /* 3 */
01167       if (tagLen == 1) {
01168         Res.Channel = *varBits;
01169         LogPutChannel(d80211b_Header->a3.a2,
01170                       d80211b_Header->a3.a3, Res.Channel);
01171       }
01172       break;
01173 
01174     case WLAN_EID_CF_PARMS:    /* 4 */
01175       SET_TYPE_BIT_AP(Res.TypeOfClient);
01176       break;
01177 
01178     case WLAN_EID_TIM:         /* 5 */
01179       // The TIM information is only present within beacon frames generated by APs
01180       SET_TYPE_BIT_AP(Res.TypeOfClient);
01181       break;
01182 
01183     case WLAN_EID_IBSS_PARMS:  /* 6 */
01184       CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
01185       SET_TYPE_BIT_P2P(Res.TypeOfClient);
01186       break;
01187 
01188     case WLAN_EID_CHALLENGE:   /* 16 */
01189       break;
01190       // Specific Vedor TAG
01191 
01192     case 7:                    /* Country Information */
01193       // Exemple : "FR ..." 0x46,0x52,0x20,0x0B,0x03,0x1E
01194       //            Country code en ASCII : FR
01195       //       Start channel      : 11
01196       //        Channels          :  3
01197       //         Max TX power     : 30 mW
01198       break;
01199 
01200     case 42:                   /* ERP Informations */
01201       break;
01202 
01203     case 133:                  /* CISCO */
01204       // It's an AP HOSTNAME, Thx for the information :-)
01205       safe_strncpy(Buff, (varBits + 0x0A), 0x10);
01206       UpdateOtherInformation(Buff);
01207       LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
01208       break;
01209 
01210     case 171:                  /* Undocumented TAG - ARUBA */
01211       break;
01212 
01213     case 221:                  /* WPA or WME */
01214       safe_strncpy(Buff, "WPA or WME Capable", 12);
01215       UpdateOtherInformation(Buff);
01216       LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
01217       AnalyseTAG221(d80211b_Header->a3.a3, varBits, tagLen);    // Analyse if for a BSSID
01218       break;
01219 
01220     case 0xFF:
01221       // End of Tag list
01222       break;
01223       // Other unknowned TAG
01224     default:
01225       snprintf(Buff, 32, "An unknow tag is detected : %02X", tagType);
01226       UpdateOtherInformation(Buff);
01227       LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
01228       debug(1,
01229             "\nWARNING -- This TagType is unknowed =%02X\n"
01230             "Please send one of this packet to the author\n", tagType);
01231       break;
01232     }
01233     varBits += tagLen;
01234   }
01235 
01236   debug(1, "\nRes.TypeOfClient=%x\n", Res.TypeOfClient);
01237 
01238   if (NbTagSSID > 1) {
01239     // It seem to be a Windows XP STA :-)
01240     debug(1, "Tag 0 (SSID) is send more than one time (%d)\n", NbTagSSID);
01241     snprintf(Buff, 85,
01242              "Tag 0 (SSID) is send more than one time (%.2d) - "
01243              "This STA is probably under Windows XP", NbTagSSID);
01244     UpdateOtherInformation(Buff);
01245     LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
01246   }
01247 }
01248 
01249 /* 
01250  * This function parse commandline and fill option ... 
01251  */
01252 void ParseCommandLine(int argc, char **argv, ConfigStruct * config)
01253 {
01254   int c, n;
01255   char *CommaPosition = NULL;
01256 
01257   int option_index = 0;
01258   static struct option long_options[] = {
01259     {"version", 0, 0, 'v'},
01260     {"help", 0, 0, 'h'},
01261     {"verbose", 1, 0, 'V'},
01262     {"output-file", 1, 0, 'F'},
01263     {"hop", 1, 0, 'H'},
01264     {"channel", 1, 0, 'S'},
01265     {"device-file", 1, 0, 'D'},
01266     {"computer-date", 0, 0, 'd'},
01267     {"iface", 1, 0, 'i'},
01268     {"pcapsrc", 1, 0, 'r'},
01269     {"ids", 0, 0, 'I'},
01270     {"max-packets", 1, 0, 'M'},
01271     {"hide-packets", 1, 0, 'N'},
01272     {"hop-delay", 1, 0, 't'},
01273     {"disable-check", 0, 0, 'c'},
01274     {"card-driver", 0, 0, 'C'},
01275 #ifdef WITH_WIRETAP
01276     {"pcap-file", 1, 0, 'W'},
01277 #endif
01278 #ifdef WITH_SYSLOG
01279     {"send-to-syslog", 0, 0, 's'},
01280 #endif
01281     {0, 0, 0, 0}
01282   };
01283 
01284 
01285   while ((c =
01286           getopt_long(argc, argv,
01287                       "vF:S:W:D:i:r:t:V:h?H:dM:N:IG:w:k:C:cs",
01288                       long_options, &option_index)) != EOF) {
01289 
01290     switch (c) {
01291       // Set channel
01292     case 'S':
01293       config->SingleChannel = atoi(optarg);
01294       if (config->SingleChannel < CHANNEL_MIN ||
01295           config->SingleChannel > CHANNEL_MAX) {
01296         fprintf(stderr,
01297                 "Error : Channel must be between %d and %d\n",
01298                 CHANNEL_MIN, CHANNEL_MAX);
01299         Bye(ERROR_CHANNEL_OUT_OF_BOUND);
01300       }
01301       break;
01302 
01303 #ifdef WITH_SYSLOG
01304       // Send Alert to Syslog
01305     case 's':
01306       config->SendAlert2Syslog = TRUE;
01307       openlog("wifiscanner", LOG_ODELAY || LOG_PID, LOG_USER);
01308       break;
01309 #endif
01310 
01311       // Output file for real time information
01312     case 'F':
01313       if (strncmp("auto", optarg, 5)) {
01314         config->OutFileName = optarg;
01315       } else {
01316 
01317       }
01318       break;
01319 
01320       // PCAP output
01321 #ifdef WITH_WIRETAP
01322     case 'W':                  // PCAP output file
01323       config->OutDumpFileName = optarg;
01324       break;
01325 #endif
01326 
01327       // .DOT output
01328     case 'D':
01329       config->OutDotFileName = optarg;
01330       break;
01331 
01332     case 'r':
01333       config->InPcapFileName = optarg;
01334       break;
01335 
01336       // Version
01337     case 'v':
01338       Bye(NO_ERROR);
01339       break;
01340 
01341       // Number of Hop for channel rotation
01342     case 'H':
01343       config->ChannelHop = atoi(optarg);
01344       if (config->ChannelHop < HOP_MIN || config->ChannelHop > HOP_MAX) {
01345         fprintf(stderr,
01346                 "Error : Hop must be between %d and %d\n",
01347                 HOP_MIN, HOP_MAX);
01348         Bye(ERROR_HOP_OUT_OF_BOUND);
01349       }
01350       break;
01351 
01352       // Verbosity level
01353     case 'V':
01354       config->DebugLevel = atoi(optarg);
01355       if (config->DebugLevel < 1 || config->DebugLevel > MAX_DEBUG_LEVEL)
01356         config->DebugLevel = MAX_DEBUG_LEVEL;
01357       n = 0;                    // Display all packets
01358       break;
01359 
01360       // Time to sleep before change channel
01361     case 't':
01362       config->TimeToSleepBeforeChangeChannel = atoi(optarg);
01363       if (config->TimeToSleepBeforeChangeChannel < 1
01364           || config->TimeToSleepBeforeChangeChannel > 10000)
01365         config->TimeToSleepBeforeChangeChannel = 10000; /* Ten seconds is enougth */
01366       break;
01367 
01368       // Choice of interface
01369     case 'i':
01370       // The interface can be "eth0" or "eth1,wifi0"
01371       // So we search the comma
01372       if (strlen(optarg) > (DEVNAME_LEN * 2 + 1)) {
01373         // Hmmm What did the user want ...
01374         fprintf(stderr,
01375                 "I think that the length of the interface is a little bit too long\n"
01376                 " Wake up ! And don't sleep on your keyboard !   :)\n");
01377         Bye(ERROR_DONT_TRY_TO_SLEEP_ON_THE_KEYBOARD);
01378       }
01379       memset(config->devname, 0, DEVNAME_LEN);
01380       memset(config->devname2, 0, DEVNAME_LEN);
01381       CommaPosition = strchr(optarg, ',');
01382       if (CommaPosition == NULL) {
01383         // Only one interface
01384         safe_strncpy(config->devname, optarg, DEVNAME_LEN);
01385         config->devname[DEVNAME_LEN - 1] = '\0';
01386         debug(3, "Only one interface is given : %s\n", config->devname);
01387       } else {
01388         UINT16 SizeOne, SizeTwo;
01389         SizeOne = CommaPosition - optarg;
01390         SizeTwo = strlen(optarg) - SizeOne;
01391         safe_strncpy(config->devname, optarg, SizeOne + 1);
01392         safe_strncpy(config->devname2, (CommaPosition + 1), SizeTwo);
01393         debug(3, "Two interface is given : (%s)[%d]-(%s)[%d]\n",
01394               config->devname, SizeOne, config->devname2, SizeTwo);
01395       }
01396       if (InterfaceIsExistant(config->devname) == FALSE) {
01397         fprintf(stderr, "Arg, the interface %s is not existant\n",
01398                 config->devname);
01399         Bye(ERROR_UNKNOWN_INTERFACE);
01400       }
01401       break;
01402 
01403       // Human readable date
01404     case 'd':
01405       config->DateFormat = 0;
01406       break;
01407 
01408       // Max packets to capture before leave
01409     case 'M':
01410       // Check if outbound
01411       if (atol(optarg) < 0)
01412         config->MaxPacket = atol(optarg);
01413       break;
01414 
01415       // IDS 
01416     case 'I':
01417       config->IDS_is_ON = TRUE;
01418       //*OutIDSFileName = optarg;
01419       break;
01420 
01421       // Hide some packets (only on display)
01422     case 'N':
01423       n = 0;
01424       fprintf(stdout, "Do not display: ");
01425       // do while until end of option or 16 sub-option ...
01426       while ((optarg[n] != 0) && (n < 16)) {
01427         switch (optarg[n]) {
01428         case 'A':
01429         case 'a':
01430           SET_BIT(config->DoNotDisplay, DISPLAY_ACK_BIT);
01431           fprintf(stdout, "ACK ");
01432           break;
01433         case 'B':
01434         case 'b':
01435           SET_BIT(config->DoNotDisplay, DISPLAY_BEACON_BIT);
01436           fprintf(stdout, "BEACON ");
01437           break;
01438         case 'C':
01439         case 'c':
01440           SET_BIT(config->DoNotDisplay, DISPLAY_CONTROL_BIT);
01441           fprintf(stdout, "CONTROL ");
01442           break;
01443         case 'D':
01444         case 'd':
01445           SET_BIT(config->DoNotDisplay, DISPLAY_DATA_BIT);
01446           fprintf(stdout, "DATA ");
01447           break;
01448         case 'P':
01449         case 'p':
01450           SET_BIT(config->DoNotDisplay, DISPLAY_PROBE_BIT);
01451           fprintf(stdout, "PROBE ");
01452           break;
01453         case 'S':
01454         case 's':
01455           SET_BIT(config->DoNotDisplay, DISPLAY_STATION_BIT);
01456           fprintf(stdout, "STATION ");
01457           break;
01458         default:
01459           break;
01460         }
01461         n++;
01462       }
01463       fprintf(stdout, "\n");
01464       if (config->DebugLevel > 1) {
01465         fprintf(stdout,
01466                 "Verbose level is more than 1 so all packets are display\n");
01467       }
01468       break;
01469 
01470       // G option
01471     case 'G':                  // ???
01472       break;
01473 
01474       // Save weak packets
01475     case 'w':
01476       break;
01477 
01478       // Save KeyStream of Authen with IV
01479     case 'k':
01480       break;
01481 
01482       // Card driver
01483     case 'C':                  // Choice of CARD
01484       if ((!strcmp(optarg, "prism"))
01485           || (!strcmp(optarg, "hostap"))
01486           || (!strcmp(optarg, "cisco"))
01487           || (!strcmp(optarg, "cisco_wifi"))
01488           || (!strcmp(optarg, "orinoco"))
01489           || (!strcmp(optarg, "prism54g"))
01490           || (!strcmp(optarg, "airjack"))
01491           || (!strcmp(optarg, "ipw2100"))
01492           || (!strcmp(optarg, "ipw2200"))
01493           || (!strcmp(optarg, "madwifi-ng"))
01494 /*          || (!strcmp(optarg, "pcap")) */
01495           || (!strcmp(optarg, "atheros"))) {
01496         if (!strcmp(optarg, "cisco_wifi")) {
01497           config->TypeOfCard = CISCO_CVS_CARD;
01498           fprintf(stderr,
01499                   "\n##############\n"
01500                   " WARNING - I'm absolutly not sure that this driver work correctly (ALPHA VERSION)\n"
01501                   "##############\n\n");
01502           sleep(5);
01503         }
01504         if (!strcmp(optarg, "cisco")) {
01505           config->TypeOfCard = CISCO_CARD;
01506         }
01507         if (!strcmp(optarg, "prism")) {
01508           config->TypeOfCard = WLAN_NG_CARD;
01509         }
01510         if (!strcmp(optarg, "prism54g")) {
01511           config->TypeOfCard = PRISM54G_CARD;
01512         }
01513         if (!strcmp(optarg, "hostap")) {
01514           config->TypeOfCard = HOSTAP_CARD;
01515         }
01516         if (!strcmp(optarg, "atheros")) {
01517           config->TypeOfCard = ATHEROS_CARD;
01518         }
01519         if (!strcmp(optarg, "madwifi-ng")) {
01520           config->TypeOfCard = MADWIFI_NG_CARD;
01521         }
01522         if (!strcmp(optarg, "orinoco")) {
01523           config->TypeOfCard = LUCENT_CARD;
01524         }
01525         if (!strcmp(optarg, "ipw2100")) {
01526           config->TypeOfCard = IPW_CARD;
01527         }
01528         if (!strcmp(optarg, "ipw2200")) {
01529           config->TypeOfCard = IPW_CARD;
01530         }
01531         if (!strcmp(optarg, "pcap")) {
01532           // XXX : NOT NOW SUPPORTED 
01533           config->TypeOfCard = PCAP_VIRTUAL_CARD;
01534         }
01535         if (!strcmp(optarg, "airjack")) {
01536           config->TypeOfCard = AIRJACK_CARD;
01537         }
01538       } else {
01539         fprintf(stderr,
01540                 "Only 'prism', 'cisco' 'cisco_wifi (eth+wifi)' 'orinoco' 'atheros', 'prism54g',\n"
01541                 " 'airjack', 'ipw2200', 'ipw2100', 'hostap', 'madwifi-ng' or 'pcap' card is allowed.\n");
01542         Bye(ERROR_UNKNOWN_INTERFACE_TYPE);
01543       }
01544       debug(2, "Driver used is : %s\n", optarg);
01545       break;
01546       // Disable curses checks
01547     case 'c':
01548       config->CheckScreenSize = FALSE;
01549       break;
01550 
01551       // Help 
01552     case '?':                  // Help
01553     case 'h':                  // Help too
01554       HelpAndBye();
01555       break;
01556 
01557       // Default
01558     default:
01559       HelpAndBye();
01560       break;
01561     }
01562   }
01563 
01564   // Post analyse of parameters
01565   if ((config->TypeOfCard == CISCO_CVS_CARD)
01566       && (!strcmp(config->devname2, ""))) {
01567     fprintf(stderr,
01568             "You must give me two interface, when card driver is cisco_wifi"
01569             "like -i eth1,wifi0\n");
01570     Bye(ERROR_BAD_PARAMETER);
01571   }
01572   if ((config->TypeOfCard == PCAP_VIRTUAL_CARD)
01573       && (!strcmp(config->InPcapFileName, ""))) {
01574     fprintf(stderr,
01575             "You must give me a PCAP source file, when card driver is PCAP\n");
01576     Bye(ERROR_MISSING_PCAP_FILE);
01577   }
01578 
01579 }
01580 
01581 
01582 
01583 /*
01584  * Summerize configuration
01585  */
01586 
01587 void DispConf(ConfigStruct * config)
01588 {
01589 
01590   if (config->TypeOfCard == CISCO_CVS_CARD) {
01591     fprintf(stdout, "Interfaces used: %s and %s \n", config->devname,
01592             config->devname2);
01593     if (InterfaceIsExistant(config->devname2) == FALSE) {
01594       fprintf(stderr, "Arg, the interface %s is not existant\n",
01595               config->devname2);
01596       Bye(ERROR_UNKNOWN_INTERFACE);
01597     }
01598   } else {
01599     fprintf(stdout, "Interface used: %s\n", config->devname);
01600   }
01601   if (InterfaceIsExistant(config->devname) == FALSE) {
01602     fprintf(stderr, "Arg, the interface %s is not existant\n",
01603             config->devname);
01604     Bye(ERROR_UNKNOWN_INTERFACE);
01605   }
01606 
01607   fprintf(stdout, "Debug Level: %d", config->DebugLevel);
01608   if (config->DebugLevel == MAX_DEBUG_LEVEL)
01609     fprintf(stdout, " (Crazy level)");
01610   // Out Files
01611   fprintf(stdout, "\nOutput filename: %s",
01612           (config->OutFileName == NULL) ? "<none>" : config->OutFileName);
01613   fprintf(stdout, "\nPCap dump file: %s",
01614           (config->OutDumpFileName ==
01615            NULL) ? "<none>" : config->OutDumpFileName);
01616   fprintf(stdout, "\nDot output filename: %s",
01617           (config->OutDotFileName ==
01618            NULL) ? "<none>" : config->OutDotFileName);
01619 
01620   fprintf(stdout, "\nChannel scan : %d", config->SingleChannel);
01621   if (config->SingleChannel == 0)
01622     fprintf(stdout, " (All channels)");
01623   fprintf(stdout, "\nSleep between channel hop: %d",
01624           config->TimeToSleepBeforeChangeChannel);
01625 
01626   fprintf(stdout, "\nMax packets before quit: %d",
01627           (int) config->MaxPacket);
01628   if (!config->MaxPacket)
01629     fprintf(stdout, " (Don't quit)");
01630   fprintf(stdout, "\nDate format: %s",
01631           (config->DateFormat) ? "Timestamp" : "Human readable");
01632   fprintf(stdout, "\nCurses Screen size detection: %s",
01633           (config->CheckScreenSize) ? "Enabled" : "Disabled");
01634   fprintf(stdout, "\nIDS active: %s",
01635           (config->IDS_is_ON) ? "Enabled" : "Disabled");
01636   fprintf(stdout, "\nSend IDS alert to Syslog: %s\n",
01637           (config->SendAlert2Syslog) ? "Enabled" : "Disabled");
01638 
01639 // Add channels per second scan info.
01640 }
01641 
01642 
01643 
01647 void ChannelToStr(char *strChannel, UINT8 Channel, UINT8 SChannel)
01648 {
01649   if (Channel == 0) {
01650     sprintf(strChannel, "%02d(%02d)", Channel, SChannel);
01651   } else {
01652     sprintf(strChannel, "%02d(%+02d)", Channel, Channel - SChannel);
01653   }
01654   debug(1, "S-C=%02d-%02d\n", Channel, SChannel);
01655 }
01656 
01657 /***
01658  * Initialisation of Configuration
01659  ***/
01660 void InitConfiguration(ConfigStruct * config)
01661 {
01662   // Configuration declaration
01663   config->SingleChannel = (UINT8) 0;
01664   //config->TimeToSleepBeforeChangeChannel = TIME_TO_SLEEP_BEFORE_CHANGE_CHANNEL;
01665   config->TimeToSleepBeforeChangeChannel = 200; // in ms
01666   config->DebugLevel = (UINT8) 0;
01667   config->ChannelHop = (UINT8) 5;
01668   config->DateFormat = (UINT8) 1;       // 1 is human readable
01669   strcpy(config->devname, "wlan0");
01670   config->TypeOfCard = WLAN_NG_CARD;
01671   config->CheckScreenSize = TRUE;
01672   config->SendAlert2Syslog = FALSE;
01673   config->JammingNow = FALSE;
01674   config->DoNotDisplay = (UINT8) 0;     // 0000 0000
01675   //                                         || |||\_Ack
01676   //                                         || ||\__Beacon
01677   //                                         || |\___Control
01678   //                                         || \____Data
01679   //                                         |\______Probe
01680   //                                         \_______Station
01681 }
01682 
01683 
01684 /*
01685  * Extract radiotap data from radiotap field
01686  *  code was get from tcpdump
01687  */
01688 /*
01689  * Copyright (c) 2001
01690  *      Fortress Technologies, Inc.  All rights reserved.
01691  *      Charlie Lenahan (clenahan@fortresstech.com)
01692  *
01693  * Redistribution and use in source and binary forms, with or without
01694  * modification, are permitted provided that: (1) source code distributions
01695  * retain the above copyright notice and this paragraph in its entirety, (2)
01696  * distributions including binary code include the above copyright notice and
01697  * this paragraph in its entirety in the documentation or other materials
01698  * provided with the distribution, and (3) all advertising materials mentioning
01699  * features or use of this software display the following acknowledgement:
01700  * ``This product includes software developed by the University of California,
01701  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
01702  * the University nor the names of its contributors may be used to endorse
01703  * or promote products derived from this software without specific prior
01704  * written permission.
01705  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
01706  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
01707  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
01708  */
01709 
01710 int extract_radiotap_field(struct cpack_state *s, u_int32_t bit,
01711                            p80211_caphdr_t * wlan_header)
01712 {
01713   union {
01714     int8_t i8;
01715     u_int8_t u8;
01716     int16_t i16;
01717     u_int16_t u16;
01718     int32_t i32;
01719     u_int32_t u32;
01720     u_int64_t u64;
01721   } u, u2;
01722   int rc;
01723   UINT16 temp;
01724 
01725   switch (bit) {
01726   case IEEE80211_RADIOTAP_FLAGS:
01727   case IEEE80211_RADIOTAP_RATE:
01728   case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
01729   case IEEE80211_RADIOTAP_DB_ANTNOISE:
01730   case IEEE80211_RADIOTAP_ANTENNA:
01731     rc = cpack_uint8(s, &u.u8);
01732     break;
01733   case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
01734   case IEEE80211_RADIOTAP_DBM_ANTNOISE:
01735     rc = cpack_int8(s, &u.i8);
01736     break;
01737   case IEEE80211_RADIOTAP_CHANNEL:
01738     rc = cpack_uint16(s, &u.u16);
01739     if (rc != NO_ERROR)
01740       break;                    // stop analyse if the first 16bits was not OK
01741     rc = cpack_uint16(s, &u2.u16);
01742     break;
01743   case IEEE80211_RADIOTAP_FHSS:
01744   case IEEE80211_RADIOTAP_LOCK_QUALITY:
01745   case IEEE80211_RADIOTAP_TX_ATTENUATION:
01746     rc = cpack_uint16(s, &u.u16);
01747     break;
01748   case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
01749     rc = cpack_uint8(s, &u.u8);
01750     break;
01751   case IEEE80211_RADIOTAP_DBM_TX_POWER:
01752     rc = cpack_int8(s, &u.i8);
01753     break;
01754   case IEEE80211_RADIOTAP_TSFT:
01755     rc = cpack_uint64(s, &u.u64);
01756     break;
01757   default:
01758     /* this bit indicates a field whose
01759      * size we do not know, so we cannot
01760      * proceed.
01761      */
01762     warning("A field in RadioTap data was not know, we skip it\n");
01763     return -1;
01764   }
01765 
01766   // --------------
01767   if (rc != NO_ERROR) {
01768     warning("Extraction of data from RadioTap was not success\n");
01769     return rc;
01770   }
01771   // --------------
01772 
01773   switch (bit) {
01774   case IEEE80211_RADIOTAP_CHANNEL:
01775     if (u2.u16 & IEEE80211_CHAN_2GHZ) {  /* 2GHz band */
01776       if (u.u16 == 2484)
01777         wlan_header->channel = 14;
01778       if (u.u16 < 2484)
01779         wlan_header->channel = (u.u16 - 2407) / 5;
01780       else
01781         wlan_header->channel = 15 + ((u.u16 - 2512) / 20);
01782     } else if (u2.u16 & IEEE80211_CHAN_5GHZ) {   /* 5Ghz band */
01783       wlan_header->channel = (u.u16 - 5000) / 5;
01784     } else {                    /* either, try to guess */
01785       if (u.u16 == 2484)
01786         wlan_header->channel = 14;
01787       if (u.u16 < 2484)
01788         wlan_header->channel = (u.u16 - 2407) / 5;
01789       if (u.u16 < 5000)
01790         wlan_header->channel = 15 + ((u.u16 - 2512) / 20);
01791       wlan_header->channel = (u.u16 - 5000) / 5;
01792     }
01793     debug(1, "IEEE80211_RADIOTAP_CHANNEL : %d (%04d Mhz / %04X )\n", wlan_header->channel, u.u16, u2.u16);
01794     break;
01795   case IEEE80211_RADIOTAP_FHSS:
01796     // Not analyzed
01797     break;
01798   case IEEE80211_RADIOTAP_RATE:
01799     wlan_header->datarate = u.u8;
01800     wlan_header->datarate = wlan_header->datarate * 5;  // my datarate is in units of 100kbps.
01801     debug(3, "IEEE80211_RADIOTAP_RATE : %X\n", wlan_header->datarate);
01802     break;
01803   case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
01804     if (u.i8 != 0) {
01805       wlan_header->ssi_signal = 200 + u.i8;
01806     }
01807     //warning (">> wlan_header->ssi_signal = %d\n", wlan_header->ssi_signal);
01808     debug(3, "IEEE80211_RADIOTAP_DBM_ANTSIGNAL : %d dB signal\n",
01809           wlan_header->ssi_signal);
01810     break;
01811   case IEEE80211_RADIOTAP_DBM_ANTNOISE:
01812     if (u.i8 != 0) {
01813       wlan_header->ssi_noise = 200 + u.i8;
01814     }
01815     debug(3, "IEEE80211_RADIOTAP_DBM_ANTNOISE : %d dB noise\n",
01816           wlan_header->ssi_noise);
01817     break;
01818   case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
01819     // Not analyzed
01820     break;
01821   case IEEE80211_RADIOTAP_DB_ANTNOISE:
01822     // Not analyzed
01823     break;
01824   case IEEE80211_RADIOTAP_LOCK_QUALITY:
01825     // Not analyzed
01826     debug(3, "IEEE80211_RADIOTAP_LOCK_QUALITY : %d sq\n", u.u16);
01827     break;
01828   case IEEE80211_RADIOTAP_TX_ATTENUATION:
01829     // Not analyzed
01830     debug(3, "IEEE80211_RADIOTAP_TX_ATTENUATION : %d tx power\n",
01831           -(int) u.u16);
01832     break;
01833   case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
01834     // Not analyzed
01835     debug(3, "IEEE80211_RADIOTAP_DB_TX_ATTENUATION : %d tx power\n",
01836           -(int) u.u8);
01837     break;
01838   case IEEE80211_RADIOTAP_DBM_TX_POWER:
01839     // Not analyzed
01840     debug(3, "IEEE80211_RADIOTAP_DBM_TX_POWER : %d tx power\n", u.i8);
01841     break;
01842   case IEEE80211_RADIOTAP_FLAGS:
01843     debug(3, "IEEE80211_RADIOTAP_FLAGS: ");
01844     if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
01845       debug(3, "cfp ");
01846     if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
01847       debug(3, "short preamble ");
01848     if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
01849       debug(3, "wep ");
01850     if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
01851       debug(3, "fragmented ");
01852     if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
01853       debug(3, "bad-fcs ");
01854     debug(3, "\n");
01855     break;
01856   case IEEE80211_RADIOTAP_ANTENNA:
01857     wlan_header->antenna = u.u8;
01858     debug(3, "IEEE80211_RADIOTAP_ANTENNA : %d\n", u.u8);
01859     break;
01860   case IEEE80211_RADIOTAP_TSFT:
01861     wlan_header->mactime = u.u64;
01862     debug(3, "IEEE80211_RADIOTAP_TSFT : %llX us tsft \n", u.u64);
01863     break;
01864   default:
01865     warning("A field in RadioTap data was not know, we skip it\n");
01866     break;
01867   }
01868   // warning("wlan_header->ssi_signal = %d\n", wlan_header->ssi_signal);
01869   return NO_ERROR;
01870 }
01871 
01872 
01873 /***
01874  * Fill Radio data in depend of DataLink
01875  * return the real size of the header
01876  ***/
01877 int FillRadioData(p80211_caphdr_t * wlan_header, int DataLink,
01878                   UINT8 * Packet, int len)
01879 {
01880   p80211msg_lnxind_wlansniffrm_t *Sniff_Frame;
01881   p80211_caphdr_t *AVS_data;
01882   struct ieee80211_radiotap_header *radiotap_hdr;
01883 
01884   int real_size_of_headers = 0;
01885 
01886   // init all data to Zero, and after we fill with the good data
01887   wlan_header->version = 0;
01888   wlan_header->length = 0;
01889   wlan_header->mactime = 0;
01890   wlan_header->hosttime = 0;
01891   wlan_header->phytype = 0;
01892   wlan_header->channel = 0;
01893   wlan_header->datarate = 0;
01894   wlan_header->antenna = 0;
01895   wlan_header->priority = 0;
01896   wlan_header->ssi_type = 0;
01897   wlan_header->ssi_signal = 0;
01898   wlan_header->ssi_noise = 0;
01899   wlan_header->preamble = 0;
01900   wlan_header->encoding = 0;
01901 
01902   switch (DataLink) {
01903   case DLT_PRISM_HEADER:
01904     Sniff_Frame = (p80211msg_lnxind_wlansniffrm_t *) Packet;
01905     wlan_header->mactime = Sniff_Frame->mactime.data;
01906     wlan_header->hosttime = Sniff_Frame->hosttime.data;
01907     wlan_header->phytype = phytype_dsss_dot11_b;        // Not used for now
01908     wlan_header->channel = Sniff_Frame->channel.data;
01909     wlan_header->datarate = Sniff_Frame->rate.data * 5; // datarate is in units of 100kbps.
01910     wlan_header->ssi_signal = Sniff_Frame->signal.data;
01911     wlan_header->ssi_noise = Sniff_Frame->noise.data;
01912     real_size_of_headers = sizeof(p80211msg_lnxind_wlansniffrm_t);
01913     break;
01914   case DLT_IEEE802_11_RADIO_AVS:
01915     AVS_data = (p80211_caphdr_t *) Packet;
01916     wlan_header->version = AVS_data->version;
01917     wlan_header->length = AVS_data->length;
01918     wlan_header->mactime = AVS_data->mactime;
01919     wlan_header->hosttime = AVS_data->hosttime;
01920     wlan_header->phytype = AVS_data->phytype;
01921     wlan_header->channel = AVS_data->channel;
01922     wlan_header->datarate = AVS_data->datarate;
01923     wlan_header->antenna = AVS_data->antenna;
01924     wlan_header->priority = AVS_data->priority;
01925     wlan_header->ssi_type = AVS_data->ssi_type;
01926     wlan_header->ssi_signal = AVS_data->ssi_signal;
01927     wlan_header->ssi_noise = AVS_data->ssi_noise;
01928     wlan_header->preamble = AVS_data->preamble;
01929     wlan_header->encoding = AVS_data->encoding;
01930     real_size_of_headers = sizeof(p80211_caphdr_t);
01931     break;
01932   case DLT_IEEE802_11_RADIO:
01933     {
01934 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
01935 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
01936 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
01937 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
01938 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
01939 #define BIT(n)  (1 << n)
01940 #define IS_EXTENDED(__p)        \
01941                   (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
01942       int bit0;
01943       enum ieee80211_radiotap_type bit;
01944       struct cpack_state cpacker;
01945       u_int32_t present, next_present;
01946       u_int32_t *presentp, *last_presentp;
01947       UINT8 exit_loop = FALSE;
01948       const u_char *iter;
01949 
01950       // Exemple : 0000 1000 2E08 0000 0002 9409 A000 C802
01951       radiotap_hdr = (struct ieee80211_radiotap_header *) Packet;
01952       //data_pt = Packet + sizeof(struct ieee80211_radiotap_header);
01953 
01954       real_size_of_headers = radiotap_hdr->it_len;
01955 
01956       debug(3, "radiotap_hdr->it_len = %02X\n", radiotap_hdr->it_len);
01957 
01958 #if 0
01959       DumpHexPaquets(RealTime_WND, Packet, radiotap_hdr->it_len);
01960       DumpHexPaquets(RealTime_WND, Packet + radiotap_hdr->it_len, len);
01961 #endif
01962 
01963       for (last_presentp = &radiotap_hdr->it_present;
01964            IS_EXTENDED(last_presentp)
01965            && (u_char *) (last_presentp + 1) <= Packet + len; last_presentp++);
01966       {
01967       }
01968 
01969       iter = (u_char *) (last_presentp + 1);
01970 
01971       if (cpack_init(&cpacker, (u_int8_t *) iter, len - (iter - Packet)) == 0) {
01972 
01973         if (IS_BIT_SET(radiotap_hdr->it_present, IEEE80211_RADIOTAP_EXT)) {
01974           warning
01975               ("Radiotap use an extended data, please send mail to the developper to notify this problem\n");
01976         } else {
01977           for (bit0 = 0, presentp = &radiotap_hdr->it_present;
01978                presentp <= last_presentp; presentp++, bit0 += 32) {
01979             for (present = EXTRACT_LE_32BITS(presentp); present;
01980                  present = next_present) {
01981               /* clear the least significant bit that is set */
01982               next_present = present & (present - 1);
01983               /* extract the least significant bit that is set */
01984               bit = (enum ieee80211_radiotap_type) (bit0 + BITNO_32(present ^ next_present)); 
01985 
01986               if (extract_radiotap_field(&cpacker, bit, wlan_header) != NO_ERROR) {
01987                 exit_loop = TRUE;
01988                 break;
01989               }
01990             }
01991             if (exit_loop == TRUE)
01992               break;
01993           }
01994         }
01995       }
01996 #undef BITNO_32
01997 #undef BITNO_16
01998 #undef BITNO_8
01999 #undef BITNO_4
02000 #undef BITNO_2
02001 #undef BIT
02002 #undef IS_EXTENDED
02003     }
02004     break;
02005   default:
02006     break;
02007   }
02008   return real_size_of_headers;
02009 }
02010 
02011 int CalculateOffset(int DataLink)
02012 {
02013   int offset = 0;
02014 
02015   switch (DataLink) {
02016   case DLT_PRISM_HEADER:
02017     debug(2, "pcap_datalink(ca.pcap) = %d = DLT_PRISM_HEADER\n", DataLink);
02018     offset = 0x90;
02019     break;
02020   case DLT_IEEE802_11:
02021     debug(2, "pcap_datalink(ca.pcap) = %d = DLT_IEEE802_11\n", DataLink);
02022     offset = 0x00;
02023     break;
02024   case DLT_AIRONET_HEADER:
02025     debug(2, "pcap_datalink(ca.pcap) = %d = DLT_AIRONET_HEADER:\n",
02026           DataLink);
02027     offset = 0x00;
02028     break;
02029   case DLT_LINUX_SLL:          //113
02030     debug(2, "pcap_datalink(ca.pcap) = %d = DLT_LINUX_SLL\n", DataLink);
02031     offset = 0x10;
02032     break;
02033   case DLT_IEEE802_11_RADIO:   //127
02034     debug(2, "pcap_datalink(ca.pcap) = %d = DLT_IEEE802_11_RADIO\n",
02035           DataLink);
02036     offset = 0x10;
02037     // ofset is calculate directly by the extract function
02038     break;
02039   case DLT_IEEE802_11_RADIO_AVS:       //163
02040     debug(2, "pcap_datalink(ca.pcap) = %d = DLT_IEEE802_11_RADIO_AVS\n",
02041           DataLink);
02042     offset = 0x40;
02043     break;
02044   default:                     //COOKED
02045     debug(2, "pcap_datalink(ca.pcap) = %d = Default to COOKED\n",
02046           DataLink);
02047     offset = 0x10;
02048   }
02049   return offset;
02050 }

Generated on Fri Jul 25 17:10:33 2008 for WifiScanner by  doxygen 1.5.5