从Linux内核发送没有目标mac地址的IP数据包

时间:2014-06-02 15:50:02

标签: c linux-kernel ip ethernet arp

我想在linux内核中传输一个包含有效tcp和ip头的skb。它应该在没有路由的情况下输出特定的接口。 我的问题是,我不能使用dev_queue_xmit,因为我不知道目的地的mac-address。 我尝试找出arp_find的mac地址失败了:

...
mh = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr));
...
arp_find(mh->h_dest, skb); //this or the next line
val = dev_queue_xmit(skb); //crashes kernel

ip_local_out的实验也失败了。我设置了ip头信息并调用ip_local_out,这也导致内核崩溃。

我无法使用ip_queue_xmit,因为我无法找到struct flowi *fl字段中提供的数据。

所以我的问题:

  • 如何在设备上发送带有ip信息的skb并且不知道关于较低级别的知识?
  • 如果对第一个问题没有答案:我怎样才能找到目的地mac /触发目标ip的arp请求?

备注:

  • 我想避免使用(原始)套接字。
  • 我成功了 如果我有的话,通过dev_queue_xmit发送自制的skbs 目标mac地址。所以构建skb的代码不是 问题。

2 个答案:

答案 0 :(得分:2)

如果您仍想使用ip_local_outip_queue_xmit,那么您可以像这样创建您的flowinfo。

struct flowi4 fl4 = {
    .flowi4_oif = skb->dev->ifindex,
    .daddr = iph->daddr,
    .saddr = iph->saddr,
};

然后用

创建dst(rtable)
ip_route_output_key

使用

设置为skb_buff
skb_dst_set

答案 1 :(得分:1)

我认为在内核中使用套接字编程将其作为RAW IP数据包发送是一种更清晰的解决方案。 您可以像这样创建套接字。 sock_create_kern(&sk, AF_INET, SOCK_RAW, IPPROTO_RAW, net);

然后打电话 kernel_sendmsg

让你的数据包通过协议栈。