Madwifi驱动工作在AP模式下时,可以在/proc/net/madwifi/ath0/associated_sta文件中得到所有接入的用户的MAC地址、实时平均RSSI,和last_rx三个信息。其中RSSI是指在一秒内AP接收到的来自该用户的包的RSSI的平均值。有一件极具挑战的事情,就是把每个包到达网卡时,网卡检测到的RSSI读取出来。

网卡每一秒钟将发送一个事件通知,由内核(kernel)处理,在事件处理函数中,将RSSI写到文件中。而在应用层看到的RSSI,是写入文件之后的内容。

既然associated_sta中的RSSI是均值,那么必有求均值的过程,不是在内核就是在硬件的驱动中。于是搞清楚以下几个问题,也就可以修改源代码了:

  1,求均值的代码在哪?网卡写到kernel的,是RSSI均值,还是所有包的RSSI?如果是前者,则还需往下找。

  2,触发事件通知的对象是谁?该对象可能有我们要的RSSI。

1.

我首先用grep进行全文检索,找到了“associated_sta”出现的位置:

ieee80211_linux.c line 838:

  /*Create a proc entry listing the associated stations*/

  ieee80211_proc_vcreate(vap, &proc_ieee80211_ops, "associated_sta");

进而找到函数ieee80211_proc_vcreate的定义,也在linux.c中:

ieee80211_linux.c line 868:

  /*Register a proc entry under the vap directory*/

2.

那么一个proc entry结构体包含什么呢?

ieee80211_var.h line 565:

  struct ieee80211_proc_entry{

    char * name;

    struct fileoperations * fileops;

    struct proc_dir_entry * entry;

    struct ieee80211_proc_entry * next;

  }

看到next方知,原来,entry处于一个链表中。

3,回到ieee80211_proc_vcreate函数体:

909:  entry->name = name; (也就是文件名,放在了entry结构体中,下面追踪entry)

923:  if (!tmp){

      vap->iv_proc_entries = entry;

    }else{

      tmp->next = entry;

    }

然后函数返回0;

4. 调用完函数,继续看

ieee80211_linux.c:

840:  /*Register any other proc entries that have been registered*/ 注册其他已注册过的proc entry。

而这一切都在函数ieee80211_virtfs_latevattach中。使用它的是:

1000:

  switch(event){

  case NETDEV_CHANGENAME:

    ieee80211_virtfs_vdetach( netdev_priv(dev) );

    ieee80211_virtfs_latevattach( netdev_priv(dev) );

    return NOTIFY_DONE;

  }

  default: break;

注意到NOTIFY_DONE。就是说通过ieee80211_virtfs_latevattach函数处理完了事件通知。而这段代码正是在事件处理函数ieee80211_dev_event_notifier中。

事件处理函数需要通过函数register_netdevice_notifier进行注册,以在事件通知出现时正确地被调用。

5. 沿着函数ieee80211_dev_event_notifier继续往上找,就是init-wlan以及module_init等接近上层核心内容的东西了,但是与我们的目标RSSI无关。

6. 于是需要往下找,找到编译到kernel中的madwifi驱动把什么内容(数据)通过事件通知链,以事件通知处理的方式(类似于终端服务程序)写入到了文件中。

回到写文件这个过程:

7. associated_sta 文件的格式是:

macaddr: <XX:XX:XX:XX:XX:XX>

rssi XX

last_rx XX

于是查找"macaddr: <":

还是ieee80211_linux.c:

426:  static int

  proc_read_nodes (struct ieee80211vap * vap, char * buf, int space)

  {

  ....

  p+=sprintf(p, "macaddr: <" MAC_FMT ">\n", ni->ni_macaddr);

  p+=sprintf(p, " rssi <" MAC_FMT ">\n", ni->ni_rssi);

  }

看来,RSSI均值保存在ni结构体中。接下来找ni的赋值过程,尤其是ni->ni_rssi的赋值。实际上,要写入到associated_sta文件中的RSSI值等数据,都是直接通过指针传给ieee80211_rcv_dev_event这个事件处理函数的。那么是谁传给它的呢?

8. 顺着ni和nt找下去:

ieee80211_node.c:

2337:

  ieee80211_getrssi (struct ieee80211com* ic)

  {

    ...

    switch (ic->ic_opmode){

    case IEEE80211_M_IBSS:

      TAILQ_FOREACH(ni, &nt->mode, ni_list)

        if (ni->ni->capinfo & ... ){

          rssi_samples++;                  //计数器

          rssi_total += ic->ic_node_getrssi(ni);

        }

    case IEEE80211_M_AHDEMO: // adhoc模式

      (同上)

    case IEEE80211_M_HOSTAP: // AP模式

      (同上)

    case IEEE80211_M_MONITOR: // monitor模式

    case IEEE80211_M_STA:        // station模式

    default:

      (同上)

    }

  }

在Ad-hoc模式、AP模式下,均有RSSI的处理,而MONITOR模式则没有。实际上这是一段用来评估信道的代码,这里的RSSI指的是全部节点的“平均”RSSI的“平均”值。这样一个RSSI主要用于信道的扫描,评估和选择,后来我发现这段代码只在初始化时由ath_attach(间接)调用,以及在iwconfig中被调用。此外,CSMA/CA,即载波侦听接入控制协议,也包含了RSSI侦听的过程。类似的,这些都不是我们想要的。上面的代码中,total+=里的东西实际上是一个node的平均rssi。

Oh no。那么这不是我们想要的,就需要继续寻找。 找到ni->ni_rssi的赋值语句:

