从以太网 header 打印 MAC 地址
Print MAC address from Ethernet header
我想检查以太网 header 被 iptables (1.4) porececed 的数据包,所以我需要编写一个模块来捕获数据包并应用我的功能。我正在以太网 header 中寻找 mac 目标值(仅用于测试目的),所以代码应该是这样的:
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 检查过),所以它是获取以太网的正确函数 header属性?
更新:
我使用了 post 中提供的解决方案,但仍然有错误的输出,就像结构指向错误的地方一样
这张图片显示了当我使用 nc 发送 "aaa" 字符串时的结果,以太网 header 在 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地址。来自 documentation/printk-formats.txt
:
MAC/FDDI addresses:
%pM 00:01:02:03:04:05
%pMR 05:04:03:02:01:00
%pMF 00-01-02-03-04-05
%pm 000102030405
%pmR 050403020100
For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm'
specifiers result in a printed address with ('M') or without ('m') byte
separators. The default byte separator is the colon (':').
Where FDDI addresses are concerned the 'F' specifier can be used after
the 'M' specifier to use dash ('-') separators instead of the default
separator.
For Bluetooth addresses the 'R' specifier shall be used after the 'M'
specifier to use reversed byte order suitable for visual interpretation
of Bluetooth addresses which are in the little endian order.
Passed by reference.
所以你可以使用这个:
printk(KERN_INFO "hdr->h_dest 0x%pM\n", hdr->h_dest);
这些格式说明符在任何使用 vsnprintf
的地方提供。这里是 an example:
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;
}
我想检查以太网 header 被 iptables (1.4) porececed 的数据包,所以我需要编写一个模块来捕获数据包并应用我的功能。我正在以太网 header 中寻找 mac 目标值(仅用于测试目的),所以代码应该是这样的:
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 检查过),所以它是获取以太网的正确函数 header属性?
更新:
我使用了 post 中提供的解决方案,但仍然有错误的输出,就像结构指向错误的地方一样
这张图片显示了当我使用 nc 发送 "aaa" 字符串时的结果,以太网 header 在 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地址。来自 documentation/printk-formats.txt
:
MAC/FDDI addresses:
%pM 00:01:02:03:04:05
%pMR 05:04:03:02:01:00
%pMF 00-01-02-03-04-05
%pm 000102030405
%pmR 050403020100
For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm'
specifiers result in a printed address with ('M') or without ('m') byte
separators. The default byte separator is the colon (':').
Where FDDI addresses are concerned the 'F' specifier can be used after
the 'M' specifier to use dash ('-') separators instead of the default
separator.
For Bluetooth addresses the 'R' specifier shall be used after the 'M'
specifier to use reversed byte order suitable for visual interpretation
of Bluetooth addresses which are in the little endian order.
Passed by reference.
所以你可以使用这个:
printk(KERN_INFO "hdr->h_dest 0x%pM\n", hdr->h_dest);
这些格式说明符在任何使用 vsnprintf
的地方提供。这里是 an example:
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;
}