All of lore.kernel.org
 help / color / mirror / Atom feed
* Modify an sk_buff from an NF_HOOK
@ 2005-03-02  1:50 Ian Norton
  2005-03-02  1:58 ` Tobias DiPasquale
  0 siblings, 1 reply; 3+ messages in thread
From: Ian Norton @ 2005-03-02  1:50 UTC (permalink / raw)
  To: netfilter-devel

Hi everyone,

I've been faffing about for well over two weeks now, and, have come almost to
the conculsion (as I hauntingly suspected) that 'any' changes to an skb that
involve changes outside of the original values of skb->head and skb->tail are 
impossible to do safely. 

say you want to add some bytes to the end of your packet payload, you might
do skb_put(skb,bytes_to_add). you will get a pointer to the old skb->tail
and the new value of skb->tail will be increased accordingly.

this is all well and good, it seems to work, you can see your packet data
without it going crazy, but, then you return your newly changed packet to
netfilter.

and...

you loose everything after the old skb->tail pointer.

I expect this is really going past what netfilter is supposed to do, (after
all, what kind of filter adds stuff?)


-- 
Ian Norton-Badrul

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Modify an sk_buff from an NF_HOOK
  2005-03-02  1:50 Modify an sk_buff from an NF_HOOK Ian Norton
@ 2005-03-02  1:58 ` Tobias DiPasquale
  2005-03-02  4:30   ` Ian Norton
  0 siblings, 1 reply; 3+ messages in thread
From: Tobias DiPasquale @ 2005-03-02  1:58 UTC (permalink / raw)
  To: Ian Norton; +Cc: nf-devel

On Wed, 2 Mar 2005 01:50:34 +0000, Ian Norton <bredroll@darkspace.org.uk> wrote:
> Hi everyone,
> 
> I've been faffing about for well over two weeks now, and, have come almost to
> the conculsion (as I hauntingly suspected) that 'any' changes to an skb that
> involve changes outside of the original values of skb->head and skb->tail are
> impossible to do safely.

No its not. How about some code, buddy? What exactly are you doing and
where are you doing it?

-- 
[ Tobias DiPasquale ]
0x636f6465736c696e67657240676d61696c2e636f6d

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Modify an sk_buff from an NF_HOOK
  2005-03-02  1:58 ` Tobias DiPasquale