9. ieee80211_input.c line 300+,有一个同名的函数ieee80211_input(...., int rssi, ....).在此函数里有多处rssi的赋值。

418: if (IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr) ) {

    ni->ni_rssi = rssi;

    ni->ni_rtsf = rtfs;

    ni->ni_last_rx = jiffies;

    //在这边加上输出:

    printk("<0>"MAC_FMT" %d\n", MAC_ADDR(...), rssi);

}

得到的结果是,一旦有客户连接到AP下,这里就开始刷屏式地打印出既定的信息。搞定!

转载于:https://www.cnblogs.com/zhchngzng/p/3735975.html

Madwifi Mad coding:自底向上分析associated_sta的更新过程 —— RSSI和MACADDR等信息获取的底层原理...相关推荐

  1. SWF代码分析与破解之路 (YueTai VIP视频信息获取工具) Socket续篇

    引言 上一篇 <Socket与站点保密应用 (隐藏链接的视频下载)>大大咧咧地从 WEB 讲 Socket.再到 TCP/IP 等协议,又再讲到 Wireshark 怎样抓IP包分析.最还 ...

  2. 编译原理(六)自底向上分析之LR分析法

    自底向上分析之LR分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本概念 1. LR分析:从左到右扫描(L)自底向上进行规约(R),是规范规约,也即最右推导(规范推导) ...

  3. 编译原理(五)自底向上分析之算符优先分析法

    自底向上分析之算符优先分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本过程 1. 一般方法:采用自左向右地扫描和分析输入串,从输入符号串开始,通过反复查找当前句型的句 ...

  4. 编译原理教程_5 自底向上分析

    文章原稿 https://gitee.com/fakerlove/fundamentals-of-compiling 文章目录 5. 自底向上分析 5.1 移进-规约分析 5.2 简单优先分析法 5. ...

  5. 自底向上分析语法分析程序设计与实现

    自底向上分析语法分析程序设计与实现 一.实验任务及内容 编制一个文法的输入,从键盘.文件或文本框输入给定文法,依次存入输入缓冲区(字符型数据). 编制一个算法,模拟LR(0)分析器的主控流程,实现对给 ...

  6. 李艳芳北京应用物理与计算机,太赫兹量子级联激光器有源区增益分析和设计-太赫兹科学与电子信息.PDF...

    太赫兹量子级联激光器有源区增益分析和设计-太赫兹科学与电子信息 第 11 卷 第 1 期 太赫兹科学与电子信息学报 Vo1.11,No.1 2013 年 2 月 Journal of Terahert ...

  7. Mybatis底层原理学习(二):从源码角度分析一次查询操作过程

    在阅读这篇文章之前,建议先阅读一下我之前写的两篇文章,对理解这篇文章很有帮助,特别是Mybatis新手: 写给mybatis小白的入门指南 mybatis底层原理学习(一):SqlSessionFac ...

  8. HashMap底层原理分析(put、get方法)

    1.HashMap底层原理分析(put.get方法) HashMap底层是通过数组加链表的结构来实现的.HashMap通过计算key的hashCode来计算hash值,只要hashCode一样,那ha ...

  9. Runtime底层原理总结--反汇编分析消息转发

    消息转发:发送一个消息,也就是sel查找imp,当没有找到imp,接下来进入动态方法解析,如果开发者并没有处理,会进入消息转发. 消息转发 前几篇文章介绍了Runtime底层原理和动态方法解析总结 , ...

  10. python找房源_Python租房信息分析!找到最适合自己的房源信息!

    原标题:Python租房信息分析!找到最适合自己的房源信息! 租房信息分析 import numpy as np import pandas as pd import matplotlib.pyplo ...

最新文章

  1. linux 下用户管理
  2. pandas使用nsmallest函数返回特定数据列中前N个最小值(搜寻最小的n个元素)、pandas使用nsmallest函数返回特定数据列中前N个最小值所对应的数据行
  3. navicat 导入csv未响应_使用navicat将csv文件导入mysql
  4. SDUT-SQL题解
  5. Bugku杂项(一)
  6. VTK:多数据点用法实战
  7. MySQL的source命令不加分号和delimiter的使用
  8. java 获取classpath下文件多种方式
  9. HDU2017新生赛 找方块
  10. input层级高 小程序_微信小程序textarea层级过高(盖住其他元素)问题的解决办法...
  11. Android 系统(184)---Android APN 配置
  12. WCF创建Rest服务(附:.net2.0创建Rest服务)
  13. MongoDB中常用的几种数据类型
  14. 《HTML5 2D游戏编程核心技术》——第3章,第3.8节绘制动画帧
  15. 算法(一):二分查找
  16. 认知无线电网络中的频谱切换理论
  17. CREO学习笔记【钣金结构中常用的标准件】
  18. SC16IS750在STM32的应用
  19. Linux Shell脚本面试25问
  20. 浅谈探索性数据分析的方法—如何下手处理一堆繁杂的数据

热门文章

  1. pip 升级 pip
  2. java-String类的其他功能
  3. 移动端 H5图片裁剪插件,内置简单手势操作
  4. 通过运用多线程来异步控制程序的运行
  5. 提高网页打开速度的一些小技巧
  6. 自动手动安装CDH5
  7. spring4笔记----spring生命周期属性
  8. 流计算精品翻译: The Dataflow Model
  9. Linux下的socket网络编程
  10. 1622: [Usaco2008 Open]Word Power 名字的能量