⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iw-info.c.svn-base

📁 嵌入式无线路由系统openwrt的web配置工具
💻 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 + -