NETFILTER: remove unnecessary goto statement for error recovery
[tomato.git] / release / src-rt / linux / linux-2.6 / net / ipv4 / netfilter / ipt_mport.c
blobb01121971f7aa88aa9064e133ac78438e18c8ee6
1 /* Kernel module to match one of a list of TCP/UDP ports: ports are in
2 the same place so we can treat them as equal. */
3 #include <linux/module.h>
4 #include <linux/types.h>
5 #include <linux/udp.h>
6 #include <linux/skbuff.h>
7 #include <linux/version.h>
9 #include <linux/netfilter_ipv4/ipt_mport.h>
10 #include <linux/netfilter_ipv4/ip_tables.h>
12 MODULE_LICENSE("GPL");
14 #if 0
15 #define duprintf(format, args...) printk(format , ## args)
16 #else
17 #define duprintf(format, args...)
18 #endif
20 /* Returns 1 if the port is matched by the test, 0 otherwise. */
21 static inline int
22 ports_match(const struct ipt_mport *minfo, u_int16_t src, u_int16_t dst)
24 unsigned int i;
25 unsigned int m;
26 u_int16_t pflags = minfo->pflags;
27 for (i=0, m=1; i<IPT_MULTI_PORTS; i++, m<<=1) {
28 u_int16_t s, e;
30 if (pflags & m
31 && minfo->ports[i] == 65535)
32 return 0;
34 s = minfo->ports[i];
36 if (pflags & m) {
37 e = minfo->ports[++i];
38 m <<= 1;
39 } else
40 e = s;
42 if (minfo->flags & IPT_MPORT_SOURCE
43 && src >= s && src <= e)
44 return 1;
46 if (minfo->flags & IPT_MPORT_DESTINATION
47 && dst >= s && dst <= e)
48 return 1;
51 return 0;
54 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
55 static int
56 #else
57 static bool
58 #endif
59 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
60 match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out,
61 const struct xt_match *match, const void *matchinfo, int offset,
62 unsigned int protoff, int *hotdrop)
63 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) */
64 match(const struct sk_buff *skb, const struct xt_match_param *par)
65 #endif
67 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
68 const struct ipt_mport *minfo = matchinfo;
69 #else
70 const struct ipt_mport *minfo = par->matchinfo;
71 const int offset = par->fragoff;
72 #endif
73 const struct iphdr *ip = ip_hdr(skb);
74 const struct udphdr *udp = (void *)ip + ip->ihl * 4;
75 unsigned int datalen = ntohs(ip->tot_len);
77 /* Must be big enough to read ports. */
78 if (offset == 0 && datalen < sizeof(struct udphdr)) {
79 /* We've been asked to examine this packet, and we
80 can't. Hence, no choice but to drop. */
81 duprintf("ipt_mport:"
82 " Dropping evil offset=0 tinygram.\n");
83 *hotdrop = 1;
84 return 0;
87 /* Must not be a fragment. */
88 return !offset
89 && ports_match(minfo, ntohs(udp->source), ntohs(udp->dest));
92 /* Called when user tries to insert an entry of this type. */
93 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
94 static int
95 #else
96 static bool
97 #endif
98 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
99 checkentry(const char *tablename, const void *inf, const struct xt_match *match,
100 void *matchinfo, unsigned int hook_mask)
101 #else
102 checkentry(const struct xt_mtchk_param *par)
103 #endif
105 const struct ipt_ip *ip = inf;
107 /* Must specify proto == TCP/UDP, no unknown flags or bad count */
108 return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
109 && !(ip->invflags & IPT_INV_PROTO);
112 static struct xt_match mport_match = {
113 .name = "mport",
114 .family = AF_INET,
115 .match = &match,
116 .matchsize = sizeof(struct ipt_mport),
117 .checkentry = &checkentry,
118 .destroy = NULL,
119 .me = THIS_MODULE
122 static int __init init(void)
124 return xt_register_match(&mport_match);
127 static void __exit fini(void)
129 xt_unregister_match(&mport_match);
132 module_init(init);
133 module_exit(fini);