All of lore.kernel.org
 help / color / mirror / Atom feed
* Netfilter hook doesn't see all packets
@ 2019-11-14 20:23 Psyspy rambo
  2019-11-20 18:01 ` Psyspy rambo
  0 siblings, 1 reply; 7+ messages in thread
From: Psyspy rambo @ 2019-11-14 20:23 UTC (permalink / raw)
  To: netfilter

Hello,

I implemented a kernel module that hooks into netfilter PREROUTING
hook and tries to log multicast dns packet tuple. If I add a iptables
log rule for mdns (port 5353), it logs all mdns packets. Verified that
it matches tcpdump output. However, the netfilter hook sees only a few
packets. Any ideas why? Thanks in advance.

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

* Re: Netfilter hook doesn't see all packets
  2019-11-14 20:23 Netfilter hook doesn't see all packets Psyspy rambo
@ 2019-11-20 18:01 ` Psyspy rambo
  2019-11-21 18:08   ` Gordon Fisher
  0 siblings, 1 reply; 7+ messages in thread
From: Psyspy rambo @ 2019-11-20 18:01 UTC (permalink / raw)
  To: netfilter

Note: I am seeing this issue only on a specific host. It works fine on
another host running in router mode. Any ideas to debug this?

Adding this log rule logs all packets: iptables -t mangle -I
PREROUTING 1 -j LOG --log-prefix="mylog" --log-level 4 --ipv4 -p udp
--sport 5353
The kernel module doesn't see ALL multicast dns packets. I assume
iptables uses netfilter hooks too, which makes this issue strange.
Here is the module code:

static uint32_t myhook(uint32_t hooknum, struct sk_buff *skb, const
struct net_device *in,  const struct net_device *out, int (*okfn)
(struct sk_buff *))
{
    struct iphdr *ip_header;
    uint8_t proto;
    struct udphdr *udp_header;
    unsigned int sip, dip, sport = 0, dport = 0;

    if(!skb)
        return NF_ACCEPT;

    if(ntohs(skb->protocol) != ETH_P_IP)
        return NF_ACCEPT;

    ip_header = (struct iphdr *)skb_network_header(skb);
    proto = ip_header->protocol;

    if (proto != IPPROTO_UDP)
        return NF_ACCEPT;

    udp_header = (struct udphdr *)skb_transport_header(skb);
    sip = (unsigned int)ntohl(ip_header->saddr);
    dip = (unsigned int)ntohl(ip_header->daddr);
    sport = (unsigned int)ntohs(udp_header->source);
    dport = (unsigned int)ntohs(udp_header->dest);
    if (dport == 5353)
        pr_err("sip: %pI4h, sport: %u; dip: %pI4h, dport: %u\n", &sip,
sport, &dip, dport);
    return NF_ACCEPT;
}

/*
pre_routing_hook_ops.hooknum = NF_INET_PRE_ROUTING;
pre_routing_hook_ops.pf = PF_INET;
pre_routing_hook_ops.priority = NF_IP_PRI_FIRST;
pre_routing_hook_ops.hook = (nf_hookfn *) myhook;
*/

On Thu, Nov 14, 2019 at 1:23 PM Psyspy rambo <psyspy2020@gmail.com> wrote:
>
> Hello,
>
> I implemented a kernel module that hooks into netfilter PREROUTING
> hook and tries to log multicast dns packet tuple. If I add a iptables
> log rule for mdns (port 5353), it logs all mdns packets. Verified that
> it matches tcpdump output. However, the netfilter hook sees only a few
> packets. Any ideas why? Thanks in advance.

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

* Re: Netfilter hook doesn't see all packets
  2019-11-20 18:01 ` Psyspy rambo
@ 2019-11-21 18:08   ` Gordon Fisher
  2019-11-21 19:36     ` Psyspy rambo
  0 siblings, 1 reply; 7+ messages in thread
From: Gordon Fisher @ 2019-11-21 18:08 UTC (permalink / raw)
  To: netfilter

Looks like your problem is that your iptables LOG rule tests for sport 
5353 while your hook code tests for dport 5353, which would explain why 
you're seeing different results.

 > Adding this log rule logs all packets: iptables -t mangle -I
 > PREROUTING 1 -j LOG --log-prefix="mylog" --log-level 4 --ipv4
 > -p udp --sport 5353

 >     if (dport == 5353)
 >         pr_err("sip: %pI4h, sport: %u; dip: %pI4h, dport: %u\n",
 > &sip, sport, &dip, dport);

-- 
gordonfish


