我编写了一个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的用途。
如何正确打印这些字符串?
答案 0 :(得分:1)
对于saddr
和daddr
,您无法以这种方式打印它们。您可以使用以下方式打印它们:
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给出数据的大小。