1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
/* horst - Highly Optimized Radio Scanning Tool
*
* Copyright (C) 2005-2016 Bruno Randolf (br1@einfach.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/wireless.h>
#include "main.h"
#include "util.h"
extern int mon; /* monitoring socket */
static bool wext_set_freq(int fd, const char* devname, int freq)
{
struct iwreq iwr;
memset(&iwr, 0, sizeof(iwr));
strncpy(iwr.ifr_name, devname, IFNAMSIZ - 1);
iwr.ifr_name[IFNAMSIZ - 1] = '\0';
freq *= 100000;
iwr.u.freq.m = freq;
iwr.u.freq.e = 1;
if (ioctl(fd, SIOCSIWFREQ, &iwr) < 0) {
printlog("ERROR: wext set channel");
return false;
}
return true;
}
static int wext_get_freq(int fd, const char* devname)
{
struct iwreq iwr;
memset(&iwr, 0, sizeof(iwr));
strncpy(iwr.ifr_name, devname, IFNAMSIZ - 1);
iwr.ifr_name[IFNAMSIZ - 1] = '\0';
if (ioctl(fd, SIOCGIWFREQ, &iwr) < 0)
return 0;
DEBUG("FREQ %d %d\n", iwr.u.freq.m, iwr.u.freq.e);
return iwr.u.freq.m;
}
static int wext_get_channels(int fd, const char* devname,
struct channel_list* channels)
{
struct iwreq iwr;
struct iw_range range;
int i;
int band0cnt = 0;
int band1cnt = 0;
memset(&iwr, 0, sizeof(iwr));
memset(&range, 0, sizeof(range));
strncpy(iwr.ifr_name, devname, IFNAMSIZ - 1);
iwr.ifr_name[IFNAMSIZ - 1] = '\0';
iwr.u.data.pointer = (caddr_t) ⦥
iwr.u.data.length = sizeof(range);
iwr.u.data.flags = 0;
if (ioctl(fd, SIOCGIWRANGE, &iwr) < 0) {
printlog("ERROR: wext get channel list");
return 0;
}
if (range.we_version_compiled < 16) {
printlog("ERROR: wext version %d too old to get channels",
range.we_version_compiled);
return 0;
}
for (i = 0; i < range.num_frequency && i < MAX_CHANNELS; i++) {
DEBUG(" Channel %.2d: %dMHz\n", range.freq[i].i, range.freq[i].m);
channels->chan[i].chan = range.freq[i].i;
/* different drivers return different frequencies
* (e.g. ipw2200 vs mac80211) try to fix them up here */
if (range.freq[i].m > 100000000)
channels->chan[i].freq = range.freq[i].m / 100000;
else
channels->chan[i].freq = range.freq[i].m;
if (channels->chan[i].freq <= 2500)
band0cnt++;
else
band1cnt++;
}
channels->num_channels = i;
channels->num_bands = band1cnt > 0 ? 2 : 1;
channels->band[0].num_channels = band0cnt;
channels->band[1].num_channels = band1cnt;
return i;
}
/*
* ifctrl.h implementation
*/
bool ifctrl_init(void)
{
return true;
};
void ifctrl_finish(void)
{
};
bool ifctrl_iwadd_monitor(__attribute__((unused)) const char *interface,
__attribute__((unused)) const char *monitor_interface)
{
printlog("add monitor: not supported with WEXT");
return false;
}
bool ifctrl_iwdel(__attribute__((unused)) const char *interface)
{
printlog("del: not supported with WEXT");
return false;
}
bool ifctrl_iwset_monitor(__attribute__((unused)) const char *interface)
{
printlog("set monitor: not supported with WEXT");
return false;
}
bool ifctrl_iwset_freq(const char *const interface,
unsigned int freq,
__attribute__((unused)) enum chan_width width,
__attribute__((unused)) unsigned int center1)
{
if (wext_set_freq(mon, interface, freq))
return true;
return false;
}
bool ifctrl_iwget_interface_info(const char *interface)
{
conf.if_freq = wext_get_freq(mon, interface);
if (conf.if_freq == 0)
return false;
return true;
}
bool ifctrl_iwget_freqlist(__attribute__((unused)) int phy, struct channel_list* channels)
{
if (wext_get_channels(mon, conf.ifname, channels))
return true;
return false;
}
bool ifctrl_is_monitor(void)
{
return true; /* assume yes */
}
|