On 11/20/2019 10:01 AM, Psyspy rambo wrote:
> Note: I am seeing this issue only on a specific host. It works fine on
> another host running in router mode. Any ideas to debug this?
>
> Adding this log rule logs all packets: iptables -t mangle -I
> PREROUTING 1 -j LOG --log-prefix="mylog" --log-level 4 --ipv4 -p udp
> --sport 5353
> The kernel module doesn't see ALL multicast dns packets. I assume
> iptables uses netfilter hooks too, which makes this issue strange.
> Here is the module code:
>
> static uint32_t myhook(uint32_t hooknum, struct sk_buff *skb, const
> struct net_device *in,  const struct net_device *out, int (*okfn)
> (struct sk_buff *))
> {
>      struct iphdr *ip_header;
>      uint8_t proto;
>      struct udphdr *udp_header;
>      unsigned int sip, dip, sport = 0, dport = 0;
>
>      if(!skb)
>          return NF_ACCEPT;
>
>      if(ntohs(skb->protocol) != ETH_P_IP)
>          return NF_ACCEPT;
>
>      ip_header = (struct iphdr *)skb_network_header(skb);
>      proto = ip_header->protocol;
>
>      if (proto != IPPROTO_UDP)
>          return NF_ACCEPT;
>
>      udp_header = (struct udphdr *)skb_transport_header(skb);
>      sip = (unsigned int)ntohl(ip_header->saddr);
>      dip = (unsigned int)ntohl(ip_header->daddr);
>      sport = (unsigned int)ntohs(udp_header->source);
>      dport = (unsigned int)ntohs(udp_header->dest);
>      if (dport == 5353)
>          pr_err("sip: %pI4h, sport: %u; dip: %pI4h, dport: %u\n", &sip,
> sport, &dip, dport);
>      return NF_ACCEPT;
> }
>
> /*
> pre_routing_hook_ops.hooknum = NF_INET_PRE_ROUTING;
> pre_routing_hook_ops.pf = PF_INET;
> pre_routing_hook_ops.priority = NF_IP_PRI_FIRST;
> pre_routing_hook_ops.hook = (nf_hookfn *) myhook;
> */
>
> On Thu, Nov 14, 2019 at 1:23 PM Psyspy rambo <psyspy2020@gmail.com> wrote:
>> Hello,
>>
>> I implemented a kernel module that hooks into netfilter PREROUTING
>> hook and tries to log multicast dns packet tuple. If I add a iptables
>> log rule for mdns (port 5353), it logs all mdns packets. Verified that
>> it matches tcpdump output. However, the netfilter hook sees only a few
>> packets. Any ideas why? Thanks in advance.


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

* Re: Netfilter hook doesn't see all packets
  2019-11-21 18:08   ` Gordon Fisher
@ 2019-11-21 19:36     ` Psyspy rambo
  2019-11-21 20:36       ` Florian Westphal
  0 siblings, 1 reply; 7+ messages in thread
From: Psyspy rambo @ 2019-11-21 19:36 UTC (permalink / raw)
  To: Gordon Fisher; +Cc: netfilter

Thanks for the reply. For multicast dns flows, both source and
destination ports are 5353. Even if I remove the if statement and dump
all udp flows, the kernel module doesn't see all of them.

On Thu, Nov 21, 2019 at 11:09 AM Gordon Fisher <gordfisherman@gmail.com> wrote:
>
> Looks like your problem is that your iptables LOG rule tests for sport
> 5353 while your hook code tests for dport 5353, which would explain why
> you're seeing different results.
>
>  > Adding this log rule logs all packets: iptables -t mangle -I
>  > PREROUTING 1 -j LOG --log-prefix="mylog" --log-level 4 --ipv4
>  > -p udp --sport 5353
>
>  >     if (dport == 5353)
>  >         pr_err("sip: %pI4h, sport: %u; dip: %pI4h, dport: %u\n",
>  > &sip, sport, &dip, dport);
>
> --
> gordonfish
>
>
> On 11/20/2019 10:01 AM, Psyspy rambo wrote:
> > Note: I am seeing this issue only on a specific host. It works fine on
> > another host running in router mode. Any ideas to debug this?
> >
> > Adding this log rule logs all packets: iptables -t mangle -I
> > PREROUTING 1 -j LOG --log-prefix="mylog" --log-level 4 --ipv4 -p udp
> > --sport 5353
> > The kernel module doesn't see ALL multicast dns packets. I assume
> > iptables uses netfilter hooks too, which makes this issue strange.
> > Here is the module code:
> >
> > static uint32_t myhook(uint32_t hooknum, struct sk_buff *skb, const
> > struct net_device *in,  const struct net_device *out, int (*okfn)
> > (struct sk_buff *))
> > {
> >      struct iphdr *ip_header;
> >      uint8_t proto;
> >      struct udphdr *udp_header;
> >      unsigned int sip, dip, sport = 0, dport = 0;
> >
> >      if(!skb)
> >          return NF_ACCEPT;
> >
> >      if(ntohs(skb->protocol) != ETH_P_IP)
> >          return NF_ACCEPT;
> >
> >      ip_header = (struct iphdr *)skb_network_header(skb);
> >      proto = ip_header->protocol;
> >
> >      if (proto != IPPROTO_UDP)
> >          return NF_ACCEPT;
> >
> >      udp_header = (struct udphdr *)skb_transport_header(skb);
> >      sip = (unsigned int)ntohl(ip_header->saddr);
> >      dip = (unsigned int)ntohl(ip_header->daddr);
> >      sport = (unsigned int)ntohs(udp_header->source);
> >      dport = (unsigned int)ntohs(udp_header->dest);
> >      if (dport == 5353)
> >          pr_err("sip: %pI4h, sport: %u; dip: %pI4h, dport: %u\n", &sip,
> > sport, &dip, dport);
> >      return NF_ACCEPT;
> > }
> >
> > /*
> > pre_routing_hook_ops.hooknum = NF_INET_PRE_ROUTING;
> > pre_routing_hook_ops.pf = PF_INET;
> > pre_routing_hook_ops.priority = NF_IP_PRI_FIRST;
> > pre_routing_hook_ops.hook = (nf_hookfn *) myhook;
> > */
> >
> > On Thu, Nov 14, 2019 at 1:23 PM Psyspy rambo <psyspy2020@gmail.com> wrote:
> >> Hello,
> >>
> >> I implemented a kernel module that hooks into netfilter PREROUTING
> >> hook and tries to log multicast dns packet tuple. If I add a iptables
> >> log rule for mdns (port 5353), it logs all mdns packets. Verified that
> >> it matches tcpdump output. However, the netfilter hook sees only a few
> >> packets. Any ideas why? Thanks in advance.
>

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

* Re: Netfilter hook doesn't see all packets
  2019-11-21 19:36     ` Psyspy rambo