@ 2005-03-02  4:30   ` Ian Norton
  0 siblings, 0 replies; 3+ messages in thread
From: Ian Norton @ 2005-03-02  4:30 UTC (permalink / raw)
  To: netfilter-devel

On Tue, Mar 01, 2005 at 08:58:18PM -0500, Tobias DiPasquale wrote:
> On Wed, 2 Mar 2005 01:50:34 +0000, Ian Norton <bredroll@darkspace.org.uk> wrote:
> > Hi everyone,
> > 
> > I've been faffing about for well over two weeks now, and, have come almost to
> > the conculsion (as I hauntingly suspected) that 'any' changes to an skb that
> > involve changes outside of the original values of skb->head and skb->tail are
> > impossible to do safely.
> 
> No its not. How about some code, buddy? What exactly are you doing and
> where are you doing it?

Im aware Im probably doing it all wrong :-).

here goes,

my hook functions is registered at the NF_IP_LOCAL_IN with NF_IP_PRI_FIRST
after some testing to see if a packet contains eg IPCOMP going from some
specific ip, i pass the skb (via the original pointer i get from the hook) 
to a function to decompress the contents of the IPCOMP data.

Im doing this in 2.4.2x .

// registered with netfilter as my hook func 
unsigned int
compressed_rx (unsigned int nfhook, struct sk_buff **skb,
	      const struct net_device *in, const struct net_device *our,
	      int (*okfn) (struct sk_buff *))
{

	struct sk_buff *skbuff = skb;
	int rx_retval = NF_ACCEPT;

	/* ignore anything that isnt a packet with an IPComp payload */
	if (skbuff->nh.iph->protocol != PROTO_IPCOMP)
		return NF_DROP;

	/* stuff removed here for clarity, nothing to do with the skb */	

	return sk_buff_data_decompress (skbuff, ACTION_INFLATE_MANUAL);
}



/* decompress the data of an sk_buff according to it's cpi */
int
sk_buff_data_decompress (struct sk_buff *_skb, int action)
{
	void *zlib_output_start;	// we will put the decompressed payload here
	u8 zlib_output_buffer[MAX_PAYLOAD_SIZE];
	size_t zlib_output_size;	// the amount of memory requested at *zlib_output_start

	int output_bytes;	// set to the length of output from zlib
	size_t payload_size;	// the total size of the payload + ipcomp hdr
	size_t new_payload_size; // decompressed payload size
	size_t ipcomp_size;	    // same as payload_size
	size_t ipcomp_payload_size;	// the length of the ipcomp data
	size_t payload_size_delta; // absolute diff between payload_size and new_payload_size
	
	u8 payload_protocol;	// save the payload value from the ipcomp header

	struct iphdr *ip_head;	// the start of the IP (nh) in the sk_buff
	struct iphdr *orig_ip_head;
	size_t iphead_size;	
	
	pneumatic_header *ipcomp_head;

	void *payload_start;	// the start of the ip payload in the skb_buff
	void *ipcomp_payload_start;	// the start of the compressed data

	struct sk_buff *skb = _skb; // do work here	
	struct sk_buff *newskb;		
	
	ip_head = skb->nh.iph;
	payload_start = skb->h.raw;
	ipcomp_head = (pneumatic_header *) payload_start;
	ipcomp_payload_start =
			(void *) ipcomp_head + sizeof (pneumatic_header);


	payload_size = ntohs (ip_head->tot_len) - (ip_head->ihl * 4);
	ipcomp_size = payload_size;
	ipcomp_payload_size = ipcomp_size - sizeof (pneumatic_header);


	/* the proto number of the compressed data */
	payload_protocol = ipcomp_head->payload_proto;

	/* set space for decompressed output */
	zlib_output_size = (size_t) MAX_PAYLOAD_SIZE;
	zlib_output_start = &zlib_output_buffer;

    /* this works without any problems, i get correct decompressed data here */
	output_bytes = pneu_inflate_decompress (ipcomp_payload_start,
						 ipcomp_payload_size, zlib_output_start, zlib_output_size);

	// compression didnt work?!     
	if (output_bytes <= 0)
		return NF_DROP;


	// packet seemed to decompress ok,
	
	new_payload_size = (size_t)output_bytes;	// length of decompressed payload
	payload_size_delta = new_payload_size - payload_size; // increased by this length 
	
	if (skb_tailroom(skb) < payload_size_delta)
		return NF_DROP; // buffer didnt have enough space in. 
	

	// the payload decompressed ok here,
	// now expand the skb's data and put the result in the payload
	// of the ip packet.

	iphead_size = sizeof(struct iphdr);
	orig_ip_head = kmalloc( iphead_size, GFP_ATOMIC );
	if (! orig_ip_head )
		return NF_DROP;

	memcpy( orig_ip_head, skb->nh.raw, iphead_size);
		
	// adjust the data area to fit the new payload
	skb_put(skb, payload_size_delta);
		
	// now copy back the old ip header
	memcpy(skb->nh.raw , orig_ip_head ,iphead_size);
	kfree(orig_ip_head);

	skb->nh.iph->protocol = payload_protocol;	// set the old protocol's value
	skb->nh.iph->tot_len = htons (ntohs(skb->nh.iph->tot_len) + payload_size_delta);
		
	// copy the stuff we got from zlib into the skb's data area
	memcpy (skb->h.raw, zlib_output_start, (unsigned int) output_bytes);

	// update ip header csum
	ip_send_check(skb->nh.iph);

	// right now, i can see the entirety of the buffer, if i copy the skb
    // and send it to myself with netif_rx() i can see the whole buffer.

    // when netfilter releases the skb back to the application/linux,
    // I see the decompressed data but it is truncated to the length of the
    // original recieved skb.
			
	return NF_ACCEPT;
}

I hope this makes sense, Ive chopped quite a fair chunk out to do with some
conditions about when to ignore or when to decompress.

Thanks for your help :-)


-- 
Ian Norton-Badrul

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-03-02  4:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-02  1:50 Modify an sk_buff from an NF_HOOK Ian Norton
2005-03-02  1:58 ` Tobias DiPasquale
2005-03-02  4:30   ` Ian Norton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.