使用802.11在Android上检索sk_buff

时间:2013-07-23 12:32:45

标签: android network-programming linux-kernel kernel-module kernel

我在这里有一段特定的代码,到目前为止互联网一直没有什么帮助。我正在尝试编写一段代码(对于初学者来说)应该能够读出802.11(无线)数据包并从MAC头中打印信息。我尝试用不同的教程,内核信息片段编写我的代码,...我正在尝试编写的程序是一个可加载的内核模块,用于android(虽然linux内核非常相似)。虽然我现在可以收到sk_buff包,但在我看来这些都是完全错误的。这是我到目前为止的代码:

/* 
 *  AUTHOR:     MATHIEU DEVOS
 *  
 */
/* Needed by all modules */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

/* KModule specific */
#include <linux/skbuff.h> /* ptype_function and others */
#include <linux/netdevice.h> /* used to print list of devices */
#include <linux/nl80211.h> /* used for iftypes types */
#include <net/cfg80211.h> /* used to handle ieee80211_ptr that point to wireless_dev*/
#include <linux/if_ether.h> /* used to specifiy which ethernet packages driver gets, not for header! */
#include <linux/netfilter.h> /* used to determine what to do with the packets */
#include <linux/string.h> /* used for memcmp */
#include <linux/ieee80211.h> /* used for 802.11 header and constants */
#include <net/mac80211.h> /* used for handling skb and getting hw */

/* used to show defines, currently unused, remove later on */
#define STR(x) #x
#define SHOW_DEFINE(x) printk(KERN_CRIT "%s = %s\n", #x, STR(x));


/* defines for modinfo */
#define DRIVER_AUTHOR "Mathieu Devos <mathieu.devos@ugent.be>"
#define DRIVER_DESC "Basic ethernet test"

/* Actual coding start */

/* initialisation of variables and functions */

    /* variables */
struct net_device *dev;
struct ieee80211_hw *hw;
static int foundWLAN = 0;
static struct packet_type ptype;

    /* functions */
static void print_mac_hdr(struct ieee80211_hdr *e_hdr);
static int dev_is_wireless(struct net_device *dev);
static void throw_hook(struct net_device *dev);
static int ptype_function(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *dev2);


/*start of functions*/

static void print_HWinfo(void){
    printk(KERN_CRIT "Network device: %s\n",dev->name);
    printk(KERN_CRIT "Network address: %pM\n",dev->dev_addr);
}

static int dev_is_wireless(struct net_device *dev){
    #ifdef CONFIG_WIRELESS_EXT
        if(dev->wireless_handlers && dev->operstate!=5){
            return 1;
        }
    #endif
    if(dev->ieee80211_ptr && dev->operstate!=5){
        return 1;
    }


    return 0; /* default false */
}

static int ptype_function(struct sk_buff *skb, struct net_device *dev1, struct packet_type *ptype, struct net_device *dev2){


    struct ieee80211_hdr *whdr = NULL;
    whdr = (struct ieee80211_hdr *)skb->mac_header;




    printk(KERN_CRIT "head: %pF",skb->head);
    printk(KERN_CRIT "mac_header: %pF",skb->mac_header);
    printk(KERN_CRIT "network_header: %pF",skb->network_header);
    printk(KERN_CRIT "transport_header: %pF",skb->transport_header);

    printk(KERN_CRIT "len: %u",skb->len);
    printk(KERN_CRIT "data_len: %u",skb->data_len);
    printk(KERN_CRIT "mac_len: %u",skb->mac_len);
    printk(KERN_CRIT "hdr_len: %u",skb->hdr_len);

    printk(KERN_CRIT "SKBUFF size: %u", sizeof(*skb));


    /*
    print_mac_hdr(whdr); */

    /* sizeof(*whdr)) = 30 bytes */
    /* sizeof(*ehdr)) = 14 bytes */

    if(memcmp(whdr->addr1,dev1->dev_addr,dev1->addr_len)==0){
        print_mac_hdr(whdr);
    }


    dev_kfree_skb(skb);
    return NF_DROP; /* NF_DROP Basically, print the info of the all the packets flying around, then drop it */
}

static void print_mac_hdr(struct ieee80211_hdr *whdr){

    printk(KERN_CRIT "DA ADDR: %pM\n",whdr->addr1);
    printk(KERN_CRIT "BSSID ADDR2: %pM\n",whdr->addr2);
    printk(KERN_CRIT "SA ADDR3: %pM\n",whdr->addr3);
    printk(KERN_CRIT "UNUSED ADDR4: %pM\n",whdr->addr4);
    /*printk(KERN_CRIT "PROTOCOL: 0x%04x\n",ntohs(ehdr->h_proto));*/
}

