从以太网报头打印MAC地址
我想检查由iptables(1.4)穿孔的数据包的以太网报头,因此我需要编写一个模块来捕获数据包并应用我的功能。我在Ethernet报头中查找mac destination值(仅用于测试目的),因此代码应如下所示:从以太网报头打印MAC地址,c,linux-kernel,iptables,C,Linux Kernel,Iptables,我想检查由iptables(1.4)穿孔的数据包的以太网报头,因此我需要编写一个模块来捕获数据包并应用我的功能。我在Ethernet报头中查找mac destination值(仅用于测试目的),因此代码应如下所示: static bool match(const struct sk_buff *skb, struct xt_action_param *par) { struct ethhdr *hdr; hdr = eth_hdr(skb); printk
static bool match(const struct sk_buff *skb, struct xt_action_param *par)
{
struct ethhdr *hdr;
hdr = eth_hdr(skb);
printk(KERN_INFO "hdr->h_dest 0x%x\n", hdr->h_dest);
printk(KERN_INFO "MACPROTO=%04x\n", hdr->h_proto);
问题是,我无法获得正确的值,我有一些东西甚至不在真实帧中(我用Wireshark检查了这一点),所以它是获取以太网头属性的正确函数吗
更新:
我使用了文章中给出的解决方案,但仍然有错误的输出,就像结构指向错误的位置一样
此图显示了当我使用nc发送“aaa”字符串时的结果,以太网报头在to帧中应相同,但与结果中显示的相同。struct ethhdr定义如下:
/*
* This is an Ethernet frame header.
*/
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
__be16 h_proto; /* packet type ID field */
} __attribute__((packed));
但是您的代码正在尝试使用%x
:打印该字节数组
printk(KERN_INFO "hdr->h_dest 0x%x\n", hdr->h_dest);
这毫无意义,可能会导致生成编译器警告。这是内核代码-您正在使用-Werror
和-Wall
,对吗
好消息:
printk
支持直接打印MAC地址。发件人:
MAC/FDDI地址:
%下午00:01:02:03:04:05
%pMR 05:04:03:02:01:00
%pMF 00-01-02-03-04-05
%下午000102030405
%pmR 05043020100
用于以十六进制表示法打印6字节MAC/FDDI地址。“M”和“M”
说明符产生一个带有('M')或不带('M')字节的打印地址
分离器。默认的字节分隔符是冒号(“:”)。
如果涉及到FDDI地址,“F”说明符可以在
“M”说明符使用破折号(“-”)分隔符而不是默认分隔符
分离器。
对于蓝牙地址,应在“M”之后使用“R”说明符
说明符使用适合视觉解释的反向字节顺序
按小端顺序排列的蓝牙地址。
通过引用传递。
所以你可以用这个:
printk(KERN_INFO "hdr->h_dest 0x%pM\n", hdr->h_dest);
这些格式说明符在使用vsnprintf
的任何位置提供。这是:
很高兴知道。我从来没有听说过%pM和朋友们+1我使用%x以六边形打印输出,这样我可以用wireshark轻松地验证结果,无论如何,我尝试了你的方法,我使用了%pM,但仍然有错误的输出,proto等于0000(wireshark show 0800)@yassine
%x
说明符打印无符号int
,而h_dest
是无符号字符的数组。如果您不理解为什么这是错误的,那么您不应该编写内核驱动程序。另外,您的代码从来没有提到任何关于打印协议字段的内容。@JonathonReinhart,我使用同一行打印原型;printk(KERN_INFO“MACPROTO=%04x\n”,hdr->h_proto);最后,我使用了另一个数据包生成器,数据包似乎打印时没有错误,谢谢
switch (dev->type) {
case ARPHRD_ETHER:
nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
ntohs(eth_hdr(skb)->h_proto));
return;
default:
break;
}