linux-kerneliptableskernel-modulenetfilter

Netfilter hook doesn't see all packets


I wrote a kernel module that uses netfilter hook to dump multicast DNS packets.

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;
*/

This kernel module doesn't log all multicast dns packets' information. However, when I add this iptables log rule:

iptables -t mangle -I PREROUTING 1 -j LOG --log-prefix="mylog" --log-level 4 --ipv4 -p udp --sport 5353

This iptables rule sees/logs all multicast dns packets. I assume iptables uses netfilter hooks too. I have no idea why it sees all mdns packets but not my kernel module. Any ideas why? Thanks in advance.


Solution

  • Your iptables rule is checking for a source port of 5353 while your netfilter code is checking for a destination port of 5353. While most mDNS packets will have both source and destination ports of 5353, this isn't actually required by RFC 6762.

    Best of luck!