Kernel 如何打印每个数据包(以太网类型:0x0806,协议:ARP)的前34个字节(以太网和IP头)? 操作系统:Ubuntu 15.10桌面(64位) 内核:4.3 司机:无线 路径:

Kernel 如何打印每个数据包(以太网类型:0x0806,协议:ARP)的前34个字节(以太网和IP头)? 操作系统:Ubuntu 15.10桌面(64位) 内核:4.3 司机:无线 路径:,kernel,linux-kernel,ip,ethernet,Kernel,Linux Kernel,Ip,Ethernet,下面是我当前的实现(int i=0;就在struct sta_info*dsta;之后,packet_number++就在原始rx.c文件中的skb=rx->skb;之前): 以下是我想要的输出: Packet xx: 74 46 a4 08 06 ... Packet xx: 55 32 3e 45 98 ... Packet xx: 00 1b 2c 70 55 ... rx->skb->data的数据类型是,为了使其与%x兼容,我不得不执行这些强制转换,最终需要使用unsigned lo

下面是我当前的实现(
int i=0;
就在
struct sta_info*dsta;
之后,
packet_number++
就在原始rx.c文件中的
skb=rx->skb;
之前):

以下是我想要的输出:

Packet xx: 74 46 a4 08 06 ...
Packet xx: 55 32 3e 45 98 ...
Packet xx: 00 1b 2c 70 55 ...
rx->skb->data的数据类型是,为了使其与%x兼容,我不得不执行这些强制转换,最终需要使用unsigned long和%lx来阻止编译警告的发生


请告诉我我做错了什么,以及如何打印每个数据包的前34个字节(以太网和IP头)(以太网类型:0x0806,协议:ARP)?

字节\u指针是指针,
(&byte_-pointer)是指针的指针,您只需要*byte_-pointer

请尝试以下代码

static void ieee80211_deliver_skb(  struct ieee80211_rx_data *rx  )
{
    (etc.)

    int i = 0;
    unsigned char *byte_pointer;
    unsigned char byte_contents = 0;

    if (ntohs(ehdr->h_proto) == 0x0806) {
        printk("Packet %d:", packet_number);
        for (i = 0; i < 34; i++) {
            byte_pointer = (unsigned char *) (rx->skb->data + i);
            byte_contents = *byte_pointer;
            printk("  %02x", byte_contents);
        }
    }
    printk("\n");
    packet_number++;
}
静态无效ieee80211_交付_skb(结构ieee80211_rx_数据*rx)
{
(等等)
int i=0;
无符号字符*字节\指针;
无符号字符字节内容=0;
如果(ntohs(ehdr->h_proto)==0x0806){
printk(“数据包%d:,数据包编号);
对于(i=0;i<34;i++){
字节指针=(无符号字符*)(rx->skb->data+i);
字节内容=*字节指针;
printk(“%02x”,字节内容);
}
}
printk(“\n”);
数据包号++;
}
或更短

u8 *p;
if (ntohs(ehdr->h_proto) == 0x0806) {
    printk("Packet %d:", packet_number);
    for (i = 0; i < 34; i++) {
        p = (u8 *)(rx->skb->data + i);
        printk("  %02x", *p);
    }
}
u8*p;
如果(ntohs(ehdr->h_proto)==0x0806){
printk(“数据包%d:,数据包编号);
对于(i=0;i<34;i++){
p=(u8*)(rx->skb->data+i);
printk(“%02x”,*p);
}
}




顺便说一下,Tx/Rx流中的大量printk消息是一件危险的事情
如果您使用的不是PC/NB,而是嵌入式系统,频繁出现的数据包会带来太多的printk处理程序调用。系统可能不会使用这些消息,然后由于printk缓冲区溢出而导致内核死机。

如果要将其放在几行上,必须使用
%*ph
说明符或
print\u hex\u dump()
。在任何情况下,这不是为时间关键部件设计的。因此,在这种情况下,您必须通过相应的
trace\u printk()
调用切换到跟踪点

对于速度较慢的,示例如下

pr_info("Packet %d: %34ph\n", packet_number, rx->skb->data);


ARP帧没有IP头。只有IP帧(EtherType 0x0800用于IPv4)具有这些功能。我的C有点生锈,但我认为您在为for循环中的
字节内容分配时犯了一个错误。IIRC
&byte\u pointer
是指向
byte\u pointer
的地址,我想你想要
byte\u pointer
指向的数据,这就是
*byte\u pointer
,不是吗。请不要这样做。
u8 *p;
if (ntohs(ehdr->h_proto) == 0x0806) {
    printk("Packet %d:", packet_number);
    for (i = 0; i < 34; i++) {
        p = (u8 *)(rx->skb->data + i);
        printk("  %02x", *p);
    }
}
pr_info("Packet %d: %34ph\n", packet_number, rx->skb->data);
pr_info("Packet %d:\n", packet_number);
print_hex_dump(KERN_INFO, "Packet:", DUMP_PREFIX_OFFSET, 16, 1, rx->skb->data, 34, false);