All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Kobylyanskiy <kentlinux@yandex.ru>
To: "Jan Engelhardt" <jengelh@medozas.de>
Cc: "Netfilter Developer Mailing List" <netfilter-devel@vger.kernel.org>
Subject: Re: TCP-packet with PUSH flag with wrong payload data in LOCAL_OUT
Date: Thu, 22 Jan 2009 18:40:00 +0300	[thread overview]
Message-ID: <68611232638800@webmail51.yandex.ru> (raw)
In-Reply-To: <alpine.LSU.2.00.0901221521450.24791@fbirervta.pbzchgretzou.qr>

22.01.09, 17:27, "Jan Engelhardt" <jengelh@medozas.de>:

> ># define IP_PRINTF(addr) ((addr) & 0xff), (((addr) >> 8) & 0xff), (((addr) >> 16) & 0xff), (((addr) >> 24) & 0xff)
> Use NIPQUAD and NIPQUAD_FMT.

Ok. Thank you.

> >int ip_packet_from_local_host(struct iphdr *iph)
> >{
> >	struct net_device *dev   = NULL;
> >	struct in_device *in_dev = NULL;
> >	struct in_ifaddr *ifaddr = NULL;
> >	
> >	for (dev = dev_base; dev; dev = dev->next)
> >	{
> >		if (!dev->ip_ptr)
> >		{
> >			continue;
> >		}
> >		in_dev = (struct in_device *)dev->ip_ptr;
> Don't cast this.

Why?


> Now consider this - tcp_data[0] invokes undefined behavior when
>  * there is no payload
>  * or the packet is fragmented (a corner case, though)
> Most likely the former is your case.

> >    ret = check_packet(skb, (short)1); //1 - out
> Do not do redundant casts.
Ok. :)


I add more debug-print to function "check_packet" - to show You, that the packet has payload data and it is not fragmented:

Rewrited function:
==================================================================

static unsigned int check_packet(struct sk_buff *skb, short in_out)
{
    if(skb->nh.iph->protocol == IPPROTO_TCP)
    {
            struct tcphdr       *tcp;
            char                *tcp_data=NULL;
            char                tcp_flags[4];
            unsigned int        tcp_data_off=0;
            unsigned int        tcp_data_len=0;
            unsigned int        if_fragmented = 0;
            unsigned int        flag_MORE_FRAGMENTS = 0;
            unsigned int        FRAGMENT_OFFSET = 0;

            flag_MORE_FRAGMENTS = ntohs(skb->nh.iph->frag_off) & 0x2000;
            FRAGMENT_OFFSET = ntohs(skb->nh.iph->frag_off) & 0x1fff;

            if( (flag_MORE_FRAGMENTS == 1) || (FRAGMENT_OFFSET != 0))
            {
                    if_fragmented = 1;
            }

            tcp = (struct tcphdr *)((char*)skb->nh.iph + skb->nh.iph->ihl * 4);
            tcp_data_off = (tcp->doff)*4;

            tcp_data_len = ntohs(skb->nh.iph->tot_len) - (skb->nh.iph->ihl * 4) - tcp_data_off;

            tcp_data = (char *)tcp + tcp_data_off;
            tcp_flags[0]=' ';
            tcp_flags[1]=' ';
            tcp_flags[2]=' ';
            tcp_flags[3]='\0';

            if(tcp->syn)
                    tcp_flags[0] = 'S';
            if(tcp->ack)
                    tcp_flags[1] = 'A';
            if(tcp->psh)
                    tcp_flags[2] = 'P';
            info("=== HOOK_PACKET: packet src_addr=%u.%u.%u.%u:%u dst_addr=%u.%u.%u.%u:%u [%s] protocol=%u, IN_OUT=%d, DATA_OFF = %u, TCP_DATA_LEN = %u, if_fragmented = %u",
                            IP_PRINTF(skb->nh.iph->saddr),ntohs(tcp->source),IP_PRINTF(skb->nh.iph->daddr),ntohs(tcp->dest),
                            tcp_flags, skb->nh.iph->protocol, in_out, tcp_data_off, tcp_data_len, if_fragmented);
            if(tcp->psh && ntohs(tcp->dest) == 80)
            {
                    info("=== HOOK_PACKET: DATA=%02x %02x %02x %02x %02x %02x", tcp_data[0],tcp_data[1],tcp_data[2],tcp_data[3],tcp_data[4],tcp_data[5]);
//                  return NF_ACCEPT;
            }
    }

==================================================================






Syslog output:
=============
Jan 22 17:27:42 FW_EXT kernel: my_fw: fw_init(): Driver my_fw started
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.198:37118 dst_addr=192.168.0.132:80 [S  ] protocol=6, IN_OUT=1, DATA_OFF = 40, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.132:80 dst_addr=192.168.0.198:37118 [SA ] protocol=6, IN_OUT=0, DATA_OFF = 40, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.198:37118 dst_addr=192.168.0.132:80 [ A ] protocol=6, IN_OUT=1, DATA_OFF = 32, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.198:37118 dst_addr=192.168.0.132:80 [ AP] protocol=6, IN_OUT=1, DATA_OFF = 32, TCP_DATA_LEN = 101, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: DATA=02 00 01 00 01 00

You see - it has 101 bytes of payload and it is not fragmented!
May be when TCP packet with PUSH flag sended from localhost, payload data stored is some special buffer?
Or kernel copy payload data after all firewall checks? (may be for some optimisation reasons )


Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.132:80 dst_addr=192.168.0.198:37118 [ A ] protocol=6, IN_OUT=0, DATA_OFF = 32, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.132:80 dst_addr=192.168.0.198:37118 [ AP] protocol=6, IN_OUT=0, DATA_OFF = 32, TCP_DATA_LEN = 842, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.198:37118 dst_addr=192.168.0.132:80 [ A ] protocol=6, IN_OUT=1, DATA_OFF = 32, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.198:37118 dst_addr=192.168.0.132:80 [ A ] protocol=6, IN_OUT=1, DATA_OFF = 32, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.132:80 dst_addr=192.168.0.198:37118 [ A ] protocol=6, IN_OUT=0, DATA_OFF = 32, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:45 FW_EXT kernel: my_fw: check_packet(): === HOOK_PACKET: packet src_addr=192.168.0.198:37118 dst_addr=192.168.0.132:80 [ A ] protocol=6, IN_OUT=1, DATA_OFF = 32, TCP_DATA_LEN = 0, if_fragmented = 0
Jan 22 17:27:49 FW_EXT kernel: my_fw: fw_cleanup(): Driver my_fw stoped

=============

  reply	other threads:[~2009-01-22 15:50 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-22 13:53 Re: TCP-packet with PUSH flag with wrong payload data in LOCAL_OUT Кобылянский Владимир
2009-01-22 14:27 ` Jan Engelhardt
2009-01-22 15:40   ` Vladimir Kobylyanskiy [this message]
2009-01-22 16:11     ` Jan Engelhardt
2009-01-22 16:54       ` Vladimir Kobylyanskiy
2009-01-22 17:22         ` Jan Engelhardt
2009-01-22 18:15       ` James King
2009-01-22 18:57         ` Jan Engelhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=68611232638800@webmail51.yandex.ru \
    --to=kentlinux@yandex.ru \
    --cc=jengelh@medozas.de \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.