0

我已经编写了一个 linux 网络驱动程序。

这是我的“hard_header”功能:

 int snull_header(struct sk_buff *skb, struct net_device *dev,
               unsigned short type, void *daddr, void *saddr,
             unsigned int len)
 {
   struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);

   pr_err("inside snull_header\n");
   pr_err("THE DATA TO SEND BEFORE ADDITION IS:%s\n", skb->data);
   pr_err("THE SOURCE IS:%s\n", (char*)saddr);
   pr_err("THE DEST IS:%s\n", (char*)daddr);
   eth->h_proto = htons(type);
   memcpy(eth->h_source, saddr ? saddr : dev->dev_addr, dev->addr_len);
   memcpy(eth->h_dest,   daddr ? daddr : dev->dev_addr, dev->addr_len);
   eth->h_dest[ETH_ALEN-1]   ^= 0x01;   /* dest is us xor 1 */
   pr_err("THE DATA TO SEND AFTER ADDITION IS:%s\n", skb->data);
   return (dev->hard_header_len);
 }

这是 pr_err 的定义(来自 printk.h):

    #define pr_err(fmt, ...) \
    printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)

当我运行加载这个驱动程序并尝试发送数据包时,我看到了所有的打印,但我看到的是乱码,而不是 skb->data、源和目标的字符串。我的猜测是它在某种程度上与我指的是内核内存的事实有关,但另一方面,这就是 printk 的用途。

如何正确打印这些字符串?

4

2 回答 2

1

对于saddrand daddr,您不能以这种方式打印它们。您可以使用以下方法打印它们:

pr_err("THE SOURCE IS:%d.%d.%d.%d\n",
       (0xff & saddr),
       (0xff00 & saddr) >> 8,
       (0xff000000 & saddr) >> 16
       (0xff000000 & saddr) >>24);

对于skb->data,它不是 null( '\0') 终止的,因此您不能使用格式打印为字符串"%s"skb->data由确定的极限skb->len。您可以通过这种方式打印 的内容skb->data

int i; 
for (i=0; i<skb->len; i++) 
    printk("%c", skb->data+i ); 
于 2013-07-24T09:22:28.923 回答
0

skb->data 的内容取决于您打印的网络层。它甚至可以包含前一层的标题。所以得到数据的长度。然后按字节打印数据的长度。然后分析它包含的内容。skb->data_len 给出数据的大小。

于 2013-07-24T09:43:01.980 回答