?? iw-info.c.svn-base
字號:
/*
* iw-info. Outputs wireless interface info in JSON format.
*
* Based on Wireless Tools, see
* <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html/>
*
* Copyright (c) 1997-2007 Jean Tourrilhes <jt@hpl.hp.com>
* Copyright (C) 2008 OpenRB.com
*
* 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 1 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef __user
#define __user
#endif
#define KILO 1e3
#define MEGA 1e6
#define GIGA 1e9
#define LOG10_MAGIC 1.25892541179
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/types.h>
#include <wireless.h>
typedef struct iw_range iwrange;
typedef struct iw_freq iwfreq;
inline int iw_get_ext(int skfd, const char * ifname, int request, struct iwreq * pwrq) {
strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
return(ioctl(skfd, request, pwrq));
}
int iw_get_range_info(int skfd, const char * ifname, iwrange * range) {
struct iwreq wrq;
char buffer[sizeof(iwrange) * 2];
bzero(buffer, sizeof(buffer));
wrq.u.data.pointer = (caddr_t) buffer;
wrq.u.data.length = sizeof(buffer);
wrq.u.data.flags = 0;
if (iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0) {
return -1;
}
memcpy((char *) range, buffer, sizeof(iwrange));
return 0;
}
double iw_freq2float(const iwfreq * in) {
int i;
double res = (double) in->m;
for(i = 0; i < in->e; i++) {
res *= 10;
}
return res;
}
double iw_format_bitrate(int bitrate) {
double rate = (double) bitrate;
int divisor;
if (rate >= GIGA) {
divisor = GIGA;
}
else if(rate >= MEGA) {
divisor = MEGA;
}
else {
divisor = KILO;
}
return (double) (rate / divisor);
}
int iw_mwatt2dbm(int in) {
double fin = (double) in;
int res = 0;
while (fin > 10.0) {
res += 10;
fin /= 10.0;
}
while (fin > 1.000001) {
res += 1;
fin /= LOG10_MAGIC;
}
return res;
}
int iw_dbm2mwatt(int in) {
int ip = in / 10;
int fp = in % 10;
int k;
double res = 1.0;
for (k = 0; k < ip; k++) {
res *= 10;
}
for(k = 0; k < fp; k++) {
res *= LOG10_MAGIC;
}
return (int) res;
}
void print_freq_info(int skfd, char * ifname) {
struct iwreq wrq;
struct iw_range range;
double freq, curfreq = 0;
int k, curchan = -1;
if (iw_get_range_info(skfd, ifname, &range) < 0) {
printf("\"channels\": null, \"chan\": null, \"freq\": null, ");
}
else {
if (iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) >= 0) {
curfreq = iw_freq2float(&(wrq.u.freq));
printf("\"freq\": %g, ", wrq.u.freq.i, (curfreq < KILO ? curfreq : curfreq / MEGA));
}
else {
printf("\"freq\": null, ");
}
printf("\"channels\": ");
if (range.num_frequency > 0) {
printf("{");
for (k = 0; k < range.num_frequency; k++) {
freq = iw_freq2float(&(range.freq[k]));
printf("%s\"%d\": %g", (k > 0 ? ", " : ""), range.freq[k].i, (freq < KILO ? freq : freq / MEGA));
if (curfreq == freq) {
curchan = range.freq[k].i;
}
}
printf("}, ");
}
if (curchan < 0) {
printf("\"chan\": null, ");
}
else {
printf("\"chan\": %d, ", curchan);
}
}
}
void print_bitrate_info(int skfd, char * ifname) {
struct iwreq wrq;
struct iw_range range;
int k;
printf("\"bitrates\": ");
if (iw_get_range_info(skfd, ifname, &range) < 0) {
printf("null, \"bitrate\": null, ");
}
else {
if ((range.num_bitrates > 0) && (range.num_bitrates <= IW_MAX_BITRATES)) {
printf("[");
for (k = 0; k < range.num_bitrates; k++) {
printf("%s%g", (k > 0 ? ", " : ""), iw_format_bitrate(range.bitrate[k]));
}
printf("], ");
}
else {
printf("null, ");
}
printf("\"bitrate\": ");
if (iw_get_ext(skfd, ifname, SIOCGIWRATE, &wrq) >= 0) {
printf("%g, ", iw_format_bitrate(wrq.u.bitrate.value));
}
else {
printf("null, ");
}
}
}
void print_txpower_info(int skfd, char * ifname) {
struct iwreq wrq;
struct iw_range range;
int dbm, k;
printf("\"txpowers\": ");
if (iw_get_range_info(skfd, ifname, &range) < 0) {
printf("null, \"txpower\": null");
}
else {
if ((range.num_txpower <= 0) || (range.num_txpower > IW_MAX_TXPOWER)) {
printf("null, ");
}
else {
printf("[");
for (k = 0; k < range.num_txpower; k++) {
if (range.txpower_capa & IW_TXPOW_MWATT) {
dbm = iw_mwatt2dbm(range.txpower[k]);
}
else {
dbm = range.txpower[k];
}
printf("%s%d", (k > 0 ? ", " : ""), dbm);
}
printf("], ");
}
printf("\"txpower\": ");
if (iw_get_ext(skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0) {
if (wrq.u.txpower.disabled) {
printf("null");
}
else {
if (wrq.u.txpower.flags & IW_TXPOW_MWATT) {
dbm = iw_mwatt2dbm(wrq.u.txpower.value);
}
else {
dbm = wrq.u.txpower.value;
}
printf("%d", dbm);
}
}
}
}
int main(int argc, char ** argv) {
int skfd;
printf("{");
if (argc > 1) {
if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
}
else {
print_freq_info(skfd, argv[1]);
print_bitrate_info(skfd, argv[1]);
print_txpower_info(skfd, argv[1]);
close(skfd);
}
}
printf("}");
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -