madwifi-ng.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  * 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: MADWIFI-NG.c 145 2006-04-10 08:13:38Z poggij $
00026  */
00027 
00028 
00029 // A lot of think is get from kismet
00030 //  http://www.kismetwireless.net/
00031 
00032 #include <include.h>
00033 #include <src/madwifi-ng.h>
00034 #include <src/wlan-ng.h>
00035 #include <src/crt_io.h>
00036 #include <src/functions.h>
00037 #include <dirent.h>
00038 
00039 static char *ID = "$Id: MADWIFI-NG.c 145 2006-04-10 08:13:38Z poggij $";
00040 
00041 // All extern value you want
00042 //extern unsigned int DebugLevel;
00043 //extern UINT8 SingleChannel;
00044 //extern UINT8 TypeOfCard;
00045 extern ConfigStruct config;
00046 extern WINDOW *Sum_WND, *RealTime_WND;
00047 
00048 static CaptureArg ca;
00049 static char errbuf[PCAP_ERRBUF_SIZE];
00050 
00051 static char devname1[DEVNAME_LEN];      // for madwifi-ng driver, it's ath?
00052 static char devname2[DEVNAME_LEN];      // for madwifi-ng driver, it's wifi?
00053 
00054 int DestroyVAP_MADWIFI_NG(char *ifname);
00055 
00056 #define STR_MAX 256
00057 
00058 //-------------
00059 int selectChannelMADWIFI_NG(char *devname, int channel)
00060 {
00061   int result = 0;
00062 
00063   result = IwconfigSetChannel(devname, channel);
00064 
00065   //return NO_ERROR;                     // XXX no error if channel is forbidden
00066   return result;
00067 }
00068 
00069 int shutCardMADWIFI_NG(char *devname)
00070 {
00071   // Destroy the created VAP
00072   return (DestroyVAP_MADWIFI_NG(devname));
00073 }
00074 
00075 int DestroyVAP_MADWIFI_NG(char *ifname)
00076 {
00077   struct ifreq ifr;
00078   int sock;
00079 
00080   // Connect to the madwifidriver
00081   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00082     warning("Failed to create socket to madwifi: %s\n", strerror(errno));
00083     return MADWIFING_ERROR_CANT_CREATE_SOCKET;
00084   }
00085   // Destroy the VAP
00086   memset(&ifr, 0, sizeof(ifr));
00087   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
00088   if (ioctl(sock, SIOC80211IFDESTROY, &ifr) < 0) {
00089     warning("Failed to destroy VAP: %s\n", strerror(errno));
00090     close(sock);
00091     return MADWIFING_ERROR_CANT_DESTROY_VAP;
00092   }
00093   close(sock);
00094 
00095   return 0;
00096 }
00097 
00098 int findAvailableIF(char *devname)
00099 {
00100   UINT16 n = 0;
00101   struct ifreq ifr;
00102   int skfd;
00103   char tnam[IFNAMSIZ];
00104 
00105   if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00106     warning("Failed to create AF_INET DGRAM socket.\n");
00107     return ERROR_CANT_CREATE_SOCKET;
00108   }
00109 
00110   tnam[0] = '\0';
00111   for (n = 0; (n < 10) && (tnam[0] == '\0'); n++) {
00112     snprintf(tnam, IFNAMSIZ, "ath%d", n);
00113 
00114     memset(&ifr, 0, sizeof(ifr));
00115     strncpy(ifr.ifr_name, tnam, sizeof(ifr.ifr_name) - 1);
00116     if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
00117       debug(3, "Interface %s is free\n", tnam);
00118       // Good it's not an existant IF, so its a free named IF
00119       strncpy(devname, tnam, IFNAMSIZ);
00120       close(skfd);
00121       return NO_ERROR;
00122     } else {
00123       // FOUND an existant IF
00124       // try to find an another free
00125       tnam[0] = '\0';
00126     }
00127   }
00128   close(skfd);
00129 
00130   return ERROR_COULDNT_FIND_A_FREE_IFACE;
00131 }
00132 
00133 int openCardMADWIFI_NG(char *devname)
00134 {
00135   char dirpath[STR_MAX];
00136   DIR *devdir;
00137   struct dirent *devfile;
00138 
00139   struct ieee80211_clone_params {
00140     char icp_name[IFNAMSIZ];
00141     UINT16 icp_opmode;
00142     UINT16 icp_flags;
00143   };
00144 
00145   struct ieee80211_clone_params cp;
00146   struct ifreq ifr;
00147   int sock;
00148 
00149   // -- Search if /sys arborescence is available
00150   snprintf(dirpath, STR_MAX, "/sys/class/net/%s/device/", devname);
00151   if ((devdir = opendir(dirpath)) == NULL) {
00152     warning("Device %s is not present !!!\n", devname);
00153     return MADWIFING_ERROR_NO_DEVICE_PRESENT;
00154   }
00155   // -- Determine ath and wifi interface number
00156   //    and destroy all VAP if exists
00157   while ((devfile = readdir(devdir)) != NULL) {
00158     if (strncmp("net:ath", devfile->d_name, 7) == 0) {
00159       strncpy(devname1, devfile->d_name + 4, IFNAMSIZ);
00160 #if 0
00161       DestroyVAP_MADWIFI_NG(devname1);
00162       debug(3, "Interface %s is destroyed\n", devname1);
00163 #else
00164       debug(3, "Interface %s is skiped\n", devname1);
00165 #endif
00166     }
00167 
00168     if (strncmp("net:wifi", devfile->d_name, 8) == 0) {
00169       strncpy(devname2, devfile->d_name + 4, IFNAMSIZ);
00170       debug(3, "Found a good Interface %s\n", devname2);
00171     }
00172   }
00173   closedir(devdir);
00174 
00175   // Now all is clean
00176   // We can create a VAP
00177 
00178   // First Step : Find a ath? interface available
00179   if (findAvailableIF(devname1) != 0) {
00180     warning("No available VAP found :-(\n");
00181     return MADWIFING_ERROR_NO_INTERFACE_AVAILABLE;
00182   }
00183   // Master interface is now devname2
00184   strncpy(devname, devname2, IFNAMSIZ);
00185   debug(3,
00186         "We now use %s as the master insterface for madwifi-ng driver\n",
00187         devname);
00188 
00189   // Second Step Create VAP and put it in MONITOR mode
00190   memset(&cp, 0, sizeof(cp));
00191   strncpy(cp.icp_name, devname1, IFNAMSIZ);
00192   cp.icp_opmode = IEEE80211_M_MONITOR;
00193   cp.icp_flags = IEEE80211_CLONE_BSSID;
00194 
00195   memset(&ifr, 0, sizeof(ifr));
00196   strncpy(ifr.ifr_name, devname2, IFNAMSIZ);
00197   ifr.ifr_data = (caddr_t) & cp;
00198 
00199   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00200     warning("Failed to create socket to madwifi: %s\n", strerror(errno));
00201     return MADWIFING_ERROR_CANT_CREATE_SOCKET;
00202   }
00203 
00204   if (ioctl(sock, SIOC80211IFCREATE, &ifr) < 0) {
00205     warning("Unable to create VAP: %s\n", strerror(errno));
00206     close(sock);
00207     return MADWIFING_ERROR_NO_VAP_CREATED;
00208   }
00209 
00210   strncpy(devname1, ifr.ifr_name, IFNAMSIZ);
00211   debug(3, "I create a VAP in monitor mode in %s\n", ifr.ifr_name);
00212   close(sock);
00213 
00214   // Slave interface and working interface is now the same
00215   strncpy(devname, devname1, IFNAMSIZ);
00216   debug(3, "We now use %s as the slave insterface for madwifi-ng driver\n",
00217         devname1);
00218 
00219   // last step : UP the interface
00220   return IfconfigSetFlags(devname, IFF_UP);
00221 }
00222 
00223 /*
00224  * Get packet from card
00225  * return the number of byte read
00226  */
00227 int getPacketMADWIFI_NG(p80211_caphdr_t * wlan_header, UINT8 * buf, int maxlen)
00228 {
00229   struct pcap_pkthdr pktHdr;
00230   u_char *RadioPacket;
00231   fd_set rs;
00232   int real_size_of_headers = 0;
00233 
00234   FD_ZERO(&rs);
00235   FD_SET(0, &rs);
00236 
00237   RadioPacket = (u_char *) pcap_next(ca.pcap, &pktHdr);
00238 
00239   if (RadioPacket != NULL) {
00240   // If no problem and packet is enought big (with data)
00241     if (pktHdr.len >= sizeof(p80211msg_lnxind_wlansniffrm_t)) {
00242       if (pktHdr.len > MAX_BUFFER_SIZE) {
00243   debug(1, "ERROR : Packet is TOOO BIG size=%d\n", pktHdr.len);
00244   //DumpHexPaquets(RealTime_WND, buf, 0x1B0);
00245   return 0;
00246       } else {
00247   real_size_of_headers = FillRadioData(wlan_header, ca.DataLink, RadioPacket, pktHdr.len);
00248   memcpy_buff(buf, (RadioPacket + real_size_of_headers), MIN_OF((pktHdr.len - real_size_of_headers), maxlen));
00249   return MAX_OF(0, (pktHdr.len - real_size_of_headers));
00250       }
00251     }
00252   }
00253   return (0);                   /* Noting to read */
00254 }
00255 
00256 int openPacketMADWIFI_NG(char *devname)
00257 {
00258   ca.pcap = pcap_open_live(devname, 3000, 1, 0, errbuf);
00259   if (ca.pcap) {
00260     pcap_setnonblock(ca.pcap, 1, errbuf);
00261     ca.DataLink = pcap_datalink(ca.pcap);
00262     ca.offset = CalculateOffset(ca.DataLink);
00263     return NO_ERROR;
00264   }
00265   return ERROR_CANT_OPEN_PCAP;
00266 }
00267 
00268 void closePacketMADWIFI_NG(void)
00269 {
00270   pcap_close(ca.pcap);
00271 }

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