从linux网络驱动程序中打印字符串

时间:2013-07-24 09:11:57

标签: c linux-device-driver

我编写了一个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->数据,源和目标字符串,而是看到乱码。 我的猜测是,它与某种方式有关,我指的是内核内存,但另一方面,这就是printk的用途。

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

2 个答案:

答案 0 :(得分:1)

对于saddrdaddr,您无法以这种方式打印它们。您可以使用以下方式打印它们:

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

对于skb->data,它不会为空('\0'),因此您无法打印为格式为"%s"的字符串。由skb->data确定的skb->len的限制。您可以这种方式打印skb->data的内容。

int i; 
for (i=0; i<skb->len; i++) 
    printk("%c", skb->data+i ); 

答案 1 :(得分:0)

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