@ 2019-11-21 20:36       ` Florian Westphal
  2019-11-21 22:31         ` Psyspy rambo
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Westphal @ 2019-11-21 20:36 UTC (permalink / raw)
  To: Psyspy rambo; +Cc: Gordon Fisher, netfilter

Psyspy rambo <psyspy2020@gmail.com> wrote:
> > >      udp_header = (struct udphdr *)skb_transport_header(skb);
> > >      sip = (unsigned int)ntohl(ip_header->saddr);
> > >      dip = (unsigned int)ntohl(ip_header->daddr);

This doesn't work reliably in netfilter hooks.

See skb_header_pointer() usage in other nf modules.

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

* Re: Netfilter hook doesn't see all packets
  2019-11-21 20:36       ` Florian Westphal
@ 2019-11-21 22:31         ` Psyspy rambo
  2019-11-21 23:39           ` Psyspy rambo
  0 siblings, 1 reply; 7+ messages in thread
From: Psyspy rambo @ 2019-11-21 22:31 UTC (permalink / raw)
  To: Florian Westphal; +Cc: Gordon Fisher, netfilter

Thanks a lot Florian. That fixed it! Curious, why is it unreliable?

On Thu, Nov 21, 2019 at 1:36 PM Florian Westphal <fw@strlen.de> wrote:
>
> Psyspy rambo <psyspy2020@gmail.com> wrote:
> > > >      udp_header = (struct udphdr *)skb_transport_header(skb);
> > > >      sip = (unsigned int)ntohl(ip_header->saddr);
> > > >      dip = (unsigned int)ntohl(ip_header->daddr);
>
> This doesn't work reliably in netfilter hooks.
>
> See skb_header_pointer() usage in other nf modules.

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

* Re: Netfilter hook doesn't see all packets
  2019-11-21 22:31         ` Psyspy rambo
@ 2019-11-21 23:39           ` Psyspy rambo
  0 siblings, 0 replies; 7+ messages in thread
From: Psyspy rambo @ 2019-11-21 23:39 UTC (permalink / raw)
  To: Florian Westphal; +Cc: Gordon Fisher, netfilter

Sorry, my last reply was marked as SPAM.
I totally forget about paged data. I think that's the issue, right?

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

end of thread, other threads:[~2019-11-21 23:39 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-14 20:23 Netfilter hook doesn't see all packets Psyspy rambo
2019-11-20 18:01 ` Psyspy rambo
2019-11-21 18:08   ` Gordon Fisher
2019-11-21 19:36     ` Psyspy rambo
2019-11-21 20:36       ` Florian Westphal
2019-11-21 22:31         ` Psyspy rambo
2019-11-21 23:39           ` Psyspy rambo

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.