1 /* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
8 /* Get Layer-4 data from the packets */
11 #include <linux/skbuff.h>
12 #include <linux/icmp.h>
13 #include <linux/icmpv6.h>
14 #include <linux/netfilter_ipv6/ip6_tables.h>
17 #include <linux/netfilter/ipset/ip_set_getport.h>
19 /* We must handle non-linear skbs */
21 get_port(const struct sk_buff
*skb
, int protocol
, unsigned int protooff
,
22 bool src
, __be16
*port
, u8
*proto
)
27 const struct tcphdr
*th
;
29 th
= skb_header_pointer(skb
, protooff
, sizeof(_tcph
), &_tcph
);
31 /* No choice either */
34 *port
= src
? th
->source
: th
->dest
;
39 const struct udphdr
*uh
;
41 uh
= skb_header_pointer(skb
, protooff
, sizeof(_udph
), &_udph
);
43 /* No choice either */
46 *port
= src
? uh
->source
: uh
->dest
;
51 const struct icmphdr
*ic
;
53 ic
= skb_header_pointer(skb
, protooff
, sizeof(_ich
), &_ich
);
57 *port
= (__force __be16
)htons((ic
->type
<< 8) | ic
->code
);
60 case IPPROTO_ICMPV6
: {
62 const struct icmp6hdr
*ic
;
64 ic
= skb_header_pointer(skb
, protooff
, sizeof(_ich
), &_ich
);
68 *port
= (__force __be16
)
69 htons((ic
->icmp6_type
<< 8) | ic
->icmp6_code
);
81 ip_set_get_ip4_port(const struct sk_buff
*skb
, bool src
,
82 __be16
*port
, u8
*proto
)
84 const struct iphdr
*iph
= ip_hdr(skb
);
85 unsigned int protooff
= ip_hdrlen(skb
);
86 int protocol
= iph
->protocol
;
88 /* See comments at tcp_match in ip_tables.c */
89 if (protocol
<= 0 || (ntohs(iph
->frag_off
) & IP_OFFSET
))
92 return get_port(skb
, protocol
, protooff
, src
, port
, proto
);
94 EXPORT_SYMBOL_GPL(ip_set_get_ip4_port
);
97 ip_set_get_ip6_port(const struct sk_buff
*skb
, bool src
,
98 __be16
*port
, u8
*proto
)
100 unsigned int protooff
= 0;
102 unsigned short fragoff
;
104 protocol
= ipv6_find_hdr(skb
, &protooff
, -1, &fragoff
);
105 if (protocol
<= 0 || fragoff
)
108 return get_port(skb
, protocol
, protooff
, src
, port
, proto
);
110 EXPORT_SYMBOL_GPL(ip_set_get_ip6_port
);
113 ip_set_get_ip_port(const struct sk_buff
*skb
, u8 pf
, bool src
, __be16
*port
)
120 ret
= ip_set_get_ip4_port(skb
, src
, port
, &proto
);
123 ret
= ip_set_get_ip6_port(skb
, src
, port
, &proto
);
138 EXPORT_SYMBOL_GPL(ip_set_get_ip_port
);