airjack.c

Go to the documentation of this file.
00001 /* Linux Prism II Stumbler - Utility Scan for 802_11 networks under Linux
00002  * 
00003  * File : $Name$
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  * Some part of this code is taken from essid_ack.c from aitrjack26
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU General Public License
00012  * as published by the Free Software Foundation; either version 2
00013  * of the License, or (at your option) any later version.
00014  * 
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023  *
00024  * $Id: airjack.c 174 2007-07-25 13:20:29Z poggij $
00025  */
00026 
00027 #include <include.h>
00028 #include <src/airjack.h>
00029 #include <src/wlan-ng.h>
00030 #include <src/functions.h>
00031 #include <src/crt_io.h>
00032 
00033 #ifdef HAVE_LINUX_WIRELESS
00034 #include <net/if.h>
00035 #endif
00036 #include <sys/socket.h>
00037 
00038 #include <features.h>           /* for the glibc version number */
00039 #include <netinet/in.h>
00040 #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
00041 #include <netpacket/packet.h>
00042 #include <net/ethernet.h>       /* the L2 protocols */
00043 #else
00044 #include <asm/types.h>
00045 #include <linux/if_packet.h>
00046 #include <linux/if_ether.h>     /* The L2 protocols */
00047 #endif
00048 
00049 static char *ID = "$Id: airjack.c 174 2007-07-25 13:20:29Z poggij $";
00050 
00051 // All extern value you want
00052 //extern unsigned int DebugLevel;
00053 //extern UINT8 SingleChannel;
00054 //extern UINT8 TypeOfCard;
00055 extern ConfigStruct config;
00056 extern UINT16 NumberOfDetectedClient;
00057 extern ClientInfo_t *ClientInfo;
00058 extern ScanResult_t Res;
00059 
00060 //--- STATIC
00061 static CaptureArg ca;
00062 static char errbuf[PCAP_ERRBUF_SIZE];
00063 static int sockfd;              /* listen and send socket */
00064 static struct ifreq req;
00065 static struct aj_config aj_conf;
00066 
00067 static const UINT8 BroadcastMAC[WLAN_ADDR_LEN] =
00068     { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
00069 
00070 //-------------
00071 int selectChannelAIRJACK(char *devname, int channel)
00072 {
00073 #define STR_MAX 80
00074   int result = 0;
00075 #if 0
00076   char str[STR_MAX];
00077   snprintf(str, STR_MAX, "set_channel -c %d -i %s 2>/dev/null",
00078            channel, devname);
00079   debug(3, "%s\n", str);
00080   result += system(str);
00081 #else
00082   req.ifr_data = (char *) &aj_conf;
00083 
00084   /* populate the structure */
00085   if (ioctl(sockfd, SIOCAJGMODE, &req) < 0) {
00086     return (-4);
00087   }
00088 
00089   aj_conf.channel = channel;
00090   aj_conf.monitor = 1;
00091 
00092   if (ioctl(sockfd, SIOCAJSMODE, &req) < 0) {
00093     return (-4);
00094   }
00095 #endif
00096   return result;
00097 }
00098 
00099 int shutCardAIRJACK(char *devname)
00100 {
00101   return IfconfigSetFlags(devname, IFF_UP);
00102 }
00103 
00104 int openCardAIRJACK(char *devname)
00105 {
00106   int result = 0;
00107   struct sockaddr_ll addr;
00108 
00109   // Turn on monitor mode
00110   result += IfconfigSetFlags(devname, IFF_UP + IFF_PROMISC);
00111 
00112   /* open the link layer socket */
00113   if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
00114     return (-1);
00115   }
00116 
00117   /* get the interface index */
00118   memset(&req, 0, sizeof(struct ifreq));
00119   memset(&aj_conf, 0, sizeof(struct aj_config));
00120   strncpy(req.ifr_name, devname, IFNAMSIZ);
00121 
00122   if (ioctl(sockfd, SIOCGIFINDEX, &req) < 0) {
00123     return (-2);
00124   }
00125 
00126   /* bind the socket to the interface */
00127   memset(&addr, 0, sizeof(struct sockaddr_ll));
00128   addr.sll_ifindex = req.ifr_ifindex;
00129   addr.sll_protocol = htons(ETH_P_ALL);
00130   addr.sll_family = AF_PACKET;
00131   if (bind(sockfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_ll)) <
00132       0) {
00133     return (-3);
00134   }
00135 
00136 
00137   return result;
00138 }
00139 
00140 
00141 // Get packet from card
00142 int getPacketAIRJACK(p80211_caphdr_t * wlan_header, UINT8 * buf, int maxlen)
00143 {
00144   struct pcap_pkthdr pktHdr;
00145   u_char *ret;
00146   fd_set rs;
00147 
00148   FD_ZERO(&rs);
00149   FD_SET(0, &rs);
00150 
00151   ret = (u_char *) pcap_next(ca.pcap, &pktHdr);
00152   // If no problem and packet is enought big (with data)
00153   if ((ret) && (pktHdr.len >= 1)) {
00154     if (memcpy_buff(buf, ret, pktHdr.len) == NULL)
00155       return 0;
00156     // Fill Header
00157     // TODO : find this information in any maner ?!
00158     wlan_header->version = 0;    // It's a reduced capture frame format
00159     wlan_header->length = 0;     // Not used for now
00160     wlan_header->mactime = 0;
00161     wlan_header->hosttime = 0;
00162     wlan_header->phytype = 0;    // Not used for now
00163     wlan_header->channel = 0;
00164     wlan_header->datarate = 0;   // datarate is in units of 100kbps.
00165     wlan_header->antenna = 0;    // Not used for now
00166     wlan_header->priority = 0;   // Not used for now
00167     wlan_header->ssi_type = 0;   // Not used for now
00168     wlan_header->ssi_signal = 0;
00169     wlan_header->ssi_noise = 0;
00170     wlan_header->preamble = 0;   // Not used for now
00171     wlan_header->encoding = 0;   // Not used for now
00172 
00173     return pktHdr.len;
00174   } else {
00175     return (0);                 // Noting to read
00176   }
00177 }
00178 
00179 int openPacketAIRJACK(char *devname)
00180 {
00181   int DataLink;
00182 
00183   ca.pcap = pcap_open_live(devname, 3000, 1, 0, errbuf);
00184   if (ca.pcap) {
00185     pcap_setnonblock(ca.pcap, 1, errbuf);
00186     DataLink = pcap_datalink(ca.pcap);
00187     switch (DataLink) {
00188     case DLT_PRISM_HEADER:
00189       debug(2,
00190             "pcap_datalink(ca.pcap) = %d = DLT_PRISM_HEADER\n", DataLink);
00191       ca.offset = 0x90;
00192       break;
00193     case DLT_IEEE802_11:
00194       debug(2, "pcap_datalink(ca.pcap) = %d = DLT_IEEE802_11\n", DataLink);
00195       ca.offset = 0;
00196       break;
00197     case DLT_AIRONET_HEADER:
00198       debug(2,
00199             "pcap_datalink(ca.pcap) = %d = DLT_AIRONET_HEADER:\n",
00200             DataLink);
00201       ca.offset = 0;
00202       break;
00203     default:                   //COOKED
00204       debug(2, "pcap_datalink(ca.pcap) = %d = COOKED:\n", DataLink);
00205       ca.offset = 160;
00206     }
00207     return 1;
00208   }
00209   return -1;
00210 }
00211 
00212 void closePacketAIRJACK(void)
00213 {
00214   pcap_close(ca.pcap);
00215 }
00216 
00217 void sendDeauth(UINT8 dest[WLAN_ADDR_LEN], UINT8 bssid[WLAN_ADDR_LEN],
00218                 UINT8 channel)
00219 {
00220   struct {
00221     struct a3_80211 hdr;
00222     unsigned short int reason;
00223   } __attribute__ ((packed)) frame;
00224   UINT8 OldChannel = 0;
00225 
00226   /* setup the frame */
00227   memset(&frame, 0, sizeof(frame));
00228   memcpy(frame.hdr.mh_mac1, dest, sizeof(frame.hdr.mh_mac1));
00229   memcpy(frame.hdr.mh_mac2, bssid, sizeof(frame.hdr.mh_mac2));
00230   memcpy(frame.hdr.mh_mac3, bssid, sizeof(frame.hdr.mh_mac3));
00231 
00232   frame.hdr.mh_type = FC_TYPE_MGT;
00233   frame.hdr.mh_subtype = MGT_DEAUTH;
00234   frame.hdr.mh_from_ds = 1;
00235   frame.reason = 2;             /* previous authentication is no longer valid */
00236 
00237   if (channel != 0) {           // Backup channel and change to the channel of the AP
00238     OldChannel = Res.SChannel;
00239     selectChannelAIRJACK(config.devname, channel);
00240   }
00241 
00242   if (write(sockfd, &frame, sizeof(frame)) < 0) {
00243     warning("AIRJACK error : write\n");
00244   }
00245 
00246   debug(2, "Send De-auth -- BSSID: %02X:%02X:%02X:%02X:%02X:%02X --"
00247         " DEST: %02X:%02X:%02X:%02X:%02X:%02X -- Channel: %d\n",
00248         bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
00249         dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], channel);
00250 
00251   if (channel != 0) {           // restore channel
00252     Res.SChannel = OldChannel;
00253     selectChannelAIRJACK(config.devname, OldChannel);
00254   }
00255 }

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