this is the basic outline i use to generate tcp packets (unimportant parts cut):
struct rt_key key = { .dst ctuple->dst.ip,
.src 0,
.oif 0,
.tos RT_TOS(IPTOS_LOWDELAY) | RTO_CONN,
#ifdef CONFIG_IP_ROUTE_FWMARK
.fwmark 0
#endif
};
if ((ip_route_output_key(&rt, &key) != 0))
return 1;
dev = rt->u.dst.dev;
skb = alloc_skb(dev->hard_header_len + sizeof(struct iphdr) +
tcp_hdr_len, GFP_ATOMIC);
if (!skb) {
ip_rt_put(rt);
return -1;
}
skb->dev = dev;
skb->dst = &rt->u.dst;
skb->protocol = __constant_htons(ETH_P_IP);
skb_reserve(skb, dev->hard_header_len);
skb->nh.raw = skb->data;
iph = (struct iphdr*) skb_put(skb, sizeof(struct iphdr));
tcph = (struct tcphdr*)skb_put(skb, tcp_hdr_len);
... fill in ip & tcp header ...
tcph->check = iph->check = 0;
tcph->check = tcp_v4_check(tcph, tcp_hdr_len, iph->saddr, iph->daddr,
csum_partial((char *)tcph, tcp_hdr_len, 0));
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
skb->ip_summed = CHECKSUM_UNNECESSARY;
return skb->dst->output(skb);
}
this works fine, except when you turn on memory allocation debugging a
BUG_ON somewhere is triggered, i haven't looked into this yet.
While looking over it right now i noticed another thing, i think usually dev->hard_header_len
is padded to 16-byte boundaries, you might want to change this.
I hope it helps ..
Patrick
Joshua Stewart wrote:
At this point, if I call skb->dst->output() what should skb->data point
to? A properly crafted IP packet? Checksummed and all? I shouldn't
need any layer 2 info in my skb at all to use this solution, should I?
Thanks for the help. I think this will do the trick.
J
On Sun, 2003-01-12 at 12:28, Patrick McHardy wrote:
Joshua Stewart wrote:
I'm trying to take "hand-built" sk_buffs with little more than some datause ip_route_output_key() and then skb->dst->output(), that way it will work on all media
and a dev member and push them to the NIC for transmission. I would
like to simply give them to dev_queue_xmit. Does anybody know what
state I should have them in before handing them to dev_queue_xmit? Should skb->data point to the start of a MAC header or an IP header?
Also, given an IP address in skb->nh.iph->daddr, what's the easiest way
to get the appropriate MAC address?
and you don't have to care about l2 resolving at all.
Patrick
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
- : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html