[NETFILTER] x_tables: Abstraction layer for {ip,ip6,arp}_tables

This monster-patch tries to do the best job for unifying the data
structures and backend interfaces for the three evil clones ip_tables,
ip6_tables and arp_tables. In an ideal world we would never have
allowed this kind of copy+paste programming... but well, our world
isn't (yet?) ideal.

o introduce a new x_tables module
o {ip,arp,ip6}_tables depend on this x_tables module
o registration functions for tables, matches and targets are only
wrappers around x_tables provided functions
o all matches/targets that are used from ip_tables and ip6_tables
are now implemented as xt_FOOBAR.c files and provide module aliases
to ipt_FOOBAR and ip6t_FOOBAR
o header files for xt_matches are in include/linux/netfilter/,
include/linux/netfilter_{ipv4,ipv6} contains compatibility wrappers
around the xt_FOOBAR.h headers

Based on this patchset we're going to further unify the code,
gradually getting rid of all the layer 3 specific assumptions.

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Harald Welte and committed by David S. Miller 2e4e6a17 880b005f

+5671 -6205
+3
include/linux/netfilter/nf_conntrack_common.h
··· 154 unsigned int expect_delete; 155 }; 156 157 #endif /* __KERNEL__ */ 158 159 #endif /* _NF_CONNTRACK_COMMON_H */
··· 154 unsigned int expect_delete; 155 }; 156 157 + /* call to create an explicit dependency on nf_conntrack. */ 158 + extern void need_conntrack(void); 159 + 160 #endif /* __KERNEL__ */ 161 162 #endif /* _NF_CONNTRACK_COMMON_H */
+224
include/linux/netfilter/x_tables.h
···
··· 1 + #ifndef _X_TABLES_H 2 + #define _X_TABLES_H 3 + 4 + #define XT_FUNCTION_MAXNAMELEN 30 5 + #define XT_TABLE_MAXNAMELEN 32 6 + 7 + /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision 8 + * kernel supports, if >= revision. */ 9 + struct xt_get_revision 10 + { 11 + char name[XT_FUNCTION_MAXNAMELEN-1]; 12 + 13 + u_int8_t revision; 14 + }; 15 + 16 + /* CONTINUE verdict for targets */ 17 + #define XT_CONTINUE 0xFFFFFFFF 18 + 19 + /* For standard target */ 20 + #define XT_RETURN (-NF_REPEAT - 1) 21 + 22 + #define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1)) 23 + 24 + /* Standard return verdict, or do jump. */ 25 + #define XT_STANDARD_TARGET "" 26 + /* Error verdict. */ 27 + #define XT_ERROR_TARGET "ERROR" 28 + 29 + /* 30 + * New IP firewall options for [gs]etsockopt at the RAW IP level. 31 + * Unlike BSD Linux inherits IP options so you don't have to use a raw 32 + * socket for this. Instead we check rights in the calls. */ 33 + #define XT_BASE_CTL 64 /* base for firewall socket options */ 34 + 35 + #define XT_SO_SET_REPLACE (XT_BASE_CTL) 36 + #define XT_SO_SET_ADD_COUNTERS (XT_BASE_CTL + 1) 37 + #define XT_SO_SET_MAX XT_SO_SET_ADD_COUNTERS 38 + 39 + #define XT_SO_GET_INFO (XT_BASE_CTL) 40 + #define XT_SO_GET_ENTRIES (XT_BASE_CTL + 1) 41 + #define XT_SO_GET_REVISION_MATCH (XT_BASE_CTL + 2) 42 + #define XT_SO_GET_REVISION_TARGET (XT_BASE_CTL + 3) 43 + #define XT_SO_GET_MAX XT_SO_GET_REVISION_TARGET 44 + 45 + #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 46 + #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 47 + 48 + struct xt_counters 49 + { 50 + u_int64_t pcnt, bcnt; /* Packet and byte counters */ 51 + }; 52 + 53 + /* The argument to IPT_SO_ADD_COUNTERS. */ 54 + struct xt_counters_info 55 + { 56 + /* Which table. */ 57 + char name[XT_TABLE_MAXNAMELEN]; 58 + 59 + unsigned int num_counters; 60 + 61 + /* The counters (actually `number' of these). */ 62 + struct xt_counters counters[0]; 63 + }; 64 + 65 + #define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 66 + 67 + #ifdef __KERNEL__ 68 + 69 + #include <linux/netdevice.h> 70 + 71 + #define ASSERT_READ_LOCK(x) 72 + #define ASSERT_WRITE_LOCK(x) 73 + #include <linux/netfilter_ipv4/listhelp.h> 74 + 75 + struct xt_match 76 + { 77 + struct list_head list; 78 + 79 + const char name[XT_FUNCTION_MAXNAMELEN-1]; 80 + 81 + u_int8_t revision; 82 + 83 + /* Return true or false: return FALSE and set *hotdrop = 1 to 84 + force immediate packet drop. */ 85 + /* Arguments changed since 2.6.9, as this must now handle 86 + non-linear skb, using skb_header_pointer and 87 + skb_ip_make_writable. */ 88 + int (*match)(const struct sk_buff *skb, 89 + const struct net_device *in, 90 + const struct net_device *out, 91 + const void *matchinfo, 92 + int offset, 93 + unsigned int protoff, 94 + int *hotdrop); 95 + 96 + /* Called when user tries to insert an entry of this type. */ 97 + /* Should return true or false. */ 98 + int (*checkentry)(const char *tablename, 99 + const void *ip, 100 + void *matchinfo, 101 + unsigned int matchinfosize, 102 + unsigned int hook_mask); 103 + 104 + /* Called when entry of this type deleted. */ 105 + void (*destroy)(void *matchinfo, unsigned int matchinfosize); 106 + 107 + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 108 + struct module *me; 109 + }; 110 + 111 + /* Registration hooks for targets. */ 112 + struct xt_target 113 + { 114 + struct list_head list; 115 + 116 + const char name[XT_FUNCTION_MAXNAMELEN-1]; 117 + 118 + u_int8_t revision; 119 + 120 + /* Returns verdict. Argument order changed since 2.6.9, as this 121 + must now handle non-linear skbs, using skb_copy_bits and 122 + skb_ip_make_writable. */ 123 + unsigned int (*target)(struct sk_buff **pskb, 124 + const struct net_device *in, 125 + const struct net_device *out, 126 + unsigned int hooknum, 127 + const void *targinfo, 128 + void *userdata); 129 + 130 + /* Called when user tries to insert an entry of this type: 131 + hook_mask is a bitmask of hooks from which it can be 132 + called. */ 133 + /* Should return true or false. */ 134 + int (*checkentry)(const char *tablename, 135 + const void *entry, 136 + void *targinfo, 137 + unsigned int targinfosize, 138 + unsigned int hook_mask); 139 + 140 + /* Called when entry of this type deleted. */ 141 + void (*destroy)(void *targinfo, unsigned int targinfosize); 142 + 143 + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 144 + struct module *me; 145 + }; 146 + 147 + /* Furniture shopping... */ 148 + struct xt_table 149 + { 150 + struct list_head list; 151 + 152 + /* A unique name... */ 153 + char name[XT_TABLE_MAXNAMELEN]; 154 + 155 + /* What hooks you will enter on */ 156 + unsigned int valid_hooks; 157 + 158 + /* Lock for the curtain */ 159 + rwlock_t lock; 160 + 161 + /* Man behind the curtain... */ 162 + //struct ip6t_table_info *private; 163 + void *private; 164 + 165 + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 166 + struct module *me; 167 + 168 + int af; /* address/protocol family */ 169 + }; 170 + 171 + #include <linux/netfilter_ipv4.h> 172 + 173 + /* The table itself */ 174 + struct xt_table_info 175 + { 176 + /* Size per table */ 177 + unsigned int size; 178 + /* Number of entries: FIXME. --RR */ 179 + unsigned int number; 180 + /* Initial number of entries. Needed for module usage count */ 181 + unsigned int initial_entries; 182 + 183 + /* Entry points and underflows */ 184 + unsigned int hook_entry[NF_IP_NUMHOOKS]; 185 + unsigned int underflow[NF_IP_NUMHOOKS]; 186 + 187 + /* ipt_entry tables: one per CPU */ 188 + char *entries[NR_CPUS]; 189 + }; 190 + 191 + extern int xt_register_target(int af, struct xt_target *target); 192 + extern void xt_unregister_target(int af, struct xt_target *target); 193 + extern int xt_register_match(int af, struct xt_match *target); 194 + extern void xt_unregister_match(int af, struct xt_match *target); 195 + 196 + extern int xt_register_table(struct xt_table *table, 197 + struct xt_table_info *bootstrap, 198 + struct xt_table_info *newinfo); 199 + extern void *xt_unregister_table(struct xt_table *table); 200 + 201 + extern struct xt_table_info *xt_replace_table(struct xt_table *table, 202 + unsigned int num_counters, 203 + struct xt_table_info *newinfo, 204 + int *error); 205 + 206 + extern struct xt_match *xt_find_match(int af, const char *name, u8 revision); 207 + extern struct xt_target *xt_find_target(int af, const char *name, u8 revision); 208 + extern struct xt_target *xt_request_find_target(int af, const char *name, 209 + u8 revision); 210 + extern int xt_find_revision(int af, const char *name, u8 revision, int target, 211 + int *err); 212 + 213 + extern struct xt_table *xt_find_table_lock(int af, const char *name); 214 + extern void xt_table_unlock(struct xt_table *t); 215 + 216 + extern int xt_proto_init(int af); 217 + extern void xt_proto_fini(int af); 218 + 219 + extern struct xt_table_info *xt_alloc_table_info(unsigned int size); 220 + extern void xt_free_table_info(struct xt_table_info *info); 221 + 222 + #endif /* __KERNEL__ */ 223 + 224 + #endif /* _X_TABLES_H */
+8
include/linux/netfilter/xt_CLASSIFY.h
···
··· 1 + #ifndef _XT_CLASSIFY_H 2 + #define _XT_CLASSIFY_H 3 + 4 + struct xt_classify_target_info { 5 + u_int32_t priority; 6 + }; 7 + 8 + #endif /*_XT_CLASSIFY_H */
+25
include/linux/netfilter/xt_CONNMARK.h
···
··· 1 + #ifndef _XT_CONNMARK_H_target 2 + #define _XT_CONNMARK_H_target 3 + 4 + /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + enum { 14 + XT_CONNMARK_SET = 0, 15 + XT_CONNMARK_SAVE, 16 + XT_CONNMARK_RESTORE 17 + }; 18 + 19 + struct xt_connmark_target_info { 20 + unsigned long mark; 21 + unsigned long mask; 22 + u_int8_t mode; 23 + }; 24 + 25 + #endif /*_XT_CONNMARK_H_target*/
+21
include/linux/netfilter/xt_MARK.h
···
··· 1 + #ifndef _XT_MARK_H_target 2 + #define _XT_MARK_H_target 3 + 4 + /* Version 0 */ 5 + struct xt_mark_target_info { 6 + unsigned long mark; 7 + }; 8 + 9 + /* Version 1 */ 10 + enum { 11 + XT_MARK_SET=0, 12 + XT_MARK_AND, 13 + XT_MARK_OR, 14 + }; 15 + 16 + struct xt_mark_target_info_v1 { 17 + unsigned long mark; 18 + u_int8_t mode; 19 + }; 20 + 21 + #endif /*_XT_MARK_H_target */
+16
include/linux/netfilter/xt_NFQUEUE.h
···
··· 1 + /* iptables module for using NFQUEUE mechanism 2 + * 3 + * (C) 2005 Harald Welte <laforge@netfilter.org> 4 + * 5 + * This software is distributed under GNU GPL v2, 1991 6 + * 7 + */ 8 + #ifndef _XT_NFQ_TARGET_H 9 + #define _XT_NFQ_TARGET_H 10 + 11 + /* target info */ 12 + struct xt_NFQ_info { 13 + u_int16_t queuenum; 14 + }; 15 + 16 + #endif /* _XT_NFQ_TARGET_H */
+10
include/linux/netfilter/xt_comment.h
···
··· 1 + #ifndef _XT_COMMENT_H 2 + #define _XT_COMMENT_H 3 + 4 + #define XT_MAX_COMMENT_LEN 256 5 + 6 + struct xt_comment_info { 7 + unsigned char comment[XT_MAX_COMMENT_LEN]; 8 + }; 9 + 10 + #endif /* XT_COMMENT_H */
+25
include/linux/netfilter/xt_connbytes.h
···
··· 1 + #ifndef _XT_CONNBYTES_H 2 + #define _XT_CONNBYTES_H 3 + 4 + enum xt_connbytes_what { 5 + XT_CONNBYTES_PKTS, 6 + XT_CONNBYTES_BYTES, 7 + XT_CONNBYTES_AVGPKT, 8 + }; 9 + 10 + enum xt_connbytes_direction { 11 + XT_CONNBYTES_DIR_ORIGINAL, 12 + XT_CONNBYTES_DIR_REPLY, 13 + XT_CONNBYTES_DIR_BOTH, 14 + }; 15 + 16 + struct xt_connbytes_info 17 + { 18 + struct { 19 + aligned_u64 from; /* count to be matched */ 20 + aligned_u64 to; /* count to be matched */ 21 + } count; 22 + u_int8_t what; /* ipt_connbytes_what */ 23 + u_int8_t direction; /* ipt_connbytes_direction */ 24 + }; 25 + #endif
+18
include/linux/netfilter/xt_connmark.h
···
··· 1 + #ifndef _XT_CONNMARK_H 2 + #define _XT_CONNMARK_H 3 + 4 + /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + struct xt_connmark_info { 14 + unsigned long mark, mask; 15 + u_int8_t invert; 16 + }; 17 + 18 + #endif /*_XT_CONNMARK_H*/
+63
include/linux/netfilter/xt_conntrack.h
···
··· 1 + /* Header file for kernel module to match connection tracking information. 2 + * GPL (C) 2001 Marc Boucher (marc@mbsi.ca). 3 + */ 4 + 5 + #ifndef _XT_CONNTRACK_H 6 + #define _XT_CONNTRACK_H 7 + 8 + #include <linux/netfilter/nf_conntrack_tuple_common.h> 9 + #include <linux/in.h> 10 + 11 + #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 12 + #define XT_CONNTRACK_STATE_INVALID (1 << 0) 13 + 14 + #define XT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) 15 + #define XT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) 16 + #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) 17 + 18 + /* flags, invflags: */ 19 + #define XT_CONNTRACK_STATE 0x01 20 + #define XT_CONNTRACK_PROTO 0x02 21 + #define XT_CONNTRACK_ORIGSRC 0x04 22 + #define XT_CONNTRACK_ORIGDST 0x08 23 + #define XT_CONNTRACK_REPLSRC 0x10 24 + #define XT_CONNTRACK_REPLDST 0x20 25 + #define XT_CONNTRACK_STATUS 0x40 26 + #define XT_CONNTRACK_EXPIRES 0x80 27 + 28 + /* This is exposed to userspace, so remains frozen in time. */ 29 + struct ip_conntrack_old_tuple 30 + { 31 + struct { 32 + __u32 ip; 33 + union { 34 + __u16 all; 35 + } u; 36 + } src; 37 + 38 + struct { 39 + __u32 ip; 40 + union { 41 + __u16 all; 42 + } u; 43 + 44 + /* The protocol. */ 45 + u16 protonum; 46 + } dst; 47 + }; 48 + 49 + struct xt_conntrack_info 50 + { 51 + unsigned int statemask, statusmask; 52 + 53 + struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; 54 + struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; 55 + 56 + unsigned long expires_min, expires_max; 57 + 58 + /* Flags word */ 59 + u_int8_t flags; 60 + /* Inverse flags */ 61 + u_int8_t invflags; 62 + }; 63 + #endif /*_XT_CONNTRACK_H*/
+23
include/linux/netfilter/xt_dccp.h
···
··· 1 + #ifndef _XT_DCCP_H_ 2 + #define _XT_DCCP_H_ 3 + 4 + #define XT_DCCP_SRC_PORTS 0x01 5 + #define XT_DCCP_DEST_PORTS 0x02 6 + #define XT_DCCP_TYPE 0x04 7 + #define XT_DCCP_OPTION 0x08 8 + 9 + #define XT_DCCP_VALID_FLAGS 0x0f 10 + 11 + struct xt_dccp_info { 12 + u_int16_t dpts[2]; /* Min, Max */ 13 + u_int16_t spts[2]; /* Min, Max */ 14 + 15 + u_int16_t flags; 16 + u_int16_t invflags; 17 + 18 + u_int16_t typemask; 19 + u_int8_t option; 20 + }; 21 + 22 + #endif /* _XT_DCCP_H_ */ 23 +
+8
include/linux/netfilter/xt_helper.h
···
··· 1 + #ifndef _XT_HELPER_H 2 + #define _XT_HELPER_H 3 + 4 + struct xt_helper_info { 5 + int invert; 6 + char name[30]; 7 + }; 8 + #endif /* _XT_HELPER_H */
+9
include/linux/netfilter/xt_length.h
···
··· 1 + #ifndef _XT_LENGTH_H 2 + #define _XT_LENGTH_H 3 + 4 + struct xt_length_info { 5 + u_int16_t min, max; 6 + u_int8_t invert; 7 + }; 8 + 9 + #endif /*_XT_LENGTH_H*/
+21
include/linux/netfilter/xt_limit.h
···
··· 1 + #ifndef _XT_RATE_H 2 + #define _XT_RATE_H 3 + 4 + /* timings are in milliseconds. */ 5 + #define XT_LIMIT_SCALE 10000 6 + 7 + /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 8 + seconds, or one every 59 hours. */ 9 + struct xt_rateinfo { 10 + u_int32_t avg; /* Average secs between packets * scale */ 11 + u_int32_t burst; /* Period multiplier for upper limit. */ 12 + 13 + /* Used internally by the kernel */ 14 + unsigned long prev; 15 + u_int32_t credit; 16 + u_int32_t credit_cap, cost; 17 + 18 + /* Ugly, ugly fucker. */ 19 + struct xt_rateinfo *master; 20 + }; 21 + #endif /*_XT_RATE_H*/
+8
include/linux/netfilter/xt_mac.h
···
··· 1 + #ifndef _XT_MAC_H 2 + #define _XT_MAC_H 3 + 4 + struct xt_mac_info { 5 + unsigned char srcaddr[ETH_ALEN]; 6 + int invert; 7 + }; 8 + #endif /*_XT_MAC_H*/
+9
include/linux/netfilter/xt_mark.h
···
··· 1 + #ifndef _XT_MARK_H 2 + #define _XT_MARK_H 3 + 4 + struct xt_mark_info { 5 + unsigned long mark, mask; 6 + u_int8_t invert; 7 + }; 8 + 9 + #endif /*_XT_MARK_H*/
+24
include/linux/netfilter/xt_physdev.h
···
··· 1 + #ifndef _XT_PHYSDEV_H 2 + #define _XT_PHYSDEV_H 3 + 4 + #ifdef __KERNEL__ 5 + #include <linux/if.h> 6 + #endif 7 + 8 + #define XT_PHYSDEV_OP_IN 0x01 9 + #define XT_PHYSDEV_OP_OUT 0x02 10 + #define XT_PHYSDEV_OP_BRIDGED 0x04 11 + #define XT_PHYSDEV_OP_ISIN 0x08 12 + #define XT_PHYSDEV_OP_ISOUT 0x10 13 + #define XT_PHYSDEV_OP_MASK (0x20 - 1) 14 + 15 + struct xt_physdev_info { 16 + char physindev[IFNAMSIZ]; 17 + char in_mask[IFNAMSIZ]; 18 + char physoutdev[IFNAMSIZ]; 19 + char out_mask[IFNAMSIZ]; 20 + u_int8_t invert; 21 + u_int8_t bitmask; 22 + }; 23 + 24 + #endif /*_XT_PHYSDEV_H*/
+8
include/linux/netfilter/xt_pkttype.h
···
··· 1 + #ifndef _XT_PKTTYPE_H 2 + #define _XT_PKTTYPE_H 3 + 4 + struct xt_pkttype_info { 5 + int pkttype; 6 + int invert; 7 + }; 8 + #endif /*_XT_PKTTYPE_H*/
+10
include/linux/netfilter/xt_realm.h
···
··· 1 + #ifndef _XT_REALM_H 2 + #define _XT_REALM_H 3 + 4 + struct xt_realm_info { 5 + u_int32_t id; 6 + u_int32_t mask; 7 + u_int8_t invert; 8 + }; 9 + 10 + #endif /* _XT_REALM_H */
+107
include/linux/netfilter/xt_sctp.h
···
··· 1 + #ifndef _XT_SCTP_H_ 2 + #define _XT_SCTP_H_ 3 + 4 + #define XT_SCTP_SRC_PORTS 0x01 5 + #define XT_SCTP_DEST_PORTS 0x02 6 + #define XT_SCTP_CHUNK_TYPES 0x04 7 + 8 + #define XT_SCTP_VALID_FLAGS 0x07 9 + 10 + #define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0])) 11 + 12 + 13 + struct xt_sctp_flag_info { 14 + u_int8_t chunktype; 15 + u_int8_t flag; 16 + u_int8_t flag_mask; 17 + }; 18 + 19 + #define XT_NUM_SCTP_FLAGS 4 20 + 21 + struct xt_sctp_info { 22 + u_int16_t dpts[2]; /* Min, Max */ 23 + u_int16_t spts[2]; /* Min, Max */ 24 + 25 + u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */ 26 + 27 + #define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */ 28 + #define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */ 29 + #define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */ 30 + 31 + u_int32_t chunk_match_type; 32 + struct xt_sctp_flag_info flag_info[XT_NUM_SCTP_FLAGS]; 33 + int flag_count; 34 + 35 + u_int32_t flags; 36 + u_int32_t invflags; 37 + }; 38 + 39 + #define bytes(type) (sizeof(type) * 8) 40 + 41 + #define SCTP_CHUNKMAP_SET(chunkmap, type) \ 42 + do { \ 43 + chunkmap[type / bytes(u_int32_t)] |= \ 44 + 1 << (type % bytes(u_int32_t)); \ 45 + } while (0) 46 + 47 + #define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ 48 + do { \ 49 + chunkmap[type / bytes(u_int32_t)] &= \ 50 + ~(1 << (type % bytes(u_int32_t))); \ 51 + } while (0) 52 + 53 + #define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ 54 + ({ \ 55 + (chunkmap[type / bytes (u_int32_t)] & \ 56 + (1 << (type % bytes (u_int32_t)))) ? 1: 0; \ 57 + }) 58 + 59 + #define SCTP_CHUNKMAP_RESET(chunkmap) \ 60 + do { \ 61 + int i; \ 62 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ 63 + chunkmap[i] = 0; \ 64 + } while (0) 65 + 66 + #define SCTP_CHUNKMAP_SET_ALL(chunkmap) \ 67 + do { \ 68 + int i; \ 69 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ 70 + chunkmap[i] = ~0; \ 71 + } while (0) 72 + 73 + #define SCTP_CHUNKMAP_COPY(destmap, srcmap) \ 74 + do { \ 75 + int i; \ 76 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ 77 + destmap[i] = srcmap[i]; \ 78 + } while (0) 79 + 80 + #define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \ 81 + ({ \ 82 + int i; \ 83 + int flag = 1; \ 84 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ 85 + if (chunkmap[i]) { \ 86 + flag = 0; \ 87 + break; \ 88 + } \ 89 + } \ 90 + flag; \ 91 + }) 92 + 93 + #define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \ 94 + ({ \ 95 + int i; \ 96 + int flag = 1; \ 97 + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ 98 + if (chunkmap[i] != ~0) { \ 99 + flag = 0; \ 100 + break; \ 101 + } \ 102 + } \ 103 + flag; \ 104 + }) 105 + 106 + #endif /* _XT_SCTP_H_ */ 107 +
+13
include/linux/netfilter/xt_state.h
···
··· 1 + #ifndef _XT_STATE_H 2 + #define _XT_STATE_H 3 + 4 + #define XT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 5 + #define XT_STATE_INVALID (1 << 0) 6 + 7 + #define XT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) 8 + 9 + struct xt_state_info 10 + { 11 + unsigned int statemask; 12 + }; 13 + #endif /*_XT_STATE_H*/
+18
include/linux/netfilter/xt_string.h
···
··· 1 + #ifndef _XT_STRING_H 2 + #define _XT_STRING_H 3 + 4 + #define XT_STRING_MAX_PATTERN_SIZE 128 5 + #define XT_STRING_MAX_ALGO_NAME_SIZE 16 6 + 7 + struct xt_string_info 8 + { 9 + u_int16_t from_offset; 10 + u_int16_t to_offset; 11 + char algo[XT_STRING_MAX_ALGO_NAME_SIZE]; 12 + char pattern[XT_STRING_MAX_PATTERN_SIZE]; 13 + u_int8_t patlen; 14 + u_int8_t invert; 15 + struct ts_config __attribute__((aligned(8))) *config; 16 + }; 17 + 18 + #endif /*_XT_STRING_H*/
+9
include/linux/netfilter/xt_tcpmss.h
···
··· 1 + #ifndef _XT_TCPMSS_MATCH_H 2 + #define _XT_TCPMSS_MATCH_H 3 + 4 + struct xt_tcpmss_match_info { 5 + u_int16_t mss_min, mss_max; 6 + u_int8_t invert; 7 + }; 8 + 9 + #endif /*_XT_TCPMSS_MATCH_H*/
+36
include/linux/netfilter/xt_tcpudp.h
···
··· 1 + #ifndef _XT_TCPUDP_H 2 + #define _XT_TCPUDP_H 3 + 4 + /* TCP matching stuff */ 5 + struct xt_tcp 6 + { 7 + u_int16_t spts[2]; /* Source port range. */ 8 + u_int16_t dpts[2]; /* Destination port range. */ 9 + u_int8_t option; /* TCP Option iff non-zero*/ 10 + u_int8_t flg_mask; /* TCP flags mask byte */ 11 + u_int8_t flg_cmp; /* TCP flags compare byte */ 12 + u_int8_t invflags; /* Inverse flags */ 13 + }; 14 + 15 + /* Values for "inv" field in struct ipt_tcp. */ 16 + #define XT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 17 + #define XT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 18 + #define XT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ 19 + #define XT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ 20 + #define XT_TCP_INV_MASK 0x0F /* All possible flags. */ 21 + 22 + /* UDP matching stuff */ 23 + struct xt_udp 24 + { 25 + u_int16_t spts[2]; /* Source port range. */ 26 + u_int16_t dpts[2]; /* Destination port range. */ 27 + u_int8_t invflags; /* Inverse flags */ 28 + }; 29 + 30 + /* Values for "invflags" field in struct ipt_udp. */ 31 + #define XT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 32 + #define XT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 33 + #define XT_UDP_INV_MASK 0x03 /* All possible flags. */ 34 + 35 + 36 + #endif
+25 -98
include/linux/netfilter_arp/arp_tables.h
··· 19 #include <linux/compiler.h> 20 #include <linux/netfilter_arp.h> 21 22 - #define ARPT_FUNCTION_MAXNAMELEN 30 23 - #define ARPT_TABLE_MAXNAMELEN 32 24 25 #define ARPT_DEV_ADDR_LEN_MAX 16 26 ··· 95 int verdict; 96 }; 97 98 - struct arpt_counters 99 - { 100 - u_int64_t pcnt, bcnt; /* Packet and byte counters */ 101 - }; 102 - 103 /* Values for "flag" field in struct arpt_ip (general arp structure). 104 * No flags defined yet. 105 */ ··· 129 unsigned int comefrom; 130 131 /* Packet and byte counters. */ 132 - struct arpt_counters counters; 133 134 /* The matches (if any), then the target. */ 135 unsigned char elems[0]; ··· 140 * Unlike BSD Linux inherits IP options so you don't have to use a raw 141 * socket for this. Instead we check rights in the calls. 142 */ 143 - #define ARPT_BASE_CTL 96 /* base for firewall socket options */ 144 145 - #define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL) 146 - #define ARPT_SO_SET_ADD_COUNTERS (ARPT_BASE_CTL + 1) 147 - #define ARPT_SO_SET_MAX ARPT_SO_SET_ADD_COUNTERS 148 149 - #define ARPT_SO_GET_INFO (ARPT_BASE_CTL) 150 - #define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1) 151 - /* #define ARPT_SO_GET_REVISION_MATCH (ARPT_BASE_CTL + 2)*/ 152 - #define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3) 153 - #define ARPT_SO_GET_MAX ARPT_SO_GET_REVISION_TARGET 154 155 /* CONTINUE verdict for targets */ 156 - #define ARPT_CONTINUE 0xFFFFFFFF 157 158 /* For standard target */ 159 - #define ARPT_RETURN (-NF_REPEAT - 1) 160 161 /* The argument to ARPT_SO_GET_INFO */ 162 struct arpt_getinfo ··· 208 /* Number of counters (must be equal to current number of entries). */ 209 unsigned int num_counters; 210 /* The old entries' counters. */ 211 - struct arpt_counters __user *counters; 212 213 /* The entries (hang off end: not really an array). */ 214 struct arpt_entry entries[0]; 215 }; 216 217 /* The argument to ARPT_SO_ADD_COUNTERS. */ 218 - struct arpt_counters_info 219 - { 220 - /* Which table. */ 221 - char name[ARPT_TABLE_MAXNAMELEN]; 222 - 223 - unsigned int num_counters; 224 - 225 - /* The counters (actually `number' of these). */ 226 - struct arpt_counters counters[0]; 227 - }; 228 229 /* The argument to ARPT_SO_GET_ENTRIES. */ 230 struct arpt_get_entries ··· 230 struct arpt_entry entrytable[0]; 231 }; 232 233 - /* The argument to ARPT_SO_GET_REVISION_*. Returns highest revision 234 - * kernel supports, if >= revision. */ 235 - struct arpt_get_revision 236 - { 237 - char name[ARPT_FUNCTION_MAXNAMELEN-1]; 238 - 239 - u_int8_t revision; 240 - }; 241 - 242 /* Standard return verdict, or do jump. */ 243 - #define ARPT_STANDARD_TARGET "" 244 /* Error verdict. */ 245 - #define ARPT_ERROR_TARGET "ERROR" 246 247 /* Helper functions */ 248 static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e) ··· 263 */ 264 #ifdef __KERNEL__ 265 266 - /* Registration hooks for targets. */ 267 - struct arpt_target 268 - { 269 - struct list_head list; 270 - 271 - const char name[ARPT_FUNCTION_MAXNAMELEN-1]; 272 - 273 - u_int8_t revision; 274 - 275 - /* Returns verdict. */ 276 - unsigned int (*target)(struct sk_buff **pskb, 277 - unsigned int hooknum, 278 - const struct net_device *in, 279 - const struct net_device *out, 280 - const void *targinfo, 281 - void *userdata); 282 - 283 - /* Called when user tries to insert an entry of this type: 284 - hook_mask is a bitmask of hooks from which it can be 285 - called. */ 286 - /* Should return true or false. */ 287 - int (*checkentry)(const char *tablename, 288 - const struct arpt_entry *e, 289 - void *targinfo, 290 - unsigned int targinfosize, 291 - unsigned int hook_mask); 292 - 293 - /* Called when entry of this type deleted. */ 294 - void (*destroy)(void *targinfo, unsigned int targinfosize); 295 - 296 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 297 - struct module *me; 298 - }; 299 - 300 - extern int arpt_register_target(struct arpt_target *target); 301 - extern void arpt_unregister_target(struct arpt_target *target); 302 - 303 - /* Furniture shopping... */ 304 - struct arpt_table 305 - { 306 - struct list_head list; 307 - 308 - /* A unique name... */ 309 - char name[ARPT_TABLE_MAXNAMELEN]; 310 - 311 - /* What hooks you will enter on */ 312 - unsigned int valid_hooks; 313 - 314 - /* Lock for the curtain */ 315 - rwlock_t lock; 316 - 317 - /* Man behind the curtain... */ 318 - struct arpt_table_info *private; 319 - 320 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 321 - struct module *me; 322 - }; 323 324 extern int arpt_register_table(struct arpt_table *table, 325 const struct arpt_replace *repl);
··· 19 #include <linux/compiler.h> 20 #include <linux/netfilter_arp.h> 21 22 + #include <linux/netfilter/x_tables.h> 23 + 24 + #define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 25 + #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN 26 + #define arpt_target xt_target 27 + #define arpt_table xt_table 28 29 #define ARPT_DEV_ADDR_LEN_MAX 16 30 ··· 91 int verdict; 92 }; 93 94 /* Values for "flag" field in struct arpt_ip (general arp structure). 95 * No flags defined yet. 96 */ ··· 130 unsigned int comefrom; 131 132 /* Packet and byte counters. */ 133 + struct xt_counters counters; 134 135 /* The matches (if any), then the target. */ 136 unsigned char elems[0]; ··· 141 * Unlike BSD Linux inherits IP options so you don't have to use a raw 142 * socket for this. Instead we check rights in the calls. 143 */ 144 + #define ARPT_CTL_OFFSET 32 145 + #define ARPT_BASE_CTL (XT_BASE_CTL+ARPT_CTL_OFFSET) 146 147 + #define ARPT_SO_SET_REPLACE (XT_SO_SET_REPLACE+ARPT_CTL_OFFSET) 148 + #define ARPT_SO_SET_ADD_COUNTERS (XT_SO_SET_ADD_COUNTERS+ARPT_CTL_OFFSET) 149 + #define ARPT_SO_SET_MAX (XT_SO_SET_MAX+ARPT_CTL_OFFSET) 150 151 + #define ARPT_SO_GET_INFO (XT_SO_GET_INFO+ARPT_CTL_OFFSET) 152 + #define ARPT_SO_GET_ENTRIES (XT_SO_GET_ENTRIES+ARPT_CTL_OFFSET) 153 + /* #define ARPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH */ 154 + #define ARPT_SO_GET_REVISION_TARGET (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) 155 + #define ARPT_SO_GET_MAX (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) 156 157 /* CONTINUE verdict for targets */ 158 + #define ARPT_CONTINUE XT_CONTINUE 159 160 /* For standard target */ 161 + #define ARPT_RETURN XT_RETURN 162 163 /* The argument to ARPT_SO_GET_INFO */ 164 struct arpt_getinfo ··· 208 /* Number of counters (must be equal to current number of entries). */ 209 unsigned int num_counters; 210 /* The old entries' counters. */ 211 + struct xt_counters __user *counters; 212 213 /* The entries (hang off end: not really an array). */ 214 struct arpt_entry entries[0]; 215 }; 216 217 /* The argument to ARPT_SO_ADD_COUNTERS. */ 218 + #define arpt_counters_info xt_counters_info 219 220 /* The argument to ARPT_SO_GET_ENTRIES. */ 221 struct arpt_get_entries ··· 239 struct arpt_entry entrytable[0]; 240 }; 241 242 /* Standard return verdict, or do jump. */ 243 + #define ARPT_STANDARD_TARGET XT_STANDARD_TARGET 244 /* Error verdict. */ 245 + #define ARPT_ERROR_TARGET XT_ERROR_TARGET 246 247 /* Helper functions */ 248 static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e) ··· 281 */ 282 #ifdef __KERNEL__ 283 284 + #define arpt_register_target(tgt) xt_register_target(NF_ARP, tgt) 285 + #define arpt_unregister_target(tgt) xt_unregister_target(NF_ARP, tgt) 286 287 extern int arpt_register_table(struct arpt_table *table, 288 const struct arpt_replace *repl);
-3
include/linux/netfilter_ipv4/ip_conntrack.h
··· 199 nf_conntrack_put(&ct->ct_general); 200 } 201 202 - /* call to create an explicit dependency on ip_conntrack. */ 203 - extern void need_ip_conntrack(void); 204 - 205 extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, 206 const struct ip_conntrack_tuple *orig); 207
··· 199 nf_conntrack_put(&ct->ct_general); 200 } 201 202 extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, 203 const struct ip_conntrack_tuple *orig); 204
+47 -170
include/linux/netfilter_ipv4/ip_tables.h
··· 25 #include <linux/compiler.h> 26 #include <linux/netfilter_ipv4.h> 27 28 - #define IPT_FUNCTION_MAXNAMELEN 30 29 - #define IPT_TABLE_MAXNAMELEN 32 30 31 /* Yes, Virginia, you have to zero the padding. */ 32 struct ipt_ip { ··· 108 int verdict; 109 }; 110 111 - struct ipt_counters 112 - { 113 - u_int64_t pcnt, bcnt; /* Packet and byte counters */ 114 - }; 115 116 /* Values for "flag" field in struct ipt_ip (general ip structure). */ 117 #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ ··· 122 #define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ 123 #define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ 124 #define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */ 125 - #define IPT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 126 #define IPT_INV_MASK 0x7F /* All possible flag bits mask. */ 127 128 /* This structure defines each of the firewall rules. Consists of 3 ··· 144 unsigned int comefrom; 145 146 /* Packet and byte counters. */ 147 - struct ipt_counters counters; 148 149 /* The matches (if any), then the target. */ 150 unsigned char elems[0]; ··· 154 * New IP firewall options for [gs]etsockopt at the RAW IP level. 155 * Unlike BSD Linux inherits IP options so you don't have to use a raw 156 * socket for this. Instead we check rights in the calls. */ 157 - #define IPT_BASE_CTL 64 /* base for firewall socket options */ 158 159 - #define IPT_SO_SET_REPLACE (IPT_BASE_CTL) 160 - #define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1) 161 - #define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS 162 163 - #define IPT_SO_GET_INFO (IPT_BASE_CTL) 164 - #define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1) 165 - #define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) 166 - #define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) 167 - #define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET 168 169 - /* CONTINUE verdict for targets */ 170 - #define IPT_CONTINUE 0xFFFFFFFF 171 172 - /* For standard target */ 173 - #define IPT_RETURN (-NF_REPEAT - 1) 174 175 - /* TCP matching stuff */ 176 - struct ipt_tcp 177 - { 178 - u_int16_t spts[2]; /* Source port range. */ 179 - u_int16_t dpts[2]; /* Destination port range. */ 180 - u_int8_t option; /* TCP Option iff non-zero*/ 181 - u_int8_t flg_mask; /* TCP flags mask byte */ 182 - u_int8_t flg_cmp; /* TCP flags compare byte */ 183 - u_int8_t invflags; /* Inverse flags */ 184 - }; 185 186 - /* Values for "inv" field in struct ipt_tcp. */ 187 - #define IPT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 188 - #define IPT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 189 - #define IPT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ 190 - #define IPT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ 191 - #define IPT_TCP_INV_MASK 0x0F /* All possible flags. */ 192 - 193 - /* UDP matching stuff */ 194 - struct ipt_udp 195 - { 196 - u_int16_t spts[2]; /* Source port range. */ 197 - u_int16_t dpts[2]; /* Destination port range. */ 198 - u_int8_t invflags; /* Inverse flags */ 199 - }; 200 - 201 - /* Values for "invflags" field in struct ipt_udp. */ 202 - #define IPT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 203 - #define IPT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 204 - #define IPT_UDP_INV_MASK 0x03 /* All possible flags. */ 205 206 /* ICMP matching stuff */ 207 struct ipt_icmp ··· 243 /* Number of counters (must be equal to current number of entries). */ 244 unsigned int num_counters; 245 /* The old entries' counters. */ 246 - struct ipt_counters __user *counters; 247 248 /* The entries (hang off end: not really an array). */ 249 struct ipt_entry entries[0]; 250 }; 251 252 /* The argument to IPT_SO_ADD_COUNTERS. */ 253 - struct ipt_counters_info 254 - { 255 - /* Which table. */ 256 - char name[IPT_TABLE_MAXNAMELEN]; 257 - 258 - unsigned int num_counters; 259 - 260 - /* The counters (actually `number' of these). */ 261 - struct ipt_counters counters[0]; 262 - }; 263 264 /* The argument to IPT_SO_GET_ENTRIES. */ 265 struct ipt_get_entries ··· 265 struct ipt_entry entrytable[0]; 266 }; 267 268 - /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision 269 - * kernel supports, if >= revision. */ 270 - struct ipt_get_revision 271 - { 272 - char name[IPT_FUNCTION_MAXNAMELEN-1]; 273 - 274 - u_int8_t revision; 275 - }; 276 - 277 /* Standard return verdict, or do jump. */ 278 - #define IPT_STANDARD_TARGET "" 279 /* Error verdict. */ 280 - #define IPT_ERROR_TARGET "ERROR" 281 282 /* Helper functions */ 283 static __inline__ struct ipt_entry_target * ··· 321 #include <linux/init.h> 322 extern void ipt_init(void) __init; 323 324 - struct ipt_match 325 - { 326 - struct list_head list; 327 328 - const char name[IPT_FUNCTION_MAXNAMELEN-1]; 329 330 - u_int8_t revision; 331 332 - /* Return true or false: return FALSE and set *hotdrop = 1 to 333 - force immediate packet drop. */ 334 - /* Arguments changed since 2.4, as this must now handle 335 - non-linear skbs, using skb_copy_bits and 336 - skb_ip_make_writable. */ 337 - int (*match)(const struct sk_buff *skb, 338 - const struct net_device *in, 339 - const struct net_device *out, 340 - const void *matchinfo, 341 - int offset, 342 - int *hotdrop); 343 - 344 - /* Called when user tries to insert an entry of this type. */ 345 - /* Should return true or false. */ 346 - int (*checkentry)(const char *tablename, 347 - const struct ipt_ip *ip, 348 - void *matchinfo, 349 - unsigned int matchinfosize, 350 - unsigned int hook_mask); 351 - 352 - /* Called when entry of this type deleted. */ 353 - void (*destroy)(void *matchinfo, unsigned int matchinfosize); 354 - 355 - /* Set this to THIS_MODULE. */ 356 - struct module *me; 357 - }; 358 - 359 - /* Registration hooks for targets. */ 360 - struct ipt_target 361 - { 362 - struct list_head list; 363 - 364 - const char name[IPT_FUNCTION_MAXNAMELEN-1]; 365 - 366 - u_int8_t revision; 367 - 368 - /* Called when user tries to insert an entry of this type: 369 - hook_mask is a bitmask of hooks from which it can be 370 - called. */ 371 - /* Should return true or false. */ 372 - int (*checkentry)(const char *tablename, 373 - const struct ipt_entry *e, 374 - void *targinfo, 375 - unsigned int targinfosize, 376 - unsigned int hook_mask); 377 - 378 - /* Called when entry of this type deleted. */ 379 - void (*destroy)(void *targinfo, unsigned int targinfosize); 380 - 381 - /* Returns verdict. Argument order changed since 2.4, as this 382 - must now handle non-linear skbs, using skb_copy_bits and 383 - skb_ip_make_writable. */ 384 - unsigned int (*target)(struct sk_buff **pskb, 385 - const struct net_device *in, 386 - const struct net_device *out, 387 - unsigned int hooknum, 388 - const void *targinfo, 389 - void *userdata); 390 - 391 - /* Set this to THIS_MODULE. */ 392 - struct module *me; 393 - }; 394 - 395 - extern int ipt_register_target(struct ipt_target *target); 396 - extern void ipt_unregister_target(struct ipt_target *target); 397 - 398 - extern int ipt_register_match(struct ipt_match *match); 399 - extern void ipt_unregister_match(struct ipt_match *match); 400 - 401 - /* Furniture shopping... */ 402 - struct ipt_table 403 - { 404 - struct list_head list; 405 - 406 - /* A unique name... */ 407 - char name[IPT_TABLE_MAXNAMELEN]; 408 - 409 - /* What hooks you will enter on */ 410 - unsigned int valid_hooks; 411 - 412 - /* Lock for the curtain */ 413 - rwlock_t lock; 414 - 415 - /* Man behind the curtain... */ 416 - struct ipt_table_info *private; 417 - 418 - /* Set to THIS_MODULE. */ 419 - struct module *me; 420 - }; 421 422 /* net/sched/ipt.c: Gimme access to your targets! Gets target->me. */ 423 extern struct ipt_target *ipt_find_target(const char *name, u8 revision); ··· 356 struct ipt_error_target target; 357 }; 358 359 - extern int ipt_register_table(struct ipt_table *table, 360 - const struct ipt_replace *repl); 361 - extern void ipt_unregister_table(struct ipt_table *table); 362 extern unsigned int ipt_do_table(struct sk_buff **pskb, 363 unsigned int hook, 364 const struct net_device *in, ··· 363 struct ipt_table *table, 364 void *userdata); 365 366 - #define IPT_ALIGN(s) (((s) + (__alignof__(struct ipt_entry)-1)) & ~(__alignof__(struct ipt_entry)-1)) 367 #endif /*__KERNEL__*/ 368 #endif /* _IPTABLES_H */
··· 25 #include <linux/compiler.h> 26 #include <linux/netfilter_ipv4.h> 27 28 + #include <linux/netfilter/x_tables.h> 29 + 30 + #define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 31 + #define IPT_TABLE_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 32 + #define ipt_match xt_match 33 + #define ipt_target xt_target 34 + #define ipt_table xt_table 35 + #define ipt_get_revision xt_get_revision 36 37 /* Yes, Virginia, you have to zero the padding. */ 38 struct ipt_ip { ··· 102 int verdict; 103 }; 104 105 + #define ipt_counters xt_counters 106 107 /* Values for "flag" field in struct ipt_ip (general ip structure). */ 108 #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ ··· 119 #define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ 120 #define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ 121 #define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */ 122 + #define IPT_INV_PROTO XT_INV_PROTO 123 #define IPT_INV_MASK 0x7F /* All possible flag bits mask. */ 124 125 /* This structure defines each of the firewall rules. Consists of 3 ··· 141 unsigned int comefrom; 142 143 /* Packet and byte counters. */ 144 + struct xt_counters counters; 145 146 /* The matches (if any), then the target. */ 147 unsigned char elems[0]; ··· 151 * New IP firewall options for [gs]etsockopt at the RAW IP level. 152 * Unlike BSD Linux inherits IP options so you don't have to use a raw 153 * socket for this. Instead we check rights in the calls. */ 154 + #define IPT_BASE_CTL XT_BASE_CTL 155 156 + #define IPT_SO_SET_REPLACE XT_SO_SET_REPLACE 157 + #define IPT_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS 158 + #define IPT_SO_SET_MAX XT_SO_SET_MAX 159 160 + #define IPT_SO_GET_INFO XT_SO_GET_INFO 161 + #define IPT_SO_GET_ENTRIES XT_SO_GET_ENTRIES 162 + #define IPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH 163 + #define IPT_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET 164 + #define IPT_SO_GET_MAX XT_SO_GET_REVISION_TARGET 165 166 + #define IPT_CONTINUE XT_CONTINUE 167 + #define IPT_RETURN XT_RETURN 168 169 + #include <linux/netfilter/xt_tcpudp.h> 170 + #define ipt_udp xt_udp 171 + #define ipt_tcp xt_tcp 172 173 + #define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT 174 + #define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT 175 + #define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS 176 + #define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION 177 + #define IPT_TCP_INV_MASK XT_TCP_INV_MASK 178 179 + #define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT 180 + #define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT 181 + #define IPT_UDP_INV_MASK XT_UDP_INV_MASK 182 183 /* ICMP matching stuff */ 184 struct ipt_icmp ··· 260 /* Number of counters (must be equal to current number of entries). */ 261 unsigned int num_counters; 262 /* The old entries' counters. */ 263 + struct xt_counters __user *counters; 264 265 /* The entries (hang off end: not really an array). */ 266 struct ipt_entry entries[0]; 267 }; 268 269 /* The argument to IPT_SO_ADD_COUNTERS. */ 270 + #define ipt_counters_info xt_counters_info 271 272 /* The argument to IPT_SO_GET_ENTRIES. */ 273 struct ipt_get_entries ··· 291 struct ipt_entry entrytable[0]; 292 }; 293 294 /* Standard return verdict, or do jump. */ 295 + #define IPT_STANDARD_TARGET XT_STANDARD_TARGET 296 /* Error verdict. */ 297 + #define IPT_ERROR_TARGET XT_ERROR_TARGET 298 299 /* Helper functions */ 300 static __inline__ struct ipt_entry_target * ··· 356 #include <linux/init.h> 357 extern void ipt_init(void) __init; 358 359 + #define ipt_register_target(tgt) xt_register_target(AF_INET, tgt) 360 + #define ipt_unregister_target(tgt) xt_unregister_target(AF_INET, tgt) 361 362 + #define ipt_register_match(mtch) xt_register_match(AF_INET, mtch) 363 + #define ipt_unregister_match(mtch) xt_unregister_match(AF_INET, mtch) 364 365 + //#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl) 366 + //#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl) 367 368 + extern int ipt_register_table(struct ipt_table *table, 369 + const struct ipt_replace *repl); 370 + extern void ipt_unregister_table(struct ipt_table *table); 371 372 /* net/sched/ipt.c: Gimme access to your targets! Gets target->me. */ 373 extern struct ipt_target *ipt_find_target(const char *name, u8 revision); ··· 476 struct ipt_error_target target; 477 }; 478 479 extern unsigned int ipt_do_table(struct sk_buff **pskb, 480 unsigned int hook, 481 const struct net_device *in, ··· 486 struct ipt_table *table, 487 void *userdata); 488 489 + #define IPT_ALIGN(s) XT_ALIGN(s) 490 #endif /*__KERNEL__*/ 491 #endif /* _IPTABLES_H */
+2 -3
include/linux/netfilter_ipv4/ipt_CLASSIFY.h
··· 1 #ifndef _IPT_CLASSIFY_H 2 #define _IPT_CLASSIFY_H 3 4 - struct ipt_classify_target_info { 5 - u_int32_t priority; 6 - }; 7 8 #endif /*_IPT_CLASSIFY_H */
··· 1 #ifndef _IPT_CLASSIFY_H 2 #define _IPT_CLASSIFY_H 3 4 + #include <linux/netfilter/xt_CLASSIFY.h> 5 + #define ipt_classify_target_info xt_classify_target_info 6 7 #endif /*_IPT_CLASSIFY_H */
+5 -11
include/linux/netfilter_ipv4/ipt_CONNMARK.h
··· 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13 - enum { 14 - IPT_CONNMARK_SET = 0, 15 - IPT_CONNMARK_SAVE, 16 - IPT_CONNMARK_RESTORE 17 - }; 18 - 19 - struct ipt_connmark_target_info { 20 - unsigned long mark; 21 - unsigned long mask; 22 - u_int8_t mode; 23 - }; 24 25 #endif /*_IPT_CONNMARK_H_target*/
··· 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 + #include <linux/netfilter/xt_CONNMARK.h> 13 + #define IPT_CONNMARK_SET XT_CONNMARK_SET 14 + #define IPT_CONNMARK_SAVE XT_CONNMARK_SAVE 15 + #define IPT_CONNMARK_RESTORE XT_CONNMARK_RESTORE 16 17 + #define ipt_connmark_target_info xt_connmark_target_info 18 19 #endif /*_IPT_CONNMARK_H_target*/
+10 -12
include/linux/netfilter_ipv4/ipt_MARK.h
··· 1 #ifndef _IPT_MARK_H_target 2 #define _IPT_MARK_H_target 3 4 /* Version 0 */ 5 - struct ipt_mark_target_info { 6 - unsigned long mark; 7 - }; 8 9 /* Version 1 */ 10 - enum { 11 - IPT_MARK_SET=0, 12 - IPT_MARK_AND, 13 - IPT_MARK_OR 14 - }; 15 16 - struct ipt_mark_target_info_v1 { 17 - unsigned long mark; 18 - u_int8_t mode; 19 - }; 20 #endif /*_IPT_MARK_H_target*/
··· 1 #ifndef _IPT_MARK_H_target 2 #define _IPT_MARK_H_target 3 4 + /* Backwards compatibility for old userspace */ 5 + 6 + #include <linux/netfilter/xt_MARK.h> 7 + 8 /* Version 0 */ 9 + #define ipt_mark_target_info xt_mark_target_info 10 11 /* Version 1 */ 12 + #define IPT_MARK_SET XT_MARK_SET 13 + #define IPT_MARK_AND XT_MARK_AND 14 + #define IPT_MARK_OR XT_MARK_OR 15 16 + #define ipt_mark_target_info_v1 xt_mark_target_info_v1 17 + 18 #endif /*_IPT_MARK_H_target*/
+4 -4
include/linux/netfilter_ipv4/ipt_NFQUEUE.h
··· 8 #ifndef _IPT_NFQ_TARGET_H 9 #define _IPT_NFQ_TARGET_H 10 11 - /* target info */ 12 - struct ipt_NFQ_info { 13 - u_int16_t queuenum; 14 - }; 15 16 #endif /* _IPT_DSCP_TARGET_H */
··· 8 #ifndef _IPT_NFQ_TARGET_H 9 #define _IPT_NFQ_TARGET_H 10 11 + /* Backwards compatibility for old userspace */ 12 + #include <linux/netfilter/xt_NFQUEUE.h> 13 + 14 + #define ipt_NFQ_info xt_NFQ_info 15 16 #endif /* _IPT_DSCP_TARGET_H */
+4 -4
include/linux/netfilter_ipv4/ipt_comment.h
··· 1 #ifndef _IPT_COMMENT_H 2 #define _IPT_COMMENT_H 3 4 - #define IPT_MAX_COMMENT_LEN 256 5 6 - struct ipt_comment_info { 7 - unsigned char comment[IPT_MAX_COMMENT_LEN]; 8 - }; 9 10 #endif /* _IPT_COMMENT_H */
··· 1 #ifndef _IPT_COMMENT_H 2 #define _IPT_COMMENT_H 3 4 + #include <linux/netfilter/xt_comment.h> 5 6 + #define IPT_MAX_COMMENT_LEN XT_MAX_COMMENT_LEN 7 + 8 + #define ipt_comment_info xt_comment_info 9 10 #endif /* _IPT_COMMENT_H */
+12 -19
include/linux/netfilter_ipv4/ipt_connbytes.h
··· 1 #ifndef _IPT_CONNBYTES_H 2 #define _IPT_CONNBYTES_H 3 4 - enum ipt_connbytes_what { 5 - IPT_CONNBYTES_PKTS, 6 - IPT_CONNBYTES_BYTES, 7 - IPT_CONNBYTES_AVGPKT, 8 - }; 9 10 - enum ipt_connbytes_direction { 11 - IPT_CONNBYTES_DIR_ORIGINAL, 12 - IPT_CONNBYTES_DIR_REPLY, 13 - IPT_CONNBYTES_DIR_BOTH, 14 - }; 15 16 - struct ipt_connbytes_info 17 - { 18 - struct { 19 - aligned_u64 from; /* count to be matched */ 20 - aligned_u64 to; /* count to be matched */ 21 - } count; 22 - u_int8_t what; /* ipt_connbytes_what */ 23 - u_int8_t direction; /* ipt_connbytes_direction */ 24 - }; 25 #endif
··· 1 #ifndef _IPT_CONNBYTES_H 2 #define _IPT_CONNBYTES_H 3 4 + #include <net/netfilter/xt_connbytes.h> 5 + #define ipt_connbytes_what xt_connbytes_what 6 7 + #define IPT_CONNBYTES_PKTS XT_CONNBYTES_PACKETS 8 + #define IPT_CONNBYTES_BYTES XT_CONNBYTES_BYTES 9 + #define IPT_CONNBYTES_AVGPKT XT_CONNBYTES_AVGPKT 10 11 + #define ipt_connbytes_direction xt_connbytes_direction 12 + #define IPT_CONNBYTES_DIR_ORIGINAL XT_CONNBYTES_DIR_ORIGINAL 13 + #define IPT_CONNBYTES_DIR_REPLY XT_CONNBYTES_DIR_REPLY 14 + #define IPT_CONNBYTES_DIR_BOTH XT_CONNBYTES_DIR_BOTH 15 + 16 + #define ipt_connbytes_info xt_connbytes_info 17 + 18 #endif
+2 -13
include/linux/netfilter_ipv4/ipt_connmark.h
··· 1 #ifndef _IPT_CONNMARK_H 2 #define _IPT_CONNMARK_H 3 4 - /* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 - * by Henrik Nordstrom <hno@marasystems.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - */ 12 - 13 - struct ipt_connmark_info { 14 - unsigned long mark, mask; 15 - u_int8_t invert; 16 - }; 17 18 #endif /*_IPT_CONNMARK_H*/
··· 1 #ifndef _IPT_CONNMARK_H 2 #define _IPT_CONNMARK_H 3 4 + #include <linux/netfilter/xt_connmark.h> 5 + #define ipt_connmark_info xt_connmark_info 6 7 #endif /*_IPT_CONNMARK_H*/
+16 -48
include/linux/netfilter_ipv4/ipt_conntrack.h
··· 5 #ifndef _IPT_CONNTRACK_H 6 #define _IPT_CONNTRACK_H 7 8 - #define IPT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 9 - #define IPT_CONNTRACK_STATE_INVALID (1 << 0) 10 11 - #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) 12 - #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) 13 - #define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) 14 15 /* flags, invflags: */ 16 - #define IPT_CONNTRACK_STATE 0x01 17 - #define IPT_CONNTRACK_PROTO 0x02 18 - #define IPT_CONNTRACK_ORIGSRC 0x04 19 - #define IPT_CONNTRACK_ORIGDST 0x08 20 - #define IPT_CONNTRACK_REPLSRC 0x10 21 - #define IPT_CONNTRACK_REPLDST 0x20 22 - #define IPT_CONNTRACK_STATUS 0x40 23 - #define IPT_CONNTRACK_EXPIRES 0x80 24 25 - /* This is exposed to userspace, so remains frozen in time. */ 26 - struct ip_conntrack_old_tuple 27 - { 28 - struct { 29 - __u32 ip; 30 - union { 31 - __u16 all; 32 - } u; 33 - } src; 34 - 35 - struct { 36 - __u32 ip; 37 - union { 38 - __u16 all; 39 - } u; 40 - 41 - /* The protocol. */ 42 - u16 protonum; 43 - } dst; 44 - }; 45 - 46 - struct ipt_conntrack_info 47 - { 48 - unsigned int statemask, statusmask; 49 - 50 - struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; 51 - struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; 52 - 53 - unsigned long expires_min, expires_max; 54 - 55 - /* Flags word */ 56 - u_int8_t flags; 57 - /* Inverse flags */ 58 - u_int8_t invflags; 59 - }; 60 #endif /*_IPT_CONNTRACK_H*/
··· 5 #ifndef _IPT_CONNTRACK_H 6 #define _IPT_CONNTRACK_H 7 8 + #include <linux/netfilter/xt_conntrack.h> 9 10 + #define IPT_CONNTRACK_STATE_BIT(ctinfo) XT_CONNTRACK_STATE_BIT(ctinfo) 11 + #define IPT_CONNTRACK_STATE_INVALID XT_CONNTRACK_STATE_INVALID 12 + 13 + #define IPT_CONNTRACK_STATE_SNAT XT_CONNTRACK_STATE_SNAT 14 + #define IPT_CONNTRACK_STATE_DNAT XT_CONNTRACK_STATE_DNAT 15 + #define IPT_CONNTRACK_STATE_UNTRACKED XT_CONNTRACK_STATE_UNTRACKED 16 17 /* flags, invflags: */ 18 + #define IPT_CONNTRACK_STATE XT_CONNTRACK_STATE 19 + #define IPT_CONNTRACK_PROTO XT_CONNTRACK_PROTO 20 + #define IPT_CONNTRACK_ORIGSRC XT_CONNTRACK_ORIGSRC 21 + #define IPT_CONNTRACK_ORIGDST XT_CONNTRACK_ORIGDST 22 + #define IPT_CONNTRACK_REPLSRC XT_CONNTRACK_REPLSRC 23 + #define IPT_CONNTRACK_REPLDST XT_CONNTRACK_REPLDST 24 + #define IPT_CONNTRACK_STATUS XT_CONNTRACK_STATUS 25 + #define IPT_CONNTRACK_EXPIRES XT_CONNTRACK_EXPIRES 26 27 + #define ipt_conntrack_info xt_conntrack_info 28 #endif /*_IPT_CONNTRACK_H*/
+7 -15
include/linux/netfilter_ipv4/ipt_dccp.h
··· 1 #ifndef _IPT_DCCP_H_ 2 #define _IPT_DCCP_H_ 3 4 - #define IPT_DCCP_SRC_PORTS 0x01 5 - #define IPT_DCCP_DEST_PORTS 0x02 6 - #define IPT_DCCP_TYPE 0x04 7 - #define IPT_DCCP_OPTION 0x08 8 9 - #define IPT_DCCP_VALID_FLAGS 0x0f 10 11 - struct ipt_dccp_info { 12 - u_int16_t dpts[2]; /* Min, Max */ 13 - u_int16_t spts[2]; /* Min, Max */ 14 - 15 - u_int16_t flags; 16 - u_int16_t invflags; 17 - 18 - u_int16_t typemask; 19 - u_int8_t option; 20 - }; 21 22 #endif /* _IPT_DCCP_H_ */ 23
··· 1 #ifndef _IPT_DCCP_H_ 2 #define _IPT_DCCP_H_ 3 4 + #include <linux/netfilter/xt_dccp.h> 5 + #define IPT_DCCP_SRC_PORTS XT_DCCP_SRC_PORTS 6 + #define IPT_DCCP_DEST_PORTS XT_DCCP_DEST_PORTS 7 + #define IPT_DCCP_TYPE XT_DCCP_TYPE 8 + #define IPT_DCCP_OPTION XT_DCCP_OPTION 9 10 + #define IPT_DCCP_VALID_FLAGS XT_DCCP_VALID_FLAGS 11 12 + #define ipt_dccp_info xt_dccp_info 13 14 #endif /* _IPT_DCCP_H_ */ 15
+3 -4
include/linux/netfilter_ipv4/ipt_helper.h
··· 1 #ifndef _IPT_HELPER_H 2 #define _IPT_HELPER_H 3 4 - struct ipt_helper_info { 5 - int invert; 6 - char name[30]; 7 - }; 8 #endif /* _IPT_HELPER_H */
··· 1 #ifndef _IPT_HELPER_H 2 #define _IPT_HELPER_H 3 4 + #include <linux/netfilter/xt_helper.h> 5 + #define ipt_helper_info xt_helper_info 6 + 7 #endif /* _IPT_HELPER_H */
+2 -4
include/linux/netfilter_ipv4/ipt_length.h
··· 1 #ifndef _IPT_LENGTH_H 2 #define _IPT_LENGTH_H 3 4 - struct ipt_length_info { 5 - u_int16_t min, max; 6 - u_int8_t invert; 7 - }; 8 9 #endif /*_IPT_LENGTH_H*/
··· 1 #ifndef _IPT_LENGTH_H 2 #define _IPT_LENGTH_H 3 4 + #include <linux/netfilter/xt_length.h> 5 + #define ipt_length_info xt_length_info 6 7 #endif /*_IPT_LENGTH_H*/
+3 -16
include/linux/netfilter_ipv4/ipt_limit.h
··· 1 #ifndef _IPT_RATE_H 2 #define _IPT_RATE_H 3 4 - /* timings are in milliseconds. */ 5 - #define IPT_LIMIT_SCALE 10000 6 7 - /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 8 - seconds, or one every 59 hours. */ 9 - struct ipt_rateinfo { 10 - u_int32_t avg; /* Average secs between packets * scale */ 11 - u_int32_t burst; /* Period multiplier for upper limit. */ 12 - 13 - /* Used internally by the kernel */ 14 - unsigned long prev; 15 - u_int32_t credit; 16 - u_int32_t credit_cap, cost; 17 - 18 - /* Ugly, ugly fucker. */ 19 - struct ipt_rateinfo *master; 20 - }; 21 #endif /*_IPT_RATE_H*/
··· 1 #ifndef _IPT_RATE_H 2 #define _IPT_RATE_H 3 4 + #include <linux/netfilter/xt_limit.h> 5 + #define IPT_LIMIT_SCALE XT_LIMIT_SCALE 6 + #define ipt_rateinfo xt_rateinfo 7 8 #endif /*_IPT_RATE_H*/
+3 -4
include/linux/netfilter_ipv4/ipt_mac.h
··· 1 #ifndef _IPT_MAC_H 2 #define _IPT_MAC_H 3 4 - struct ipt_mac_info { 5 - unsigned char srcaddr[ETH_ALEN]; 6 - int invert; 7 - }; 8 #endif /*_IPT_MAC_H*/
··· 1 #ifndef _IPT_MAC_H 2 #define _IPT_MAC_H 3 4 + #include <linux/netfilter/xt_mac.h> 5 + #define ipt_mac_info xt_mac_info 6 + 7 #endif /*_IPT_MAC_H*/
+4 -4
include/linux/netfilter_ipv4/ipt_mark.h
··· 1 #ifndef _IPT_MARK_H 2 #define _IPT_MARK_H 3 4 - struct ipt_mark_info { 5 - unsigned long mark, mask; 6 - u_int8_t invert; 7 - }; 8 9 #endif /*_IPT_MARK_H*/
··· 1 #ifndef _IPT_MARK_H 2 #define _IPT_MARK_H 3 4 + /* Backwards compatibility for old userspace */ 5 + #include <linux/netfilter/xt_mark.h> 6 + 7 + #define ipt_mark_info xt_mark_info 8 9 #endif /*_IPT_MARK_H*/
+10 -17
include/linux/netfilter_ipv4/ipt_physdev.h
··· 1 #ifndef _IPT_PHYSDEV_H 2 #define _IPT_PHYSDEV_H 3 4 - #ifdef __KERNEL__ 5 - #include <linux/if.h> 6 - #endif 7 8 - #define IPT_PHYSDEV_OP_IN 0x01 9 - #define IPT_PHYSDEV_OP_OUT 0x02 10 - #define IPT_PHYSDEV_OP_BRIDGED 0x04 11 - #define IPT_PHYSDEV_OP_ISIN 0x08 12 - #define IPT_PHYSDEV_OP_ISOUT 0x10 13 - #define IPT_PHYSDEV_OP_MASK (0x20 - 1) 14 15 - struct ipt_physdev_info { 16 - char physindev[IFNAMSIZ]; 17 - char in_mask[IFNAMSIZ]; 18 - char physoutdev[IFNAMSIZ]; 19 - char out_mask[IFNAMSIZ]; 20 - u_int8_t invert; 21 - u_int8_t bitmask; 22 - }; 23 24 #endif /*_IPT_PHYSDEV_H*/
··· 1 #ifndef _IPT_PHYSDEV_H 2 #define _IPT_PHYSDEV_H 3 4 + /* Backwards compatibility for old userspace */ 5 6 + #include <linux/netfilter/xt_physdev.h> 7 8 + #define IPT_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN 9 + #define IPT_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT 10 + #define IPT_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED 11 + #define IPT_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN 12 + #define IPT_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT 13 + #define IPT_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK 14 + 15 + #define ipt_physdev_info xt_physdev_info 16 17 #endif /*_IPT_PHYSDEV_H*/
+3 -4
include/linux/netfilter_ipv4/ipt_pkttype.h
··· 1 #ifndef _IPT_PKTTYPE_H 2 #define _IPT_PKTTYPE_H 3 4 - struct ipt_pkttype_info { 5 - int pkttype; 6 - int invert; 7 - }; 8 #endif /*_IPT_PKTTYPE_H*/
··· 1 #ifndef _IPT_PKTTYPE_H 2 #define _IPT_PKTTYPE_H 3 4 + #include <linux/netfilter/xt_pkttype.h> 5 + #define ipt_pkttype_info xt_pkttype_info 6 + 7 #endif /*_IPT_PKTTYPE_H*/
+2 -5
include/linux/netfilter_ipv4/ipt_realm.h
··· 1 #ifndef _IPT_REALM_H 2 #define _IPT_REALM_H 3 4 - struct ipt_realm_info { 5 - u_int32_t id; 6 - u_int32_t mask; 7 - u_int8_t invert; 8 - }; 9 10 #endif /* _IPT_REALM_H */
··· 1 #ifndef _IPT_REALM_H 2 #define _IPT_REALM_H 3 4 + #include <linux/netfilter/xt_realm.h> 5 + #define ipt_realm_info xt_realm_info 6 7 #endif /* _IPT_REALM_H */
+9 -7
include/linux/netfilter_ipv4/ipt_state.h
··· 1 #ifndef _IPT_STATE_H 2 #define _IPT_STATE_H 3 4 - #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) 5 - #define IPT_STATE_INVALID (1 << 0) 6 7 - #define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) 8 9 - struct ipt_state_info 10 - { 11 - unsigned int statemask; 12 - }; 13 #endif /*_IPT_STATE_H*/
··· 1 #ifndef _IPT_STATE_H 2 #define _IPT_STATE_H 3 4 + /* Backwards compatibility for old userspace */ 5 6 + #include <linux/netfilter/xt_state.h> 7 8 + #define IPT_STATE_BIT XT_STATE_BIT 9 + #define IPT_STATE_INVALID XT_STATE_INVALID 10 + 11 + #define IPT_STATE_UNTRACKED XT_STATE_UNTRACKED 12 + 13 + #define ipt_state_info xt_state_info 14 + 15 #endif /*_IPT_STATE_H*/
+4 -12
include/linux/netfilter_ipv4/ipt_string.h
··· 1 #ifndef _IPT_STRING_H 2 #define _IPT_STRING_H 3 4 - #define IPT_STRING_MAX_PATTERN_SIZE 128 5 - #define IPT_STRING_MAX_ALGO_NAME_SIZE 16 6 7 - struct ipt_string_info 8 - { 9 - u_int16_t from_offset; 10 - u_int16_t to_offset; 11 - char algo[IPT_STRING_MAX_ALGO_NAME_SIZE]; 12 - char pattern[IPT_STRING_MAX_PATTERN_SIZE]; 13 - u_int8_t patlen; 14 - u_int8_t invert; 15 - struct ts_config __attribute__((aligned(8))) *config; 16 - }; 17 18 #endif /*_IPT_STRING_H*/
··· 1 #ifndef _IPT_STRING_H 2 #define _IPT_STRING_H 3 4 + #include <linux/netfilter/xt_string.h> 5 6 + #define IPT_STRING_MAX_PATTERN_SIZE XT_STRING_MAX_PATTERN_SIZE 7 + #define IPT_STRING_MAX_ALGO_NAME_SIZE XT_STRING_MAX_ALGO_NAME_SIZE 8 + #define ipt_string_info xt_string_info 9 10 #endif /*_IPT_STRING_H*/
+2 -4
include/linux/netfilter_ipv4/ipt_tcpmss.h
··· 1 #ifndef _IPT_TCPMSS_MATCH_H 2 #define _IPT_TCPMSS_MATCH_H 3 4 - struct ipt_tcpmss_match_info { 5 - u_int16_t mss_min, mss_max; 6 - u_int8_t invert; 7 - }; 8 9 #endif /*_IPT_TCPMSS_MATCH_H*/
··· 1 #ifndef _IPT_TCPMSS_MATCH_H 2 #define _IPT_TCPMSS_MATCH_H 3 4 + #include <linux/netfilter/xt_tcpmss.h> 5 + #define ipt_tcpmss_match_info xt_tcpmss_match_info 6 7 #endif /*_IPT_TCPMSS_MATCH_H*/
+44 -164
include/linux/netfilter_ipv6/ip6_tables.h
··· 25 #include <linux/compiler.h> 26 #include <linux/netfilter_ipv6.h> 27 28 - #define IP6T_FUNCTION_MAXNAMELEN 30 29 - #define IP6T_TABLE_MAXNAMELEN 32 30 31 /* Yes, Virginia, you have to zero the padding. */ 32 struct ip6t_ip6 { ··· 111 int verdict; 112 }; 113 114 - struct ip6t_counters 115 - { 116 - u_int64_t pcnt, bcnt; /* Packet and byte counters */ 117 - }; 118 119 /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */ 120 #define IP6T_F_PROTO 0x01 /* Set if rule cares about upper ··· 127 #define IP6T_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ 128 #define IP6T_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ 129 #define IP6T_INV_FRAG 0x20 /* Invert the sense of FRAG. */ 130 - #define IP6T_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 131 #define IP6T_INV_MASK 0x7F /* All possible flag bits mask. */ 132 133 /* This structure defines each of the firewall rules. Consists of 3 ··· 149 unsigned int comefrom; 150 151 /* Packet and byte counters. */ 152 - struct ip6t_counters counters; 153 154 /* The matches (if any), then the target. */ 155 unsigned char elems[0]; ··· 159 * New IP firewall options for [gs]etsockopt at the RAW IP level. 160 * Unlike BSD Linux inherits IP options so you don't have to use 161 * a raw socket for this. Instead we check rights in the calls. */ 162 - #define IP6T_BASE_CTL 64 /* base for firewall socket options */ 163 164 - #define IP6T_SO_SET_REPLACE (IP6T_BASE_CTL) 165 - #define IP6T_SO_SET_ADD_COUNTERS (IP6T_BASE_CTL + 1) 166 - #define IP6T_SO_SET_MAX IP6T_SO_SET_ADD_COUNTERS 167 168 - #define IP6T_SO_GET_INFO (IP6T_BASE_CTL) 169 - #define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1) 170 - #define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 2) 171 - #define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 3) 172 - #define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET 173 174 /* CONTINUE verdict for targets */ 175 - #define IP6T_CONTINUE 0xFFFFFFFF 176 177 /* For standard target */ 178 - #define IP6T_RETURN (-NF_REPEAT - 1) 179 180 - /* TCP matching stuff */ 181 - struct ip6t_tcp 182 - { 183 - u_int16_t spts[2]; /* Source port range. */ 184 - u_int16_t dpts[2]; /* Destination port range. */ 185 - u_int8_t option; /* TCP Option iff non-zero*/ 186 - u_int8_t flg_mask; /* TCP flags mask byte */ 187 - u_int8_t flg_cmp; /* TCP flags compare byte */ 188 - u_int8_t invflags; /* Inverse flags */ 189 - }; 190 191 /* Values for "inv" field in struct ipt_tcp. */ 192 - #define IP6T_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 193 - #define IP6T_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 194 - #define IP6T_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ 195 - #define IP6T_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ 196 - #define IP6T_TCP_INV_MASK 0x0F /* All possible flags. */ 197 - 198 - /* UDP matching stuff */ 199 - struct ip6t_udp 200 - { 201 - u_int16_t spts[2]; /* Source port range. */ 202 - u_int16_t dpts[2]; /* Destination port range. */ 203 - u_int8_t invflags; /* Inverse flags */ 204 - }; 205 206 /* Values for "invflags" field in struct ipt_udp. */ 207 - #define IP6T_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ 208 - #define IP6T_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ 209 - #define IP6T_UDP_INV_MASK 0x03 /* All possible flags. */ 210 211 /* ICMP matching stuff */ 212 struct ip6t_icmp ··· 255 /* Number of counters (must be equal to current number of entries). */ 256 unsigned int num_counters; 257 /* The old entries' counters. */ 258 - struct ip6t_counters __user *counters; 259 260 /* The entries (hang off end: not really an array). */ 261 struct ip6t_entry entries[0]; 262 }; 263 264 /* The argument to IP6T_SO_ADD_COUNTERS. */ 265 - struct ip6t_counters_info 266 - { 267 - /* Which table. */ 268 - char name[IP6T_TABLE_MAXNAMELEN]; 269 - 270 - unsigned int num_counters; 271 - 272 - /* The counters (actually `number' of these). */ 273 - struct ip6t_counters counters[0]; 274 - }; 275 276 /* The argument to IP6T_SO_GET_ENTRIES. */ 277 struct ip6t_get_entries ··· 277 struct ip6t_entry entrytable[0]; 278 }; 279 280 - /* The argument to IP6T_SO_GET_REVISION_*. Returns highest revision 281 - * kernel supports, if >= revision. */ 282 - struct ip6t_get_revision 283 - { 284 - char name[IP6T_FUNCTION_MAXNAMELEN-1]; 285 - 286 - u_int8_t revision; 287 - }; 288 - 289 /* Standard return verdict, or do jump. */ 290 - #define IP6T_STANDARD_TARGET "" 291 /* Error verdict. */ 292 - #define IP6T_ERROR_TARGET "ERROR" 293 294 /* Helper functions */ 295 static __inline__ struct ip6t_entry_target * ··· 334 #include <linux/init.h> 335 extern void ip6t_init(void) __init; 336 337 - struct ip6t_match 338 - { 339 - struct list_head list; 340 341 - const char name[IP6T_FUNCTION_MAXNAMELEN-1]; 342 - 343 - u_int8_t revision; 344 - 345 - /* Return true or false: return FALSE and set *hotdrop = 1 to 346 - force immediate packet drop. */ 347 - /* Arguments changed since 2.6.9, as this must now handle 348 - non-linear skb, using skb_header_pointer and 349 - skb_ip_make_writable. */ 350 - int (*match)(const struct sk_buff *skb, 351 - const struct net_device *in, 352 - const struct net_device *out, 353 - const void *matchinfo, 354 - int offset, 355 - unsigned int protoff, 356 - int *hotdrop); 357 - 358 - /* Called when user tries to insert an entry of this type. */ 359 - /* Should return true or false. */ 360 - int (*checkentry)(const char *tablename, 361 - const struct ip6t_ip6 *ip, 362 - void *matchinfo, 363 - unsigned int matchinfosize, 364 - unsigned int hook_mask); 365 - 366 - /* Called when entry of this type deleted. */ 367 - void (*destroy)(void *matchinfo, unsigned int matchinfosize); 368 - 369 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 370 - struct module *me; 371 - }; 372 - 373 - /* Registration hooks for targets. */ 374 - struct ip6t_target 375 - { 376 - struct list_head list; 377 - 378 - const char name[IP6T_FUNCTION_MAXNAMELEN-1]; 379 - 380 - u_int8_t revision; 381 - 382 - /* Returns verdict. Argument order changed since 2.6.9, as this 383 - must now handle non-linear skbs, using skb_copy_bits and 384 - skb_ip_make_writable. */ 385 - unsigned int (*target)(struct sk_buff **pskb, 386 - const struct net_device *in, 387 - const struct net_device *out, 388 - unsigned int hooknum, 389 - const void *targinfo, 390 - void *userdata); 391 - 392 - /* Called when user tries to insert an entry of this type: 393 - hook_mask is a bitmask of hooks from which it can be 394 - called. */ 395 - /* Should return true or false. */ 396 - int (*checkentry)(const char *tablename, 397 - const struct ip6t_entry *e, 398 - void *targinfo, 399 - unsigned int targinfosize, 400 - unsigned int hook_mask); 401 - 402 - /* Called when entry of this type deleted. */ 403 - void (*destroy)(void *targinfo, unsigned int targinfosize); 404 - 405 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 406 - struct module *me; 407 - }; 408 - 409 - extern int ip6t_register_target(struct ip6t_target *target); 410 - extern void ip6t_unregister_target(struct ip6t_target *target); 411 - 412 - extern int ip6t_register_match(struct ip6t_match *match); 413 - extern void ip6t_unregister_match(struct ip6t_match *match); 414 - 415 - /* Furniture shopping... */ 416 - struct ip6t_table 417 - { 418 - struct list_head list; 419 - 420 - /* A unique name... */ 421 - char name[IP6T_TABLE_MAXNAMELEN]; 422 - 423 - /* What hooks you will enter on */ 424 - unsigned int valid_hooks; 425 - 426 - /* Lock for the curtain */ 427 - rwlock_t lock; 428 - 429 - /* Man behind the curtain... */ 430 - struct ip6t_table_info *private; 431 - 432 - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 433 - struct module *me; 434 - }; 435 436 extern int ip6t_register_table(struct ip6t_table *table, 437 const struct ip6t_replace *repl);
··· 25 #include <linux/compiler.h> 26 #include <linux/netfilter_ipv6.h> 27 28 + #include <linux/netfilter/x_tables.h> 29 + 30 + #define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN 31 + #define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN 32 + 33 + #define ip6t_match xt_match 34 + #define ip6t_target xt_target 35 + #define ip6t_table xt_table 36 + #define ip6t_get_revision xt_get_revision 37 38 /* Yes, Virginia, you have to zero the padding. */ 39 struct ip6t_ip6 { ··· 104 int verdict; 105 }; 106 107 + #define ip6t_counters xt_counters 108 109 /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */ 110 #define IP6T_F_PROTO 0x01 /* Set if rule cares about upper ··· 123 #define IP6T_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ 124 #define IP6T_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ 125 #define IP6T_INV_FRAG 0x20 /* Invert the sense of FRAG. */ 126 + #define IP6T_INV_PROTO XT_INV_PROTO 127 #define IP6T_INV_MASK 0x7F /* All possible flag bits mask. */ 128 129 /* This structure defines each of the firewall rules. Consists of 3 ··· 145 unsigned int comefrom; 146 147 /* Packet and byte counters. */ 148 + struct xt_counters counters; 149 150 /* The matches (if any), then the target. */ 151 unsigned char elems[0]; ··· 155 * New IP firewall options for [gs]etsockopt at the RAW IP level. 156 * Unlike BSD Linux inherits IP options so you don't have to use 157 * a raw socket for this. Instead we check rights in the calls. */ 158 + #define IP6T_BASE_CTL XT_BASE_CTL 159 160 + #define IP6T_SO_SET_REPLACE XT_SO_SET_REPLACE 161 + #define IP6T_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS 162 + #define IP6T_SO_SET_MAX XT_SO_SET_MAX 163 164 + #define IP6T_SO_GET_INFO XT_SO_GET_INFO 165 + #define IP6T_SO_GET_ENTRIES XT_SO_GET_ENTRIES 166 + #define IP6T_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH 167 + #define IP6T_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET 168 + #define IP6T_SO_GET_MAX XT_SO_GET_REVISION_TARGET 169 170 /* CONTINUE verdict for targets */ 171 + #define IP6T_CONTINUE XT_CONTINUE 172 173 /* For standard target */ 174 + #define IP6T_RETURN XT_RETURN 175 176 + /* TCP/UDP matching stuff */ 177 + #include <linux/netfilter/xt_tcpudp.h> 178 + 179 + #define ip6t_tcp xt_tcp 180 + #define ip6t_udp xt_udp 181 182 /* Values for "inv" field in struct ipt_tcp. */ 183 + #define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT 184 + #define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT 185 + #define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS 186 + #define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION 187 + #define IP6T_TCP_INV_MASK XT_TCP_INV_MASK 188 189 /* Values for "invflags" field in struct ipt_udp. */ 190 + #define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT 191 + #define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT 192 + #define IP6T_UDP_INV_MASK XT_UDP_INV_MASK 193 194 /* ICMP matching stuff */ 195 struct ip6t_icmp ··· 264 /* Number of counters (must be equal to current number of entries). */ 265 unsigned int num_counters; 266 /* The old entries' counters. */ 267 + struct xt_counters __user *counters; 268 269 /* The entries (hang off end: not really an array). */ 270 struct ip6t_entry entries[0]; 271 }; 272 273 /* The argument to IP6T_SO_ADD_COUNTERS. */ 274 + #define ip6t_counters_info xt_counters_info 275 276 /* The argument to IP6T_SO_GET_ENTRIES. */ 277 struct ip6t_get_entries ··· 295 struct ip6t_entry entrytable[0]; 296 }; 297 298 /* Standard return verdict, or do jump. */ 299 + #define IP6T_STANDARD_TARGET XT_STANDARD_TARGET 300 /* Error verdict. */ 301 + #define IP6T_ERROR_TARGET XT_ERROR_TARGET 302 303 /* Helper functions */ 304 static __inline__ struct ip6t_entry_target * ··· 361 #include <linux/init.h> 362 extern void ip6t_init(void) __init; 363 364 + #define ip6t_register_target(tgt) xt_register_target(AF_INET6, tgt) 365 + #define ip6t_unregister_target(tgt) xt_unregister_target(AF_INET6, tgt) 366 367 + #define ip6t_register_match(match) xt_register_match(AF_INET6, match) 368 + #define ip6t_unregister_match(match) xt_unregister_match(AF_INET6, match) 369 370 extern int ip6t_register_table(struct ip6t_table *table, 371 const struct ip6t_replace *repl);
+5 -4
include/linux/netfilter_ipv6/ip6t_MARK.h
··· 1 #ifndef _IP6T_MARK_H_target 2 #define _IP6T_MARK_H_target 3 4 - struct ip6t_mark_target_info { 5 - unsigned long mark; 6 - }; 7 8 - #endif /*_IPT_MARK_H_target*/
··· 1 #ifndef _IP6T_MARK_H_target 2 #define _IP6T_MARK_H_target 3 4 + /* Backwards compatibility for old userspace */ 5 + #include <linux/netfilter/xt_MARK.h> 6 7 + #define ip6t_mark_target_info xt_mark_target_info 8 + 9 + #endif /*_IP6T_MARK_H_target*/
+2 -4
include/linux/netfilter_ipv6/ip6t_length.h
··· 1 #ifndef _IP6T_LENGTH_H 2 #define _IP6T_LENGTH_H 3 4 - struct ip6t_length_info { 5 - u_int16_t min, max; 6 - u_int8_t invert; 7 - }; 8 9 #endif /*_IP6T_LENGTH_H*/ 10
··· 1 #ifndef _IP6T_LENGTH_H 2 #define _IP6T_LENGTH_H 3 4 + #include <linux/netfilter/xt_length.h> 5 + #define ip6t_length_info xt_length_info 6 7 #endif /*_IP6T_LENGTH_H*/ 8
+4 -17
include/linux/netfilter_ipv6/ip6t_limit.h
··· 1 #ifndef _IP6T_RATE_H 2 #define _IP6T_RATE_H 3 4 - /* timings are in milliseconds. */ 5 - #define IP6T_LIMIT_SCALE 10000 6 7 - /* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 8 - seconds, or one every 59 hours. */ 9 - struct ip6t_rateinfo { 10 - u_int32_t avg; /* Average secs between packets * scale */ 11 - u_int32_t burst; /* Period multiplier for upper limit. */ 12 - 13 - /* Used internally by the kernel */ 14 - unsigned long prev; 15 - u_int32_t credit; 16 - u_int32_t credit_cap, cost; 17 - 18 - /* Ugly, ugly fucker. */ 19 - struct ip6t_rateinfo *master; 20 - }; 21 - #endif /*_IPT_RATE_H*/
··· 1 #ifndef _IP6T_RATE_H 2 #define _IP6T_RATE_H 3 4 + #include <linux/netfilter/xt_limit.h> 5 + #define IP6T_LIMIT_SCALE XT_LIMIT_SCALE 6 + #define ip6t_rateinfo xt_rateinfo 7 8 + #endif /*_IP6T_RATE_H*/
+4 -5
include/linux/netfilter_ipv6/ip6t_mac.h
··· 1 #ifndef _IP6T_MAC_H 2 #define _IP6T_MAC_H 3 4 - struct ip6t_mac_info { 5 - unsigned char srcaddr[ETH_ALEN]; 6 - int invert; 7 - }; 8 - #endif /*_IPT_MAC_H*/
··· 1 #ifndef _IP6T_MAC_H 2 #define _IP6T_MAC_H 3 4 + #include <linux/netfilter/xt_mac.h> 5 + #define ip6t_mac_info xt_mac_info 6 + 7 + #endif /*_IP6T_MAC_H*/
+4 -4
include/linux/netfilter_ipv6/ip6t_mark.h
··· 1 #ifndef _IP6T_MARK_H 2 #define _IP6T_MARK_H 3 4 - struct ip6t_mark_info { 5 - unsigned long mark, mask; 6 - u_int8_t invert; 7 - }; 8 9 #endif /*_IPT_MARK_H*/
··· 1 #ifndef _IP6T_MARK_H 2 #define _IP6T_MARK_H 3 4 + /* Backwards compatibility for old userspace */ 5 + #include <linux/netfilter/xt_mark.h> 6 + 7 + #define ip6t_mark_info xt_mark_info 8 9 #endif /*_IPT_MARK_H*/
+10 -17
include/linux/netfilter_ipv6/ip6t_physdev.h
··· 1 #ifndef _IP6T_PHYSDEV_H 2 #define _IP6T_PHYSDEV_H 3 4 - #ifdef __KERNEL__ 5 - #include <linux/if.h> 6 - #endif 7 8 - #define IP6T_PHYSDEV_OP_IN 0x01 9 - #define IP6T_PHYSDEV_OP_OUT 0x02 10 - #define IP6T_PHYSDEV_OP_BRIDGED 0x04 11 - #define IP6T_PHYSDEV_OP_ISIN 0x08 12 - #define IP6T_PHYSDEV_OP_ISOUT 0x10 13 - #define IP6T_PHYSDEV_OP_MASK (0x20 - 1) 14 15 - struct ip6t_physdev_info { 16 - char physindev[IFNAMSIZ]; 17 - char in_mask[IFNAMSIZ]; 18 - char physoutdev[IFNAMSIZ]; 19 - char out_mask[IFNAMSIZ]; 20 - u_int8_t invert; 21 - u_int8_t bitmask; 22 - }; 23 24 #endif /*_IP6T_PHYSDEV_H*/
··· 1 #ifndef _IP6T_PHYSDEV_H 2 #define _IP6T_PHYSDEV_H 3 4 + /* Backwards compatibility for old userspace */ 5 6 + #include <linux/netfilter/xt_physdev.h> 7 8 + #define IP6T_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN 9 + #define IP6T_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT 10 + #define IP6T_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED 11 + #define IP6T_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN 12 + #define IP6T_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT 13 + #define IP6T_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK 14 + 15 + #define ip6t_physdev_info xt_physdev_info 16 17 #endif /*_IP6T_PHYSDEV_H*/
-3
include/net/netfilter/ipv4/nf_conntrack_ipv4.h
··· 37 struct sk_buff * 38 nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb); 39 40 - /* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */ 41 - extern void need_ip_conntrack(void); 42 - 43 #endif /*_NF_CONNTRACK_IPV4_H*/
··· 37 struct sk_buff * 38 nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb); 39 40 #endif /*_NF_CONNTRACK_IPV4_H*/
-3
include/net/netfilter/nf_conntrack.h
··· 221 extern struct nf_conntrack_helper * 222 __nf_conntrack_helper_find_byname(const char *name); 223 224 - /* call to create an explicit dependency on nf_conntrack. */ 225 - extern void need_nf_conntrack(void); 226 - 227 extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 228 const struct nf_conntrack_tuple *orig); 229
··· 221 extern struct nf_conntrack_helper * 222 __nf_conntrack_helper_find_byname(const char *name); 223 224 extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 225 const struct nf_conntrack_tuple *orig); 226
+1
net/bridge/netfilter/ebt_log.c
··· 15 #include <linux/netfilter.h> 16 #include <linux/module.h> 17 #include <linux/ip.h> 18 #include <linux/if_arp.h> 19 #include <linux/spinlock.h> 20
··· 15 #include <linux/netfilter.h> 16 #include <linux/module.h> 17 #include <linux/ip.h> 18 + #include <linux/in.h> 19 #include <linux/if_arp.h> 20 #include <linux/spinlock.h> 21
+2 -248
net/ipv4/netfilter/Kconfig
··· 182 183 config IP_NF_IPTABLES 184 tristate "IP tables support (required for filtering/masq/NAT)" 185 help 186 iptables is a general, extensible packet identification framework. 187 The packet filtering and full NAT (masquerading, port forwarding, ··· 192 To compile it as a module, choose M here. If unsure, say N. 193 194 # The matches. 195 - config IP_NF_MATCH_LIMIT 196 - tristate "limit match support" 197 - depends on IP_NF_IPTABLES 198 - help 199 - limit matching allows you to control the rate at which a rule can be 200 - matched: mainly useful in combination with the LOG target ("LOG 201 - target support", below) and to avoid some Denial of Service attacks. 202 - 203 - To compile it as a module, choose M here. If unsure, say N. 204 - 205 config IP_NF_MATCH_IPRANGE 206 tristate "IP range match support" 207 depends on IP_NF_IPTABLES 208 help 209 This option makes possible to match IP addresses against IP address 210 ranges. 211 - 212 - To compile it as a module, choose M here. If unsure, say N. 213 - 214 - config IP_NF_MATCH_MAC 215 - tristate "MAC address match support" 216 - depends on IP_NF_IPTABLES 217 - help 218 - MAC matching allows you to match packets based on the source 219 - Ethernet address of the packet. 220 - 221 - To compile it as a module, choose M here. If unsure, say N. 222 - 223 - config IP_NF_MATCH_PKTTYPE 224 - tristate "Packet type match support" 225 - depends on IP_NF_IPTABLES 226 - help 227 - Packet type matching allows you to match a packet by 228 - its "class", eg. BROADCAST, MULTICAST, ... 229 - 230 - Typical usage: 231 - iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG 232 - 233 - To compile it as a module, choose M here. If unsure, say N. 234 - 235 - config IP_NF_MATCH_MARK 236 - tristate "netfilter MARK match support" 237 - depends on IP_NF_IPTABLES 238 - help 239 - Netfilter mark matching allows you to match packets based on the 240 - `nfmark' value in the packet. This can be set by the MARK target 241 - (see below). 242 243 To compile it as a module, choose M here. If unsure, say N. 244 ··· 261 262 To compile it as a module, choose M here. If unsure, say N. 263 264 - config IP_NF_MATCH_LENGTH 265 - tristate "LENGTH match support" 266 - depends on IP_NF_IPTABLES 267 - help 268 - This option allows you to match the length of a packet against a 269 - specific value or range of values. 270 - 271 - To compile it as a module, choose M here. If unsure, say N. 272 - 273 config IP_NF_MATCH_TTL 274 tristate "TTL match support" 275 depends on IP_NF_IPTABLES 276 help 277 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user 278 to match packets by their TTL value. 279 - 280 - To compile it as a module, choose M here. If unsure, say N. 281 - 282 - config IP_NF_MATCH_TCPMSS 283 - tristate "tcpmss match support" 284 - depends on IP_NF_IPTABLES 285 - help 286 - This option adds a `tcpmss' match, which allows you to examine the 287 - MSS value of TCP SYN packets, which control the maximum packet size 288 - for that connection. 289 - 290 - To compile it as a module, choose M here. If unsure, say N. 291 - 292 - config IP_NF_MATCH_HELPER 293 - tristate "Helper match support" 294 - depends on IP_NF_IPTABLES 295 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 296 - help 297 - Helper matching allows you to match packets in dynamic connections 298 - tracked by a conntrack-helper, ie. ip_conntrack_ftp 299 - 300 - To compile it as a module, choose M here. If unsure, say Y. 301 - 302 - config IP_NF_MATCH_STATE 303 - tristate "Connection state match support" 304 - depends on IP_NF_IPTABLES 305 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 306 - help 307 - Connection state matching allows you to match packets based on their 308 - relationship to a tracked connection (ie. previous packets). This 309 - is a powerful tool for packet classification. 310 - 311 - To compile it as a module, choose M here. If unsure, say N. 312 - 313 - config IP_NF_MATCH_CONNTRACK 314 - tristate "Connection tracking match support" 315 - depends on IP_NF_IPTABLES 316 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 317 - help 318 - This is a general conntrack match module, a superset of the state match. 319 - 320 - It allows matching on additional conntrack information, which is 321 - useful in complex configurations, such as NAT gateways with multiple 322 - internet links or tunnels. 323 324 To compile it as a module, choose M here. If unsure, say N. 325 ··· 279 280 To compile it as a module, choose M here. If unsure, say N. 281 282 - config IP_NF_MATCH_PHYSDEV 283 - tristate "Physdev match support" 284 - depends on IP_NF_IPTABLES && BRIDGE_NETFILTER 285 - help 286 - Physdev packet matching matches against the physical bridge ports 287 - the IP packet arrived on or will leave by. 288 - 289 - To compile it as a module, choose M here. If unsure, say N. 290 - 291 config IP_NF_MATCH_ADDRTYPE 292 tristate 'address type match support' 293 depends on IP_NF_IPTABLES ··· 286 This option allows you to match what routing thinks of an address, 287 eg. UNICAST, LOCAL, BROADCAST, ... 288 289 - If you want to compile it as a module, say M here and read 290 - <file:Documentation/modules.txt>. If unsure, say `N'. 291 - 292 - config IP_NF_MATCH_REALM 293 - tristate 'realm match support' 294 - depends on IP_NF_IPTABLES 295 - select NET_CLS_ROUTE 296 - help 297 - This option adds a `realm' match, which allows you to use the realm 298 - key from the routing subsystem inside iptables. 299 - 300 - This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 301 - in tc world. 302 - 303 - If you want to compile it as a module, say M here and read 304 - <file:Documentation/modules.txt>. If unsure, say `N'. 305 - 306 - config IP_NF_MATCH_SCTP 307 - tristate 'SCTP protocol match support' 308 - depends on IP_NF_IPTABLES 309 - help 310 - With this option enabled, you will be able to use the iptables 311 - `sctp' match in order to match on SCTP source/destination ports 312 - and SCTP chunk types. 313 - 314 - If you want to compile it as a module, say M here and read 315 - <file:Documentation/modules.txt>. If unsure, say `N'. 316 - 317 - config IP_NF_MATCH_DCCP 318 - tristate 'DCCP protocol match support' 319 - depends on IP_NF_IPTABLES 320 - help 321 - With this option enabled, you will be able to use the iptables 322 - `dccp' match in order to match on DCCP source/destination ports 323 - and DCCP flags. 324 - 325 - If you want to compile it as a module, say M here and read 326 - <file:Documentation/modules.txt>. If unsure, say `N'. 327 - 328 - config IP_NF_MATCH_COMMENT 329 - tristate 'comment match support' 330 - depends on IP_NF_IPTABLES 331 - help 332 - This option adds a `comment' dummy-match, which allows you to put 333 - comments in your iptables ruleset. 334 - 335 - If you want to compile it as a module, say M here and read 336 - <file:Documentation/modules.txt>. If unsure, say `N'. 337 - 338 - config IP_NF_MATCH_CONNMARK 339 - tristate 'Connection mark match support' 340 - depends on IP_NF_IPTABLES 341 - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 342 - help 343 - This option adds a `connmark' match, which allows you to match the 344 - connection mark value previously set for the session by `CONNMARK'. 345 - 346 - If you want to compile it as a module, say M here and read 347 - <file:Documentation/modules.txt>. The module will be called 348 - ipt_connmark.o. If unsure, say `N'. 349 - 350 - config IP_NF_MATCH_CONNBYTES 351 - tristate 'Connection byte/packet counter match support' 352 - depends on IP_NF_IPTABLES 353 - depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4) 354 - help 355 - This option adds a `connbytes' match, which allows you to match the 356 - number of bytes and/or packets for each direction within a connection. 357 - 358 If you want to compile it as a module, say M here and read 359 <file:Documentation/modules.txt>. If unsure, say `N'. 360 ··· 302 It enables you to express policies like `10kpps for any given 303 destination IP' or `500pps from any given source IP' with a single 304 IPtables rule. 305 - 306 - config IP_NF_MATCH_STRING 307 - tristate 'string match support' 308 - depends on IP_NF_IPTABLES 309 - select TEXTSEARCH 310 - select TEXTSEARCH_KMP 311 - select TEXTSEARCH_BM 312 - select TEXTSEARCH_FSM 313 - help 314 - This option adds a `string' match, which allows you to look for 315 - pattern matchings in packets. 316 - 317 - To compile it as a module, choose M here. If unsure, say N. 318 319 config IP_NF_MATCH_POLICY 320 tristate "IPsec policy match support" ··· 385 386 iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \ 387 -j TCPMSS --clamp-mss-to-pmtu 388 - 389 - To compile it as a module, choose M here. If unsure, say N. 390 - 391 - config IP_NF_TARGET_NFQUEUE 392 - tristate "NFQUEUE Target Support" 393 - depends on IP_NF_IPTABLES 394 - help 395 - This Target replaced the old obsolete QUEUE target. 396 - 397 - As opposed to QUEUE, it supports 65535 different queues, 398 - not just one. 399 400 To compile it as a module, choose M here. If unsure, say N. 401 ··· 540 541 To compile it as a module, choose M here. If unsure, say N. 542 543 - config IP_NF_TARGET_MARK 544 - tristate "MARK target support" 545 - depends on IP_NF_MANGLE 546 - help 547 - This option adds a `MARK' target, which allows you to create rules 548 - in the `mangle' table which alter the netfilter mark (nfmark) field 549 - associated with the packet prior to routing. This can change 550 - the routing method (see `Use netfilter MARK value as routing 551 - key') and can also be used by other subsystems to change their 552 - behavior. 553 - 554 - To compile it as a module, choose M here. If unsure, say N. 555 - 556 - config IP_NF_TARGET_CLASSIFY 557 - tristate "CLASSIFY target support" 558 - depends on IP_NF_MANGLE 559 - help 560 - This option adds a `CLASSIFY' target, which enables the user to set 561 - the priority of a packet. Some qdiscs can use this value for 562 - classification, among these are: 563 - 564 - atm, cbq, dsmark, pfifo_fast, htb, prio 565 - 566 - To compile it as a module, choose M here. If unsure, say N. 567 - 568 config IP_NF_TARGET_TTL 569 tristate 'TTL target support' 570 depends on IP_NF_MANGLE ··· 553 create immortal packets that loop forever on the network. 554 555 To compile it as a module, choose M here. If unsure, say N. 556 - 557 - config IP_NF_TARGET_CONNMARK 558 - tristate 'CONNMARK target support' 559 - depends on IP_NF_MANGLE 560 - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 561 - help 562 - This option adds a `CONNMARK' target, which allows one to manipulate 563 - the connection mark value. Similar to the MARK target, but 564 - affects the connection mark value rather than the packet mark value. 565 - 566 - If you want to compile it as a module, say M here and read 567 - <file:Documentation/modules.txt>. The module will be called 568 - ipt_CONNMARK.o. If unsure, say `N'. 569 570 config IP_NF_TARGET_CLUSTERIP 571 tristate "CLUSTERIP target support (EXPERIMENTAL)" ··· 577 If you want to compile it as a module, say M here and read 578 <file:Documentation/modules.txt>. If unsure, say `N'. 579 580 - config IP_NF_TARGET_NOTRACK 581 - tristate 'NOTRACK target support' 582 - depends on IP_NF_RAW 583 - depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 584 - help 585 - The NOTRACK target allows a select rule to specify 586 - which packets *not* to enter the conntrack/NAT 587 - subsystem with all the consequences (no ICMP error tracking, 588 - no protocol helpers for the selected packets). 589 - 590 - If you want to compile it as a module, say M here and read 591 - <file:Documentation/modules.txt>. If unsure, say `N'. 592 - 593 - 594 # ARP tables 595 config IP_NF_ARPTABLES 596 tristate "ARP tables support" 597 help 598 arptables is a general, extensible packet identification framework. 599 The ARP packet filtering and mangling (manipulation)subsystems
··· 182 183 config IP_NF_IPTABLES 184 tristate "IP tables support (required for filtering/masq/NAT)" 185 + depends on NETFILTER_XTABLES 186 help 187 iptables is a general, extensible packet identification framework. 188 The packet filtering and full NAT (masquerading, port forwarding, ··· 191 To compile it as a module, choose M here. If unsure, say N. 192 193 # The matches. 194 config IP_NF_MATCH_IPRANGE 195 tristate "IP range match support" 196 depends on IP_NF_IPTABLES 197 help 198 This option makes possible to match IP addresses against IP address 199 ranges. 200 201 To compile it as a module, choose M here. If unsure, say N. 202 ··· 301 302 To compile it as a module, choose M here. If unsure, say N. 303 304 config IP_NF_MATCH_TTL 305 tristate "TTL match support" 306 depends on IP_NF_IPTABLES 307 help 308 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user 309 to match packets by their TTL value. 310 311 To compile it as a module, choose M here. If unsure, say N. 312 ··· 372 373 To compile it as a module, choose M here. If unsure, say N. 374 375 config IP_NF_MATCH_ADDRTYPE 376 tristate 'address type match support' 377 depends on IP_NF_IPTABLES ··· 388 This option allows you to match what routing thinks of an address, 389 eg. UNICAST, LOCAL, BROADCAST, ... 390 391 If you want to compile it as a module, say M here and read 392 <file:Documentation/modules.txt>. If unsure, say `N'. 393 ··· 473 It enables you to express policies like `10kpps for any given 474 destination IP' or `500pps from any given source IP' with a single 475 IPtables rule. 476 477 config IP_NF_MATCH_POLICY 478 tristate "IPsec policy match support" ··· 569 570 iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \ 571 -j TCPMSS --clamp-mss-to-pmtu 572 573 To compile it as a module, choose M here. If unsure, say N. 574 ··· 735 736 To compile it as a module, choose M here. If unsure, say N. 737 738 config IP_NF_TARGET_TTL 739 tristate 'TTL target support' 740 depends on IP_NF_MANGLE ··· 773 create immortal packets that loop forever on the network. 774 775 To compile it as a module, choose M here. If unsure, say N. 776 777 config IP_NF_TARGET_CLUSTERIP 778 tristate "CLUSTERIP target support (EXPERIMENTAL)" ··· 810 If you want to compile it as a module, say M here and read 811 <file:Documentation/modules.txt>. If unsure, say `N'. 812 813 # ARP tables 814 config IP_NF_ARPTABLES 815 tristate "ARP tables support" 816 + depends on NETFILTER_XTABLES 817 help 818 arptables is a general, extensible packet identification framework. 819 The ARP packet filtering and mangling (manipulation)subsystems
-21
net/ipv4/netfilter/Makefile
··· 47 48 # matches 49 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o 50 - obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o 51 obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o 52 - obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o 53 - obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o 54 - obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o 55 - obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o 56 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o 57 - obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o 58 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o 59 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o 60 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o ··· 56 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 57 obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o 58 obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o 59 - obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o 60 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 61 - obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o 62 - obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o 63 - obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o 64 - obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o 65 - obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o 66 - obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o 67 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 68 - obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o 69 obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o 70 - obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o 71 - obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o 72 73 # targets 74 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 75 obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o 76 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o 77 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o 78 - obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o 79 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o 80 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o 81 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o 82 obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o 83 - obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o 84 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o 85 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o 86 - obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o 87 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o 88 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o 89 - obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o 90 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o 91 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o 92 - obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o 93 94 # generic ARP tables 95 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
··· 47 48 # matches 49 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o 50 obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o 51 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o 52 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o 53 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o 54 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o ··· 62 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 63 obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o 64 obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o 65 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 66 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 67 obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o 68 69 # targets 70 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o 71 obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o 72 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o 73 obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o 74 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o 75 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o 76 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o 77 obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o 78 obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o 79 obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o 80 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o 81 obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o 82 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o 83 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o 84 85 # generic ARP tables 86 obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o
+79 -365
net/ipv4/netfilter/arp_tables.c
··· 24 #include <asm/uaccess.h> 25 #include <asm/semaphore.h> 26 27 #include <linux/netfilter_arp/arp_tables.h> 28 29 MODULE_LICENSE("GPL"); ··· 56 #else 57 #define ARP_NF_ASSERT(x) 58 #endif 59 - #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 60 61 - static DECLARE_MUTEX(arpt_mutex); 62 - 63 - #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) 64 - #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) 65 #include <linux/netfilter_ipv4/listhelp.h> 66 - 67 - struct arpt_table_info { 68 - unsigned int size; 69 - unsigned int number; 70 - unsigned int initial_entries; 71 - unsigned int hook_entry[NF_ARP_NUMHOOKS]; 72 - unsigned int underflow[NF_ARP_NUMHOOKS]; 73 - void *entries[NR_CPUS]; 74 - }; 75 - 76 - static LIST_HEAD(arpt_target); 77 - static LIST_HEAD(arpt_tables); 78 - #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 79 - #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 80 81 static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, 82 char *hdr_addr, int len) ··· 205 } 206 207 static unsigned int arpt_error(struct sk_buff **pskb, 208 - unsigned int hooknum, 209 const struct net_device *in, 210 const struct net_device *out, 211 const void *targinfo, 212 void *userinfo) 213 { ··· 236 struct arpt_entry *e, *back; 237 const char *indev, *outdev; 238 void *table_base; 239 240 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ 241 if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + ··· 248 outdev = out ? out->name : nulldevname; 249 250 read_lock_bh(&table->lock); 251 - table_base = (void *)table->private->entries[smp_processor_id()]; 252 - e = get_entry(table_base, table->private->hook_entry[hook]); 253 - back = get_entry(table_base, table->private->underflow[hook]); 254 255 arp = (*pskb)->nh.arph; 256 do { ··· 298 * abs. verdicts 299 */ 300 verdict = t->u.kernel.target->target(pskb, 301 - hook, 302 in, out, 303 t->data, 304 userdata); 305 ··· 324 return verdict; 325 } 326 327 - /* 328 - * These are weird, but module loading must not be done with mutex 329 - * held (since they will register), and we have to have a single 330 - * function to use try_then_request_module(). 331 - */ 332 - 333 - /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 334 - static inline struct arpt_table *find_table_lock(const char *name) 335 - { 336 - struct arpt_table *t; 337 - 338 - if (down_interruptible(&arpt_mutex) != 0) 339 - return ERR_PTR(-EINTR); 340 - 341 - list_for_each_entry(t, &arpt_tables, list) 342 - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 343 - return t; 344 - up(&arpt_mutex); 345 - return NULL; 346 - } 347 - 348 - 349 - /* Find target, grabs ref. Returns ERR_PTR() on error. */ 350 - static inline struct arpt_target *find_target(const char *name, u8 revision) 351 - { 352 - struct arpt_target *t; 353 - int err = 0; 354 - 355 - if (down_interruptible(&arpt_mutex) != 0) 356 - return ERR_PTR(-EINTR); 357 - 358 - list_for_each_entry(t, &arpt_target, list) { 359 - if (strcmp(t->name, name) == 0) { 360 - if (t->revision == revision) { 361 - if (try_module_get(t->me)) { 362 - up(&arpt_mutex); 363 - return t; 364 - } 365 - } else 366 - err = -EPROTOTYPE; /* Found something. */ 367 - } 368 - } 369 - up(&arpt_mutex); 370 - return ERR_PTR(err); 371 - } 372 - 373 - struct arpt_target *arpt_find_target(const char *name, u8 revision) 374 - { 375 - struct arpt_target *target; 376 - 377 - target = try_then_request_module(find_target(name, revision), 378 - "arpt_%s", name); 379 - if (IS_ERR(target) || !target) 380 - return NULL; 381 - return target; 382 - } 383 - 384 - static int target_revfn(const char *name, u8 revision, int *bestp) 385 - { 386 - struct arpt_target *t; 387 - int have_rev = 0; 388 - 389 - list_for_each_entry(t, &arpt_target, list) { 390 - if (strcmp(t->name, name) == 0) { 391 - if (t->revision > *bestp) 392 - *bestp = t->revision; 393 - if (t->revision == revision) 394 - have_rev =1; 395 - } 396 - } 397 - return have_rev; 398 - } 399 - 400 - /* Returns true or false (if no such extension at all) */ 401 - static inline int find_revision(const char *name, u8 revision, 402 - int (*revfn)(const char *, u8, int *), 403 - int *err) 404 - { 405 - int have_rev, best = -1; 406 - 407 - if (down_interruptible(&arpt_mutex) != 0) { 408 - *err = -EINTR; 409 - return 1; 410 - } 411 - have_rev = revfn(name, revision, &best); 412 - up(&arpt_mutex); 413 - 414 - /* Nothing at all? Return 0 to try loading module. */ 415 - if (best == -1) { 416 - *err = -ENOENT; 417 - return 0; 418 - } 419 - 420 - *err = best; 421 - if (!have_rev) 422 - *err = -EPROTONOSUPPORT; 423 - return 1; 424 - } 425 - 426 - 427 /* All zeroes == unconditional rule. */ 428 static inline int unconditional(const struct arpt_arp *arp) 429 { ··· 339 /* Figures out from what hook each rule can be called: returns 0 if 340 * there are loops. Puts hook bitmask in comefrom. 341 */ 342 - static int mark_source_chains(struct arpt_table_info *newinfo, 343 unsigned int valid_hooks, void *entry0) 344 { 345 unsigned int hook; ··· 470 } 471 472 t = arpt_get_target(e); 473 - target = try_then_request_module(find_target(t->u.user.name, 474 - t->u.user.revision), 475 "arpt_%s", t->u.user.name); 476 if (IS_ERR(target) || !target) { 477 duprintf("check_entry: `%s' not found\n", t->u.user.name); ··· 505 } 506 507 static inline int check_entry_size_and_hooks(struct arpt_entry *e, 508 - struct arpt_table_info *newinfo, 509 unsigned char *base, 510 unsigned char *limit, 511 const unsigned int *hook_entries, ··· 539 < 0 (not ARPT_RETURN). --RR */ 540 541 /* Clear counters and comefrom */ 542 - e->counters = ((struct arpt_counters) { 0, 0 }); 543 e->comefrom = 0; 544 545 (*i)++; ··· 566 */ 567 static int translate_table(const char *name, 568 unsigned int valid_hooks, 569 - struct arpt_table_info *newinfo, 570 void *entry0, 571 unsigned int size, 572 unsigned int number, ··· 647 return ret; 648 } 649 650 - static struct arpt_table_info *replace_table(struct arpt_table *table, 651 - unsigned int num_counters, 652 - struct arpt_table_info *newinfo, 653 - int *error) 654 - { 655 - struct arpt_table_info *oldinfo; 656 - 657 - /* Do the substitution. */ 658 - write_lock_bh(&table->lock); 659 - /* Check inside lock: is the old number correct? */ 660 - if (num_counters != table->private->number) { 661 - duprintf("num_counters != table->private->number (%u/%u)\n", 662 - num_counters, table->private->number); 663 - write_unlock_bh(&table->lock); 664 - *error = -EAGAIN; 665 - return NULL; 666 - } 667 - oldinfo = table->private; 668 - table->private = newinfo; 669 - newinfo->initial_entries = oldinfo->initial_entries; 670 - write_unlock_bh(&table->lock); 671 - 672 - return oldinfo; 673 - } 674 - 675 /* Gets counters. */ 676 static inline int add_entry_to_counter(const struct arpt_entry *e, 677 - struct arpt_counters total[], 678 unsigned int *i) 679 { 680 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 659 } 660 661 static inline int set_entry_to_counter(const struct arpt_entry *e, 662 - struct arpt_counters total[], 663 unsigned int *i) 664 { 665 SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 668 return 0; 669 } 670 671 - static void get_counters(const struct arpt_table_info *t, 672 - struct arpt_counters counters[]) 673 { 674 unsigned int cpu; 675 unsigned int i; ··· 707 { 708 unsigned int off, num, countersize; 709 struct arpt_entry *e; 710 - struct arpt_counters *counters; 711 int ret = 0; 712 void *loc_cpu_entry; 713 ··· 716 * (other than comefrom, which userspace doesn't care 717 * about). 718 */ 719 - countersize = sizeof(struct arpt_counters) * table->private->number; 720 - counters = vmalloc(countersize); 721 722 if (counters == NULL) 723 return -ENOMEM; 724 725 /* First, sum counters... */ 726 write_lock_bh(&table->lock); 727 - get_counters(table->private, counters); 728 write_unlock_bh(&table->lock); 729 730 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 731 /* ... then copy entire thing ... */ 732 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 733 ret = -EFAULT; ··· 770 int ret; 771 struct arpt_table *t; 772 773 - t = find_table_lock(entries->name); 774 if (t || !IS_ERR(t)) { 775 duprintf("t->private->number = %u\n", 776 - t->private->number); 777 - if (entries->size == t->private->size) 778 - ret = copy_entries_to_user(t->private->size, 779 t, uptr->entrytable); 780 else { 781 duprintf("get_entries: I've got %u not %u!\n", 782 - t->private->size, 783 - entries->size); 784 ret = -EINVAL; 785 } 786 module_put(t->me); 787 - up(&arpt_mutex); 788 } else 789 ret = t ? PTR_ERR(t) : -ENOENT; 790 791 return ret; 792 - } 793 - 794 - static void free_table_info(struct arpt_table_info *info) 795 - { 796 - int cpu; 797 - for_each_cpu(cpu) { 798 - if (info->size <= PAGE_SIZE) 799 - kfree(info->entries[cpu]); 800 - else 801 - vfree(info->entries[cpu]); 802 - } 803 - kfree(info); 804 - } 805 - 806 - static struct arpt_table_info *alloc_table_info(unsigned int size) 807 - { 808 - struct arpt_table_info *newinfo; 809 - int cpu; 810 - 811 - newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL); 812 - if (!newinfo) 813 - return NULL; 814 - 815 - newinfo->size = size; 816 - 817 - for_each_cpu(cpu) { 818 - if (size <= PAGE_SIZE) 819 - newinfo->entries[cpu] = kmalloc_node(size, 820 - GFP_KERNEL, 821 - cpu_to_node(cpu)); 822 - else 823 - newinfo->entries[cpu] = vmalloc_node(size, 824 - cpu_to_node(cpu)); 825 - 826 - if (newinfo->entries[cpu] == NULL) { 827 - free_table_info(newinfo); 828 - return NULL; 829 - } 830 - } 831 - 832 - return newinfo; 833 } 834 835 static int do_replace(void __user *user, unsigned int len) ··· 796 int ret; 797 struct arpt_replace tmp; 798 struct arpt_table *t; 799 - struct arpt_table_info *newinfo, *oldinfo; 800 - struct arpt_counters *counters; 801 void *loc_cpu_entry, *loc_cpu_old_entry; 802 803 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ··· 807 if (len != sizeof(tmp) + tmp.size) 808 return -ENOPROTOOPT; 809 810 - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 811 - if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) 812 - return -ENOMEM; 813 - 814 - newinfo = alloc_table_info(tmp.size); 815 if (!newinfo) 816 return -ENOMEM; 817 ··· 819 goto free_newinfo; 820 } 821 822 - counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters)); 823 if (!counters) { 824 ret = -ENOMEM; 825 goto free_newinfo; ··· 833 834 duprintf("arp_tables: Translated table\n"); 835 836 - t = try_then_request_module(find_table_lock(tmp.name), 837 "arptable_%s", tmp.name); 838 if (!t || IS_ERR(t)) { 839 ret = t ? PTR_ERR(t) : -ENOENT; ··· 848 goto put_module; 849 } 850 851 - oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); 852 if (!oldinfo) 853 goto put_module; 854 ··· 868 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 869 ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 870 871 - free_table_info(oldinfo); 872 if (copy_to_user(tmp.counters, counters, 873 - sizeof(struct arpt_counters) * tmp.num_counters) != 0) 874 ret = -EFAULT; 875 vfree(counters); 876 - up(&arpt_mutex); 877 return ret; 878 879 put_module: 880 module_put(t->me); 881 - up(&arpt_mutex); 882 free_newinfo_counters_untrans: 883 ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 884 free_newinfo_counters: 885 vfree(counters); 886 free_newinfo: 887 - free_table_info(newinfo); 888 return ret; 889 } 890 ··· 892 * and everything is OK. 893 */ 894 static inline int add_counter_to_entry(struct arpt_entry *e, 895 - const struct arpt_counters addme[], 896 unsigned int *i) 897 { 898 ··· 905 static int do_add_counters(void __user *user, unsigned int len) 906 { 907 unsigned int i; 908 - struct arpt_counters_info tmp, *paddc; 909 struct arpt_table *t; 910 int ret = 0; 911 void *loc_cpu_entry; 912 913 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 914 return -EFAULT; 915 916 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters)) 917 return -EINVAL; 918 919 paddc = vmalloc(len); ··· 926 goto free; 927 } 928 929 - t = find_table_lock(tmp.name); 930 if (!t || IS_ERR(t)) { 931 ret = t ? PTR_ERR(t) : -ENOENT; 932 goto free; 933 } 934 935 write_lock_bh(&t->lock); 936 - if (t->private->number != paddc->num_counters) { 937 ret = -EINVAL; 938 goto unlock_up_free; 939 } 940 941 i = 0; 942 /* Choose the copy that is on our node */ 943 - loc_cpu_entry = t->private->entries[smp_processor_id()]; 944 ARPT_ENTRY_ITERATE(loc_cpu_entry, 945 - t->private->size, 946 add_counter_to_entry, 947 paddc->counters, 948 &i); 949 unlock_up_free: 950 write_unlock_bh(&t->lock); 951 - up(&arpt_mutex); 952 module_put(t->me); 953 free: 954 vfree(paddc); ··· 1006 } 1007 name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; 1008 1009 - t = try_then_request_module(find_table_lock(name), 1010 "arptable_%s", name); 1011 if (t && !IS_ERR(t)) { 1012 struct arpt_getinfo info; 1013 1014 info.valid_hooks = t->valid_hooks; 1015 - memcpy(info.hook_entry, t->private->hook_entry, 1016 sizeof(info.hook_entry)); 1017 - memcpy(info.underflow, t->private->underflow, 1018 sizeof(info.underflow)); 1019 - info.num_entries = t->private->number; 1020 - info.size = t->private->size; 1021 strcpy(info.name, name); 1022 1023 if (copy_to_user(user, &info, *len) != 0) 1024 ret = -EFAULT; 1025 else 1026 ret = 0; 1027 - up(&arpt_mutex); 1028 module_put(t->me); 1029 } else 1030 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1050 } 1051 1052 case ARPT_SO_GET_REVISION_TARGET: { 1053 - struct arpt_get_revision rev; 1054 1055 if (*len != sizeof(rev)) { 1056 ret = -EINVAL; ··· 1061 break; 1062 } 1063 1064 - try_then_request_module(find_revision(rev.name, rev.revision, 1065 - target_revfn, &ret), 1066 "arpt_%s", rev.name); 1067 break; 1068 } ··· 1075 return ret; 1076 } 1077 1078 - /* Registration hooks for targets. */ 1079 - int arpt_register_target(struct arpt_target *target) 1080 - { 1081 - int ret; 1082 - 1083 - ret = down_interruptible(&arpt_mutex); 1084 - if (ret != 0) 1085 - return ret; 1086 - 1087 - list_add(&target->list, &arpt_target); 1088 - up(&arpt_mutex); 1089 - 1090 - return ret; 1091 - } 1092 - 1093 - void arpt_unregister_target(struct arpt_target *target) 1094 - { 1095 - down(&arpt_mutex); 1096 - LIST_DELETE(&arpt_target, target); 1097 - up(&arpt_mutex); 1098 - } 1099 - 1100 int arpt_register_table(struct arpt_table *table, 1101 const struct arpt_replace *repl) 1102 { 1103 int ret; 1104 - struct arpt_table_info *newinfo; 1105 - static struct arpt_table_info bootstrap 1106 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1107 void *loc_cpu_entry; 1108 1109 - newinfo = alloc_table_info(repl->size); 1110 if (!newinfo) { 1111 ret = -ENOMEM; 1112 return ret; ··· 1099 repl->num_entries, 1100 repl->hook_entry, 1101 repl->underflow); 1102 duprintf("arpt_register_table: translate table gives %d\n", ret); 1103 if (ret != 0) { 1104 - free_table_info(newinfo); 1105 return ret; 1106 } 1107 1108 - ret = down_interruptible(&arpt_mutex); 1109 - if (ret != 0) { 1110 - free_table_info(newinfo); 1111 return ret; 1112 } 1113 1114 - /* Don't autoload: we'd eat our tail... */ 1115 - if (list_named_find(&arpt_tables, table->name)) { 1116 - ret = -EEXIST; 1117 - goto free_unlock; 1118 - } 1119 - 1120 - /* Simplifies replace_table code. */ 1121 - table->private = &bootstrap; 1122 - if (!replace_table(table, 0, newinfo, &ret)) 1123 - goto free_unlock; 1124 - 1125 - duprintf("table->private->number = %u\n", 1126 - table->private->number); 1127 - 1128 - /* save number of initial entries */ 1129 - table->private->initial_entries = table->private->number; 1130 - 1131 - rwlock_init(&table->lock); 1132 - list_prepend(&arpt_tables, table); 1133 - 1134 - unlock: 1135 - up(&arpt_mutex); 1136 - return ret; 1137 - 1138 - free_unlock: 1139 - free_table_info(newinfo); 1140 - goto unlock; 1141 } 1142 1143 void arpt_unregister_table(struct arpt_table *table) 1144 { 1145 void *loc_cpu_entry; 1146 1147 - down(&arpt_mutex); 1148 - LIST_DELETE(&arpt_tables, table); 1149 - up(&arpt_mutex); 1150 1151 /* Decrease module usage counts and free resources */ 1152 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1153 - ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, 1154 cleanup_entry, NULL); 1155 - free_table_info(table->private); 1156 } 1157 1158 /* The built-in targets: standard (NULL) and error. */ ··· 1148 .get = do_arpt_get_ctl, 1149 }; 1150 1151 - #ifdef CONFIG_PROC_FS 1152 - static inline int print_name(const struct arpt_table *t, 1153 - off_t start_offset, char *buffer, int length, 1154 - off_t *pos, unsigned int *count) 1155 - { 1156 - if ((*count)++ >= start_offset) { 1157 - unsigned int namelen; 1158 - 1159 - namelen = sprintf(buffer + *pos, "%s\n", t->name); 1160 - if (*pos + namelen > length) { 1161 - /* Stop iterating */ 1162 - return 1; 1163 - } 1164 - *pos += namelen; 1165 - } 1166 - return 0; 1167 - } 1168 - 1169 - static int arpt_get_tables(char *buffer, char **start, off_t offset, int length) 1170 - { 1171 - off_t pos = 0; 1172 - unsigned int count = 0; 1173 - 1174 - if (down_interruptible(&arpt_mutex) != 0) 1175 - return 0; 1176 - 1177 - LIST_FIND(&arpt_tables, print_name, struct arpt_table *, 1178 - offset, buffer, length, &pos, &count); 1179 - 1180 - up(&arpt_mutex); 1181 - 1182 - /* `start' hack - see fs/proc/generic.c line ~105 */ 1183 - *start=(char *)((unsigned long)count-offset); 1184 - return pos; 1185 - } 1186 - #endif /*CONFIG_PROC_FS*/ 1187 - 1188 static int __init init(void) 1189 { 1190 int ret; 1191 1192 /* Noone else will be downing sem now, so we won't sleep */ 1193 - down(&arpt_mutex); 1194 - list_append(&arpt_target, &arpt_standard_target); 1195 - list_append(&arpt_target, &arpt_error_target); 1196 - up(&arpt_mutex); 1197 1198 /* Register setsockopt */ 1199 ret = nf_register_sockopt(&arpt_sockopts); ··· 1165 return ret; 1166 } 1167 1168 - #ifdef CONFIG_PROC_FS 1169 - { 1170 - struct proc_dir_entry *proc; 1171 - 1172 - proc = proc_net_create("arp_tables_names", 0, arpt_get_tables); 1173 - if (!proc) { 1174 - nf_unregister_sockopt(&arpt_sockopts); 1175 - return -ENOMEM; 1176 - } 1177 - proc->owner = THIS_MODULE; 1178 - } 1179 - #endif 1180 - 1181 printk("arp_tables: (C) 2002 David S. Miller\n"); 1182 return 0; 1183 } ··· 1172 static void __exit fini(void) 1173 { 1174 nf_unregister_sockopt(&arpt_sockopts); 1175 - #ifdef CONFIG_PROC_FS 1176 - proc_net_remove("arp_tables_names"); 1177 - #endif 1178 } 1179 1180 EXPORT_SYMBOL(arpt_register_table); 1181 EXPORT_SYMBOL(arpt_unregister_table); 1182 EXPORT_SYMBOL(arpt_do_table); 1183 - EXPORT_SYMBOL(arpt_register_target); 1184 - EXPORT_SYMBOL(arpt_unregister_target); 1185 1186 module_init(init); 1187 module_exit(fini);
··· 24 #include <asm/uaccess.h> 25 #include <asm/semaphore.h> 26 27 + #include <linux/netfilter/x_tables.h> 28 #include <linux/netfilter_arp/arp_tables.h> 29 30 MODULE_LICENSE("GPL"); ··· 55 #else 56 #define ARP_NF_ASSERT(x) 57 #endif 58 59 #include <linux/netfilter_ipv4/listhelp.h> 60 61 static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, 62 char *hdr_addr, int len) ··· 223 } 224 225 static unsigned int arpt_error(struct sk_buff **pskb, 226 const struct net_device *in, 227 const struct net_device *out, 228 + unsigned int hooknum, 229 const void *targinfo, 230 void *userinfo) 231 { ··· 254 struct arpt_entry *e, *back; 255 const char *indev, *outdev; 256 void *table_base; 257 + struct xt_table_info *private = table->private; 258 259 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ 260 if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + ··· 265 outdev = out ? out->name : nulldevname; 266 267 read_lock_bh(&table->lock); 268 + table_base = (void *)private->entries[smp_processor_id()]; 269 + e = get_entry(table_base, private->hook_entry[hook]); 270 + back = get_entry(table_base, private->underflow[hook]); 271 272 arp = (*pskb)->nh.arph; 273 do { ··· 315 * abs. verdicts 316 */ 317 verdict = t->u.kernel.target->target(pskb, 318 in, out, 319 + hook, 320 t->data, 321 userdata); 322 ··· 341 return verdict; 342 } 343 344 /* All zeroes == unconditional rule. */ 345 static inline int unconditional(const struct arpt_arp *arp) 346 { ··· 456 /* Figures out from what hook each rule can be called: returns 0 if 457 * there are loops. Puts hook bitmask in comefrom. 458 */ 459 + static int mark_source_chains(struct xt_table_info *newinfo, 460 unsigned int valid_hooks, void *entry0) 461 { 462 unsigned int hook; ··· 587 } 588 589 t = arpt_get_target(e); 590 + target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, 591 + t->u.user.revision), 592 "arpt_%s", t->u.user.name); 593 if (IS_ERR(target) || !target) { 594 duprintf("check_entry: `%s' not found\n", t->u.user.name); ··· 622 } 623 624 static inline int check_entry_size_and_hooks(struct arpt_entry *e, 625 + struct xt_table_info *newinfo, 626 unsigned char *base, 627 unsigned char *limit, 628 const unsigned int *hook_entries, ··· 656 < 0 (not ARPT_RETURN). --RR */ 657 658 /* Clear counters and comefrom */ 659 + e->counters = ((struct xt_counters) { 0, 0 }); 660 e->comefrom = 0; 661 662 (*i)++; ··· 683 */ 684 static int translate_table(const char *name, 685 unsigned int valid_hooks, 686 + struct xt_table_info *newinfo, 687 void *entry0, 688 unsigned int size, 689 unsigned int number, ··· 764 return ret; 765 } 766 767 /* Gets counters. */ 768 static inline int add_entry_to_counter(const struct arpt_entry *e, 769 + struct xt_counters total[], 770 unsigned int *i) 771 { 772 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 801 } 802 803 static inline int set_entry_to_counter(const struct arpt_entry *e, 804 + struct xt_counters total[], 805 unsigned int *i) 806 { 807 SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 810 return 0; 811 } 812 813 + static void get_counters(const struct xt_table_info *t, 814 + struct xt_counters counters[]) 815 { 816 unsigned int cpu; 817 unsigned int i; ··· 849 { 850 unsigned int off, num, countersize; 851 struct arpt_entry *e; 852 + struct xt_counters *counters; 853 + struct xt_table_info *private = table->private; 854 int ret = 0; 855 void *loc_cpu_entry; 856 ··· 857 * (other than comefrom, which userspace doesn't care 858 * about). 859 */ 860 + countersize = sizeof(struct xt_counters) * private->number; 861 + counters = vmalloc_node(countersize, numa_node_id()); 862 863 if (counters == NULL) 864 return -ENOMEM; 865 866 /* First, sum counters... */ 867 write_lock_bh(&table->lock); 868 + get_counters(private, counters); 869 write_unlock_bh(&table->lock); 870 871 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 872 /* ... then copy entire thing ... */ 873 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 874 ret = -EFAULT; ··· 911 int ret; 912 struct arpt_table *t; 913 914 + t = xt_find_table_lock(NF_ARP, entries->name); 915 if (t || !IS_ERR(t)) { 916 + struct xt_table_info *private = t->private; 917 duprintf("t->private->number = %u\n", 918 + private->number); 919 + if (entries->size == private->size) 920 + ret = copy_entries_to_user(private->size, 921 t, uptr->entrytable); 922 else { 923 duprintf("get_entries: I've got %u not %u!\n", 924 + private->size, entries->size); 925 ret = -EINVAL; 926 } 927 module_put(t->me); 928 + xt_table_unlock(t); 929 } else 930 ret = t ? PTR_ERR(t) : -ENOENT; 931 932 return ret; 933 } 934 935 static int do_replace(void __user *user, unsigned int len) ··· 978 int ret; 979 struct arpt_replace tmp; 980 struct arpt_table *t; 981 + struct xt_table_info *newinfo, *oldinfo; 982 + struct xt_counters *counters; 983 void *loc_cpu_entry, *loc_cpu_old_entry; 984 985 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ··· 989 if (len != sizeof(tmp) + tmp.size) 990 return -ENOPROTOOPT; 991 992 + newinfo = xt_alloc_table_info(tmp.size); 993 if (!newinfo) 994 return -ENOMEM; 995 ··· 1005 goto free_newinfo; 1006 } 1007 1008 + counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 1009 if (!counters) { 1010 ret = -ENOMEM; 1011 goto free_newinfo; ··· 1019 1020 duprintf("arp_tables: Translated table\n"); 1021 1022 + t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name), 1023 "arptable_%s", tmp.name); 1024 if (!t || IS_ERR(t)) { 1025 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1034 goto put_module; 1035 } 1036 1037 + oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 1038 if (!oldinfo) 1039 goto put_module; 1040 ··· 1054 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1055 ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 1056 1057 + xt_free_table_info(oldinfo); 1058 if (copy_to_user(tmp.counters, counters, 1059 + sizeof(struct xt_counters) * tmp.num_counters) != 0) 1060 ret = -EFAULT; 1061 vfree(counters); 1062 + xt_table_unlock(t); 1063 return ret; 1064 1065 put_module: 1066 module_put(t->me); 1067 + xt_table_unlock(t); 1068 free_newinfo_counters_untrans: 1069 ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1070 free_newinfo_counters: 1071 vfree(counters); 1072 free_newinfo: 1073 + xt_free_table_info(newinfo); 1074 return ret; 1075 } 1076 ··· 1078 * and everything is OK. 1079 */ 1080 static inline int add_counter_to_entry(struct arpt_entry *e, 1081 + const struct xt_counters addme[], 1082 unsigned int *i) 1083 { 1084 ··· 1091 static int do_add_counters(void __user *user, unsigned int len) 1092 { 1093 unsigned int i; 1094 + struct xt_counters_info tmp, *paddc; 1095 struct arpt_table *t; 1096 + struct xt_table_info *private; 1097 int ret = 0; 1098 void *loc_cpu_entry; 1099 1100 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1101 return -EFAULT; 1102 1103 + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 1104 return -EINVAL; 1105 1106 paddc = vmalloc(len); ··· 1111 goto free; 1112 } 1113 1114 + t = xt_find_table_lock(NF_ARP, tmp.name); 1115 if (!t || IS_ERR(t)) { 1116 ret = t ? PTR_ERR(t) : -ENOENT; 1117 goto free; 1118 } 1119 1120 write_lock_bh(&t->lock); 1121 + private = t->private; 1122 + if (private->number != paddc->num_counters) { 1123 ret = -EINVAL; 1124 goto unlock_up_free; 1125 } 1126 1127 i = 0; 1128 /* Choose the copy that is on our node */ 1129 + loc_cpu_entry = private->entries[smp_processor_id()]; 1130 ARPT_ENTRY_ITERATE(loc_cpu_entry, 1131 + private->size, 1132 add_counter_to_entry, 1133 paddc->counters, 1134 &i); 1135 unlock_up_free: 1136 write_unlock_bh(&t->lock); 1137 + xt_table_unlock(t); 1138 module_put(t->me); 1139 free: 1140 vfree(paddc); ··· 1190 } 1191 name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; 1192 1193 + t = try_then_request_module(xt_find_table_lock(NF_ARP, name), 1194 "arptable_%s", name); 1195 if (t && !IS_ERR(t)) { 1196 struct arpt_getinfo info; 1197 + struct xt_table_info *private = t->private; 1198 1199 info.valid_hooks = t->valid_hooks; 1200 + memcpy(info.hook_entry, private->hook_entry, 1201 sizeof(info.hook_entry)); 1202 + memcpy(info.underflow, private->underflow, 1203 sizeof(info.underflow)); 1204 + info.num_entries = private->number; 1205 + info.size = private->size; 1206 strcpy(info.name, name); 1207 1208 if (copy_to_user(user, &info, *len) != 0) 1209 ret = -EFAULT; 1210 else 1211 ret = 0; 1212 + xt_table_unlock(t); 1213 module_put(t->me); 1214 } else 1215 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1233 } 1234 1235 case ARPT_SO_GET_REVISION_TARGET: { 1236 + struct xt_get_revision rev; 1237 1238 if (*len != sizeof(rev)) { 1239 ret = -EINVAL; ··· 1244 break; 1245 } 1246 1247 + try_then_request_module(xt_find_revision(NF_ARP, rev.name, 1248 + rev.revision, 1, &ret), 1249 "arpt_%s", rev.name); 1250 break; 1251 } ··· 1258 return ret; 1259 } 1260 1261 int arpt_register_table(struct arpt_table *table, 1262 const struct arpt_replace *repl) 1263 { 1264 int ret; 1265 + struct xt_table_info *newinfo; 1266 + static struct xt_table_info bootstrap 1267 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1268 void *loc_cpu_entry; 1269 1270 + newinfo = xt_alloc_table_info(repl->size); 1271 if (!newinfo) { 1272 ret = -ENOMEM; 1273 return ret; ··· 1304 repl->num_entries, 1305 repl->hook_entry, 1306 repl->underflow); 1307 + 1308 duprintf("arpt_register_table: translate table gives %d\n", ret); 1309 if (ret != 0) { 1310 + xt_free_table_info(newinfo); 1311 return ret; 1312 } 1313 1314 + if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1315 + xt_free_table_info(newinfo); 1316 return ret; 1317 } 1318 1319 + return 0; 1320 } 1321 1322 void arpt_unregister_table(struct arpt_table *table) 1323 { 1324 + struct xt_table_info *private; 1325 void *loc_cpu_entry; 1326 1327 + private = xt_unregister_table(table); 1328 1329 /* Decrease module usage counts and free resources */ 1330 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1331 + ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, 1332 cleanup_entry, NULL); 1333 + xt_free_table_info(private); 1334 } 1335 1336 /* The built-in targets: standard (NULL) and error. */ ··· 1380 .get = do_arpt_get_ctl, 1381 }; 1382 1383 static int __init init(void) 1384 { 1385 int ret; 1386 1387 + xt_proto_init(NF_ARP); 1388 + 1389 /* Noone else will be downing sem now, so we won't sleep */ 1390 + xt_register_target(NF_ARP, &arpt_standard_target); 1391 + xt_register_target(NF_ARP, &arpt_error_target); 1392 1393 /* Register setsockopt */ 1394 ret = nf_register_sockopt(&arpt_sockopts); ··· 1434 return ret; 1435 } 1436 1437 printk("arp_tables: (C) 2002 David S. Miller\n"); 1438 return 0; 1439 } ··· 1454 static void __exit fini(void) 1455 { 1456 nf_unregister_sockopt(&arpt_sockopts); 1457 + xt_proto_fini(NF_ARP); 1458 } 1459 1460 EXPORT_SYMBOL(arpt_register_table); 1461 EXPORT_SYMBOL(arpt_unregister_table); 1462 EXPORT_SYMBOL(arpt_do_table); 1463 1464 module_init(init); 1465 module_exit(fini);
+4 -3
net/ipv4/netfilter/arpt_mangle.c
··· 8 MODULE_DESCRIPTION("arptables arp payload mangle target"); 9 10 static unsigned int 11 - target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, 12 - const struct net_device *out, const void *targinfo, void *userinfo) 13 { 14 const struct arpt_mangle *mangle = targinfo; 15 struct arphdr *arp; ··· 65 } 66 67 static int 68 - checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, 69 unsigned int targinfosize, unsigned int hook_mask) 70 { 71 const struct arpt_mangle *mangle = targinfo;
··· 8 MODULE_DESCRIPTION("arptables arp payload mangle target"); 9 10 static unsigned int 11 + target(struct sk_buff **pskb, const struct net_device *in, 12 + const struct net_device *out, unsigned int hooknum, const void *targinfo, 13 + void *userinfo) 14 { 15 const struct arpt_mangle *mangle = targinfo; 16 struct arphdr *arp; ··· 64 } 65 66 static int 67 + checkentry(const char *tablename, const void *e, void *targinfo, 68 unsigned int targinfosize, unsigned int hook_mask) 69 { 70 const struct arpt_mangle *mangle = targinfo;
+1
net/ipv4/netfilter/arptable_filter.c
··· 145 .lock = RW_LOCK_UNLOCKED, 146 .private = NULL, 147 .me = THIS_MODULE, 148 }; 149 150 /* The work comes in here from netfilter.c */
··· 145 .lock = RW_LOCK_UNLOCKED, 146 .private = NULL, 147 .me = THIS_MODULE, 148 + .af = NF_ARP, 149 }; 150 151 /* The work comes in here from netfilter.c */
+2 -2
net/ipv4/netfilter/ip_conntrack_standalone.c
··· 944 945 /* Some modules need us, but don't depend directly on any symbol. 946 They should call this. */ 947 - void need_ip_conntrack(void) 948 { 949 } 950 ··· 962 EXPORT_SYMBOL(invert_tuplepr); 963 EXPORT_SYMBOL(ip_conntrack_alter_reply); 964 EXPORT_SYMBOL(ip_conntrack_destroyed); 965 - EXPORT_SYMBOL(need_ip_conntrack); 966 EXPORT_SYMBOL(ip_conntrack_helper_register); 967 EXPORT_SYMBOL(ip_conntrack_helper_unregister); 968 EXPORT_SYMBOL(ip_ct_iterate_cleanup);
··· 944 945 /* Some modules need us, but don't depend directly on any symbol. 946 They should call this. */ 947 + void need_conntrack(void) 948 { 949 } 950 ··· 962 EXPORT_SYMBOL(invert_tuplepr); 963 EXPORT_SYMBOL(ip_conntrack_alter_reply); 964 EXPORT_SYMBOL(ip_conntrack_destroyed); 965 + EXPORT_SYMBOL(need_conntrack); 966 EXPORT_SYMBOL(ip_conntrack_helper_register); 967 EXPORT_SYMBOL(ip_conntrack_helper_unregister); 968 EXPORT_SYMBOL(ip_ct_iterate_cleanup);
+3 -2
net/ipv4/netfilter/ip_nat_rule.c
··· 95 .valid_hooks = NAT_VALID_HOOKS, 96 .lock = RW_LOCK_UNLOCKED, 97 .me = THIS_MODULE, 98 }; 99 100 /* Source NAT */ ··· 169 } 170 171 static int ipt_snat_checkentry(const char *tablename, 172 - const struct ipt_entry *e, 173 void *targinfo, 174 unsigned int targinfosize, 175 unsigned int hook_mask) ··· 202 } 203 204 static int ipt_dnat_checkentry(const char *tablename, 205 - const struct ipt_entry *e, 206 void *targinfo, 207 unsigned int targinfosize, 208 unsigned int hook_mask)
··· 95 .valid_hooks = NAT_VALID_HOOKS, 96 .lock = RW_LOCK_UNLOCKED, 97 .me = THIS_MODULE, 98 + .af = AF_INET, 99 }; 100 101 /* Source NAT */ ··· 168 } 169 170 static int ipt_snat_checkentry(const char *tablename, 171 + const void *entry, 172 void *targinfo, 173 unsigned int targinfosize, 174 unsigned int hook_mask) ··· 201 } 202 203 static int ipt_dnat_checkentry(const char *tablename, 204 + const void *entry, 205 void *targinfo, 206 unsigned int targinfosize, 207 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ip_nat_standalone.c
··· 364 { 365 int ret = 0; 366 367 - need_ip_conntrack(); 368 369 if (!init) goto cleanup; 370
··· 364 { 365 int ret = 0; 366 367 + need_conntrack(); 368 369 if (!init) goto cleanup; 370
+95 -747
net/ipv4/netfilter/ip_tables.c
··· 2 * Packet matching code. 3 * 4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 5 - * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as ··· 11 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> 12 * - increase module usage count as soon as we have rules inside 13 * a table 14 */ 15 #include <linux/config.h> 16 #include <linux/cache.h> ··· 22 #include <linux/vmalloc.h> 23 #include <linux/netdevice.h> 24 #include <linux/module.h> 25 - #include <linux/tcp.h> 26 - #include <linux/udp.h> 27 #include <linux/icmp.h> 28 #include <net/ip.h> 29 #include <asm/uaccess.h> ··· 30 #include <linux/err.h> 31 #include <linux/cpumask.h> 32 33 #include <linux/netfilter_ipv4/ip_tables.h> 34 35 MODULE_LICENSE("GPL"); ··· 63 #else 64 #define IP_NF_ASSERT(x) 65 #endif 66 - #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 67 - 68 - static DECLARE_MUTEX(ipt_mutex); 69 - 70 - /* Must have mutex */ 71 - #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) 72 - #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) 73 - #include <linux/netfilter_ipv4/listhelp.h> 74 75 #if 0 76 /* All the better to debug you with... */ ··· 78 the counters or update the rules. 79 80 Hence the start of any table is given by get_table() below. */ 81 - 82 - /* The table itself */ 83 - struct ipt_table_info 84 - { 85 - /* Size per table */ 86 - unsigned int size; 87 - /* Number of entries: FIXME. --RR */ 88 - unsigned int number; 89 - /* Initial number of entries. Needed for module usage count */ 90 - unsigned int initial_entries; 91 - 92 - /* Entry points and underflows */ 93 - unsigned int hook_entry[NF_IP_NUMHOOKS]; 94 - unsigned int underflow[NF_IP_NUMHOOKS]; 95 - 96 - /* ipt_entry tables: one per CPU */ 97 - void *entries[NR_CPUS]; 98 - }; 99 - 100 - static LIST_HEAD(ipt_target); 101 - static LIST_HEAD(ipt_match); 102 - static LIST_HEAD(ipt_tables); 103 - #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 104 - #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 105 - 106 - #if 0 107 - #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) 108 - #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) 109 - #define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) 110 - #endif 111 112 /* Returns whether matches rule or not. */ 113 static inline int ··· 197 int *hotdrop) 198 { 199 /* Stop iteration if it doesn't match */ 200 - if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop)) 201 return 1; 202 else 203 return 0; ··· 229 const char *indev, *outdev; 230 void *table_base; 231 struct ipt_entry *e, *back; 232 233 /* Initialization */ 234 ip = (*pskb)->nh.iph; ··· 246 247 read_lock_bh(&table->lock); 248 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 249 - table_base = (void *)table->private->entries[smp_processor_id()]; 250 - e = get_entry(table_base, table->private->hook_entry[hook]); 251 - 252 - #ifdef CONFIG_NETFILTER_DEBUG 253 - /* Check noone else using our table */ 254 - if (((struct ipt_entry *)table_base)->comefrom != 0xdead57ac 255 - && ((struct ipt_entry *)table_base)->comefrom != 0xeeeeeeec) { 256 - printk("ASSERT: CPU #%u, %s comefrom(%p) = %X\n", 257 - smp_processor_id(), 258 - table->name, 259 - &((struct ipt_entry *)table_base)->comefrom, 260 - ((struct ipt_entry *)table_base)->comefrom); 261 - } 262 - ((struct ipt_entry *)table_base)->comefrom = 0x57acc001; 263 - #endif 264 265 /* For return from builtin chain */ 266 - back = get_entry(table_base, table->private->underflow[hook]); 267 268 do { 269 IP_NF_ASSERT(e); ··· 336 } 337 } while (!hotdrop); 338 339 - #ifdef CONFIG_NETFILTER_DEBUG 340 - ((struct ipt_entry *)table_base)->comefrom = 0xdead57ac; 341 - #endif 342 read_unlock_bh(&table->lock); 343 344 #ifdef DEBUG_ALLOW_ALL ··· 346 else return verdict; 347 #endif 348 } 349 - 350 - /* 351 - * These are weird, but module loading must not be done with mutex 352 - * held (since they will register), and we have to have a single 353 - * function to use try_then_request_module(). 354 - */ 355 - 356 - /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 357 - static inline struct ipt_table *find_table_lock(const char *name) 358 - { 359 - struct ipt_table *t; 360 - 361 - if (down_interruptible(&ipt_mutex) != 0) 362 - return ERR_PTR(-EINTR); 363 - 364 - list_for_each_entry(t, &ipt_tables, list) 365 - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 366 - return t; 367 - up(&ipt_mutex); 368 - return NULL; 369 - } 370 - 371 - /* Find match, grabs ref. Returns ERR_PTR() on error. */ 372 - static inline struct ipt_match *find_match(const char *name, u8 revision) 373 - { 374 - struct ipt_match *m; 375 - int err = 0; 376 - 377 - if (down_interruptible(&ipt_mutex) != 0) 378 - return ERR_PTR(-EINTR); 379 - 380 - list_for_each_entry(m, &ipt_match, list) { 381 - if (strcmp(m->name, name) == 0) { 382 - if (m->revision == revision) { 383 - if (try_module_get(m->me)) { 384 - up(&ipt_mutex); 385 - return m; 386 - } 387 - } else 388 - err = -EPROTOTYPE; /* Found something. */ 389 - } 390 - } 391 - up(&ipt_mutex); 392 - return ERR_PTR(err); 393 - } 394 - 395 - /* Find target, grabs ref. Returns ERR_PTR() on error. */ 396 - static inline struct ipt_target *find_target(const char *name, u8 revision) 397 - { 398 - struct ipt_target *t; 399 - int err = 0; 400 - 401 - if (down_interruptible(&ipt_mutex) != 0) 402 - return ERR_PTR(-EINTR); 403 - 404 - list_for_each_entry(t, &ipt_target, list) { 405 - if (strcmp(t->name, name) == 0) { 406 - if (t->revision == revision) { 407 - if (try_module_get(t->me)) { 408 - up(&ipt_mutex); 409 - return t; 410 - } 411 - } else 412 - err = -EPROTOTYPE; /* Found something. */ 413 - } 414 - } 415 - up(&ipt_mutex); 416 - return ERR_PTR(err); 417 - } 418 - 419 - struct ipt_target *ipt_find_target(const char *name, u8 revision) 420 - { 421 - struct ipt_target *target; 422 - 423 - target = try_then_request_module(find_target(name, revision), 424 - "ipt_%s", name); 425 - if (IS_ERR(target) || !target) 426 - return NULL; 427 - return target; 428 - } 429 - 430 - static int match_revfn(const char *name, u8 revision, int *bestp) 431 - { 432 - struct ipt_match *m; 433 - int have_rev = 0; 434 - 435 - list_for_each_entry(m, &ipt_match, list) { 436 - if (strcmp(m->name, name) == 0) { 437 - if (m->revision > *bestp) 438 - *bestp = m->revision; 439 - if (m->revision == revision) 440 - have_rev = 1; 441 - } 442 - } 443 - return have_rev; 444 - } 445 - 446 - static int target_revfn(const char *name, u8 revision, int *bestp) 447 - { 448 - struct ipt_target *t; 449 - int have_rev = 0; 450 - 451 - list_for_each_entry(t, &ipt_target, list) { 452 - if (strcmp(t->name, name) == 0) { 453 - if (t->revision > *bestp) 454 - *bestp = t->revision; 455 - if (t->revision == revision) 456 - have_rev = 1; 457 - } 458 - } 459 - return have_rev; 460 - } 461 - 462 - /* Returns true or false (if no such extension at all) */ 463 - static inline int find_revision(const char *name, u8 revision, 464 - int (*revfn)(const char *, u8, int *), 465 - int *err) 466 - { 467 - int have_rev, best = -1; 468 - 469 - if (down_interruptible(&ipt_mutex) != 0) { 470 - *err = -EINTR; 471 - return 1; 472 - } 473 - have_rev = revfn(name, revision, &best); 474 - up(&ipt_mutex); 475 - 476 - /* Nothing at all? Return 0 to try loading module. */ 477 - if (best == -1) { 478 - *err = -ENOENT; 479 - return 0; 480 - } 481 - 482 - *err = best; 483 - if (!have_rev) 484 - *err = -EPROTONOSUPPORT; 485 - return 1; 486 - } 487 - 488 489 /* All zeroes == unconditional rule. */ 490 static inline int ··· 363 /* Figures out from what hook each rule can be called: returns 0 if 364 there are loops. Puts hook bitmask in comefrom. */ 365 static int 366 - mark_source_chains(struct ipt_table_info *newinfo, 367 unsigned int valid_hooks, void *entry0) 368 { 369 unsigned int hook; ··· 509 { 510 struct ipt_match *match; 511 512 - match = try_then_request_module(find_match(m->u.user.name, 513 m->u.user.revision), 514 "ipt_%s", m->u.user.name); 515 if (IS_ERR(match) || !match) { ··· 554 goto cleanup_matches; 555 556 t = ipt_get_target(e); 557 - target = try_then_request_module(find_target(t->u.user.name, 558 t->u.user.revision), 559 "ipt_%s", t->u.user.name); 560 if (IS_ERR(target) || !target) { ··· 592 593 static inline int 594 check_entry_size_and_hooks(struct ipt_entry *e, 595 - struct ipt_table_info *newinfo, 596 unsigned char *base, 597 unsigned char *limit, 598 const unsigned int *hook_entries, ··· 626 < 0 (not IPT_RETURN). --RR */ 627 628 /* Clear counters and comefrom */ 629 - e->counters = ((struct ipt_counters) { 0, 0 }); 630 e->comefrom = 0; 631 632 (*i)++; ··· 656 static int 657 translate_table(const char *name, 658 unsigned int valid_hooks, 659 - struct ipt_table_info *newinfo, 660 void *entry0, 661 unsigned int size, 662 unsigned int number, ··· 733 return ret; 734 } 735 736 - static struct ipt_table_info * 737 - replace_table(struct ipt_table *table, 738 - unsigned int num_counters, 739 - struct ipt_table_info *newinfo, 740 - int *error) 741 - { 742 - struct ipt_table_info *oldinfo; 743 - 744 - #ifdef CONFIG_NETFILTER_DEBUG 745 - { 746 - int cpu; 747 - 748 - for_each_cpu(cpu) { 749 - struct ipt_entry *table_base = newinfo->entries[cpu]; 750 - if (table_base) 751 - table_base->comefrom = 0xdead57ac; 752 - } 753 - } 754 - #endif 755 - 756 - /* Do the substitution. */ 757 - write_lock_bh(&table->lock); 758 - /* Check inside lock: is the old number correct? */ 759 - if (num_counters != table->private->number) { 760 - duprintf("num_counters != table->private->number (%u/%u)\n", 761 - num_counters, table->private->number); 762 - write_unlock_bh(&table->lock); 763 - *error = -EAGAIN; 764 - return NULL; 765 - } 766 - oldinfo = table->private; 767 - table->private = newinfo; 768 - newinfo->initial_entries = oldinfo->initial_entries; 769 - write_unlock_bh(&table->lock); 770 - 771 - return oldinfo; 772 - } 773 - 774 /* Gets counters. */ 775 static inline int 776 add_entry_to_counter(const struct ipt_entry *e, 777 - struct ipt_counters total[], 778 unsigned int *i) 779 { 780 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 757 } 758 759 static void 760 - get_counters(const struct ipt_table_info *t, 761 - struct ipt_counters counters[]) 762 { 763 unsigned int cpu; 764 unsigned int i; ··· 797 { 798 unsigned int off, num, countersize; 799 struct ipt_entry *e; 800 - struct ipt_counters *counters; 801 int ret = 0; 802 void *loc_cpu_entry; 803 804 /* We need atomic snapshot of counters: rest doesn't change 805 (other than comefrom, which userspace doesn't care 806 about). */ 807 - countersize = sizeof(struct ipt_counters) * table->private->number; 808 counters = vmalloc_node(countersize, numa_node_id()); 809 810 if (counters == NULL) ··· 813 814 /* First, sum counters... */ 815 write_lock_bh(&table->lock); 816 - get_counters(table->private, counters); 817 write_unlock_bh(&table->lock); 818 819 /* choose the copy that is on our node/cpu, ... 820 * This choice is lazy (because current thread is 821 * allowed to migrate to another cpu) 822 */ 823 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 824 /* ... then copy entire thing ... */ 825 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 826 ret = -EFAULT; ··· 882 int ret; 883 struct ipt_table *t; 884 885 - t = find_table_lock(entries->name); 886 if (t && !IS_ERR(t)) { 887 duprintf("t->private->number = %u\n", 888 - t->private->number); 889 - if (entries->size == t->private->size) 890 - ret = copy_entries_to_user(t->private->size, 891 t, uptr->entrytable); 892 else { 893 duprintf("get_entries: I've got %u not %u!\n", 894 - t->private->size, 895 entries->size); 896 ret = -EINVAL; 897 } 898 module_put(t->me); 899 - up(&ipt_mutex); 900 } else 901 ret = t ? PTR_ERR(t) : -ENOENT; 902 903 return ret; 904 - } 905 - 906 - static void free_table_info(struct ipt_table_info *info) 907 - { 908 - int cpu; 909 - for_each_cpu(cpu) { 910 - if (info->size <= PAGE_SIZE) 911 - kfree(info->entries[cpu]); 912 - else 913 - vfree(info->entries[cpu]); 914 - } 915 - kfree(info); 916 - } 917 - 918 - static struct ipt_table_info *alloc_table_info(unsigned int size) 919 - { 920 - struct ipt_table_info *newinfo; 921 - int cpu; 922 - 923 - newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL); 924 - if (!newinfo) 925 - return NULL; 926 - 927 - newinfo->size = size; 928 - 929 - for_each_cpu(cpu) { 930 - if (size <= PAGE_SIZE) 931 - newinfo->entries[cpu] = kmalloc_node(size, 932 - GFP_KERNEL, 933 - cpu_to_node(cpu)); 934 - else 935 - newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu)); 936 - if (newinfo->entries[cpu] == 0) { 937 - free_table_info(newinfo); 938 - return NULL; 939 - } 940 - } 941 - 942 - return newinfo; 943 } 944 945 static int ··· 910 int ret; 911 struct ipt_replace tmp; 912 struct ipt_table *t; 913 - struct ipt_table_info *newinfo, *oldinfo; 914 - struct ipt_counters *counters; 915 void *loc_cpu_entry, *loc_cpu_old_entry; 916 917 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ··· 921 if (len != sizeof(tmp) + tmp.size) 922 return -ENOPROTOOPT; 923 924 - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 925 - if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) 926 - return -ENOMEM; 927 - 928 - newinfo = alloc_table_info(tmp.size); 929 if (!newinfo) 930 return -ENOMEM; 931 ··· 933 goto free_newinfo; 934 } 935 936 - counters = vmalloc(tmp.num_counters * sizeof(struct ipt_counters)); 937 if (!counters) { 938 ret = -ENOMEM; 939 goto free_newinfo; ··· 947 948 duprintf("ip_tables: Translated table\n"); 949 950 - t = try_then_request_module(find_table_lock(tmp.name), 951 "iptable_%s", tmp.name); 952 if (!t || IS_ERR(t)) { 953 ret = t ? PTR_ERR(t) : -ENOENT; ··· 962 goto put_module; 963 } 964 965 - oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); 966 if (!oldinfo) 967 goto put_module; 968 ··· 981 /* Decrease module usage counts and free resource */ 982 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 983 IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 984 - free_table_info(oldinfo); 985 if (copy_to_user(tmp.counters, counters, 986 - sizeof(struct ipt_counters) * tmp.num_counters) != 0) 987 ret = -EFAULT; 988 vfree(counters); 989 - up(&ipt_mutex); 990 return ret; 991 992 put_module: 993 module_put(t->me); 994 - up(&ipt_mutex); 995 free_newinfo_counters_untrans: 996 IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 997 free_newinfo_counters: 998 vfree(counters); 999 free_newinfo: 1000 - free_table_info(newinfo); 1001 return ret; 1002 } 1003 ··· 1005 * and everything is OK. */ 1006 static inline int 1007 add_counter_to_entry(struct ipt_entry *e, 1008 - const struct ipt_counters addme[], 1009 unsigned int *i) 1010 { 1011 #if 0 ··· 1027 do_add_counters(void __user *user, unsigned int len) 1028 { 1029 unsigned int i; 1030 - struct ipt_counters_info tmp, *paddc; 1031 struct ipt_table *t; 1032 int ret = 0; 1033 void *loc_cpu_entry; 1034 1035 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1036 return -EFAULT; 1037 1038 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) 1039 return -EINVAL; 1040 1041 paddc = vmalloc_node(len, numa_node_id()); ··· 1048 goto free; 1049 } 1050 1051 - t = find_table_lock(tmp.name); 1052 if (!t || IS_ERR(t)) { 1053 ret = t ? PTR_ERR(t) : -ENOENT; 1054 goto free; 1055 } 1056 1057 write_lock_bh(&t->lock); 1058 - if (t->private->number != paddc->num_counters) { 1059 ret = -EINVAL; 1060 goto unlock_up_free; 1061 } 1062 1063 i = 0; 1064 /* Choose the copy that is on our node */ 1065 - loc_cpu_entry = t->private->entries[raw_smp_processor_id()]; 1066 IPT_ENTRY_ITERATE(loc_cpu_entry, 1067 - t->private->size, 1068 add_counter_to_entry, 1069 paddc->counters, 1070 &i); 1071 unlock_up_free: 1072 write_unlock_bh(&t->lock); 1073 - up(&ipt_mutex); 1074 module_put(t->me); 1075 free: 1076 vfree(paddc); ··· 1130 } 1131 name[IPT_TABLE_MAXNAMELEN-1] = '\0'; 1132 1133 - t = try_then_request_module(find_table_lock(name), 1134 "iptable_%s", name); 1135 if (t && !IS_ERR(t)) { 1136 struct ipt_getinfo info; 1137 1138 info.valid_hooks = t->valid_hooks; 1139 - memcpy(info.hook_entry, t->private->hook_entry, 1140 sizeof(info.hook_entry)); 1141 - memcpy(info.underflow, t->private->underflow, 1142 sizeof(info.underflow)); 1143 - info.num_entries = t->private->number; 1144 - info.size = t->private->size; 1145 memcpy(info.name, name, sizeof(info.name)); 1146 1147 if (copy_to_user(user, &info, *len) != 0) 1148 ret = -EFAULT; 1149 else 1150 ret = 0; 1151 - up(&ipt_mutex); 1152 module_put(t->me); 1153 } else 1154 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1176 case IPT_SO_GET_REVISION_MATCH: 1177 case IPT_SO_GET_REVISION_TARGET: { 1178 struct ipt_get_revision rev; 1179 - int (*revfn)(const char *, u8, int *); 1180 1181 if (*len != sizeof(rev)) { 1182 ret = -EINVAL; ··· 1188 } 1189 1190 if (cmd == IPT_SO_GET_REVISION_TARGET) 1191 - revfn = target_revfn; 1192 else 1193 - revfn = match_revfn; 1194 1195 - try_then_request_module(find_revision(rev.name, rev.revision, 1196 - revfn, &ret), 1197 "ipt_%s", rev.name); 1198 break; 1199 } ··· 1207 return ret; 1208 } 1209 1210 - /* Registration hooks for targets. */ 1211 - int 1212 - ipt_register_target(struct ipt_target *target) 1213 { 1214 int ret; 1215 - 1216 - ret = down_interruptible(&ipt_mutex); 1217 - if (ret != 0) 1218 - return ret; 1219 - list_add(&target->list, &ipt_target); 1220 - up(&ipt_mutex); 1221 - return ret; 1222 - } 1223 - 1224 - void 1225 - ipt_unregister_target(struct ipt_target *target) 1226 - { 1227 - down(&ipt_mutex); 1228 - LIST_DELETE(&ipt_target, target); 1229 - up(&ipt_mutex); 1230 - } 1231 - 1232 - int 1233 - ipt_register_match(struct ipt_match *match) 1234 - { 1235 - int ret; 1236 - 1237 - ret = down_interruptible(&ipt_mutex); 1238 - if (ret != 0) 1239 - return ret; 1240 - 1241 - list_add(&match->list, &ipt_match); 1242 - up(&ipt_mutex); 1243 - 1244 - return ret; 1245 - } 1246 - 1247 - void 1248 - ipt_unregister_match(struct ipt_match *match) 1249 - { 1250 - down(&ipt_mutex); 1251 - LIST_DELETE(&ipt_match, match); 1252 - up(&ipt_mutex); 1253 - } 1254 - 1255 - int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) 1256 - { 1257 - int ret; 1258 - struct ipt_table_info *newinfo; 1259 - static struct ipt_table_info bootstrap 1260 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1261 void *loc_cpu_entry; 1262 1263 - newinfo = alloc_table_info(repl->size); 1264 if (!newinfo) 1265 return -ENOMEM; 1266 ··· 1231 repl->hook_entry, 1232 repl->underflow); 1233 if (ret != 0) { 1234 - free_table_info(newinfo); 1235 return ret; 1236 } 1237 1238 - ret = down_interruptible(&ipt_mutex); 1239 - if (ret != 0) { 1240 - free_table_info(newinfo); 1241 return ret; 1242 } 1243 1244 - /* Don't autoload: we'd eat our tail... */ 1245 - if (list_named_find(&ipt_tables, table->name)) { 1246 - ret = -EEXIST; 1247 - goto free_unlock; 1248 - } 1249 - 1250 - /* Simplifies replace_table code. */ 1251 - table->private = &bootstrap; 1252 - if (!replace_table(table, 0, newinfo, &ret)) 1253 - goto free_unlock; 1254 - 1255 - duprintf("table->private->number = %u\n", 1256 - table->private->number); 1257 - 1258 - /* save number of initial entries */ 1259 - table->private->initial_entries = table->private->number; 1260 - 1261 - rwlock_init(&table->lock); 1262 - list_prepend(&ipt_tables, table); 1263 - 1264 - unlock: 1265 - up(&ipt_mutex); 1266 - return ret; 1267 - 1268 - free_unlock: 1269 - free_table_info(newinfo); 1270 - goto unlock; 1271 } 1272 1273 void ipt_unregister_table(struct ipt_table *table) 1274 { 1275 void *loc_cpu_entry; 1276 1277 - down(&ipt_mutex); 1278 - LIST_DELETE(&ipt_tables, table); 1279 - up(&ipt_mutex); 1280 1281 /* Decrease module usage counts and free resources */ 1282 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1283 - IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, 1284 - cleanup_entry, NULL); 1285 - free_table_info(table->private); 1286 - } 1287 - 1288 - /* Returns 1 if the port is matched by the range, 0 otherwise */ 1289 - static inline int 1290 - port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 1291 - { 1292 - int ret; 1293 - 1294 - ret = (port >= min && port <= max) ^ invert; 1295 - return ret; 1296 - } 1297 - 1298 - static int 1299 - tcp_find_option(u_int8_t option, 1300 - const struct sk_buff *skb, 1301 - unsigned int optlen, 1302 - int invert, 1303 - int *hotdrop) 1304 - { 1305 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 1306 - u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 1307 - unsigned int i; 1308 - 1309 - duprintf("tcp_match: finding option\n"); 1310 - 1311 - if (!optlen) 1312 - return invert; 1313 - 1314 - /* If we don't have the whole header, drop packet. */ 1315 - op = skb_header_pointer(skb, 1316 - skb->nh.iph->ihl*4 + sizeof(struct tcphdr), 1317 - optlen, _opt); 1318 - if (op == NULL) { 1319 - *hotdrop = 1; 1320 - return 0; 1321 - } 1322 - 1323 - for (i = 0; i < optlen; ) { 1324 - if (op[i] == option) return !invert; 1325 - if (op[i] < 2) i++; 1326 - else i += op[i+1]?:1; 1327 - } 1328 - 1329 - return invert; 1330 - } 1331 - 1332 - static int 1333 - tcp_match(const struct sk_buff *skb, 1334 - const struct net_device *in, 1335 - const struct net_device *out, 1336 - const void *matchinfo, 1337 - int offset, 1338 - int *hotdrop) 1339 - { 1340 - struct tcphdr _tcph, *th; 1341 - const struct ipt_tcp *tcpinfo = matchinfo; 1342 - 1343 - if (offset) { 1344 - /* To quote Alan: 1345 - 1346 - Don't allow a fragment of TCP 8 bytes in. Nobody normal 1347 - causes this. Its a cracker trying to break in by doing a 1348 - flag overwrite to pass the direction checks. 1349 - */ 1350 - if (offset == 1) { 1351 - duprintf("Dropping evil TCP offset=1 frag.\n"); 1352 - *hotdrop = 1; 1353 - } 1354 - /* Must not be a fragment. */ 1355 - return 0; 1356 - } 1357 - 1358 - #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 1359 - 1360 - th = skb_header_pointer(skb, skb->nh.iph->ihl*4, 1361 - sizeof(_tcph), &_tcph); 1362 - if (th == NULL) { 1363 - /* We've been asked to examine this packet, and we 1364 - can't. Hence, no choice but to drop. */ 1365 - duprintf("Dropping evil TCP offset=0 tinygram.\n"); 1366 - *hotdrop = 1; 1367 - return 0; 1368 - } 1369 - 1370 - if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 1371 - ntohs(th->source), 1372 - !!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))) 1373 - return 0; 1374 - if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 1375 - ntohs(th->dest), 1376 - !!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))) 1377 - return 0; 1378 - if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 1379 - == tcpinfo->flg_cmp, 1380 - IPT_TCP_INV_FLAGS)) 1381 - return 0; 1382 - if (tcpinfo->option) { 1383 - if (th->doff * 4 < sizeof(_tcph)) { 1384 - *hotdrop = 1; 1385 - return 0; 1386 - } 1387 - if (!tcp_find_option(tcpinfo->option, skb, 1388 - th->doff*4 - sizeof(_tcph), 1389 - tcpinfo->invflags & IPT_TCP_INV_OPTION, 1390 - hotdrop)) 1391 - return 0; 1392 - } 1393 - return 1; 1394 - } 1395 - 1396 - /* Called when user tries to insert an entry of this type. */ 1397 - static int 1398 - tcp_checkentry(const char *tablename, 1399 - const struct ipt_ip *ip, 1400 - void *matchinfo, 1401 - unsigned int matchsize, 1402 - unsigned int hook_mask) 1403 - { 1404 - const struct ipt_tcp *tcpinfo = matchinfo; 1405 - 1406 - /* Must specify proto == TCP, and no unknown invflags */ 1407 - return ip->proto == IPPROTO_TCP 1408 - && !(ip->invflags & IPT_INV_PROTO) 1409 - && matchsize == IPT_ALIGN(sizeof(struct ipt_tcp)) 1410 - && !(tcpinfo->invflags & ~IPT_TCP_INV_MASK); 1411 - } 1412 - 1413 - static int 1414 - udp_match(const struct sk_buff *skb, 1415 - const struct net_device *in, 1416 - const struct net_device *out, 1417 - const void *matchinfo, 1418 - int offset, 1419 - int *hotdrop) 1420 - { 1421 - struct udphdr _udph, *uh; 1422 - const struct ipt_udp *udpinfo = matchinfo; 1423 - 1424 - /* Must not be a fragment. */ 1425 - if (offset) 1426 - return 0; 1427 - 1428 - uh = skb_header_pointer(skb, skb->nh.iph->ihl*4, 1429 - sizeof(_udph), &_udph); 1430 - if (uh == NULL) { 1431 - /* We've been asked to examine this packet, and we 1432 - can't. Hence, no choice but to drop. */ 1433 - duprintf("Dropping evil UDP tinygram.\n"); 1434 - *hotdrop = 1; 1435 - return 0; 1436 - } 1437 - 1438 - return port_match(udpinfo->spts[0], udpinfo->spts[1], 1439 - ntohs(uh->source), 1440 - !!(udpinfo->invflags & IPT_UDP_INV_SRCPT)) 1441 - && port_match(udpinfo->dpts[0], udpinfo->dpts[1], 1442 - ntohs(uh->dest), 1443 - !!(udpinfo->invflags & IPT_UDP_INV_DSTPT)); 1444 - } 1445 - 1446 - /* Called when user tries to insert an entry of this type. */ 1447 - static int 1448 - udp_checkentry(const char *tablename, 1449 - const struct ipt_ip *ip, 1450 - void *matchinfo, 1451 - unsigned int matchinfosize, 1452 - unsigned int hook_mask) 1453 - { 1454 - const struct ipt_udp *udpinfo = matchinfo; 1455 - 1456 - /* Must specify proto == UDP, and no unknown invflags */ 1457 - if (ip->proto != IPPROTO_UDP || (ip->invflags & IPT_INV_PROTO)) { 1458 - duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, 1459 - IPPROTO_UDP); 1460 - return 0; 1461 - } 1462 - if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_udp))) { 1463 - duprintf("ipt_udp: matchsize %u != %u\n", 1464 - matchinfosize, IPT_ALIGN(sizeof(struct ipt_udp))); 1465 - return 0; 1466 - } 1467 - if (udpinfo->invflags & ~IPT_UDP_INV_MASK) { 1468 - duprintf("ipt_udp: unknown flags %X\n", 1469 - udpinfo->invflags); 1470 - return 0; 1471 - } 1472 - 1473 - return 1; 1474 } 1475 1476 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ ··· 1272 const struct net_device *out, 1273 const void *matchinfo, 1274 int offset, 1275 int *hotdrop) 1276 { 1277 struct icmphdr _icmph, *ic; ··· 1282 if (offset) 1283 return 0; 1284 1285 - ic = skb_header_pointer(skb, skb->nh.iph->ihl*4, 1286 - sizeof(_icmph), &_icmph); 1287 if (ic == NULL) { 1288 /* We've been asked to examine this packet, and we 1289 * can't. Hence, no choice but to drop. ··· 1302 /* Called when user tries to insert an entry of this type. */ 1303 static int 1304 icmp_checkentry(const char *tablename, 1305 - const struct ipt_ip *ip, 1306 void *matchinfo, 1307 unsigned int matchsize, 1308 unsigned int hook_mask) 1309 { 1310 const struct ipt_icmp *icmpinfo = matchinfo; 1311 1312 /* Must specify proto == ICMP, and no unknown invflags */ ··· 1337 .get = do_ipt_get_ctl, 1338 }; 1339 1340 - static struct ipt_match tcp_matchstruct = { 1341 - .name = "tcp", 1342 - .match = &tcp_match, 1343 - .checkentry = &tcp_checkentry, 1344 - }; 1345 - 1346 - static struct ipt_match udp_matchstruct = { 1347 - .name = "udp", 1348 - .match = &udp_match, 1349 - .checkentry = &udp_checkentry, 1350 - }; 1351 - 1352 static struct ipt_match icmp_matchstruct = { 1353 .name = "icmp", 1354 .match = &icmp_match, 1355 .checkentry = &icmp_checkentry, 1356 }; 1357 1358 - #ifdef CONFIG_PROC_FS 1359 - static inline int print_name(const char *i, 1360 - off_t start_offset, char *buffer, int length, 1361 - off_t *pos, unsigned int *count) 1362 - { 1363 - if ((*count)++ >= start_offset) { 1364 - unsigned int namelen; 1365 - 1366 - namelen = sprintf(buffer + *pos, "%s\n", 1367 - i + sizeof(struct list_head)); 1368 - if (*pos + namelen > length) { 1369 - /* Stop iterating */ 1370 - return 1; 1371 - } 1372 - *pos += namelen; 1373 - } 1374 - return 0; 1375 - } 1376 - 1377 - static inline int print_target(const struct ipt_target *t, 1378 - off_t start_offset, char *buffer, int length, 1379 - off_t *pos, unsigned int *count) 1380 - { 1381 - if (t == &ipt_standard_target || t == &ipt_error_target) 1382 - return 0; 1383 - return print_name((char *)t, start_offset, buffer, length, pos, count); 1384 - } 1385 - 1386 - static int ipt_get_tables(char *buffer, char **start, off_t offset, int length) 1387 - { 1388 - off_t pos = 0; 1389 - unsigned int count = 0; 1390 - 1391 - if (down_interruptible(&ipt_mutex) != 0) 1392 - return 0; 1393 - 1394 - LIST_FIND(&ipt_tables, print_name, void *, 1395 - offset, buffer, length, &pos, &count); 1396 - 1397 - up(&ipt_mutex); 1398 - 1399 - /* `start' hack - see fs/proc/generic.c line ~105 */ 1400 - *start=(char *)((unsigned long)count-offset); 1401 - return pos; 1402 - } 1403 - 1404 - static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) 1405 - { 1406 - off_t pos = 0; 1407 - unsigned int count = 0; 1408 - 1409 - if (down_interruptible(&ipt_mutex) != 0) 1410 - return 0; 1411 - 1412 - LIST_FIND(&ipt_target, print_target, struct ipt_target *, 1413 - offset, buffer, length, &pos, &count); 1414 - 1415 - up(&ipt_mutex); 1416 - 1417 - *start = (char *)((unsigned long)count - offset); 1418 - return pos; 1419 - } 1420 - 1421 - static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) 1422 - { 1423 - off_t pos = 0; 1424 - unsigned int count = 0; 1425 - 1426 - if (down_interruptible(&ipt_mutex) != 0) 1427 - return 0; 1428 - 1429 - LIST_FIND(&ipt_match, print_name, void *, 1430 - offset, buffer, length, &pos, &count); 1431 - 1432 - up(&ipt_mutex); 1433 - 1434 - *start = (char *)((unsigned long)count - offset); 1435 - return pos; 1436 - } 1437 - 1438 - static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = 1439 - { { "ip_tables_names", ipt_get_tables }, 1440 - { "ip_tables_targets", ipt_get_targets }, 1441 - { "ip_tables_matches", ipt_get_matches }, 1442 - { NULL, NULL} }; 1443 - #endif /*CONFIG_PROC_FS*/ 1444 - 1445 static int __init init(void) 1446 { 1447 int ret; 1448 1449 /* Noone else will be downing sem now, so we won't sleep */ 1450 - down(&ipt_mutex); 1451 - list_append(&ipt_target, &ipt_standard_target); 1452 - list_append(&ipt_target, &ipt_error_target); 1453 - list_append(&ipt_match, &tcp_matchstruct); 1454 - list_append(&ipt_match, &udp_matchstruct); 1455 - list_append(&ipt_match, &icmp_matchstruct); 1456 - up(&ipt_mutex); 1457 1458 /* Register setsockopt */ 1459 ret = nf_register_sockopt(&ipt_sockopts); ··· 1361 return ret; 1362 } 1363 1364 - #ifdef CONFIG_PROC_FS 1365 - { 1366 - struct proc_dir_entry *proc; 1367 - int i; 1368 - 1369 - for (i = 0; ipt_proc_entry[i].name; i++) { 1370 - proc = proc_net_create(ipt_proc_entry[i].name, 0, 1371 - ipt_proc_entry[i].get_info); 1372 - if (!proc) { 1373 - while (--i >= 0) 1374 - proc_net_remove(ipt_proc_entry[i].name); 1375 - nf_unregister_sockopt(&ipt_sockopts); 1376 - return -ENOMEM; 1377 - } 1378 - proc->owner = THIS_MODULE; 1379 - } 1380 - } 1381 - #endif 1382 - 1383 - printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); 1384 return 0; 1385 } 1386 1387 static void __exit fini(void) 1388 { 1389 nf_unregister_sockopt(&ipt_sockopts); 1390 - #ifdef CONFIG_PROC_FS 1391 - { 1392 - int i; 1393 - for (i = 0; ipt_proc_entry[i].name; i++) 1394 - proc_net_remove(ipt_proc_entry[i].name); 1395 - } 1396 - #endif 1397 } 1398 1399 EXPORT_SYMBOL(ipt_register_table); 1400 EXPORT_SYMBOL(ipt_unregister_table); 1401 - EXPORT_SYMBOL(ipt_register_match); 1402 - EXPORT_SYMBOL(ipt_unregister_match); 1403 EXPORT_SYMBOL(ipt_do_table); 1404 - EXPORT_SYMBOL(ipt_register_target); 1405 - EXPORT_SYMBOL(ipt_unregister_target); 1406 - EXPORT_SYMBOL(ipt_find_target); 1407 - 1408 module_init(init); 1409 module_exit(fini);
··· 2 * Packet matching code. 3 * 4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 5 + * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as ··· 11 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org> 12 * - increase module usage count as soon as we have rules inside 13 * a table 14 + * 08 Oct 2005 Harald Welte <lafore@netfilter.org> 15 + * - Generalize into "x_tables" layer and "{ip,ip6,arp}_tables" 16 */ 17 #include <linux/config.h> 18 #include <linux/cache.h> ··· 20 #include <linux/vmalloc.h> 21 #include <linux/netdevice.h> 22 #include <linux/module.h> 23 #include <linux/icmp.h> 24 #include <net/ip.h> 25 #include <asm/uaccess.h> ··· 30 #include <linux/err.h> 31 #include <linux/cpumask.h> 32 33 + #include <linux/netfilter/x_tables.h> 34 #include <linux/netfilter_ipv4/ip_tables.h> 35 36 MODULE_LICENSE("GPL"); ··· 62 #else 63 #define IP_NF_ASSERT(x) 64 #endif 65 66 #if 0 67 /* All the better to debug you with... */ ··· 85 the counters or update the rules. 86 87 Hence the start of any table is given by get_table() below. */ 88 89 /* Returns whether matches rule or not. */ 90 static inline int ··· 234 int *hotdrop) 235 { 236 /* Stop iteration if it doesn't match */ 237 + if (!m->u.kernel.match->match(skb, in, out, m->data, offset, 238 + skb->nh.iph->ihl*4, hotdrop)) 239 return 1; 240 else 241 return 0; ··· 265 const char *indev, *outdev; 266 void *table_base; 267 struct ipt_entry *e, *back; 268 + struct xt_table_info *private = table->private; 269 270 /* Initialization */ 271 ip = (*pskb)->nh.iph; ··· 281 282 read_lock_bh(&table->lock); 283 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 284 + table_base = (void *)private->entries[smp_processor_id()]; 285 + e = get_entry(table_base, private->hook_entry[hook]); 286 287 /* For return from builtin chain */ 288 + back = get_entry(table_base, private->underflow[hook]); 289 290 do { 291 IP_NF_ASSERT(e); ··· 384 } 385 } while (!hotdrop); 386 387 read_unlock_bh(&table->lock); 388 389 #ifdef DEBUG_ALLOW_ALL ··· 397 else return verdict; 398 #endif 399 } 400 401 /* All zeroes == unconditional rule. */ 402 static inline int ··· 553 /* Figures out from what hook each rule can be called: returns 0 if 554 there are loops. Puts hook bitmask in comefrom. */ 555 static int 556 + mark_source_chains(struct xt_table_info *newinfo, 557 unsigned int valid_hooks, void *entry0) 558 { 559 unsigned int hook; ··· 699 { 700 struct ipt_match *match; 701 702 + match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, 703 m->u.user.revision), 704 "ipt_%s", m->u.user.name); 705 if (IS_ERR(match) || !match) { ··· 744 goto cleanup_matches; 745 746 t = ipt_get_target(e); 747 + target = try_then_request_module(xt_find_target(AF_INET, 748 + t->u.user.name, 749 t->u.user.revision), 750 "ipt_%s", t->u.user.name); 751 if (IS_ERR(target) || !target) { ··· 781 782 static inline int 783 check_entry_size_and_hooks(struct ipt_entry *e, 784 + struct xt_table_info *newinfo, 785 unsigned char *base, 786 unsigned char *limit, 787 const unsigned int *hook_entries, ··· 815 < 0 (not IPT_RETURN). --RR */ 816 817 /* Clear counters and comefrom */ 818 + e->counters = ((struct xt_counters) { 0, 0 }); 819 e->comefrom = 0; 820 821 (*i)++; ··· 845 static int 846 translate_table(const char *name, 847 unsigned int valid_hooks, 848 + struct xt_table_info *newinfo, 849 void *entry0, 850 unsigned int size, 851 unsigned int number, ··· 922 return ret; 923 } 924 925 /* Gets counters. */ 926 static inline int 927 add_entry_to_counter(const struct ipt_entry *e, 928 + struct xt_counters total[], 929 unsigned int *i) 930 { 931 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 984 } 985 986 static void 987 + get_counters(const struct xt_table_info *t, 988 + struct xt_counters counters[]) 989 { 990 unsigned int cpu; 991 unsigned int i; ··· 1024 { 1025 unsigned int off, num, countersize; 1026 struct ipt_entry *e; 1027 + struct xt_counters *counters; 1028 + struct xt_table_info *private = table->private; 1029 int ret = 0; 1030 void *loc_cpu_entry; 1031 1032 /* We need atomic snapshot of counters: rest doesn't change 1033 (other than comefrom, which userspace doesn't care 1034 about). */ 1035 + countersize = sizeof(struct xt_counters) * private->number; 1036 counters = vmalloc_node(countersize, numa_node_id()); 1037 1038 if (counters == NULL) ··· 1039 1040 /* First, sum counters... */ 1041 write_lock_bh(&table->lock); 1042 + get_counters(private, counters); 1043 write_unlock_bh(&table->lock); 1044 1045 /* choose the copy that is on our node/cpu, ... 1046 * This choice is lazy (because current thread is 1047 * allowed to migrate to another cpu) 1048 */ 1049 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1050 /* ... then copy entire thing ... */ 1051 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 1052 ret = -EFAULT; ··· 1108 int ret; 1109 struct ipt_table *t; 1110 1111 + t = xt_find_table_lock(AF_INET, entries->name); 1112 if (t && !IS_ERR(t)) { 1113 + struct xt_table_info *private = t->private; 1114 duprintf("t->private->number = %u\n", 1115 + private->number); 1116 + if (entries->size == private->size) 1117 + ret = copy_entries_to_user(private->size, 1118 t, uptr->entrytable); 1119 else { 1120 duprintf("get_entries: I've got %u not %u!\n", 1121 + private->size, 1122 entries->size); 1123 ret = -EINVAL; 1124 } 1125 module_put(t->me); 1126 + xt_table_unlock(t); 1127 } else 1128 ret = t ? PTR_ERR(t) : -ENOENT; 1129 1130 return ret; 1131 } 1132 1133 static int ··· 1174 int ret; 1175 struct ipt_replace tmp; 1176 struct ipt_table *t; 1177 + struct xt_table_info *newinfo, *oldinfo; 1178 + struct xt_counters *counters; 1179 void *loc_cpu_entry, *loc_cpu_old_entry; 1180 1181 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ··· 1185 if (len != sizeof(tmp) + tmp.size) 1186 return -ENOPROTOOPT; 1187 1188 + newinfo = xt_alloc_table_info(tmp.size); 1189 if (!newinfo) 1190 return -ENOMEM; 1191 ··· 1201 goto free_newinfo; 1202 } 1203 1204 + counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 1205 if (!counters) { 1206 ret = -ENOMEM; 1207 goto free_newinfo; ··· 1215 1216 duprintf("ip_tables: Translated table\n"); 1217 1218 + t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), 1219 "iptable_%s", tmp.name); 1220 if (!t || IS_ERR(t)) { 1221 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1230 goto put_module; 1231 } 1232 1233 + oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 1234 if (!oldinfo) 1235 goto put_module; 1236 ··· 1249 /* Decrease module usage counts and free resource */ 1250 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1251 IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 1252 + xt_free_table_info(oldinfo); 1253 if (copy_to_user(tmp.counters, counters, 1254 + sizeof(struct xt_counters) * tmp.num_counters) != 0) 1255 ret = -EFAULT; 1256 vfree(counters); 1257 + xt_table_unlock(t); 1258 return ret; 1259 1260 put_module: 1261 module_put(t->me); 1262 + xt_table_unlock(t); 1263 free_newinfo_counters_untrans: 1264 IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 1265 free_newinfo_counters: 1266 vfree(counters); 1267 free_newinfo: 1268 + xt_free_table_info(newinfo); 1269 return ret; 1270 } 1271 ··· 1273 * and everything is OK. */ 1274 static inline int 1275 add_counter_to_entry(struct ipt_entry *e, 1276 + const struct xt_counters addme[], 1277 unsigned int *i) 1278 { 1279 #if 0 ··· 1295 do_add_counters(void __user *user, unsigned int len) 1296 { 1297 unsigned int i; 1298 + struct xt_counters_info tmp, *paddc; 1299 struct ipt_table *t; 1300 + struct xt_table_info *private; 1301 int ret = 0; 1302 void *loc_cpu_entry; 1303 1304 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1305 return -EFAULT; 1306 1307 + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 1308 return -EINVAL; 1309 1310 paddc = vmalloc_node(len, numa_node_id()); ··· 1315 goto free; 1316 } 1317 1318 + t = xt_find_table_lock(AF_INET, tmp.name); 1319 if (!t || IS_ERR(t)) { 1320 ret = t ? PTR_ERR(t) : -ENOENT; 1321 goto free; 1322 } 1323 1324 write_lock_bh(&t->lock); 1325 + private = t->private; 1326 + if (private->number != paddc->num_counters) { 1327 ret = -EINVAL; 1328 goto unlock_up_free; 1329 } 1330 1331 i = 0; 1332 /* Choose the copy that is on our node */ 1333 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1334 IPT_ENTRY_ITERATE(loc_cpu_entry, 1335 + private->size, 1336 add_counter_to_entry, 1337 paddc->counters, 1338 &i); 1339 unlock_up_free: 1340 write_unlock_bh(&t->lock); 1341 + xt_table_unlock(t); 1342 module_put(t->me); 1343 free: 1344 vfree(paddc); ··· 1396 } 1397 name[IPT_TABLE_MAXNAMELEN-1] = '\0'; 1398 1399 + t = try_then_request_module(xt_find_table_lock(AF_INET, name), 1400 "iptable_%s", name); 1401 if (t && !IS_ERR(t)) { 1402 struct ipt_getinfo info; 1403 + struct xt_table_info *private = t->private; 1404 1405 info.valid_hooks = t->valid_hooks; 1406 + memcpy(info.hook_entry, private->hook_entry, 1407 sizeof(info.hook_entry)); 1408 + memcpy(info.underflow, private->underflow, 1409 sizeof(info.underflow)); 1410 + info.num_entries = private->number; 1411 + info.size = private->size; 1412 memcpy(info.name, name, sizeof(info.name)); 1413 1414 if (copy_to_user(user, &info, *len) != 0) 1415 ret = -EFAULT; 1416 else 1417 ret = 0; 1418 + xt_table_unlock(t); 1419 module_put(t->me); 1420 } else 1421 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1441 case IPT_SO_GET_REVISION_MATCH: 1442 case IPT_SO_GET_REVISION_TARGET: { 1443 struct ipt_get_revision rev; 1444 + int target; 1445 1446 if (*len != sizeof(rev)) { 1447 ret = -EINVAL; ··· 1453 } 1454 1455 if (cmd == IPT_SO_GET_REVISION_TARGET) 1456 + target = 1; 1457 else 1458 + target = 0; 1459 1460 + try_then_request_module(xt_find_revision(AF_INET, rev.name, 1461 + rev.revision, 1462 + target, &ret), 1463 "ipt_%s", rev.name); 1464 break; 1465 } ··· 1471 return ret; 1472 } 1473 1474 + int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) 1475 { 1476 int ret; 1477 + struct xt_table_info *newinfo; 1478 + static struct xt_table_info bootstrap 1479 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1480 void *loc_cpu_entry; 1481 1482 + newinfo = xt_alloc_table_info(repl->size); 1483 if (!newinfo) 1484 return -ENOMEM; 1485 ··· 1540 repl->hook_entry, 1541 repl->underflow); 1542 if (ret != 0) { 1543 + xt_free_table_info(newinfo); 1544 return ret; 1545 } 1546 1547 + if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1548 + xt_free_table_info(newinfo); 1549 return ret; 1550 } 1551 1552 + return 0; 1553 } 1554 1555 void ipt_unregister_table(struct ipt_table *table) 1556 { 1557 + struct xt_table_info *private; 1558 void *loc_cpu_entry; 1559 1560 + private = xt_unregister_table(table); 1561 1562 /* Decrease module usage counts and free resources */ 1563 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1564 + IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 1565 + xt_free_table_info(private); 1566 } 1567 1568 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ ··· 1798 const struct net_device *out, 1799 const void *matchinfo, 1800 int offset, 1801 + unsigned int protoff, 1802 int *hotdrop) 1803 { 1804 struct icmphdr _icmph, *ic; ··· 1807 if (offset) 1808 return 0; 1809 1810 + ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 1811 if (ic == NULL) { 1812 /* We've been asked to examine this packet, and we 1813 * can't. Hence, no choice but to drop. ··· 1828 /* Called when user tries to insert an entry of this type. */ 1829 static int 1830 icmp_checkentry(const char *tablename, 1831 + const void *info, 1832 void *matchinfo, 1833 unsigned int matchsize, 1834 unsigned int hook_mask) 1835 { 1836 + const struct ipt_ip *ip = info; 1837 const struct ipt_icmp *icmpinfo = matchinfo; 1838 1839 /* Must specify proto == ICMP, and no unknown invflags */ ··· 1862 .get = do_ipt_get_ctl, 1863 }; 1864 1865 static struct ipt_match icmp_matchstruct = { 1866 .name = "icmp", 1867 .match = &icmp_match, 1868 .checkentry = &icmp_checkentry, 1869 }; 1870 1871 static int __init init(void) 1872 { 1873 int ret; 1874 1875 + xt_proto_init(AF_INET); 1876 + 1877 /* Noone else will be downing sem now, so we won't sleep */ 1878 + xt_register_target(AF_INET, &ipt_standard_target); 1879 + xt_register_target(AF_INET, &ipt_error_target); 1880 + xt_register_match(AF_INET, &icmp_matchstruct); 1881 1882 /* Register setsockopt */ 1883 ret = nf_register_sockopt(&ipt_sockopts); ··· 1987 return ret; 1988 } 1989 1990 + printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); 1991 return 0; 1992 } 1993 1994 static void __exit fini(void) 1995 { 1996 nf_unregister_sockopt(&ipt_sockopts); 1997 + 1998 + xt_unregister_match(AF_INET, &icmp_matchstruct); 1999 + xt_unregister_target(AF_INET, &ipt_error_target); 2000 + xt_unregister_target(AF_INET, &ipt_standard_target); 2001 + 2002 + xt_proto_fini(AF_INET); 2003 } 2004 2005 EXPORT_SYMBOL(ipt_register_table); 2006 EXPORT_SYMBOL(ipt_unregister_table); 2007 EXPORT_SYMBOL(ipt_do_table); 2008 module_init(init); 2009 module_exit(fini);
-90
net/ipv4/netfilter/ipt_CLASSIFY.c
··· 1 - /* 2 - * This is a module which is used for setting the skb->priority field 3 - * of an skb for qdisc classification. 4 - */ 5 - 6 - /* (C) 2001-2002 Patrick McHardy <kaber@trash.net> 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License version 2 as 10 - * published by the Free Software Foundation. 11 - */ 12 - 13 - #include <linux/module.h> 14 - #include <linux/skbuff.h> 15 - #include <linux/ip.h> 16 - #include <net/checksum.h> 17 - 18 - #include <linux/netfilter_ipv4/ip_tables.h> 19 - #include <linux/netfilter_ipv4/ipt_CLASSIFY.h> 20 - 21 - MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 22 - MODULE_LICENSE("GPL"); 23 - MODULE_DESCRIPTION("iptables qdisc classification target module"); 24 - 25 - static unsigned int 26 - target(struct sk_buff **pskb, 27 - const struct net_device *in, 28 - const struct net_device *out, 29 - unsigned int hooknum, 30 - const void *targinfo, 31 - void *userinfo) 32 - { 33 - const struct ipt_classify_target_info *clinfo = targinfo; 34 - 35 - if((*pskb)->priority != clinfo->priority) 36 - (*pskb)->priority = clinfo->priority; 37 - 38 - return IPT_CONTINUE; 39 - } 40 - 41 - static int 42 - checkentry(const char *tablename, 43 - const struct ipt_entry *e, 44 - void *targinfo, 45 - unsigned int targinfosize, 46 - unsigned int hook_mask) 47 - { 48 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){ 49 - printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", 50 - targinfosize, 51 - IPT_ALIGN(sizeof(struct ipt_classify_target_info))); 52 - return 0; 53 - } 54 - 55 - if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 56 - (1 << NF_IP_POST_ROUTING))) { 57 - printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD " 58 - "and POST_ROUTING.\n"); 59 - return 0; 60 - } 61 - 62 - if (strcmp(tablename, "mangle") != 0) { 63 - printk(KERN_ERR "CLASSIFY: can only be called from " 64 - "\"mangle\" table, not \"%s\".\n", 65 - tablename); 66 - return 0; 67 - } 68 - 69 - return 1; 70 - } 71 - 72 - static struct ipt_target ipt_classify_reg = { 73 - .name = "CLASSIFY", 74 - .target = target, 75 - .checkentry = checkentry, 76 - .me = THIS_MODULE, 77 - }; 78 - 79 - static int __init init(void) 80 - { 81 - return ipt_register_target(&ipt_classify_reg); 82 - } 83 - 84 - static void __exit fini(void) 85 - { 86 - ipt_unregister_target(&ipt_classify_reg); 87 - } 88 - 89 - module_init(init); 90 - module_exit(fini);
···
+2 -1
net/ipv4/netfilter/ipt_CLUSTERIP.c
··· 379 380 static int 381 checkentry(const char *tablename, 382 - const struct ipt_entry *e, 383 void *targinfo, 384 unsigned int targinfosize, 385 unsigned int hook_mask) 386 { 387 struct ipt_clusterip_tgt_info *cipinfo = targinfo; 388 389 struct clusterip_config *config; 390
··· 379 380 static int 381 checkentry(const char *tablename, 382 + const void *e_void, 383 void *targinfo, 384 unsigned int targinfosize, 385 unsigned int hook_mask) 386 { 387 struct ipt_clusterip_tgt_info *cipinfo = targinfo; 388 + const struct ipt_entry *e = e_void; 389 390 struct clusterip_config *config; 391
-122
net/ipv4/netfilter/ipt_CONNMARK.c
··· 1 - /* This kernel module is used to modify the connection mark values, or 2 - * to optionally restore the skb nfmark from the connection mark 3 - * 4 - * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 - * by Henrik Nordstrom <hno@marasystems.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - * 12 - * This program is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - * GNU General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU General Public License 18 - * along with this program; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 - */ 21 - #include <linux/module.h> 22 - #include <linux/skbuff.h> 23 - #include <linux/ip.h> 24 - #include <net/checksum.h> 25 - 26 - MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 27 - MODULE_DESCRIPTION("IP tables CONNMARK matching module"); 28 - MODULE_LICENSE("GPL"); 29 - 30 - #include <linux/netfilter_ipv4/ip_tables.h> 31 - #include <linux/netfilter_ipv4/ipt_CONNMARK.h> 32 - #include <net/netfilter/nf_conntrack_compat.h> 33 - 34 - static unsigned int 35 - target(struct sk_buff **pskb, 36 - const struct net_device *in, 37 - const struct net_device *out, 38 - unsigned int hooknum, 39 - const void *targinfo, 40 - void *userinfo) 41 - { 42 - const struct ipt_connmark_target_info *markinfo = targinfo; 43 - u_int32_t diff; 44 - u_int32_t nfmark; 45 - u_int32_t newmark; 46 - u_int32_t ctinfo; 47 - u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); 48 - 49 - if (ctmark) { 50 - switch(markinfo->mode) { 51 - case IPT_CONNMARK_SET: 52 - newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; 53 - if (newmark != *ctmark) 54 - *ctmark = newmark; 55 - break; 56 - case IPT_CONNMARK_SAVE: 57 - newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); 58 - if (*ctmark != newmark) 59 - *ctmark = newmark; 60 - break; 61 - case IPT_CONNMARK_RESTORE: 62 - nfmark = (*pskb)->nfmark; 63 - diff = (*ctmark ^ nfmark) & markinfo->mask; 64 - if (diff != 0) 65 - (*pskb)->nfmark = nfmark ^ diff; 66 - break; 67 - } 68 - } 69 - 70 - return IPT_CONTINUE; 71 - } 72 - 73 - static int 74 - checkentry(const char *tablename, 75 - const struct ipt_entry *e, 76 - void *targinfo, 77 - unsigned int targinfosize, 78 - unsigned int hook_mask) 79 - { 80 - struct ipt_connmark_target_info *matchinfo = targinfo; 81 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) { 82 - printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", 83 - targinfosize, 84 - IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); 85 - return 0; 86 - } 87 - 88 - if (matchinfo->mode == IPT_CONNMARK_RESTORE) { 89 - if (strcmp(tablename, "mangle") != 0) { 90 - printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); 91 - return 0; 92 - } 93 - } 94 - 95 - if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { 96 - printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 97 - return 0; 98 - } 99 - 100 - return 1; 101 - } 102 - 103 - static struct ipt_target ipt_connmark_reg = { 104 - .name = "CONNMARK", 105 - .target = &target, 106 - .checkentry = &checkentry, 107 - .me = THIS_MODULE 108 - }; 109 - 110 - static int __init init(void) 111 - { 112 - need_ip_conntrack(); 113 - return ipt_register_target(&ipt_connmark_reg); 114 - } 115 - 116 - static void __exit fini(void) 117 - { 118 - ipt_unregister_target(&ipt_connmark_reg); 119 - } 120 - 121 - module_init(init); 122 - module_exit(fini);
···
+1 -1
net/ipv4/netfilter/ipt_DSCP.c
··· 57 58 static int 59 checkentry(const char *tablename, 60 - const struct ipt_entry *e, 61 void *targinfo, 62 unsigned int targinfosize, 63 unsigned int hook_mask)
··· 57 58 static int 59 checkentry(const char *tablename, 60 + const void *e_void, 61 void *targinfo, 62 unsigned int targinfosize, 63 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_ECN.c
··· 113 114 static int 115 checkentry(const char *tablename, 116 - const struct ipt_entry *e, 117 void *targinfo, 118 unsigned int targinfosize, 119 unsigned int hook_mask) 120 { 121 const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; 122 123 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { 124 printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
··· 113 114 static int 115 checkentry(const char *tablename, 116 + const void *e_void, 117 void *targinfo, 118 unsigned int targinfosize, 119 unsigned int hook_mask) 120 { 121 const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; 122 + const struct ipt_entry *e = e_void; 123 124 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { 125 printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n",
+1 -1
net/ipv4/netfilter/ipt_LOG.c
··· 431 } 432 433 static int ipt_log_checkentry(const char *tablename, 434 - const struct ipt_entry *e, 435 void *targinfo, 436 unsigned int targinfosize, 437 unsigned int hook_mask)
··· 431 } 432 433 static int ipt_log_checkentry(const char *tablename, 434 + const void *e, 435 void *targinfo, 436 unsigned int targinfosize, 437 unsigned int hook_mask)
-172
net/ipv4/netfilter/ipt_MARK.c
··· 1 - /* This is a module which is used for setting the NFMARK field of an skb. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <linux/ip.h> 13 - #include <net/checksum.h> 14 - 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - #include <linux/netfilter_ipv4/ipt_MARK.h> 17 - 18 - MODULE_LICENSE("GPL"); 19 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 20 - MODULE_DESCRIPTION("iptables MARK modification module"); 21 - 22 - static unsigned int 23 - target_v0(struct sk_buff **pskb, 24 - const struct net_device *in, 25 - const struct net_device *out, 26 - unsigned int hooknum, 27 - const void *targinfo, 28 - void *userinfo) 29 - { 30 - const struct ipt_mark_target_info *markinfo = targinfo; 31 - 32 - if((*pskb)->nfmark != markinfo->mark) 33 - (*pskb)->nfmark = markinfo->mark; 34 - 35 - return IPT_CONTINUE; 36 - } 37 - 38 - static unsigned int 39 - target_v1(struct sk_buff **pskb, 40 - const struct net_device *in, 41 - const struct net_device *out, 42 - unsigned int hooknum, 43 - const void *targinfo, 44 - void *userinfo) 45 - { 46 - const struct ipt_mark_target_info_v1 *markinfo = targinfo; 47 - int mark = 0; 48 - 49 - switch (markinfo->mode) { 50 - case IPT_MARK_SET: 51 - mark = markinfo->mark; 52 - break; 53 - 54 - case IPT_MARK_AND: 55 - mark = (*pskb)->nfmark & markinfo->mark; 56 - break; 57 - 58 - case IPT_MARK_OR: 59 - mark = (*pskb)->nfmark | markinfo->mark; 60 - break; 61 - } 62 - 63 - if((*pskb)->nfmark != mark) 64 - (*pskb)->nfmark = mark; 65 - 66 - return IPT_CONTINUE; 67 - } 68 - 69 - 70 - static int 71 - checkentry_v0(const char *tablename, 72 - const struct ipt_entry *e, 73 - void *targinfo, 74 - unsigned int targinfosize, 75 - unsigned int hook_mask) 76 - { 77 - struct ipt_mark_target_info *markinfo = targinfo; 78 - 79 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) { 80 - printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 81 - targinfosize, 82 - IPT_ALIGN(sizeof(struct ipt_mark_target_info))); 83 - return 0; 84 - } 85 - 86 - if (strcmp(tablename, "mangle") != 0) { 87 - printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 88 - return 0; 89 - } 90 - 91 - if (markinfo->mark > 0xffffffff) { 92 - printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 93 - return 0; 94 - } 95 - 96 - return 1; 97 - } 98 - 99 - static int 100 - checkentry_v1(const char *tablename, 101 - const struct ipt_entry *e, 102 - void *targinfo, 103 - unsigned int targinfosize, 104 - unsigned int hook_mask) 105 - { 106 - struct ipt_mark_target_info_v1 *markinfo = targinfo; 107 - 108 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){ 109 - printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 110 - targinfosize, 111 - IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))); 112 - return 0; 113 - } 114 - 115 - if (strcmp(tablename, "mangle") != 0) { 116 - printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 117 - return 0; 118 - } 119 - 120 - if (markinfo->mode != IPT_MARK_SET 121 - && markinfo->mode != IPT_MARK_AND 122 - && markinfo->mode != IPT_MARK_OR) { 123 - printk(KERN_WARNING "MARK: unknown mode %u\n", 124 - markinfo->mode); 125 - return 0; 126 - } 127 - 128 - if (markinfo->mark > 0xffffffff) { 129 - printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 130 - return 0; 131 - } 132 - 133 - return 1; 134 - } 135 - 136 - static struct ipt_target ipt_mark_reg_v0 = { 137 - .name = "MARK", 138 - .target = target_v0, 139 - .checkentry = checkentry_v0, 140 - .me = THIS_MODULE, 141 - .revision = 0, 142 - }; 143 - 144 - static struct ipt_target ipt_mark_reg_v1 = { 145 - .name = "MARK", 146 - .target = target_v1, 147 - .checkentry = checkentry_v1, 148 - .me = THIS_MODULE, 149 - .revision = 1, 150 - }; 151 - 152 - static int __init init(void) 153 - { 154 - int err; 155 - 156 - err = ipt_register_target(&ipt_mark_reg_v0); 157 - if (!err) { 158 - err = ipt_register_target(&ipt_mark_reg_v1); 159 - if (err) 160 - ipt_unregister_target(&ipt_mark_reg_v0); 161 - } 162 - return err; 163 - } 164 - 165 - static void __exit fini(void) 166 - { 167 - ipt_unregister_target(&ipt_mark_reg_v0); 168 - ipt_unregister_target(&ipt_mark_reg_v1); 169 - } 170 - 171 - module_init(init); 172 - module_exit(fini);
···
+1 -1
net/ipv4/netfilter/ipt_MASQUERADE.c
··· 40 /* FIXME: Multiple targets. --RR */ 41 static int 42 masquerade_check(const char *tablename, 43 - const struct ipt_entry *e, 44 void *targinfo, 45 unsigned int targinfosize, 46 unsigned int hook_mask)
··· 40 /* FIXME: Multiple targets. --RR */ 41 static int 42 masquerade_check(const char *tablename, 43 + const void *e, 44 void *targinfo, 45 unsigned int targinfosize, 46 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ipt_NETMAP.c
··· 31 32 static int 33 check(const char *tablename, 34 - const struct ipt_entry *e, 35 void *targinfo, 36 unsigned int targinfosize, 37 unsigned int hook_mask)
··· 31 32 static int 33 check(const char *tablename, 34 + const void *e, 35 void *targinfo, 36 unsigned int targinfosize, 37 unsigned int hook_mask)
-70
net/ipv4/netfilter/ipt_NFQUEUE.c
··· 1 - /* iptables module for using new netfilter netlink queue 2 - * 3 - * (C) 2005 by Harald Welte <laforge@netfilter.org> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - * 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #include <linux/netfilter.h> 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> 17 - 18 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 19 - MODULE_DESCRIPTION("iptables NFQUEUE target"); 20 - MODULE_LICENSE("GPL"); 21 - 22 - static unsigned int 23 - target(struct sk_buff **pskb, 24 - const struct net_device *in, 25 - const struct net_device *out, 26 - unsigned int hooknum, 27 - const void *targinfo, 28 - void *userinfo) 29 - { 30 - const struct ipt_NFQ_info *tinfo = targinfo; 31 - 32 - return NF_QUEUE_NR(tinfo->queuenum); 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ipt_entry *e, 38 - void *targinfo, 39 - unsigned int targinfosize, 40 - unsigned int hook_mask) 41 - { 42 - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_NFQ_info))) { 43 - printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", 44 - targinfosize, 45 - IPT_ALIGN(sizeof(struct ipt_NFQ_info))); 46 - return 0; 47 - } 48 - 49 - return 1; 50 - } 51 - 52 - static struct ipt_target ipt_NFQ_reg = { 53 - .name = "NFQUEUE", 54 - .target = target, 55 - .checkentry = checkentry, 56 - .me = THIS_MODULE, 57 - }; 58 - 59 - static int __init init(void) 60 - { 61 - return ipt_register_target(&ipt_NFQ_reg); 62 - } 63 - 64 - static void __exit fini(void) 65 - { 66 - ipt_unregister_target(&ipt_NFQ_reg); 67 - } 68 - 69 - module_init(init); 70 - module_exit(fini);
···
-76
net/ipv4/netfilter/ipt_NOTRACK.c
··· 1 - /* This is a module which is used for setting up fake conntracks 2 - * on packets so that they are not seen by the conntrack/NAT code. 3 - */ 4 - #include <linux/module.h> 5 - #include <linux/skbuff.h> 6 - 7 - #include <linux/netfilter_ipv4/ip_tables.h> 8 - #include <net/netfilter/nf_conntrack_compat.h> 9 - 10 - static unsigned int 11 - target(struct sk_buff **pskb, 12 - const struct net_device *in, 13 - const struct net_device *out, 14 - unsigned int hooknum, 15 - const void *targinfo, 16 - void *userinfo) 17 - { 18 - /* Previously seen (loopback)? Ignore. */ 19 - if ((*pskb)->nfct != NULL) 20 - return IPT_CONTINUE; 21 - 22 - /* Attach fake conntrack entry. 23 - If there is a real ct entry correspondig to this packet, 24 - it'll hang aroun till timing out. We don't deal with it 25 - for performance reasons. JK */ 26 - nf_ct_untrack(*pskb); 27 - (*pskb)->nfctinfo = IP_CT_NEW; 28 - nf_conntrack_get((*pskb)->nfct); 29 - 30 - return IPT_CONTINUE; 31 - } 32 - 33 - static int 34 - checkentry(const char *tablename, 35 - const struct ipt_entry *e, 36 - void *targinfo, 37 - unsigned int targinfosize, 38 - unsigned int hook_mask) 39 - { 40 - if (targinfosize != 0) { 41 - printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", 42 - targinfosize); 43 - return 0; 44 - } 45 - 46 - if (strcmp(tablename, "raw") != 0) { 47 - printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); 48 - return 0; 49 - } 50 - 51 - return 1; 52 - } 53 - 54 - static struct ipt_target ipt_notrack_reg = { 55 - .name = "NOTRACK", 56 - .target = target, 57 - .checkentry = checkentry, 58 - .me = THIS_MODULE 59 - }; 60 - 61 - static int __init init(void) 62 - { 63 - if (ipt_register_target(&ipt_notrack_reg)) 64 - return -EINVAL; 65 - 66 - return 0; 67 - } 68 - 69 - static void __exit fini(void) 70 - { 71 - ipt_unregister_target(&ipt_notrack_reg); 72 - } 73 - 74 - module_init(init); 75 - module_exit(fini); 76 - MODULE_LICENSE("GPL");
···
+1 -1
net/ipv4/netfilter/ipt_REDIRECT.c
··· 33 /* FIXME: Take multiple ranges --RR */ 34 static int 35 redirect_check(const char *tablename, 36 - const struct ipt_entry *e, 37 void *targinfo, 38 unsigned int targinfosize, 39 unsigned int hook_mask)
··· 33 /* FIXME: Take multiple ranges --RR */ 34 static int 35 redirect_check(const char *tablename, 36 + const void *e, 37 void *targinfo, 38 unsigned int targinfosize, 39 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_REJECT.c
··· 282 } 283 284 static int check(const char *tablename, 285 - const struct ipt_entry *e, 286 void *targinfo, 287 unsigned int targinfosize, 288 unsigned int hook_mask) 289 { 290 const struct ipt_reject_info *rejinfo = targinfo; 291 292 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { 293 DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
··· 282 } 283 284 static int check(const char *tablename, 285 + const void *e_void, 286 void *targinfo, 287 unsigned int targinfosize, 288 unsigned int hook_mask) 289 { 290 const struct ipt_reject_info *rejinfo = targinfo; 291 + const struct ipt_entry *e = e_void; 292 293 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { 294 DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize);
+1 -1
net/ipv4/netfilter/ipt_SAME.c
··· 49 50 static int 51 same_check(const char *tablename, 52 - const struct ipt_entry *e, 53 void *targinfo, 54 unsigned int targinfosize, 55 unsigned int hook_mask)
··· 49 50 static int 51 same_check(const char *tablename, 52 + const void *e, 53 void *targinfo, 54 unsigned int targinfosize, 55 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_TCPMSS.c
··· 210 /* Must specify -p tcp --syn/--tcp-flags SYN */ 211 static int 212 ipt_tcpmss_checkentry(const char *tablename, 213 - const struct ipt_entry *e, 214 void *targinfo, 215 unsigned int targinfosize, 216 unsigned int hook_mask) 217 { 218 const struct ipt_tcpmss_info *tcpmssinfo = targinfo; 219 220 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { 221 DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n",
··· 210 /* Must specify -p tcp --syn/--tcp-flags SYN */ 211 static int 212 ipt_tcpmss_checkentry(const char *tablename, 213 + const void *e_void, 214 void *targinfo, 215 unsigned int targinfosize, 216 unsigned int hook_mask) 217 { 218 const struct ipt_tcpmss_info *tcpmssinfo = targinfo; 219 + const struct ipt_entry *e = e_void; 220 221 if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { 222 DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n",
+1 -1
net/ipv4/netfilter/ipt_TOS.c
··· 52 53 static int 54 checkentry(const char *tablename, 55 - const struct ipt_entry *e, 56 void *targinfo, 57 unsigned int targinfosize, 58 unsigned int hook_mask)
··· 52 53 static int 54 checkentry(const char *tablename, 55 + const void *e_void, 56 void *targinfo, 57 unsigned int targinfosize, 58 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ipt_TTL.c
··· 66 } 67 68 static int ipt_ttl_checkentry(const char *tablename, 69 - const struct ipt_entry *e, 70 void *targinfo, 71 unsigned int targinfosize, 72 unsigned int hook_mask)
··· 66 } 67 68 static int ipt_ttl_checkentry(const char *tablename, 69 + const void *e, 70 void *targinfo, 71 unsigned int targinfosize, 72 unsigned int hook_mask)
+1 -1
net/ipv4/netfilter/ipt_ULOG.c
··· 330 } 331 332 static int ipt_ulog_checkentry(const char *tablename, 333 - const struct ipt_entry *e, 334 void *targinfo, 335 unsigned int targinfosize, 336 unsigned int hookmask)
··· 330 } 331 332 static int ipt_ulog_checkentry(const char *tablename, 333 + const void *e, 334 void *targinfo, 335 unsigned int targinfosize, 336 unsigned int hookmask)
+2 -2
net/ipv4/netfilter/ipt_addrtype.c
··· 29 30 static int match(const struct sk_buff *skb, const struct net_device *in, 31 const struct net_device *out, const void *matchinfo, 32 - int offset, int *hotdrop) 33 { 34 const struct ipt_addrtype_info *info = matchinfo; 35 const struct iphdr *iph = skb->nh.iph; ··· 43 return ret; 44 } 45 46 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 47 void *matchinfo, unsigned int matchsize, 48 unsigned int hook_mask) 49 {
··· 29 30 static int match(const struct sk_buff *skb, const struct net_device *in, 31 const struct net_device *out, const void *matchinfo, 32 + int offset, unsigned int protoff, int *hotdrop) 33 { 34 const struct ipt_addrtype_info *info = matchinfo; 35 const struct iphdr *iph = skb->nh.iph; ··· 43 return ret; 44 } 45 46 + static int checkentry(const char *tablename, const void *ip, 47 void *matchinfo, unsigned int matchsize, 48 unsigned int hook_mask) 49 {
+4 -2
net/ipv4/netfilter/ipt_ah.c
··· 41 const struct net_device *out, 42 const void *matchinfo, 43 int offset, 44 int *hotdrop) 45 { 46 struct ip_auth_hdr _ahdr, *ah; ··· 51 if (offset) 52 return 0; 53 54 - ah = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 55 sizeof(_ahdr), &_ahdr); 56 if (ah == NULL) { 57 /* We've been asked to examine this packet, and we ··· 70 /* Called when user tries to insert an entry of this type. */ 71 static int 72 checkentry(const char *tablename, 73 - const struct ipt_ip *ip, 74 void *matchinfo, 75 unsigned int matchinfosize, 76 unsigned int hook_mask) 77 { 78 const struct ipt_ah *ahinfo = matchinfo; 79 80 /* Must specify proto == AH, and no unknown invflags */ 81 if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) {
··· 41 const struct net_device *out, 42 const void *matchinfo, 43 int offset, 44 + unsigned int protoff, 45 int *hotdrop) 46 { 47 struct ip_auth_hdr _ahdr, *ah; ··· 50 if (offset) 51 return 0; 52 53 + ah = skb_header_pointer(skb, protoff, 54 sizeof(_ahdr), &_ahdr); 55 if (ah == NULL) { 56 /* We've been asked to examine this packet, and we ··· 69 /* Called when user tries to insert an entry of this type. */ 70 static int 71 checkentry(const char *tablename, 72 + const void *ip_void, 73 void *matchinfo, 74 unsigned int matchinfosize, 75 unsigned int hook_mask) 76 { 77 const struct ipt_ah *ahinfo = matchinfo; 78 + const struct ipt_ip *ip = ip_void; 79 80 /* Must specify proto == AH, and no unknown invflags */ 81 if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) {
-59
net/ipv4/netfilter/ipt_comment.c
··· 1 - /* 2 - * Implements a dummy match to allow attaching comments to rules 3 - * 4 - * 2003-05-13 Brad Fisher (brad@info-link.net) 5 - */ 6 - 7 - #include <linux/module.h> 8 - #include <linux/skbuff.h> 9 - #include <linux/netfilter_ipv4/ip_tables.h> 10 - #include <linux/netfilter_ipv4/ipt_comment.h> 11 - 12 - MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); 13 - MODULE_DESCRIPTION("iptables comment match module"); 14 - MODULE_LICENSE("GPL"); 15 - 16 - static int 17 - match(const struct sk_buff *skb, 18 - const struct net_device *in, 19 - const struct net_device *out, 20 - const void *matchinfo, 21 - int offset, 22 - int *hotdrop) 23 - { 24 - /* We always match */ 25 - return 1; 26 - } 27 - 28 - static int 29 - checkentry(const char *tablename, 30 - const struct ipt_ip *ip, 31 - void *matchinfo, 32 - unsigned int matchsize, 33 - unsigned int hook_mask) 34 - { 35 - /* Check the size */ 36 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info))) 37 - return 0; 38 - return 1; 39 - } 40 - 41 - static struct ipt_match comment_match = { 42 - .name = "comment", 43 - .match = match, 44 - .checkentry = checkentry, 45 - .me = THIS_MODULE 46 - }; 47 - 48 - static int __init init(void) 49 - { 50 - return ipt_register_match(&comment_match); 51 - } 52 - 53 - static void __exit fini(void) 54 - { 55 - ipt_unregister_match(&comment_match); 56 - } 57 - 58 - module_init(init); 59 - module_exit(fini);
···
-161
net/ipv4/netfilter/ipt_connbytes.c
··· 1 - /* Kernel module to match connection tracking byte counter. 2 - * GPL (C) 2002 Martin Devera (devik@cdi.cz). 3 - * 4 - * 2004-07-20 Harald Welte <laforge@netfilter.org> 5 - * - reimplemented to use per-connection accounting counters 6 - * - add functionality to match number of packets 7 - * - add functionality to match average packet size 8 - * - add support to match directions seperately 9 - * 10 - */ 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <net/netfilter/nf_conntrack_compat.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - #include <linux/netfilter_ipv4/ipt_connbytes.h> 16 - 17 - #include <asm/div64.h> 18 - #include <asm/bitops.h> 19 - 20 - MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 22 - MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); 23 - 24 - /* 64bit divisor, dividend and result. dynamic precision */ 25 - static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) 26 - { 27 - u_int32_t d = divisor; 28 - 29 - if (divisor > 0xffffffffULL) { 30 - unsigned int shift = fls(divisor >> 32); 31 - 32 - d = divisor >> shift; 33 - dividend >>= shift; 34 - } 35 - 36 - do_div(dividend, d); 37 - return dividend; 38 - } 39 - 40 - static int 41 - match(const struct sk_buff *skb, 42 - const struct net_device *in, 43 - const struct net_device *out, 44 - const void *matchinfo, 45 - int offset, 46 - int *hotdrop) 47 - { 48 - const struct ipt_connbytes_info *sinfo = matchinfo; 49 - u_int64_t what = 0; /* initialize to make gcc happy */ 50 - const struct ip_conntrack_counter *counters; 51 - 52 - if (!(counters = nf_ct_get_counters(skb))) 53 - return 0; /* no match */ 54 - 55 - switch (sinfo->what) { 56 - case IPT_CONNBYTES_PKTS: 57 - switch (sinfo->direction) { 58 - case IPT_CONNBYTES_DIR_ORIGINAL: 59 - what = counters[IP_CT_DIR_ORIGINAL].packets; 60 - break; 61 - case IPT_CONNBYTES_DIR_REPLY: 62 - what = counters[IP_CT_DIR_REPLY].packets; 63 - break; 64 - case IPT_CONNBYTES_DIR_BOTH: 65 - what = counters[IP_CT_DIR_ORIGINAL].packets; 66 - what += counters[IP_CT_DIR_REPLY].packets; 67 - break; 68 - } 69 - break; 70 - case IPT_CONNBYTES_BYTES: 71 - switch (sinfo->direction) { 72 - case IPT_CONNBYTES_DIR_ORIGINAL: 73 - what = counters[IP_CT_DIR_ORIGINAL].bytes; 74 - break; 75 - case IPT_CONNBYTES_DIR_REPLY: 76 - what = counters[IP_CT_DIR_REPLY].bytes; 77 - break; 78 - case IPT_CONNBYTES_DIR_BOTH: 79 - what = counters[IP_CT_DIR_ORIGINAL].bytes; 80 - what += counters[IP_CT_DIR_REPLY].bytes; 81 - break; 82 - } 83 - break; 84 - case IPT_CONNBYTES_AVGPKT: 85 - switch (sinfo->direction) { 86 - case IPT_CONNBYTES_DIR_ORIGINAL: 87 - what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, 88 - counters[IP_CT_DIR_ORIGINAL].packets); 89 - break; 90 - case IPT_CONNBYTES_DIR_REPLY: 91 - what = div64_64(counters[IP_CT_DIR_REPLY].bytes, 92 - counters[IP_CT_DIR_REPLY].packets); 93 - break; 94 - case IPT_CONNBYTES_DIR_BOTH: 95 - { 96 - u_int64_t bytes; 97 - u_int64_t pkts; 98 - bytes = counters[IP_CT_DIR_ORIGINAL].bytes + 99 - counters[IP_CT_DIR_REPLY].bytes; 100 - pkts = counters[IP_CT_DIR_ORIGINAL].packets+ 101 - counters[IP_CT_DIR_REPLY].packets; 102 - 103 - /* FIXME_THEORETICAL: what to do if sum 104 - * overflows ? */ 105 - 106 - what = div64_64(bytes, pkts); 107 - } 108 - break; 109 - } 110 - break; 111 - } 112 - 113 - if (sinfo->count.to) 114 - return (what <= sinfo->count.to && what >= sinfo->count.from); 115 - else 116 - return (what >= sinfo->count.from); 117 - } 118 - 119 - static int check(const char *tablename, 120 - const struct ipt_ip *ip, 121 - void *matchinfo, 122 - unsigned int matchsize, 123 - unsigned int hook_mask) 124 - { 125 - const struct ipt_connbytes_info *sinfo = matchinfo; 126 - 127 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) 128 - return 0; 129 - 130 - if (sinfo->what != IPT_CONNBYTES_PKTS && 131 - sinfo->what != IPT_CONNBYTES_BYTES && 132 - sinfo->what != IPT_CONNBYTES_AVGPKT) 133 - return 0; 134 - 135 - if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL && 136 - sinfo->direction != IPT_CONNBYTES_DIR_REPLY && 137 - sinfo->direction != IPT_CONNBYTES_DIR_BOTH) 138 - return 0; 139 - 140 - return 1; 141 - } 142 - 143 - static struct ipt_match state_match = { 144 - .name = "connbytes", 145 - .match = &match, 146 - .checkentry = &check, 147 - .me = THIS_MODULE 148 - }; 149 - 150 - static int __init init(void) 151 - { 152 - return ipt_register_match(&state_match); 153 - } 154 - 155 - static void __exit fini(void) 156 - { 157 - ipt_unregister_match(&state_match); 158 - } 159 - 160 - module_init(init); 161 - module_exit(fini);
···
-88
net/ipv4/netfilter/ipt_connmark.c
··· 1 - /* This kernel module matches connection mark values set by the 2 - * CONNMARK target 3 - * 4 - * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 - * by Henrik Nordstrom <hno@marasystems.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License as published by 9 - * the Free Software Foundation; either version 2 of the License, or 10 - * (at your option) any later version. 11 - * 12 - * This program is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - * GNU General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU General Public License 18 - * along with this program; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 - */ 21 - 22 - #include <linux/module.h> 23 - #include <linux/skbuff.h> 24 - 25 - MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 26 - MODULE_DESCRIPTION("IP tables connmark match module"); 27 - MODULE_LICENSE("GPL"); 28 - 29 - #include <linux/netfilter_ipv4/ip_tables.h> 30 - #include <linux/netfilter_ipv4/ipt_connmark.h> 31 - #include <net/netfilter/nf_conntrack_compat.h> 32 - 33 - static int 34 - match(const struct sk_buff *skb, 35 - const struct net_device *in, 36 - const struct net_device *out, 37 - const void *matchinfo, 38 - int offset, 39 - int *hotdrop) 40 - { 41 - const struct ipt_connmark_info *info = matchinfo; 42 - u_int32_t ctinfo; 43 - const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); 44 - if (!ctmark) 45 - return 0; 46 - 47 - return (((*ctmark) & info->mask) == info->mark) ^ info->invert; 48 - } 49 - 50 - static int 51 - checkentry(const char *tablename, 52 - const struct ipt_ip *ip, 53 - void *matchinfo, 54 - unsigned int matchsize, 55 - unsigned int hook_mask) 56 - { 57 - struct ipt_connmark_info *cm = 58 - (struct ipt_connmark_info *)matchinfo; 59 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info))) 60 - return 0; 61 - 62 - if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 63 - printk(KERN_WARNING "connmark: only support 32bit mark\n"); 64 - return 0; 65 - } 66 - 67 - return 1; 68 - } 69 - 70 - static struct ipt_match connmark_match = { 71 - .name = "connmark", 72 - .match = &match, 73 - .checkentry = &checkentry, 74 - .me = THIS_MODULE 75 - }; 76 - 77 - static int __init init(void) 78 - { 79 - return ipt_register_match(&connmark_match); 80 - } 81 - 82 - static void __exit fini(void) 83 - { 84 - ipt_unregister_match(&connmark_match); 85 - } 86 - 87 - module_init(init); 88 - module_exit(fini);
···
-232
net/ipv4/netfilter/ipt_conntrack.c
··· 1 - /* Kernel module to match connection tracking information. 2 - * Superset of Rusty's minimalistic state match. 3 - * 4 - * (C) 2001 Marc Boucher (marc@mbsi.ca). 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 15 - #include <linux/netfilter_ipv4/ip_conntrack.h> 16 - #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 17 - #else 18 - #include <net/netfilter/nf_conntrack.h> 19 - #endif 20 - 21 - #include <linux/netfilter_ipv4/ip_tables.h> 22 - #include <linux/netfilter_ipv4/ipt_conntrack.h> 23 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 26 - MODULE_DESCRIPTION("iptables connection tracking match module"); 27 - 28 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 29 - 30 - static int 31 - match(const struct sk_buff *skb, 32 - const struct net_device *in, 33 - const struct net_device *out, 34 - const void *matchinfo, 35 - int offset, 36 - int *hotdrop) 37 - { 38 - const struct ipt_conntrack_info *sinfo = matchinfo; 39 - struct ip_conntrack *ct; 40 - enum ip_conntrack_info ctinfo; 41 - unsigned int statebit; 42 - 43 - ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 44 - 45 - #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 46 - 47 - if (ct == &ip_conntrack_untracked) 48 - statebit = IPT_CONNTRACK_STATE_UNTRACKED; 49 - else if (ct) 50 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); 51 - else 52 - statebit = IPT_CONNTRACK_STATE_INVALID; 53 - 54 - if(sinfo->flags & IPT_CONNTRACK_STATE) { 55 - if (ct) { 56 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != 57 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) 58 - statebit |= IPT_CONNTRACK_STATE_SNAT; 59 - 60 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != 61 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) 62 - statebit |= IPT_CONNTRACK_STATE_DNAT; 63 - } 64 - 65 - if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) 66 - return 0; 67 - } 68 - 69 - if(sinfo->flags & IPT_CONNTRACK_PROTO) { 70 - if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) 71 - return 0; 72 - } 73 - 74 - if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { 75 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) 76 - return 0; 77 - } 78 - 79 - if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { 80 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) 81 - return 0; 82 - } 83 - 84 - if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { 85 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) 86 - return 0; 87 - } 88 - 89 - if(sinfo->flags & IPT_CONNTRACK_REPLDST) { 90 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) 91 - return 0; 92 - } 93 - 94 - if(sinfo->flags & IPT_CONNTRACK_STATUS) { 95 - if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) 96 - return 0; 97 - } 98 - 99 - if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { 100 - unsigned long expires; 101 - 102 - if(!ct) 103 - return 0; 104 - 105 - expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 106 - 107 - if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) 108 - return 0; 109 - } 110 - 111 - return 1; 112 - } 113 - 114 - #else /* CONFIG_IP_NF_CONNTRACK */ 115 - static int 116 - match(const struct sk_buff *skb, 117 - const struct net_device *in, 118 - const struct net_device *out, 119 - const void *matchinfo, 120 - int offset, 121 - int *hotdrop) 122 - { 123 - const struct ipt_conntrack_info *sinfo = matchinfo; 124 - struct nf_conn *ct; 125 - enum ip_conntrack_info ctinfo; 126 - unsigned int statebit; 127 - 128 - ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 129 - 130 - #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 131 - 132 - if (ct == &nf_conntrack_untracked) 133 - statebit = IPT_CONNTRACK_STATE_UNTRACKED; 134 - else if (ct) 135 - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); 136 - else 137 - statebit = IPT_CONNTRACK_STATE_INVALID; 138 - 139 - if(sinfo->flags & IPT_CONNTRACK_STATE) { 140 - if (ct) { 141 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != 142 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) 143 - statebit |= IPT_CONNTRACK_STATE_SNAT; 144 - 145 - if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != 146 - ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) 147 - statebit |= IPT_CONNTRACK_STATE_DNAT; 148 - } 149 - 150 - if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) 151 - return 0; 152 - } 153 - 154 - if(sinfo->flags & IPT_CONNTRACK_PROTO) { 155 - if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) 156 - return 0; 157 - } 158 - 159 - if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { 160 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) 161 - return 0; 162 - } 163 - 164 - if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { 165 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) 166 - return 0; 167 - } 168 - 169 - if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { 170 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) 171 - return 0; 172 - } 173 - 174 - if(sinfo->flags & IPT_CONNTRACK_REPLDST) { 175 - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) 176 - return 0; 177 - } 178 - 179 - if(sinfo->flags & IPT_CONNTRACK_STATUS) { 180 - if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) 181 - return 0; 182 - } 183 - 184 - if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { 185 - unsigned long expires; 186 - 187 - if(!ct) 188 - return 0; 189 - 190 - expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 191 - 192 - if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) 193 - return 0; 194 - } 195 - 196 - return 1; 197 - } 198 - 199 - #endif /* CONFIG_NF_IP_CONNTRACK */ 200 - 201 - static int check(const char *tablename, 202 - const struct ipt_ip *ip, 203 - void *matchinfo, 204 - unsigned int matchsize, 205 - unsigned int hook_mask) 206 - { 207 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info))) 208 - return 0; 209 - 210 - return 1; 211 - } 212 - 213 - static struct ipt_match conntrack_match = { 214 - .name = "conntrack", 215 - .match = &match, 216 - .checkentry = &check, 217 - .me = THIS_MODULE, 218 - }; 219 - 220 - static int __init init(void) 221 - { 222 - need_ip_conntrack(); 223 - return ipt_register_match(&conntrack_match); 224 - } 225 - 226 - static void __exit fini(void) 227 - { 228 - ipt_unregister_match(&conntrack_match); 229 - } 230 - 231 - module_init(init); 232 - module_exit(fini);
···
-176
net/ipv4/netfilter/ipt_dccp.c
··· 1 - /* 2 - * iptables module for DCCP protocol header matching 3 - * 4 - * (C) 2005 by Harald Welte <laforge@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/spinlock.h> 14 - #include <net/ip.h> 15 - #include <linux/dccp.h> 16 - 17 - #include <linux/netfilter_ipv4/ip_tables.h> 18 - #include <linux/netfilter_ipv4/ipt_dccp.h> 19 - 20 - #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 21 - || (!!((invflag) & (option)) ^ (cond))) 22 - 23 - static unsigned char *dccp_optbuf; 24 - static DEFINE_SPINLOCK(dccp_buflock); 25 - 26 - static inline int 27 - dccp_find_option(u_int8_t option, 28 - const struct sk_buff *skb, 29 - const struct dccp_hdr *dh, 30 - int *hotdrop) 31 - { 32 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 33 - unsigned char *op; 34 - unsigned int optoff = __dccp_hdr_len(dh); 35 - unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh); 36 - unsigned int i; 37 - 38 - if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) { 39 - *hotdrop = 1; 40 - return 0; 41 - } 42 - 43 - if (!optlen) 44 - return 0; 45 - 46 - spin_lock_bh(&dccp_buflock); 47 - op = skb_header_pointer(skb, 48 - skb->nh.iph->ihl*4 + optoff, 49 - optlen, dccp_optbuf); 50 - if (op == NULL) { 51 - /* If we don't have the whole header, drop packet. */ 52 - spin_unlock_bh(&dccp_buflock); 53 - *hotdrop = 1; 54 - return 0; 55 - } 56 - 57 - for (i = 0; i < optlen; ) { 58 - if (op[i] == option) { 59 - spin_unlock_bh(&dccp_buflock); 60 - return 1; 61 - } 62 - 63 - if (op[i] < 2) 64 - i++; 65 - else 66 - i += op[i+1]?:1; 67 - } 68 - 69 - spin_unlock_bh(&dccp_buflock); 70 - return 0; 71 - } 72 - 73 - 74 - static inline int 75 - match_types(const struct dccp_hdr *dh, u_int16_t typemask) 76 - { 77 - return (typemask & (1 << dh->dccph_type)); 78 - } 79 - 80 - static inline int 81 - match_option(u_int8_t option, const struct sk_buff *skb, 82 - const struct dccp_hdr *dh, int *hotdrop) 83 - { 84 - return dccp_find_option(option, skb, dh, hotdrop); 85 - } 86 - 87 - static int 88 - match(const struct sk_buff *skb, 89 - const struct net_device *in, 90 - const struct net_device *out, 91 - const void *matchinfo, 92 - int offset, 93 - int *hotdrop) 94 - { 95 - const struct ipt_dccp_info *info = 96 - (const struct ipt_dccp_info *)matchinfo; 97 - struct dccp_hdr _dh, *dh; 98 - 99 - if (offset) 100 - return 0; 101 - 102 - dh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_dh), &_dh); 103 - if (dh == NULL) { 104 - *hotdrop = 1; 105 - return 0; 106 - } 107 - 108 - return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) 109 - && (ntohs(dh->dccph_sport) <= info->spts[1])), 110 - IPT_DCCP_SRC_PORTS, info->flags, info->invflags) 111 - && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) 112 - && (ntohs(dh->dccph_dport) <= info->dpts[1])), 113 - IPT_DCCP_DEST_PORTS, info->flags, info->invflags) 114 - && DCCHECK(match_types(dh, info->typemask), 115 - IPT_DCCP_TYPE, info->flags, info->invflags) 116 - && DCCHECK(match_option(info->option, skb, dh, hotdrop), 117 - IPT_DCCP_OPTION, info->flags, info->invflags); 118 - } 119 - 120 - static int 121 - checkentry(const char *tablename, 122 - const struct ipt_ip *ip, 123 - void *matchinfo, 124 - unsigned int matchsize, 125 - unsigned int hook_mask) 126 - { 127 - const struct ipt_dccp_info *info; 128 - 129 - info = (const struct ipt_dccp_info *)matchinfo; 130 - 131 - return ip->proto == IPPROTO_DCCP 132 - && !(ip->invflags & IPT_INV_PROTO) 133 - && matchsize == IPT_ALIGN(sizeof(struct ipt_dccp_info)) 134 - && !(info->flags & ~IPT_DCCP_VALID_FLAGS) 135 - && !(info->invflags & ~IPT_DCCP_VALID_FLAGS) 136 - && !(info->invflags & ~info->flags); 137 - } 138 - 139 - static struct ipt_match dccp_match = 140 - { 141 - .name = "dccp", 142 - .match = &match, 143 - .checkentry = &checkentry, 144 - .me = THIS_MODULE, 145 - }; 146 - 147 - static int __init init(void) 148 - { 149 - int ret; 150 - 151 - /* doff is 8 bits, so the maximum option size is (4*256). Don't put 152 - * this in BSS since DaveM is worried about locked TLB's for kernel 153 - * BSS. */ 154 - dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); 155 - if (!dccp_optbuf) 156 - return -ENOMEM; 157 - ret = ipt_register_match(&dccp_match); 158 - if (ret) 159 - kfree(dccp_optbuf); 160 - 161 - return ret; 162 - } 163 - 164 - static void __exit fini(void) 165 - { 166 - ipt_unregister_match(&dccp_match); 167 - kfree(dccp_optbuf); 168 - } 169 - 170 - module_init(init); 171 - module_exit(fini); 172 - 173 - MODULE_LICENSE("GPL"); 174 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 175 - MODULE_DESCRIPTION("Match for DCCP protocol packets"); 176 -
···
+2 -2
net/ipv4/netfilter/ipt_dscp.c
··· 21 22 static int match(const struct sk_buff *skb, const struct net_device *in, 23 const struct net_device *out, const void *matchinfo, 24 - int offset, int *hotdrop) 25 { 26 const struct ipt_dscp_info *info = matchinfo; 27 const struct iphdr *iph = skb->nh.iph; ··· 31 return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; 32 } 33 34 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 35 void *matchinfo, unsigned int matchsize, 36 unsigned int hook_mask) 37 {
··· 21 22 static int match(const struct sk_buff *skb, const struct net_device *in, 23 const struct net_device *out, const void *matchinfo, 24 + int offset, unsigned int protoff, int *hotdrop) 25 { 26 const struct ipt_dscp_info *info = matchinfo; 27 const struct iphdr *iph = skb->nh.iph; ··· 31 return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; 32 } 33 34 + static int checkentry(const char *tablename, const void *ip, 35 void *matchinfo, unsigned int matchsize, 36 unsigned int hook_mask) 37 {
+3 -2
net/ipv4/netfilter/ipt_ecn.c
··· 67 68 static int match(const struct sk_buff *skb, const struct net_device *in, 69 const struct net_device *out, const void *matchinfo, 70 - int offset, int *hotdrop) 71 { 72 const struct ipt_ecn_info *info = matchinfo; 73 ··· 85 return 1; 86 } 87 88 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 89 void *matchinfo, unsigned int matchsize, 90 unsigned int hook_mask) 91 { 92 const struct ipt_ecn_info *info = matchinfo; 93 94 if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) 95 return 0;
··· 67 68 static int match(const struct sk_buff *skb, const struct net_device *in, 69 const struct net_device *out, const void *matchinfo, 70 + int offset, unsigned int protoff, int *hotdrop) 71 { 72 const struct ipt_ecn_info *info = matchinfo; 73 ··· 85 return 1; 86 } 87 88 + static int checkentry(const char *tablename, const void *ip_void, 89 void *matchinfo, unsigned int matchsize, 90 unsigned int hook_mask) 91 { 92 const struct ipt_ecn_info *info = matchinfo; 93 + const struct ipt_ip *ip = ip_void; 94 95 if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) 96 return 0;
+4 -2
net/ipv4/netfilter/ipt_esp.c
··· 42 const struct net_device *out, 43 const void *matchinfo, 44 int offset, 45 int *hotdrop) 46 { 47 struct ip_esp_hdr _esp, *eh; ··· 52 if (offset) 53 return 0; 54 55 - eh = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 56 sizeof(_esp), &_esp); 57 if (eh == NULL) { 58 /* We've been asked to examine this packet, and we ··· 71 /* Called when user tries to insert an entry of this type. */ 72 static int 73 checkentry(const char *tablename, 74 - const struct ipt_ip *ip, 75 void *matchinfo, 76 unsigned int matchinfosize, 77 unsigned int hook_mask) 78 { 79 const struct ipt_esp *espinfo = matchinfo; 80 81 /* Must specify proto == ESP, and no unknown invflags */ 82 if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) {
··· 42 const struct net_device *out, 43 const void *matchinfo, 44 int offset, 45 + unsigned int protoff, 46 int *hotdrop) 47 { 48 struct ip_esp_hdr _esp, *eh; ··· 51 if (offset) 52 return 0; 53 54 + eh = skb_header_pointer(skb, protoff, 55 sizeof(_esp), &_esp); 56 if (eh == NULL) { 57 /* We've been asked to examine this packet, and we ··· 70 /* Called when user tries to insert an entry of this type. */ 71 static int 72 checkentry(const char *tablename, 73 + const void *ip_void, 74 void *matchinfo, 75 unsigned int matchinfosize, 76 unsigned int hook_mask) 77 { 78 const struct ipt_esp *espinfo = matchinfo; 79 + const struct ipt_ip *ip = ip_void; 80 81 /* Must specify proto == ESP, and no unknown invflags */ 82 if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) {
+2 -1
net/ipv4/netfilter/ipt_hashlimit.c
··· 429 const struct net_device *out, 430 const void *matchinfo, 431 int offset, 432 int *hotdrop) 433 { 434 struct ipt_hashlimit_info *r = ··· 505 506 static int 507 hashlimit_checkentry(const char *tablename, 508 - const struct ipt_ip *ip, 509 void *matchinfo, 510 unsigned int matchsize, 511 unsigned int hook_mask)
··· 429 const struct net_device *out, 430 const void *matchinfo, 431 int offset, 432 + unsigned int protoff, 433 int *hotdrop) 434 { 435 struct ipt_hashlimit_info *r = ··· 504 505 static int 506 hashlimit_checkentry(const char *tablename, 507 + const void *inf, 508 void *matchinfo, 509 unsigned int matchsize, 510 unsigned int hook_mask)
-168
net/ipv4/netfilter/ipt_helper.c
··· 1 - /* iptables module to match on related connections */ 2 - /* 3 - * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - * 9 - * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: 10 - * - Port to newnat infrastructure 11 - */ 12 - 13 - #include <linux/module.h> 14 - #include <linux/skbuff.h> 15 - #include <linux/netfilter.h> 16 - #include <linux/interrupt.h> 17 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 18 - #include <linux/netfilter_ipv4/ip_conntrack.h> 19 - #include <linux/netfilter_ipv4/ip_conntrack_core.h> 20 - #include <linux/netfilter_ipv4/ip_conntrack_helper.h> 21 - #else 22 - #include <net/netfilter/nf_conntrack.h> 23 - #include <net/netfilter/nf_conntrack_core.h> 24 - #include <net/netfilter/nf_conntrack_helper.h> 25 - #endif 26 - #include <linux/netfilter_ipv4/ip_tables.h> 27 - #include <linux/netfilter_ipv4/ipt_helper.h> 28 - 29 - MODULE_LICENSE("GPL"); 30 - MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); 31 - MODULE_DESCRIPTION("iptables helper match module"); 32 - 33 - #if 0 34 - #define DEBUGP printk 35 - #else 36 - #define DEBUGP(format, args...) 37 - #endif 38 - 39 - #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 40 - static int 41 - match(const struct sk_buff *skb, 42 - const struct net_device *in, 43 - const struct net_device *out, 44 - const void *matchinfo, 45 - int offset, 46 - int *hotdrop) 47 - { 48 - const struct ipt_helper_info *info = matchinfo; 49 - struct ip_conntrack *ct; 50 - enum ip_conntrack_info ctinfo; 51 - int ret = info->invert; 52 - 53 - ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 54 - if (!ct) { 55 - DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); 56 - return ret; 57 - } 58 - 59 - if (!ct->master) { 60 - DEBUGP("ipt_helper: conntrack %p has no master\n", ct); 61 - return ret; 62 - } 63 - 64 - read_lock_bh(&ip_conntrack_lock); 65 - if (!ct->master->helper) { 66 - DEBUGP("ipt_helper: master ct %p has no helper\n", 67 - exp->expectant); 68 - goto out_unlock; 69 - } 70 - 71 - DEBUGP("master's name = %s , info->name = %s\n", 72 - ct->master->helper->name, info->name); 73 - 74 - if (info->name[0] == '\0') 75 - ret ^= 1; 76 - else 77 - ret ^= !strncmp(ct->master->helper->name, info->name, 78 - strlen(ct->master->helper->name)); 79 - out_unlock: 80 - read_unlock_bh(&ip_conntrack_lock); 81 - return ret; 82 - } 83 - 84 - #else /* CONFIG_IP_NF_CONNTRACK */ 85 - 86 - static int 87 - match(const struct sk_buff *skb, 88 - const struct net_device *in, 89 - const struct net_device *out, 90 - const void *matchinfo, 91 - int offset, 92 - int *hotdrop) 93 - { 94 - const struct ipt_helper_info *info = matchinfo; 95 - struct nf_conn *ct; 96 - enum ip_conntrack_info ctinfo; 97 - int ret = info->invert; 98 - 99 - ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 100 - if (!ct) { 101 - DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); 102 - return ret; 103 - } 104 - 105 - if (!ct->master) { 106 - DEBUGP("ipt_helper: conntrack %p has no master\n", ct); 107 - return ret; 108 - } 109 - 110 - read_lock_bh(&nf_conntrack_lock); 111 - if (!ct->master->helper) { 112 - DEBUGP("ipt_helper: master ct %p has no helper\n", 113 - exp->expectant); 114 - goto out_unlock; 115 - } 116 - 117 - DEBUGP("master's name = %s , info->name = %s\n", 118 - ct->master->helper->name, info->name); 119 - 120 - if (info->name[0] == '\0') 121 - ret ^= 1; 122 - else 123 - ret ^= !strncmp(ct->master->helper->name, info->name, 124 - strlen(ct->master->helper->name)); 125 - out_unlock: 126 - read_unlock_bh(&nf_conntrack_lock); 127 - return ret; 128 - } 129 - #endif 130 - 131 - static int check(const char *tablename, 132 - const struct ipt_ip *ip, 133 - void *matchinfo, 134 - unsigned int matchsize, 135 - unsigned int hook_mask) 136 - { 137 - struct ipt_helper_info *info = matchinfo; 138 - 139 - info->name[29] = '\0'; 140 - 141 - /* verify size */ 142 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) 143 - return 0; 144 - 145 - return 1; 146 - } 147 - 148 - static struct ipt_match helper_match = { 149 - .name = "helper", 150 - .match = &match, 151 - .checkentry = &check, 152 - .me = THIS_MODULE, 153 - }; 154 - 155 - static int __init init(void) 156 - { 157 - need_ip_conntrack(); 158 - return ipt_register_match(&helper_match); 159 - } 160 - 161 - static void __exit fini(void) 162 - { 163 - ipt_unregister_match(&helper_match); 164 - } 165 - 166 - module_init(init); 167 - module_exit(fini); 168 -
···
+2 -2
net/ipv4/netfilter/ipt_iprange.c
··· 28 const struct net_device *in, 29 const struct net_device *out, 30 const void *matchinfo, 31 - int offset, int *hotdrop) 32 { 33 const struct ipt_iprange_info *info = matchinfo; 34 const struct iphdr *iph = skb->nh.iph; ··· 63 } 64 65 static int check(const char *tablename, 66 - const struct ipt_ip *ip, 67 void *matchinfo, 68 unsigned int matchsize, 69 unsigned int hook_mask)
··· 28 const struct net_device *in, 29 const struct net_device *out, 30 const void *matchinfo, 31 + int offset, unsigned int protoff, int *hotdrop) 32 { 33 const struct ipt_iprange_info *info = matchinfo; 34 const struct iphdr *iph = skb->nh.iph; ··· 63 } 64 65 static int check(const char *tablename, 66 + const void *inf, 67 void *matchinfo, 68 unsigned int matchsize, 69 unsigned int hook_mask)
-64
net/ipv4/netfilter/ipt_length.c
··· 1 - /* Kernel module to match packet length. */ 2 - /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 as 6 - * published by the Free Software Foundation. 7 - */ 8 - 9 - #include <linux/module.h> 10 - #include <linux/skbuff.h> 11 - 12 - #include <linux/netfilter_ipv4/ipt_length.h> 13 - #include <linux/netfilter_ipv4/ip_tables.h> 14 - 15 - MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 16 - MODULE_DESCRIPTION("IP tables packet length matching module"); 17 - MODULE_LICENSE("GPL"); 18 - 19 - static int 20 - match(const struct sk_buff *skb, 21 - const struct net_device *in, 22 - const struct net_device *out, 23 - const void *matchinfo, 24 - int offset, 25 - int *hotdrop) 26 - { 27 - const struct ipt_length_info *info = matchinfo; 28 - u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); 29 - 30 - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 31 - } 32 - 33 - static int 34 - checkentry(const char *tablename, 35 - const struct ipt_ip *ip, 36 - void *matchinfo, 37 - unsigned int matchsize, 38 - unsigned int hook_mask) 39 - { 40 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info))) 41 - return 0; 42 - 43 - return 1; 44 - } 45 - 46 - static struct ipt_match length_match = { 47 - .name = "length", 48 - .match = &match, 49 - .checkentry = &checkentry, 50 - .me = THIS_MODULE, 51 - }; 52 - 53 - static int __init init(void) 54 - { 55 - return ipt_register_match(&length_match); 56 - } 57 - 58 - static void __exit fini(void) 59 - { 60 - ipt_unregister_match(&length_match); 61 - } 62 - 63 - module_init(init); 64 - module_exit(fini);
···
-157
net/ipv4/netfilter/ipt_limit.c
··· 1 - /* Kernel module to control the rate 2 - * 3 - * 2 September 1999: Changed from the target RATE to the match 4 - * `limit', removed logging. Did I mention that 5 - * Alexey is a fucking genius? 6 - * Rusty Russell (rusty@rustcorp.com.au). */ 7 - 8 - /* (C) 1999 J�r�me de Vivie <devivie@info.enserb.u-bordeaux.fr> 9 - * (C) 1999 Herv� Eychenne <eychenne@info.enserb.u-bordeaux.fr> 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License version 2 as 13 - * published by the Free Software Foundation. 14 - */ 15 - 16 - #include <linux/module.h> 17 - #include <linux/skbuff.h> 18 - #include <linux/spinlock.h> 19 - #include <linux/interrupt.h> 20 - 21 - #include <linux/netfilter_ipv4/ip_tables.h> 22 - #include <linux/netfilter_ipv4/ipt_limit.h> 23 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); 26 - MODULE_DESCRIPTION("iptables rate limit match"); 27 - 28 - /* The algorithm used is the Simple Token Bucket Filter (TBF) 29 - * see net/sched/sch_tbf.c in the linux source tree 30 - */ 31 - 32 - static DEFINE_SPINLOCK(limit_lock); 33 - 34 - /* Rusty: This is my (non-mathematically-inclined) understanding of 35 - this algorithm. The `average rate' in jiffies becomes your initial 36 - amount of credit `credit' and the most credit you can ever have 37 - `credit_cap'. The `peak rate' becomes the cost of passing the 38 - test, `cost'. 39 - 40 - `prev' tracks the last packet hit: you gain one credit per jiffy. 41 - If you get credit balance more than this, the extra credit is 42 - discarded. Every time the match passes, you lose `cost' credits; 43 - if you don't have that many, the test fails. 44 - 45 - See Alexey's formal explanation in net/sched/sch_tbf.c. 46 - 47 - To get the maxmum range, we multiply by this factor (ie. you get N 48 - credits per jiffy). We want to allow a rate as low as 1 per day 49 - (slowest userspace tool allows), which means 50 - CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32. ie. */ 51 - #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24)) 52 - 53 - /* Repeated shift and or gives us all 1s, final shift and add 1 gives 54 - * us the power of 2 below the theoretical max, so GCC simply does a 55 - * shift. */ 56 - #define _POW2_BELOW2(x) ((x)|((x)>>1)) 57 - #define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2)) 58 - #define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4)) 59 - #define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8)) 60 - #define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16)) 61 - #define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1) 62 - 63 - #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 64 - 65 - static int 66 - ipt_limit_match(const struct sk_buff *skb, 67 - const struct net_device *in, 68 - const struct net_device *out, 69 - const void *matchinfo, 70 - int offset, 71 - int *hotdrop) 72 - { 73 - struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master; 74 - unsigned long now = jiffies; 75 - 76 - spin_lock_bh(&limit_lock); 77 - r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; 78 - if (r->credit > r->credit_cap) 79 - r->credit = r->credit_cap; 80 - 81 - if (r->credit >= r->cost) { 82 - /* We're not limited. */ 83 - r->credit -= r->cost; 84 - spin_unlock_bh(&limit_lock); 85 - return 1; 86 - } 87 - 88 - spin_unlock_bh(&limit_lock); 89 - return 0; 90 - } 91 - 92 - /* Precision saver. */ 93 - static u_int32_t 94 - user2credits(u_int32_t user) 95 - { 96 - /* If multiplying would overflow... */ 97 - if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 98 - /* Divide first. */ 99 - return (user / IPT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 100 - 101 - return (user * HZ * CREDITS_PER_JIFFY) / IPT_LIMIT_SCALE; 102 - } 103 - 104 - static int 105 - ipt_limit_checkentry(const char *tablename, 106 - const struct ipt_ip *ip, 107 - void *matchinfo, 108 - unsigned int matchsize, 109 - unsigned int hook_mask) 110 - { 111 - struct ipt_rateinfo *r = matchinfo; 112 - 113 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo))) 114 - return 0; 115 - 116 - /* Check for overflow. */ 117 - if (r->burst == 0 118 - || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 119 - printk("Overflow in ipt_limit, try lower: %u/%u\n", 120 - r->avg, r->burst); 121 - return 0; 122 - } 123 - 124 - /* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies * 125 - 128. */ 126 - r->prev = jiffies; 127 - r->credit = user2credits(r->avg * r->burst); /* Credits full. */ 128 - r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 129 - r->cost = user2credits(r->avg); 130 - 131 - /* For SMP, we only want to use one set of counters. */ 132 - r->master = r; 133 - 134 - return 1; 135 - } 136 - 137 - static struct ipt_match ipt_limit_reg = { 138 - .name = "limit", 139 - .match = ipt_limit_match, 140 - .checkentry = ipt_limit_checkentry, 141 - .me = THIS_MODULE, 142 - }; 143 - 144 - static int __init init(void) 145 - { 146 - if (ipt_register_match(&ipt_limit_reg)) 147 - return -EINVAL; 148 - return 0; 149 - } 150 - 151 - static void __exit fini(void) 152 - { 153 - ipt_unregister_match(&ipt_limit_reg); 154 - } 155 - 156 - module_init(init); 157 - module_exit(fini);
···
-80
net/ipv4/netfilter/ipt_mac.c
··· 1 - /* Kernel module to match MAC address parameters. */ 2 - 3 - /* (C) 1999-2001 Paul `Rusty' Russell 4 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/if_ether.h> 14 - #include <linux/etherdevice.h> 15 - 16 - #include <linux/netfilter_ipv4/ipt_mac.h> 17 - #include <linux/netfilter_ipv4/ip_tables.h> 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 21 - MODULE_DESCRIPTION("iptables mac matching module"); 22 - 23 - static int 24 - match(const struct sk_buff *skb, 25 - const struct net_device *in, 26 - const struct net_device *out, 27 - const void *matchinfo, 28 - int offset, 29 - int *hotdrop) 30 - { 31 - const struct ipt_mac_info *info = matchinfo; 32 - 33 - /* Is mac pointer valid? */ 34 - return (skb->mac.raw >= skb->head 35 - && (skb->mac.raw + ETH_HLEN) <= skb->data 36 - /* If so, compare... */ 37 - && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 38 - ^ info->invert)); 39 - } 40 - 41 - static int 42 - ipt_mac_checkentry(const char *tablename, 43 - const struct ipt_ip *ip, 44 - void *matchinfo, 45 - unsigned int matchsize, 46 - unsigned int hook_mask) 47 - { 48 - /* FORWARD isn't always valid, but it's nice to be able to do --RR */ 49 - if (hook_mask 50 - & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 51 - | (1 << NF_IP_FORWARD))) { 52 - printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 53 - return 0; 54 - } 55 - 56 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info))) 57 - return 0; 58 - 59 - return 1; 60 - } 61 - 62 - static struct ipt_match mac_match = { 63 - .name = "mac", 64 - .match = &match, 65 - .checkentry = &ipt_mac_checkentry, 66 - .me = THIS_MODULE, 67 - }; 68 - 69 - static int __init init(void) 70 - { 71 - return ipt_register_match(&mac_match); 72 - } 73 - 74 - static void __exit fini(void) 75 - { 76 - ipt_unregister_match(&mac_match); 77 - } 78 - 79 - module_init(init); 80 - module_exit(fini);
···
-71
net/ipv4/netfilter/ipt_mark.c
··· 1 - /* Kernel module to match NFMARK values. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - 13 - #include <linux/netfilter_ipv4/ipt_mark.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - 16 - MODULE_LICENSE("GPL"); 17 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 18 - MODULE_DESCRIPTION("iptables mark matching module"); 19 - 20 - static int 21 - match(const struct sk_buff *skb, 22 - const struct net_device *in, 23 - const struct net_device *out, 24 - const void *matchinfo, 25 - int offset, 26 - int *hotdrop) 27 - { 28 - const struct ipt_mark_info *info = matchinfo; 29 - 30 - return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 31 - } 32 - 33 - static int 34 - checkentry(const char *tablename, 35 - const struct ipt_ip *ip, 36 - void *matchinfo, 37 - unsigned int matchsize, 38 - unsigned int hook_mask) 39 - { 40 - struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo; 41 - 42 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info))) 43 - return 0; 44 - 45 - if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 46 - printk(KERN_WARNING "mark: only supports 32bit mark\n"); 47 - return 0; 48 - } 49 - 50 - return 1; 51 - } 52 - 53 - static struct ipt_match mark_match = { 54 - .name = "mark", 55 - .match = &match, 56 - .checkentry = &checkentry, 57 - .me = THIS_MODULE, 58 - }; 59 - 60 - static int __init init(void) 61 - { 62 - return ipt_register_match(&mark_match); 63 - } 64 - 65 - static void __exit fini(void) 66 - { 67 - ipt_unregister_match(&mark_match); 68 - } 69 - 70 - module_init(init); 71 - module_exit(fini);
···
+6 -4
net/ipv4/netfilter/ipt_multiport.c
··· 97 const struct net_device *out, 98 const void *matchinfo, 99 int offset, 100 int *hotdrop) 101 { 102 u16 _ports[2], *pptr; ··· 106 if (offset) 107 return 0; 108 109 - pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 110 sizeof(_ports), _ports); 111 if (pptr == NULL) { 112 /* We've been asked to examine this packet, and we ··· 129 const struct net_device *out, 130 const void *matchinfo, 131 int offset, 132 int *hotdrop) 133 { 134 u16 _ports[2], *pptr; ··· 138 if (offset) 139 return 0; 140 141 - pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 142 sizeof(_ports), _ports); 143 if (pptr == NULL) { 144 /* We've been asked to examine this packet, and we ··· 156 /* Called when user tries to insert an entry of this type. */ 157 static int 158 checkentry(const char *tablename, 159 - const struct ipt_ip *ip, 160 void *matchinfo, 161 unsigned int matchsize, 162 unsigned int hook_mask) ··· 166 167 static int 168 checkentry_v1(const char *tablename, 169 - const struct ipt_ip *ip, 170 void *matchinfo, 171 unsigned int matchsize, 172 unsigned int hook_mask)
··· 97 const struct net_device *out, 98 const void *matchinfo, 99 int offset, 100 + unsigned int protoff, 101 int *hotdrop) 102 { 103 u16 _ports[2], *pptr; ··· 105 if (offset) 106 return 0; 107 108 + pptr = skb_header_pointer(skb, protoff, 109 sizeof(_ports), _ports); 110 if (pptr == NULL) { 111 /* We've been asked to examine this packet, and we ··· 128 const struct net_device *out, 129 const void *matchinfo, 130 int offset, 131 + unsigned int protoff, 132 int *hotdrop) 133 { 134 u16 _ports[2], *pptr; ··· 136 if (offset) 137 return 0; 138 139 + pptr = skb_header_pointer(skb, protoff, 140 sizeof(_ports), _ports); 141 if (pptr == NULL) { 142 /* We've been asked to examine this packet, and we ··· 154 /* Called when user tries to insert an entry of this type. */ 155 static int 156 checkentry(const char *tablename, 157 + const void *ip, 158 void *matchinfo, 159 unsigned int matchsize, 160 unsigned int hook_mask) ··· 164 165 static int 166 checkentry_v1(const char *tablename, 167 + const void *ip, 168 void *matchinfo, 169 unsigned int matchsize, 170 unsigned int hook_mask)
+2 -1
net/ipv4/netfilter/ipt_owner.c
··· 27 const struct net_device *out, 28 const void *matchinfo, 29 int offset, 30 int *hotdrop) 31 { 32 const struct ipt_owner_info *info = matchinfo; ··· 52 53 static int 54 checkentry(const char *tablename, 55 - const struct ipt_ip *ip, 56 void *matchinfo, 57 unsigned int matchsize, 58 unsigned int hook_mask)
··· 27 const struct net_device *out, 28 const void *matchinfo, 29 int offset, 30 + unsigned int protoff, 31 int *hotdrop) 32 { 33 const struct ipt_owner_info *info = matchinfo; ··· 51 52 static int 53 checkentry(const char *tablename, 54 + const void *ip, 55 void *matchinfo, 56 unsigned int matchsize, 57 unsigned int hook_mask)
-135
net/ipv4/netfilter/ipt_physdev.c
··· 1 - /* Kernel module to match the bridge port in and 2 - * out device for IP packets coming into contact with a bridge. */ 3 - 4 - /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/netdevice.h> 13 - #include <linux/skbuff.h> 14 - #include <linux/netfilter_ipv4/ipt_physdev.h> 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - #include <linux/netfilter_bridge.h> 17 - #define MATCH 1 18 - #define NOMATCH 0 19 - 20 - MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 22 - MODULE_DESCRIPTION("iptables bridge physical device match module"); 23 - 24 - static int 25 - match(const struct sk_buff *skb, 26 - const struct net_device *in, 27 - const struct net_device *out, 28 - const void *matchinfo, 29 - int offset, 30 - int *hotdrop) 31 - { 32 - int i; 33 - static const char nulldevname[IFNAMSIZ]; 34 - const struct ipt_physdev_info *info = matchinfo; 35 - unsigned int ret; 36 - const char *indev, *outdev; 37 - struct nf_bridge_info *nf_bridge; 38 - 39 - /* Not a bridged IP packet or no info available yet: 40 - * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 41 - * the destination device will be a bridge. */ 42 - if (!(nf_bridge = skb->nf_bridge)) { 43 - /* Return MATCH if the invert flags of the used options are on */ 44 - if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && 45 - !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) 46 - return NOMATCH; 47 - if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && 48 - !(info->invert & IPT_PHYSDEV_OP_ISIN)) 49 - return NOMATCH; 50 - if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && 51 - !(info->invert & IPT_PHYSDEV_OP_ISOUT)) 52 - return NOMATCH; 53 - if ((info->bitmask & IPT_PHYSDEV_OP_IN) && 54 - !(info->invert & IPT_PHYSDEV_OP_IN)) 55 - return NOMATCH; 56 - if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && 57 - !(info->invert & IPT_PHYSDEV_OP_OUT)) 58 - return NOMATCH; 59 - return MATCH; 60 - } 61 - 62 - /* This only makes sense in the FORWARD and POSTROUTING chains */ 63 - if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && 64 - (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 65 - !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) 66 - return NOMATCH; 67 - 68 - if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && 69 - (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || 70 - (info->bitmask & IPT_PHYSDEV_OP_ISOUT && 71 - (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) 72 - return NOMATCH; 73 - 74 - if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) 75 - goto match_outdev; 76 - indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 77 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 78 - ret |= (((const unsigned int *)indev)[i] 79 - ^ ((const unsigned int *)info->physindev)[i]) 80 - & ((const unsigned int *)info->in_mask)[i]; 81 - } 82 - 83 - if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) 84 - return NOMATCH; 85 - 86 - match_outdev: 87 - if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) 88 - return MATCH; 89 - outdev = nf_bridge->physoutdev ? 90 - nf_bridge->physoutdev->name : nulldevname; 91 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 92 - ret |= (((const unsigned int *)outdev)[i] 93 - ^ ((const unsigned int *)info->physoutdev)[i]) 94 - & ((const unsigned int *)info->out_mask)[i]; 95 - } 96 - 97 - return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); 98 - } 99 - 100 - static int 101 - checkentry(const char *tablename, 102 - const struct ipt_ip *ip, 103 - void *matchinfo, 104 - unsigned int matchsize, 105 - unsigned int hook_mask) 106 - { 107 - const struct ipt_physdev_info *info = matchinfo; 108 - 109 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) 110 - return 0; 111 - if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || 112 - info->bitmask & ~IPT_PHYSDEV_OP_MASK) 113 - return 0; 114 - return 1; 115 - } 116 - 117 - static struct ipt_match physdev_match = { 118 - .name = "physdev", 119 - .match = &match, 120 - .checkentry = &checkentry, 121 - .me = THIS_MODULE, 122 - }; 123 - 124 - static int __init init(void) 125 - { 126 - return ipt_register_match(&physdev_match); 127 - } 128 - 129 - static void __exit fini(void) 130 - { 131 - ipt_unregister_match(&physdev_match); 132 - } 133 - 134 - module_init(init); 135 - module_exit(fini);
···
-70
net/ipv4/netfilter/ipt_pkttype.c
··· 1 - /* (C) 1999-2001 Michal Ludvig <michal@logix.cz> 2 - * 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. 6 - */ 7 - 8 - #include <linux/module.h> 9 - #include <linux/skbuff.h> 10 - #include <linux/if_ether.h> 11 - #include <linux/if_packet.h> 12 - 13 - #include <linux/netfilter_ipv4/ipt_pkttype.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - 16 - MODULE_LICENSE("GPL"); 17 - MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); 18 - MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); 19 - 20 - static int match(const struct sk_buff *skb, 21 - const struct net_device *in, 22 - const struct net_device *out, 23 - const void *matchinfo, 24 - int offset, 25 - int *hotdrop) 26 - { 27 - const struct ipt_pkttype_info *info = matchinfo; 28 - 29 - return (skb->pkt_type == info->pkttype) ^ info->invert; 30 - } 31 - 32 - static int checkentry(const char *tablename, 33 - const struct ipt_ip *ip, 34 - void *matchinfo, 35 - unsigned int matchsize, 36 - unsigned int hook_mask) 37 - { 38 - /* 39 - if (hook_mask 40 - & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 41 - | (1 << NF_IP_FORWARD))) { 42 - printk("ipt_pkttype: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 43 - return 0; 44 - } 45 - */ 46 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_pkttype_info))) 47 - return 0; 48 - 49 - return 1; 50 - } 51 - 52 - static struct ipt_match pkttype_match = { 53 - .name = "pkttype", 54 - .match = &match, 55 - .checkentry = &checkentry, 56 - .me = THIS_MODULE, 57 - }; 58 - 59 - static int __init init(void) 60 - { 61 - return ipt_register_match(&pkttype_match); 62 - } 63 - 64 - static void __exit fini(void) 65 - { 66 - ipt_unregister_match(&pkttype_match); 67 - } 68 - 69 - module_init(init); 70 - module_exit(fini);
···
-76
net/ipv4/netfilter/ipt_realm.c
··· 1 - /* IP tables module for matching the routing realm 2 - * 3 - * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $ 4 - * 5 - * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - */ 11 - 12 - #include <linux/module.h> 13 - #include <linux/skbuff.h> 14 - #include <linux/netdevice.h> 15 - #include <net/route.h> 16 - 17 - #include <linux/netfilter_ipv4/ipt_realm.h> 18 - #include <linux/netfilter_ipv4/ip_tables.h> 19 - 20 - MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); 21 - MODULE_LICENSE("GPL"); 22 - MODULE_DESCRIPTION("iptables realm match"); 23 - 24 - static int 25 - match(const struct sk_buff *skb, 26 - const struct net_device *in, 27 - const struct net_device *out, 28 - const void *matchinfo, 29 - int offset, 30 - int *hotdrop) 31 - { 32 - const struct ipt_realm_info *info = matchinfo; 33 - struct dst_entry *dst = skb->dst; 34 - 35 - return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 36 - } 37 - 38 - static int check(const char *tablename, 39 - const struct ipt_ip *ip, 40 - void *matchinfo, 41 - unsigned int matchsize, 42 - unsigned int hook_mask) 43 - { 44 - if (hook_mask 45 - & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | 46 - (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { 47 - printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, " 48 - "LOCAL_IN or FORWARD.\n"); 49 - return 0; 50 - } 51 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) { 52 - printk("ipt_realm: invalid matchsize.\n"); 53 - return 0; 54 - } 55 - return 1; 56 - } 57 - 58 - static struct ipt_match realm_match = { 59 - .name = "realm", 60 - .match = match, 61 - .checkentry = check, 62 - .me = THIS_MODULE 63 - }; 64 - 65 - static int __init init(void) 66 - { 67 - return ipt_register_match(&realm_match); 68 - } 69 - 70 - static void __exit fini(void) 71 - { 72 - ipt_unregister_match(&realm_match); 73 - } 74 - 75 - module_init(init); 76 - module_exit(fini);
···
+4 -2
net/ipv4/netfilter/ipt_recent.c
··· 104 const struct net_device *out, 105 const void *matchinfo, 106 int offset, 107 int *hotdrop); 108 109 /* Function to hash a given address into the hash table of table_size size */ ··· 318 skb->nh.iph->daddr = 0; 319 /* Clear ttl since we have no way of knowing it */ 320 skb->nh.iph->ttl = 0; 321 - match(skb,NULL,NULL,info,0,NULL); 322 323 kfree(skb->nh.iph); 324 out_free_skb: ··· 358 const struct net_device *out, 359 const void *matchinfo, 360 int offset, 361 int *hotdrop) 362 { 363 int pkt_count, hits_found, ans; ··· 656 */ 657 static int 658 checkentry(const char *tablename, 659 - const struct ipt_ip *ip, 660 void *matchinfo, 661 unsigned int matchsize, 662 unsigned int hook_mask)
··· 104 const struct net_device *out, 105 const void *matchinfo, 106 int offset, 107 + unsigned int protoff, 108 int *hotdrop); 109 110 /* Function to hash a given address into the hash table of table_size size */ ··· 317 skb->nh.iph->daddr = 0; 318 /* Clear ttl since we have no way of knowing it */ 319 skb->nh.iph->ttl = 0; 320 + match(skb,NULL,NULL,info,0,0,NULL); 321 322 kfree(skb->nh.iph); 323 out_free_skb: ··· 357 const struct net_device *out, 358 const void *matchinfo, 359 int offset, 360 + unsigned int protoff, 361 int *hotdrop) 362 { 363 int pkt_count, hits_found, ans; ··· 654 */ 655 static int 656 checkentry(const char *tablename, 657 + const void *ip, 658 void *matchinfo, 659 unsigned int matchsize, 660 unsigned int hook_mask)
-203
net/ipv4/netfilter/ipt_sctp.c
··· 1 - #include <linux/module.h> 2 - #include <linux/skbuff.h> 3 - #include <net/ip.h> 4 - #include <linux/sctp.h> 5 - 6 - #include <linux/netfilter_ipv4/ip_tables.h> 7 - #include <linux/netfilter_ipv4/ipt_sctp.h> 8 - 9 - #ifdef DEBUG_SCTP 10 - #define duprintf(format, args...) printk(format , ## args) 11 - #else 12 - #define duprintf(format, args...) 13 - #endif 14 - 15 - #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 16 - || (!!((invflag) & (option)) ^ (cond))) 17 - 18 - static int 19 - match_flags(const struct ipt_sctp_flag_info *flag_info, 20 - const int flag_count, 21 - u_int8_t chunktype, 22 - u_int8_t chunkflags) 23 - { 24 - int i; 25 - 26 - for (i = 0; i < flag_count; i++) { 27 - if (flag_info[i].chunktype == chunktype) { 28 - return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; 29 - } 30 - } 31 - 32 - return 1; 33 - } 34 - 35 - static int 36 - match_packet(const struct sk_buff *skb, 37 - const u_int32_t *chunkmap, 38 - int chunk_match_type, 39 - const struct ipt_sctp_flag_info *flag_info, 40 - const int flag_count, 41 - int *hotdrop) 42 - { 43 - int offset; 44 - u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 45 - sctp_chunkhdr_t _sch, *sch; 46 - 47 - #ifdef DEBUG_SCTP 48 - int i = 0; 49 - #endif 50 - 51 - if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) { 52 - SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); 53 - } 54 - 55 - offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t); 56 - do { 57 - sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); 58 - if (sch == NULL) { 59 - duprintf("Dropping invalid SCTP packet.\n"); 60 - *hotdrop = 1; 61 - return 0; 62 - } 63 - 64 - duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 65 - ++i, offset, sch->type, htons(sch->length), sch->flags); 66 - 67 - offset += (htons(sch->length) + 3) & ~3; 68 - 69 - duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); 70 - 71 - if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { 72 - switch (chunk_match_type) { 73 - case SCTP_CHUNK_MATCH_ANY: 74 - if (match_flags(flag_info, flag_count, 75 - sch->type, sch->flags)) { 76 - return 1; 77 - } 78 - break; 79 - 80 - case SCTP_CHUNK_MATCH_ALL: 81 - if (match_flags(flag_info, flag_count, 82 - sch->type, sch->flags)) { 83 - SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); 84 - } 85 - break; 86 - 87 - case SCTP_CHUNK_MATCH_ONLY: 88 - if (!match_flags(flag_info, flag_count, 89 - sch->type, sch->flags)) { 90 - return 0; 91 - } 92 - break; 93 - } 94 - } else { 95 - switch (chunk_match_type) { 96 - case SCTP_CHUNK_MATCH_ONLY: 97 - return 0; 98 - } 99 - } 100 - } while (offset < skb->len); 101 - 102 - switch (chunk_match_type) { 103 - case SCTP_CHUNK_MATCH_ALL: 104 - return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); 105 - case SCTP_CHUNK_MATCH_ANY: 106 - return 0; 107 - case SCTP_CHUNK_MATCH_ONLY: 108 - return 1; 109 - } 110 - 111 - /* This will never be reached, but required to stop compiler whine */ 112 - return 0; 113 - } 114 - 115 - static int 116 - match(const struct sk_buff *skb, 117 - const struct net_device *in, 118 - const struct net_device *out, 119 - const void *matchinfo, 120 - int offset, 121 - int *hotdrop) 122 - { 123 - const struct ipt_sctp_info *info; 124 - sctp_sctphdr_t _sh, *sh; 125 - 126 - info = (const struct ipt_sctp_info *)matchinfo; 127 - 128 - if (offset) { 129 - duprintf("Dropping non-first fragment.. FIXME\n"); 130 - return 0; 131 - } 132 - 133 - sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh); 134 - if (sh == NULL) { 135 - duprintf("Dropping evil TCP offset=0 tinygram.\n"); 136 - *hotdrop = 1; 137 - return 0; 138 - } 139 - duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 140 - 141 - return SCCHECK(((ntohs(sh->source) >= info->spts[0]) 142 - && (ntohs(sh->source) <= info->spts[1])), 143 - IPT_SCTP_SRC_PORTS, info->flags, info->invflags) 144 - && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) 145 - && (ntohs(sh->dest) <= info->dpts[1])), 146 - IPT_SCTP_DEST_PORTS, info->flags, info->invflags) 147 - && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type, 148 - info->flag_info, info->flag_count, 149 - hotdrop), 150 - IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 151 - } 152 - 153 - static int 154 - checkentry(const char *tablename, 155 - const struct ipt_ip *ip, 156 - void *matchinfo, 157 - unsigned int matchsize, 158 - unsigned int hook_mask) 159 - { 160 - const struct ipt_sctp_info *info; 161 - 162 - info = (const struct ipt_sctp_info *)matchinfo; 163 - 164 - return ip->proto == IPPROTO_SCTP 165 - && !(ip->invflags & IPT_INV_PROTO) 166 - && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info)) 167 - && !(info->flags & ~IPT_SCTP_VALID_FLAGS) 168 - && !(info->invflags & ~IPT_SCTP_VALID_FLAGS) 169 - && !(info->invflags & ~info->flags) 170 - && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) || 171 - (info->chunk_match_type & 172 - (SCTP_CHUNK_MATCH_ALL 173 - | SCTP_CHUNK_MATCH_ANY 174 - | SCTP_CHUNK_MATCH_ONLY))); 175 - } 176 - 177 - static struct ipt_match sctp_match = 178 - { 179 - .list = { NULL, NULL}, 180 - .name = "sctp", 181 - .match = &match, 182 - .checkentry = &checkentry, 183 - .destroy = NULL, 184 - .me = THIS_MODULE 185 - }; 186 - 187 - static int __init init(void) 188 - { 189 - return ipt_register_match(&sctp_match); 190 - } 191 - 192 - static void __exit fini(void) 193 - { 194 - ipt_unregister_match(&sctp_match); 195 - } 196 - 197 - module_init(init); 198 - module_exit(fini); 199 - 200 - MODULE_LICENSE("GPL"); 201 - MODULE_AUTHOR("Kiran Kumar Immidi"); 202 - MODULE_DESCRIPTION("Match for SCTP protocol packets"); 203 -
···
-74
net/ipv4/netfilter/ipt_state.c
··· 1 - /* Kernel module to match connection tracking information. */ 2 - 3 - /* (C) 1999-2001 Paul `Rusty' Russell 4 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <net/netfilter/nf_conntrack_compat.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - #include <linux/netfilter_ipv4/ipt_state.h> 16 - 17 - MODULE_LICENSE("GPL"); 18 - MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 19 - MODULE_DESCRIPTION("iptables connection tracking state match module"); 20 - 21 - static int 22 - match(const struct sk_buff *skb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - const void *matchinfo, 26 - int offset, 27 - int *hotdrop) 28 - { 29 - const struct ipt_state_info *sinfo = matchinfo; 30 - enum ip_conntrack_info ctinfo; 31 - unsigned int statebit; 32 - 33 - if (nf_ct_is_untracked(skb)) 34 - statebit = IPT_STATE_UNTRACKED; 35 - else if (!nf_ct_get_ctinfo(skb, &ctinfo)) 36 - statebit = IPT_STATE_INVALID; 37 - else 38 - statebit = IPT_STATE_BIT(ctinfo); 39 - 40 - return (sinfo->statemask & statebit); 41 - } 42 - 43 - static int check(const char *tablename, 44 - const struct ipt_ip *ip, 45 - void *matchinfo, 46 - unsigned int matchsize, 47 - unsigned int hook_mask) 48 - { 49 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info))) 50 - return 0; 51 - 52 - return 1; 53 - } 54 - 55 - static struct ipt_match state_match = { 56 - .name = "state", 57 - .match = &match, 58 - .checkentry = &check, 59 - .me = THIS_MODULE, 60 - }; 61 - 62 - static int __init init(void) 63 - { 64 - need_ip_conntrack(); 65 - return ipt_register_match(&state_match); 66 - } 67 - 68 - static void __exit fini(void) 69 - { 70 - ipt_unregister_match(&state_match); 71 - } 72 - 73 - module_init(init); 74 - module_exit(fini);
···
-91
net/ipv4/netfilter/ipt_string.c
··· 1 - /* String matching match for iptables 2 - * 3 - * (C) 2005 Pablo Neira Ayuso <pablo@eurodev.net> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/init.h> 11 - #include <linux/module.h> 12 - #include <linux/kernel.h> 13 - #include <linux/skbuff.h> 14 - #include <linux/netfilter_ipv4/ip_tables.h> 15 - #include <linux/netfilter_ipv4/ipt_string.h> 16 - #include <linux/textsearch.h> 17 - 18 - MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); 19 - MODULE_DESCRIPTION("IP tables string match module"); 20 - MODULE_LICENSE("GPL"); 21 - 22 - static int match(const struct sk_buff *skb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - const void *matchinfo, 26 - int offset, 27 - int *hotdrop) 28 - { 29 - struct ts_state state; 30 - struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo; 31 - 32 - memset(&state, 0, sizeof(struct ts_state)); 33 - 34 - return (skb_find_text((struct sk_buff *)skb, conf->from_offset, 35 - conf->to_offset, conf->config, &state) 36 - != UINT_MAX) && !conf->invert; 37 - } 38 - 39 - #define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m) 40 - 41 - static int checkentry(const char *tablename, 42 - const struct ipt_ip *ip, 43 - void *matchinfo, 44 - unsigned int matchsize, 45 - unsigned int hook_mask) 46 - { 47 - struct ipt_string_info *conf = matchinfo; 48 - struct ts_config *ts_conf; 49 - 50 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) 51 - return 0; 52 - 53 - /* Damn, can't handle this case properly with iptables... */ 54 - if (conf->from_offset > conf->to_offset) 55 - return 0; 56 - 57 - ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, 58 - GFP_KERNEL, TS_AUTOLOAD); 59 - if (IS_ERR(ts_conf)) 60 - return 0; 61 - 62 - conf->config = ts_conf; 63 - 64 - return 1; 65 - } 66 - 67 - static void destroy(void *matchinfo, unsigned int matchsize) 68 - { 69 - textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 70 - } 71 - 72 - static struct ipt_match string_match = { 73 - .name = "string", 74 - .match = match, 75 - .checkentry = checkentry, 76 - .destroy = destroy, 77 - .me = THIS_MODULE 78 - }; 79 - 80 - static int __init init(void) 81 - { 82 - return ipt_register_match(&string_match); 83 - } 84 - 85 - static void __exit fini(void) 86 - { 87 - ipt_unregister_match(&string_match); 88 - } 89 - 90 - module_init(init); 91 - module_exit(fini);
···
-127
net/ipv4/netfilter/ipt_tcpmss.c
··· 1 - /* Kernel module to match TCP MSS values. */ 2 - 3 - /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <net/tcp.h> 13 - 14 - #include <linux/netfilter_ipv4/ipt_tcpmss.h> 15 - #include <linux/netfilter_ipv4/ip_tables.h> 16 - 17 - #define TH_SYN 0x02 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 21 - MODULE_DESCRIPTION("iptables TCP MSS match module"); 22 - 23 - /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ 24 - static inline int 25 - mssoption_match(u_int16_t min, u_int16_t max, 26 - const struct sk_buff *skb, 27 - int invert, 28 - int *hotdrop) 29 - { 30 - struct tcphdr _tcph, *th; 31 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 32 - u8 _opt[15 * 4 - sizeof(_tcph)], *op; 33 - unsigned int i, optlen; 34 - 35 - /* If we don't have the whole header, drop packet. */ 36 - th = skb_header_pointer(skb, skb->nh.iph->ihl * 4, 37 - sizeof(_tcph), &_tcph); 38 - if (th == NULL) 39 - goto dropit; 40 - 41 - /* Malformed. */ 42 - if (th->doff*4 < sizeof(*th)) 43 - goto dropit; 44 - 45 - optlen = th->doff*4 - sizeof(*th); 46 - if (!optlen) 47 - goto out; 48 - 49 - /* Truncated options. */ 50 - op = skb_header_pointer(skb, skb->nh.iph->ihl * 4 + sizeof(*th), 51 - optlen, _opt); 52 - if (op == NULL) 53 - goto dropit; 54 - 55 - for (i = 0; i < optlen; ) { 56 - if (op[i] == TCPOPT_MSS 57 - && (optlen - i) >= TCPOLEN_MSS 58 - && op[i+1] == TCPOLEN_MSS) { 59 - u_int16_t mssval; 60 - 61 - mssval = (op[i+2] << 8) | op[i+3]; 62 - 63 - return (mssval >= min && mssval <= max) ^ invert; 64 - } 65 - if (op[i] < 2) i++; 66 - else i += op[i+1]?:1; 67 - } 68 - out: 69 - return invert; 70 - 71 - dropit: 72 - *hotdrop = 1; 73 - return 0; 74 - } 75 - 76 - static int 77 - match(const struct sk_buff *skb, 78 - const struct net_device *in, 79 - const struct net_device *out, 80 - const void *matchinfo, 81 - int offset, 82 - int *hotdrop) 83 - { 84 - const struct ipt_tcpmss_match_info *info = matchinfo; 85 - 86 - return mssoption_match(info->mss_min, info->mss_max, skb, 87 - info->invert, hotdrop); 88 - } 89 - 90 - static int 91 - checkentry(const char *tablename, 92 - const struct ipt_ip *ip, 93 - void *matchinfo, 94 - unsigned int matchsize, 95 - unsigned int hook_mask) 96 - { 97 - if (matchsize != IPT_ALIGN(sizeof(struct ipt_tcpmss_match_info))) 98 - return 0; 99 - 100 - /* Must specify -p tcp */ 101 - if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { 102 - printk("tcpmss: Only works on TCP packets\n"); 103 - return 0; 104 - } 105 - 106 - return 1; 107 - } 108 - 109 - static struct ipt_match tcpmss_match = { 110 - .name = "tcpmss", 111 - .match = &match, 112 - .checkentry = &checkentry, 113 - .me = THIS_MODULE, 114 - }; 115 - 116 - static int __init init(void) 117 - { 118 - return ipt_register_match(&tcpmss_match); 119 - } 120 - 121 - static void __exit fini(void) 122 - { 123 - ipt_unregister_match(&tcpmss_match); 124 - } 125 - 126 - module_init(init); 127 - module_exit(fini);
···
+2 -1
net/ipv4/netfilter/ipt_tos.c
··· 23 const struct net_device *out, 24 const void *matchinfo, 25 int offset, 26 int *hotdrop) 27 { 28 const struct ipt_tos_info *info = matchinfo; ··· 33 34 static int 35 checkentry(const char *tablename, 36 - const struct ipt_ip *ip, 37 void *matchinfo, 38 unsigned int matchsize, 39 unsigned int hook_mask)
··· 23 const struct net_device *out, 24 const void *matchinfo, 25 int offset, 26 + unsigned int protoff, 27 int *hotdrop) 28 { 29 const struct ipt_tos_info *info = matchinfo; ··· 32 33 static int 34 checkentry(const char *tablename, 35 + const void *ip, 36 void *matchinfo, 37 unsigned int matchsize, 38 unsigned int hook_mask)
+2 -2
net/ipv4/netfilter/ipt_ttl.c
··· 21 22 static int match(const struct sk_buff *skb, const struct net_device *in, 23 const struct net_device *out, const void *matchinfo, 24 - int offset, int *hotdrop) 25 { 26 const struct ipt_ttl_info *info = matchinfo; 27 ··· 47 return 0; 48 } 49 50 - static int checkentry(const char *tablename, const struct ipt_ip *ip, 51 void *matchinfo, unsigned int matchsize, 52 unsigned int hook_mask) 53 {
··· 21 22 static int match(const struct sk_buff *skb, const struct net_device *in, 23 const struct net_device *out, const void *matchinfo, 24 + int offset, unsigned int protoff, int *hotdrop) 25 { 26 const struct ipt_ttl_info *info = matchinfo; 27 ··· 47 return 0; 48 } 49 50 + static int checkentry(const char *tablename, const void *ip, 51 void *matchinfo, unsigned int matchsize, 52 unsigned int hook_mask) 53 {
+2 -1
net/ipv4/netfilter/iptable_filter.c
··· 78 .name = "filter", 79 .valid_hooks = FILTER_VALID_HOOKS, 80 .lock = RW_LOCK_UNLOCKED, 81 - .me = THIS_MODULE 82 }; 83 84 /* The work comes in here from netfilter.c. */
··· 78 .name = "filter", 79 .valid_hooks = FILTER_VALID_HOOKS, 80 .lock = RW_LOCK_UNLOCKED, 81 + .me = THIS_MODULE, 82 + .af = AF_INET, 83 }; 84 85 /* The work comes in here from netfilter.c. */
+1
net/ipv4/netfilter/iptable_mangle.c
··· 109 .valid_hooks = MANGLE_VALID_HOOKS, 110 .lock = RW_LOCK_UNLOCKED, 111 .me = THIS_MODULE, 112 }; 113 114 /* The work comes in here from netfilter.c. */
··· 109 .valid_hooks = MANGLE_VALID_HOOKS, 110 .lock = RW_LOCK_UNLOCKED, 111 .me = THIS_MODULE, 112 + .af = AF_INET, 113 }; 114 115 /* The work comes in here from netfilter.c. */
+2 -1
net/ipv4/netfilter/iptable_raw.c
··· 83 .name = "raw", 84 .valid_hooks = RAW_VALID_HOOKS, 85 .lock = RW_LOCK_UNLOCKED, 86 - .me = THIS_MODULE 87 }; 88 89 /* The work comes in here from netfilter.c. */
··· 83 .name = "raw", 84 .valid_hooks = RAW_VALID_HOOKS, 85 .lock = RW_LOCK_UNLOCKED, 86 + .me = THIS_MODULE, 87 + .af = AF_INET, 88 }; 89 90 /* The work comes in here from netfilter.c. */
+1 -6
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
··· 575 576 static int __init init(void) 577 { 578 - need_nf_conntrack(); 579 return init_or_cleanup(1); 580 } 581 ··· 587 module_init(init); 588 module_exit(fini); 589 590 - void need_ip_conntrack(void) 591 - { 592 - } 593 - 594 - EXPORT_SYMBOL(need_ip_conntrack); 595 EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
··· 575 576 static int __init init(void) 577 { 578 + need_conntrack(); 579 return init_or_cleanup(1); 580 } 581 ··· 587 module_init(init); 588 module_exit(fini); 589 590 EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
+1 -71
net/ipv6/netfilter/Kconfig
··· 41 42 config IP6_NF_IPTABLES 43 tristate "IP6 tables support (required for filtering/masq/NAT)" 44 help 45 ip6tables is a general, extensible packet identification framework. 46 Currently only the packet filtering and packet mangling subsystem ··· 51 To compile it as a module, choose M here. If unsure, say N. 52 53 # The simple matches. 54 - config IP6_NF_MATCH_LIMIT 55 - tristate "limit match support" 56 - depends on IP6_NF_IPTABLES 57 - help 58 - limit matching allows you to control the rate at which a rule can be 59 - matched: mainly useful in combination with the LOG target ("LOG 60 - target support", below) and to avoid some Denial of Service attacks. 61 - 62 - To compile it as a module, choose M here. If unsure, say N. 63 - 64 - config IP6_NF_MATCH_MAC 65 - tristate "MAC address match support" 66 - depends on IP6_NF_IPTABLES 67 - help 68 - mac matching allows you to match packets based on the source 69 - Ethernet address of the packet. 70 - 71 - To compile it as a module, choose M here. If unsure, say N. 72 - 73 config IP6_NF_MATCH_RT 74 tristate "Routing header match support" 75 depends on IP6_NF_IPTABLES ··· 106 107 To compile it as a module, choose M here. If unsure, say N. 108 109 - config IP6_NF_MATCH_MARK 110 - tristate "netfilter MARK match support" 111 - depends on IP6_NF_IPTABLES 112 - help 113 - Netfilter mark matching allows you to match packets based on the 114 - `nfmark' value in the packet. This can be set by the MARK target 115 - (see below). 116 - 117 - To compile it as a module, choose M here. If unsure, say N. 118 - 119 config IP6_NF_MATCH_IPV6HEADER 120 tristate "IPv6 Extension Headers Match" 121 depends on IP6_NF_IPTABLES ··· 123 124 To compile it as a module, choose M here. If unsure, say N. 125 126 - config IP6_NF_MATCH_LENGTH 127 - tristate "Packet Length match support" 128 - depends on IP6_NF_IPTABLES 129 - help 130 - This option allows you to match the length of a packet against a 131 - specific value or range of values. 132 - 133 - To compile it as a module, choose M here. If unsure, say N. 134 - 135 config IP6_NF_MATCH_EUI64 136 tristate "EUI64 address check" 137 depends on IP6_NF_IPTABLES ··· 130 This module performs checking on the IPv6 source address 131 Compares the last 64 bits with the EUI64 (delivered 132 from the MAC address) address 133 - 134 - To compile it as a module, choose M here. If unsure, say N. 135 - 136 - config IP6_NF_MATCH_PHYSDEV 137 - tristate "Physdev match support" 138 - depends on IP6_NF_IPTABLES && BRIDGE_NETFILTER 139 - help 140 - Physdev packet matching matches against the physical bridge ports 141 - the IP packet arrived on or will leave by. 142 143 To compile it as a module, choose M here. If unsure, say N. 144 ··· 173 174 To compile it as a module, choose M here. If unsure, say N. 175 176 - config IP6_NF_TARGET_NFQUEUE 177 - tristate "NFQUEUE Target Support" 178 - depends on IP6_NF_IPTABLES 179 - help 180 - This Target replaced the old obsolete QUEUE target. 181 - 182 - As opposed to QUEUE, it supports 65535 different queues, 183 - not just one. 184 - 185 - To compile it as a module, choose M here. If unsure, say N. 186 - 187 config IP6_NF_MANGLE 188 tristate "Packet mangling" 189 depends on IP6_NF_IPTABLES ··· 180 This option adds a `mangle' table to iptables: see the man page for 181 iptables(8). This table is used for various packet alterations 182 which can effect how the packet is routed. 183 - 184 - To compile it as a module, choose M here. If unsure, say N. 185 - 186 - config IP6_NF_TARGET_MARK 187 - tristate "MARK target support" 188 - depends on IP6_NF_MANGLE 189 - help 190 - This option adds a `MARK' target, which allows you to create rules 191 - in the `mangle' table which alter the netfilter mark (nfmark) field 192 - associated with the packet packet prior to routing. This can change 193 - the routing method (see `Use netfilter MARK value as routing 194 - key') and can also be used by other subsystems to change their 195 - behavior. 196 197 To compile it as a module, choose M here. If unsure, say N. 198
··· 41 42 config IP6_NF_IPTABLES 43 tristate "IP6 tables support (required for filtering/masq/NAT)" 44 + depends on NETFILTER_XTABLES 45 help 46 ip6tables is a general, extensible packet identification framework. 47 Currently only the packet filtering and packet mangling subsystem ··· 50 To compile it as a module, choose M here. If unsure, say N. 51 52 # The simple matches. 53 config IP6_NF_MATCH_RT 54 tristate "Routing header match support" 55 depends on IP6_NF_IPTABLES ··· 124 125 To compile it as a module, choose M here. If unsure, say N. 126 127 config IP6_NF_MATCH_IPV6HEADER 128 tristate "IPv6 Extension Headers Match" 129 depends on IP6_NF_IPTABLES ··· 151 152 To compile it as a module, choose M here. If unsure, say N. 153 154 config IP6_NF_MATCH_EUI64 155 tristate "EUI64 address check" 156 depends on IP6_NF_IPTABLES ··· 167 This module performs checking on the IPv6 source address 168 Compares the last 64 bits with the EUI64 (delivered 169 from the MAC address) address 170 171 To compile it as a module, choose M here. If unsure, say N. 172 ··· 219 220 To compile it as a module, choose M here. If unsure, say N. 221 222 config IP6_NF_MANGLE 223 tristate "Packet mangling" 224 depends on IP6_NF_IPTABLES ··· 237 This option adds a `mangle' table to iptables: see the man page for 238 iptables(8). This table is used for various packet alterations 239 which can effect how the packet is routed. 240 241 To compile it as a module, choose M here. If unsure, say N. 242
-6
net/ipv6/netfilter/Makefile
··· 4 5 # Link order matters here. 6 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o 7 - obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o 8 - obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o 9 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o 10 - obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o 11 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o 12 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o 13 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o ··· 14 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o 15 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o 16 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o 17 - obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o 18 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o 19 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 20 - obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o 21 obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o 22 - obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o 23 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o 24 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o 25 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
··· 4 5 # Link order matters here. 6 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o 7 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o 8 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o 9 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o 10 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o ··· 17 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o 18 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o 19 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o 20 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o 21 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o 22 obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o 23 obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o 24 obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o 25 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
+101 -727
net/ipv6/netfilter/ip6_tables.c
··· 13 * a table 14 * 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu> 15 * - new extension header parser code 16 */ 17 18 #include <linux/capability.h> ··· 26 #include <linux/vmalloc.h> 27 #include <linux/netdevice.h> 28 #include <linux/module.h> 29 - #include <linux/tcp.h> 30 - #include <linux/udp.h> 31 #include <linux/icmpv6.h> 32 #include <net/ipv6.h> 33 #include <asm/uaccess.h> ··· 34 #include <linux/cpumask.h> 35 36 #include <linux/netfilter_ipv6/ip6_tables.h> 37 38 MODULE_LICENSE("GPL"); 39 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); ··· 69 #else 70 #define IP_NF_ASSERT(x) 71 #endif 72 - #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 73 74 - static DECLARE_MUTEX(ip6t_mutex); 75 76 - /* Must have mutex */ 77 - #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) 78 - #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) 79 #include <linux/netfilter_ipv4/listhelp.h> 80 81 #if 0 ··· 87 the counters or update the rules. 88 89 Hence the start of any table is given by get_table() below. */ 90 - 91 - /* The table itself */ 92 - struct ip6t_table_info 93 - { 94 - /* Size per table */ 95 - unsigned int size; 96 - /* Number of entries: FIXME. --RR */ 97 - unsigned int number; 98 - /* Initial number of entries. Needed for module usage count */ 99 - unsigned int initial_entries; 100 - 101 - /* Entry points and underflows */ 102 - unsigned int hook_entry[NF_IP6_NUMHOOKS]; 103 - unsigned int underflow[NF_IP6_NUMHOOKS]; 104 - 105 - /* ip6t_entry tables: one per CPU */ 106 - void *entries[NR_CPUS]; 107 - }; 108 - 109 - static LIST_HEAD(ip6t_target); 110 - static LIST_HEAD(ip6t_match); 111 - static LIST_HEAD(ip6t_tables); 112 - #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) 113 - #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) 114 115 #if 0 116 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) ··· 270 unsigned int hook, 271 const struct net_device *in, 272 const struct net_device *out, 273 - struct ip6t_table *table, 274 void *userdata) 275 { 276 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); ··· 282 const char *indev, *outdev; 283 void *table_base; 284 struct ip6t_entry *e, *back; 285 286 /* Initialization */ 287 indev = in ? in->name : nulldevname; ··· 295 * match it. */ 296 297 read_lock_bh(&table->lock); 298 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 299 - table_base = (void *)table->private->entries[smp_processor_id()]; 300 - e = get_entry(table_base, table->private->hook_entry[hook]); 301 302 #ifdef CONFIG_NETFILTER_DEBUG 303 /* Check noone else using our table */ ··· 314 #endif 315 316 /* For return from builtin chain */ 317 - back = get_entry(table_base, table->private->underflow[hook]); 318 319 do { 320 IP_NF_ASSERT(e); ··· 414 #endif 415 } 416 417 - /* 418 - * These are weird, but module loading must not be done with mutex 419 - * held (since they will register), and we have to have a single 420 - * function to use try_then_request_module(). 421 - */ 422 - 423 - /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 424 - static inline struct ip6t_table *find_table_lock(const char *name) 425 - { 426 - struct ip6t_table *t; 427 - 428 - if (down_interruptible(&ip6t_mutex) != 0) 429 - return ERR_PTR(-EINTR); 430 - 431 - list_for_each_entry(t, &ip6t_tables, list) 432 - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 433 - return t; 434 - up(&ip6t_mutex); 435 - return NULL; 436 - } 437 - 438 - /* Find match, grabs ref. Returns ERR_PTR() on error. */ 439 - static inline struct ip6t_match *find_match(const char *name, u8 revision) 440 - { 441 - struct ip6t_match *m; 442 - int err = 0; 443 - 444 - if (down_interruptible(&ip6t_mutex) != 0) 445 - return ERR_PTR(-EINTR); 446 - 447 - list_for_each_entry(m, &ip6t_match, list) { 448 - if (strcmp(m->name, name) == 0) { 449 - if (m->revision == revision) { 450 - if (try_module_get(m->me)) { 451 - up(&ip6t_mutex); 452 - return m; 453 - } 454 - } else 455 - err = -EPROTOTYPE; /* Found something. */ 456 - } 457 - } 458 - up(&ip6t_mutex); 459 - return ERR_PTR(err); 460 - } 461 - 462 - /* Find target, grabs ref. Returns ERR_PTR() on error. */ 463 - static inline struct ip6t_target *find_target(const char *name, u8 revision) 464 - { 465 - struct ip6t_target *t; 466 - int err = 0; 467 - 468 - if (down_interruptible(&ip6t_mutex) != 0) 469 - return ERR_PTR(-EINTR); 470 - 471 - list_for_each_entry(t, &ip6t_target, list) { 472 - if (strcmp(t->name, name) == 0) { 473 - if (t->revision == revision) { 474 - if (try_module_get(t->me)) { 475 - up(&ip6t_mutex); 476 - return t; 477 - } 478 - } else 479 - err = -EPROTOTYPE; /* Found something. */ 480 - } 481 - } 482 - up(&ip6t_mutex); 483 - return ERR_PTR(err); 484 - } 485 - 486 - struct ip6t_target *ip6t_find_target(const char *name, u8 revision) 487 - { 488 - struct ip6t_target *target; 489 - 490 - target = try_then_request_module(find_target(name, revision), 491 - "ip6t_%s", name); 492 - if (IS_ERR(target) || !target) 493 - return NULL; 494 - return target; 495 - } 496 - 497 - static int match_revfn(const char *name, u8 revision, int *bestp) 498 - { 499 - struct ip6t_match *m; 500 - int have_rev = 0; 501 - 502 - list_for_each_entry(m, &ip6t_match, list) { 503 - if (strcmp(m->name, name) == 0) { 504 - if (m->revision > *bestp) 505 - *bestp = m->revision; 506 - if (m->revision == revision) 507 - have_rev = 1; 508 - } 509 - } 510 - return have_rev; 511 - } 512 - 513 - static int target_revfn(const char *name, u8 revision, int *bestp) 514 - { 515 - struct ip6t_target *t; 516 - int have_rev = 0; 517 - 518 - list_for_each_entry(t, &ip6t_target, list) { 519 - if (strcmp(t->name, name) == 0) { 520 - if (t->revision > *bestp) 521 - *bestp = t->revision; 522 - if (t->revision == revision) 523 - have_rev = 1; 524 - } 525 - } 526 - return have_rev; 527 - } 528 - 529 - /* Returns true or fals (if no such extension at all) */ 530 - static inline int find_revision(const char *name, u8 revision, 531 - int (*revfn)(const char *, u8, int *), 532 - int *err) 533 - { 534 - int have_rev, best = -1; 535 - 536 - if (down_interruptible(&ip6t_mutex) != 0) { 537 - *err = -EINTR; 538 - return 1; 539 - } 540 - have_rev = revfn(name, revision, &best); 541 - up(&ip6t_mutex); 542 - 543 - /* Nothing at all? Return 0 to try loading module. */ 544 - if (best == -1) { 545 - *err = -ENOENT; 546 - return 0; 547 - } 548 - 549 - *err = best; 550 - if (!have_rev) 551 - *err = -EPROTONOSUPPORT; 552 - return 1; 553 - } 554 - 555 - 556 /* All zeroes == unconditional rule. */ 557 static inline int 558 unconditional(const struct ip6t_ip6 *ipv6) ··· 430 /* Figures out from what hook each rule can be called: returns 0 if 431 there are loops. Puts hook bitmask in comefrom. */ 432 static int 433 - mark_source_chains(struct ip6t_table_info *newinfo, 434 unsigned int valid_hooks, void *entry0) 435 { 436 unsigned int hook; ··· 576 { 577 struct ip6t_match *match; 578 579 - match = try_then_request_module(find_match(m->u.user.name, 580 - m->u.user.revision), 581 "ip6t_%s", m->u.user.name); 582 if (IS_ERR(match) || !match) { 583 - duprintf("check_match: `%s' not found\n", m->u.user.name); 584 return match ? PTR_ERR(match) : -ENOENT; 585 } 586 m->u.kernel.match = match; ··· 621 goto cleanup_matches; 622 623 t = ip6t_get_target(e); 624 - target = try_then_request_module(find_target(t->u.user.name, 625 - t->u.user.revision), 626 "ip6t_%s", t->u.user.name); 627 if (IS_ERR(target) || !target) { 628 duprintf("check_entry: `%s' not found\n", t->u.user.name); ··· 659 660 static inline int 661 check_entry_size_and_hooks(struct ip6t_entry *e, 662 - struct ip6t_table_info *newinfo, 663 unsigned char *base, 664 unsigned char *limit, 665 const unsigned int *hook_entries, ··· 693 < 0 (not IP6T_RETURN). --RR */ 694 695 /* Clear counters and comefrom */ 696 - e->counters = ((struct ip6t_counters) { 0, 0 }); 697 e->comefrom = 0; 698 699 (*i)++; ··· 723 static int 724 translate_table(const char *name, 725 unsigned int valid_hooks, 726 - struct ip6t_table_info *newinfo, 727 void *entry0, 728 unsigned int size, 729 unsigned int number, ··· 800 return ret; 801 } 802 803 - static struct ip6t_table_info * 804 - replace_table(struct ip6t_table *table, 805 - unsigned int num_counters, 806 - struct ip6t_table_info *newinfo, 807 - int *error) 808 - { 809 - struct ip6t_table_info *oldinfo; 810 - 811 - #ifdef CONFIG_NETFILTER_DEBUG 812 - { 813 - int cpu; 814 - 815 - for_each_cpu(cpu) { 816 - struct ip6t_entry *table_base = newinfo->entries[cpu]; 817 - if (table_base) 818 - table_base->comefrom = 0xdead57ac; 819 - } 820 - } 821 - #endif 822 - 823 - /* Do the substitution. */ 824 - write_lock_bh(&table->lock); 825 - /* Check inside lock: is the old number correct? */ 826 - if (num_counters != table->private->number) { 827 - duprintf("num_counters != table->private->number (%u/%u)\n", 828 - num_counters, table->private->number); 829 - write_unlock_bh(&table->lock); 830 - *error = -EAGAIN; 831 - return NULL; 832 - } 833 - oldinfo = table->private; 834 - table->private = newinfo; 835 - newinfo->initial_entries = oldinfo->initial_entries; 836 - write_unlock_bh(&table->lock); 837 - 838 - return oldinfo; 839 - } 840 - 841 /* Gets counters. */ 842 static inline int 843 add_entry_to_counter(const struct ip6t_entry *e, 844 - struct ip6t_counters total[], 845 unsigned int *i) 846 { 847 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 824 } 825 826 static void 827 - get_counters(const struct ip6t_table_info *t, 828 - struct ip6t_counters counters[]) 829 { 830 unsigned int cpu; 831 unsigned int i; ··· 859 860 static int 861 copy_entries_to_user(unsigned int total_size, 862 - struct ip6t_table *table, 863 void __user *userptr) 864 { 865 unsigned int off, num, countersize; 866 struct ip6t_entry *e; 867 - struct ip6t_counters *counters; 868 int ret = 0; 869 void *loc_cpu_entry; 870 871 /* We need atomic snapshot of counters: rest doesn't change 872 (other than comefrom, which userspace doesn't care 873 about). */ 874 - countersize = sizeof(struct ip6t_counters) * table->private->number; 875 counters = vmalloc(countersize); 876 877 if (counters == NULL) ··· 880 881 /* First, sum counters... */ 882 write_lock_bh(&table->lock); 883 - get_counters(table->private, counters); 884 write_unlock_bh(&table->lock); 885 886 /* choose the copy that is on ourc node/cpu */ 887 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 888 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 889 ret = -EFAULT; 890 goto free_counters; ··· 943 struct ip6t_get_entries __user *uptr) 944 { 945 int ret; 946 - struct ip6t_table *t; 947 948 - t = find_table_lock(entries->name); 949 if (t && !IS_ERR(t)) { 950 - duprintf("t->private->number = %u\n", 951 - t->private->number); 952 - if (entries->size == t->private->size) 953 - ret = copy_entries_to_user(t->private->size, 954 t, uptr->entrytable); 955 else { 956 duprintf("get_entries: I've got %u not %u!\n", 957 - t->private->size, 958 - entries->size); 959 ret = -EINVAL; 960 } 961 module_put(t->me); 962 - up(&ip6t_mutex); 963 } else 964 ret = t ? PTR_ERR(t) : -ENOENT; 965 966 return ret; 967 - } 968 - 969 - static void free_table_info(struct ip6t_table_info *info) 970 - { 971 - int cpu; 972 - for_each_cpu(cpu) { 973 - if (info->size <= PAGE_SIZE) 974 - kfree(info->entries[cpu]); 975 - else 976 - vfree(info->entries[cpu]); 977 - } 978 - kfree(info); 979 - } 980 - 981 - static struct ip6t_table_info *alloc_table_info(unsigned int size) 982 - { 983 - struct ip6t_table_info *newinfo; 984 - int cpu; 985 - 986 - newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL); 987 - if (!newinfo) 988 - return NULL; 989 - 990 - newinfo->size = size; 991 - 992 - for_each_cpu(cpu) { 993 - if (size <= PAGE_SIZE) 994 - newinfo->entries[cpu] = kmalloc_node(size, 995 - GFP_KERNEL, 996 - cpu_to_node(cpu)); 997 - else 998 - newinfo->entries[cpu] = vmalloc_node(size, 999 - cpu_to_node(cpu)); 1000 - if (newinfo->entries[cpu] == NULL) { 1001 - free_table_info(newinfo); 1002 - return NULL; 1003 - } 1004 - } 1005 - 1006 - return newinfo; 1007 } 1008 1009 static int ··· 970 { 971 int ret; 972 struct ip6t_replace tmp; 973 - struct ip6t_table *t; 974 - struct ip6t_table_info *newinfo, *oldinfo; 975 - struct ip6t_counters *counters; 976 void *loc_cpu_entry, *loc_cpu_old_entry; 977 978 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 979 return -EFAULT; 980 981 - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 982 - if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) 983 - return -ENOMEM; 984 - 985 - newinfo = alloc_table_info(tmp.size); 986 if (!newinfo) 987 return -ENOMEM; 988 ··· 990 goto free_newinfo; 991 } 992 993 - counters = vmalloc(tmp.num_counters * sizeof(struct ip6t_counters)); 994 if (!counters) { 995 ret = -ENOMEM; 996 goto free_newinfo; ··· 1004 1005 duprintf("ip_tables: Translated table\n"); 1006 1007 - t = try_then_request_module(find_table_lock(tmp.name), 1008 "ip6table_%s", tmp.name); 1009 if (!t || IS_ERR(t)) { 1010 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1019 goto put_module; 1020 } 1021 1022 - oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); 1023 if (!oldinfo) 1024 goto put_module; 1025 ··· 1038 /* Decrease module usage counts and free resource */ 1039 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1040 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 1041 - free_table_info(oldinfo); 1042 if (copy_to_user(tmp.counters, counters, 1043 - sizeof(struct ip6t_counters) * tmp.num_counters) != 0) 1044 ret = -EFAULT; 1045 vfree(counters); 1046 - up(&ip6t_mutex); 1047 return ret; 1048 1049 put_module: 1050 module_put(t->me); 1051 - up(&ip6t_mutex); 1052 free_newinfo_counters_untrans: 1053 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 1054 free_newinfo_counters: 1055 vfree(counters); 1056 free_newinfo: 1057 - free_table_info(newinfo); 1058 return ret; 1059 } 1060 ··· 1062 * and everything is OK. */ 1063 static inline int 1064 add_counter_to_entry(struct ip6t_entry *e, 1065 - const struct ip6t_counters addme[], 1066 unsigned int *i) 1067 { 1068 #if 0 ··· 1084 do_add_counters(void __user *user, unsigned int len) 1085 { 1086 unsigned int i; 1087 - struct ip6t_counters_info tmp, *paddc; 1088 - struct ip6t_table *t; 1089 int ret = 0; 1090 void *loc_cpu_entry; 1091 1092 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1093 return -EFAULT; 1094 1095 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ip6t_counters)) 1096 return -EINVAL; 1097 1098 paddc = vmalloc(len); ··· 1105 goto free; 1106 } 1107 1108 - t = find_table_lock(tmp.name); 1109 if (!t || IS_ERR(t)) { 1110 ret = t ? PTR_ERR(t) : -ENOENT; 1111 goto free; 1112 } 1113 1114 write_lock_bh(&t->lock); 1115 - if (t->private->number != paddc->num_counters) { 1116 ret = -EINVAL; 1117 goto unlock_up_free; 1118 } 1119 1120 i = 0; 1121 /* Choose the copy that is on our node */ 1122 - loc_cpu_entry = t->private->entries[smp_processor_id()]; 1123 IP6T_ENTRY_ITERATE(loc_cpu_entry, 1124 - t->private->size, 1125 add_counter_to_entry, 1126 paddc->counters, 1127 &i); 1128 unlock_up_free: 1129 write_unlock_bh(&t->lock); 1130 - up(&ip6t_mutex); 1131 module_put(t->me); 1132 free: 1133 vfree(paddc); ··· 1172 switch (cmd) { 1173 case IP6T_SO_GET_INFO: { 1174 char name[IP6T_TABLE_MAXNAMELEN]; 1175 - struct ip6t_table *t; 1176 1177 if (*len != sizeof(struct ip6t_getinfo)) { 1178 duprintf("length %u != %u\n", *len, ··· 1187 } 1188 name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; 1189 1190 - t = try_then_request_module(find_table_lock(name), 1191 "ip6table_%s", name); 1192 if (t && !IS_ERR(t)) { 1193 struct ip6t_getinfo info; 1194 1195 info.valid_hooks = t->valid_hooks; 1196 - memcpy(info.hook_entry, t->private->hook_entry, 1197 sizeof(info.hook_entry)); 1198 - memcpy(info.underflow, t->private->underflow, 1199 sizeof(info.underflow)); 1200 - info.num_entries = t->private->number; 1201 - info.size = t->private->size; 1202 memcpy(info.name, name, sizeof(info.name)); 1203 1204 if (copy_to_user(user, &info, *len) != 0) 1205 ret = -EFAULT; 1206 else 1207 ret = 0; 1208 - up(&ip6t_mutex); 1209 module_put(t->me); 1210 } else 1211 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1233 case IP6T_SO_GET_REVISION_MATCH: 1234 case IP6T_SO_GET_REVISION_TARGET: { 1235 struct ip6t_get_revision rev; 1236 - int (*revfn)(const char *, u8, int *); 1237 1238 if (*len != sizeof(rev)) { 1239 ret = -EINVAL; ··· 1245 } 1246 1247 if (cmd == IP6T_SO_GET_REVISION_TARGET) 1248 - revfn = target_revfn; 1249 else 1250 - revfn = match_revfn; 1251 1252 - try_then_request_module(find_revision(rev.name, rev.revision, 1253 - revfn, &ret), 1254 "ip6t_%s", rev.name); 1255 break; 1256 } ··· 1264 return ret; 1265 } 1266 1267 - /* Registration hooks for targets. */ 1268 - int 1269 - ip6t_register_target(struct ip6t_target *target) 1270 - { 1271 - int ret; 1272 - 1273 - ret = down_interruptible(&ip6t_mutex); 1274 - if (ret != 0) 1275 - return ret; 1276 - list_add(&target->list, &ip6t_target); 1277 - up(&ip6t_mutex); 1278 - return ret; 1279 - } 1280 - 1281 - void 1282 - ip6t_unregister_target(struct ip6t_target *target) 1283 - { 1284 - down(&ip6t_mutex); 1285 - LIST_DELETE(&ip6t_target, target); 1286 - up(&ip6t_mutex); 1287 - } 1288 - 1289 - int 1290 - ip6t_register_match(struct ip6t_match *match) 1291 - { 1292 - int ret; 1293 - 1294 - ret = down_interruptible(&ip6t_mutex); 1295 - if (ret != 0) 1296 - return ret; 1297 - 1298 - list_add(&match->list, &ip6t_match); 1299 - up(&ip6t_mutex); 1300 - 1301 - return ret; 1302 - } 1303 - 1304 - void 1305 - ip6t_unregister_match(struct ip6t_match *match) 1306 - { 1307 - down(&ip6t_mutex); 1308 - LIST_DELETE(&ip6t_match, match); 1309 - up(&ip6t_mutex); 1310 - } 1311 - 1312 - int ip6t_register_table(struct ip6t_table *table, 1313 const struct ip6t_replace *repl) 1314 { 1315 int ret; 1316 - struct ip6t_table_info *newinfo; 1317 - static struct ip6t_table_info bootstrap 1318 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1319 void *loc_cpu_entry; 1320 1321 - newinfo = alloc_table_info(repl->size); 1322 if (!newinfo) 1323 return -ENOMEM; 1324 ··· 1287 repl->hook_entry, 1288 repl->underflow); 1289 if (ret != 0) { 1290 - free_table_info(newinfo); 1291 return ret; 1292 } 1293 1294 - ret = down_interruptible(&ip6t_mutex); 1295 - if (ret != 0) { 1296 - free_table_info(newinfo); 1297 return ret; 1298 } 1299 1300 - /* Don't autoload: we'd eat our tail... */ 1301 - if (list_named_find(&ip6t_tables, table->name)) { 1302 - ret = -EEXIST; 1303 - goto free_unlock; 1304 - } 1305 - 1306 - /* Simplifies replace_table code. */ 1307 - table->private = &bootstrap; 1308 - if (!replace_table(table, 0, newinfo, &ret)) 1309 - goto free_unlock; 1310 - 1311 - duprintf("table->private->number = %u\n", 1312 - table->private->number); 1313 - 1314 - /* save number of initial entries */ 1315 - table->private->initial_entries = table->private->number; 1316 - 1317 - rwlock_init(&table->lock); 1318 - list_prepend(&ip6t_tables, table); 1319 - 1320 - unlock: 1321 - up(&ip6t_mutex); 1322 - return ret; 1323 - 1324 - free_unlock: 1325 - free_table_info(newinfo); 1326 - goto unlock; 1327 } 1328 1329 - void ip6t_unregister_table(struct ip6t_table *table) 1330 { 1331 void *loc_cpu_entry; 1332 1333 - down(&ip6t_mutex); 1334 - LIST_DELETE(&ip6t_tables, table); 1335 - up(&ip6t_mutex); 1336 1337 /* Decrease module usage counts and free resources */ 1338 - loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; 1339 - IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size, 1340 - cleanup_entry, NULL); 1341 - free_table_info(table->private); 1342 - } 1343 - 1344 - /* Returns 1 if the port is matched by the range, 0 otherwise */ 1345 - static inline int 1346 - port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 1347 - { 1348 - int ret; 1349 - 1350 - ret = (port >= min && port <= max) ^ invert; 1351 - return ret; 1352 - } 1353 - 1354 - static int 1355 - tcp_find_option(u_int8_t option, 1356 - const struct sk_buff *skb, 1357 - unsigned int tcpoff, 1358 - unsigned int optlen, 1359 - int invert, 1360 - int *hotdrop) 1361 - { 1362 - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 1363 - u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 1364 - unsigned int i; 1365 - 1366 - duprintf("tcp_match: finding option\n"); 1367 - if (!optlen) 1368 - return invert; 1369 - /* If we don't have the whole header, drop packet. */ 1370 - op = skb_header_pointer(skb, tcpoff + sizeof(struct tcphdr), optlen, 1371 - _opt); 1372 - if (op == NULL) { 1373 - *hotdrop = 1; 1374 - return 0; 1375 - } 1376 - 1377 - for (i = 0; i < optlen; ) { 1378 - if (op[i] == option) return !invert; 1379 - if (op[i] < 2) i++; 1380 - else i += op[i+1]?:1; 1381 - } 1382 - 1383 - return invert; 1384 - } 1385 - 1386 - static int 1387 - tcp_match(const struct sk_buff *skb, 1388 - const struct net_device *in, 1389 - const struct net_device *out, 1390 - const void *matchinfo, 1391 - int offset, 1392 - unsigned int protoff, 1393 - int *hotdrop) 1394 - { 1395 - struct tcphdr _tcph, *th; 1396 - const struct ip6t_tcp *tcpinfo = matchinfo; 1397 - 1398 - if (offset) { 1399 - /* To quote Alan: 1400 - 1401 - Don't allow a fragment of TCP 8 bytes in. Nobody normal 1402 - causes this. Its a cracker trying to break in by doing a 1403 - flag overwrite to pass the direction checks. 1404 - */ 1405 - if (offset == 1) { 1406 - duprintf("Dropping evil TCP offset=1 frag.\n"); 1407 - *hotdrop = 1; 1408 - } 1409 - /* Must not be a fragment. */ 1410 - return 0; 1411 - } 1412 - 1413 - #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 1414 - 1415 - th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 1416 - if (th == NULL) { 1417 - /* We've been asked to examine this packet, and we 1418 - can't. Hence, no choice but to drop. */ 1419 - duprintf("Dropping evil TCP offset=0 tinygram.\n"); 1420 - *hotdrop = 1; 1421 - return 0; 1422 - } 1423 - 1424 - if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 1425 - ntohs(th->source), 1426 - !!(tcpinfo->invflags & IP6T_TCP_INV_SRCPT))) 1427 - return 0; 1428 - if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 1429 - ntohs(th->dest), 1430 - !!(tcpinfo->invflags & IP6T_TCP_INV_DSTPT))) 1431 - return 0; 1432 - if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 1433 - == tcpinfo->flg_cmp, 1434 - IP6T_TCP_INV_FLAGS)) 1435 - return 0; 1436 - if (tcpinfo->option) { 1437 - if (th->doff * 4 < sizeof(_tcph)) { 1438 - *hotdrop = 1; 1439 - return 0; 1440 - } 1441 - if (!tcp_find_option(tcpinfo->option, skb, protoff, 1442 - th->doff*4 - sizeof(*th), 1443 - tcpinfo->invflags & IP6T_TCP_INV_OPTION, 1444 - hotdrop)) 1445 - return 0; 1446 - } 1447 - return 1; 1448 - } 1449 - 1450 - /* Called when user tries to insert an entry of this type. */ 1451 - static int 1452 - tcp_checkentry(const char *tablename, 1453 - const struct ip6t_ip6 *ipv6, 1454 - void *matchinfo, 1455 - unsigned int matchsize, 1456 - unsigned int hook_mask) 1457 - { 1458 - const struct ip6t_tcp *tcpinfo = matchinfo; 1459 - 1460 - /* Must specify proto == TCP, and no unknown invflags */ 1461 - return ipv6->proto == IPPROTO_TCP 1462 - && !(ipv6->invflags & IP6T_INV_PROTO) 1463 - && matchsize == IP6T_ALIGN(sizeof(struct ip6t_tcp)) 1464 - && !(tcpinfo->invflags & ~IP6T_TCP_INV_MASK); 1465 - } 1466 - 1467 - static int 1468 - udp_match(const struct sk_buff *skb, 1469 - const struct net_device *in, 1470 - const struct net_device *out, 1471 - const void *matchinfo, 1472 - int offset, 1473 - unsigned int protoff, 1474 - int *hotdrop) 1475 - { 1476 - struct udphdr _udph, *uh; 1477 - const struct ip6t_udp *udpinfo = matchinfo; 1478 - 1479 - /* Must not be a fragment. */ 1480 - if (offset) 1481 - return 0; 1482 - 1483 - uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 1484 - if (uh == NULL) { 1485 - /* We've been asked to examine this packet, and we 1486 - can't. Hence, no choice but to drop. */ 1487 - duprintf("Dropping evil UDP tinygram.\n"); 1488 - *hotdrop = 1; 1489 - return 0; 1490 - } 1491 - 1492 - return port_match(udpinfo->spts[0], udpinfo->spts[1], 1493 - ntohs(uh->source), 1494 - !!(udpinfo->invflags & IP6T_UDP_INV_SRCPT)) 1495 - && port_match(udpinfo->dpts[0], udpinfo->dpts[1], 1496 - ntohs(uh->dest), 1497 - !!(udpinfo->invflags & IP6T_UDP_INV_DSTPT)); 1498 - } 1499 - 1500 - /* Called when user tries to insert an entry of this type. */ 1501 - static int 1502 - udp_checkentry(const char *tablename, 1503 - const struct ip6t_ip6 *ipv6, 1504 - void *matchinfo, 1505 - unsigned int matchinfosize, 1506 - unsigned int hook_mask) 1507 - { 1508 - const struct ip6t_udp *udpinfo = matchinfo; 1509 - 1510 - /* Must specify proto == UDP, and no unknown invflags */ 1511 - if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & IP6T_INV_PROTO)) { 1512 - duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, 1513 - IPPROTO_UDP); 1514 - return 0; 1515 - } 1516 - if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_udp))) { 1517 - duprintf("ip6t_udp: matchsize %u != %u\n", 1518 - matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_udp))); 1519 - return 0; 1520 - } 1521 - if (udpinfo->invflags & ~IP6T_UDP_INV_MASK) { 1522 - duprintf("ip6t_udp: unknown flags %X\n", 1523 - udpinfo->invflags); 1524 - return 0; 1525 - } 1526 - 1527 - return 1; 1528 } 1529 1530 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ ··· 1357 /* Called when user tries to insert an entry of this type. */ 1358 static int 1359 icmp6_checkentry(const char *tablename, 1360 - const struct ip6t_ip6 *ipv6, 1361 void *matchinfo, 1362 unsigned int matchsize, 1363 unsigned int hook_mask) 1364 { 1365 const struct ip6t_icmp *icmpinfo = matchinfo; 1366 1367 /* Must specify proto == ICMP, and no unknown invflags */ ··· 1392 .get = do_ip6t_get_ctl, 1393 }; 1394 1395 - static struct ip6t_match tcp_matchstruct = { 1396 - .name = "tcp", 1397 - .match = &tcp_match, 1398 - .checkentry = &tcp_checkentry, 1399 - }; 1400 - 1401 - static struct ip6t_match udp_matchstruct = { 1402 - .name = "udp", 1403 - .match = &udp_match, 1404 - .checkentry = &udp_checkentry, 1405 - }; 1406 - 1407 static struct ip6t_match icmp6_matchstruct = { 1408 .name = "icmp6", 1409 .match = &icmp6_match, 1410 .checkentry = &icmp6_checkentry, 1411 }; 1412 1413 - #ifdef CONFIG_PROC_FS 1414 - static inline int print_name(const char *i, 1415 - off_t start_offset, char *buffer, int length, 1416 - off_t *pos, unsigned int *count) 1417 - { 1418 - if ((*count)++ >= start_offset) { 1419 - unsigned int namelen; 1420 - 1421 - namelen = sprintf(buffer + *pos, "%s\n", 1422 - i + sizeof(struct list_head)); 1423 - if (*pos + namelen > length) { 1424 - /* Stop iterating */ 1425 - return 1; 1426 - } 1427 - *pos += namelen; 1428 - } 1429 - return 0; 1430 - } 1431 - 1432 - static inline int print_target(const struct ip6t_target *t, 1433 - off_t start_offset, char *buffer, int length, 1434 - off_t *pos, unsigned int *count) 1435 - { 1436 - if (t == &ip6t_standard_target || t == &ip6t_error_target) 1437 - return 0; 1438 - return print_name((char *)t, start_offset, buffer, length, pos, count); 1439 - } 1440 - 1441 - static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length) 1442 - { 1443 - off_t pos = 0; 1444 - unsigned int count = 0; 1445 - 1446 - if (down_interruptible(&ip6t_mutex) != 0) 1447 - return 0; 1448 - 1449 - LIST_FIND(&ip6t_tables, print_name, char *, 1450 - offset, buffer, length, &pos, &count); 1451 - 1452 - up(&ip6t_mutex); 1453 - 1454 - /* `start' hack - see fs/proc/generic.c line ~105 */ 1455 - *start=(char *)((unsigned long)count-offset); 1456 - return pos; 1457 - } 1458 - 1459 - static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length) 1460 - { 1461 - off_t pos = 0; 1462 - unsigned int count = 0; 1463 - 1464 - if (down_interruptible(&ip6t_mutex) != 0) 1465 - return 0; 1466 - 1467 - LIST_FIND(&ip6t_target, print_target, struct ip6t_target *, 1468 - offset, buffer, length, &pos, &count); 1469 - 1470 - up(&ip6t_mutex); 1471 - 1472 - *start = (char *)((unsigned long)count - offset); 1473 - return pos; 1474 - } 1475 - 1476 - static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length) 1477 - { 1478 - off_t pos = 0; 1479 - unsigned int count = 0; 1480 - 1481 - if (down_interruptible(&ip6t_mutex) != 0) 1482 - return 0; 1483 - 1484 - LIST_FIND(&ip6t_match, print_name, char *, 1485 - offset, buffer, length, &pos, &count); 1486 - 1487 - up(&ip6t_mutex); 1488 - 1489 - *start = (char *)((unsigned long)count - offset); 1490 - return pos; 1491 - } 1492 - 1493 - static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = 1494 - { { "ip6_tables_names", ip6t_get_tables }, 1495 - { "ip6_tables_targets", ip6t_get_targets }, 1496 - { "ip6_tables_matches", ip6t_get_matches }, 1497 - { NULL, NULL} }; 1498 - #endif /*CONFIG_PROC_FS*/ 1499 - 1500 static int __init init(void) 1501 { 1502 int ret; 1503 1504 /* Noone else will be downing sem now, so we won't sleep */ 1505 - down(&ip6t_mutex); 1506 - list_append(&ip6t_target, &ip6t_standard_target); 1507 - list_append(&ip6t_target, &ip6t_error_target); 1508 - list_append(&ip6t_match, &tcp_matchstruct); 1509 - list_append(&ip6t_match, &udp_matchstruct); 1510 - list_append(&ip6t_match, &icmp6_matchstruct); 1511 - up(&ip6t_mutex); 1512 1513 /* Register setsockopt */ 1514 ret = nf_register_sockopt(&ip6t_sockopts); 1515 if (ret < 0) { 1516 duprintf("Unable to register sockopts.\n"); 1517 return ret; 1518 } 1519 1520 - #ifdef CONFIG_PROC_FS 1521 - { 1522 - struct proc_dir_entry *proc; 1523 - int i; 1524 - 1525 - for (i = 0; ip6t_proc_entry[i].name; i++) { 1526 - proc = proc_net_create(ip6t_proc_entry[i].name, 0, 1527 - ip6t_proc_entry[i].get_info); 1528 - if (!proc) { 1529 - while (--i >= 0) 1530 - proc_net_remove(ip6t_proc_entry[i].name); 1531 - nf_unregister_sockopt(&ip6t_sockopts); 1532 - return -ENOMEM; 1533 - } 1534 - proc->owner = THIS_MODULE; 1535 - } 1536 - } 1537 - #endif 1538 - 1539 - printk("ip6_tables: (C) 2000-2002 Netfilter core team\n"); 1540 return 0; 1541 } 1542 1543 static void __exit fini(void) 1544 { 1545 nf_unregister_sockopt(&ip6t_sockopts); 1546 - #ifdef CONFIG_PROC_FS 1547 - { 1548 - int i; 1549 - for (i = 0; ip6t_proc_entry[i].name; i++) 1550 - proc_net_remove(ip6t_proc_entry[i].name); 1551 - } 1552 - #endif 1553 } 1554 1555 /* ··· 1506 EXPORT_SYMBOL(ip6t_register_table); 1507 EXPORT_SYMBOL(ip6t_unregister_table); 1508 EXPORT_SYMBOL(ip6t_do_table); 1509 - EXPORT_SYMBOL(ip6t_register_match); 1510 - EXPORT_SYMBOL(ip6t_unregister_match); 1511 - EXPORT_SYMBOL(ip6t_register_target); 1512 - EXPORT_SYMBOL(ip6t_unregister_target); 1513 EXPORT_SYMBOL(ip6t_ext_hdr); 1514 EXPORT_SYMBOL(ipv6_find_hdr); 1515 EXPORT_SYMBOL(ip6_masked_addrcmp);
··· 13 * a table 14 * 06 Jun 2002 Andras Kis-Szabo <kisza@sch.bme.hu> 15 * - new extension header parser code 16 + * 15 Oct 2005 Harald Welte <laforge@netfilter.org> 17 + * - Unification of {ip,ip6}_tables into x_tables 18 + * - Removed tcp and udp code, since it's not ipv6 specific 19 */ 20 21 #include <linux/capability.h> ··· 23 #include <linux/vmalloc.h> 24 #include <linux/netdevice.h> 25 #include <linux/module.h> 26 #include <linux/icmpv6.h> 27 #include <net/ipv6.h> 28 #include <asm/uaccess.h> ··· 33 #include <linux/cpumask.h> 34 35 #include <linux/netfilter_ipv6/ip6_tables.h> 36 + #include <linux/netfilter/x_tables.h> 37 38 MODULE_LICENSE("GPL"); 39 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); ··· 67 #else 68 #define IP_NF_ASSERT(x) 69 #endif 70 71 72 #include <linux/netfilter_ipv4/listhelp.h> 73 74 #if 0 ··· 90 the counters or update the rules. 91 92 Hence the start of any table is given by get_table() below. */ 93 94 #if 0 95 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) ··· 297 unsigned int hook, 298 const struct net_device *in, 299 const struct net_device *out, 300 + struct xt_table *table, 301 void *userdata) 302 { 303 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); ··· 309 const char *indev, *outdev; 310 void *table_base; 311 struct ip6t_entry *e, *back; 312 + struct xt_table_info *private; 313 314 /* Initialization */ 315 indev = in ? in->name : nulldevname; ··· 321 * match it. */ 322 323 read_lock_bh(&table->lock); 324 + private = table->private; 325 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 326 + table_base = (void *)private->entries[smp_processor_id()]; 327 + e = get_entry(table_base, private->hook_entry[hook]); 328 329 #ifdef CONFIG_NETFILTER_DEBUG 330 /* Check noone else using our table */ ··· 339 #endif 340 341 /* For return from builtin chain */ 342 + back = get_entry(table_base, private->underflow[hook]); 343 344 do { 345 IP_NF_ASSERT(e); ··· 439 #endif 440 } 441 442 /* All zeroes == unconditional rule. */ 443 static inline int 444 unconditional(const struct ip6t_ip6 *ipv6) ··· 594 /* Figures out from what hook each rule can be called: returns 0 if 595 there are loops. Puts hook bitmask in comefrom. */ 596 static int 597 + mark_source_chains(struct xt_table_info *newinfo, 598 unsigned int valid_hooks, void *entry0) 599 { 600 unsigned int hook; ··· 740 { 741 struct ip6t_match *match; 742 743 + match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, 744 + m->u.user.revision), 745 "ip6t_%s", m->u.user.name); 746 if (IS_ERR(match) || !match) { 747 + duprintf("check_match: `%s' not found\n", m->u.user.name); 748 return match ? PTR_ERR(match) : -ENOENT; 749 } 750 m->u.kernel.match = match; ··· 785 goto cleanup_matches; 786 787 t = ip6t_get_target(e); 788 + target = try_then_request_module(xt_find_target(AF_INET6, 789 + t->u.user.name, 790 + t->u.user.revision), 791 "ip6t_%s", t->u.user.name); 792 if (IS_ERR(target) || !target) { 793 duprintf("check_entry: `%s' not found\n", t->u.user.name); ··· 822 823 static inline int 824 check_entry_size_and_hooks(struct ip6t_entry *e, 825 + struct xt_table_info *newinfo, 826 unsigned char *base, 827 unsigned char *limit, 828 const unsigned int *hook_entries, ··· 856 < 0 (not IP6T_RETURN). --RR */ 857 858 /* Clear counters and comefrom */ 859 + e->counters = ((struct xt_counters) { 0, 0 }); 860 e->comefrom = 0; 861 862 (*i)++; ··· 886 static int 887 translate_table(const char *name, 888 unsigned int valid_hooks, 889 + struct xt_table_info *newinfo, 890 void *entry0, 891 unsigned int size, 892 unsigned int number, ··· 963 return ret; 964 } 965 966 /* Gets counters. */ 967 static inline int 968 add_entry_to_counter(const struct ip6t_entry *e, 969 + struct xt_counters total[], 970 unsigned int *i) 971 { 972 ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); ··· 1025 } 1026 1027 static void 1028 + get_counters(const struct xt_table_info *t, 1029 + struct xt_counters counters[]) 1030 { 1031 unsigned int cpu; 1032 unsigned int i; ··· 1060 1061 static int 1062 copy_entries_to_user(unsigned int total_size, 1063 + struct xt_table *table, 1064 void __user *userptr) 1065 { 1066 unsigned int off, num, countersize; 1067 struct ip6t_entry *e; 1068 + struct xt_counters *counters; 1069 + struct xt_table_info *private = table->private; 1070 int ret = 0; 1071 void *loc_cpu_entry; 1072 1073 /* We need atomic snapshot of counters: rest doesn't change 1074 (other than comefrom, which userspace doesn't care 1075 about). */ 1076 + countersize = sizeof(struct xt_counters) * private->number; 1077 counters = vmalloc(countersize); 1078 1079 if (counters == NULL) ··· 1080 1081 /* First, sum counters... */ 1082 write_lock_bh(&table->lock); 1083 + get_counters(private, counters); 1084 write_unlock_bh(&table->lock); 1085 1086 /* choose the copy that is on ourc node/cpu */ 1087 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1088 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { 1089 ret = -EFAULT; 1090 goto free_counters; ··· 1143 struct ip6t_get_entries __user *uptr) 1144 { 1145 int ret; 1146 + struct xt_table *t; 1147 1148 + t = xt_find_table_lock(AF_INET6, entries->name); 1149 if (t && !IS_ERR(t)) { 1150 + struct xt_table_info *private = t->private; 1151 + duprintf("t->private->number = %u\n", private->number); 1152 + if (entries->size == private->size) 1153 + ret = copy_entries_to_user(private->size, 1154 t, uptr->entrytable); 1155 else { 1156 duprintf("get_entries: I've got %u not %u!\n", 1157 + private->size, entries->size); 1158 ret = -EINVAL; 1159 } 1160 module_put(t->me); 1161 + xt_table_unlock(t); 1162 } else 1163 ret = t ? PTR_ERR(t) : -ENOENT; 1164 1165 return ret; 1166 } 1167 1168 static int ··· 1211 { 1212 int ret; 1213 struct ip6t_replace tmp; 1214 + struct xt_table *t; 1215 + struct xt_table_info *newinfo, *oldinfo; 1216 + struct xt_counters *counters; 1217 void *loc_cpu_entry, *loc_cpu_old_entry; 1218 1219 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1220 return -EFAULT; 1221 1222 + newinfo = xt_alloc_table_info(tmp.size); 1223 if (!newinfo) 1224 return -ENOMEM; 1225 ··· 1235 goto free_newinfo; 1236 } 1237 1238 + counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 1239 if (!counters) { 1240 ret = -ENOMEM; 1241 goto free_newinfo; ··· 1249 1250 duprintf("ip_tables: Translated table\n"); 1251 1252 + t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name), 1253 "ip6table_%s", tmp.name); 1254 if (!t || IS_ERR(t)) { 1255 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1264 goto put_module; 1265 } 1266 1267 + oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 1268 if (!oldinfo) 1269 goto put_module; 1270 ··· 1283 /* Decrease module usage counts and free resource */ 1284 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1285 IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 1286 + xt_free_table_info(oldinfo); 1287 if (copy_to_user(tmp.counters, counters, 1288 + sizeof(struct xt_counters) * tmp.num_counters) != 0) 1289 ret = -EFAULT; 1290 vfree(counters); 1291 + xt_table_unlock(t); 1292 return ret; 1293 1294 put_module: 1295 module_put(t->me); 1296 + xt_table_unlock(t); 1297 free_newinfo_counters_untrans: 1298 IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 1299 free_newinfo_counters: 1300 vfree(counters); 1301 free_newinfo: 1302 + xt_free_table_info(newinfo); 1303 return ret; 1304 } 1305 ··· 1307 * and everything is OK. */ 1308 static inline int 1309 add_counter_to_entry(struct ip6t_entry *e, 1310 + const struct xt_counters addme[], 1311 unsigned int *i) 1312 { 1313 #if 0 ··· 1329 do_add_counters(void __user *user, unsigned int len) 1330 { 1331 unsigned int i; 1332 + struct xt_counters_info tmp, *paddc; 1333 + struct xt_table_info *private; 1334 + struct xt_table *t; 1335 int ret = 0; 1336 void *loc_cpu_entry; 1337 1338 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1339 return -EFAULT; 1340 1341 + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 1342 return -EINVAL; 1343 1344 paddc = vmalloc(len); ··· 1349 goto free; 1350 } 1351 1352 + t = xt_find_table_lock(AF_INET6, tmp.name); 1353 if (!t || IS_ERR(t)) { 1354 ret = t ? PTR_ERR(t) : -ENOENT; 1355 goto free; 1356 } 1357 1358 write_lock_bh(&t->lock); 1359 + private = t->private; 1360 + if (private->number != paddc->num_counters) { 1361 ret = -EINVAL; 1362 goto unlock_up_free; 1363 } 1364 1365 i = 0; 1366 /* Choose the copy that is on our node */ 1367 + loc_cpu_entry = private->entries[smp_processor_id()]; 1368 IP6T_ENTRY_ITERATE(loc_cpu_entry, 1369 + private->size, 1370 add_counter_to_entry, 1371 paddc->counters, 1372 &i); 1373 unlock_up_free: 1374 write_unlock_bh(&t->lock); 1375 + xt_table_unlock(t); 1376 module_put(t->me); 1377 free: 1378 vfree(paddc); ··· 1415 switch (cmd) { 1416 case IP6T_SO_GET_INFO: { 1417 char name[IP6T_TABLE_MAXNAMELEN]; 1418 + struct xt_table *t; 1419 1420 if (*len != sizeof(struct ip6t_getinfo)) { 1421 duprintf("length %u != %u\n", *len, ··· 1430 } 1431 name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; 1432 1433 + t = try_then_request_module(xt_find_table_lock(AF_INET6, name), 1434 "ip6table_%s", name); 1435 if (t && !IS_ERR(t)) { 1436 struct ip6t_getinfo info; 1437 + struct xt_table_info *private = t->private; 1438 1439 info.valid_hooks = t->valid_hooks; 1440 + memcpy(info.hook_entry, private->hook_entry, 1441 sizeof(info.hook_entry)); 1442 + memcpy(info.underflow, private->underflow, 1443 sizeof(info.underflow)); 1444 + info.num_entries = private->number; 1445 + info.size = private->size; 1446 memcpy(info.name, name, sizeof(info.name)); 1447 1448 if (copy_to_user(user, &info, *len) != 0) 1449 ret = -EFAULT; 1450 else 1451 ret = 0; 1452 + xt_table_unlock(t); 1453 module_put(t->me); 1454 } else 1455 ret = t ? PTR_ERR(t) : -ENOENT; ··· 1475 case IP6T_SO_GET_REVISION_MATCH: 1476 case IP6T_SO_GET_REVISION_TARGET: { 1477 struct ip6t_get_revision rev; 1478 + int target; 1479 1480 if (*len != sizeof(rev)) { 1481 ret = -EINVAL; ··· 1487 } 1488 1489 if (cmd == IP6T_SO_GET_REVISION_TARGET) 1490 + target = 1; 1491 else 1492 + target = 0; 1493 1494 + try_then_request_module(xt_find_revision(AF_INET6, rev.name, 1495 + rev.revision, 1496 + target, &ret), 1497 "ip6t_%s", rev.name); 1498 break; 1499 } ··· 1505 return ret; 1506 } 1507 1508 + int ip6t_register_table(struct xt_table *table, 1509 const struct ip6t_replace *repl) 1510 { 1511 int ret; 1512 + struct xt_table_info *newinfo; 1513 + static struct xt_table_info bootstrap 1514 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1515 void *loc_cpu_entry; 1516 1517 + newinfo = xt_alloc_table_info(repl->size); 1518 if (!newinfo) 1519 return -ENOMEM; 1520 ··· 1573 repl->hook_entry, 1574 repl->underflow); 1575 if (ret != 0) { 1576 + xt_free_table_info(newinfo); 1577 return ret; 1578 } 1579 1580 + if (xt_register_table(table, &bootstrap, newinfo) != 0) { 1581 + xt_free_table_info(newinfo); 1582 return ret; 1583 } 1584 1585 + return 0; 1586 } 1587 1588 + void ip6t_unregister_table(struct xt_table *table) 1589 { 1590 + struct xt_table_info *private; 1591 void *loc_cpu_entry; 1592 1593 + private = xt_unregister_table(table); 1594 1595 /* Decrease module usage counts and free resources */ 1596 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1597 + IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); 1598 + xt_free_table_info(private); 1599 } 1600 1601 /* Returns 1 if the type and code is matched by the range, 0 otherwise */ ··· 1858 /* Called when user tries to insert an entry of this type. */ 1859 static int 1860 icmp6_checkentry(const char *tablename, 1861 + const void *entry, 1862 void *matchinfo, 1863 unsigned int matchsize, 1864 unsigned int hook_mask) 1865 { 1866 + const struct ip6t_ip6 *ipv6 = entry; 1867 const struct ip6t_icmp *icmpinfo = matchinfo; 1868 1869 /* Must specify proto == ICMP, and no unknown invflags */ ··· 1892 .get = do_ip6t_get_ctl, 1893 }; 1894 1895 static struct ip6t_match icmp6_matchstruct = { 1896 .name = "icmp6", 1897 .match = &icmp6_match, 1898 .checkentry = &icmp6_checkentry, 1899 }; 1900 1901 static int __init init(void) 1902 { 1903 int ret; 1904 1905 + xt_proto_init(AF_INET6); 1906 + 1907 /* Noone else will be downing sem now, so we won't sleep */ 1908 + xt_register_target(AF_INET6, &ip6t_standard_target); 1909 + xt_register_target(AF_INET6, &ip6t_error_target); 1910 + xt_register_match(AF_INET6, &icmp6_matchstruct); 1911 1912 /* Register setsockopt */ 1913 ret = nf_register_sockopt(&ip6t_sockopts); 1914 if (ret < 0) { 1915 duprintf("Unable to register sockopts.\n"); 1916 + xt_proto_fini(AF_INET6); 1917 return ret; 1918 } 1919 1920 + printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); 1921 return 0; 1922 } 1923 1924 static void __exit fini(void) 1925 { 1926 nf_unregister_sockopt(&ip6t_sockopts); 1927 + xt_unregister_match(AF_INET6, &icmp6_matchstruct); 1928 + xt_unregister_target(AF_INET6, &ip6t_error_target); 1929 + xt_unregister_target(AF_INET6, &ip6t_standard_target); 1930 + xt_proto_fini(AF_INET6); 1931 } 1932 1933 /* ··· 2128 EXPORT_SYMBOL(ip6t_register_table); 2129 EXPORT_SYMBOL(ip6t_unregister_table); 2130 EXPORT_SYMBOL(ip6t_do_table); 2131 EXPORT_SYMBOL(ip6t_ext_hdr); 2132 EXPORT_SYMBOL(ipv6_find_hdr); 2133 EXPORT_SYMBOL(ip6_masked_addrcmp);
+1 -1
net/ipv6/netfilter/ip6t_HL.c
··· 62 } 63 64 static int ip6t_hl_checkentry(const char *tablename, 65 - const struct ip6t_entry *e, 66 void *targinfo, 67 unsigned int targinfosize, 68 unsigned int hook_mask)
··· 62 } 63 64 static int ip6t_hl_checkentry(const char *tablename, 65 + const void *entry, 66 void *targinfo, 67 unsigned int targinfosize, 68 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_LOG.c
··· 444 445 446 static int ip6t_log_checkentry(const char *tablename, 447 - const struct ip6t_entry *e, 448 void *targinfo, 449 unsigned int targinfosize, 450 unsigned int hook_mask)
··· 444 445 446 static int ip6t_log_checkentry(const char *tablename, 447 + const void *entry, 448 void *targinfo, 449 unsigned int targinfosize, 450 unsigned int hook_mask)
-81
net/ipv6/netfilter/ip6t_MARK.c
··· 1 - /* This is a module which is used for setting the NFMARK field of an skb. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <linux/ip.h> 13 - #include <net/checksum.h> 14 - 15 - #include <linux/netfilter_ipv6/ip6_tables.h> 16 - #include <linux/netfilter_ipv6/ip6t_MARK.h> 17 - 18 - MODULE_LICENSE("GPL"); 19 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 20 - 21 - static unsigned int 22 - target(struct sk_buff **pskb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - unsigned int hooknum, 26 - const void *targinfo, 27 - void *userinfo) 28 - { 29 - const struct ip6t_mark_target_info *markinfo = targinfo; 30 - 31 - if((*pskb)->nfmark != markinfo->mark) 32 - (*pskb)->nfmark = markinfo->mark; 33 - 34 - return IP6T_CONTINUE; 35 - } 36 - 37 - static int 38 - checkentry(const char *tablename, 39 - const struct ip6t_entry *e, 40 - void *targinfo, 41 - unsigned int targinfosize, 42 - unsigned int hook_mask) 43 - { 44 - if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) { 45 - printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 46 - targinfosize, 47 - IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))); 48 - return 0; 49 - } 50 - 51 - if (strcmp(tablename, "mangle") != 0) { 52 - printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 53 - return 0; 54 - } 55 - 56 - return 1; 57 - } 58 - 59 - static struct ip6t_target ip6t_mark_reg = { 60 - .name = "MARK", 61 - .target = target, 62 - .checkentry = checkentry, 63 - .me = THIS_MODULE 64 - }; 65 - 66 - static int __init init(void) 67 - { 68 - printk(KERN_DEBUG "registering ipv6 mark target\n"); 69 - if (ip6t_register_target(&ip6t_mark_reg)) 70 - return -EINVAL; 71 - 72 - return 0; 73 - } 74 - 75 - static void __exit fini(void) 76 - { 77 - ip6t_unregister_target(&ip6t_mark_reg); 78 - } 79 - 80 - module_init(init); 81 - module_exit(fini);
···
-70
net/ipv6/netfilter/ip6t_NFQUEUE.c
··· 1 - /* ip6tables module for using new netfilter netlink queue 2 - * 3 - * (C) 2005 by Harald Welte <laforge@netfilter.org> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - * 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #include <linux/netfilter.h> 15 - #include <linux/netfilter_ipv6/ip6_tables.h> 16 - #include <linux/netfilter_ipv4/ipt_NFQUEUE.h> 17 - 18 - MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 19 - MODULE_DESCRIPTION("ip6tables NFQUEUE target"); 20 - MODULE_LICENSE("GPL"); 21 - 22 - static unsigned int 23 - target(struct sk_buff **pskb, 24 - const struct net_device *in, 25 - const struct net_device *out, 26 - unsigned int hooknum, 27 - const void *targinfo, 28 - void *userinfo) 29 - { 30 - const struct ipt_NFQ_info *tinfo = targinfo; 31 - 32 - return NF_QUEUE_NR(tinfo->queuenum); 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ip6t_entry *e, 38 - void *targinfo, 39 - unsigned int targinfosize, 40 - unsigned int hook_mask) 41 - { 42 - if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) { 43 - printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", 44 - targinfosize, 45 - IP6T_ALIGN(sizeof(struct ipt_NFQ_info))); 46 - return 0; 47 - } 48 - 49 - return 1; 50 - } 51 - 52 - static struct ip6t_target ipt_NFQ_reg = { 53 - .name = "NFQUEUE", 54 - .target = target, 55 - .checkentry = checkentry, 56 - .me = THIS_MODULE, 57 - }; 58 - 59 - static int __init init(void) 60 - { 61 - return ip6t_register_target(&ipt_NFQ_reg); 62 - } 63 - 64 - static void __exit fini(void) 65 - { 66 - ip6t_unregister_target(&ipt_NFQ_reg); 67 - } 68 - 69 - module_init(init); 70 - module_exit(fini);
···
+2 -1
net/ipv6/netfilter/ip6t_REJECT.c
··· 218 } 219 220 static int check(const char *tablename, 221 - const struct ip6t_entry *e, 222 void *targinfo, 223 unsigned int targinfosize, 224 unsigned int hook_mask) 225 { 226 const struct ip6t_reject_info *rejinfo = targinfo; 227 228 if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) { 229 DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
··· 218 } 219 220 static int check(const char *tablename, 221 + const void *entry, 222 void *targinfo, 223 unsigned int targinfosize, 224 unsigned int hook_mask) 225 { 226 const struct ip6t_reject_info *rejinfo = targinfo; 227 + const struct ip6t_entry *e = entry; 228 229 if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) { 230 DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize);
+1 -1
net/ipv6/netfilter/ip6t_ah.c
··· 98 /* Called when user tries to insert an entry of this type. */ 99 static int 100 checkentry(const char *tablename, 101 - const struct ip6t_ip6 *ip, 102 void *matchinfo, 103 unsigned int matchinfosize, 104 unsigned int hook_mask)
··· 98 /* Called when user tries to insert an entry of this type. */ 99 static int 100 checkentry(const char *tablename, 101 + const void *entry, 102 void *matchinfo, 103 unsigned int matchinfosize, 104 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_dst.c
··· 178 /* Called when user tries to insert an entry of this type. */ 179 static int 180 checkentry(const char *tablename, 181 - const struct ip6t_ip6 *ip, 182 void *matchinfo, 183 unsigned int matchinfosize, 184 unsigned int hook_mask)
··· 178 /* Called when user tries to insert an entry of this type. */ 179 static int 180 checkentry(const char *tablename, 181 + const void *info, 182 void *matchinfo, 183 unsigned int matchinfosize, 184 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_esp.c
··· 76 /* Called when user tries to insert an entry of this type. */ 77 static int 78 checkentry(const char *tablename, 79 - const struct ip6t_ip6 *ip, 80 void *matchinfo, 81 unsigned int matchinfosize, 82 unsigned int hook_mask)
··· 76 /* Called when user tries to insert an entry of this type. */ 77 static int 78 checkentry(const char *tablename, 79 + const void *ip, 80 void *matchinfo, 81 unsigned int matchinfosize, 82 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_eui64.c
··· 62 63 static int 64 ip6t_eui64_checkentry(const char *tablename, 65 - const struct ip6t_ip6 *ip, 66 void *matchinfo, 67 unsigned int matchsize, 68 unsigned int hook_mask)
··· 62 63 static int 64 ip6t_eui64_checkentry(const char *tablename, 65 + const void *ip, 66 void *matchinfo, 67 unsigned int matchsize, 68 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_frag.c
··· 115 /* Called when user tries to insert an entry of this type. */ 116 static int 117 checkentry(const char *tablename, 118 - const struct ip6t_ip6 *ip, 119 void *matchinfo, 120 unsigned int matchinfosize, 121 unsigned int hook_mask)
··· 115 /* Called when user tries to insert an entry of this type. */ 116 static int 117 checkentry(const char *tablename, 118 + const void *ip, 119 void *matchinfo, 120 unsigned int matchinfosize, 121 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_hbh.c
··· 178 /* Called when user tries to insert an entry of this type. */ 179 static int 180 checkentry(const char *tablename, 181 - const struct ip6t_ip6 *ip, 182 void *matchinfo, 183 unsigned int matchinfosize, 184 unsigned int hook_mask)
··· 178 /* Called when user tries to insert an entry of this type. */ 179 static int 180 checkentry(const char *tablename, 181 + const void *entry, 182 void *matchinfo, 183 unsigned int matchinfosize, 184 unsigned int hook_mask)
+1 -1
net/ipv6/netfilter/ip6t_hl.c
··· 48 return 0; 49 } 50 51 - static int checkentry(const char *tablename, const struct ip6t_ip6 *ip, 52 void *matchinfo, unsigned int matchsize, 53 unsigned int hook_mask) 54 {
··· 48 return 0; 49 } 50 51 + static int checkentry(const char *tablename, const void *entry, 52 void *matchinfo, unsigned int matchsize, 53 unsigned int hook_mask) 54 {
+1 -1
net/ipv6/netfilter/ip6t_ipv6header.c
··· 124 125 static int 126 ipv6header_checkentry(const char *tablename, 127 - const struct ip6t_ip6 *ip, 128 void *matchinfo, 129 unsigned int matchsize, 130 unsigned int hook_mask)
··· 124 125 static int 126 ipv6header_checkentry(const char *tablename, 127 + const void *ip, 128 void *matchinfo, 129 unsigned int matchsize, 130 unsigned int hook_mask)
-66
net/ipv6/netfilter/ip6t_length.c
··· 1 - /* Length Match - IPv6 Port */ 2 - 3 - /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/netfilter_ipv6/ip6t_length.h> 14 - #include <linux/netfilter_ipv6/ip6_tables.h> 15 - 16 - MODULE_LICENSE("GPL"); 17 - MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 18 - MODULE_DESCRIPTION("IPv6 packet length match"); 19 - 20 - static int 21 - match(const struct sk_buff *skb, 22 - const struct net_device *in, 23 - const struct net_device *out, 24 - const void *matchinfo, 25 - int offset, 26 - unsigned int protoff, 27 - int *hotdrop) 28 - { 29 - const struct ip6t_length_info *info = matchinfo; 30 - u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); 31 - 32 - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ip6t_ip6 *ip, 38 - void *matchinfo, 39 - unsigned int matchsize, 40 - unsigned int hook_mask) 41 - { 42 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info))) 43 - return 0; 44 - 45 - return 1; 46 - } 47 - 48 - static struct ip6t_match length_match = { 49 - .name = "length", 50 - .match = &match, 51 - .checkentry = &checkentry, 52 - .me = THIS_MODULE, 53 - }; 54 - 55 - static int __init init(void) 56 - { 57 - return ip6t_register_match(&length_match); 58 - } 59 - 60 - static void __exit fini(void) 61 - { 62 - ip6t_unregister_match(&length_match); 63 - } 64 - 65 - module_init(init); 66 - module_exit(fini);
···
-147
net/ipv6/netfilter/ip6t_limit.c
··· 1 - /* Kernel module to control the rate 2 - * 3 - * 2 September 1999: Changed from the target RATE to the match 4 - * `limit', removed logging. Did I mention that 5 - * Alexey is a fucking genius? 6 - * Rusty Russell (rusty@rustcorp.com.au). */ 7 - 8 - /* (C) 1999 J�r�me de Vivie <devivie@info.enserb.u-bordeaux.fr> 9 - * (C) 1999 Herv� Eychenne <eychenne@info.enserb.u-bordeaux.fr> 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License version 2 as 13 - * published by the Free Software Foundation. 14 - */ 15 - 16 - #include <linux/module.h> 17 - #include <linux/skbuff.h> 18 - #include <linux/spinlock.h> 19 - #include <linux/interrupt.h> 20 - 21 - #include <linux/netfilter_ipv6/ip6_tables.h> 22 - #include <linux/netfilter_ipv6/ip6t_limit.h> 23 - 24 - MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); 26 - MODULE_DESCRIPTION("rate limiting within ip6tables"); 27 - 28 - /* The algorithm used is the Simple Token Bucket Filter (TBF) 29 - * see net/sched/sch_tbf.c in the linux source tree 30 - */ 31 - 32 - static DEFINE_SPINLOCK(limit_lock); 33 - 34 - /* Rusty: This is my (non-mathematically-inclined) understanding of 35 - this algorithm. The `average rate' in jiffies becomes your initial 36 - amount of credit `credit' and the most credit you can ever have 37 - `credit_cap'. The `peak rate' becomes the cost of passing the 38 - test, `cost'. 39 - 40 - `prev' tracks the last packet hit: you gain one credit per jiffy. 41 - If you get credit balance more than this, the extra credit is 42 - discarded. Every time the match passes, you lose `cost' credits; 43 - if you don't have that many, the test fails. 44 - 45 - See Alexey's formal explanation in net/sched/sch_tbf.c. 46 - 47 - To avoid underflow, we multiply by 128 (ie. you get 128 credits per 48 - jiffy). Hence a cost of 2^32-1, means one pass per 32768 seconds 49 - at 1024HZ (or one every 9 hours). A cost of 1 means 12800 passes 50 - per second at 100HZ. */ 51 - 52 - #define CREDITS_PER_JIFFY 128 53 - 54 - static int 55 - ip6t_limit_match(const struct sk_buff *skb, 56 - const struct net_device *in, 57 - const struct net_device *out, 58 - const void *matchinfo, 59 - int offset, 60 - unsigned int protoff, 61 - int *hotdrop) 62 - { 63 - struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master; 64 - unsigned long now = jiffies; 65 - 66 - spin_lock_bh(&limit_lock); 67 - r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; 68 - if (r->credit > r->credit_cap) 69 - r->credit = r->credit_cap; 70 - 71 - if (r->credit >= r->cost) { 72 - /* We're not limited. */ 73 - r->credit -= r->cost; 74 - spin_unlock_bh(&limit_lock); 75 - return 1; 76 - } 77 - 78 - spin_unlock_bh(&limit_lock); 79 - return 0; 80 - } 81 - 82 - /* Precision saver. */ 83 - static u_int32_t 84 - user2credits(u_int32_t user) 85 - { 86 - /* If multiplying would overflow... */ 87 - if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 88 - /* Divide first. */ 89 - return (user / IP6T_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 90 - 91 - return (user * HZ * CREDITS_PER_JIFFY) / IP6T_LIMIT_SCALE; 92 - } 93 - 94 - static int 95 - ip6t_limit_checkentry(const char *tablename, 96 - const struct ip6t_ip6 *ip, 97 - void *matchinfo, 98 - unsigned int matchsize, 99 - unsigned int hook_mask) 100 - { 101 - struct ip6t_rateinfo *r = matchinfo; 102 - 103 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rateinfo))) 104 - return 0; 105 - 106 - /* Check for overflow. */ 107 - if (r->burst == 0 108 - || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 109 - printk("Call rusty: overflow in ip6t_limit: %u/%u\n", 110 - r->avg, r->burst); 111 - return 0; 112 - } 113 - 114 - /* User avg in seconds * IP6T_LIMIT_SCALE: convert to jiffies * 115 - 128. */ 116 - r->prev = jiffies; 117 - r->credit = user2credits(r->avg * r->burst); /* Credits full. */ 118 - r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 119 - r->cost = user2credits(r->avg); 120 - 121 - /* For SMP, we only want to use one set of counters. */ 122 - r->master = r; 123 - 124 - return 1; 125 - } 126 - 127 - static struct ip6t_match ip6t_limit_reg = { 128 - .name = "limit", 129 - .match = ip6t_limit_match, 130 - .checkentry = ip6t_limit_checkentry, 131 - .me = THIS_MODULE, 132 - }; 133 - 134 - static int __init init(void) 135 - { 136 - if (ip6t_register_match(&ip6t_limit_reg)) 137 - return -EINVAL; 138 - return 0; 139 - } 140 - 141 - static void __exit fini(void) 142 - { 143 - ip6t_unregister_match(&ip6t_limit_reg); 144 - } 145 - 146 - module_init(init); 147 - module_exit(fini);
···
-81
net/ipv6/netfilter/ip6t_mac.c
··· 1 - /* Kernel module to match MAC address parameters. */ 2 - 3 - /* (C) 1999-2001 Paul `Rusty' Russell 4 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/if_ether.h> 14 - #include <linux/etherdevice.h> 15 - 16 - #include <linux/netfilter_ipv6/ip6t_mac.h> 17 - #include <linux/netfilter_ipv6/ip6_tables.h> 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_DESCRIPTION("MAC address matching module for IPv6"); 21 - MODULE_AUTHOR("Netfilter Core Teaam <coreteam@netfilter.org>"); 22 - 23 - static int 24 - match(const struct sk_buff *skb, 25 - const struct net_device *in, 26 - const struct net_device *out, 27 - const void *matchinfo, 28 - int offset, 29 - unsigned int protoff, 30 - int *hotdrop) 31 - { 32 - const struct ip6t_mac_info *info = matchinfo; 33 - 34 - /* Is mac pointer valid? */ 35 - return (skb->mac.raw >= skb->head 36 - && (skb->mac.raw + ETH_HLEN) <= skb->data 37 - /* If so, compare... */ 38 - && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 39 - ^ info->invert)); 40 - } 41 - 42 - static int 43 - ip6t_mac_checkentry(const char *tablename, 44 - const struct ip6t_ip6 *ip, 45 - void *matchinfo, 46 - unsigned int matchsize, 47 - unsigned int hook_mask) 48 - { 49 - if (hook_mask 50 - & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) 51 - | (1 << NF_IP6_FORWARD))) { 52 - printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or" 53 - " FORWARD\n"); 54 - return 0; 55 - } 56 - 57 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info))) 58 - return 0; 59 - 60 - return 1; 61 - } 62 - 63 - static struct ip6t_match mac_match = { 64 - .name = "mac", 65 - .match = &match, 66 - .checkentry = &ip6t_mac_checkentry, 67 - .me = THIS_MODULE, 68 - }; 69 - 70 - static int __init init(void) 71 - { 72 - return ip6t_register_match(&mac_match); 73 - } 74 - 75 - static void __exit fini(void) 76 - { 77 - ip6t_unregister_match(&mac_match); 78 - } 79 - 80 - module_init(init); 81 - module_exit(fini);
···
-66
net/ipv6/netfilter/ip6t_mark.c
··· 1 - /* Kernel module to match NFMARK values. */ 2 - 3 - /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License version 2 as 7 - * published by the Free Software Foundation. 8 - */ 9 - 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - 14 - #include <linux/netfilter_ipv6/ip6t_mark.h> 15 - #include <linux/netfilter_ipv6/ip6_tables.h> 16 - 17 - MODULE_LICENSE("GPL"); 18 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 19 - MODULE_DESCRIPTION("ip6tables mark match"); 20 - 21 - static int 22 - match(const struct sk_buff *skb, 23 - const struct net_device *in, 24 - const struct net_device *out, 25 - const void *matchinfo, 26 - int offset, 27 - unsigned int protoff, 28 - int *hotdrop) 29 - { 30 - const struct ip6t_mark_info *info = matchinfo; 31 - 32 - return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 33 - } 34 - 35 - static int 36 - checkentry(const char *tablename, 37 - const struct ip6t_ip6 *ip, 38 - void *matchinfo, 39 - unsigned int matchsize, 40 - unsigned int hook_mask) 41 - { 42 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info))) 43 - return 0; 44 - 45 - return 1; 46 - } 47 - 48 - static struct ip6t_match mark_match = { 49 - .name = "mark", 50 - .match = &match, 51 - .checkentry = &checkentry, 52 - .me = THIS_MODULE, 53 - }; 54 - 55 - static int __init init(void) 56 - { 57 - return ip6t_register_match(&mark_match); 58 - } 59 - 60 - static void __exit fini(void) 61 - { 62 - ip6t_unregister_match(&mark_match); 63 - } 64 - 65 - module_init(init); 66 - module_exit(fini);
···
+2 -1
net/ipv6/netfilter/ip6t_multiport.c
··· 84 /* Called when user tries to insert an entry of this type. */ 85 static int 86 checkentry(const char *tablename, 87 - const struct ip6t_ip6 *ip, 88 void *matchinfo, 89 unsigned int matchsize, 90 unsigned int hook_mask) 91 { 92 const struct ip6t_multiport *multiinfo = matchinfo; 93 94 if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport)))
··· 84 /* Called when user tries to insert an entry of this type. */ 85 static int 86 checkentry(const char *tablename, 87 + const void *info, 88 void *matchinfo, 89 unsigned int matchsize, 90 unsigned int hook_mask) 91 { 92 + const struct ip6t_ip6 *ip = info; 93 const struct ip6t_multiport *multiinfo = matchinfo; 94 95 if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport)))
+1 -1
net/ipv6/netfilter/ip6t_owner.c
··· 53 54 static int 55 checkentry(const char *tablename, 56 - const struct ip6t_ip6 *ip, 57 void *matchinfo, 58 unsigned int matchsize, 59 unsigned int hook_mask)
··· 53 54 static int 55 checkentry(const char *tablename, 56 + const void *ip, 57 void *matchinfo, 58 unsigned int matchsize, 59 unsigned int hook_mask)
-135
net/ipv6/netfilter/ip6t_physdev.c
··· 1 - /* Kernel module to match the bridge port in and 2 - * out device for IP packets coming into contact with a bridge. */ 3 - 4 - /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License version 2 as 8 - * published by the Free Software Foundation. 9 - */ 10 - 11 - #include <linux/module.h> 12 - #include <linux/skbuff.h> 13 - #include <linux/netfilter_ipv6/ip6t_physdev.h> 14 - #include <linux/netfilter_ipv6/ip6_tables.h> 15 - #include <linux/netfilter_bridge.h> 16 - #define MATCH 1 17 - #define NOMATCH 0 18 - 19 - MODULE_LICENSE("GPL"); 20 - MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 21 - MODULE_DESCRIPTION("iptables bridge physical device match module"); 22 - 23 - static int 24 - match(const struct sk_buff *skb, 25 - const struct net_device *in, 26 - const struct net_device *out, 27 - const void *matchinfo, 28 - int offset, 29 - unsigned int protoff, 30 - int *hotdrop) 31 - { 32 - int i; 33 - static const char nulldevname[IFNAMSIZ]; 34 - const struct ip6t_physdev_info *info = matchinfo; 35 - unsigned int ret; 36 - const char *indev, *outdev; 37 - struct nf_bridge_info *nf_bridge; 38 - 39 - /* Not a bridged IP packet or no info available yet: 40 - * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 41 - * the destination device will be a bridge. */ 42 - if (!(nf_bridge = skb->nf_bridge)) { 43 - /* Return MATCH if the invert flags of the used options are on */ 44 - if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && 45 - !(info->invert & IP6T_PHYSDEV_OP_BRIDGED)) 46 - return NOMATCH; 47 - if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN) && 48 - !(info->invert & IP6T_PHYSDEV_OP_ISIN)) 49 - return NOMATCH; 50 - if ((info->bitmask & IP6T_PHYSDEV_OP_ISOUT) && 51 - !(info->invert & IP6T_PHYSDEV_OP_ISOUT)) 52 - return NOMATCH; 53 - if ((info->bitmask & IP6T_PHYSDEV_OP_IN) && 54 - !(info->invert & IP6T_PHYSDEV_OP_IN)) 55 - return NOMATCH; 56 - if ((info->bitmask & IP6T_PHYSDEV_OP_OUT) && 57 - !(info->invert & IP6T_PHYSDEV_OP_OUT)) 58 - return NOMATCH; 59 - return MATCH; 60 - } 61 - 62 - /* This only makes sense in the FORWARD and POSTROUTING chains */ 63 - if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && 64 - (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 65 - !(info->invert & IP6T_PHYSDEV_OP_BRIDGED))) 66 - return NOMATCH; 67 - 68 - if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN && 69 - (!nf_bridge->physindev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISIN))) || 70 - (info->bitmask & IP6T_PHYSDEV_OP_ISOUT && 71 - (!nf_bridge->physoutdev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISOUT)))) 72 - return NOMATCH; 73 - 74 - if (!(info->bitmask & IP6T_PHYSDEV_OP_IN)) 75 - goto match_outdev; 76 - indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 77 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 78 - ret |= (((const unsigned int *)indev)[i] 79 - ^ ((const unsigned int *)info->physindev)[i]) 80 - & ((const unsigned int *)info->in_mask)[i]; 81 - } 82 - 83 - if ((ret == 0) ^ !(info->invert & IP6T_PHYSDEV_OP_IN)) 84 - return NOMATCH; 85 - 86 - match_outdev: 87 - if (!(info->bitmask & IP6T_PHYSDEV_OP_OUT)) 88 - return MATCH; 89 - outdev = nf_bridge->physoutdev ? 90 - nf_bridge->physoutdev->name : nulldevname; 91 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 92 - ret |= (((const unsigned int *)outdev)[i] 93 - ^ ((const unsigned int *)info->physoutdev)[i]) 94 - & ((const unsigned int *)info->out_mask)[i]; 95 - } 96 - 97 - return (ret != 0) ^ !(info->invert & IP6T_PHYSDEV_OP_OUT); 98 - } 99 - 100 - static int 101 - checkentry(const char *tablename, 102 - const struct ip6t_ip6 *ip, 103 - void *matchinfo, 104 - unsigned int matchsize, 105 - unsigned int hook_mask) 106 - { 107 - const struct ip6t_physdev_info *info = matchinfo; 108 - 109 - if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_physdev_info))) 110 - return 0; 111 - if (!(info->bitmask & IP6T_PHYSDEV_OP_MASK) || 112 - info->bitmask & ~IP6T_PHYSDEV_OP_MASK) 113 - return 0; 114 - return 1; 115 - } 116 - 117 - static struct ip6t_match physdev_match = { 118 - .name = "physdev", 119 - .match = &match, 120 - .checkentry = &checkentry, 121 - .me = THIS_MODULE, 122 - }; 123 - 124 - static int __init init(void) 125 - { 126 - return ip6t_register_match(&physdev_match); 127 - } 128 - 129 - static void __exit fini(void) 130 - { 131 - ip6t_unregister_match(&physdev_match); 132 - } 133 - 134 - module_init(init); 135 - module_exit(fini);
···
+1 -1
net/ipv6/netfilter/ip6t_rt.c
··· 183 /* Called when user tries to insert an entry of this type. */ 184 static int 185 checkentry(const char *tablename, 186 - const struct ip6t_ip6 *ip, 187 void *matchinfo, 188 unsigned int matchinfosize, 189 unsigned int hook_mask)
··· 183 /* Called when user tries to insert an entry of this type. */ 184 static int 185 checkentry(const char *tablename, 186 + const void *entry, 187 void *matchinfo, 188 unsigned int matchinfosize, 189 unsigned int hook_mask)
+1
net/ipv6/netfilter/ip6table_filter.c
··· 97 .valid_hooks = FILTER_VALID_HOOKS, 98 .lock = RW_LOCK_UNLOCKED, 99 .me = THIS_MODULE, 100 }; 101 102 /* The work comes in here from netfilter.c. */
··· 97 .valid_hooks = FILTER_VALID_HOOKS, 98 .lock = RW_LOCK_UNLOCKED, 99 .me = THIS_MODULE, 100 + .af = AF_INET6, 101 }; 102 103 /* The work comes in here from netfilter.c. */
+1
net/ipv6/netfilter/ip6table_mangle.c
··· 127 .valid_hooks = MANGLE_VALID_HOOKS, 128 .lock = RW_LOCK_UNLOCKED, 129 .me = THIS_MODULE, 130 }; 131 132 /* The work comes in here from netfilter.c. */
··· 127 .valid_hooks = MANGLE_VALID_HOOKS, 128 .lock = RW_LOCK_UNLOCKED, 129 .me = THIS_MODULE, 130 + .af = AF_INET6, 131 }; 132 133 /* The work comes in here from netfilter.c. */
+3 -2
net/ipv6/netfilter/ip6table_raw.c
··· 106 } 107 }; 108 109 - static struct ip6t_table packet_raw = { 110 .name = "raw", 111 .valid_hooks = RAW_VALID_HOOKS, 112 .lock = RW_LOCK_UNLOCKED, 113 - .me = THIS_MODULE 114 }; 115 116 /* The work comes in here from netfilter.c. */
··· 106 } 107 }; 108 109 + static struct xt_table packet_raw = { 110 .name = "raw", 111 .valid_hooks = RAW_VALID_HOOKS, 112 .lock = RW_LOCK_UNLOCKED, 113 + .me = THIS_MODULE, 114 + .af = AF_INET6, 115 }; 116 117 /* The work comes in here from netfilter.c. */
+1 -7
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
··· 584 585 static int __init init(void) 586 { 587 - need_nf_conntrack(); 588 return init_or_cleanup(1); 589 } 590 ··· 595 596 module_init(init); 597 module_exit(fini); 598 - 599 - void need_ip6_conntrack(void) 600 - { 601 - } 602 - 603 - EXPORT_SYMBOL(need_ip6_conntrack);
··· 584 585 static int __init init(void) 586 { 587 + need_conntrack(); 588 return init_or_cleanup(1); 589 } 590 ··· 595 596 module_init(init); 597 module_exit(fini);
+16 -29
net/ipv6/netfilter/nf_conntrack_reasm.c
··· 70 71 struct nf_ct_frag6_queue 72 { 73 - struct nf_ct_frag6_queue *next; 74 - struct list_head lru_list; /* lru list member */ 75 76 __u32 id; /* fragment id */ 77 struct in6_addr saddr; ··· 90 #define FIRST_IN 2 91 #define LAST_IN 1 92 __u16 nhoffset; 93 - struct nf_ct_frag6_queue **pprev; 94 }; 95 96 /* Hash table. */ 97 98 #define FRAG6Q_HASHSZ 64 99 100 - static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ]; 101 static DEFINE_RWLOCK(nf_ct_frag6_lock); 102 static u32 nf_ct_frag6_hash_rnd; 103 static LIST_HEAD(nf_ct_frag6_lru_list); ··· 104 105 static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) 106 { 107 - if (fq->next) 108 - fq->next->pprev = fq->pprev; 109 - *fq->pprev = fq->next; 110 list_del(&fq->lru_list); 111 nf_ct_frag6_nqueues--; 112 } ··· 155 get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32)); 156 for (i = 0; i < FRAG6Q_HASHSZ; i++) { 157 struct nf_ct_frag6_queue *q; 158 159 - q = nf_ct_frag6_hash[i]; 160 - while (q) { 161 - struct nf_ct_frag6_queue *next = q->next; 162 unsigned int hval = ip6qhashfn(q->id, 163 &q->saddr, 164 &q->daddr); 165 - 166 if (hval != i) { 167 - /* Unlink. */ 168 - if (q->next) 169 - q->next->pprev = q->pprev; 170 - *q->pprev = q->next; 171 - 172 /* Relink to new hash chain. */ 173 - if ((q->next = nf_ct_frag6_hash[hval]) != NULL) 174 - q->next->pprev = &q->next; 175 - nf_ct_frag6_hash[hval] = q; 176 - q->pprev = &nf_ct_frag6_hash[hval]; 177 } 178 - 179 - q = next; 180 } 181 } 182 write_unlock(&nf_ct_frag6_lock); ··· 301 302 /* Creation primitives. */ 303 304 - 305 static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, 306 struct nf_ct_frag6_queue *fq_in) 307 { 308 struct nf_ct_frag6_queue *fq; 309 310 write_lock(&nf_ct_frag6_lock); 311 #ifdef CONFIG_SMP 312 - for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { 313 if (fq->id == fq_in->id && 314 !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) && 315 !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) { ··· 329 atomic_inc(&fq->refcnt); 330 331 atomic_inc(&fq->refcnt); 332 - if ((fq->next = nf_ct_frag6_hash[hash]) != NULL) 333 - fq->next->pprev = &fq->next; 334 - nf_ct_frag6_hash[hash] = fq; 335 - fq->pprev = &nf_ct_frag6_hash[hash]; 336 INIT_LIST_HEAD(&fq->lru_list); 337 list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list); 338 nf_ct_frag6_nqueues++; ··· 370 fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 371 { 372 struct nf_ct_frag6_queue *fq; 373 unsigned int hash = ip6qhashfn(id, src, dst); 374 375 read_lock(&nf_ct_frag6_lock); 376 - for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { 377 if (fq->id == id && 378 !ipv6_addr_cmp(src, &fq->saddr) && 379 !ipv6_addr_cmp(dst, &fq->daddr)) {
··· 70 71 struct nf_ct_frag6_queue 72 { 73 + struct hlist_node list; 74 + struct list_head lru_list; /* lru list member */ 75 76 __u32 id; /* fragment id */ 77 struct in6_addr saddr; ··· 90 #define FIRST_IN 2 91 #define LAST_IN 1 92 __u16 nhoffset; 93 }; 94 95 /* Hash table. */ 96 97 #define FRAG6Q_HASHSZ 64 98 99 + static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ]; 100 static DEFINE_RWLOCK(nf_ct_frag6_lock); 101 static u32 nf_ct_frag6_hash_rnd; 102 static LIST_HEAD(nf_ct_frag6_lru_list); ··· 105 106 static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) 107 { 108 + hlist_del(&fq->list); 109 list_del(&fq->lru_list); 110 nf_ct_frag6_nqueues--; 111 } ··· 158 get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32)); 159 for (i = 0; i < FRAG6Q_HASHSZ; i++) { 160 struct nf_ct_frag6_queue *q; 161 + struct hlist_node *p, *n; 162 163 + hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) { 164 unsigned int hval = ip6qhashfn(q->id, 165 &q->saddr, 166 &q->daddr); 167 if (hval != i) { 168 + hlist_del(&q->list); 169 /* Relink to new hash chain. */ 170 + hlist_add_head(&q->list, 171 + &nf_ct_frag6_hash[hval]); 172 } 173 } 174 } 175 write_unlock(&nf_ct_frag6_lock); ··· 314 315 /* Creation primitives. */ 316 317 static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, 318 struct nf_ct_frag6_queue *fq_in) 319 { 320 struct nf_ct_frag6_queue *fq; 321 + #ifdef CONFIG_SMP 322 + struct hlist_node *n; 323 + #endif 324 325 write_lock(&nf_ct_frag6_lock); 326 #ifdef CONFIG_SMP 327 + hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { 328 if (fq->id == fq_in->id && 329 !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) && 330 !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) { ··· 340 atomic_inc(&fq->refcnt); 341 342 atomic_inc(&fq->refcnt); 343 + hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]); 344 INIT_LIST_HEAD(&fq->lru_list); 345 list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list); 346 nf_ct_frag6_nqueues++; ··· 384 fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 385 { 386 struct nf_ct_frag6_queue *fq; 387 + struct hlist_node *n; 388 unsigned int hash = ip6qhashfn(id, src, dst); 389 390 read_lock(&nf_ct_frag6_lock); 391 + hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { 392 if (fq->id == id && 393 !ipv6_addr_cmp(src, &fq->saddr) && 394 !ipv6_addr_cmp(dst, &fq->daddr)) {
+258
net/netfilter/Kconfig
··· 103 This option enables support for a netlink-based userspace interface 104 105 endmenu
··· 103 This option enables support for a netlink-based userspace interface 104 105 endmenu 106 + 107 + config NETFILTER_XTABLES 108 + tristate "Netfilter Xtables support (required for ip_tables)" 109 + help 110 + This is required if you intend to use any of ip_tables, 111 + ip6_tables or arp_tables. 112 + 113 + # alphabetically ordered list of targets 114 + 115 + config NETFILTER_XT_TARGET_CLASSIFY 116 + tristate '"CLASSIFY" target support' 117 + depends on NETFILTER_XTABLES 118 + help 119 + This option adds a `CLASSIFY' target, which enables the user to set 120 + the priority of a packet. Some qdiscs can use this value for 121 + classification, among these are: 122 + 123 + atm, cbq, dsmark, pfifo_fast, htb, prio 124 + 125 + To compile it as a module, choose M here. If unsure, say N. 126 + 127 + config NETFILTER_XT_TARGET_CONNMARK 128 + tristate '"CONNMARK" target support' 129 + depends on NETFILTER_XTABLES 130 + depends on IP_NF_MANGLE || IP6_NF_MANGLE 131 + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 132 + help 133 + This option adds a `CONNMARK' target, which allows one to manipulate 134 + the connection mark value. Similar to the MARK target, but 135 + affects the connection mark value rather than the packet mark value. 136 + 137 + If you want to compile it as a module, say M here and read 138 + <file:Documentation/modules.txt>. The module will be called 139 + ipt_CONNMARK.o. If unsure, say `N'. 140 + 141 + config NETFILTER_XT_TARGET_MARK 142 + tristate '"MARK" target support' 143 + depends on NETFILTER_XTABLES 144 + help 145 + This option adds a `MARK' target, which allows you to create rules 146 + in the `mangle' table which alter the netfilter mark (nfmark) field 147 + associated with the packet prior to routing. This can change 148 + the routing method (see `Use netfilter MARK value as routing 149 + key') and can also be used by other subsystems to change their 150 + behavior. 151 + 152 + To compile it as a module, choose M here. If unsure, say N. 153 + 154 + config NETFILTER_XT_TARGET_NFQUEUE 155 + tristate '"NFQUEUE" target Support' 156 + depends on NETFILTER_XTABLES 157 + help 158 + This Target replaced the old obsolete QUEUE target. 159 + 160 + As opposed to QUEUE, it supports 65535 different queues, 161 + not just one. 162 + 163 + To compile it as a module, choose M here. If unsure, say N. 164 + 165 + config NETFILTER_XT_TARGET_NOTRACK 166 + tristate '"NOTRACK" target support' 167 + depends on NETFILTER_XTABLES 168 + depends on IP_NF_RAW || IP6_NF_RAW 169 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 170 + help 171 + The NOTRACK target allows a select rule to specify 172 + which packets *not* to enter the conntrack/NAT 173 + subsystem with all the consequences (no ICMP error tracking, 174 + no protocol helpers for the selected packets). 175 + 176 + If you want to compile it as a module, say M here and read 177 + <file:Documentation/modules.txt>. If unsure, say `N'. 178 + 179 + config NETFILTER_XT_MATCH_COMMENT 180 + tristate '"comment" match support' 181 + depends on NETFILTER_XTABLES 182 + help 183 + This option adds a `comment' dummy-match, which allows you to put 184 + comments in your iptables ruleset. 185 + 186 + If you want to compile it as a module, say M here and read 187 + <file:Documentation/modules.txt>. If unsure, say `N'. 188 + 189 + config NETFILTER_XT_MATCH_CONNBYTES 190 + tristate '"connbytes" per-connection counter match support' 191 + depends on NETFILTER_XTABLES 192 + depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT 193 + help 194 + This option adds a `connbytes' match, which allows you to match the 195 + number of bytes and/or packets for each direction within a connection. 196 + 197 + If you want to compile it as a module, say M here and read 198 + <file:Documentation/modules.txt>. If unsure, say `N'. 199 + 200 + config NETFILTER_XT_MATCH_CONNMARK 201 + tristate '"connmark" connection mark match support' 202 + depends on NETFILTER_XTABLES 203 + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK 204 + help 205 + This option adds a `connmark' match, which allows you to match the 206 + connection mark value previously set for the session by `CONNMARK'. 207 + 208 + If you want to compile it as a module, say M here and read 209 + <file:Documentation/modules.txt>. The module will be called 210 + ipt_connmark.o. If unsure, say `N'. 211 + 212 + config NETFILTER_XT_MATCH_CONNTRACK 213 + tristate '"conntrack" connection tracking match support' 214 + depends on NETFILTER_XTABLES 215 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 216 + help 217 + This is a general conntrack match module, a superset of the state match. 218 + 219 + It allows matching on additional conntrack information, which is 220 + useful in complex configurations, such as NAT gateways with multiple 221 + internet links or tunnels. 222 + 223 + To compile it as a module, choose M here. If unsure, say N. 224 + 225 + config NETFILTER_XT_MATCH_DCCP 226 + tristate '"DCCP" protocol match support' 227 + depends on NETFILTER_XTABLES 228 + help 229 + With this option enabled, you will be able to use the iptables 230 + `dccp' match in order to match on DCCP source/destination ports 231 + and DCCP flags. 232 + 233 + If you want to compile it as a module, say M here and read 234 + <file:Documentation/modules.txt>. If unsure, say `N'. 235 + 236 + config NETFILTER_XT_MATCH_HELPER 237 + tristate '"helper" match support' 238 + depends on NETFILTER_XTABLES 239 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 240 + help 241 + Helper matching allows you to match packets in dynamic connections 242 + tracked by a conntrack-helper, ie. ip_conntrack_ftp 243 + 244 + To compile it as a module, choose M here. If unsure, say Y. 245 + 246 + config NETFILTER_XT_MATCH_LENGTH 247 + tristate '"length" match support' 248 + depends on NETFILTER_XTABLES 249 + help 250 + This option allows you to match the length of a packet against a 251 + specific value or range of values. 252 + 253 + To compile it as a module, choose M here. If unsure, say N. 254 + 255 + config NETFILTER_XT_MATCH_LIMIT 256 + tristate '"limit" match support' 257 + depends on NETFILTER_XTABLES 258 + help 259 + limit matching allows you to control the rate at which a rule can be 260 + matched: mainly useful in combination with the LOG target ("LOG 261 + target support", below) and to avoid some Denial of Service attacks. 262 + 263 + To compile it as a module, choose M here. If unsure, say N. 264 + 265 + config NETFILTER_XT_MATCH_MAC 266 + tristate '"mac" address match support' 267 + depends on NETFILTER_XTABLES 268 + help 269 + MAC matching allows you to match packets based on the source 270 + Ethernet address of the packet. 271 + 272 + To compile it as a module, choose M here. If unsure, say N. 273 + 274 + config NETFILTER_XT_MATCH_MARK 275 + tristate '"mark" match support' 276 + depends on NETFILTER_XTABLES 277 + help 278 + Netfilter mark matching allows you to match packets based on the 279 + `nfmark' value in the packet. This can be set by the MARK target 280 + (see below). 281 + 282 + To compile it as a module, choose M here. If unsure, say N. 283 + 284 + config NETFILTER_XT_MATCH_PHYSDEV 285 + tristate '"physdev" match support' 286 + depends on NETFILTER_XTABLES && BRIDGE_NETFILTER 287 + help 288 + Physdev packet matching matches against the physical bridge ports 289 + the IP packet arrived on or will leave by. 290 + 291 + To compile it as a module, choose M here. If unsure, say N. 292 + 293 + config NETFILTER_XT_MATCH_PKTTYPE 294 + tristate '"pkttype" packet type match support' 295 + depends on NETFILTER_XTABLES 296 + help 297 + Packet type matching allows you to match a packet by 298 + its "class", eg. BROADCAST, MULTICAST, ... 299 + 300 + Typical usage: 301 + iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG 302 + 303 + To compile it as a module, choose M here. If unsure, say N. 304 + 305 + config NETFILTER_XT_MATCH_REALM 306 + tristate '"realm" match support' 307 + depends on NETFILTER_XTABLES 308 + select NET_CLS_ROUTE 309 + help 310 + This option adds a `realm' match, which allows you to use the realm 311 + key from the routing subsystem inside iptables. 312 + 313 + This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 314 + in tc world. 315 + 316 + If you want to compile it as a module, say M here and read 317 + <file:Documentation/modules.txt>. If unsure, say `N'. 318 + 319 + config NETFILTER_XT_MATCH_SCTP 320 + tristate '"sctp" protocol match support' 321 + depends on NETFILTER_XTABLES 322 + help 323 + With this option enabled, you will be able to use the 324 + `sctp' match in order to match on SCTP source/destination ports 325 + and SCTP chunk types. 326 + 327 + If you want to compile it as a module, say M here and read 328 + <file:Documentation/modules.txt>. If unsure, say `N'. 329 + 330 + config NETFILTER_XT_MATCH_STATE 331 + tristate '"state" match support' 332 + depends on NETFILTER_XTABLES 333 + depends on IP_NF_CONNTRACK || NF_CONNTRACK 334 + help 335 + Connection state matching allows you to match packets based on their 336 + relationship to a tracked connection (ie. previous packets). This 337 + is a powerful tool for packet classification. 338 + 339 + To compile it as a module, choose M here. If unsure, say N. 340 + 341 + config NETFILTER_XT_MATCH_STRING 342 + tristate '"string" match support' 343 + depends on NETFILTER_XTABLES 344 + select TEXTSEARCH 345 + select TEXTSEARCH_KMP 346 + select TEXTSEARCH_BM 347 + select TEXTSEARCH_FSM 348 + help 349 + This option adds a `string' match, which allows you to look for 350 + pattern matchings in packets. 351 + 352 + To compile it as a module, choose M here. If unsure, say N. 353 + 354 + config NETFILTER_XT_MATCH_TCPMSS 355 + tristate '"tcpmss" match support' 356 + depends on NETFILTER_XTABLES 357 + help 358 + This option adds a `tcpmss' match, which allows you to examine the 359 + MSS value of TCP SYN packets, which control the maximum packet size 360 + for that connection. 361 + 362 + To compile it as a module, choose M here. If unsure, say N. 363 +
+34 -3
net/netfilter/Makefile
··· 1 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o 2 3 obj-$(CONFIG_NETFILTER) = netfilter.o 4 ··· 7 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 8 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o 9 10 - nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o 11 - 12 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o 13 - obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o 14 15 # SCTP protocol connection tracking 16 obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o 17 18 # netlink interface for nf_conntrack 19 obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
··· 1 netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o 2 + nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o 3 4 obj-$(CONFIG_NETFILTER) = netfilter.o 5 ··· 6 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 7 obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o 8 9 + # connection tracking 10 obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o 11 12 # SCTP protocol connection tracking 13 obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o 14 15 # netlink interface for nf_conntrack 16 obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o 17 + 18 + # connection tracking helpers 19 + obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o 20 + 21 + # generic X tables 22 + obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 23 + 24 + # targets 25 + obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o 26 + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o 27 + obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o 28 + obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 29 + obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 30 + 31 + # matches 32 + obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o 33 + obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o 34 + obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o 35 + obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o 36 + obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o 37 + obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o 38 + obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o 39 + obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o 40 + obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o 41 + obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o 42 + obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o 43 + obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o 44 + obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o 45 + obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o 46 + obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o 47 + obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o 48 + obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
+2 -2
net/netfilter/nf_conntrack_standalone.c
··· 821 822 /* Some modules need us, but don't depend directly on any symbol. 823 They should call this. */ 824 - void need_nf_conntrack(void) 825 { 826 } 827 ··· 841 EXPORT_SYMBOL(nf_ct_invert_tuplepr); 842 EXPORT_SYMBOL(nf_conntrack_alter_reply); 843 EXPORT_SYMBOL(nf_conntrack_destroyed); 844 - EXPORT_SYMBOL(need_nf_conntrack); 845 EXPORT_SYMBOL(nf_conntrack_helper_register); 846 EXPORT_SYMBOL(nf_conntrack_helper_unregister); 847 EXPORT_SYMBOL(nf_ct_iterate_cleanup);
··· 821 822 /* Some modules need us, but don't depend directly on any symbol. 823 They should call this. */ 824 + void need_conntrack(void) 825 { 826 } 827 ··· 841 EXPORT_SYMBOL(nf_ct_invert_tuplepr); 842 EXPORT_SYMBOL(nf_conntrack_alter_reply); 843 EXPORT_SYMBOL(nf_conntrack_destroyed); 844 + EXPORT_SYMBOL(need_conntrack); 845 EXPORT_SYMBOL(nf_conntrack_helper_register); 846 EXPORT_SYMBOL(nf_conntrack_helper_unregister); 847 EXPORT_SYMBOL(nf_ct_iterate_cleanup);
+624
net/netfilter/x_tables.c
···
··· 1 + /* 2 + * x_tables core - Backend for {ip,ip6,arp}_tables 3 + * 4 + * Copyright (C) 2006-2006 Harald Welte <laforge@netfilter.org> 5 + * 6 + * Based on existing ip_tables code which is 7 + * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling 8 + * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + */ 15 + 16 + #include <linux/config.h> 17 + #include <linux/kernel.h> 18 + #include <linux/socket.h> 19 + #include <linux/net.h> 20 + #include <linux/proc_fs.h> 21 + #include <linux/seq_file.h> 22 + #include <linux/string.h> 23 + #include <linux/vmalloc.h> 24 + 25 + #include <linux/netfilter/x_tables.h> 26 + #include <linux/netfilter_arp.h> 27 + 28 + MODULE_LICENSE("GPL"); 29 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 30 + MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); 31 + 32 + #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 33 + 34 + struct xt_af { 35 + struct semaphore mutex; 36 + struct list_head match; 37 + struct list_head target; 38 + struct list_head tables; 39 + }; 40 + 41 + static struct xt_af *xt; 42 + 43 + #ifdef DEBUG_IP_FIREWALL_USER 44 + #define duprintf(format, args...) printk(format , ## args) 45 + #else 46 + #define duprintf(format, args...) 47 + #endif 48 + 49 + enum { 50 + TABLE, 51 + TARGET, 52 + MATCH, 53 + }; 54 + 55 + /* Registration hooks for targets. */ 56 + int 57 + xt_register_target(int af, struct xt_target *target) 58 + { 59 + int ret; 60 + 61 + ret = down_interruptible(&xt[af].mutex); 62 + if (ret != 0) 63 + return ret; 64 + list_add(&target->list, &xt[af].target); 65 + up(&xt[af].mutex); 66 + return ret; 67 + } 68 + EXPORT_SYMBOL(xt_register_target); 69 + 70 + void 71 + xt_unregister_target(int af, struct xt_target *target) 72 + { 73 + down(&xt[af].mutex); 74 + LIST_DELETE(&xt[af].target, target); 75 + up(&xt[af].mutex); 76 + } 77 + EXPORT_SYMBOL(xt_unregister_target); 78 + 79 + int 80 + xt_register_match(int af, struct xt_match *match) 81 + { 82 + int ret; 83 + 84 + ret = down_interruptible(&xt[af].mutex); 85 + if (ret != 0) 86 + return ret; 87 + 88 + list_add(&match->list, &xt[af].match); 89 + up(&xt[af].mutex); 90 + 91 + return ret; 92 + } 93 + EXPORT_SYMBOL(xt_register_match); 94 + 95 + void 96 + xt_unregister_match(int af, struct xt_match *match) 97 + { 98 + down(&xt[af].mutex); 99 + LIST_DELETE(&xt[af].match, match); 100 + up(&xt[af].mutex); 101 + } 102 + EXPORT_SYMBOL(xt_unregister_match); 103 + 104 + 105 + /* 106 + * These are weird, but module loading must not be done with mutex 107 + * held (since they will register), and we have to have a single 108 + * function to use try_then_request_module(). 109 + */ 110 + 111 + /* Find match, grabs ref. Returns ERR_PTR() on error. */ 112 + struct xt_match *xt_find_match(int af, const char *name, u8 revision) 113 + { 114 + struct xt_match *m; 115 + int err = 0; 116 + 117 + if (down_interruptible(&xt[af].mutex) != 0) 118 + return ERR_PTR(-EINTR); 119 + 120 + list_for_each_entry(m, &xt[af].match, list) { 121 + if (strcmp(m->name, name) == 0) { 122 + if (m->revision == revision) { 123 + if (try_module_get(m->me)) { 124 + up(&xt[af].mutex); 125 + return m; 126 + } 127 + } else 128 + err = -EPROTOTYPE; /* Found something. */ 129 + } 130 + } 131 + up(&xt[af].mutex); 132 + return ERR_PTR(err); 133 + } 134 + EXPORT_SYMBOL(xt_find_match); 135 + 136 + /* Find target, grabs ref. Returns ERR_PTR() on error. */ 137 + struct xt_target *xt_find_target(int af, const char *name, u8 revision) 138 + { 139 + struct xt_target *t; 140 + int err = 0; 141 + 142 + if (down_interruptible(&xt[af].mutex) != 0) 143 + return ERR_PTR(-EINTR); 144 + 145 + list_for_each_entry(t, &xt[af].target, list) { 146 + if (strcmp(t->name, name) == 0) { 147 + if (t->revision == revision) { 148 + if (try_module_get(t->me)) { 149 + up(&xt[af].mutex); 150 + return t; 151 + } 152 + } else 153 + err = -EPROTOTYPE; /* Found something. */ 154 + } 155 + } 156 + up(&xt[af].mutex); 157 + return ERR_PTR(err); 158 + } 159 + EXPORT_SYMBOL(xt_find_target); 160 + 161 + static const char *xt_prefix[NPROTO] = { 162 + [AF_INET] = "ipt_%s", 163 + [AF_INET6] = "ip6t_%s", 164 + [NF_ARP] = "arpt_%s", 165 + }; 166 + 167 + struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) 168 + { 169 + struct xt_target *target; 170 + 171 + target = try_then_request_module(xt_find_target(af, name, revision), 172 + xt_prefix[af], name); 173 + if (IS_ERR(target) || !target) 174 + return NULL; 175 + return target; 176 + } 177 + EXPORT_SYMBOL_GPL(xt_request_find_target); 178 + 179 + static int match_revfn(int af, const char *name, u8 revision, int *bestp) 180 + { 181 + struct xt_match *m; 182 + int have_rev = 0; 183 + 184 + list_for_each_entry(m, &xt[af].match, list) { 185 + if (strcmp(m->name, name) == 0) { 186 + if (m->revision > *bestp) 187 + *bestp = m->revision; 188 + if (m->revision == revision) 189 + have_rev = 1; 190 + } 191 + } 192 + return have_rev; 193 + } 194 + 195 + static int target_revfn(int af, const char *name, u8 revision, int *bestp) 196 + { 197 + struct xt_target *t; 198 + int have_rev = 0; 199 + 200 + list_for_each_entry(t, &xt[af].target, list) { 201 + if (strcmp(t->name, name) == 0) { 202 + if (t->revision > *bestp) 203 + *bestp = t->revision; 204 + if (t->revision == revision) 205 + have_rev = 1; 206 + } 207 + } 208 + return have_rev; 209 + } 210 + 211 + /* Returns true or false (if no such extension at all) */ 212 + int xt_find_revision(int af, const char *name, u8 revision, int target, 213 + int *err) 214 + { 215 + int have_rev, best = -1; 216 + 217 + if (down_interruptible(&xt[af].mutex) != 0) { 218 + *err = -EINTR; 219 + return 1; 220 + } 221 + if (target == 1) 222 + have_rev = target_revfn(af, name, revision, &best); 223 + else 224 + have_rev = match_revfn(af, name, revision, &best); 225 + up(&xt[af].mutex); 226 + 227 + /* Nothing at all? Return 0 to try loading module. */ 228 + if (best == -1) { 229 + *err = -ENOENT; 230 + return 0; 231 + } 232 + 233 + *err = best; 234 + if (!have_rev) 235 + *err = -EPROTONOSUPPORT; 236 + return 1; 237 + } 238 + EXPORT_SYMBOL_GPL(xt_find_revision); 239 + 240 + struct xt_table_info *xt_alloc_table_info(unsigned int size) 241 + { 242 + struct xt_table_info *newinfo; 243 + int cpu; 244 + 245 + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ 246 + if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages) 247 + return NULL; 248 + 249 + newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL); 250 + if (!newinfo) 251 + return NULL; 252 + 253 + newinfo->size = size; 254 + 255 + for_each_cpu(cpu) { 256 + if (size <= PAGE_SIZE) 257 + newinfo->entries[cpu] = kmalloc_node(size, 258 + GFP_KERNEL, 259 + cpu_to_node(cpu)); 260 + else 261 + newinfo->entries[cpu] = vmalloc_node(size, 262 + cpu_to_node(cpu)); 263 + 264 + if (newinfo->entries[cpu] == NULL) { 265 + xt_free_table_info(newinfo); 266 + return NULL; 267 + } 268 + } 269 + 270 + return newinfo; 271 + } 272 + EXPORT_SYMBOL(xt_alloc_table_info); 273 + 274 + void xt_free_table_info(struct xt_table_info *info) 275 + { 276 + int cpu; 277 + 278 + for_each_cpu(cpu) { 279 + if (info->size <= PAGE_SIZE) 280 + kfree(info->entries[cpu]); 281 + else 282 + vfree(info->entries[cpu]); 283 + } 284 + kfree(info); 285 + } 286 + EXPORT_SYMBOL(xt_free_table_info); 287 + 288 + /* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 289 + struct xt_table *xt_find_table_lock(int af, const char *name) 290 + { 291 + struct xt_table *t; 292 + 293 + if (down_interruptible(&xt[af].mutex) != 0) 294 + return ERR_PTR(-EINTR); 295 + 296 + list_for_each_entry(t, &xt[af].tables, list) 297 + if (strcmp(t->name, name) == 0 && try_module_get(t->me)) 298 + return t; 299 + up(&xt[af].mutex); 300 + return NULL; 301 + } 302 + EXPORT_SYMBOL_GPL(xt_find_table_lock); 303 + 304 + void xt_table_unlock(struct xt_table *table) 305 + { 306 + up(&xt[table->af].mutex); 307 + } 308 + EXPORT_SYMBOL_GPL(xt_table_unlock); 309 + 310 + 311 + struct xt_table_info * 312 + xt_replace_table(struct xt_table *table, 313 + unsigned int num_counters, 314 + struct xt_table_info *newinfo, 315 + int *error) 316 + { 317 + struct xt_table_info *oldinfo, *private; 318 + 319 + /* Do the substitution. */ 320 + write_lock_bh(&table->lock); 321 + private = table->private; 322 + /* Check inside lock: is the old number correct? */ 323 + if (num_counters != private->number) { 324 + duprintf("num_counters != table->private->number (%u/%u)\n", 325 + num_counters, private->number); 326 + write_unlock_bh(&table->lock); 327 + *error = -EAGAIN; 328 + return NULL; 329 + } 330 + oldinfo = private; 331 + table->private = newinfo; 332 + newinfo->initial_entries = oldinfo->initial_entries; 333 + write_unlock_bh(&table->lock); 334 + 335 + return oldinfo; 336 + } 337 + EXPORT_SYMBOL_GPL(xt_replace_table); 338 + 339 + int xt_register_table(struct xt_table *table, 340 + struct xt_table_info *bootstrap, 341 + struct xt_table_info *newinfo) 342 + { 343 + int ret; 344 + struct xt_table_info *private; 345 + 346 + ret = down_interruptible(&xt[table->af].mutex); 347 + if (ret != 0) 348 + return ret; 349 + 350 + /* Don't autoload: we'd eat our tail... */ 351 + if (list_named_find(&xt[table->af].tables, table->name)) { 352 + ret = -EEXIST; 353 + goto unlock; 354 + } 355 + 356 + /* Simplifies replace_table code. */ 357 + table->private = bootstrap; 358 + if (!xt_replace_table(table, 0, newinfo, &ret)) 359 + goto unlock; 360 + 361 + private = table->private; 362 + duprintf("table->private->number = %u\n", private->number); 363 + 364 + /* save number of initial entries */ 365 + private->initial_entries = private->number; 366 + 367 + rwlock_init(&table->lock); 368 + list_prepend(&xt[table->af].tables, table); 369 + 370 + ret = 0; 371 + unlock: 372 + up(&xt[table->af].mutex); 373 + return ret; 374 + } 375 + EXPORT_SYMBOL_GPL(xt_register_table); 376 + 377 + void *xt_unregister_table(struct xt_table *table) 378 + { 379 + struct xt_table_info *private; 380 + 381 + down(&xt[table->af].mutex); 382 + private = table->private; 383 + LIST_DELETE(&xt[table->af].tables, table); 384 + up(&xt[table->af].mutex); 385 + 386 + return private; 387 + } 388 + EXPORT_SYMBOL_GPL(xt_unregister_table); 389 + 390 + #ifdef CONFIG_PROC_FS 391 + static char *xt_proto_prefix[NPROTO] = { 392 + [AF_INET] = "ip", 393 + [AF_INET6] = "ip6", 394 + [NF_ARP] = "arp", 395 + }; 396 + 397 + static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos) 398 + { 399 + struct list_head *head = list->next; 400 + 401 + if (!head || list_empty(list)) 402 + return NULL; 403 + 404 + while (pos && (head = head->next)) { 405 + if (head == list) 406 + return NULL; 407 + pos--; 408 + } 409 + return pos ? NULL : head; 410 + } 411 + 412 + static struct list_head *type2list(u_int16_t af, u_int16_t type) 413 + { 414 + struct list_head *list; 415 + 416 + switch (type) { 417 + case TARGET: 418 + list = &xt[af].target; 419 + break; 420 + case MATCH: 421 + list = &xt[af].match; 422 + break; 423 + case TABLE: 424 + list = &xt[af].tables; 425 + break; 426 + default: 427 + list = NULL; 428 + break; 429 + } 430 + 431 + return list; 432 + } 433 + 434 + static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos) 435 + { 436 + struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private; 437 + u_int16_t af = (unsigned long)pde->data & 0xffff; 438 + u_int16_t type = (unsigned long)pde->data >> 16; 439 + struct list_head *list; 440 + 441 + if (af >= NPROTO) 442 + return NULL; 443 + 444 + list = type2list(af, type); 445 + if (!list) 446 + return NULL; 447 + 448 + if (down_interruptible(&xt[af].mutex) != 0) 449 + return NULL; 450 + 451 + return xt_get_idx(list, seq, *pos); 452 + } 453 + 454 + static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos) 455 + { 456 + struct proc_dir_entry *pde = seq->private; 457 + u_int16_t af = (unsigned long)pde->data & 0xffff; 458 + u_int16_t type = (unsigned long)pde->data >> 16; 459 + struct list_head *list; 460 + 461 + if (af >= NPROTO) 462 + return NULL; 463 + 464 + list = type2list(af, type); 465 + if (!list) 466 + return NULL; 467 + 468 + (*pos)++; 469 + return xt_get_idx(list, seq, *pos); 470 + } 471 + 472 + static void xt_tgt_seq_stop(struct seq_file *seq, void *v) 473 + { 474 + struct proc_dir_entry *pde = seq->private; 475 + u_int16_t af = (unsigned long)pde->data & 0xffff; 476 + 477 + up(&xt[af].mutex); 478 + } 479 + 480 + static int xt_name_seq_show(struct seq_file *seq, void *v) 481 + { 482 + char *name = (char *)v + sizeof(struct list_head); 483 + 484 + if (strlen(name)) 485 + return seq_printf(seq, "%s\n", name); 486 + else 487 + return 0; 488 + } 489 + 490 + static struct seq_operations xt_tgt_seq_ops = { 491 + .start = xt_tgt_seq_start, 492 + .next = xt_tgt_seq_next, 493 + .stop = xt_tgt_seq_stop, 494 + .show = xt_name_seq_show, 495 + }; 496 + 497 + static int xt_tgt_open(struct inode *inode, struct file *file) 498 + { 499 + int ret; 500 + 501 + ret = seq_open(file, &xt_tgt_seq_ops); 502 + if (!ret) { 503 + struct seq_file *seq = file->private_data; 504 + struct proc_dir_entry *pde = PDE(inode); 505 + 506 + seq->private = pde; 507 + } 508 + 509 + return ret; 510 + } 511 + 512 + static struct file_operations xt_file_ops = { 513 + .owner = THIS_MODULE, 514 + .open = xt_tgt_open, 515 + .read = seq_read, 516 + .llseek = seq_lseek, 517 + .release = seq_release, 518 + }; 519 + 520 + #define FORMAT_TABLES "_tables_names" 521 + #define FORMAT_MATCHES "_tables_matches" 522 + #define FORMAT_TARGETS "_tables_targets" 523 + 524 + #endif /* CONFIG_PROC_FS */ 525 + 526 + int xt_proto_init(int af) 527 + { 528 + #ifdef CONFIG_PROC_FS 529 + char buf[XT_FUNCTION_MAXNAMELEN]; 530 + struct proc_dir_entry *proc; 531 + #endif 532 + 533 + if (af >= NPROTO) 534 + return -EINVAL; 535 + 536 + 537 + #ifdef CONFIG_PROC_FS 538 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 539 + strlcat(buf, FORMAT_TABLES, sizeof(buf)); 540 + proc = proc_net_fops_create(buf, 0440, &xt_file_ops); 541 + if (!proc) 542 + goto out; 543 + proc->data = (void *) ((unsigned long) af | (TABLE << 16)); 544 + 545 + 546 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 547 + strlcat(buf, FORMAT_MATCHES, sizeof(buf)); 548 + proc = proc_net_fops_create(buf, 0440, &xt_file_ops); 549 + if (!proc) 550 + goto out_remove_tables; 551 + proc->data = (void *) ((unsigned long) af | (MATCH << 16)); 552 + 553 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 554 + strlcat(buf, FORMAT_TARGETS, sizeof(buf)); 555 + proc = proc_net_fops_create(buf, 0440, &xt_file_ops); 556 + if (!proc) 557 + goto out_remove_matches; 558 + proc->data = (void *) ((unsigned long) af | (TARGET << 16)); 559 + #endif 560 + 561 + return 0; 562 + 563 + #ifdef CONFIG_PROC_FS 564 + out_remove_matches: 565 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 566 + strlcat(buf, FORMAT_MATCHES, sizeof(buf)); 567 + proc_net_remove(buf); 568 + 569 + out_remove_tables: 570 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 571 + strlcat(buf, FORMAT_TABLES, sizeof(buf)); 572 + proc_net_remove(buf); 573 + out: 574 + return -1; 575 + #endif 576 + } 577 + EXPORT_SYMBOL_GPL(xt_proto_init); 578 + 579 + void xt_proto_fini(int af) 580 + { 581 + #ifdef CONFIG_PROC_FS 582 + char buf[XT_FUNCTION_MAXNAMELEN]; 583 + 584 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 585 + strlcat(buf, FORMAT_TABLES, sizeof(buf)); 586 + proc_net_remove(buf); 587 + 588 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 589 + strlcat(buf, FORMAT_TARGETS, sizeof(buf)); 590 + proc_net_remove(buf); 591 + 592 + strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); 593 + strlcat(buf, FORMAT_MATCHES, sizeof(buf)); 594 + proc_net_remove(buf); 595 + #endif /*CONFIG_PROC_FS*/ 596 + } 597 + EXPORT_SYMBOL_GPL(xt_proto_fini); 598 + 599 + 600 + static int __init xt_init(void) 601 + { 602 + int i; 603 + 604 + xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); 605 + if (!xt) 606 + return -ENOMEM; 607 + 608 + for (i = 0; i < NPROTO; i++) { 609 + init_MUTEX(&xt[i].mutex); 610 + INIT_LIST_HEAD(&xt[i].target); 611 + INIT_LIST_HEAD(&xt[i].match); 612 + INIT_LIST_HEAD(&xt[i].tables); 613 + } 614 + return 0; 615 + } 616 + 617 + static void __exit xt_fini(void) 618 + { 619 + kfree(xt); 620 + } 621 + 622 + module_init(xt_init); 623 + module_exit(xt_fini); 624 +
+109
net/netfilter/xt_CLASSIFY.c
···
··· 1 + /* 2 + * This is a module which is used for setting the skb->priority field 3 + * of an skb for qdisc classification. 4 + */ 5 + 6 + /* (C) 2001-2002 Patrick McHardy <kaber@trash.net> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <linux/ip.h> 16 + #include <net/checksum.h> 17 + 18 + #include <linux/netfilter/x_tables.h> 19 + #include <linux/netfilter/xt_CLASSIFY.h> 20 + 21 + MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 22 + MODULE_LICENSE("GPL"); 23 + MODULE_DESCRIPTION("iptables qdisc classification target module"); 24 + MODULE_ALIAS("ipt_CLASSIFY"); 25 + 26 + static unsigned int 27 + target(struct sk_buff **pskb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + unsigned int hooknum, 31 + const void *targinfo, 32 + void *userinfo) 33 + { 34 + const struct xt_classify_target_info *clinfo = targinfo; 35 + 36 + if ((*pskb)->priority != clinfo->priority) 37 + (*pskb)->priority = clinfo->priority; 38 + 39 + return XT_CONTINUE; 40 + } 41 + 42 + static int 43 + checkentry(const char *tablename, 44 + const void *e, 45 + void *targinfo, 46 + unsigned int targinfosize, 47 + unsigned int hook_mask) 48 + { 49 + if (targinfosize != XT_ALIGN(sizeof(struct xt_classify_target_info))){ 50 + printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", 51 + targinfosize, 52 + XT_ALIGN(sizeof(struct xt_classify_target_info))); 53 + return 0; 54 + } 55 + 56 + if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 57 + (1 << NF_IP_POST_ROUTING))) { 58 + printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD " 59 + "and POST_ROUTING.\n"); 60 + return 0; 61 + } 62 + 63 + if (strcmp(tablename, "mangle") != 0) { 64 + printk(KERN_ERR "CLASSIFY: can only be called from " 65 + "\"mangle\" table, not \"%s\".\n", 66 + tablename); 67 + return 0; 68 + } 69 + 70 + return 1; 71 + } 72 + 73 + static struct xt_target classify_reg = { 74 + .name = "CLASSIFY", 75 + .target = target, 76 + .checkentry = checkentry, 77 + .me = THIS_MODULE, 78 + }; 79 + static struct xt_target classify6_reg = { 80 + .name = "CLASSIFY", 81 + .target = target, 82 + .checkentry = checkentry, 83 + .me = THIS_MODULE, 84 + }; 85 + 86 + 87 + static int __init init(void) 88 + { 89 + int ret; 90 + 91 + ret = xt_register_target(AF_INET, &classify_reg); 92 + if (ret) 93 + return ret; 94 + 95 + ret = xt_register_target(AF_INET6, &classify6_reg); 96 + if (ret) 97 + xt_unregister_target(AF_INET, &classify_reg); 98 + 99 + return ret; 100 + } 101 + 102 + static void __exit fini(void) 103 + { 104 + xt_unregister_target(AF_INET, &classify_reg); 105 + xt_unregister_target(AF_INET6, &classify6_reg); 106 + } 107 + 108 + module_init(init); 109 + module_exit(fini);
+141
net/netfilter/xt_CONNMARK.c
···
··· 1 + /* This kernel module is used to modify the connection mark values, or 2 + * to optionally restore the skb nfmark from the connection mark 3 + * 4 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + #include <linux/module.h> 22 + #include <linux/skbuff.h> 23 + #include <linux/ip.h> 24 + #include <net/checksum.h> 25 + 26 + MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 27 + MODULE_DESCRIPTION("IP tables CONNMARK matching module"); 28 + MODULE_LICENSE("GPL"); 29 + MODULE_ALIAS("ipt_CONNMARK"); 30 + 31 + #include <linux/netfilter/x_tables.h> 32 + #include <linux/netfilter/xt_CONNMARK.h> 33 + #include <net/netfilter/nf_conntrack_compat.h> 34 + 35 + static unsigned int 36 + target(struct sk_buff **pskb, 37 + const struct net_device *in, 38 + const struct net_device *out, 39 + unsigned int hooknum, 40 + const void *targinfo, 41 + void *userinfo) 42 + { 43 + const struct xt_connmark_target_info *markinfo = targinfo; 44 + u_int32_t diff; 45 + u_int32_t nfmark; 46 + u_int32_t newmark; 47 + u_int32_t ctinfo; 48 + u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); 49 + 50 + if (ctmark) { 51 + switch(markinfo->mode) { 52 + case XT_CONNMARK_SET: 53 + newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; 54 + if (newmark != *ctmark) 55 + *ctmark = newmark; 56 + break; 57 + case XT_CONNMARK_SAVE: 58 + newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); 59 + if (*ctmark != newmark) 60 + *ctmark = newmark; 61 + break; 62 + case XT_CONNMARK_RESTORE: 63 + nfmark = (*pskb)->nfmark; 64 + diff = (*ctmark ^ nfmark) & markinfo->mask; 65 + if (diff != 0) 66 + (*pskb)->nfmark = nfmark ^ diff; 67 + break; 68 + } 69 + } 70 + 71 + return XT_CONTINUE; 72 + } 73 + 74 + static int 75 + checkentry(const char *tablename, 76 + const void *entry, 77 + void *targinfo, 78 + unsigned int targinfosize, 79 + unsigned int hook_mask) 80 + { 81 + struct xt_connmark_target_info *matchinfo = targinfo; 82 + if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) { 83 + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", 84 + targinfosize, 85 + XT_ALIGN(sizeof(struct xt_connmark_target_info))); 86 + return 0; 87 + } 88 + 89 + if (matchinfo->mode == XT_CONNMARK_RESTORE) { 90 + if (strcmp(tablename, "mangle") != 0) { 91 + printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); 92 + return 0; 93 + } 94 + } 95 + 96 + if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { 97 + printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 98 + return 0; 99 + } 100 + 101 + return 1; 102 + } 103 + 104 + static struct xt_target connmark_reg = { 105 + .name = "CONNMARK", 106 + .target = &target, 107 + .checkentry = &checkentry, 108 + .me = THIS_MODULE 109 + }; 110 + static struct xt_target connmark6_reg = { 111 + .name = "CONNMARK", 112 + .target = &target, 113 + .checkentry = &checkentry, 114 + .me = THIS_MODULE 115 + }; 116 + 117 + static int __init init(void) 118 + { 119 + int ret; 120 + 121 + need_conntrack(); 122 + 123 + ret = xt_register_target(AF_INET, &connmark_reg); 124 + if (ret) 125 + return ret; 126 + 127 + ret = xt_register_target(AF_INET6, &connmark6_reg); 128 + if (ret) 129 + xt_unregister_target(AF_INET, &connmark_reg); 130 + 131 + return ret; 132 + } 133 + 134 + static void __exit fini(void) 135 + { 136 + xt_unregister_target(AF_INET, &connmark_reg); 137 + xt_unregister_target(AF_INET6, &connmark6_reg); 138 + } 139 + 140 + module_init(init); 141 + module_exit(fini);
+191
net/netfilter/xt_MARK.c
···
··· 1 + /* This is a module which is used for setting the NFMARK field of an skb. */ 2 + 3 + /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/skbuff.h> 12 + #include <linux/ip.h> 13 + #include <net/checksum.h> 14 + 15 + #include <linux/netfilter/x_tables.h> 16 + #include <linux/netfilter/xt_MARK.h> 17 + 18 + MODULE_LICENSE("GPL"); 19 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 20 + MODULE_DESCRIPTION("ip[6]tables MARK modification module"); 21 + MODULE_ALIAS("ipt_MARK"); 22 + MODULE_ALIAS("ip6t_MARK"); 23 + 24 + static unsigned int 25 + target_v0(struct sk_buff **pskb, 26 + const struct net_device *in, 27 + const struct net_device *out, 28 + unsigned int hooknum, 29 + const void *targinfo, 30 + void *userinfo) 31 + { 32 + const struct xt_mark_target_info *markinfo = targinfo; 33 + 34 + if((*pskb)->nfmark != markinfo->mark) 35 + (*pskb)->nfmark = markinfo->mark; 36 + 37 + return XT_CONTINUE; 38 + } 39 + 40 + static unsigned int 41 + target_v1(struct sk_buff **pskb, 42 + const struct net_device *in, 43 + const struct net_device *out, 44 + unsigned int hooknum, 45 + const void *targinfo, 46 + void *userinfo) 47 + { 48 + const struct xt_mark_target_info_v1 *markinfo = targinfo; 49 + int mark = 0; 50 + 51 + switch (markinfo->mode) { 52 + case XT_MARK_SET: 53 + mark = markinfo->mark; 54 + break; 55 + 56 + case XT_MARK_AND: 57 + mark = (*pskb)->nfmark & markinfo->mark; 58 + break; 59 + 60 + case XT_MARK_OR: 61 + mark = (*pskb)->nfmark | markinfo->mark; 62 + break; 63 + } 64 + 65 + if((*pskb)->nfmark != mark) 66 + (*pskb)->nfmark = mark; 67 + 68 + return XT_CONTINUE; 69 + } 70 + 71 + 72 + static int 73 + checkentry_v0(const char *tablename, 74 + const void *entry, 75 + void *targinfo, 76 + unsigned int targinfosize, 77 + unsigned int hook_mask) 78 + { 79 + struct xt_mark_target_info *markinfo = targinfo; 80 + 81 + if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info))) { 82 + printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 83 + targinfosize, 84 + XT_ALIGN(sizeof(struct xt_mark_target_info))); 85 + return 0; 86 + } 87 + 88 + if (strcmp(tablename, "mangle") != 0) { 89 + printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 90 + return 0; 91 + } 92 + 93 + if (markinfo->mark > 0xffffffff) { 94 + printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 95 + return 0; 96 + } 97 + 98 + return 1; 99 + } 100 + 101 + static int 102 + checkentry_v1(const char *tablename, 103 + const void *entry, 104 + void *targinfo, 105 + unsigned int targinfosize, 106 + unsigned int hook_mask) 107 + { 108 + struct xt_mark_target_info_v1 *markinfo = targinfo; 109 + 110 + if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info_v1))){ 111 + printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", 112 + targinfosize, 113 + XT_ALIGN(sizeof(struct xt_mark_target_info_v1))); 114 + return 0; 115 + } 116 + 117 + if (strcmp(tablename, "mangle") != 0) { 118 + printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); 119 + return 0; 120 + } 121 + 122 + if (markinfo->mode != XT_MARK_SET 123 + && markinfo->mode != XT_MARK_AND 124 + && markinfo->mode != XT_MARK_OR) { 125 + printk(KERN_WARNING "MARK: unknown mode %u\n", 126 + markinfo->mode); 127 + return 0; 128 + } 129 + 130 + if (markinfo->mark > 0xffffffff) { 131 + printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 132 + return 0; 133 + } 134 + 135 + return 1; 136 + } 137 + 138 + static struct xt_target ipt_mark_reg_v0 = { 139 + .name = "MARK", 140 + .target = target_v0, 141 + .checkentry = checkentry_v0, 142 + .me = THIS_MODULE, 143 + .revision = 0, 144 + }; 145 + 146 + static struct xt_target ipt_mark_reg_v1 = { 147 + .name = "MARK", 148 + .target = target_v1, 149 + .checkentry = checkentry_v1, 150 + .me = THIS_MODULE, 151 + .revision = 1, 152 + }; 153 + 154 + static struct xt_target ip6t_mark_reg_v0 = { 155 + .name = "MARK", 156 + .target = target_v0, 157 + .checkentry = checkentry_v0, 158 + .me = THIS_MODULE, 159 + .revision = 0, 160 + }; 161 + 162 + static int __init init(void) 163 + { 164 + int err; 165 + 166 + err = xt_register_target(AF_INET, &ipt_mark_reg_v0); 167 + if (err) 168 + return err; 169 + 170 + err = xt_register_target(AF_INET, &ipt_mark_reg_v1); 171 + if (err) 172 + xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 173 + 174 + err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0); 175 + if (err) { 176 + xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 177 + xt_unregister_target(AF_INET, &ipt_mark_reg_v1); 178 + } 179 + 180 + return err; 181 + } 182 + 183 + static void __exit fini(void) 184 + { 185 + xt_unregister_target(AF_INET, &ipt_mark_reg_v0); 186 + xt_unregister_target(AF_INET, &ipt_mark_reg_v1); 187 + xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0); 188 + } 189 + 190 + module_init(init); 191 + module_exit(fini);
+107
net/netfilter/xt_NFQUEUE.c
···
··· 1 + /* iptables module for using new netfilter netlink queue 2 + * 3 + * (C) 2005 by Harald Welte <laforge@netfilter.org> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + 14 + #include <linux/netfilter.h> 15 + #include <linux/netfilter_arp.h> 16 + #include <linux/netfilter/x_tables.h> 17 + #include <linux/netfilter/xt_NFQUEUE.h> 18 + 19 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 20 + MODULE_DESCRIPTION("[ip,ip6,arp]_tables NFQUEUE target"); 21 + MODULE_LICENSE("GPL"); 22 + MODULE_ALIAS("ipt_NFQUEUE"); 23 + MODULE_ALIAS("ip6t_NFQUEUE"); 24 + MODULE_ALIAS("arpt_NFQUEUE"); 25 + 26 + static unsigned int 27 + target(struct sk_buff **pskb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + unsigned int hooknum, 31 + const void *targinfo, 32 + void *userinfo) 33 + { 34 + const struct xt_NFQ_info *tinfo = targinfo; 35 + 36 + return NF_QUEUE_NR(tinfo->queuenum); 37 + } 38 + 39 + static int 40 + checkentry(const char *tablename, 41 + const void *entry, 42 + void *targinfo, 43 + unsigned int targinfosize, 44 + unsigned int hook_mask) 45 + { 46 + if (targinfosize != XT_ALIGN(sizeof(struct xt_NFQ_info))) { 47 + printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", 48 + targinfosize, 49 + XT_ALIGN(sizeof(struct xt_NFQ_info))); 50 + return 0; 51 + } 52 + 53 + return 1; 54 + } 55 + 56 + static struct xt_target ipt_NFQ_reg = { 57 + .name = "NFQUEUE", 58 + .target = target, 59 + .checkentry = checkentry, 60 + .me = THIS_MODULE, 61 + }; 62 + 63 + static struct xt_target ip6t_NFQ_reg = { 64 + .name = "NFQUEUE", 65 + .target = target, 66 + .checkentry = checkentry, 67 + .me = THIS_MODULE, 68 + }; 69 + 70 + static struct xt_target arpt_NFQ_reg = { 71 + .name = "NFQUEUE", 72 + .target = target, 73 + .checkentry = checkentry, 74 + .me = THIS_MODULE, 75 + }; 76 + 77 + static int __init init(void) 78 + { 79 + int ret; 80 + ret = xt_register_target(AF_INET, &ipt_NFQ_reg); 81 + if (ret) 82 + return ret; 83 + ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg); 84 + if (ret) 85 + goto out_ip; 86 + ret = xt_register_target(NF_ARP, &arpt_NFQ_reg); 87 + if (ret) 88 + goto out_ip6; 89 + 90 + return ret; 91 + out_ip6: 92 + xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); 93 + out_ip: 94 + xt_unregister_target(AF_INET, &ipt_NFQ_reg); 95 + 96 + return ret; 97 + } 98 + 99 + static void __exit fini(void) 100 + { 101 + xt_unregister_target(NF_ARP, &arpt_NFQ_reg); 102 + xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); 103 + xt_unregister_target(AF_INET, &ipt_NFQ_reg); 104 + } 105 + 106 + module_init(init); 107 + module_exit(fini);
+92
net/netfilter/xt_NOTRACK.c
···
··· 1 + /* This is a module which is used for setting up fake conntracks 2 + * on packets so that they are not seen by the conntrack/NAT code. 3 + */ 4 + #include <linux/module.h> 5 + #include <linux/skbuff.h> 6 + 7 + #include <linux/netfilter/x_tables.h> 8 + #include <net/netfilter/nf_conntrack_compat.h> 9 + 10 + MODULE_LICENSE("GPL"); 11 + MODULE_ALIAS("ipt_NOTRACK"); 12 + 13 + static unsigned int 14 + target(struct sk_buff **pskb, 15 + const struct net_device *in, 16 + const struct net_device *out, 17 + unsigned int hooknum, 18 + const void *targinfo, 19 + void *userinfo) 20 + { 21 + /* Previously seen (loopback)? Ignore. */ 22 + if ((*pskb)->nfct != NULL) 23 + return XT_CONTINUE; 24 + 25 + /* Attach fake conntrack entry. 26 + If there is a real ct entry correspondig to this packet, 27 + it'll hang aroun till timing out. We don't deal with it 28 + for performance reasons. JK */ 29 + nf_ct_untrack(*pskb); 30 + (*pskb)->nfctinfo = IP_CT_NEW; 31 + nf_conntrack_get((*pskb)->nfct); 32 + 33 + return XT_CONTINUE; 34 + } 35 + 36 + static int 37 + checkentry(const char *tablename, 38 + const void *entry, 39 + void *targinfo, 40 + unsigned int targinfosize, 41 + unsigned int hook_mask) 42 + { 43 + if (targinfosize != 0) { 44 + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", 45 + targinfosize); 46 + return 0; 47 + } 48 + 49 + if (strcmp(tablename, "raw") != 0) { 50 + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); 51 + return 0; 52 + } 53 + 54 + return 1; 55 + } 56 + 57 + static struct xt_target notrack_reg = { 58 + .name = "NOTRACK", 59 + .target = target, 60 + .checkentry = checkentry, 61 + .me = THIS_MODULE, 62 + }; 63 + static struct xt_target notrack6_reg = { 64 + .name = "NOTRACK", 65 + .target = target, 66 + .checkentry = checkentry, 67 + .me = THIS_MODULE, 68 + }; 69 + 70 + static int __init init(void) 71 + { 72 + int ret; 73 + 74 + ret = xt_register_target(AF_INET, &notrack_reg); 75 + if (ret) 76 + return ret; 77 + 78 + ret = xt_register_target(AF_INET6, &notrack6_reg); 79 + if (ret) 80 + xt_unregister_target(AF_INET, &notrack_reg); 81 + 82 + return ret; 83 + } 84 + 85 + static void __exit fini(void) 86 + { 87 + xt_unregister_target(AF_INET6, &notrack6_reg); 88 + xt_unregister_target(AF_INET, &notrack_reg); 89 + } 90 + 91 + module_init(init); 92 + module_exit(fini);
+80
net/netfilter/xt_comment.c
···
··· 1 + /* 2 + * Implements a dummy match to allow attaching comments to rules 3 + * 4 + * 2003-05-13 Brad Fisher (brad@info-link.net) 5 + */ 6 + 7 + #include <linux/module.h> 8 + #include <linux/skbuff.h> 9 + #include <linux/netfilter/x_tables.h> 10 + #include <linux/netfilter/xt_comment.h> 11 + 12 + MODULE_AUTHOR("Brad Fisher <brad@info-link.net>"); 13 + MODULE_DESCRIPTION("iptables comment match module"); 14 + MODULE_LICENSE("GPL"); 15 + MODULE_ALIAS("ipt_comment"); 16 + MODULE_ALIAS("ip6t_comment"); 17 + 18 + static int 19 + match(const struct sk_buff *skb, 20 + const struct net_device *in, 21 + const struct net_device *out, 22 + const void *matchinfo, 23 + int offset, 24 + unsigned int protooff, 25 + int *hotdrop) 26 + { 27 + /* We always match */ 28 + return 1; 29 + } 30 + 31 + static int 32 + checkentry(const char *tablename, 33 + const void *ip, 34 + void *matchinfo, 35 + unsigned int matchsize, 36 + unsigned int hook_mask) 37 + { 38 + /* Check the size */ 39 + if (matchsize != XT_ALIGN(sizeof(struct xt_comment_info))) 40 + return 0; 41 + return 1; 42 + } 43 + 44 + static struct xt_match comment_match = { 45 + .name = "comment", 46 + .match = match, 47 + .checkentry = checkentry, 48 + .me = THIS_MODULE 49 + }; 50 + 51 + static struct xt_match comment6_match = { 52 + .name = "comment", 53 + .match = match, 54 + .checkentry = checkentry, 55 + .me = THIS_MODULE 56 + }; 57 + 58 + static int __init init(void) 59 + { 60 + int ret; 61 + 62 + ret = xt_register_match(AF_INET, &comment_match); 63 + if (ret) 64 + return ret; 65 + 66 + ret = xt_register_match(AF_INET6, &comment6_match); 67 + if (ret) 68 + xt_unregister_match(AF_INET, &comment_match); 69 + 70 + return ret; 71 + } 72 + 73 + static void __exit fini(void) 74 + { 75 + xt_unregister_match(AF_INET, &comment_match); 76 + xt_unregister_match(AF_INET6, &comment6_match); 77 + } 78 + 79 + module_init(init); 80 + module_exit(fini);
+180
net/netfilter/xt_connbytes.c
···
··· 1 + /* Kernel module to match connection tracking byte counter. 2 + * GPL (C) 2002 Martin Devera (devik@cdi.cz). 3 + * 4 + * 2004-07-20 Harald Welte <laforge@netfilter.org> 5 + * - reimplemented to use per-connection accounting counters 6 + * - add functionality to match number of packets 7 + * - add functionality to match average packet size 8 + * - add support to match directions seperately 9 + * 2005-10-16 Harald Welte <laforge@netfilter.org> 10 + * - Port to x_tables 11 + * 12 + */ 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <net/netfilter/nf_conntrack_compat.h> 16 + #include <linux/netfilter/x_tables.h> 17 + #include <linux/netfilter/xt_connbytes.h> 18 + 19 + #include <asm/div64.h> 20 + #include <asm/bitops.h> 21 + 22 + MODULE_LICENSE("GPL"); 23 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 24 + MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); 25 + MODULE_ALIAS("ipt_connbytes"); 26 + 27 + /* 64bit divisor, dividend and result. dynamic precision */ 28 + static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) 29 + { 30 + u_int32_t d = divisor; 31 + 32 + if (divisor > 0xffffffffULL) { 33 + unsigned int shift = fls(divisor >> 32); 34 + 35 + d = divisor >> shift; 36 + dividend >>= shift; 37 + } 38 + 39 + do_div(dividend, d); 40 + return dividend; 41 + } 42 + 43 + static int 44 + match(const struct sk_buff *skb, 45 + const struct net_device *in, 46 + const struct net_device *out, 47 + const void *matchinfo, 48 + int offset, 49 + unsigned int protoff, 50 + int *hotdrop) 51 + { 52 + const struct xt_connbytes_info *sinfo = matchinfo; 53 + u_int64_t what = 0; /* initialize to make gcc happy */ 54 + const struct ip_conntrack_counter *counters; 55 + 56 + if (!(counters = nf_ct_get_counters(skb))) 57 + return 0; /* no match */ 58 + 59 + switch (sinfo->what) { 60 + case XT_CONNBYTES_PKTS: 61 + switch (sinfo->direction) { 62 + case XT_CONNBYTES_DIR_ORIGINAL: 63 + what = counters[IP_CT_DIR_ORIGINAL].packets; 64 + break; 65 + case XT_CONNBYTES_DIR_REPLY: 66 + what = counters[IP_CT_DIR_REPLY].packets; 67 + break; 68 + case XT_CONNBYTES_DIR_BOTH: 69 + what = counters[IP_CT_DIR_ORIGINAL].packets; 70 + what += counters[IP_CT_DIR_REPLY].packets; 71 + break; 72 + } 73 + break; 74 + case XT_CONNBYTES_BYTES: 75 + switch (sinfo->direction) { 76 + case XT_CONNBYTES_DIR_ORIGINAL: 77 + what = counters[IP_CT_DIR_ORIGINAL].bytes; 78 + break; 79 + case XT_CONNBYTES_DIR_REPLY: 80 + what = counters[IP_CT_DIR_REPLY].bytes; 81 + break; 82 + case XT_CONNBYTES_DIR_BOTH: 83 + what = counters[IP_CT_DIR_ORIGINAL].bytes; 84 + what += counters[IP_CT_DIR_REPLY].bytes; 85 + break; 86 + } 87 + break; 88 + case XT_CONNBYTES_AVGPKT: 89 + switch (sinfo->direction) { 90 + case XT_CONNBYTES_DIR_ORIGINAL: 91 + what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, 92 + counters[IP_CT_DIR_ORIGINAL].packets); 93 + break; 94 + case XT_CONNBYTES_DIR_REPLY: 95 + what = div64_64(counters[IP_CT_DIR_REPLY].bytes, 96 + counters[IP_CT_DIR_REPLY].packets); 97 + break; 98 + case XT_CONNBYTES_DIR_BOTH: 99 + { 100 + u_int64_t bytes; 101 + u_int64_t pkts; 102 + bytes = counters[IP_CT_DIR_ORIGINAL].bytes + 103 + counters[IP_CT_DIR_REPLY].bytes; 104 + pkts = counters[IP_CT_DIR_ORIGINAL].packets+ 105 + counters[IP_CT_DIR_REPLY].packets; 106 + 107 + /* FIXME_THEORETICAL: what to do if sum 108 + * overflows ? */ 109 + 110 + what = div64_64(bytes, pkts); 111 + } 112 + break; 113 + } 114 + break; 115 + } 116 + 117 + if (sinfo->count.to) 118 + return (what <= sinfo->count.to && what >= sinfo->count.from); 119 + else 120 + return (what >= sinfo->count.from); 121 + } 122 + 123 + static int check(const char *tablename, 124 + const void *ip, 125 + void *matchinfo, 126 + unsigned int matchsize, 127 + unsigned int hook_mask) 128 + { 129 + const struct xt_connbytes_info *sinfo = matchinfo; 130 + 131 + if (matchsize != XT_ALIGN(sizeof(struct xt_connbytes_info))) 132 + return 0; 133 + 134 + if (sinfo->what != XT_CONNBYTES_PKTS && 135 + sinfo->what != XT_CONNBYTES_BYTES && 136 + sinfo->what != XT_CONNBYTES_AVGPKT) 137 + return 0; 138 + 139 + if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL && 140 + sinfo->direction != XT_CONNBYTES_DIR_REPLY && 141 + sinfo->direction != XT_CONNBYTES_DIR_BOTH) 142 + return 0; 143 + 144 + return 1; 145 + } 146 + 147 + static struct xt_match connbytes_match = { 148 + .name = "connbytes", 149 + .match = &match, 150 + .checkentry = &check, 151 + .me = THIS_MODULE 152 + }; 153 + static struct xt_match connbytes6_match = { 154 + .name = "connbytes", 155 + .match = &match, 156 + .checkentry = &check, 157 + .me = THIS_MODULE 158 + }; 159 + 160 + static int __init init(void) 161 + { 162 + int ret; 163 + ret = xt_register_match(AF_INET, &connbytes_match); 164 + if (ret) 165 + return ret; 166 + 167 + ret = xt_register_match(AF_INET6, &connbytes6_match); 168 + if (ret) 169 + xt_unregister_match(AF_INET, &connbytes_match); 170 + return ret; 171 + } 172 + 173 + static void __exit fini(void) 174 + { 175 + xt_unregister_match(AF_INET, &connbytes_match); 176 + xt_unregister_match(AF_INET6, &connbytes6_match); 177 + } 178 + 179 + module_init(init); 180 + module_exit(fini);
+109
net/netfilter/xt_connmark.c
···
··· 1 + /* This kernel module matches connection mark values set by the 2 + * CONNMARK target 3 + * 4 + * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com> 5 + * by Henrik Nordstrom <hno@marasystems.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/skbuff.h> 24 + 25 + MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>"); 26 + MODULE_DESCRIPTION("IP tables connmark match module"); 27 + MODULE_LICENSE("GPL"); 28 + MODULE_ALIAS("ipt_connmark"); 29 + 30 + #include <linux/netfilter/x_tables.h> 31 + #include <linux/netfilter/xt_connmark.h> 32 + #include <net/netfilter/nf_conntrack_compat.h> 33 + 34 + static int 35 + match(const struct sk_buff *skb, 36 + const struct net_device *in, 37 + const struct net_device *out, 38 + const void *matchinfo, 39 + int offset, 40 + unsigned int protoff, 41 + int *hotdrop) 42 + { 43 + const struct xt_connmark_info *info = matchinfo; 44 + u_int32_t ctinfo; 45 + const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); 46 + if (!ctmark) 47 + return 0; 48 + 49 + return (((*ctmark) & info->mask) == info->mark) ^ info->invert; 50 + } 51 + 52 + static int 53 + checkentry(const char *tablename, 54 + const void *ip, 55 + void *matchinfo, 56 + unsigned int matchsize, 57 + unsigned int hook_mask) 58 + { 59 + struct xt_connmark_info *cm = 60 + (struct xt_connmark_info *)matchinfo; 61 + if (matchsize != XT_ALIGN(sizeof(struct xt_connmark_info))) 62 + return 0; 63 + 64 + if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 65 + printk(KERN_WARNING "connmark: only support 32bit mark\n"); 66 + return 0; 67 + } 68 + 69 + return 1; 70 + } 71 + 72 + static struct xt_match connmark_match = { 73 + .name = "connmark", 74 + .match = &match, 75 + .checkentry = &checkentry, 76 + .me = THIS_MODULE 77 + }; 78 + static struct xt_match connmark6_match = { 79 + .name = "connmark", 80 + .match = &match, 81 + .checkentry = &checkentry, 82 + .me = THIS_MODULE 83 + }; 84 + 85 + 86 + static int __init init(void) 87 + { 88 + int ret; 89 + 90 + need_conntrack(); 91 + 92 + ret = xt_register_match(AF_INET, &connmark_match); 93 + if (ret) 94 + return ret; 95 + 96 + ret = xt_register_match(AF_INET6, &connmark6_match); 97 + if (ret) 98 + xt_unregister_match(AF_INET, &connmark_match); 99 + return ret; 100 + } 101 + 102 + static void __exit fini(void) 103 + { 104 + xt_unregister_match(AF_INET6, &connmark6_match); 105 + xt_unregister_match(AF_INET, &connmark_match); 106 + } 107 + 108 + module_init(init); 109 + module_exit(fini);
+238
net/netfilter/xt_conntrack.c
···
··· 1 + /* Kernel module to match connection tracking information. 2 + * Superset of Rusty's minimalistic state match. 3 + * 4 + * (C) 2001 Marc Boucher (marc@mbsi.ca). 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + 14 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 15 + #include <linux/netfilter_ipv4/ip_conntrack.h> 16 + #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 17 + #else 18 + #include <net/netfilter/nf_conntrack.h> 19 + #endif 20 + 21 + #include <linux/netfilter/x_tables.h> 22 + #include <linux/netfilter/xt_conntrack.h> 23 + 24 + MODULE_LICENSE("GPL"); 25 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 26 + MODULE_DESCRIPTION("iptables connection tracking match module"); 27 + MODULE_ALIAS("ipt_conntrack"); 28 + 29 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 30 + 31 + static int 32 + match(const struct sk_buff *skb, 33 + const struct net_device *in, 34 + const struct net_device *out, 35 + const void *matchinfo, 36 + int offset, 37 + unsigned int protoff, 38 + int *hotdrop) 39 + { 40 + const struct xt_conntrack_info *sinfo = matchinfo; 41 + struct ip_conntrack *ct; 42 + enum ip_conntrack_info ctinfo; 43 + unsigned int statebit; 44 + 45 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 46 + 47 + #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 48 + 49 + if (ct == &ip_conntrack_untracked) 50 + statebit = XT_CONNTRACK_STATE_UNTRACKED; 51 + else if (ct) 52 + statebit = XT_CONNTRACK_STATE_BIT(ctinfo); 53 + else 54 + statebit = XT_CONNTRACK_STATE_INVALID; 55 + 56 + if(sinfo->flags & XT_CONNTRACK_STATE) { 57 + if (ct) { 58 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != 59 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) 60 + statebit |= XT_CONNTRACK_STATE_SNAT; 61 + 62 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != 63 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) 64 + statebit |= XT_CONNTRACK_STATE_DNAT; 65 + } 66 + 67 + if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) 68 + return 0; 69 + } 70 + 71 + if(sinfo->flags & XT_CONNTRACK_PROTO) { 72 + if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) 73 + return 0; 74 + } 75 + 76 + if(sinfo->flags & XT_CONNTRACK_ORIGSRC) { 77 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC)) 78 + return 0; 79 + } 80 + 81 + if(sinfo->flags & XT_CONNTRACK_ORIGDST) { 82 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST)) 83 + return 0; 84 + } 85 + 86 + if(sinfo->flags & XT_CONNTRACK_REPLSRC) { 87 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC)) 88 + return 0; 89 + } 90 + 91 + if(sinfo->flags & XT_CONNTRACK_REPLDST) { 92 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST)) 93 + return 0; 94 + } 95 + 96 + if(sinfo->flags & XT_CONNTRACK_STATUS) { 97 + if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) 98 + return 0; 99 + } 100 + 101 + if(sinfo->flags & XT_CONNTRACK_EXPIRES) { 102 + unsigned long expires; 103 + 104 + if(!ct) 105 + return 0; 106 + 107 + expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 108 + 109 + if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) 110 + return 0; 111 + } 112 + 113 + return 1; 114 + } 115 + 116 + #else /* CONFIG_IP_NF_CONNTRACK */ 117 + static int 118 + match(const struct sk_buff *skb, 119 + const struct net_device *in, 120 + const struct net_device *out, 121 + const void *matchinfo, 122 + int offset, 123 + unsigned int protoff, 124 + int *hotdrop) 125 + { 126 + const struct xt_conntrack_info *sinfo = matchinfo; 127 + struct nf_conn *ct; 128 + enum ip_conntrack_info ctinfo; 129 + unsigned int statebit; 130 + 131 + ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 132 + 133 + #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 134 + 135 + if (ct == &nf_conntrack_untracked) 136 + statebit = XT_CONNTRACK_STATE_UNTRACKED; 137 + else if (ct) 138 + statebit = XT_CONNTRACK_STATE_BIT(ctinfo); 139 + else 140 + statebit = XT_CONNTRACK_STATE_INVALID; 141 + 142 + if(sinfo->flags & XT_CONNTRACK_STATE) { 143 + if (ct) { 144 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != 145 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) 146 + statebit |= XT_CONNTRACK_STATE_SNAT; 147 + 148 + if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != 149 + ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) 150 + statebit |= XT_CONNTRACK_STATE_DNAT; 151 + } 152 + 153 + if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) 154 + return 0; 155 + } 156 + 157 + if(sinfo->flags & XT_CONNTRACK_PROTO) { 158 + if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) 159 + return 0; 160 + } 161 + 162 + if(sinfo->flags & XT_CONNTRACK_ORIGSRC) { 163 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC)) 164 + return 0; 165 + } 166 + 167 + if(sinfo->flags & XT_CONNTRACK_ORIGDST) { 168 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST)) 169 + return 0; 170 + } 171 + 172 + if(sinfo->flags & XT_CONNTRACK_REPLSRC) { 173 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC)) 174 + return 0; 175 + } 176 + 177 + if(sinfo->flags & XT_CONNTRACK_REPLDST) { 178 + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST)) 179 + return 0; 180 + } 181 + 182 + if(sinfo->flags & XT_CONNTRACK_STATUS) { 183 + if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) 184 + return 0; 185 + } 186 + 187 + if(sinfo->flags & XT_CONNTRACK_EXPIRES) { 188 + unsigned long expires; 189 + 190 + if(!ct) 191 + return 0; 192 + 193 + expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; 194 + 195 + if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) 196 + return 0; 197 + } 198 + 199 + return 1; 200 + } 201 + 202 + #endif /* CONFIG_NF_IP_CONNTRACK */ 203 + 204 + static int check(const char *tablename, 205 + const void *ip, 206 + void *matchinfo, 207 + unsigned int matchsize, 208 + unsigned int hook_mask) 209 + { 210 + if (matchsize != XT_ALIGN(sizeof(struct xt_conntrack_info))) 211 + return 0; 212 + 213 + return 1; 214 + } 215 + 216 + static struct xt_match conntrack_match = { 217 + .name = "conntrack", 218 + .match = &match, 219 + .checkentry = &check, 220 + .me = THIS_MODULE, 221 + }; 222 + 223 + static int __init init(void) 224 + { 225 + int ret; 226 + need_conntrack(); 227 + ret = xt_register_match(AF_INET, &conntrack_match); 228 + 229 + return ret; 230 + } 231 + 232 + static void __exit fini(void) 233 + { 234 + xt_unregister_match(AF_INET, &conntrack_match); 235 + } 236 + 237 + module_init(init); 238 + module_exit(fini);
+221
net/netfilter/xt_dccp.c
···
··· 1 + /* 2 + * iptables module for DCCP protocol header matching 3 + * 4 + * (C) 2005 by Harald Welte <laforge@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/spinlock.h> 14 + #include <net/ip.h> 15 + #include <linux/dccp.h> 16 + 17 + #include <linux/netfilter/x_tables.h> 18 + #include <linux/netfilter/xt_dccp.h> 19 + 20 + #include <linux/netfilter_ipv4/ip_tables.h> 21 + #include <linux/netfilter_ipv6/ip6_tables.h> 22 + 23 + MODULE_LICENSE("GPL"); 24 + MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 25 + MODULE_DESCRIPTION("Match for DCCP protocol packets"); 26 + MODULE_ALIAS("ipt_dccp"); 27 + 28 + #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 29 + || (!!((invflag) & (option)) ^ (cond))) 30 + 31 + static unsigned char *dccp_optbuf; 32 + static DEFINE_SPINLOCK(dccp_buflock); 33 + 34 + static inline int 35 + dccp_find_option(u_int8_t option, 36 + const struct sk_buff *skb, 37 + unsigned int protoff, 38 + const struct dccp_hdr *dh, 39 + int *hotdrop) 40 + { 41 + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 42 + unsigned char *op; 43 + unsigned int optoff = __dccp_hdr_len(dh); 44 + unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh); 45 + unsigned int i; 46 + 47 + if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) { 48 + *hotdrop = 1; 49 + return 0; 50 + } 51 + 52 + if (!optlen) 53 + return 0; 54 + 55 + spin_lock_bh(&dccp_buflock); 56 + op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf); 57 + if (op == NULL) { 58 + /* If we don't have the whole header, drop packet. */ 59 + spin_unlock_bh(&dccp_buflock); 60 + *hotdrop = 1; 61 + return 0; 62 + } 63 + 64 + for (i = 0; i < optlen; ) { 65 + if (op[i] == option) { 66 + spin_unlock_bh(&dccp_buflock); 67 + return 1; 68 + } 69 + 70 + if (op[i] < 2) 71 + i++; 72 + else 73 + i += op[i+1]?:1; 74 + } 75 + 76 + spin_unlock_bh(&dccp_buflock); 77 + return 0; 78 + } 79 + 80 + 81 + static inline int 82 + match_types(const struct dccp_hdr *dh, u_int16_t typemask) 83 + { 84 + return (typemask & (1 << dh->dccph_type)); 85 + } 86 + 87 + static inline int 88 + match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff, 89 + const struct dccp_hdr *dh, int *hotdrop) 90 + { 91 + return dccp_find_option(option, skb, protoff, dh, hotdrop); 92 + } 93 + 94 + static int 95 + match(const struct sk_buff *skb, 96 + const struct net_device *in, 97 + const struct net_device *out, 98 + const void *matchinfo, 99 + int offset, 100 + unsigned int protoff, 101 + int *hotdrop) 102 + { 103 + const struct xt_dccp_info *info = 104 + (const struct xt_dccp_info *)matchinfo; 105 + struct dccp_hdr _dh, *dh; 106 + 107 + if (offset) 108 + return 0; 109 + 110 + dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); 111 + if (dh == NULL) { 112 + *hotdrop = 1; 113 + return 0; 114 + } 115 + 116 + return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) 117 + && (ntohs(dh->dccph_sport) <= info->spts[1])), 118 + XT_DCCP_SRC_PORTS, info->flags, info->invflags) 119 + && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) 120 + && (ntohs(dh->dccph_dport) <= info->dpts[1])), 121 + XT_DCCP_DEST_PORTS, info->flags, info->invflags) 122 + && DCCHECK(match_types(dh, info->typemask), 123 + XT_DCCP_TYPE, info->flags, info->invflags) 124 + && DCCHECK(match_option(info->option, skb, protoff, dh, 125 + hotdrop), 126 + XT_DCCP_OPTION, info->flags, info->invflags); 127 + } 128 + 129 + static int 130 + checkentry(const char *tablename, 131 + const void *inf, 132 + void *matchinfo, 133 + unsigned int matchsize, 134 + unsigned int hook_mask) 135 + { 136 + const struct ipt_ip *ip = inf; 137 + const struct xt_dccp_info *info; 138 + 139 + info = (const struct xt_dccp_info *)matchinfo; 140 + 141 + return ip->proto == IPPROTO_DCCP 142 + && !(ip->invflags & XT_INV_PROTO) 143 + && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) 144 + && !(info->flags & ~XT_DCCP_VALID_FLAGS) 145 + && !(info->invflags & ~XT_DCCP_VALID_FLAGS) 146 + && !(info->invflags & ~info->flags); 147 + } 148 + 149 + static int 150 + checkentry6(const char *tablename, 151 + const void *inf, 152 + void *matchinfo, 153 + unsigned int matchsize, 154 + unsigned int hook_mask) 155 + { 156 + const struct ip6t_ip6 *ip = inf; 157 + const struct xt_dccp_info *info; 158 + 159 + info = (const struct xt_dccp_info *)matchinfo; 160 + 161 + return ip->proto == IPPROTO_DCCP 162 + && !(ip->invflags & XT_INV_PROTO) 163 + && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) 164 + && !(info->flags & ~XT_DCCP_VALID_FLAGS) 165 + && !(info->invflags & ~XT_DCCP_VALID_FLAGS) 166 + && !(info->invflags & ~info->flags); 167 + } 168 + 169 + 170 + static struct xt_match dccp_match = 171 + { 172 + .name = "dccp", 173 + .match = &match, 174 + .checkentry = &checkentry, 175 + .me = THIS_MODULE, 176 + }; 177 + static struct xt_match dccp6_match = 178 + { 179 + .name = "dccp", 180 + .match = &match, 181 + .checkentry = &checkentry6, 182 + .me = THIS_MODULE, 183 + }; 184 + 185 + 186 + static int __init init(void) 187 + { 188 + int ret; 189 + 190 + /* doff is 8 bits, so the maximum option size is (4*256). Don't put 191 + * this in BSS since DaveM is worried about locked TLB's for kernel 192 + * BSS. */ 193 + dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); 194 + if (!dccp_optbuf) 195 + return -ENOMEM; 196 + ret = xt_register_match(AF_INET, &dccp_match); 197 + if (ret) 198 + goto out_kfree; 199 + ret = xt_register_match(AF_INET6, &dccp6_match); 200 + if (ret) 201 + goto out_unreg; 202 + 203 + return ret; 204 + 205 + out_unreg: 206 + xt_unregister_match(AF_INET, &dccp_match); 207 + out_kfree: 208 + kfree(dccp_optbuf); 209 + 210 + return ret; 211 + } 212 + 213 + static void __exit fini(void) 214 + { 215 + xt_unregister_match(AF_INET6, &dccp6_match); 216 + xt_unregister_match(AF_INET, &dccp_match); 217 + kfree(dccp_optbuf); 218 + } 219 + 220 + module_init(init); 221 + module_exit(fini);
+188
net/netfilter/xt_helper.c
···
··· 1 + /* iptables module to match on related connections */ 2 + /* 3 + * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: 10 + * - Port to newnat infrastructure 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/skbuff.h> 15 + #include <linux/netfilter.h> 16 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 17 + #include <linux/netfilter_ipv4/ip_conntrack.h> 18 + #include <linux/netfilter_ipv4/ip_conntrack_core.h> 19 + #include <linux/netfilter_ipv4/ip_conntrack_helper.h> 20 + #else 21 + #include <net/netfilter/nf_conntrack.h> 22 + #include <net/netfilter/nf_conntrack_core.h> 23 + #include <net/netfilter/nf_conntrack_helper.h> 24 + #endif 25 + #include <linux/netfilter/x_tables.h> 26 + #include <linux/netfilter/xt_helper.h> 27 + 28 + MODULE_LICENSE("GPL"); 29 + MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); 30 + MODULE_DESCRIPTION("iptables helper match module"); 31 + MODULE_ALIAS("ipt_helper"); 32 + MODULE_ALIAS("ip6t_helper"); 33 + 34 + #if 0 35 + #define DEBUGP printk 36 + #else 37 + #define DEBUGP(format, args...) 38 + #endif 39 + 40 + #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 41 + static int 42 + match(const struct sk_buff *skb, 43 + const struct net_device *in, 44 + const struct net_device *out, 45 + const void *matchinfo, 46 + int offset, 47 + unsigned int protoff, 48 + int *hotdrop) 49 + { 50 + const struct xt_helper_info *info = matchinfo; 51 + struct ip_conntrack *ct; 52 + enum ip_conntrack_info ctinfo; 53 + int ret = info->invert; 54 + 55 + ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 56 + if (!ct) { 57 + DEBUGP("xt_helper: Eek! invalid conntrack?\n"); 58 + return ret; 59 + } 60 + 61 + if (!ct->master) { 62 + DEBUGP("xt_helper: conntrack %p has no master\n", ct); 63 + return ret; 64 + } 65 + 66 + read_lock_bh(&ip_conntrack_lock); 67 + if (!ct->master->helper) { 68 + DEBUGP("xt_helper: master ct %p has no helper\n", 69 + exp->expectant); 70 + goto out_unlock; 71 + } 72 + 73 + DEBUGP("master's name = %s , info->name = %s\n", 74 + ct->master->helper->name, info->name); 75 + 76 + if (info->name[0] == '\0') 77 + ret ^= 1; 78 + else 79 + ret ^= !strncmp(ct->master->helper->name, info->name, 80 + strlen(ct->master->helper->name)); 81 + out_unlock: 82 + read_unlock_bh(&ip_conntrack_lock); 83 + return ret; 84 + } 85 + 86 + #else /* CONFIG_IP_NF_CONNTRACK */ 87 + 88 + static int 89 + match(const struct sk_buff *skb, 90 + const struct net_device *in, 91 + const struct net_device *out, 92 + const void *matchinfo, 93 + int offset, 94 + unsigned int protoff, 95 + int *hotdrop) 96 + { 97 + const struct xt_helper_info *info = matchinfo; 98 + struct nf_conn *ct; 99 + enum ip_conntrack_info ctinfo; 100 + int ret = info->invert; 101 + 102 + ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 103 + if (!ct) { 104 + DEBUGP("xt_helper: Eek! invalid conntrack?\n"); 105 + return ret; 106 + } 107 + 108 + if (!ct->master) { 109 + DEBUGP("xt_helper: conntrack %p has no master\n", ct); 110 + return ret; 111 + } 112 + 113 + read_lock_bh(&nf_conntrack_lock); 114 + if (!ct->master->helper) { 115 + DEBUGP("xt_helper: master ct %p has no helper\n", 116 + exp->expectant); 117 + goto out_unlock; 118 + } 119 + 120 + DEBUGP("master's name = %s , info->name = %s\n", 121 + ct->master->helper->name, info->name); 122 + 123 + if (info->name[0] == '\0') 124 + ret ^= 1; 125 + else 126 + ret ^= !strncmp(ct->master->helper->name, info->name, 127 + strlen(ct->master->helper->name)); 128 + out_unlock: 129 + read_unlock_bh(&nf_conntrack_lock); 130 + return ret; 131 + } 132 + #endif 133 + 134 + static int check(const char *tablename, 135 + const void *inf, 136 + void *matchinfo, 137 + unsigned int matchsize, 138 + unsigned int hook_mask) 139 + { 140 + struct xt_helper_info *info = matchinfo; 141 + 142 + info->name[29] = '\0'; 143 + 144 + /* verify size */ 145 + if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info))) 146 + return 0; 147 + 148 + return 1; 149 + } 150 + 151 + static struct xt_match helper_match = { 152 + .name = "helper", 153 + .match = &match, 154 + .checkentry = &check, 155 + .me = THIS_MODULE, 156 + }; 157 + static struct xt_match helper6_match = { 158 + .name = "helper", 159 + .match = &match, 160 + .checkentry = &check, 161 + .me = THIS_MODULE, 162 + }; 163 + 164 + static int __init init(void) 165 + { 166 + int ret; 167 + need_conntrack(); 168 + 169 + ret = xt_register_match(AF_INET, &helper_match); 170 + if (ret < 0) 171 + return ret; 172 + 173 + ret = xt_register_match(AF_INET6, &helper6_match); 174 + if (ret < 0) 175 + xt_unregister_match(AF_INET, &helper_match); 176 + 177 + return ret; 178 + } 179 + 180 + static void __exit fini(void) 181 + { 182 + xt_unregister_match(AF_INET, &helper_match); 183 + xt_unregister_match(AF_INET6, &helper6_match); 184 + } 185 + 186 + module_init(init); 187 + module_exit(fini); 188 +
+98
net/netfilter/xt_length.c
···
··· 1 + /* Kernel module to match packet length. */ 2 + /* (C) 1999-2001 James Morris <jmorros@intercode.com.au> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/module.h> 10 + #include <linux/skbuff.h> 11 + #include <net/ip.h> 12 + 13 + #include <linux/netfilter/xt_length.h> 14 + #include <linux/netfilter/x_tables.h> 15 + 16 + MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 17 + MODULE_DESCRIPTION("IP tables packet length matching module"); 18 + MODULE_LICENSE("GPL"); 19 + MODULE_ALIAS("ipt_length"); 20 + MODULE_ALIAS("ip6t_length"); 21 + 22 + static int 23 + match(const struct sk_buff *skb, 24 + const struct net_device *in, 25 + const struct net_device *out, 26 + const void *matchinfo, 27 + int offset, 28 + unsigned int protoff, 29 + int *hotdrop) 30 + { 31 + const struct xt_length_info *info = matchinfo; 32 + u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); 33 + 34 + return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 35 + } 36 + 37 + static int 38 + match6(const struct sk_buff *skb, 39 + const struct net_device *in, 40 + const struct net_device *out, 41 + const void *matchinfo, 42 + int offset, 43 + unsigned int protoff, 44 + int *hotdrop) 45 + { 46 + const struct xt_length_info *info = matchinfo; 47 + u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); 48 + 49 + return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 50 + } 51 + 52 + static int 53 + checkentry(const char *tablename, 54 + const void *ip, 55 + void *matchinfo, 56 + unsigned int matchsize, 57 + unsigned int hook_mask) 58 + { 59 + if (matchsize != XT_ALIGN(sizeof(struct xt_length_info))) 60 + return 0; 61 + 62 + return 1; 63 + } 64 + 65 + static struct xt_match length_match = { 66 + .name = "length", 67 + .match = &match, 68 + .checkentry = &checkentry, 69 + .me = THIS_MODULE, 70 + }; 71 + static struct xt_match length6_match = { 72 + .name = "length", 73 + .match = &match6, 74 + .checkentry = &checkentry, 75 + .me = THIS_MODULE, 76 + }; 77 + 78 + static int __init init(void) 79 + { 80 + int ret; 81 + ret = xt_register_match(AF_INET, &length_match); 82 + if (ret) 83 + return ret; 84 + ret = xt_register_match(AF_INET6, &length6_match); 85 + if (ret) 86 + xt_unregister_match(AF_INET, &length_match); 87 + 88 + return ret; 89 + } 90 + 91 + static void __exit fini(void) 92 + { 93 + xt_unregister_match(AF_INET, &length_match); 94 + xt_unregister_match(AF_INET6, &length6_match); 95 + } 96 + 97 + module_init(init); 98 + module_exit(fini);
+175
net/netfilter/xt_limit.c
···
··· 1 + /* Kernel module to control the rate 2 + * 3 + * 2 September 1999: Changed from the target RATE to the match 4 + * `limit', removed logging. Did I mention that 5 + * Alexey is a fucking genius? 6 + * Rusty Russell (rusty@rustcorp.com.au). */ 7 + 8 + /* (C) 1999 J�r�me de Vivie <devivie@info.enserb.u-bordeaux.fr> 9 + * (C) 1999 Herv� Eychenne <eychenne@info.enserb.u-bordeaux.fr> 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License version 2 as 13 + * published by the Free Software Foundation. 14 + */ 15 + 16 + #include <linux/module.h> 17 + #include <linux/skbuff.h> 18 + #include <linux/spinlock.h> 19 + #include <linux/interrupt.h> 20 + 21 + #include <linux/netfilter/x_tables.h> 22 + #include <linux/netfilter/xt_limit.h> 23 + 24 + MODULE_LICENSE("GPL"); 25 + MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>"); 26 + MODULE_DESCRIPTION("iptables rate limit match"); 27 + MODULE_ALIAS("ipt_limit"); 28 + MODULE_ALIAS("ip6t_limit"); 29 + 30 + /* The algorithm used is the Simple Token Bucket Filter (TBF) 31 + * see net/sched/sch_tbf.c in the linux source tree 32 + */ 33 + 34 + static DEFINE_SPINLOCK(limit_lock); 35 + 36 + /* Rusty: This is my (non-mathematically-inclined) understanding of 37 + this algorithm. The `average rate' in jiffies becomes your initial 38 + amount of credit `credit' and the most credit you can ever have 39 + `credit_cap'. The `peak rate' becomes the cost of passing the 40 + test, `cost'. 41 + 42 + `prev' tracks the last packet hit: you gain one credit per jiffy. 43 + If you get credit balance more than this, the extra credit is 44 + discarded. Every time the match passes, you lose `cost' credits; 45 + if you don't have that many, the test fails. 46 + 47 + See Alexey's formal explanation in net/sched/sch_tbf.c. 48 + 49 + To get the maxmum range, we multiply by this factor (ie. you get N 50 + credits per jiffy). We want to allow a rate as low as 1 per day 51 + (slowest userspace tool allows), which means 52 + CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32. ie. */ 53 + #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24)) 54 + 55 + /* Repeated shift and or gives us all 1s, final shift and add 1 gives 56 + * us the power of 2 below the theoretical max, so GCC simply does a 57 + * shift. */ 58 + #define _POW2_BELOW2(x) ((x)|((x)>>1)) 59 + #define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2)) 60 + #define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4)) 61 + #define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8)) 62 + #define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16)) 63 + #define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1) 64 + 65 + #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 66 + 67 + static int 68 + ipt_limit_match(const struct sk_buff *skb, 69 + const struct net_device *in, 70 + const struct net_device *out, 71 + const void *matchinfo, 72 + int offset, 73 + unsigned int protoff, 74 + int *hotdrop) 75 + { 76 + struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master; 77 + unsigned long now = jiffies; 78 + 79 + spin_lock_bh(&limit_lock); 80 + r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; 81 + if (r->credit > r->credit_cap) 82 + r->credit = r->credit_cap; 83 + 84 + if (r->credit >= r->cost) { 85 + /* We're not limited. */ 86 + r->credit -= r->cost; 87 + spin_unlock_bh(&limit_lock); 88 + return 1; 89 + } 90 + 91 + spin_unlock_bh(&limit_lock); 92 + return 0; 93 + } 94 + 95 + /* Precision saver. */ 96 + static u_int32_t 97 + user2credits(u_int32_t user) 98 + { 99 + /* If multiplying would overflow... */ 100 + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 101 + /* Divide first. */ 102 + return (user / XT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 103 + 104 + return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; 105 + } 106 + 107 + static int 108 + ipt_limit_checkentry(const char *tablename, 109 + const void *inf, 110 + void *matchinfo, 111 + unsigned int matchsize, 112 + unsigned int hook_mask) 113 + { 114 + struct xt_rateinfo *r = matchinfo; 115 + 116 + if (matchsize != XT_ALIGN(sizeof(struct xt_rateinfo))) 117 + return 0; 118 + 119 + /* Check for overflow. */ 120 + if (r->burst == 0 121 + || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 122 + printk("Overflow in xt_limit, try lower: %u/%u\n", 123 + r->avg, r->burst); 124 + return 0; 125 + } 126 + 127 + /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies * 128 + 128. */ 129 + r->prev = jiffies; 130 + r->credit = user2credits(r->avg * r->burst); /* Credits full. */ 131 + r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 132 + r->cost = user2credits(r->avg); 133 + 134 + /* For SMP, we only want to use one set of counters. */ 135 + r->master = r; 136 + 137 + return 1; 138 + } 139 + 140 + static struct xt_match ipt_limit_reg = { 141 + .name = "limit", 142 + .match = ipt_limit_match, 143 + .checkentry = ipt_limit_checkentry, 144 + .me = THIS_MODULE, 145 + }; 146 + static struct xt_match limit6_reg = { 147 + .name = "limit", 148 + .match = ipt_limit_match, 149 + .checkentry = ipt_limit_checkentry, 150 + .me = THIS_MODULE, 151 + }; 152 + 153 + static int __init init(void) 154 + { 155 + int ret; 156 + 157 + ret = xt_register_match(AF_INET, &ipt_limit_reg); 158 + if (ret) 159 + return ret; 160 + 161 + ret = xt_register_match(AF_INET6, &limit6_reg); 162 + if (ret) 163 + xt_unregister_match(AF_INET, &ipt_limit_reg); 164 + 165 + return ret; 166 + } 167 + 168 + static void __exit fini(void) 169 + { 170 + xt_unregister_match(AF_INET, &ipt_limit_reg); 171 + xt_unregister_match(AF_INET6, &limit6_reg); 172 + } 173 + 174 + module_init(init); 175 + module_exit(fini);
+100
net/netfilter/xt_mac.c
···
··· 1 + /* Kernel module to match MAC address parameters. */ 2 + 3 + /* (C) 1999-2001 Paul `Rusty' Russell 4 + * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/if_ether.h> 14 + #include <linux/etherdevice.h> 15 + 16 + #include <linux/netfilter_ipv4.h> 17 + #include <linux/netfilter/xt_mac.h> 18 + #include <linux/netfilter/x_tables.h> 19 + 20 + MODULE_LICENSE("GPL"); 21 + MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 22 + MODULE_DESCRIPTION("iptables mac matching module"); 23 + MODULE_ALIAS("ipt_mac"); 24 + MODULE_ALIAS("ip6t_mac"); 25 + 26 + static int 27 + match(const struct sk_buff *skb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + const void *matchinfo, 31 + int offset, 32 + unsigned int protoff, 33 + int *hotdrop) 34 + { 35 + const struct xt_mac_info *info = matchinfo; 36 + 37 + /* Is mac pointer valid? */ 38 + return (skb->mac.raw >= skb->head 39 + && (skb->mac.raw + ETH_HLEN) <= skb->data 40 + /* If so, compare... */ 41 + && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 42 + ^ info->invert)); 43 + } 44 + 45 + static int 46 + ipt_mac_checkentry(const char *tablename, 47 + const void *inf, 48 + void *matchinfo, 49 + unsigned int matchsize, 50 + unsigned int hook_mask) 51 + { 52 + /* FORWARD isn't always valid, but it's nice to be able to do --RR */ 53 + if (hook_mask 54 + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) 55 + | (1 << NF_IP_FORWARD))) { 56 + printk("xt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); 57 + return 0; 58 + } 59 + 60 + if (matchsize != XT_ALIGN(sizeof(struct xt_mac_info))) 61 + return 0; 62 + 63 + return 1; 64 + } 65 + 66 + static struct xt_match mac_match = { 67 + .name = "mac", 68 + .match = &match, 69 + .checkentry = &ipt_mac_checkentry, 70 + .me = THIS_MODULE, 71 + }; 72 + static struct xt_match mac6_match = { 73 + .name = "mac", 74 + .match = &match, 75 + .checkentry = &ipt_mac_checkentry, 76 + .me = THIS_MODULE, 77 + }; 78 + 79 + static int __init init(void) 80 + { 81 + int ret; 82 + ret = xt_register_match(AF_INET, &mac_match); 83 + if (ret) 84 + return ret; 85 + 86 + ret = xt_register_match(AF_INET6, &mac6_match); 87 + if (ret) 88 + xt_unregister_match(AF_INET, &mac_match); 89 + 90 + return ret; 91 + } 92 + 93 + static void __exit fini(void) 94 + { 95 + xt_unregister_match(AF_INET, &mac_match); 96 + xt_unregister_match(AF_INET6, &mac6_match); 97 + } 98 + 99 + module_init(init); 100 + module_exit(fini);
+91
net/netfilter/xt_mark.c
···
··· 1 + /* Kernel module to match NFMARK values. */ 2 + 3 + /* (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/skbuff.h> 12 + 13 + #include <linux/netfilter/xt_mark.h> 14 + #include <linux/netfilter/x_tables.h> 15 + 16 + MODULE_LICENSE("GPL"); 17 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 18 + MODULE_DESCRIPTION("iptables mark matching module"); 19 + MODULE_ALIAS("ipt_mark"); 20 + MODULE_ALIAS("ip6t_mark"); 21 + 22 + static int 23 + match(const struct sk_buff *skb, 24 + const struct net_device *in, 25 + const struct net_device *out, 26 + const void *matchinfo, 27 + int offset, 28 + unsigned int protoff, 29 + int *hotdrop) 30 + { 31 + const struct xt_mark_info *info = matchinfo; 32 + 33 + return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 34 + } 35 + 36 + static int 37 + checkentry(const char *tablename, 38 + const void *entry, 39 + void *matchinfo, 40 + unsigned int matchsize, 41 + unsigned int hook_mask) 42 + { 43 + struct xt_mark_info *minfo = (struct xt_mark_info *) matchinfo; 44 + 45 + if (matchsize != XT_ALIGN(sizeof(struct xt_mark_info))) 46 + return 0; 47 + 48 + if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 49 + printk(KERN_WARNING "mark: only supports 32bit mark\n"); 50 + return 0; 51 + } 52 + 53 + return 1; 54 + } 55 + 56 + static struct xt_match mark_match = { 57 + .name = "mark", 58 + .match = &match, 59 + .checkentry = &checkentry, 60 + .me = THIS_MODULE, 61 + }; 62 + 63 + static struct xt_match mark6_match = { 64 + .name = "mark", 65 + .match = &match, 66 + .checkentry = &checkentry, 67 + .me = THIS_MODULE, 68 + }; 69 + 70 + static int __init init(void) 71 + { 72 + int ret; 73 + ret = xt_register_match(AF_INET, &mark_match); 74 + if (ret) 75 + return ret; 76 + 77 + ret = xt_register_match(AF_INET6, &mark6_match); 78 + if (ret) 79 + xt_unregister_match(AF_INET, &mark_match); 80 + 81 + return ret; 82 + } 83 + 84 + static void __exit fini(void) 85 + { 86 + xt_unregister_match(AF_INET, &mark_match); 87 + xt_unregister_match(AF_INET6, &mark6_match); 88 + } 89 + 90 + module_init(init); 91 + module_exit(fini);
+155
net/netfilter/xt_physdev.c
···
··· 1 + /* Kernel module to match the bridge port in and 2 + * out device for IP packets coming into contact with a bridge. */ 3 + 4 + /* (C) 2001-2003 Bart De Schuymer <bdschuym@pandora.be> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <linux/netfilter/xt_physdev.h> 14 + #include <linux/netfilter/x_tables.h> 15 + #include <linux/netfilter_bridge.h> 16 + #define MATCH 1 17 + #define NOMATCH 0 18 + 19 + MODULE_LICENSE("GPL"); 20 + MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 21 + MODULE_DESCRIPTION("iptables bridge physical device match module"); 22 + MODULE_ALIAS("ipt_physdev"); 23 + MODULE_ALIAS("ip6t_physdev"); 24 + 25 + static int 26 + match(const struct sk_buff *skb, 27 + const struct net_device *in, 28 + const struct net_device *out, 29 + const void *matchinfo, 30 + int offset, 31 + unsigned int protoff, 32 + int *hotdrop) 33 + { 34 + int i; 35 + static const char nulldevname[IFNAMSIZ]; 36 + const struct xt_physdev_info *info = matchinfo; 37 + unsigned int ret; 38 + const char *indev, *outdev; 39 + struct nf_bridge_info *nf_bridge; 40 + 41 + /* Not a bridged IP packet or no info available yet: 42 + * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 43 + * the destination device will be a bridge. */ 44 + if (!(nf_bridge = skb->nf_bridge)) { 45 + /* Return MATCH if the invert flags of the used options are on */ 46 + if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 47 + !(info->invert & XT_PHYSDEV_OP_BRIDGED)) 48 + return NOMATCH; 49 + if ((info->bitmask & XT_PHYSDEV_OP_ISIN) && 50 + !(info->invert & XT_PHYSDEV_OP_ISIN)) 51 + return NOMATCH; 52 + if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) && 53 + !(info->invert & XT_PHYSDEV_OP_ISOUT)) 54 + return NOMATCH; 55 + if ((info->bitmask & XT_PHYSDEV_OP_IN) && 56 + !(info->invert & XT_PHYSDEV_OP_IN)) 57 + return NOMATCH; 58 + if ((info->bitmask & XT_PHYSDEV_OP_OUT) && 59 + !(info->invert & XT_PHYSDEV_OP_OUT)) 60 + return NOMATCH; 61 + return MATCH; 62 + } 63 + 64 + /* This only makes sense in the FORWARD and POSTROUTING chains */ 65 + if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 66 + (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 67 + !(info->invert & XT_PHYSDEV_OP_BRIDGED))) 68 + return NOMATCH; 69 + 70 + if ((info->bitmask & XT_PHYSDEV_OP_ISIN && 71 + (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || 72 + (info->bitmask & XT_PHYSDEV_OP_ISOUT && 73 + (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) 74 + return NOMATCH; 75 + 76 + if (!(info->bitmask & XT_PHYSDEV_OP_IN)) 77 + goto match_outdev; 78 + indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 79 + for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 80 + ret |= (((const unsigned int *)indev)[i] 81 + ^ ((const unsigned int *)info->physindev)[i]) 82 + & ((const unsigned int *)info->in_mask)[i]; 83 + } 84 + 85 + if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN)) 86 + return NOMATCH; 87 + 88 + match_outdev: 89 + if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) 90 + return MATCH; 91 + outdev = nf_bridge->physoutdev ? 92 + nf_bridge->physoutdev->name : nulldevname; 93 + for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 94 + ret |= (((const unsigned int *)outdev)[i] 95 + ^ ((const unsigned int *)info->physoutdev)[i]) 96 + & ((const unsigned int *)info->out_mask)[i]; 97 + } 98 + 99 + return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT); 100 + } 101 + 102 + static int 103 + checkentry(const char *tablename, 104 + const void *ip, 105 + void *matchinfo, 106 + unsigned int matchsize, 107 + unsigned int hook_mask) 108 + { 109 + const struct xt_physdev_info *info = matchinfo; 110 + 111 + if (matchsize != XT_ALIGN(sizeof(struct xt_physdev_info))) 112 + return 0; 113 + if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 114 + info->bitmask & ~XT_PHYSDEV_OP_MASK) 115 + return 0; 116 + return 1; 117 + } 118 + 119 + static struct xt_match physdev_match = { 120 + .name = "physdev", 121 + .match = &match, 122 + .checkentry = &checkentry, 123 + .me = THIS_MODULE, 124 + }; 125 + 126 + static struct xt_match physdev6_match = { 127 + .name = "physdev", 128 + .match = &match, 129 + .checkentry = &checkentry, 130 + .me = THIS_MODULE, 131 + }; 132 + 133 + static int __init init(void) 134 + { 135 + int ret; 136 + 137 + ret = xt_register_match(AF_INET, &physdev_match); 138 + if (ret < 0) 139 + return ret; 140 + 141 + ret = xt_register_match(AF_INET6, &physdev6_match); 142 + if (ret < 0) 143 + xt_unregister_match(AF_INET, &physdev_match); 144 + 145 + return ret; 146 + } 147 + 148 + static void __exit fini(void) 149 + { 150 + xt_unregister_match(AF_INET, &physdev_match); 151 + xt_unregister_match(AF_INET6, &physdev6_match); 152 + } 153 + 154 + module_init(init); 155 + module_exit(fini);
+82
net/netfilter/xt_pkttype.c
···
··· 1 + /* (C) 1999-2001 Michal Ludvig <michal@logix.cz> 2 + * 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. 6 + */ 7 + 8 + #include <linux/module.h> 9 + #include <linux/skbuff.h> 10 + #include <linux/if_ether.h> 11 + #include <linux/if_packet.h> 12 + 13 + #include <linux/netfilter/xt_pkttype.h> 14 + #include <linux/netfilter/x_tables.h> 15 + 16 + MODULE_LICENSE("GPL"); 17 + MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>"); 18 + MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); 19 + MODULE_ALIAS("ipt_pkttype"); 20 + MODULE_ALIAS("ip6t_pkttype"); 21 + 22 + static int match(const struct sk_buff *skb, 23 + const struct net_device *in, 24 + const struct net_device *out, 25 + const void *matchinfo, 26 + int offset, 27 + unsigned int protoff, 28 + int *hotdrop) 29 + { 30 + const struct xt_pkttype_info *info = matchinfo; 31 + 32 + return (skb->pkt_type == info->pkttype) ^ info->invert; 33 + } 34 + 35 + static int checkentry(const char *tablename, 36 + const void *ip, 37 + void *matchinfo, 38 + unsigned int matchsize, 39 + unsigned int hook_mask) 40 + { 41 + if (matchsize != XT_ALIGN(sizeof(struct xt_pkttype_info))) 42 + return 0; 43 + 44 + return 1; 45 + } 46 + 47 + static struct xt_match pkttype_match = { 48 + .name = "pkttype", 49 + .match = &match, 50 + .checkentry = &checkentry, 51 + .me = THIS_MODULE, 52 + }; 53 + static struct xt_match pkttype6_match = { 54 + .name = "pkttype", 55 + .match = &match, 56 + .checkentry = &checkentry, 57 + .me = THIS_MODULE, 58 + }; 59 + 60 + 61 + static int __init init(void) 62 + { 63 + int ret; 64 + ret = xt_register_match(AF_INET, &pkttype_match); 65 + if (ret) 66 + return ret; 67 + 68 + ret = xt_register_match(AF_INET6, &pkttype6_match); 69 + if (ret) 70 + xt_unregister_match(AF_INET, &pkttype_match); 71 + 72 + return ret; 73 + } 74 + 75 + static void __exit fini(void) 76 + { 77 + xt_unregister_match(AF_INET, &pkttype_match); 78 + xt_unregister_match(AF_INET6, &pkttype6_match); 79 + } 80 + 81 + module_init(init); 82 + module_exit(fini);
+79
net/netfilter/xt_realm.c
···
··· 1 + /* IP tables module for matching the routing realm 2 + * 3 + * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $ 4 + * 5 + * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/skbuff.h> 14 + #include <linux/netdevice.h> 15 + #include <net/route.h> 16 + 17 + #include <linux/netfilter_ipv4.h> 18 + #include <linux/netfilter/xt_realm.h> 19 + #include <linux/netfilter/x_tables.h> 20 + 21 + MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>"); 22 + MODULE_LICENSE("GPL"); 23 + MODULE_DESCRIPTION("X_tables realm match"); 24 + MODULE_ALIAS("ipt_realm"); 25 + 26 + static int 27 + match(const struct sk_buff *skb, 28 + const struct net_device *in, 29 + const struct net_device *out, 30 + const void *matchinfo, 31 + int offset, 32 + unsigned int protoff, 33 + int *hotdrop) 34 + { 35 + const struct xt_realm_info *info = matchinfo; 36 + struct dst_entry *dst = skb->dst; 37 + 38 + return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 39 + } 40 + 41 + static int check(const char *tablename, 42 + const void *ip, 43 + void *matchinfo, 44 + unsigned int matchsize, 45 + unsigned int hook_mask) 46 + { 47 + if (hook_mask 48 + & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | 49 + (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { 50 + printk("xt_realm: only valid for POST_ROUTING, LOCAL_OUT, " 51 + "LOCAL_IN or FORWARD.\n"); 52 + return 0; 53 + } 54 + if (matchsize != XT_ALIGN(sizeof(struct xt_realm_info))) { 55 + printk("xt_realm: invalid matchsize.\n"); 56 + return 0; 57 + } 58 + return 1; 59 + } 60 + 61 + static struct xt_match realm_match = { 62 + .name = "realm", 63 + .match = match, 64 + .checkentry = check, 65 + .me = THIS_MODULE 66 + }; 67 + 68 + static int __init init(void) 69 + { 70 + return xt_register_match(AF_INET, &realm_match); 71 + } 72 + 73 + static void __exit fini(void) 74 + { 75 + xt_unregister_match(AF_INET, &realm_match); 76 + } 77 + 78 + module_init(init); 79 + module_exit(fini);
+250
net/netfilter/xt_sctp.c
···
··· 1 + #include <linux/module.h> 2 + #include <linux/skbuff.h> 3 + #include <net/ip.h> 4 + #include <net/ipv6.h> 5 + #include <linux/sctp.h> 6 + 7 + #include <linux/netfilter/x_tables.h> 8 + #include <linux/netfilter/xt_sctp.h> 9 + #include <linux/netfilter_ipv4/ip_tables.h> 10 + #include <linux/netfilter_ipv6/ip6_tables.h> 11 + 12 + MODULE_LICENSE("GPL"); 13 + MODULE_AUTHOR("Kiran Kumar Immidi"); 14 + MODULE_DESCRIPTION("Match for SCTP protocol packets"); 15 + MODULE_ALIAS("ipt_sctp"); 16 + 17 + #ifdef DEBUG_SCTP 18 + #define duprintf(format, args...) printk(format , ## args) 19 + #else 20 + #define duprintf(format, args...) 21 + #endif 22 + 23 + #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 24 + || (!!((invflag) & (option)) ^ (cond))) 25 + 26 + static int 27 + match_flags(const struct xt_sctp_flag_info *flag_info, 28 + const int flag_count, 29 + u_int8_t chunktype, 30 + u_int8_t chunkflags) 31 + { 32 + int i; 33 + 34 + for (i = 0; i < flag_count; i++) { 35 + if (flag_info[i].chunktype == chunktype) { 36 + return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; 37 + } 38 + } 39 + 40 + return 1; 41 + } 42 + 43 + static inline int 44 + match_packet(const struct sk_buff *skb, 45 + unsigned int offset, 46 + const u_int32_t *chunkmap, 47 + int chunk_match_type, 48 + const struct xt_sctp_flag_info *flag_info, 49 + const int flag_count, 50 + int *hotdrop) 51 + { 52 + u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 53 + sctp_chunkhdr_t _sch, *sch; 54 + 55 + #ifdef DEBUG_SCTP 56 + int i = 0; 57 + #endif 58 + 59 + if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) { 60 + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); 61 + } 62 + 63 + do { 64 + sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); 65 + if (sch == NULL) { 66 + duprintf("Dropping invalid SCTP packet.\n"); 67 + *hotdrop = 1; 68 + return 0; 69 + } 70 + 71 + duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 72 + ++i, offset, sch->type, htons(sch->length), sch->flags); 73 + 74 + offset += (htons(sch->length) + 3) & ~3; 75 + 76 + duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); 77 + 78 + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { 79 + switch (chunk_match_type) { 80 + case SCTP_CHUNK_MATCH_ANY: 81 + if (match_flags(flag_info, flag_count, 82 + sch->type, sch->flags)) { 83 + return 1; 84 + } 85 + break; 86 + 87 + case SCTP_CHUNK_MATCH_ALL: 88 + if (match_flags(flag_info, flag_count, 89 + sch->type, sch->flags)) { 90 + SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); 91 + } 92 + break; 93 + 94 + case SCTP_CHUNK_MATCH_ONLY: 95 + if (!match_flags(flag_info, flag_count, 96 + sch->type, sch->flags)) { 97 + return 0; 98 + } 99 + break; 100 + } 101 + } else { 102 + switch (chunk_match_type) { 103 + case SCTP_CHUNK_MATCH_ONLY: 104 + return 0; 105 + } 106 + } 107 + } while (offset < skb->len); 108 + 109 + switch (chunk_match_type) { 110 + case SCTP_CHUNK_MATCH_ALL: 111 + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); 112 + case SCTP_CHUNK_MATCH_ANY: 113 + return 0; 114 + case SCTP_CHUNK_MATCH_ONLY: 115 + return 1; 116 + } 117 + 118 + /* This will never be reached, but required to stop compiler whine */ 119 + return 0; 120 + } 121 + 122 + static int 123 + match(const struct sk_buff *skb, 124 + const struct net_device *in, 125 + const struct net_device *out, 126 + const void *matchinfo, 127 + int offset, 128 + unsigned int protoff, 129 + int *hotdrop) 130 + { 131 + const struct xt_sctp_info *info; 132 + sctp_sctphdr_t _sh, *sh; 133 + 134 + info = (const struct xt_sctp_info *)matchinfo; 135 + 136 + if (offset) { 137 + duprintf("Dropping non-first fragment.. FIXME\n"); 138 + return 0; 139 + } 140 + 141 + sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); 142 + if (sh == NULL) { 143 + duprintf("Dropping evil TCP offset=0 tinygram.\n"); 144 + *hotdrop = 1; 145 + return 0; 146 + } 147 + duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 148 + 149 + return SCCHECK(((ntohs(sh->source) >= info->spts[0]) 150 + && (ntohs(sh->source) <= info->spts[1])), 151 + XT_SCTP_SRC_PORTS, info->flags, info->invflags) 152 + && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) 153 + && (ntohs(sh->dest) <= info->dpts[1])), 154 + XT_SCTP_DEST_PORTS, info->flags, info->invflags) 155 + && SCCHECK(match_packet(skb, protoff, 156 + info->chunkmap, info->chunk_match_type, 157 + info->flag_info, info->flag_count, 158 + hotdrop), 159 + XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 160 + } 161 + 162 + static int 163 + checkentry(const char *tablename, 164 + const void *inf, 165 + void *matchinfo, 166 + unsigned int matchsize, 167 + unsigned int hook_mask) 168 + { 169 + const struct xt_sctp_info *info; 170 + const struct ipt_ip *ip = inf; 171 + 172 + info = (const struct xt_sctp_info *)matchinfo; 173 + 174 + return ip->proto == IPPROTO_SCTP 175 + && !(ip->invflags & XT_INV_PROTO) 176 + && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) 177 + && !(info->flags & ~XT_SCTP_VALID_FLAGS) 178 + && !(info->invflags & ~XT_SCTP_VALID_FLAGS) 179 + && !(info->invflags & ~info->flags) 180 + && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || 181 + (info->chunk_match_type & 182 + (SCTP_CHUNK_MATCH_ALL 183 + | SCTP_CHUNK_MATCH_ANY 184 + | SCTP_CHUNK_MATCH_ONLY))); 185 + } 186 + 187 + static int 188 + checkentry6(const char *tablename, 189 + const void *inf, 190 + void *matchinfo, 191 + unsigned int matchsize, 192 + unsigned int hook_mask) 193 + { 194 + const struct xt_sctp_info *info; 195 + const struct ip6t_ip6 *ip = inf; 196 + 197 + info = (const struct xt_sctp_info *)matchinfo; 198 + 199 + return ip->proto == IPPROTO_SCTP 200 + && !(ip->invflags & XT_INV_PROTO) 201 + && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) 202 + && !(info->flags & ~XT_SCTP_VALID_FLAGS) 203 + && !(info->invflags & ~XT_SCTP_VALID_FLAGS) 204 + && !(info->invflags & ~info->flags) 205 + && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || 206 + (info->chunk_match_type & 207 + (SCTP_CHUNK_MATCH_ALL 208 + | SCTP_CHUNK_MATCH_ANY 209 + | SCTP_CHUNK_MATCH_ONLY))); 210 + } 211 + 212 + 213 + static struct xt_match sctp_match = 214 + { 215 + .name = "sctp", 216 + .match = &match, 217 + .checkentry = &checkentry, 218 + .me = THIS_MODULE 219 + }; 220 + static struct xt_match sctp6_match = 221 + { 222 + .name = "sctp", 223 + .match = &match, 224 + .checkentry = &checkentry6, 225 + .me = THIS_MODULE 226 + }; 227 + 228 + 229 + static int __init init(void) 230 + { 231 + int ret; 232 + ret = xt_register_match(AF_INET, &sctp_match); 233 + if (ret) 234 + return ret; 235 + 236 + ret = xt_register_match(AF_INET6, &sctp6_match); 237 + if (ret) 238 + xt_unregister_match(AF_INET, &sctp_match); 239 + 240 + return ret; 241 + } 242 + 243 + static void __exit fini(void) 244 + { 245 + xt_unregister_match(AF_INET6, &sctp6_match); 246 + xt_unregister_match(AF_INET, &sctp_match); 247 + } 248 + 249 + module_init(init); 250 + module_exit(fini);
+96
net/netfilter/xt_state.c
···
··· 1 + /* Kernel module to match connection tracking information. */ 2 + 3 + /* (C) 1999-2001 Paul `Rusty' Russell 4 + * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <net/netfilter/nf_conntrack_compat.h> 14 + #include <linux/netfilter/x_tables.h> 15 + #include <linux/netfilter/xt_state.h> 16 + 17 + MODULE_LICENSE("GPL"); 18 + MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 19 + MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module"); 20 + MODULE_ALIAS("ipt_state"); 21 + MODULE_ALIAS("ip6t_state"); 22 + 23 + static int 24 + match(const struct sk_buff *skb, 25 + const struct net_device *in, 26 + const struct net_device *out, 27 + const void *matchinfo, 28 + int offset, 29 + unsigned int protoff, 30 + int *hotdrop) 31 + { 32 + const struct xt_state_info *sinfo = matchinfo; 33 + enum ip_conntrack_info ctinfo; 34 + unsigned int statebit; 35 + 36 + if (nf_ct_is_untracked(skb)) 37 + statebit = XT_STATE_UNTRACKED; 38 + else if (!nf_ct_get_ctinfo(skb, &ctinfo)) 39 + statebit = XT_STATE_INVALID; 40 + else 41 + statebit = XT_STATE_BIT(ctinfo); 42 + 43 + return (sinfo->statemask & statebit); 44 + } 45 + 46 + static int check(const char *tablename, 47 + const void *ip, 48 + void *matchinfo, 49 + unsigned int matchsize, 50 + unsigned int hook_mask) 51 + { 52 + if (matchsize != XT_ALIGN(sizeof(struct xt_state_info))) 53 + return 0; 54 + 55 + return 1; 56 + } 57 + 58 + static struct xt_match state_match = { 59 + .name = "state", 60 + .match = &match, 61 + .checkentry = &check, 62 + .me = THIS_MODULE, 63 + }; 64 + 65 + static struct xt_match state6_match = { 66 + .name = "state", 67 + .match = &match, 68 + .checkentry = &check, 69 + .me = THIS_MODULE, 70 + }; 71 + 72 + static int __init init(void) 73 + { 74 + int ret; 75 + 76 + need_conntrack(); 77 + 78 + ret = xt_register_match(AF_INET, &state_match); 79 + if (ret < 0) 80 + return ret; 81 + 82 + ret = xt_register_match(AF_INET6, &state6_match); 83 + if (ret < 0) 84 + xt_unregister_match(AF_INET,&state_match); 85 + 86 + return ret; 87 + } 88 + 89 + static void __exit fini(void) 90 + { 91 + xt_unregister_match(AF_INET, &state_match); 92 + xt_unregister_match(AF_INET6, &state6_match); 93 + } 94 + 95 + module_init(init); 96 + module_exit(fini);
+111
net/netfilter/xt_string.c
···
··· 1 + /* String matching match for iptables 2 + * 3 + * (C) 2005 Pablo Neira Ayuso <pablo@eurodev.net> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #include <linux/init.h> 11 + #include <linux/module.h> 12 + #include <linux/kernel.h> 13 + #include <linux/skbuff.h> 14 + #include <linux/netfilter/x_tables.h> 15 + #include <linux/netfilter/xt_string.h> 16 + #include <linux/textsearch.h> 17 + 18 + MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>"); 19 + MODULE_DESCRIPTION("IP tables string match module"); 20 + MODULE_LICENSE("GPL"); 21 + MODULE_ALIAS("ipt_string"); 22 + MODULE_ALIAS("ip6t_string"); 23 + 24 + static int match(const struct sk_buff *skb, 25 + const struct net_device *in, 26 + const struct net_device *out, 27 + const void *matchinfo, 28 + int offset, 29 + unsigned int protoff, 30 + int *hotdrop) 31 + { 32 + struct ts_state state; 33 + struct xt_string_info *conf = (struct xt_string_info *) matchinfo; 34 + 35 + memset(&state, 0, sizeof(struct ts_state)); 36 + 37 + return (skb_find_text((struct sk_buff *)skb, conf->from_offset, 38 + conf->to_offset, conf->config, &state) 39 + != UINT_MAX) && !conf->invert; 40 + } 41 + 42 + #define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m) 43 + 44 + static int checkentry(const char *tablename, 45 + const void *ip, 46 + void *matchinfo, 47 + unsigned int matchsize, 48 + unsigned int hook_mask) 49 + { 50 + struct xt_string_info *conf = matchinfo; 51 + struct ts_config *ts_conf; 52 + 53 + if (matchsize != XT_ALIGN(sizeof(struct xt_string_info))) 54 + return 0; 55 + 56 + /* Damn, can't handle this case properly with iptables... */ 57 + if (conf->from_offset > conf->to_offset) 58 + return 0; 59 + 60 + ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, 61 + GFP_KERNEL, TS_AUTOLOAD); 62 + if (IS_ERR(ts_conf)) 63 + return 0; 64 + 65 + conf->config = ts_conf; 66 + 67 + return 1; 68 + } 69 + 70 + static void destroy(void *matchinfo, unsigned int matchsize) 71 + { 72 + textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 73 + } 74 + 75 + static struct xt_match string_match = { 76 + .name = "string", 77 + .match = match, 78 + .checkentry = checkentry, 79 + .destroy = destroy, 80 + .me = THIS_MODULE 81 + }; 82 + static struct xt_match string6_match = { 83 + .name = "string", 84 + .match = match, 85 + .checkentry = checkentry, 86 + .destroy = destroy, 87 + .me = THIS_MODULE 88 + }; 89 + 90 + static int __init init(void) 91 + { 92 + int ret; 93 + 94 + ret = xt_register_match(AF_INET, &string_match); 95 + if (ret) 96 + return ret; 97 + ret = xt_register_match(AF_INET6, &string6_match); 98 + if (ret) 99 + xt_unregister_match(AF_INET, &string_match); 100 + 101 + return ret; 102 + } 103 + 104 + static void __exit fini(void) 105 + { 106 + xt_unregister_match(AF_INET, &string_match); 107 + xt_unregister_match(AF_INET6, &string6_match); 108 + } 109 + 110 + module_init(init); 111 + module_exit(fini);
+172
net/netfilter/xt_tcpmss.c
···
··· 1 + /* Kernel module to match TCP MSS values. */ 2 + 3 + /* Copyright (C) 2000 Marc Boucher <marc@mbsi.ca> 4 + * Portions (C) 2005 by Harald Welte <laforge@netfilter.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/module.h> 12 + #include <linux/skbuff.h> 13 + #include <net/tcp.h> 14 + 15 + #include <linux/netfilter/xt_tcpmss.h> 16 + #include <linux/netfilter/x_tables.h> 17 + 18 + #include <linux/netfilter_ipv4/ip_tables.h> 19 + #include <linux/netfilter_ipv6/ip6_tables.h> 20 + 21 + #define TH_SYN 0x02 22 + 23 + MODULE_LICENSE("GPL"); 24 + MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 25 + MODULE_DESCRIPTION("iptables TCP MSS match module"); 26 + MODULE_ALIAS("ipt_tcpmss"); 27 + 28 + /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ 29 + static inline int 30 + mssoption_match(u_int16_t min, u_int16_t max, 31 + const struct sk_buff *skb, 32 + unsigned int protoff, 33 + int invert, 34 + int *hotdrop) 35 + { 36 + struct tcphdr _tcph, *th; 37 + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 38 + u8 _opt[15 * 4 - sizeof(_tcph)], *op; 39 + unsigned int i, optlen; 40 + 41 + /* If we don't have the whole header, drop packet. */ 42 + th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 43 + if (th == NULL) 44 + goto dropit; 45 + 46 + /* Malformed. */ 47 + if (th->doff*4 < sizeof(*th)) 48 + goto dropit; 49 + 50 + optlen = th->doff*4 - sizeof(*th); 51 + if (!optlen) 52 + goto out; 53 + 54 + /* Truncated options. */ 55 + op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); 56 + if (op == NULL) 57 + goto dropit; 58 + 59 + for (i = 0; i < optlen; ) { 60 + if (op[i] == TCPOPT_MSS 61 + && (optlen - i) >= TCPOLEN_MSS 62 + && op[i+1] == TCPOLEN_MSS) { 63 + u_int16_t mssval; 64 + 65 + mssval = (op[i+2] << 8) | op[i+3]; 66 + 67 + return (mssval >= min && mssval <= max) ^ invert; 68 + } 69 + if (op[i] < 2) i++; 70 + else i += op[i+1]?:1; 71 + } 72 + out: 73 + return invert; 74 + 75 + dropit: 76 + *hotdrop = 1; 77 + return 0; 78 + } 79 + 80 + static int 81 + match(const struct sk_buff *skb, 82 + const struct net_device *in, 83 + const struct net_device *out, 84 + const void *matchinfo, 85 + int offset, 86 + unsigned int protoff, 87 + int *hotdrop) 88 + { 89 + const struct xt_tcpmss_match_info *info = matchinfo; 90 + 91 + return mssoption_match(info->mss_min, info->mss_max, skb, protoff, 92 + info->invert, hotdrop); 93 + } 94 + 95 + static int 96 + checkentry(const char *tablename, 97 + const void *ipinfo, 98 + void *matchinfo, 99 + unsigned int matchsize, 100 + unsigned int hook_mask) 101 + { 102 + const struct ipt_ip *ip = ipinfo; 103 + if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) 104 + return 0; 105 + 106 + /* Must specify -p tcp */ 107 + if (ip->proto != IPPROTO_TCP || (ip->invflags & IPT_INV_PROTO)) { 108 + printk("tcpmss: Only works on TCP packets\n"); 109 + return 0; 110 + } 111 + 112 + return 1; 113 + } 114 + 115 + static int 116 + checkentry6(const char *tablename, 117 + const void *ipinfo, 118 + void *matchinfo, 119 + unsigned int matchsize, 120 + unsigned int hook_mask) 121 + { 122 + const struct ip6t_ip6 *ip = ipinfo; 123 + 124 + if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) 125 + return 0; 126 + 127 + /* Must specify -p tcp */ 128 + if (ip->proto != IPPROTO_TCP || (ip->invflags & XT_INV_PROTO)) { 129 + printk("tcpmss: Only works on TCP packets\n"); 130 + return 0; 131 + } 132 + 133 + return 1; 134 + } 135 + 136 + static struct xt_match tcpmss_match = { 137 + .name = "tcpmss", 138 + .match = &match, 139 + .checkentry = &checkentry, 140 + .me = THIS_MODULE, 141 + }; 142 + 143 + static struct xt_match tcpmss6_match = { 144 + .name = "tcpmss", 145 + .match = &match, 146 + .checkentry = &checkentry6, 147 + .me = THIS_MODULE, 148 + }; 149 + 150 + 151 + static int __init init(void) 152 + { 153 + int ret; 154 + ret = xt_register_match(AF_INET, &tcpmss_match); 155 + if (ret) 156 + return ret; 157 + 158 + ret = xt_register_match(AF_INET6, &tcpmss6_match); 159 + if (ret) 160 + xt_unregister_match(AF_INET, &tcpmss_match); 161 + 162 + return ret; 163 + } 164 + 165 + static void __exit fini(void) 166 + { 167 + xt_unregister_match(AF_INET6, &tcpmss6_match); 168 + xt_unregister_match(AF_INET, &tcpmss_match); 169 + } 170 + 171 + module_init(init); 172 + module_exit(fini);
+333
net/netfilter/xt_tcpudp.c
···
··· 1 + #include <linux/types.h> 2 + #include <linux/module.h> 3 + #include <net/ip.h> 4 + #include <net/ipv6.h> 5 + #include <net/tcp.h> 6 + #include <net/udp.h> 7 + #include <linux/netfilter/x_tables.h> 8 + #include <linux/netfilter/xt_tcpudp.h> 9 + #include <linux/netfilter_ipv4/ip_tables.h> 10 + #include <linux/netfilter_ipv6/ip6_tables.h> 11 + 12 + MODULE_DESCRIPTION("x_tables match for TCP and UDP, supports IPv4 and IPv6"); 13 + MODULE_LICENSE("GPL"); 14 + MODULE_ALIAS("xt_tcp"); 15 + MODULE_ALIAS("xt_udp"); 16 + MODULE_ALIAS("ipt_udp"); 17 + MODULE_ALIAS("ipt_tcp"); 18 + MODULE_ALIAS("ip6t_udp"); 19 + MODULE_ALIAS("ip6t_tcp"); 20 + 21 + #ifdef DEBUG_IP_FIREWALL_USER 22 + #define duprintf(format, args...) printk(format , ## args) 23 + #else 24 + #define duprintf(format, args...) 25 + #endif 26 + 27 + 28 + /* Returns 1 if the port is matched by the range, 0 otherwise */ 29 + static inline int 30 + port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 31 + { 32 + int ret; 33 + 34 + ret = (port >= min && port <= max) ^ invert; 35 + return ret; 36 + } 37 + 38 + static int 39 + tcp_find_option(u_int8_t option, 40 + const struct sk_buff *skb, 41 + unsigned int protoff, 42 + unsigned int optlen, 43 + int invert, 44 + int *hotdrop) 45 + { 46 + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 47 + u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 48 + unsigned int i; 49 + 50 + duprintf("tcp_match: finding option\n"); 51 + 52 + if (!optlen) 53 + return invert; 54 + 55 + /* If we don't have the whole header, drop packet. */ 56 + op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr), 57 + optlen, _opt); 58 + if (op == NULL) { 59 + *hotdrop = 1; 60 + return 0; 61 + } 62 + 63 + for (i = 0; i < optlen; ) { 64 + if (op[i] == option) return !invert; 65 + if (op[i] < 2) i++; 66 + else i += op[i+1]?:1; 67 + } 68 + 69 + return invert; 70 + } 71 + 72 + static int 73 + tcp_match(const struct sk_buff *skb, 74 + const struct net_device *in, 75 + const struct net_device *out, 76 + const void *matchinfo, 77 + int offset, 78 + unsigned int protoff, 79 + int *hotdrop) 80 + { 81 + struct tcphdr _tcph, *th; 82 + const struct xt_tcp *tcpinfo = matchinfo; 83 + 84 + if (offset) { 85 + /* To quote Alan: 86 + 87 + Don't allow a fragment of TCP 8 bytes in. Nobody normal 88 + causes this. Its a cracker trying to break in by doing a 89 + flag overwrite to pass the direction checks. 90 + */ 91 + if (offset == 1) { 92 + duprintf("Dropping evil TCP offset=1 frag.\n"); 93 + *hotdrop = 1; 94 + } 95 + /* Must not be a fragment. */ 96 + return 0; 97 + } 98 + 99 + #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 100 + 101 + th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 102 + if (th == NULL) { 103 + /* We've been asked to examine this packet, and we 104 + can't. Hence, no choice but to drop. */ 105 + duprintf("Dropping evil TCP offset=0 tinygram.\n"); 106 + *hotdrop = 1; 107 + return 0; 108 + } 109 + 110 + if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 111 + ntohs(th->source), 112 + !!(tcpinfo->invflags & XT_TCP_INV_SRCPT))) 113 + return 0; 114 + if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 115 + ntohs(th->dest), 116 + !!(tcpinfo->invflags & XT_TCP_INV_DSTPT))) 117 + return 0; 118 + if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 119 + == tcpinfo->flg_cmp, 120 + XT_TCP_INV_FLAGS)) 121 + return 0; 122 + if (tcpinfo->option) { 123 + if (th->doff * 4 < sizeof(_tcph)) { 124 + *hotdrop = 1; 125 + return 0; 126 + } 127 + if (!tcp_find_option(tcpinfo->option, skb, protoff, 128 + th->doff*4 - sizeof(_tcph), 129 + tcpinfo->invflags & XT_TCP_INV_OPTION, 130 + hotdrop)) 131 + return 0; 132 + } 133 + return 1; 134 + } 135 + 136 + /* Called when user tries to insert an entry of this type. */ 137 + static int 138 + tcp_checkentry(const char *tablename, 139 + const void *info, 140 + void *matchinfo, 141 + unsigned int matchsize, 142 + unsigned int hook_mask) 143 + { 144 + const struct ipt_ip *ip = info; 145 + const struct xt_tcp *tcpinfo = matchinfo; 146 + 147 + /* Must specify proto == TCP, and no unknown invflags */ 148 + return ip->proto == IPPROTO_TCP 149 + && !(ip->invflags & XT_INV_PROTO) 150 + && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) 151 + && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 152 + } 153 + 154 + /* Called when user tries to insert an entry of this type. */ 155 + static int 156 + tcp6_checkentry(const char *tablename, 157 + const void *entry, 158 + void *matchinfo, 159 + unsigned int matchsize, 160 + unsigned int hook_mask) 161 + { 162 + const struct ip6t_ip6 *ipv6 = entry; 163 + const struct xt_tcp *tcpinfo = matchinfo; 164 + 165 + /* Must specify proto == TCP, and no unknown invflags */ 166 + return ipv6->proto == IPPROTO_TCP 167 + && !(ipv6->invflags & XT_INV_PROTO) 168 + && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) 169 + && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 170 + } 171 + 172 + 173 + static int 174 + udp_match(const struct sk_buff *skb, 175 + const struct net_device *in, 176 + const struct net_device *out, 177 + const void *matchinfo, 178 + int offset, 179 + unsigned int protoff, 180 + int *hotdrop) 181 + { 182 + struct udphdr _udph, *uh; 183 + const struct xt_udp *udpinfo = matchinfo; 184 + 185 + /* Must not be a fragment. */ 186 + if (offset) 187 + return 0; 188 + 189 + uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 190 + if (uh == NULL) { 191 + /* We've been asked to examine this packet, and we 192 + can't. Hence, no choice but to drop. */ 193 + duprintf("Dropping evil UDP tinygram.\n"); 194 + *hotdrop = 1; 195 + return 0; 196 + } 197 + 198 + return port_match(udpinfo->spts[0], udpinfo->spts[1], 199 + ntohs(uh->source), 200 + !!(udpinfo->invflags & XT_UDP_INV_SRCPT)) 201 + && port_match(udpinfo->dpts[0], udpinfo->dpts[1], 202 + ntohs(uh->dest), 203 + !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); 204 + } 205 + 206 + /* Called when user tries to insert an entry of this type. */ 207 + static int 208 + udp_checkentry(const char *tablename, 209 + const void *info, 210 + void *matchinfo, 211 + unsigned int matchinfosize, 212 + unsigned int hook_mask) 213 + { 214 + const struct ipt_ip *ip = info; 215 + const struct xt_udp *udpinfo = matchinfo; 216 + 217 + /* Must specify proto == UDP, and no unknown invflags */ 218 + if (ip->proto != IPPROTO_UDP || (ip->invflags & XT_INV_PROTO)) { 219 + duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, 220 + IPPROTO_UDP); 221 + return 0; 222 + } 223 + if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { 224 + duprintf("ipt_udp: matchsize %u != %u\n", 225 + matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); 226 + return 0; 227 + } 228 + if (udpinfo->invflags & ~XT_UDP_INV_MASK) { 229 + duprintf("ipt_udp: unknown flags %X\n", 230 + udpinfo->invflags); 231 + return 0; 232 + } 233 + 234 + return 1; 235 + } 236 + 237 + /* Called when user tries to insert an entry of this type. */ 238 + static int 239 + udp6_checkentry(const char *tablename, 240 + const void *entry, 241 + void *matchinfo, 242 + unsigned int matchinfosize, 243 + unsigned int hook_mask) 244 + { 245 + const struct ip6t_ip6 *ipv6 = entry; 246 + const struct xt_udp *udpinfo = matchinfo; 247 + 248 + /* Must specify proto == UDP, and no unknown invflags */ 249 + if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & XT_INV_PROTO)) { 250 + duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, 251 + IPPROTO_UDP); 252 + return 0; 253 + } 254 + if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { 255 + duprintf("ip6t_udp: matchsize %u != %u\n", 256 + matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); 257 + return 0; 258 + } 259 + if (udpinfo->invflags & ~XT_UDP_INV_MASK) { 260 + duprintf("ip6t_udp: unknown flags %X\n", 261 + udpinfo->invflags); 262 + return 0; 263 + } 264 + 265 + return 1; 266 + } 267 + 268 + static struct xt_match tcp_matchstruct = { 269 + .name = "tcp", 270 + .match = &tcp_match, 271 + .checkentry = &tcp_checkentry, 272 + .me = THIS_MODULE, 273 + }; 274 + static struct xt_match tcp6_matchstruct = { 275 + .name = "tcp", 276 + .match = &tcp_match, 277 + .checkentry = &tcp6_checkentry, 278 + .me = THIS_MODULE, 279 + }; 280 + 281 + static struct xt_match udp_matchstruct = { 282 + .name = "udp", 283 + .match = &udp_match, 284 + .checkentry = &udp_checkentry, 285 + .me = THIS_MODULE, 286 + }; 287 + static struct xt_match udp6_matchstruct = { 288 + .name = "udp", 289 + .match = &udp_match, 290 + .checkentry = &udp6_checkentry, 291 + .me = THIS_MODULE, 292 + }; 293 + 294 + static int __init init(void) 295 + { 296 + int ret; 297 + ret = xt_register_match(AF_INET, &tcp_matchstruct); 298 + if (ret) 299 + return ret; 300 + 301 + ret = xt_register_match(AF_INET6, &tcp6_matchstruct); 302 + if (ret) 303 + goto out_unreg_tcp; 304 + 305 + ret = xt_register_match(AF_INET, &udp_matchstruct); 306 + if (ret) 307 + goto out_unreg_tcp6; 308 + 309 + ret = xt_register_match(AF_INET6, &udp6_matchstruct); 310 + if (ret) 311 + goto out_unreg_udp; 312 + 313 + return ret; 314 + 315 + out_unreg_udp: 316 + xt_unregister_match(AF_INET, &tcp_matchstruct); 317 + out_unreg_tcp6: 318 + xt_unregister_match(AF_INET6, &tcp6_matchstruct); 319 + out_unreg_tcp: 320 + xt_unregister_match(AF_INET, &tcp_matchstruct); 321 + return ret; 322 + } 323 + 324 + static void __exit fini(void) 325 + { 326 + xt_unregister_match(AF_INET6, &udp6_matchstruct); 327 + xt_unregister_match(AF_INET, &udp_matchstruct); 328 + xt_unregister_match(AF_INET6, &tcp6_matchstruct); 329 + xt_unregister_match(AF_INET, &tcp_matchstruct); 330 + } 331 + 332 + module_init(init); 333 + module_exit(fini);
+1 -1
net/sched/act_ipt.c
··· 62 struct ipt_target *target; 63 int ret = 0; 64 65 - target = ipt_find_target(t->u.user.name, t->u.user.revision); 66 if (!target) 67 return -ENOENT; 68
··· 62 struct ipt_target *target; 63 int ret = 0; 64 65 + target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision); 66 if (!target) 67 return -ENOENT; 68