2005-03-17 17:16:18

by Weber Matthias

[permalink] [raw]
Subject: Getting ethernet dest hw_addr

Hi,

i want to write a packet handler for redirecting ethernet packets from an input device to an output device. actually my problem is to get the dest hw addr from the computer physically connected to mine.
the only way seems to restrict on ip packets since it seems that routing and arp needs to be used. so i tried to use ip_route_output_key which fills skb->dst. Unfortunately i don't have any idea how to get the needed addr from there. Below is a piece of code showing what i want to do.

Can anyone help me, please?
The favorite way would be to get the addr without limiting to ip...

Thanks and bye
Matthias

static int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) {
struct sk_buff *o_skb = skb_clone(skb, GFP_ATOMIC);
struct iphdr *iph = o_skb->nh.iph;
struct tcphdr *th = (struct tcphdr *) ((char *) o_skb->h.th + (iph->ihl << 2));

//prevent OS for handling packet
skb->pkt_type = PACKET_OTHERHOST;

if (iph->saddr == ext_addr) { //out->in
//modify header
iph->saddr = gw_int_addr;
iph->daddr = int_addr;
o_skb->dev = devs[2];
} else if (iph->saddr == int_addr) { //in->out
//modify header
iph->saddr = gw_ext_addr;
iph->daddr = ext_addr;
o_skb->dev = devs[1];
} else {
return 0;
}

//route packet
struct flowi flow = {
.nl_u = {
.ip4_u = {
.saddr = iph->saddr,
.daddr = iph->daddr,
.tos = RT_TOS(iph->tos)
}
},
.proto = iph->protocol
};
struct rtable *rt;
ip_route_output_key(&rt, &flow);
o_skb->dst = &(rt->u.dst);

//ip checksum
...works

//broadcast paket to dev -> no dest ethernet addr needed
o_skb->dev->hard_header(
o_skb,
o_skb->dev,
ntohs(o_skb->protocol),
o_skb->dst->neighbour->ha, //destination hw addr needed - seems to be wrong!
o_skb->dev->dev_addr,
o_skb->len
);

//send packet
o_skb->pkt_type = PACKET_OUTGOING;
dev_queue_xmit(o_skb);

kfree_skb(o_skb);

return 0;
}