All of lore.kernel.org
 help / color / mirror / Atom feed
* Problem getting IPv6 port numbers
@ 2011-03-25 11:27 Mark Montague
  2011-03-25 13:29 ` Jan Engelhardt
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Montague @ 2011-03-25 11:27 UTC (permalink / raw)
  To: netfilter-devel

  I'm writing a netfilter match extension (xtables-addons 1.33, kernel 
2.6.35, .family=NFPROTO_UNSPEC) that needs to examine the source and 
destination port numbers of all packets.  The following code 
successfully gets the port numbers for IPv4 TCP and UDP packets:

static bool xt_mymatch_mt(const struct sk_buff *skb,
                           struct xt_action_param *par)
{
         const __be16 *pptr;
         __be16 _ports[2];
         int sport = 0;
         int dport = 0;

         if (par->fragoff == 0) {
                 pptr = skb_header_pointer(skb, par->thoff,
                         sizeof(_ports), _ports);
                 if (pptr != NULL) {
                         sport = ntohs(pptr[0]);
                         dport = ntohs(pptr[1]);
                 }
         }
         /* ...remaining code omitted... */
}

However, when I test this with "telnet ::1 1234", it does not work for 
IPv6 TCP packets (I have not tried with IPv6 UDP packets yet).  By 
adding printk() statements, I've determined that par->fragoff is never 0 
for my IPv6 TCP packets -- instead, it is large numbers such as 
33569744, 2164528116, or 2164412871.  However, par->in and par->out are 
both correct.  par->matchinfo, ipv6_hdr(skb)->saddr, and 
ipv6_hdr(skb)->daddr are also all correct.

What am I doing wrong?

Thanks in advance for any help.

--
   Mark Montague
   mark@catseye.org


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

* Re: Problem getting IPv6 port numbers
  2011-03-25 11:27 Problem getting IPv6 port numbers Mark Montague
@ 2011-03-25 13:29 ` Jan Engelhardt
  2011-03-26  2:54   ` Mark Montague
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Engelhardt @ 2011-03-25 13:29 UTC (permalink / raw)
  To: Mark Montague; +Cc: netfilter-devel

On Friday 2011-03-25 12:27, Mark Montague wrote:

> I'm writing a netfilter match extension (xtables-addons 1.33, kernel 2.6.35,
> .family=NFPROTO_UNSPEC) that needs to examine the source and destination port
> numbers of all packets.  The following code successfully gets the port numbers
> for IPv4 TCP and UDP packets:
>
> static bool xt_mymatch_mt(const struct sk_buff *skb,
>                          struct xt_action_param *par)
> {
>        const __be16 *pptr;
>        __be16 _ports[2];
>        int sport = 0;
>        int dport = 0;
>
>        if (par->fragoff == 0) {
>                pptr = skb_header_pointer(skb, par->thoff,
>                        sizeof(_ports), _ports);
>                if (pptr != NULL) {
>                        sport = ntohs(pptr[0]);
>                        dport = ntohs(pptr[1]);
>                }
>        }
>        /* ...remaining code omitted... */
> }
>
> However, when I test this with "telnet ::1 1234", it does not work for IPv6 TCP
> packets (I have not tried with IPv6 UDP packets yet).  By adding printk()
> statements, I've determined that par->fragoff is never 0 for my IPv6 TCP
> packets -- instead, it is large numbers such as 33569744, 2164528116, or
> 2164412871.  However, par->in and par->out are both correct.  par->matchinfo,
> ipv6_hdr(skb)->saddr, and ipv6_hdr(skb)->daddr are also all correct.

It seems that for IPv6, fragoff is only filled when you explicitly test 
for a protocol using -p.

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

* Re: Problem getting IPv6 port numbers
  2011-03-25 13:29 ` Jan Engelhardt
@ 2011-03-26  2:54   ` Mark Montague
  2011-03-26 12:19     ` Jan Engelhardt
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Montague @ 2011-03-26  2:54 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

  On March 25, 2011 9:29 , Jan Engelhardt <jengelh@medozas.de>  wrote:
>>         if (par->fragoff == 0) {
>>                 pptr = skb_header_pointer(skb, par->thoff,
>>                         sizeof(_ports), _ports);
>>                 if (pptr != NULL) {
>>                         sport = ntohs(pptr[0]);
>>                         dport = ntohs(pptr[1]);
>>                 }
>>         }
>>         /* ...remaining code omitted... */
>> }
>>
>> However, when I test this with "telnet ::1 1234", it does not work for IPv6 TCP
>> packets (I have not tried with IPv6 UDP packets yet).  By adding printk()
>> statements, I've determined that par->fragoff is never 0 for my IPv6 TCP
>> packets
> It seems that for IPv6, fragoff is only filled when you explicitly test
> for a protocol using -p.

This was the problem.  Many thanks for the answer!

Adding a "-p tcp" to my ip6tables rule causes the above code to report 
the source and destination port numbers properly.

Also of note:  it seems like the transport header can only be retrieved 
if the ip6tables rule explicitly tests for a protocol:  Without a -p 
test, I took out the "if (par->fragoff == 0)" check, with the result 
that the sport and dport were set to random (incorrect) numbers.

So I'll continue checking fragoff and I'll put in the documentation for 
the module I'm writing, "If you are using IPv6, port numbers are only 
available if you use '-p tcp' or '-p udp' in your ip6tables rule.  For 
IPv4, you do not have to use a -p test in your iptables rule; ports will 
automatically be correctly reported for protocols that use ports, and 
will be reported as 0 for protocols that do not use ports."

--
   Mark Montague
   mark@catseye.org


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

* Re: Problem getting IPv6 port numbers
  2011-03-26  2:54   ` Mark Montague
@ 2011-03-26 12:19     ` Jan Engelhardt
  0 siblings, 0 replies; 4+ messages in thread
From: Jan Engelhardt @ 2011-03-26 12:19 UTC (permalink / raw)
  To: Mark Montague; +Cc: netfilter-devel


On Saturday 2011-03-26 03:54, Mark Montague wrote:
>
>> It seems that for IPv6, fragoff is only filled when you explicitly test
>> for a protocol using -p.
>
> This was the problem.  Many thanks for the answer!
>
> Adding a "-p tcp" to my ip6tables rule causes the above code to report the
> source and destination port numbers properly.
>
> Also of note:  it seems like the transport header can only be retrieved if the
> ip6tables rule explicitly tests for a protocol:  Without a -p test, I took out
> the "if (par->fragoff == 0)" check, with the result that the sport and dport
> were set to random (incorrect) numbers.

Because like fragoff, thoff is only filled in if you actually want to
match something. Calculating fragoff/thoff is somewhat more
computationally intensive, as there may be many headers in a IPv6
packet, whereas there is just one static one in IPv4.

Specifically, if you use (ipv6) -p frag, fragoff and thoff will be
valid, but testing for sport/dport will do garbage too, because they
do not actually point to a TCP header.

Yeah this ought to get better..

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

end of thread, other threads:[~2011-03-26 12:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-25 11:27 Problem getting IPv6 port numbers Mark Montague
2011-03-25 13:29 ` Jan Engelhardt
2011-03-26  2:54   ` Mark Montague
2011-03-26 12:19     ` Jan Engelhardt

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.