In my schoool project (kernel 2.2.X), I would like to pass some data attached
immediately above IP. (i.e. w/o UDP and TCP) I have assigned an arbitrary
protocol # in the IP header field so that the received data is passed on to my
protocol stack.
There is no problem on reception but I got stuck at all the transmission and
forwarding operations:
1, How can I transmit data by using a sk_buff that is created from scratch?
2, How can I forward data from the sk_buff of a received packet.
I have run some trial codes (attached below) but the kernel crashes.
Is my description clear? I surely have missed out something but I have no
clue. Could anyone point out what is missing from my code?
Thanks in advance. :)
======================================
Transmit Data from Scratch (version 1)
======================================
/* this is how I try the thing out */
struct sk_buff *skb=alloc_skb(sizeof(struct iphdr)+15,GFP_ATOMIC)
skb_put(skb,data_len);
memcpy(skb->data,data_ptr,data_len);
ip_route_output(&rt, [some dst addr in __u32] , 0, RT_TOS(0), 0);
iph = (struct iphdr*) skb->nh.iph;
iph->version = 4;
iph->ihl = sizeof(struct iphdr) >> 2;
iph->tos = 0;
iph->tot_len = htons(skb->len);
iph->id = htons(ip_id_count++);
iph->frag_off = 0;
iph->ttl = 64;
iph->protocol = [some self-defined #];
iph->saddr = rt->rt_src;
iph->daddr = rt->rt_dst;
ip_send_check(iph);
skb->dst = &rt->u.dst;
skb->dst->output(skb);
======================================
Transmit Data from Scratch (version 2)
======================================
/* code that I find somewhere else */
/* my comment */
[original comment]
skb->dev = [put device here]; /* = ip_dev_find(daddr); ? */
skb->nh.iph->saddr = [alter the saddress to this m/c]
/* Is there a "raddr" in "include/linux/ip.h"? */
skb->nh.iph->raddr = [alter the router address]
if(!skb->dst)
[allocate dst_entry stucture] /* how can I do this? :p */
rt = (struct rtable *) skb->dst;
ip_route_output(&rt, skb->nh.iph->raddr, skb->nh.iph->saddr, 1, 0 )
hdr = (struct ethhdr *)skb_push( skb, ETH_HLEN);
memcpy(hdr->h_source, skb->dev->dev_addr, skb->dev->addr_len);
hdr->h_proto = __constant_htons(ETH_P_IP);
arp_find(skb->dev->h_dest, skb);
dev_queue_xmit(skb);
===============================
Forward Data of Received Packet
===============================
/* just alter the destination IP address */
/* or may add some data as well */
/* and then send it out */
/* outgoing device may be different from incoming device */
/* skb is the received skb */
struct rtable *rt;
struct iphdr *iph;
struct sk_buff *skb2;
skb2 = skb_copy(skb, GFP_KERNEL);
iph = (struct iphdr*) skb2->nh.iph;
ip_route_output(&rt, [some dst addr in __u32] , 0, RT_TOS(0), 0);
iph->daddr = [some dst addr in __u32];
/* // if I add 4 bytes of data as well
iph->tot_len = htons(ntohs(iph->tot_len) + 4);
skb->tail += 4;
skb->len += 4;
*/
ip_send_check(iph);
skb2->dst = &rt->u.dst;
skb2->dst->output(skb2);
____________________________________________________________________
Get your own FREE, personal Netscape WebMail account today at http://home.netscape.com/webmail
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/