我在这里有一段特定的代码,到目前为止互联网一直没有什么帮助。我正在尝试编写一段代码(对于初学者来说)应该能够读出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);
我所知道的当前项目:
当前输出的样本:
<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_hwstruct ieee80211_hw *hw = wiphy_to_ieee80211_hw(dev->ieee802_ptr->wiphy);
但是由于这仍然是未定义的,它不会导致ieee80211_hw,因此它会崩溃我的模块(甚至不会加载):(。