diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c index 7936f7e..5575334 100644 --- a/net/netfilter/xt_pkttype.c +++ b/net/netfilter/xt_pkttype.c @@ -29,18 +29,21 @@ pkttype_mt(const struct sk_buff *skb, const struct net_device *in, bool *hotdrop) { const struct xt_pkttype_info *info = matchinfo; - u_int8_t type; + u_int8_t type = 0; - if (skb->pkt_type != PACKET_LOOPBACK) - type = skb->pkt_type; - else if (match->family == AF_INET && - ipv4_is_multicast(ip_hdr(skb)->daddr)) - type = PACKET_MULTICAST; - else if (match->family == AF_INET6 && + if (match->family == AF_INET) { + const struct net *net = dev_net(skb->dst->dev); + const struct iphdr *iph = ip_hdr(skb); + if (ipv4_is_multicast(iph->daddr)) + type = PACKET_MULTICAST; + else if (inet_addr_type(net, iph->daddr) == RTN_BROADCAST) + type = PACKET_BROADCAST; + } else if (match->family == AF_INET6 && ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF) type = PACKET_MULTICAST; - else - type = PACKET_BROADCAST; + + if (!type) + type = skb->pkt_type; return (type == info->pkttype) ^ info->invert; }