static void throw_hook(struct net_device *dev){
    ptype.type = htons(ETH_P_ALL); /* listen to all ethernet packets! This should still work, even for 802.11, change later */
    ptype.func = &ptype_function;
    ptype.dev = dev;
    dev_add_pack(&ptype);
    printk(KERN_CRIT "Done setting up packet type");

}

static void delete_hook(struct net_device *dev){
    dev_remove_pack(&ptype);
    synchronize_net();
}

/* Handle init and exit of module */

static int __init init_mymodule(void){
    printk(KERN_CRIT "Started kernel module!\n");

    dev = first_net_device(&init_net);
    while(dev && !foundWLAN){
        foundWLAN = dev_is_wireless(dev);
        if(!foundWLAN){
            dev = next_net_device(dev);
        }
    }

    if(dev && dev->ieee80211_ptr->iftype==NL80211_IFTYPE_STATION){
        print_HWinfo();

        /*
        hw = wiphy_to_ieee80211_hw(dev->ieee80211_ptr->wiphy);
        if(!hw){
            printk(KERN_CRIT "Could not assign HW!");
        }else{
            printk(KERN_CRIT "Assigned hw!");
        }
        */

        throw_hook(dev);
    }

    return 0;

}

static void __exit exit_mymodule(void){

    delete_hook(dev);

    printk(KERN_CRIT "Finished kernel module, exiting \n");
}

module_init(init_mymodule);
module_exit(exit_mymodule);

/*
 *   Extra info for modinfo
 */

MODULE_LICENSE("GPL");

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);

我所知道的当前项目:

  1. 在检查wifi设备时,我同时收到p2p0和wlan0,因为我想编写通用代码,我宁愿不根据名称选择“正确”的设备。因此,为什么我要根据DORMANT(operstate)状态选择它。
  2. 目前我不知道是否需要调用硬件信息(wiphy_to_ieee80211_hw),但是当我尝试运行所述函数时,我的__init不再返回0(因此它得到一个错误代码)我甚至无法启动我的模块
  3. 当尝试使用skb-&gt;数据时,我的内核崩溃并且还试图读出数据指针(* data)导致崩溃。
  4. 正如您在下面的示例输出中看到的那样,我正在接收两个mac_len,data_len是完全错误的。 Mac_len应该是30(802.11标头的字节)和data_len,好吧,不应该一直是0。
  5. 当前输出的样本:

    <2>[19476.400718] c0 head: 0xe2e4f440
    <2>[19476.400766] c0 mac_header: 0xe2e4f48e
    <2>[19476.400818] c0 network_header: 0xe2e4f432
    <2>[19476.400873] c0 transport_header: 0xe2e4f440
    <2>[19476.400929] c0 len: 78
    <2>[19476.400964] c0 data_len: 0
    <2>[19476.401003] c0 mac_len: 14
    <2>[19476.401041] c0 hdr_len: 0
    <2>[19476.401079] c0 SKBUFF size: 184
    <2>[19476.401307] c0 head: 0xe2e4f440
    <2>[19476.401362] c0 mac_header: 0xe2e4f4dc
    <2>[19476.401423] c0 network_header: 0xe2e4f432
    <2>[19476.401485] c0 transport_header: 0xe2e4f440
    <2>[19476.401541] c0 len: 156
    <2>[19476.401577] c0 data_len: 0
    <2>[19476.401615] c0 mac_len: 14
    <2>[19476.401656] c0 hdr_len: 0
    <2>[19476.401701] c0 SKBUFF size: 184
    

    希望自从我刚接触本网站以来,就这些问题获得一些积极的见解,但是已经使用它一段时间来帮助解决我的编程问题。

    在我保存所有进度并尝试寻找更多明天之前先进行快速编辑:

    加入:

    extern struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy);
    

    到函数初始化(当尝试做同样但用wiphy_to_ieee80211_hw而不是* wiphy_to_ieee80211_hw我似乎得到了一大堆错误)。使用指针函数(* wiphy_to_ieee80211_hw)我只能得到它未定义的。 所以这个功能仍未定义,这对我来说相当烦人。我更改了我的makefile以添加:KBUILD_EXTRA_SYMBOLS = .. / kernel / net / mac80211(这是export_symbol所在的位置:../ kernel / net / mac80211 / util.c) 总makefile:

    obj-m += ethernet_test.o
    
    all:
      make -C ../kernel M=$(PWD) KBUILD_EXTRA_SYMBOLS=../kernel/net/mac80211 modules
    clean:
      make -C ../kernel M=$(PWD) clean
    

    还尝试使用:

    再次加载__init部分的ieee80211_hw
    struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(dev->ieee802_ptr->wiphy);
    

    但是由于这仍然是未定义的,它不会导致ieee80211_hw,因此它会崩溃我的模块(甚至不会加载):(。

0 个答案:

没有答案