1.通过skb里面的信息获取mac,如下
struct ethhdr *eth_hdr = (struct ethhdr *)skb_mac_header(skb);
if(skb_mac_header_was_set(skb))
{
memcpy(dmac, eth_hdr->h_dest, ETH_ALEN);
}
注意:需要先通过skb_mac_header_was_set函数判断是否已经设置了mac头,如果没有设置依然调用memcpy将会卡住或者报内存未对齐的错误。
由于自己在iptables的OUTPUT链上挂载了一个target,这个时候捕获到的数据包是3层的,还没有mac地址头,因此上面的方法行不通。
2.根据内核arp.c的arp_find函数写一个查询arp的函数,如下:
/* 从内核arp.c扣的arp_find函数,把skb->dev改为了dst->dev */
int arp_find_local(unsigned char *haddr, struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct net_device *dev = dst->dev;
__be32 paddr;
struct neighbour *n;
if (!skb_dst(skb)) {
pr_debug("arp_find is called with dst==NULL\n");
kfree_skb(skb);
return 1;
}
paddr = rt_nexthop(skb_rtable(skb), ip_hdr(skb)->daddr);
/* 指定create为0,只查找缓存,create = 1时貌似没找到会发arp查询包 */
n = __neigh_lookup(&arp_tbl, &paddr, dev, 0);
if (n) {
n->used = jiffies;
if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) {
neigh_ha_snapshot(haddr, n, dev);
neigh_release(n);
return 0;
}
neigh_release(n);
} else
kfree_skb(skb);
return 1;
}