11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/capability.h>
17 #include <linux/netdevice.h>
18 #include <linux/module.h>
19 #include <linux/icmp.h>
22 #include <asm/uaccess.h>
28 #include <linux/netfilter/x_tables.h>
29 #include <linux/netfilter_ipv4/ip_tables.h>
31 #include "../../netfilter/xt_repldata.h"
41 #ifdef DEBUG_IP_FIREWALL
42 #define dprintf(format, args...) pr_info(format , ## args)
44 #define dprintf(format, args...)
47 #ifdef DEBUG_IP_FIREWALL_USER
48 #define duprintf(format, args...) pr_info(format , ## args)
50 #define duprintf(format, args...)
53 #ifdef CONFIG_NETFILTER_DEBUG
54 #define IP_NF_ASSERT(x) WARN_ON(!(x))
56 #define IP_NF_ASSERT(x)
74 ip_packet_match(
const struct iphdr *
ip,
77 const struct ipt_ip *ipinfo,
82 #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
84 if (
FWINV((ip->
saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
88 dprintf(
"Source or dest mismatch.\n");
90 dprintf(
"SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
91 &ip->
saddr, &ipinfo->smsk.s_addr, &ipinfo->src.s_addr,
93 dprintf(
"DST: %pI4 Mask: %pI4 Target: %pI4.%s\n",
102 dprintf(
"VIA in mismatch (%s vs %s).%s\n",
111 dprintf(
"VIA out mismatch (%s vs %s).%s\n",
120 dprintf(
"Packet protocol %hi does not match %hi.%s\n",
129 dprintf(
"Fragment rule but not fragment.%s\n",
138 ip_checkentry(
const struct ipt_ip *ip)
141 duprintf(
"Unknown flag bits set: %08X\n",
146 duprintf(
"Unknown invflag bits set: %08X\n",
170 static inline bool unconditional(
const struct ipt_ip *ip)
172 static const struct ipt_ip uncond;
174 return memcmp(ip, &uncond,
sizeof(uncond)) == 0;
182 return ipt_get_target((
struct ipt_entry *)e);
185 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
186 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
187 static const char *
const hooknames[] = {
195 enum nf_ip_trace_comments {
196 NF_IP_TRACE_COMMENT_RULE,
197 NF_IP_TRACE_COMMENT_RETURN,
198 NF_IP_TRACE_COMMENT_POLICY,
201 static const char *
const comments[] = {
202 [NF_IP_TRACE_COMMENT_RULE] =
"rule",
203 [NF_IP_TRACE_COMMENT_RETURN] =
"return",
204 [NF_IP_TRACE_COMMENT_POLICY] =
"policy",
220 const char *hookname,
const char **chainname,
221 const char **comment,
unsigned int *rulenum)
227 *chainname = t->
target.data;
236 unconditional(&s->
ip)) {
238 *comment = *chainname == hookname
239 ? comments[NF_IP_TRACE_COMMENT_POLICY]
240 : comments[NF_IP_TRACE_COMMENT_RETURN];
249 static void trace_packet(
const struct sk_buff *skb,
253 const char *tablename,
257 const void *table_base;
259 const char *hookname, *chainname, *comment;
261 unsigned int rulenum = 0;
264 root =
get_entry(table_base, private->hook_entry[hook]);
266 hookname = chainname = hooknames[
hook];
267 comment = comments[NF_IP_TRACE_COMMENT_RULE];
270 if (get_chainname_rulenum(iter, e, hookname,
271 &chainname, &comment, &rulenum) != 0)
276 tablename, chainname, comment, rulenum);
297 unsigned int verdict =
NF_DROP;
298 const char *indev, *outdev;
299 const void *table_base;
301 unsigned int *stackptr, origptr,
cpu;
308 indev = in ? in->
name : nulldevname;
309 outdev = out ? out->
name : nulldevname;
317 acpar.
thoff = ip_hdrlen(skb);
326 addend = xt_write_recseq_begin();
329 table_base =
private->entries[
cpu];
330 jumpstack = (
struct ipt_entry **)private->jumpstack[cpu];
334 e =
get_entry(table_base, private->hook_entry[hook]);
336 pr_debug(
"Entering %s(hook %u); sp at %u (UF %p)\n",
337 table->
name, hook, origptr,
338 get_entry(table_base, private->underflow[hook]));
345 if (!ip_packet_match(ip, indev, outdev,
348 e = ipt_next_entry(e);
355 if (!acpar.
match->match(skb, &acpar))
361 t = ipt_get_target(e);
364 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
365 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
368 trace_packet(skb, hook, in, out,
369 table->
name,
private, e);
372 if (!t->
u.
kernel.target->target) {
379 verdict = (
unsigned int)(-v) - 1;
382 if (*stackptr <= origptr) {
384 private->underflow[hook]);
385 pr_debug(
"Underflow (this is normal) "
388 e = jumpstack[--*stackptr];
389 pr_debug(
"Pulled %p out from pos %u\n",
391 e = ipt_next_entry(e);
395 if (table_base + v != ipt_next_entry(e) &&
397 if (*stackptr >= private->stacksize) {
401 jumpstack[(*stackptr)++] =
e;
413 verdict = t->
u.
kernel.target->target(skb, &acpar);
417 e = ipt_next_entry(e);
422 pr_debug(
"Exiting %s; resetting sp from %u to %u\n",
423 __func__, *stackptr, origptr);
425 xt_write_recseq_end(addend);
428 #ifdef DEBUG_ALLOW_ALL
441 unsigned int valid_hooks,
void *entry0)
451 if (!(valid_hooks & (1 << hook)))
459 = (
void *)ipt_get_target_c(e);
462 if (e->
comefrom & (1 << NF_INET_NUMHOOKS)) {
463 pr_err(
"iptables: loop hook %u pos %u %08X.\n",
473 t->
verdict < 0 && unconditional(&e->
ip)) ||
475 unsigned int oldpos,
size;
481 "negative verdict (%i)\n",
490 #ifdef DEBUG_IP_FIREWALL_USER
492 & (1 << NF_INET_NUMHOOKS)) {
514 (entry0 + pos + size);
523 if (newpos > newinfo->
size -
526 "bad verdict (%i)\n",
544 duprintf(
"Finished chain %u\n", hook);
558 par.
match->destroy(&par);
559 module_put(par.
match->me);
567 if (!ip_checkentry(&e->
ip)) {
568 duprintf(
"ip check failed %p %s.\n", e, name);
576 t = ipt_get_target_c(e);
610 duprintf(
"find_check_match: `%s' not found\n", m->
u.
user.name);
611 return PTR_ERR(match);
621 module_put(m->
u.
kernel.match->me);
625 static int check_target(
struct ipt_entry *e,
struct net *net,
const char *name)
642 duprintf(
"check failed for `%s'.\n",
650 find_check_entry(
struct ipt_entry *e,
struct net *net,
const char *name,
660 ret = check_entry(e, name);
667 mtpar.entryinfo = &e->
ip;
671 ret = find_check_match(ematch, &mtpar);
673 goto cleanup_matches;
677 t = ipt_get_target(e);
680 if (IS_ERR(target)) {
681 duprintf(
"find_check_entry: `%s' not found\n", t->
u.
user.name);
682 ret = PTR_ERR(target);
683 goto cleanup_matches;
687 ret = check_target(e, net, name);
692 module_put(t->
u.
kernel.target->me);
697 cleanup_match(ematch, net);
702 static bool check_underflow(
const struct ipt_entry *e)
705 unsigned int verdict;
707 if (!unconditional(&e->
ip))
709 t = ipt_get_target_c(e);
713 verdict = -verdict - 1;
718 check_entry_size_and_hooks(
struct ipt_entry *e,
720 const unsigned char *base,
721 const unsigned char *
limit,
722 const unsigned int *hook_entries,
723 const unsigned int *underflows,
724 unsigned int valid_hooks)
728 if ((
unsigned long)e % __alignof__(
struct ipt_entry) != 0 ||
729 (
unsigned char *)e +
sizeof(
struct ipt_entry) >= limit) {
736 duprintf(
"checking: element %p size %u\n",
743 if (!(valid_hooks & (1 << h)))
745 if ((
unsigned char *)e - base == hook_entries[h])
747 if ((
unsigned char *)e - base == underflows[h]) {
748 if (!check_underflow(e)) {
749 pr_err(
"Underflows must be unconditional and "
750 "use the STANDARD target with "
765 cleanup_entry(
struct ipt_entry *e,
struct net *net)
773 cleanup_match(ematch, net);
774 t = ipt_get_target(e);
777 par.target = t->u.
kernel.target;
778 par.targinfo = t->
data;
782 module_put(par.target->me);
795 newinfo->size = repl->size;
796 newinfo->number = repl->num_entries;
800 newinfo->hook_entry[
i] = 0xFFFFFFFF;
801 newinfo->underflow[
i] = 0xFFFFFFFF;
804 duprintf(
"translate_table: size %u\n", newinfo->size);
808 ret = check_entry_size_and_hooks(iter, newinfo, entry0,
816 if (
strcmp(ipt_get_target(iter)->u.user.name,
818 ++newinfo->stacksize;
821 if (i != repl->num_entries) {
822 duprintf(
"translate_table: %u not %u entries\n",
823 i, repl->num_entries);
830 if (!(repl->valid_hooks & (1 << i)))
832 if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
833 duprintf(
"Invalid hook entry %u %u\n",
834 i, repl->hook_entry[i]);
837 if (newinfo->underflow[i] == 0xFFFFFFFF) {
838 duprintf(
"Invalid underflow %u %u\n",
839 i, repl->underflow[i]);
844 if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
850 ret = find_check_entry(iter, net, repl->name, repl->size);
860 cleanup_entry(iter, net);
867 if (newinfo->entries[i] && newinfo->entries[i] != entry0)
868 memcpy(newinfo->entries[i], entry0, newinfo->size);
891 start = read_seqcount_begin(s);
894 }
while (read_seqcount_retry(s, start));
904 unsigned int countersize;
911 countersize =
sizeof(
struct xt_counters) *
private->number;
912 counters =
vzalloc(countersize);
914 if (counters ==
NULL)
925 void __user *userptr)
927 unsigned int off,
num;
932 const void *loc_cpu_entry;
934 counters = alloc_counters(table);
935 if (IS_ERR(counters))
936 return PTR_ERR(counters);
943 if (
copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
955 e = (
struct ipt_entry *)(loc_cpu_entry + off);
959 sizeof(counters[num])) != 0) {
980 t = ipt_get_target_c(e);
997 static void compat_standard_from_user(
void *
dst,
const void *
src)
1002 v += xt_compat_calc_jump(AF_INET, v);
1003 memcpy(dst, &v,
sizeof(v));
1006 static int compat_standard_to_user(
void __user *dst,
const void *src)
1011 cv -= xt_compat_calc_jump(AF_INET, cv);
1015 static int compat_calc_entry(
const struct ipt_entry *e,
1021 unsigned int entry_offset;
1025 entry_offset = (
void *)e - base;
1027 off += xt_compat_match_offset(ematch->u.kernel.match);
1028 t = ipt_get_target_c(e);
1029 off += xt_compat_target_offset(t->u.kernel.target);
1030 newinfo->size -= off;
1031 ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1035 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1046 static int compat_table_info(
const struct xt_table_info *info,
1050 void *loc_cpu_entry;
1053 if (!newinfo || !info)
1060 xt_compat_init_offsets(AF_INET, info->
number);
1062 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
1070 static int get_info(
struct net *net,
void __user *
user,
1071 const int *len,
int compat)
1078 duprintf(
"length %u != %zu\n", *len,
1087 #ifdef CONFIG_COMPAT
1089 xt_compat_lock(AF_INET);
1092 "iptable_%s", name);
1093 if (t && !IS_ERR(t)) {
1096 #ifdef CONFIG_COMPAT
1100 ret = compat_table_info(
private, &
tmp);
1101 xt_compat_flush_offsets(AF_INET);
1105 memset(&info, 0,
sizeof(info));
1111 info.num_entries =
private->
number;
1112 info.
size =
private->size;
1123 ret = t ? PTR_ERR(t) : -
ENOENT;
1124 #ifdef CONFIG_COMPAT
1126 xt_compat_unlock(AF_INET);
1139 if (*len <
sizeof(
get)) {
1140 duprintf(
"get_entries: %u < %zu\n", *len,
sizeof(
get));
1146 duprintf(
"get_entries: %u != %zu\n",
1147 *len,
sizeof(
get) +
get.size);
1152 if (t && !IS_ERR(t)) {
1154 duprintf(
"t->private->number = %u\n", private->number);
1155 if (
get.size == private->size)
1156 ret = copy_entries_to_user(private->size,
1157 t, uptr->entrytable);
1159 duprintf(
"get_entries: I've got %u not %u!\n",
1160 private->size,
get.size);
1166 ret = t ? PTR_ERR(t) : -
ENOENT;
1172 __do_replace(
struct net *net,
const char *name,
unsigned int valid_hooks,
1174 void __user *counters_ptr)
1180 void *loc_cpu_old_entry;
1191 "iptable_%s", name);
1192 if (!t || IS_ERR(t)) {
1193 ret = t ? PTR_ERR(t) : -
ENOENT;
1194 goto free_newinfo_counters_untrans;
1199 duprintf(
"Valid hook crap: %08X vs %08X\n",
1210 duprintf(
"do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
1225 cleanup_entry(iter, net);
1238 free_newinfo_counters_untrans:
1245 do_replace(
struct net *net,
const void __user *user,
unsigned int len)
1250 void *loc_cpu_entry;
1273 ret = translate_table(net, newinfo, loc_cpu_entry, &
tmp);
1279 ret = __do_replace(net,
tmp.
name,
tmp.valid_hooks, newinfo,
1280 tmp.num_counters,
tmp.counters);
1282 goto free_newinfo_untrans;
1285 free_newinfo_untrans:
1287 cleanup_entry(iter, net);
1294 do_add_counters(
struct net *net,
const void __user *user,
1295 unsigned int len,
int compat)
1297 unsigned int i, curcpu;
1300 unsigned int num_counters;
1307 void *loc_cpu_entry;
1309 unsigned int addend;
1310 #ifdef CONFIG_COMPAT
1311 struct compat_xt_counters_info compat_tmp;
1315 size =
sizeof(
struct compat_xt_counters_info);
1326 #ifdef CONFIG_COMPAT
1328 num_counters = compat_tmp.num_counters;
1329 name = compat_tmp.name;
1333 num_counters =
tmp.num_counters;
1337 if (len != size + num_counters *
sizeof(
struct xt_counters))
1350 if (!t || IS_ERR(t)) {
1351 ret = t ? PTR_ERR(t) : -
ENOENT;
1357 if (private->number != num_counters) {
1359 goto unlock_up_free;
1365 loc_cpu_entry =
private->entries[curcpu];
1366 addend = xt_write_recseq_begin();
1371 xt_write_recseq_end(addend);
1382 #ifdef CONFIG_COMPAT
1383 struct compat_ipt_replace {
1392 struct compat_ipt_entry
entries[0];
1396 compat_copy_entry_to_user(
struct ipt_entry *e,
void __user **dstptr,
1401 struct compat_ipt_entry
__user *
ce;
1408 ce = (
struct compat_ipt_entry
__user *)*dstptr;
1411 sizeof(counters[i])) != 0)
1414 *dstptr +=
sizeof(
struct compat_ipt_entry);
1418 ret = xt_compat_match_to_user(ematch, dstptr, size);
1423 t = ipt_get_target(e);
1424 ret = xt_compat_target_to_user(t, dstptr, size);
1428 if (
put_user(target_offset, &ce->target_offset) != 0 ||
1429 put_user(next_offset, &ce->next_offset) != 0)
1438 unsigned int hookmask,
1444 m->
u.
user.revision);
1445 if (IS_ERR(match)) {
1446 duprintf(
"compat_check_calc_match: `%s' not found\n",
1448 return PTR_ERR(match);
1451 *size += xt_compat_match_offset(match);
1455 static void compat_release_entry(
struct compat_ipt_entry *e)
1462 module_put(ematch->u.
kernel.match->me);
1463 t = compat_ipt_get_target(e);
1464 module_put(t->u.
kernel.target->me);
1468 check_compat_entry_size_and_hooks(
struct compat_ipt_entry *e,
1471 const unsigned char *base,
1472 const unsigned char *limit,
1473 const unsigned int *hook_entries,
1474 const unsigned int *underflows,
1480 unsigned int entry_offset;
1484 duprintf(
"check_compat_entry_size_and_hooks %p\n", e);
1485 if ((
unsigned long)e % __alignof__(
struct compat_ipt_entry) != 0 ||
1486 (
unsigned char *)e +
sizeof(
struct compat_ipt_entry) >= limit) {
1487 duprintf(
"Bad offset %p, limit = %p\n", e, limit);
1491 if (e->next_offset <
sizeof(
struct compat_ipt_entry) +
1492 sizeof(
struct compat_xt_entry_target)) {
1493 duprintf(
"checking: element %p size %u\n",
1499 ret = check_entry((
struct ipt_entry *)e, name);
1504 entry_offset = (
void *)e - (
void *)base;
1507 ret = compat_find_calc_match(ematch, name,
1508 &e->ip, e->comefrom, &off);
1510 goto release_matches;
1514 t = compat_ipt_get_target(e);
1516 t->
u.
user.revision);
1517 if (IS_ERR(target)) {
1518 duprintf(
"check_compat_entry_size_and_hooks: `%s' not found\n",
1520 ret = PTR_ERR(target);
1521 goto release_matches;
1525 off += xt_compat_target_offset(target);
1527 ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1533 if ((
unsigned char *)e - base == hook_entries[h])
1534 newinfo->hook_entry[
h] = hook_entries[
h];
1535 if ((
unsigned char *)e - base == underflows[h])
1536 newinfo->underflow[
h] = underflows[
h];
1540 memset(&e->counters, 0,
sizeof(e->counters));
1545 module_put(t->
u.
kernel.target->me);
1550 module_put(ematch->
u.
kernel.match->me);
1556 compat_copy_entry_from_user(
struct compat_ipt_entry *e,
void **dstptr,
1557 unsigned int *size,
const char *name,
1563 unsigned int origsize;
1577 ret = xt_compat_match_from_user(ematch, dstptr, size);
1582 t = compat_ipt_get_target(e);
1584 xt_compat_target_from_user(t, dstptr, size);
1588 if ((
unsigned char *)de - base < newinfo->
hook_entry[
h])
1590 if ((
unsigned char *)de - base < newinfo->
underflow[
h])
1591 newinfo->
underflow[h] -= origsize - *size;
1597 compat_check_entry(
struct ipt_entry *e,
struct net *net,
const char *name)
1607 mtpar.entryinfo = &e->
ip;
1613 goto cleanup_matches;
1617 ret = check_target(e, net, name);
1619 goto cleanup_matches;
1626 cleanup_match(ematch, net);
1632 translate_compat_table(
struct net *net,
1634 unsigned int valid_hooks,
1637 unsigned int total_size,
1638 unsigned int number,
1639 unsigned int *hook_entries,
1640 unsigned int *underflows)
1644 void *
pos, *entry0, *entry1;
1645 struct compat_ipt_entry *iter0;
1661 duprintf(
"translate_compat_table: size %u\n", info->
size);
1663 xt_compat_lock(AF_INET);
1664 xt_compat_init_offsets(AF_INET, number);
1667 ret = check_compat_entry_size_and_hooks(iter0, info, &size,
1669 entry0 + total_size,
1680 duprintf(
"translate_compat_table: %u not %u entries\n",
1688 if (!(valid_hooks & (1 << i)))
1691 duprintf(
"Invalid hook entry %u %u\n",
1692 i, hook_entries[i]);
1696 duprintf(
"Invalid underflow %u %u\n",
1707 newinfo->
number = number;
1716 ret = compat_copy_entry_from_user(iter0, &pos, &size,
1717 name, newinfo, entry1);
1721 xt_compat_flush_offsets(AF_INET);
1722 xt_compat_unlock(AF_INET);
1727 if (!mark_source_chains(newinfo, valid_hooks, entry1))
1732 ret = compat_check_entry(iter1, net, name);
1736 if (
strcmp(ipt_get_target(iter1)->u.user.name,
1753 compat_release_entry(iter0);
1758 cleanup_entry(iter1, net);
1780 compat_release_entry(iter0);
1784 xt_compat_flush_offsets(AF_INET);
1785 xt_compat_unlock(AF_INET);
1790 compat_do_replace(
struct net *net,
void __user *user,
unsigned int len)
1793 struct compat_ipt_replace
tmp;
1795 void *loc_cpu_entry;
1820 ret = translate_compat_table(net,
tmp.
name,
tmp.valid_hooks,
1821 &newinfo, &loc_cpu_entry,
tmp.size,
1822 tmp.num_entries,
tmp.hook_entry,
1827 duprintf(
"compat_do_replace: Translated table\n");
1829 ret = __do_replace(net,
tmp.
name,
tmp.valid_hooks, newinfo,
1830 tmp.num_counters, compat_ptr(
tmp.counters));
1832 goto free_newinfo_untrans;
1835 free_newinfo_untrans:
1837 cleanup_entry(iter, net);
1854 ret = compat_do_replace(sock_net(sk), user, len);
1858 ret = do_add_counters(sock_net(sk), user, len, 1);
1862 duprintf(
"do_ipt_set_ctl: unknown request %i\n", cmd);
1869 struct compat_ipt_get_entries {
1872 struct compat_ipt_entry entrytable[0];
1876 compat_copy_entries_to_user(
unsigned int total_size,
struct xt_table *table,
1877 void __user *userptr)
1884 const void *loc_cpu_entry;
1888 counters = alloc_counters(table);
1889 if (IS_ERR(counters))
1890 return PTR_ERR(counters);
1900 ret = compat_copy_entry_to_user(iter, &pos,
1901 &size, counters, i++);
1911 compat_get_entries(
struct net *net,
struct compat_ipt_get_entries __user *uptr,
1915 struct compat_ipt_get_entries
get;
1918 if (*len <
sizeof(
get)) {
1919 duprintf(
"compat_get_entries: %u < %zu\n", *len,
sizeof(
get));
1926 if (*len !=
sizeof(
struct compat_ipt_get_entries) +
get.size) {
1927 duprintf(
"compat_get_entries: %u != %zu\n",
1928 *len,
sizeof(
get) +
get.size);
1932 xt_compat_lock(AF_INET);
1934 if (t && !IS_ERR(t)) {
1937 duprintf(
"t->private->number = %u\n", private->number);
1938 ret = compat_table_info(
private, &info);
1939 if (!ret &&
get.size == info.
size) {
1940 ret = compat_copy_entries_to_user(private->size,
1941 t, uptr->entrytable);
1943 duprintf(
"compat_get_entries: I've got %u not %u!\n",
1944 private->size,
get.size);
1947 xt_compat_flush_offsets(AF_INET);
1951 ret = t ? PTR_ERR(t) : -
ENOENT;
1953 xt_compat_unlock(AF_INET);
1957 static int do_ipt_get_ctl(
struct sock *,
int,
void __user *,
int *);
1960 compat_do_ipt_get_ctl(
struct sock *sk,
int cmd,
void __user *user,
int *len)
1969 ret = get_info(sock_net(sk), user, len, 1);
1972 ret = compat_get_entries(sock_net(sk), user, len);
1975 ret = do_ipt_get_ctl(sk, cmd, user, len);
1982 do_ipt_set_ctl(
struct sock *sk,
int cmd,
void __user *user,
unsigned int len)
1991 ret = do_replace(sock_net(sk), user, len);
1995 ret = do_add_counters(sock_net(sk), user, len, 0);
1999 duprintf(
"do_ipt_set_ctl: unknown request %i\n", cmd);
2007 do_ipt_get_ctl(
struct sock *sk,
int cmd,
void __user *user,
int *len)
2016 ret = get_info(sock_net(sk), user, len, 0);
2020 ret = get_entries(sock_net(sk), user, len);
2028 if (*len !=
sizeof(
rev)) {
2036 rev.name[
sizeof(
rev.name)-1] = 0;
2046 "ipt_%s",
rev.name);
2051 duprintf(
"do_ipt_get_ctl: unknown request %i\n", cmd);
2065 void *loc_cpu_entry;
2078 ret = translate_table(net, newinfo, loc_cpu_entry, repl);
2083 if (IS_ERR(new_table)) {
2084 ret = PTR_ERR(new_table);
2093 return ERR_PTR(ret);
2099 void *loc_cpu_entry;
2100 struct module *table_owner = table->
me;
2108 cleanup_entry(iter, net);
2109 if (private->number > private->initial_entries)
2110 module_put(table_owner);
2120 return ((test_type == 0xFF) ||
2121 (type == test_type && code >= min_code && code <= max_code))
2136 ic = skb_header_pointer(skb, par->
thoff,
sizeof(_icmph), &_icmph);
2141 duprintf(
"Dropping evil ICMP tinygram.\n");
2146 return icmp_type_code_match(icmpinfo->
type,
2164 .targetsize =
sizeof(
int),
2166 #ifdef CONFIG_COMPAT
2168 .compat_from_user = compat_standard_from_user,
2169 .compat_to_user = compat_standard_to_user,
2180 static struct nf_sockopt_ops ipt_sockopts = {
2184 .set = do_ipt_set_ctl,
2185 #ifdef CONFIG_COMPAT
2186 .compat_set = compat_do_ipt_set_ctl,
2190 .get = do_ipt_get_ctl,
2191 #ifdef CONFIG_COMPAT
2192 .compat_get = compat_do_ipt_get_ctl,
2197 static struct xt_match ipt_builtin_mt[] __read_mostly = {
2200 .match = icmp_match,
2201 .matchsize =
sizeof(
struct ipt_icmp),
2202 .checkentry = icmp_checkentry,
2208 static int __net_init ip_tables_net_init(
struct net *net)
2213 static void __net_exit ip_tables_net_exit(
struct net *net)
2219 .init = ip_tables_net_init,
2220 .exit = ip_tables_net_exit,
2223 static int __init ip_tables_init(
void)
2244 pr_info(
"(C) 2000-2006 Netfilter Core Team\n");
2257 static void __exit ip_tables_fini(
void)