Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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,v 1.49 2005/02/23 11:36:53 poggij Exp $
00026  */
00027 
00028 #include <include.h>
00029 #include <src/functions.h>
00030 #include <src/analyse.h>
00031 #include <src/crc-32.h>
00032 #include <src/crt_io.h>
00033 #include <src/conversion.h>
00034 #include <getopt.h>
00035 #ifdef WITH_SYSLOG
00036 #include <syslog.h>
00037 #endif
00038 
00039 /*
00040  * This two functions come from scanner.c
00041  */
00042 void HelpAndBye(void);
00043 void Bye(void);
00044 
00045 /*
00046  * Some internal forward refs
00047  */
00048 int analyseBeacon(unsigned char *packet, int len);
00049 int analyseProbeReq(unsigned char *packet, int len);
00050 int analyseProbeRep(unsigned char *packet, int len);
00051 int analyseCTS(unsigned char *packet);
00052 int analyseRTS(unsigned char *packet);
00053 int analyseACK(unsigned char *packet);
00054 int analysePSPOLL(unsigned char *packet);
00055 int analyseData(unsigned char *packet, int len);
00056 int analyseMGMT(unsigned char *packet); 
00057 
00058 void ProcessTagBits(unsigned char *packet, int len, int FrameType);
00059 UINT8 dataIsCrypted(unsigned char *packet, int len);
00060 
00061 /*
00062  * Use globals, ugly but efficient
00063  */
00064 extern struct sockaddr_nl nl_sk_addr;
00065 extern ScanResult_t Res;
00066 extern Statistics_t Stats;
00067 extern WINDOW *Title_WND, *Panel_WND, *Sum_WND, *RealTime_WND;
00068 
00069 extern p80211_caphdr_t wlan_header;
00070 
00071 //extern UINT8 wlan_payload[];
00072 
00073 /************************************/
00074 
00075 /*
00076  * Same as strncpy and snprintf, but always be sure the result is terminated.
00077  */
00078 
00079 char *safe_strncpy(char *dst, const char *src, int size)
00080 {
00081   dst[size - 1] = '\0';
00082   return strncpy(dst, src, size - 1);
00083 }
00084 
00085 int safe_snprintf(char *s, int size, char *fmt, ...)
00086 {
00087   va_list ap;
00088   int ret;
00089 
00090   va_start(ap, fmt);
00091   ret = vsnprintf(s, size, fmt, ap);
00092   s[size - 1] = '\0';
00093   va_end(ap);
00094 
00095   return ret;
00096 }
00097 
00098 /*
00099  * Function to copy some data to buf, but no more data ...
00100  */
00101 void *memcpy_buff(void *dest, const void *src, size_t n)
00102 {
00103   if (n > MAX_BUFFER_SIZE) {
00104     debug(1, "ERROR : Packet is TOOO BIG size=%d\n", n);
00105     //DumpHexPaquets(RealTime_WND, dest, (MAX_BUFFER_SIZE + 0x10));
00106     return NULL;
00107   } else {
00108     return memcpy(dest, src, n);
00109   }
00110 
00111 }
00112 
00113 
00114 /*************************************/
00115 /* How to detect a crypted packet ?  */
00116 /* Take a look at airsnort ;-)       */
00117 UINT8 dataIsCrypted(unsigned char *DataFrame, int len)
00118 {
00119   UINT8 ret = 0;
00120   UINT8 fc_wep = 0;
00121   FixedField_t *FixedField;
00122 
00123   p80211_hdr_t *d80211b_Header;
00124   (char *) d80211b_Header = DataFrame;
00125 
00126   UINT8 IndexData = 24;
00127   (char *) FixedField = DataFrame + sizeof(p80211_hdr_a3_t);
00128 
00129   // if it's a 4 MAC
00130   // ---------------
00131   if (WLAN_GET_FC_TODS(d80211b_Header->a3.fc)
00132       && WLAN_GET_FC_FROMDS(d80211b_Header->a3.fc)) {
00133     IndexData = 30;
00134   }
00135 
00136   fc_wep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00137 
00138   //                    SNAP                       NetBIOS
00139   //if ((DataFrame[IndexData] == 0xAA) || (DataFrame[IndexData] == 0xF0))
00140   //if (DataFrame[IndexData] == 0xAA)
00141   if ((fc_wep == 0)
00142       && ((DataFrame[IndexData] == 0xAA)
00143           && (DataFrame[IndexData + 1] == 0xAA)))
00144     ret = 0;
00145   else {
00146     ret = 1;
00147     Stats.CryptedPackets++;
00148     // is there some crypted data in packet ?
00149     if ((unsigned int) len > (IndexData + 4)) {
00150       // TODO : Check if it was x86/ppc compatible code
00151       // Save IV and key number
00152       // IV:IV:IV:
00153       Res.IV[0] = DataFrame[IndexData + 0];
00154       Res.IV[1] = DataFrame[IndexData + 1];
00155       Res.IV[2] = DataFrame[IndexData + 2];
00156       Res.IV[3] = DataFrame[IndexData + 3];
00157       Stats.IV[0] = DataFrame[IndexData + 0];
00158       Stats.IV[1] = DataFrame[IndexData + 1];
00159       Stats.IV[2] = DataFrame[IndexData + 2];
00160       Stats.IV[3] = DataFrame[IndexData + 3];
00161 
00162       // Check if it's a Weak IV
00163       // For more Information take a look at :
00164       // http://www.dachb0den.com/projects/bsd-airtools/wepexp.txt
00165       // Code is Ok for x86/ppc
00166       if ((Res.IV[1] == 255 && Res.IV[0] > 2 && Res.IV[0] < 16)
00167           || ((Res.IV[0] + Res.IV[1]) == 1
00168               && (Res.IV[2] <= 0x0A || Res.IV[2] == 0xFF))
00169           || ((Res.IV[0] + Res.IV[1]) <= 0x0C
00170               && (Res.IV[2] >= 0xF2 && Res.IV[2] <= 0xFE
00171                   && Res.IV[2] != 0xFD)))
00172         Stats.WeakIV++;
00173 
00174     }
00175   }
00176   return ret;
00177 }
00178 
00179 // Update Res.OtherInformation
00180 void UpdateOtherInformation(char *Buff)
00181 {
00182   char Buff2[MAXSIZE_OTHERINFORMATION + 1];
00183 
00184   strncpy(Buff2, Res.OtherInformation, MAXSIZE_OTHERINFORMATION);
00185   if ((strlen(Buff) + strlen(Buff2)) > (MAXSIZE_OTHERINFORMATION - 3))
00186     snprintf(Res.OtherInformation, MAXSIZE_OTHERINFORMATION,
00187              "%s - %s", Buff2, Buff);
00188   else
00189     sprintf(Res.OtherInformation, "%s - %s", Buff2, Buff);
00190 
00191   debug(2, "--- Processing UpdateOtherInformation : %s ---\n", Buff);
00192 
00193 }
00194 
00195 
00196 // Print MAC Add in a correct Format
00197 void printfMAC(UINT8 AddMac[WLAN_ADDR_LEN])
00198 {
00199   printf("%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", AddMac[0], AddMac[1],
00200          AddMac[2], AddMac[3], AddMac[4], AddMac[5]);
00201 }
00202 
00203 /*
00204  * Get the different data from the MGMT header. Fill global struct
00205  */
00206 int processPacket(unsigned char *packet, int len)
00207 {
00208   int ReturnCode = 0;
00209   UINT32 CRC;
00210 
00211   p80211_hdr_t *d80211b_Header;
00212 
00213   (char *) d80211b_Header = packet;
00214   Res.TypeSubtype = d80211b_Header->a3.fc;
00215 
00216   Res.Signal = wlan_header.ssi_signal;
00217   Res.Noise = wlan_header.ssi_noise;
00218   Res.Rate = wlan_header.datarate;
00219 
00220   switch (WLAN_GET_FC_FTYPE(d80211b_Header->a3.fc)) {
00221     /* Frame subtypes */
00222   case WLAN_FTYPE_MGMT:
00223     debug(1, "Process Management Frame\n");
00224     /* Management */
00225     switch (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc)) {
00226     case WLAN_FSTYPE_ASSOCREQ: // To be analyse
00227       ReturnCode = analyseMGMT(packet);
00228       break;
00229     case WLAN_FSTYPE_ASSOCRESP:
00230       ReturnCode = analyseMGMT(packet);
00231       break;
00232     case WLAN_FSTYPE_REASSOCREQ:
00233       ReturnCode = analyseMGMT(packet); // To be analyse
00234       break;
00235     case WLAN_FSTYPE_REASSOCRESP:
00236       ReturnCode = analyseMGMT(packet);
00237       break;
00238     case WLAN_FSTYPE_PROBEREQ:
00239       ReturnCode = analyseProbeReq(packet, len);
00240       break;
00241     case WLAN_FSTYPE_PROBERESP:
00242       ReturnCode = analyseProbeRep(packet, len);
00243       break;
00244     case WLAN_FSTYPE_BEACON:
00245       ReturnCode = analyseBeacon(packet, len);
00246       Stats.Beacon++;
00247       break;
00248     case WLAN_FSTYPE_ATIM:
00249       ReturnCode = analyseMGMT(packet);
00250       break;
00251     case WLAN_FSTYPE_DISASSOC:
00252       ReturnCode = analyseMGMT(packet);
00253       break;
00254     case WLAN_FSTYPE_AUTHEN:
00255       ReturnCode = analyseMGMT(packet);
00256       break;
00257     case WLAN_FSTYPE_DEAUTHEN:
00258       // TODO : Clear BSSID of the Deauthenticated Client
00259       ReturnCode = analyseMGMT(packet);
00260       break;
00261     }
00262     break;
00263   case WLAN_FTYPE_CTL:
00264     debug(1, "Process Control Frame\n");
00265     switch (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc)) {
00266       /* Control */
00267     case WLAN_FSTYPE_PSPOLL:
00268       ReturnCode = analysePSPOLL(packet);
00269       break;
00270     case WLAN_FSTYPE_RTS:
00271       ReturnCode = analyseRTS(packet);
00272       break;
00273     case WLAN_FSTYPE_CTS:
00274       ReturnCode = analyseCTS(packet);
00275       break;
00276     case WLAN_FSTYPE_ACK:
00277       ReturnCode = analyseACK(packet);
00278       break;
00279     case WLAN_FSTYPE_CFEND:
00280       break;
00281     case WLAN_FSTYPE_CFENDCFACK:
00282       break;
00283     }
00284     break;
00285   case WLAN_FTYPE_DATA:
00286     debug(1, "Process Data Frame\n");
00287     //CLEAR_TYPE_BIT_AP (Res.TypeOfClient);
00288     SET_TYPE_BIT_DATA(Res.TypeOfClient);
00289     switch (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc)) {
00290       /* Data */
00291     case WLAN_FSTYPE_DATAONLY:
00292       ReturnCode = analyseData(packet, len);
00293       break;
00294     case WLAN_FSTYPE_DATA_CFACK:
00295       ReturnCode = analyseData(packet, len);
00296       break;
00297     case WLAN_FSTYPE_DATA_CFPOLL:
00298       ReturnCode = analyseData(packet, len);
00299       break;
00300     case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
00301       ReturnCode = analyseData(packet, len);
00302       break;
00303     case WLAN_FSTYPE_NULL:
00304       ReturnCode = analyseData(packet, len);
00305       break;
00306     case WLAN_FSTYPE_CFACK:
00307       break;
00308     case WLAN_FSTYPE_CFPOLL:
00309       break;
00310     case WLAN_FSTYPE_CFACK_CFPOLL:
00311       break;
00312     }
00313     break;
00314   }
00315 
00316   memcpy(&CRC, packet + len - 4, 4);
00317 
00318 /*
00319   // Check if the packet is a good packet
00320 //#ifndef LWNG_15
00321 //  if ((CRC == 0xFFFFFFFF)
00322 //      || ((unsigned) len < sizeof (p80211msg_lnxind_wlansniffrm_t))) {
00323 //#else
00324   if ((unsigned) len < sizeof (p80211msg_lnxind_wlansniffrm_t)) {
00325 //#endif
00326     if (DebugLevel >= 1) {
00327       debug (0, "INVALID PACKET : BAD CRC (%08X) or too short (%04X)\n",
00328              CRC, len);
00329       if ((unsigned) len > sizeof (p80211msg_lnxind_wlansniffrm_t)) {
00330         CRC =
00331           doFCS (&packet[sizeof (p80211msg_lnxind_wlansniffrm_t)],
00332                  (len - 4 - sizeof (p80211msg_lnxind_wlansniffrm_t)));
00333         debug (1, "Calculed CRC is : %08X\n", CRC);
00334       }
00335     }
00336     strncpy (Res.TypeOfPacket, "INVLID", WLAN_SIZEOF_TYPEOFPACKET);
00337     Stats.INVLD++;
00338     ReturnCode = 0;
00339   } else { */
00340 
00341   // Copy type of packet (in text)
00342   strncpy(Res.TypeOfPacket,
00343           TypeOfPacketToString(d80211b_Header->a3.fc),
00344           WLAN_SIZEOF_TYPEOFPACKET);
00345   //}
00346 
00347   debug(1, "FrameType=%04X (type:%X subtype:%X)\n",
00348         d80211b_Header->a3.fc,
00349         WLAN_GET_FC_FTYPE(d80211b_Header->a3.fc),
00350         WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc));
00351 
00352   return ReturnCode;
00353 }
00354 
00355 /* ***
00356  * Functions of Analyse
00357  */
00358 
00359 int analyseBeacon(unsigned char *packet, int len)
00360 {
00361   p80211_hdr_t *d80211b_Header;
00362   FixedField_t *FixedField;
00363 
00364   (unsigned char *) d80211b_Header = packet;
00365   (char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00366 
00367   sprintf(Res.DestMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00368           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00369           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00370           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00371   sprintf(Res.SrcMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00372           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00373           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00374           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00375   sprintf(Res.BssId, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00376           d80211b_Header->a3.a3[0], d80211b_Header->a3.a3[1],
00377           d80211b_Header->a3.a3[2], d80211b_Header->a3.a3[3],
00378           d80211b_Header->a3.a3[4], d80211b_Header->a3.a3[5]);
00379 
00380   //Res.isAp = WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info);
00381   Res.hasWep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00382 
00383   /* Log */
00384   LogDetectedClient(d80211b_Header->a3.a2);
00385   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00386   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00387   // Here we know if it's an AP or an Ah-Hoc client
00388   SET_TYPE_BIT_BEACON(Res.TypeOfClient);
00389   if (WLAN_GET_MGMT_CAP_INFO_IBSS(FixedField->cap_info)) {
00390     SET_TYPE_BIT_P2P(Res.TypeOfClient);
00391     CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00392     LogPutIsP2P(d80211b_Header->a3.a2, Res.hasWep, FixedField->bcn_int);
00393   } else {
00394     CLEAR_TYPE_BIT_P2P(Res.TypeOfClient);
00395     if (WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info)) {
00396       SET_TYPE_BIT_AP(Res.TypeOfClient);
00397       LogPutIsAP(d80211b_Header->a3.a2, Res.hasWep, FixedField->bcn_int);
00398     } else {
00399       CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00400     }
00401   }
00402   LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00403   LogPutTimestamp(d80211b_Header->a3.a2, FixedField->ts);
00404   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00405 
00406   debug(1,
00407         "Dst:%s Src:%s Bssid:%s\n" "Fragment number : 0x%04X\n"
00408         "Sequence number : 0x%02X\n" "Timestamp : 0x%016llX\n"
00409         "Beacon Interval : 0x%X\n" "Capabilities : 0x%X\n"
00410         "S/N : %ld/%ld\n", Res.DestMac, Res.SrcMac, Res.BssId,
00411         WLAN_GET_SEQ_FRGNUM(d80211b_Header->a3.seq),
00412         WLAN_GET_SEQ_SEQNUM(d80211b_Header->a3.seq), FixedField->ts,
00413         FixedField->bcn_int, FixedField->cap_info, Res.Signal, Res.Noise);
00414 
00415   if ((unsigned int) len <= (sizeof(p80211_hdr_t) + sizeof(FixedField_t)))
00416     return 0;
00417 
00418   ProcessTagBits(packet, len, WLAN_FSTYPE_BEACON);
00419 
00420   return 1;
00421 }
00422 
00423 /*************************/
00424 
00425 int analyseProbeReq(unsigned char *packet, int len)
00426 {
00427   p80211_hdr_t *d80211b_Header;
00428   FixedField_t *FixedField;
00429 
00430   (unsigned char *) d80211b_Header = packet;
00431   (char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00432 
00433   sprintf(Res.DestMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00434           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00435           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00436           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00437   sprintf(Res.SrcMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00438           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00439           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00440           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00441   sprintf(Res.BssId, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00442           d80211b_Header->a3.a3[0], d80211b_Header->a3.a3[1],
00443           d80211b_Header->a3.a3[2], d80211b_Header->a3.a3[3],
00444           d80211b_Header->a3.a3[4], d80211b_Header->a3.a3[5]);
00445 
00446   debug(1,
00447         "Dst:%s Src:%s Bssid:%s\n" "Fragment number : 0x%04X\n"
00448         "Sequence number : 0x%02X\n" "S/N : %ld/%ld\n", Res.DestMac,
00449         Res.SrcMac, Res.BssId,
00450         WLAN_GET_SEQ_FRGNUM(d80211b_Header->a3.seq),
00451         WLAN_GET_SEQ_SEQNUM(d80211b_Header->a3.seq), Res.Signal,
00452         Res.Noise);
00453 
00454   /* Log */
00455   LogDetectedClient(d80211b_Header->a3.a2);
00456   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00457   LogPutRate(d80211b_Header->a3.a2, Res.Noise);
00458   //LogPutIsAP (d80211b_Header->a3.a2, Res.hasWep, FixedField->bcn_int);
00459   LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00460   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00461 
00462   Res.hasWep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00463 
00464   ProcessTagBits(packet, len, WLAN_FSTYPE_PROBEREQ);
00465 
00466   //Res.isAp = WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info);
00467 
00468   return 1;                     /* All is OK */
00469 }
00470 
00471 /*************************/
00472 
00473 int analyseProbeRep(unsigned char *packet, int len)
00474 {
00475   p80211_hdr_t *d80211b_Header;
00476   FixedField_t *FixedField;
00477 
00478   (char *) d80211b_Header = packet;
00479   (char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00480 
00481   sprintf(Res.DestMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00482           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00483           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00484           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00485   sprintf(Res.SrcMac, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00486           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00487           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00488           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00489   sprintf(Res.BssId, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00490           d80211b_Header->a3.a3[0], d80211b_Header->a3.a3[1],
00491           d80211b_Header->a3.a3[2], d80211b_Header->a3.a3[3],
00492           d80211b_Header->a3.a3[4], d80211b_Header->a3.a3[5]);
00493 
00494   debug(1,
00495         "Dst:%s Src:%s Bssid:%s\n" "Fragment number : 0x%04X\n"
00496         "Sequence number : 0x%02X\n" "Timestamp : 0x%016llX\n"
00497         "Capabilities : 0x%X\n" "S/N : %ld/%ld\n", Res.DestMac,
00498         Res.SrcMac, Res.BssId,
00499         WLAN_GET_SEQ_FRGNUM(d80211b_Header->a3.seq),
00500         WLAN_GET_SEQ_SEQNUM(d80211b_Header->a3.seq), FixedField->ts,
00501         FixedField->cap_info, Res.Signal, Res.Noise);
00502 
00503   /* Log */
00504   LogDetectedClient(d80211b_Header->a3.a1);
00505   /* STA */
00506   LogDetectedClient(d80211b_Header->a3.a2);     /* AP */
00507 
00508   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00509   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00510   LogPutIsAP(d80211b_Header->a3.a2,
00511              WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info),
00512              FixedField->bcn_int);
00513   LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00514   LogPutTimestamp(d80211b_Header->a3.a2, FixedField->ts);
00515   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00516 
00517   //Res.isAp = WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info);
00518   Res.hasWep = WLAN_GET_MGMT_CAP_INFO_PRIVACY(FixedField->cap_info);
00519 
00520   if (WLAN_GET_MGMT_CAP_INFO_IBSS(FixedField->cap_info)) {
00521     SET_TYPE_BIT_P2P(Res.TypeOfClient);
00522     CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00523     LogPutIsP2P(d80211b_Header->a3.a2, Res.hasWep, 0);
00524   } else {
00525     CLEAR_TYPE_BIT_P2P(Res.TypeOfClient);
00526     if (WLAN_GET_MGMT_CAP_INFO_ESS(FixedField->cap_info)) {
00527       SET_TYPE_BIT_AP(Res.TypeOfClient);
00528       LogPutIsAP(d80211b_Header->a3.a2, Res.hasWep, 0);
00529     } else {
00530       CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00531     }
00532   }
00533   ProcessTagBits(packet, len, WLAN_FSTYPE_PROBERESP);
00534 
00535   return 1;                     /* All is OK */
00536 }
00537 
00538 
00539 /**********/
00540 
00541 int analyseRTS(unsigned char *packet)
00542 {
00543   p80211_hdr_t *d80211b_Header;
00544   char strAddresse1[WLAN_STR_ADDR_LEN];
00545   char strAddresse2[WLAN_STR_ADDR_LEN];
00546 
00547   (unsigned char *) d80211b_Header = packet;
00548 
00549   sprintf(strAddresse1, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00550           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00551           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00552           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00553   sprintf(strAddresse2, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00554           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00555           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00556           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00557 
00558   debug(1, "FC=%X", d80211b_Header->a3.fc);
00559 
00560   strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00561   strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00562   strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00563   /* Log */
00564   LogDetectedClient(d80211b_Header->a3.a1);     /* STA */
00565   LogDetectedClient(d80211b_Header->a3.a2);     /* AP */
00566   LogPutSN(d80211b_Header->a3.a3, Res.Signal);
00567   LogPutRate(d80211b_Header->a3.a3, Res.Rate);
00568 
00569   return 1;                     /* All is OK */
00570 }
00571 
00572 int analyseCTS(unsigned char *packet)
00573 {
00574   p80211_hdr_t *d80211b_Header;
00575   char strAddresse1[WLAN_STR_ADDR_LEN];
00576 
00577   (unsigned char *) d80211b_Header = packet;
00578 
00579   sprintf(strAddresse1, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00580           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00581           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00582           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00583 
00584   debug(1, "FC=%X", d80211b_Header->a3.fc);
00585 
00586   strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00587   strncpy(Res.SrcMac, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00588   strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00589   /* Log */
00590   LogDetectedClient(d80211b_Header->a3.a1);     /* STA */
00591 
00592   return 1;                     /* All is OK */
00593 }
00594 
00595 /*
00596  * Function to analyse an Acknoledge frame
00597  */ int analyseACK(
00598                     unsigned char *packet)
00599 {
00600   p80211_hdr_t *d80211b_Header;
00601   char strAddresse1[WLAN_STR_ADDR_LEN];
00602 
00603   (unsigned char *) d80211b_Header = packet;
00604 
00605   sprintf(strAddresse1, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00606           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00607           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00608           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00609 
00610   debug(1, "FC=%X", d80211b_Header->a3.fc);
00611 
00612   strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00613   strncpy(Res.SrcMac, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00614   strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00615   /* Log */
00616   LogDetectedClient(d80211b_Header->a3.a1);     /* STA or AP */
00617 
00618   return 1;                     /* All is OK */
00619 }
00620 
00621 int analysePSPOLL(unsigned char *packet)
00622 {
00623   p80211_hdr_t *d80211b_Header;
00624   char strAddresse1[WLAN_STR_ADDR_LEN];
00625   char strAddresse2[WLAN_STR_ADDR_LEN];
00626 
00627   (unsigned char *) d80211b_Header = packet;
00628 
00629   sprintf(strAddresse1, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00630           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00631           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00632           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00633   sprintf(strAddresse2, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00634           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00635           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00636           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00637 
00638   debug(1, "FC=%X", d80211b_Header->a3.fc);
00639 
00640   strncpy(Res.SrcMac, strAddresse1, WLAN_STR_ADDR_LEN);
00641   strncpy(Res.DestMac, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00642   strncpy(Res.BssId, strAddresse2, WLAN_STR_ADDR_LEN);
00643   /* Log */
00644   LogDetectedClient(d80211b_Header->a3.a1);     /* STA */
00645   LogPutSN(d80211b_Header->a3.a1, Res.Signal);
00646   LogPutRate(d80211b_Header->a3.a1, Res.Rate);
00647   LogPutSeqNum(d80211b_Header->a3.a1, Res.DestMac, d80211b_Header->a3.seq);
00648 
00649   return 1;                     /* All is OK */
00650 }
00651 
00652 /*
00653  * Function to analyse and parse a Data Frame
00654  */ int analyseData(
00655                      unsigned char *packet, int len)
00656 {
00657   p80211_hdr_t *d80211b_Header;
00658   FixedField_t *FixedField;
00659   char strAddresse1[WLAN_STR_ADDR_LEN];
00660   char strAddresse2[WLAN_STR_ADDR_LEN];
00661   char strAddresse3[WLAN_STR_ADDR_LEN];
00662 
00663   (unsigned char *) d80211b_Header = packet;
00664   (char *) FixedField = packet + sizeof(p80211_hdr_a3_t);
00665 
00666   sprintf(strAddresse1, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00667           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00668           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00669           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00670   sprintf(strAddresse2, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00671           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00672           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00673           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00674   sprintf(strAddresse3, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00675           d80211b_Header->a3.a3[0], d80211b_Header->a3.a3[1],
00676           d80211b_Header->a3.a3[2], d80211b_Header->a3.a3[3],
00677           d80211b_Header->a3.a3[4], d80211b_Header->a3.a3[5]);
00678 
00679   debug(1, "FC=%X", d80211b_Header->a3.fc);
00680 
00681   if (WLAN_GET_FC_TODS(d80211b_Header->a3.fc)) {
00682     if (WLAN_GET_FC_FROMDS(d80211b_Header->a3.fc)) {
00683       // Data From AP by AP to STA
00684       debug(2, " AP to AP");
00685 
00686       SET_TYPE_BIT_TODS(Res.TypeOfClient);
00687       SET_TYPE_BIT_FROMDS(Res.TypeOfClient);
00688 
00689       LogDetectedClient(d80211b_Header->a3.a1);
00690       LogDetectedClient(d80211b_Header->a3.a2);
00691       LogDetectedClient(d80211b_Header->a3.a3);
00692 
00693       strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00694       strncpy(Res.DestMac, strAddresse3, WLAN_STR_ADDR_LEN);
00695       strncpy(Res.BssId, "00:00:00:00:00:00", WLAN_STR_ADDR_LEN);
00696       /* Log */
00697       LogPutSN(d80211b_Header->a3.a1, Res.Signal);
00698       LogPutRate(d80211b_Header->a3.a1, Res.Rate);
00699       LogPutIsAP(d80211b_Header->a3.a2,
00700                  WLAN_GET_MGMT_CAP_INFO_PRIVACY
00701                  (FixedField->cap_info), FixedField->bcn_int);
00702       //Res.isAp = 1;
00703       SET_TYPE_BIT_AP(Res.TypeOfClient);
00704     } else {
00705       // Data from DS to STA
00706       debug(1, " TODS");
00707       SET_TYPE_BIT_TODS(Res.TypeOfClient);
00708 
00709       strncpy(Res.BssId, strAddresse1, WLAN_STR_ADDR_LEN);
00710       strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00711       strncpy(Res.DestMac, strAddresse3, WLAN_STR_ADDR_LEN);
00712       /* Log */
00713       LogDetectedClient(d80211b_Header->a3.a2);
00714       LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00715       LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00716       //LogPutIsAP (d80211b_Header->a3.a2, Res.hasWep, FixedField->bcn_int);
00717       LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a1);
00718       //LogPutDS (d80211b_Header->a3.a3);
00719     }
00720   } else if (WLAN_GET_FC_FROMDS(d80211b_Header->a3.fc)) {
00721     // Data to DS to STA
00722     debug(1, " FROMDS");
00723 
00724     SET_TYPE_BIT_FROMDS(Res.TypeOfClient);
00725 
00726     strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00727     strncpy(Res.BssId, strAddresse2, WLAN_STR_ADDR_LEN);
00728     strncpy(Res.SrcMac, strAddresse3, WLAN_STR_ADDR_LEN);
00729     /* Log */
00730     LogDetectedClient(d80211b_Header->a3.a3);
00731     LogPutSN(d80211b_Header->a3.a3, Res.Signal);
00732     LogPutRate(d80211b_Header->a3.a3, Res.Rate);
00733     LogPutBSSID(d80211b_Header->a3.a3, d80211b_Header->a3.a2);
00734     LogPutDS(d80211b_Header->a3.a3);
00735   } else {
00736     // Data from STA to STA
00737     debug(1, " STA to STA");
00738 
00739     strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00740     strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00741     strncpy(Res.BssId, strAddresse3, WLAN_STR_ADDR_LEN);
00742     /* Log */
00743     LogDetectedClient(d80211b_Header->a3.a1);
00744     LogDetectedClient(d80211b_Header->a3.a2);
00745     LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00746     LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00747     LogPutBSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3);
00748   }
00749 
00750   debug(1, "\n");
00751 
00752   // If it's a NULL Function Packet : 
00753   //    do not fill IV and do not try to detect if it crypted
00754   if (WLAN_GET_FC_FSTYPE(d80211b_Header->a3.fc) != WLAN_FSTYPE_NULL)
00755     Res.hasWep = dataIsCrypted(packet, len);
00756 
00757   // TODO : put LastIV in Struct ClientInfo
00758 
00759   return 1;                     /* All is OK */
00760 }
00761 
00762 int analyseMGMT(unsigned char *packet)
00763 {
00764   p80211_hdr_t *d80211b_Header;
00765   char strAddresse1[WLAN_STR_ADDR_LEN];
00766   char strAddresse2[WLAN_STR_ADDR_LEN];
00767   char strAddresse3[WLAN_STR_ADDR_LEN];
00768 
00769   (unsigned char *) d80211b_Header = packet;
00770 
00771   sprintf(strAddresse1, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00772           d80211b_Header->a3.a1[0], d80211b_Header->a3.a1[1],
00773           d80211b_Header->a3.a1[2], d80211b_Header->a3.a1[3],
00774           d80211b_Header->a3.a1[4], d80211b_Header->a3.a1[5]);
00775   sprintf(strAddresse2, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00776           d80211b_Header->a3.a2[0], d80211b_Header->a3.a2[1],
00777           d80211b_Header->a3.a2[2], d80211b_Header->a3.a2[3],
00778           d80211b_Header->a3.a2[4], d80211b_Header->a3.a2[5]);
00779   sprintf(strAddresse3, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
00780           d80211b_Header->a3.a3[0], d80211b_Header->a3.a3[1],
00781           d80211b_Header->a3.a3[2], d80211b_Header->a3.a3[3],
00782           d80211b_Header->a3.a3[4], d80211b_Header->a3.a3[5]);
00783 
00784   debug(1, "FC=%X", d80211b_Header->a3.fc);
00785 
00786   strncpy(Res.DestMac, strAddresse1, WLAN_STR_ADDR_LEN);
00787   strncpy(Res.SrcMac, strAddresse2, WLAN_STR_ADDR_LEN);
00788   strncpy(Res.BssId, strAddresse3, WLAN_STR_ADDR_LEN);
00789   /* Log */
00790   LogDetectedClient(d80211b_Header->a3.a1);
00791   LogDetectedClient(d80211b_Header->a3.a2);
00792   LogPutSN(d80211b_Header->a3.a2, Res.Signal);
00793   LogPutRate(d80211b_Header->a3.a2, Res.Rate);
00794   LogPutSeqNum(d80211b_Header->a3.a2, Res.DestMac, d80211b_Header->a3.seq);
00795 
00796   return 1;                     /* All is OK */
00797 }
00798 
00799 // Function to filter not printable caractere in some SSID
00800 UINT8 FilterESSID(char *ESSID)
00801 {
00802   UINT8 i;
00803   UINT8 modified = FALSE;
00804 
00805   for (i = 0; i < strlen(ESSID); i++) {
00806     //if (!isprint (ESSID[i]))
00807     if (ESSID[i] < ' ') {
00808       ESSID[i] = '?';
00809       modified++;
00810     }
00811   }
00812   ESSID[i] = 0x00;              // In case OF ... :-)
00813   return modified;
00814 }
00815 
00816 void ProcessTagBits(unsigned char *packet, int len, int FrameType)
00817 {
00818   static UINT8 NbTagSSID = 0;
00819   unsigned char *varBits;
00820   p80211_hdr_t *d80211b_Header;
00821   int tagType, tagLen;
00822   char Buff[0x101];             // BAD !!!
00823   UINT8 MaxRate, i;
00824   UINT8 NbCarCTRL = 0;          // Number of Control char is SSID 
00825 
00826   /* Get only that we want */
00827   (unsigned char *) d80211b_Header = packet;
00828   (unsigned char *) varBits = packet + sizeof(p80211_hdr_a3_t);
00829 
00830   /* Do a correction on the size of the Fixed Field and fill MacAdd */
00831   switch (FrameType) {
00832   case WLAN_FSTYPE_ASSOCREQ:
00833     break;
00834   case WLAN_FSTYPE_ASSOCRESP:
00835     break;
00836   case WLAN_FSTYPE_REASSOCREQ:
00837     break;
00838   case WLAN_FSTYPE_REASSOCRESP:
00839     break;
00840   case WLAN_FSTYPE_PROBEREQ:
00841     /* Size of FixedField = 0 */
00842     break;
00843   case WLAN_FSTYPE_PROBERESP:
00844     /* Size of FixedField = 0x0C */
00845     varBits += sizeof(FixedField_t);
00846     break;
00847   case WLAN_FSTYPE_BEACON:
00848     /* Size of FixedField = 0x0C */
00849     varBits += sizeof(FixedField_t);
00850     break;
00851   case WLAN_FSTYPE_ATIM:
00852     break;
00853   }
00854   NbTagSSID = 0;
00855 
00856   /* Get the tagged values 
00857    * There is a type and a length field
00858    * Followed by tha actual data 
00859    */
00860 
00861   tagType = 0;
00862   debug(1, "TagType(len) = ");
00863 
00864   /* -4 is the CRC, I don't want CRC :-)) */
00865   while ((varBits < (packet + len - 4)) && (tagType != 0xFF)) {
00866 
00867     tagType = varBits[0];
00868     tagLen = varBits[1];
00869     varBits += 2;
00870     debug(1, "%02d(%02d),", tagType, tagLen);
00871     switch (tagType) {
00872 
00873     case WLAN_EID_SSID:        /* 0 */
00874       //strncpy (Res.SSID, varBits, tagLen);
00875       memcpy(Res.SSID, varBits, tagLen);
00876       //warning ("0> SSID = '%s'\n", Res.SSID);
00877       FilterESSID(Res.SSID);
00878       // Catch wellenreiter probes
00879       if (!strncmp(Res.SSID, "this_is_used_for_wellenreiter", 32)) {
00880         warning
00881             ("\nWARNING : Somebody use wellenreiter to probe SomeBody!\n");
00882       }
00883       // Catch Windows XP probes
00884       // Check some two or three think to find if it's a WinXP
00885       if (tagLen == 32) {
00886         for (i = 0; i < tagLen; i++) {
00887           if (varBits[i] < 32)
00888             NbCarCTRL++;
00889         }
00890         if (NbCarCTRL >= 10) {
00891           //warning ("WARNING : Windows XP is HERE !\n");
00892           strncpy(Res.SSID, "<I'm a Buggy WinXP>", 31);
00893         }
00894       }
00895       if ((tagLen == 0)
00896           && (FrameType == WLAN_FSTYPE_BEACON)) {
00897         strncpy(Res.SSID, "<Hidden SSID>", 31);
00898       }
00899       if ((tagLen != 0) && (varBits[0] == 0)
00900           && (varBits[1] == 0)
00901           && (varBits[2] == 0)) {
00902         // CISCO has this Bug : Send a Blank SSID but the length is not zeroized
00903         strncpy(Res.SSID, "<Hidden SSID of known length>", 31);
00904       }
00905       LogPutSSID(d80211b_Header->a3.a2, d80211b_Header->a3.a3, Res.SSID);
00906       NbTagSSID++;
00907       break;
00908 
00909     case 50:                   /* 50 - Extended Supported Rates */
00910     case WLAN_EID_SUPP_RATES:  /*  1 - Supported Rates */
00911       MaxRate = (*varBits) & 0x7F;
00912       for (i = 0; i < tagLen; i++) {
00913         if (MaxRate < (*(varBits + i) & 0x7F))
00914           MaxRate = *(varBits + i) & 0x7F;
00915       }
00916       LogPutMaxRate(d80211b_Header->a3.a2, (UINT8) MaxRate);
00917       break;
00918 
00919     case WLAN_EID_FH_PARMS:    /* 2 */
00920       break;
00921 
00922     case WLAN_EID_DS_PARMS:    /* 3 */
00923       if (tagLen == 1) {
00924         Res.Channel = *varBits;
00925         LogPutChannel(d80211b_Header->a3.a2,
00926                       d80211b_Header->a3.a3, Res.Channel);
00927       }
00928       break;
00929 
00930     case WLAN_EID_CF_PARMS:    /* 4 */
00931       SET_TYPE_BIT_AP(Res.TypeOfClient);
00932       break;
00933 
00934     case WLAN_EID_TIM:         /* 5 */
00935       // The TIM information is only present within beacon frames generated by APs
00936       SET_TYPE_BIT_AP(Res.TypeOfClient);
00937       break;
00938 
00939     case WLAN_EID_IBSS_PARMS:  /* 6 */
00940       CLEAR_TYPE_BIT_AP(Res.TypeOfClient);
00941       SET_TYPE_BIT_P2P(Res.TypeOfClient);
00942       break;
00943 
00944     case WLAN_EID_CHALLENGE:   /* 16 */
00945       break;
00946       // Specific Vedor TAG
00947 
00948     case 7:                    /* Country Information */
00949       // Exemple : "FR ..." 0x46,0x52,0x20,0x0B,0x03,0x1E
00950       //            Country code en ASCII : FR
00951       //       Start channel      : 11
00952       //        Channels          :  3
00953       //         Max TX power     : 30 mW
00954       break;
00955 
00956     case 42:                   /* ERP Informations */
00957       break;
00958 
00959     case 133:                  /* CISCO AIRONET */
00960       // It's an AP NAME, Thx for the information :-)
00961       strncpy(Buff, (varBits + 0x0A), 0x10);
00962       UpdateOtherInformation(Buff);
00963       LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
00964       break;
00965 
00966     case 171:                  /* Undocumented TAG - ARUBA */
00967       break;
00968 
00969     case 221:                  /* WPA */
00970       strncpy(Buff, "WPA Capable", 12);
00971       UpdateOtherInformation(Buff);
00972       LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
00973       break;
00974 
00975     case 0xFF:
00976       // End of Tag list
00977       break;
00978       // Other unknowned TAG
00979     default:
00980       snprintf(Buff, 32, "An unknow tag is detected : %02X", tagType);
00981       UpdateOtherInformation(Buff);
00982       LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
00983       debug(1,
00984             "\nWARNING -- This TagType is unknowed =%02X\n"
00985             "Please send one of this packet to the author\n", tagType);
00986       break;
00987     }
00988     varBits += tagLen;
00989   }
00990 
00991   debug(1, "\nRes.TypeOfClient=%x\n", Res.TypeOfClient);
00992 
00993   if (NbTagSSID > 1) {
00994     // It seem to be a Windows XP STA :-)
00995     debug(1, "Tag 0 (SSID) is send more than one time (%d)\n", NbTagSSID);
00996     snprintf(Buff, 85,
00997              "Tag 0 (SSID) is send more than one time (%.2d) - "
00998              "This STA is probably under Windows XP", NbTagSSID);
00999     UpdateOtherInformation(Buff);
01000     LogPutOtherInformation(d80211b_Header->a3.a2, Res.OtherInformation);
01001   }
01002 }
01003 
01004 /* 
01005  * This function parse commandline and fill option ... 
01006  */
01007 void ParseCommandLine(int argc, char **argv, ConfigStruct * config)
01008 {
01009   int c, n;
01010   char *CommaPosition = NULL;
01011 
01012   int option_index = 0;
01013   static struct option long_options[] = {
01014     {"version", 0, 0, 'v'},
01015     {"help", 0, 0, 'h'},
01016     {"verbose", 1, 0, 'V'},
01017     {"output-file", 1, 0, 'F'},
01018     {"hop", 1, 0, 'H'},
01019     {"channel", 1, 0, 'S'},
01020     {"device-file", 1, 0, 'D'},
01021     {"computer-date", 0, 0, 'd'},
01022     {"iface", 1, 0, 'i'},
01023     {"ids", 0, 0, 'I'},
01024     {"max-packets", 1, 0, 'M'},
01025     {"hide-packets", 1, 0, 'N'},
01026     {"hop-delay", 1, 0, 't'},
01027     {"disable-check", 0, 0, 'c'},
01028     {"card-driver", 0, 0, 'C'},
01029 #ifdef WITH_WIRETAP
01030     {"pcap-file", 1, 0, 'W'},
01031 #endif
01032 #ifdef WITH_SYSLOG
01033     {"send-to-syslog", 0, 0, 's'},
01034 #endif
01035     {0, 0, 0, 0}
01036   };
01037 
01038 
01039   while ((c =
01040           getopt_long(argc, argv,
01041                       "vF:S:W:D:i:t:V:h?H:dM:N:IG:w:k:C:cs",
01042                       long_options, &option_index)) != EOF) {
01043 
01044     switch (c) {
01045       // Set channel
01046     case 'S':
01047       config->SingleChannel = atoi(optarg);
01048       if (config->SingleChannel < CHANNEL_MIN ||
01049           config->SingleChannel > CHANNEL_MAX) {
01050         fprintf(stderr,
01051                 "Error : Channel must be between %d and %d\n",
01052                 CHANNEL_MIN, CHANNEL_MAX);
01053         Bye();
01054       }
01055       break;
01056 
01057 #ifdef WITH_SYSLOG
01058       // Send Alert to Syslog
01059     case 's':
01060       config->SendAlert2Syslog = TRUE;
01061       openlog("wifiscanner", LOG_ODELAY || LOG_PID, LOG_USER);
01062       break;
01063 #endif
01064 
01065       // Output file for real time information
01066     case 'F':
01067       if (strncmp("auto", optarg, 5)) {
01068         config->OutFileName = optarg;
01069       } else {
01070 
01071       }
01072       break;
01073 
01074       // PCAP output
01075 #ifdef WITH_WIRETAP
01076     case 'W':                  // PCAP output file
01077       config->OutDumpFileName = optarg;
01078       break;
01079 #endif
01080 
01081       // .DOT output
01082     case 'D':
01083       config->OutDotFileName = optarg;
01084       break;
01085 
01086       // Version
01087     case 'v':
01088       Bye();
01089       break;
01090 
01091       // Number of Hop for channel rotation
01092     case 'H':
01093       config->ChannelHop = atoi(optarg);
01094       if (config->ChannelHop < HOP_MIN || config->ChannelHop > HOP_MAX) {
01095         fprintf(stderr,
01096                 "Error : Hop must be between %d and %d\n",
01097                 HOP_MIN, HOP_MAX);
01098         Bye();
01099       }
01100       break;
01101 
01102       // Verbosity level
01103     case 'V':
01104       config->DebugLevel = atoi(optarg);
01105       if (config->DebugLevel < 1 || config->DebugLevel > MAX_DEBUG_LEVEL)
01106         config->DebugLevel = MAX_DEBUG_LEVEL;
01107       n = 0;                    // Display all packets
01108       break;
01109 
01110       // Time to sleep before change channel
01111     case 't':
01112       config->TimeToSleepBeforeChangeChannel = atoi(optarg);
01113       if (config->TimeToSleepBeforeChangeChannel < 1
01114           || config->TimeToSleepBeforeChangeChannel > 10000)
01115         config->TimeToSleepBeforeChangeChannel = 10000; /* Ten seconds is enougth */
01116       break;
01117 
01118       // Choice of interface
01119     case 'i':
01120       // The interface can be "eth0" or "eth1,wifi0"
01121       // So we search the comma
01122       if (strlen(optarg) > (DEVNAME_LEN * 2 + 1)) {
01123         // Hmmm What did the user want ...
01124         fprintf(stderr,
01125                 "I think that the length of the interface is a little bit too long\n"
01126                 " Wake up ! And don't sleep on the keyboard !   :)\n");
01127         Bye();
01128       }
01129       memset(config->devname, 0, DEVNAME_LEN);
01130       memset(config->devname2, 0, DEVNAME_LEN);
01131       CommaPosition = strchr(optarg, ',');
01132       if (CommaPosition == NULL) {
01133         // Only one interface
01134         strncpy(config->devname, optarg, DEVNAME_LEN);
01135         config->devname[DEVNAME_LEN - 1] = '\0';
01136         debug(3, "Only one interface is given : %s\n", config->devname);
01137       } else {
01138         UINT16 SizeOne, SizeTwo;
01139         SizeOne = CommaPosition - optarg;
01140         SizeTwo = strlen(optarg) - SizeOne - 1;
01141         strncpy(config->devname, optarg, SizeOne);
01142         strncpy(config->devname2, (CommaPosition + 1), SizeTwo);
01143         debug(3, "Two interface is given : (%s)[%d]-(%s)[%d]\n",
01144               config->devname, SizeOne, config->devname2, SizeTwo);
01145       }
01146 
01147       break;
01148 
01149       // Human readable date
01150     case 'd':
01151       config->DateFormat = 0;
01152       break;
01153 
01154       // Max packets to capture before leave
01155     case 'M':
01156       // Check if outbound
01157       if (atol(optarg) < 0)
01158         config->MaxPacket = atol(optarg);
01159       break;
01160 
01161       // Help 
01162     case '?':                  // Help
01163     case 'h':                  // Help too
01164       HelpAndBye();
01165       break;
01166 
01167       // IDS 
01168     case 'I':
01169       config->IDS_is_ON = TRUE;
01170       //*OutIDSFileName = optarg;
01171       break;
01172 
01173       // Hide some packets (only on display)
01174     case 'N':
01175       n = 0;
01176       fprintf(stdout, "Do not display: ");
01177       // do while until end of option or 16 sub-option ...
01178       while ((optarg[n] != 0) && (n < 16)) {
01179         switch (optarg[n]) {
01180         case 'A':
01181         case 'a':
01182           SET_BIT(config->DoNotDisplay, 0);
01183           fprintf(stdout, "ACK ");
01184           break;
01185         case 'B':
01186         case 'b':
01187           SET_BIT(config->DoNotDisplay, 1);
01188           fprintf(stdout, "BEACON ");
01189           break;
01190         case 'C':
01191         case 'c':
01192           SET_BIT(config->DoNotDisplay, 2);
01193           fprintf(stdout, "CONTROL ");
01194           break;
01195         case 'D':
01196         case 'd':
01197           SET_BIT(config->DoNotDisplay, 3);
01198           fprintf(stdout, "DATA ");
01199           break;
01200         case 'S':
01201         case 's':
01202           SET_BIT(config->DoNotDisplay, 4);
01203           fprintf(stdout, "STATION ");
01204           break;
01205         default:
01206           break;
01207         }
01208         n++;
01209       }
01210       fprintf(stdout, "\n");
01211       if (config->DebugLevel > 1) {
01212         fprintf(stdout,
01213                 "Verbose level is more than 1 so all packets are display\n");
01214       }
01215       break;
01216 
01217       // G option
01218     case 'G':                  // ???
01219       break;
01220 
01221       // Save weak packets
01222     case 'w':
01223       break;
01224 
01225       // Save KeyStream of Authen with IV
01226     case 'k':
01227       break;
01228 
01229       // Card driver
01230     case 'C':                  // Choice of CARD
01231       if ((!strcmp(optarg, "prism"))
01232           || (!strcmp(optarg, "hostap"))
01233           || (!strcmp(optarg, "cisco"))
01234           || (!strcmp(optarg, "cisco_wifi"))
01235           || (!strcmp(optarg, "orinoco"))
01236           || (!strcmp(optarg, "prism54g"))
01237           || (!strcmp(optarg, "atheros"))) {
01238         //if ((!strcmp (optarg, "prism")) || (!strcmp (optarg, "hostap"))) {
01239         if (!strcmp(optarg, "cisco_wifi")) {
01240           config->TypeOfCard = CISCO_CVS_CARD;
01241           fprintf(stderr,
01242                   "\n##############\n"
01243                   " WARNING - I'm absolutly not sure that this driver work correctly (ALPHA VERSION)\n"
01244                   "##############\n\n");
01245           sleep(5);
01246         }
01247         if (!strcmp(optarg, "cisco")) {
01248           config->TypeOfCard = CISCO_CARD;
01249         }
01250         if (!strcmp(optarg, "prism")) {
01251           config->TypeOfCard = WLAN_NG_CARD;
01252         }
01253         if (!strcmp(optarg, "prism54g")) {
01254           config->TypeOfCard = PRISM54G_CARD;
01255         }
01256         if (!strcmp(optarg, "hostap")) {
01257           config->TypeOfCard = HOSTAP_CARD;
01258         }
01259         if (!strcmp(optarg, "atheros")) {
01260           config->TypeOfCard = ATHEROS_CARD;
01261         }
01262         if (!strcmp(optarg, "orinoco")) {
01263           config->TypeOfCard = LUCENT_CARD;
01264         }
01265       } else {
01266 //               "Only 'prism', 'hostap', 'cisco_cvs' or 'cisco'"
01267         fprintf(stderr,
01268                 "Only 'prism', 'cisco' 'cisco_wifi (eth+wifi)' 'orinoco' 'atheros', 'prism54g', or 'hostap'"
01269                 " card is allowed.\n");
01270         Bye();
01271       }
01272       debug(2, "Driver used is : %s\n", optarg);
01273       break;
01274       // Disable curses checks
01275     case 'c':
01276       config->CheckScreenSize = FALSE;
01277       break;
01278 
01279       // Default
01280     default:
01281       break;
01282     }
01283   }
01284 
01285   // Post analyse of parameters
01286   if ((config->TypeOfCard == CISCO_CVS_CARD)
01287       && (!strcmp(config->devname2, ""))) {
01288     fprintf(stderr,
01289             "You must give me two interface, when card driver is cisco_wifi"
01290             "like -i eth1,wifi0\n");
01291     Bye();
01292   }
01293 
01294 }
01295 
01296 
01297 
01298 /*
01299  * Summerize configuration
01300  */
01301 
01302 void DispConf(ConfigStruct * config)
01303 {
01304 
01305   if (config->TypeOfCard == CISCO_CVS_CARD) {
01306     fprintf(stdout, "Interfaces used: %s and %s \n", config->devname,
01307             config->devname2);
01308   } else {
01309     fprintf(stdout, "Interface used: %s\n", config->devname);
01310   }
01311   fprintf(stdout, "Debug Level: %d", config->DebugLevel);
01312   if (config->DebugLevel == MAX_DEBUG_LEVEL)
01313     fprintf(stdout, " (Crazy level)");
01314   // Out Files
01315   fprintf(stdout, "\nOutput filename: %s",
01316           (config->OutFileName == NULL) ? "<none>" : config->OutFileName);
01317   fprintf(stdout, "\nPCap dump file: %s",
01318           (config->OutDumpFileName ==
01319            NULL) ? "<none>" : config->OutDumpFileName);
01320   fprintf(stdout, "\nDot output filename: %s",
01321           (config->OutDotFileName ==
01322            NULL) ? "<none>" : config->OutDotFileName);
01323 
01324   fprintf(stdout, "\nChannel scan : %d", config->SingleChannel);
01325   if (config->SingleChannel == 0)
01326     fprintf(stdout, " (All channels)");
01327   fprintf(stdout, "\nSleep between channel hop: %d",
01328           config->TimeToSleepBeforeChangeChannel);
01329 
01330   fprintf(stdout, "\nMax packets before quit: %d",
01331           (int) config->MaxPacket);
01332   if (!config->MaxPacket)
01333     fprintf(stdout, " (Don't quit)");
01334   fprintf(stdout, "\nDate format: %s",
01335           (config->DateFormat) ? "Timestamp" : "Human readable");
01336   fprintf(stdout, "\nCurses Screen size detection: %s",
01337           (config->CheckScreenSize) ? "Enabled" : "Disabled");
01338   fprintf(stdout, "\nIDS active: %s",
01339           (config->IDS_is_ON) ? "Enabled" : "Disabled");
01340   fprintf(stdout, "\nSend IDS alert to Syslog: %s\n",
01341           (config->SendAlert2Syslog) ? "Enabled" : "Disabled");
01342 
01343 // Add channels per second scan info.
01344 }
01345 
01346 
01347 
01351 void ChannelToStr(char *strChannel, UINT8 Channel, UINT8 SChannel)
01352 {
01353   if (Channel == 0) {
01354     sprintf(strChannel, "%02d(%02d)", Channel, SChannel);
01355   } else {
01356     sprintf(strChannel, "%02d(%+02d)", Channel, Channel - SChannel);
01357   }
01358   debug(1, "S-C=%02d-%02d\n", Channel, SChannel);
01359 }
01360 
01361 /***
01362  * Initialisation of Configuration
01363  ***/
01364 void InitConfiguration(ConfigStruct * config)
01365 {
01366   // Configuration declaration
01367   config->SingleChannel = (UINT8) 0;
01368   //config->TimeToSleepBeforeChangeChannel = TIME_TO_SLEEP_BEFORE_CHANGE_CHANNEL;
01369   config->TimeToSleepBeforeChangeChannel = 200; // in ms
01370   config->DebugLevel = (UINT8) 0;
01371   config->ChannelHop = (UINT8) 5;
01372   config->DateFormat = (UINT8) 1;       // 1 is human readable
01373   strcpy(config->devname, "wlan0");
01374   config->TypeOfCard = WLAN_NG_CARD;
01375   config->CheckScreenSize = TRUE;
01376   config->SendAlert2Syslog = FALSE;
01377   config->DoNotDisplay = (UINT8) 0;     // 0000 0000
01378   //                                          | |||\_Ack
01379   //                                          | ||\__Beacon
01380   //                                          | |\___Control
01381   //                                          | \____Data
01382   //                                          \______Station
01383 }

Generated on Fri Feb 25 12:02:37 2005 for WifiScanner by  doxygen 1.4.1