Re: How to copy, modify and send the modified duplicate of an sk_buff

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!

On 17:11 Wed 22 Jul     , Loránd Jakab wrote:
> On Wednesday, July 22, 2009 08:15:12 Michael Blizek wrote:
> > Hi!
> >
> > On 18:28 Tue 21 Jul     , Loránd Jakab wrote:
> > > Hello,
> > >
> > > I am working on implementing an experimental network protocol. I
> > > have netfilter hook which changes the payload after the IP header
> > > and the destination IP in packets with a certain protocol id. This
> > > part works.
> > >
> > > For some packets, I need to generate an extra packet. To do this, I
> > > copy the sk_buff, modify stuff on the copy and try sending it with
> > > dev_queue_xmit(), then modify the original and return NF_ACCEPT.
> > > The result is: the original get through (the one with NF_ACCEPT)
> > > but the copy doesn't.
> > >
> > > Here's the code for copying and sending the copy:
> > >
> > > static void send_payload(struct sk_buff *skb, struct in_addr rloc)
> >
> > Where do you call this function? Immediately before the ip stack
> > calls dev_queue_xmit? If not, the ip stack might not have finished
> > building the packet.
> >
> > 	-Michi
> 
> Hi,
> 
> This function is called from an ipfilter hook, which is registered at 
> IP_PRE_ROUTING. I replace some data, but I don't do the routing so the 
> correct MAC header is not created. After discovering this, I tried three 
> approaches:
> 
> * Calling ip_route_input and then dev_queue_xmit() - same as before, I 
>   get the IP header in place of the MAC header
> * Calling ip_queue_xmit() - which does routing as well, I checked the
>   implementation - I get a kernel panic
> * Futile, but just in case, ip_route_input() and ip_queue_xmit() -
>   kernel panic

Do you get something like this?
void skb_under_panic(struct sk_buff *skb, int sz, void *here)
{
        printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p "
                          "data:%p tail:%#lx end:%#lx dev:%s\n",
               here, skb->len, sz, skb->head, skb->data,
               (unsigned long)skb->tail, (unsigned long)skb->end,
               skb->dev ? skb->dev->name : "<NULL>");
        BUG();
}


> It seems that ip_queue_xmit should be what I need, I don't know why it 
> crashes...

If the above text is the reason, it may be triggered by this line in
ip_queue_xmit:

skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));

Which basically means that it assumes that there is no ip header so far and
this function wants to add it at the beginning of the buffer. However, there
is no headroom and so it crashes. You can try this immediately before calling
ip_queue_xmit(I know it is ugly, maybe someboby knows a better way?):

skb_push(skb, (int)(skb_transport_header(skb) - skb->head));

	-Michi
-- 
programing a layer 3+4 network protocol for mesh networks
see http://michaelblizek.twilightparadox.com


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux