📄 wlancis.c
字号:
/*
* File : wlancis.c
*
* Program to get the cis info from the wlan driver
*
* Usage: wlancis <ethX> [outfile]
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <linux/wireless.h>
//#include <utils.h>
#ifndef __ATTRIB_PACK__
#define __ATTRIB_PACK__ __attribute__((packed))
#endif
#include "wlan_wext.h"
#ifndef le16_to_cpu
#define le16_to_cpu(x) (x)
#endif
typedef unsigned char cisdata_t;
/* Bits in IRQInfo1 field */
#define IRQ_MASK 0x0f
#define IRQ_NMI_ID 0x01
#define IRQ_IOCK_ID 0x02
#define IRQ_BERR_ID 0x04
#define IRQ_VEND_ID 0x08
#define IRQ_INFO2_VALID 0x10
#define IRQ_LEVEL_ID 0x20
#define IRQ_PULSE_ID 0x40
#define IRQ_SHARE_ID 0x80
/* Return codes */
#define CS_SUCCESS 0x00
#define CS_UNSUPPORTED_FUNCTION 0x15
#define CS_BAD_TUPLE 0x40
#define CISTPL_DEVICE 0x01
#define CISTPL_CONFIG_CB 0x04
#define CISTPL_LINKTARGET 0x13
#define CISTPL_NO_LINK 0x14
#define CISTPL_VERS_1 0x15
#define CISTPL_DEVICE_A 0x17
#define CISTPL_CONFIG 0x1a
#define CISTPL_CFTABLE_ENTRY 0x1b
#define CISTPL_MANFID 0x20
#define CISTPL_FUNCID 0x21
#define CISTPL_FUNCE 0x22
#define CISTPL_END 0xff
#define CISTPL_MAX_DEVICES 4
typedef struct cistpl_device_t {
unsigned char ndev;
struct {
unsigned char type;
unsigned char wp;
unsigned int speed;
unsigned int size;
} dev[CISTPL_MAX_DEVICES];
} cistpl_device_t;
#define CISTPL_VERS_1_MAX_PROD_STRINGS 4
typedef struct cistpl_vers_1_t {
unsigned char major;
unsigned char minor;
unsigned char ns;
unsigned char ofs[CISTPL_VERS_1_MAX_PROD_STRINGS];
char str[254];
} cistpl_vers_1_t;
typedef struct cistpl_manfid_t {
unsigned short manf;
unsigned short card;
} cistpl_manfid_t;
#define CISTPL_FUNCID_NETWORK 0x06
#define CISTPL_SYSINIT_POST 0x01
#define CISTPL_SYSINIT_ROM 0x02
typedef struct cistpl_funcid_t {
unsigned char func;
unsigned char sysinit;
} cistpl_funcid_t;
typedef struct cistpl_funce_t {
unsigned char type;
unsigned char data[0];
} cistpl_funce_t;
/*======================================================================
LAN Function Extension Tuples
======================================================================*/
#define CISTPL_FUNCE_LAN_TECH 0x01
#define CISTPL_FUNCE_LAN_SPEED 0x02
#define CISTPL_FUNCE_LAN_MEDIA 0x03
#define CISTPL_FUNCE_LAN_NODE_ID 0x04
#define CISTPL_FUNCE_LAN_CONNECTOR 0x05
/* LAN technologies */
#define CISTPL_LAN_TECH_ARCNET 0x01
#define CISTPL_LAN_TECH_ETHERNET 0x02
#define CISTPL_LAN_TECH_TOKENRING 0x03
#define CISTPL_LAN_TECH_LOCALTALK 0x04
#define CISTPL_LAN_TECH_FDDI 0x05
#define CISTPL_LAN_TECH_ATM 0x06
#define CISTPL_LAN_TECH_WIRELESS 0x07
typedef struct cistpl_lan_tech_t {
unsigned char tech;
} cistpl_lan_tech_t;
typedef struct cistpl_lan_speed_t {
unsigned int speed;
} cistpl_lan_speed_t;
/* LAN media definitions */
#define CISTPL_LAN_MEDIA_UTP 0x01
#define CISTPL_LAN_MEDIA_STP 0x02
#define CISTPL_LAN_MEDIA_THIN_COAX 0x03
#define CISTPL_LAN_MEDIA_THICK_COAX 0x04
#define CISTPL_LAN_MEDIA_FIBER 0x05
#define CISTPL_LAN_MEDIA_900MHZ 0x06
#define CISTPL_LAN_MEDIA_2GHZ 0x07
#define CISTPL_LAN_MEDIA_5GHZ 0x08
#define CISTPL_LAN_MEDIA_DIFF_IR 0x09
#define CISTPL_LAN_MEDIA_PTP_IR 0x0a
typedef struct cistpl_lan_media_t {
unsigned char media;
} cistpl_lan_media_t;
typedef struct cistpl_lan_node_id_t {
unsigned char nb;
unsigned char id[16];
} cistpl_lan_node_id_t;
typedef struct cistpl_lan_connector_t {
unsigned char code;
} cistpl_lan_connector_t;
/*======================================================================
Configuration Table Entries
======================================================================*/
typedef struct cistpl_config_t {
unsigned char last_idx;
unsigned int base;
unsigned int rmask[4];
unsigned char subtuples;
} cistpl_config_t;
/* These are bits in the 'present' field, and indices in 'param' */
#define CISTPL_POWER_VNOM 0
#define CISTPL_POWER_VMIN 1
#define CISTPL_POWER_VMAX 2
#define CISTPL_POWER_ISTATIC 3
#define CISTPL_POWER_IAVG 4
#define CISTPL_POWER_IPEAK 5
#define CISTPL_POWER_IDOWN 6
#define CISTPL_POWER_HIGHZ_OK 0x01
#define CISTPL_POWER_HIGHZ_REQ 0x02
typedef struct cistpl_power_t {
unsigned char present;
unsigned char flags;
unsigned int param[7];
} cistpl_power_t;
typedef struct cistpl_timing_t {
unsigned int wait, waitscale;
unsigned int ready, rdyscale;
unsigned int reserved, rsvscale;
} cistpl_timing_t;
#define CISTPL_IO_LINES_MASK 0x1f
#define CISTPL_IO_8BIT 0x20
#define CISTPL_IO_16BIT 0x40
#define CISTPL_IO_RANGE 0x80
#define CISTPL_IO_MAX_WIN 16
typedef struct cistpl_io_t {
unsigned char flags;
unsigned char nwin;
struct {
unsigned int base;
unsigned int len;
} win[CISTPL_IO_MAX_WIN];
} cistpl_io_t;
typedef struct cistpl_irq_t {
unsigned int IRQInfo1;
unsigned int IRQInfo2;
} cistpl_irq_t;
#define CISTPL_MEM_MAX_WIN 8
typedef struct cistpl_mem_t {
unsigned char flags;
unsigned char nwin;
struct {
unsigned int len;
unsigned int card_addr;
unsigned int host_addr;
} win[CISTPL_MEM_MAX_WIN];
} cistpl_mem_t;
#define CISTPL_CFTABLE_DEFAULT 0x0001
#define CISTPL_CFTABLE_BVDS 0x0002
#define CISTPL_CFTABLE_WP 0x0004
#define CISTPL_CFTABLE_RDYBSY 0x0008
#define CISTPL_CFTABLE_MWAIT 0x0010
#define CISTPL_CFTABLE_AUDIO 0x0800
#define CISTPL_CFTABLE_READONLY 0x1000
#define CISTPL_CFTABLE_PWRDOWN 0x2000
typedef struct cistpl_cftable_entry_t {
unsigned char index;
unsigned short flags;
unsigned char interface;
cistpl_power_t vcc, vpp1, vpp2;
cistpl_timing_t timing;
cistpl_io_t io;
cistpl_irq_t irq;
cistpl_mem_t mem;
unsigned char subtuples;
} cistpl_cftable_entry_t;
typedef union cisparse_t {
cistpl_device_t device;
cistpl_vers_1_t version_1;
cistpl_manfid_t manfid;
cistpl_funcid_t funcid;
cistpl_funce_t funce;
cistpl_config_t config;
cistpl_cftable_entry_t cftable_entry;
} cisparse_t;
typedef struct tuple_t {
unsigned int CISOffset; /* internal use */
cisdata_t TupleCode;
cisdata_t TupleLink;
cisdata_t TupleOffset;
cisdata_t TupleDataMax;
cisdata_t TupleDataLen;
cisdata_t *TupleData;
} tuple_t;
#define CISTPL_MAX_CIS_SIZE 0x200
typedef struct tuple_parse_t {
tuple_t tuple;
cisdata_t data[255];
cisparse_t parse;
} tuple_parse_t;
void hexdump(char *prompt, void *p, int len, char delim)
{
int i;
unsigned char *s = p;
printf("%s : ", prompt);
for (i = 0; i < len; i++) {
if (i != len - 1)
printf("%02x%c", *s++, delim);
else
printf("%02x\n", *s);
}
}
static char *usage[] = {
"Usage: wlancis <ethX> [outputfile]",
};
void display_usage(void)
{
int i;
for (i = 0; i < (sizeof(usage) / sizeof(usage[0])); i++)
fprintf(stderr, "%s\n", usage[i]);
}
static char indent[10] = " ";
#ifdef DEBUG
static void print_tuple(tuple_parse_t *tup)
{
int i;
printf("%soffset 0x%2.2x, tuple 0x%2.2x, link 0x%2.2x\n",
indent, tup->tuple.CISOffset, tup->tuple.TupleCode,
tup->tuple.TupleLink);
for (i = 0; i < tup->tuple.TupleDataLen; i++) {
if ((i % 16) == 0) printf("%s ", indent);
printf("%2.2x ", (unsigned char)tup->data[i]);
if ((i % 16) == 15) putchar('\n');
}
if ((i % 16) != 0) putchar('\n');
}
#endif /* DEBUG */
static void print_funcid(cistpl_funcid_t *fn)
{
printf("%sfuncid ", indent);
switch (fn->func) {
case CISTPL_FUNCID_NETWORK:
printf("network_adapter"); break;
default:
printf("unknown");
break;
}
if (fn->sysinit & CISTPL_SYSINIT_POST)
printf(" [post]");
if (fn->sysinit & CISTPL_SYSINIT_ROM)
printf(" [rom]");
putchar('\n');
}
static void print_size(unsigned int size)
{
if (size < 1024)
printf("%ub", size);
else if (size < 1024*1024)
printf("%ukb", size/1024);
else
printf("%umb", size/(1024*1024));
}
static void print_unit(unsigned int v, char *unit, char tag)
{
int n;
for (n = 0; (v % 1000) == 0; n++) v /= 1000;
printf("%u", v);
if (n < strlen(unit)) putchar(unit[n]);
putchar(tag);
}
static void print_time(unsigned int tm, unsigned long scale)
{
print_unit(tm * scale, "num", 's');
}
static void print_volt(unsigned int vi)
{
print_unit(vi * 10, "um", 'V');
}
static void print_current(unsigned int ii)
{
print_unit(ii / 10, "um", 'A');
}
static void print_speed(unsigned int b)
{
if (b < 1000)
printf("%u bits/sec", b);
else if (b < 1000000)
printf("%u kb/sec", b/1000);
else
printf("%u mb/sec", b/1000000);
}
static const char *dtype[] = {
"NULL", "ROM", "OTPROM", "EPROM", "EEPROM", "FLASH", "SRAM",
"DRAM", "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", "fn_specific",
"extended", "rsvd"
};
static void print_device(cistpl_device_t *dev)
{
int i;
for (i = 0; i < dev->ndev; i++) {
printf("%s %s ", indent, dtype[dev->dev[i].type]);
printf("%uns, ", dev->dev[i].speed);
print_size(dev->dev[i].size);
putchar('\n');
}
if (dev->ndev == 0)
printf("%s no_info\n", indent);
}
static void print_power(char *tag, cistpl_power_t *power)
{
int i, n;
for (i = n = 0; i < 8; i++)
if (power->present & (1<<i)) n++;
i = 0;
printf("%s %s", indent, tag);
if (power->present & (1<<CISTPL_POWER_VNOM)) {
printf(" Vnom "); i++;
print_volt(power->param[CISTPL_POWER_VNOM]);
}
if (power->present & (1<<CISTPL_POWER_VMIN)) {
printf(" Vmin "); i++;
print_volt(power->param[CISTPL_POWER_VMIN]);
}
if (power->present & (1<<CISTPL_POWER_VMAX)) {
printf(" Vmax "); i++;
print_volt(power->param[CISTPL_POWER_VMAX]);
}
if (power->present & (1<<CISTPL_POWER_ISTATIC)) {
printf(" Istatic "); i++;
print_current(power->param[CISTPL_POWER_ISTATIC]);
}
if (power->present & (1<<CISTPL_POWER_IAVG)) {
if (++i == 5) printf("\n%s ", indent);
printf(" Iavg ");
print_current(power->param[CISTPL_POWER_IAVG]);
}
if (power->present & (1<<CISTPL_POWER_IPEAK)) {
if (++i == 5) printf("\n%s ", indent);
printf(" Ipeak ");
print_current(power->param[CISTPL_POWER_IPEAK]);
}
if (power->present & (1<<CISTPL_POWER_IDOWN)) {
if (++i == 5) printf("\n%s ", indent);
printf(" Idown ");
print_current(power->param[CISTPL_POWER_IDOWN]);
}
if (power->flags & CISTPL_POWER_HIGHZ_OK) {
if (++i == 5) printf("\n%s ", indent);
printf(" [highz OK]");
}
if (power->flags & CISTPL_POWER_HIGHZ_REQ) {
printf(" [highz]");
}
putchar('\n');
}
static void print_cftable_entry(cistpl_cftable_entry_t *entry)
{
int i;
printf("%scftable_entry 0x%2.2x%s\n", indent, entry->index,
(entry->flags & CISTPL_CFTABLE_DEFAULT) ? " [default]" : "");
if (entry->flags & ~CISTPL_CFTABLE_DEFAULT) {
printf("%s ", indent);
if (entry->flags & CISTPL_CFTABLE_BVDS)
printf(" [bvd]");
if (entry->flags & CISTPL_CFTABLE_WP)
printf(" [wp]");
if (entry->flags & CISTPL_CFTABLE_RDYBSY)
printf(" [rdybsy]");
if (entry->flags & CISTPL_CFTABLE_MWAIT)
printf(" [mwait]");
if (entry->flags & CISTPL_CFTABLE_AUDIO)
printf(" [audio]");
if (entry->flags & CISTPL_CFTABLE_READONLY)
printf(" [readonly]");
if (entry->flags & CISTPL_CFTABLE_PWRDOWN)
printf(" [pwrdown]");
putchar('\n');
}
if (entry->vcc.present)
print_power("Vcc", &entry->vcc);
if (entry->vpp1.present)
print_power("Vpp1", &entry->vpp1);
if (entry->vpp2.present)
print_power("Vpp2", &entry->vpp2);
if ((entry->timing.wait != 0) || (entry->timing.ready != 0) ||
(entry->timing.reserved != 0)) {
printf("%s timing", indent);
if (entry->timing.wait != 0) {
printf(" wait ");
print_time(entry->timing.wait, entry->timing.waitscale);
}
if (entry->timing.ready != 0) {
printf(" ready ");
print_time(entry->timing.ready, entry->timing.rdyscale);
}
if (entry->timing.reserved != 0) {
printf(" reserved ");
print_time(entry->timing.reserved,
entry->timing.rsvscale);
}
putchar('\n');
}
if (entry->io.nwin) {
cistpl_io_t *io = &entry->io;
printf("%s io", indent);
for (i = 0; i < io->nwin; i++) {
if (i) putchar(',');
printf(" 0x%4.4x-0x%4.4x", io->win[i].base,
io->win[i].base+io->win[i].len-1);
}
printf(" [lines=%d]", io->flags & CISTPL_IO_LINES_MASK);
if (io->flags & CISTPL_IO_8BIT) printf(" [8bit]");
if (io->flags & CISTPL_IO_16BIT) printf(" [16bit]");
if (io->flags & CISTPL_IO_RANGE) printf(" [range]");
putchar('\n');
}
if (entry->irq.IRQInfo1) {
printf("%s irq ", indent);
if (entry->irq.IRQInfo1 & IRQ_INFO2_VALID)
printf("mask 0x%04x", entry->irq.IRQInfo2);
else
printf("%u", entry->irq.IRQInfo1 & IRQ_MASK);
if (entry->irq.IRQInfo1 & IRQ_LEVEL_ID) printf(" [level]");
if (entry->irq.IRQInfo1 & IRQ_PULSE_ID) printf(" [pulse]");
if (entry->irq.IRQInfo1 & IRQ_SHARE_ID) printf(" [shared]");
putchar('\n');
}
if (entry->mem.nwin) {
cistpl_mem_t *mem = &entry->mem;
printf("%s memory", indent);
for (i = 0; i < mem->nwin; i++) {
if (i) putchar(',');
printf(" 0x%4.4x-0x%4.4x @ 0x%4.4x",
mem->win[i].card_addr,
mem->win[i].card_addr + mem->win[i].len-1,
mem->win[i].host_addr);
}
putchar('\n');
}
if (entry->subtuples)
printf("%s %d bytes in subtuples\n", indent, entry->subtuples);
}
static const char *tech[] = {
"undefined", "ARCnet", "ethernet", "token_ring",
"localtalk", "FDDI/CDDI", "ATM", "wireless"
};
static const char *media[] = {
"undefined", "unshielded_twisted_pair", "shielded_twisted_pair",
"thin_coax", "thick_coax", "fiber", "900_MHz", "2.4_GHz",
"5.4_GHz", "diffuse_infrared", "point_to_point_infrared"
};
static void print_network(cistpl_funce_t *funce)
{
cistpl_lan_tech_t *t;
cistpl_lan_speed_t *s;
cistpl_lan_media_t *m;
cistpl_lan_node_id_t *n;
cistpl_lan_connector_t *c;
int i;
switch (funce->type) {
case CISTPL_FUNCE_LAN_TECH:
t = (cistpl_lan_tech_t *)(funce->data);
printf("%slan_technology %s\n", indent, tech[t->tech]);
break;
case CISTPL_FUNCE_LAN_SPEED:
s = (cistpl_lan_speed_t *)(funce->data);
printf("%slan_speed ", indent);
print_speed(s->speed);
putchar('\n');
break;
case CISTPL_FUNCE_LAN_MEDIA:
m = (cistpl_lan_media_t *)(funce->data);
printf("%slan_media %s\n", indent, media[m->media]);
break;
case CISTPL_FUNCE_LAN_NODE_ID:
n = (cistpl_lan_node_id_t *)(funce->data);
printf("%slan_node_id", indent);
for (i = 0; i < n->nb; i++)
printf(" %02x", n->id[i]);
putchar('\n');
break;
case CISTPL_FUNCE_LAN_CONNECTOR:
c = (cistpl_lan_connector_t *)(funce->data);
printf("%slan_connector ", indent);
if (c->code == 0)
printf("Open connector standard\n");
else
printf("Closed connector standard\n");
break;
}
}
static void print_vers_1(cistpl_vers_1_t *v1)
{
int i, n;
char s[32];
sprintf(s, "%svers_1 %d.%d", indent, v1->major, v1->minor);
printf("%s", s);
n = strlen(s);
for (i = 0; i < v1->ns; i++) {
if (n + strlen(v1->str + v1->ofs[i]) + 4 > 72) {
n = strlen(indent) + 2;
printf(",\n%s ", indent);
} else {
printf(", ");
n += 2;
}
printf("\"%s\"", v1->str + v1->ofs[i]);
n += strlen(v1->str + v1->ofs[i]) + 2;
}
putchar('\n');
}
static void print_config(int code, cistpl_config_t *cfg)
{
printf("%sconfig%s base 0x%4.4x", indent,
(code == CISTPL_CONFIG_CB) ? "_cb" : "", cfg->base);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -