* 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.