with kernels that do not support it, will result in a plain DROP instead
of REJECT. Use with caution.
Kernels that do support it:
+ 2.4 - since 2.4.22-pre9
+ 2.6 - all
- There are some issues related to upgrading from 1.2.x to 1.3.x on a system
with dynamic ruleset changes during runtime. (Please see
ifndef KERNEL_DIR
KERNEL_DIR=/usr/src/linux
endif
-IPTABLES_VERSION:=1.3.2
-OLD_IPTABLES_VERSION:=1.3.1
+IPTABLES_VERSION:=1.3.5
+OLD_IPTABLES_VERSION:=1.3.4
PREFIX:=/usr/local
LIBDIR:=$(PREFIX)/lib
+++ /dev/null
-#! /bin/sh
-[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ip_pool.h ] && echo pool POOL
# header files are present in the include/linux directory of this iptables
# package (HW)
#
-PF_EXT_SLIB:=ah comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
-PF6_EXT_SLIB:=eui64 hl icmpv6 length limit mac mark multiport owner physdev standard tcp udp HL LOG MARK TRACE
+PF_EXT_SLIB:=ah comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype policy realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
+PF6_EXT_SLIB:=connmark eui64 hl icmpv6 length limit mac mark multiport owner physdev policy standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
# Optionals
PF_EXT_SLIB_OPTS:=$(foreach T,$(wildcard extensions/.*-test),$(shell KERNEL_DIR=$(KERNEL_DIR) $(T)))
-This is used to modify the IPv6 HOPLIMIT header field. The HOPLIMIT field is
-similar to what is known as TTL value in IPv4. Setting or incrementing the
-HOPLIMIT field can potentially be very dangerous, so it should be avoided at
-any cost.
-.TP
-.B Don't ever set or increment the value on packets that leave your local network!
+This is used to modify the Hop Limit field in IPv6 header. The Hop Limit field
+is similar to what is known as TTL value in IPv4. Setting or incrementing the
+Hop Limit field can potentially be very dangerous, so it should be avoided at
+any cost. This target is only valid in
.B mangle
table.
.TP
+.B Don't ever set or increment the value on packets that leave your local network!
+.TP
.BI "--hl-set " "value"
-Set the HOPLIMIT value to `value'.
+Set the Hop Limit to `value'.
.TP
.BI "--hl-dec " "value"
-Decrement the HOPLIMIT value `value' times.
+Decrement the Hop Limit `value' times.
.TP
.BI "--hl-inc " "value"
-Increment the HOPLIMIT value `value' times.
+Increment the Hop Limit `value' times.
.B " icmp6-port-unreachable"
.B " port-unreach"
.fi
-which return the appropriate IPv6-ICMP error message (\fBport-unreach\fP is
+which return the appropriate ICMPv6 error message (\fBport-unreach\fP is
the default). Finally, the option
.B tcp-reset
can be used on rules which only match the TCP protocol: this causes a
.I ident
(113/tcp) probes which frequently occur when sending mail to broken mail
hosts (which won't accept your mail otherwise).
+.B tcp-reset
+can only be used with kernel versions 2.6.14 or latter.
-This module matches the SPIs in AH header of IPSec packets.
+This module matches the parameters in Authentication header of IPsec packets.
.TP
.BR "--ahspi " "[!] \fIspi\fP[:\fIspi\fP]"
+Matches SPI.
+.TP
+.BR "--ahlen " "[!] \fIlength"
+Total length of this header in octets.
+.TP
+.BI "--ahres"
+Matches if the reserved field is filled with zero.
This matches if a specific /proc filename is '0' or '1'.
.TP
-.BI "--condition " "[!] filename"
+.BR "--condition " "[!] \fIfilename"
Match on boolean value stored in /proc/net/ip6t_condition/filename file
-This module matches the IPv6 destination header options
+This module matches the parameters in Destination Options header
.TP
-.BI "--dst-len" "[!]" "length"
-Total length of this header
+.BR "--dst-len " "[!] \fIlength"
+Total length of this header in octets.
.TP
-.BI "--dst-opts " "TYPE[:LEN],[,TYPE[:LEN]...]"
-Options and it's length (List).
+.BR "--dst-opts " "\fItype\fP[:\fIlength\fP][,\fItype\fP[:\fIlength\fP]...]"
+numeric type of option and the length of the option data in octets.
-This module matches the SPIs in ESP header of IPSec packets.
+This module matches the SPIs in ESP header of IPsec packets.
.TP
.BR "--espspi " "[!] \fIspi\fP[:\fIspi\fP]"
-This module matches the EUI64 part of a stateless autoconfigured IPv6 address. It compares the source MAC address with the lower 64 bits of the IPv6 address.
+This module matches the EUI-64 part of a stateless autoconfigured IPv6 address.
+It compares the EUI-64 derived from the source MAC address in Ehternet frame
+with the lower 64 bits of the IPv6 source address. But "Universal/Local"
+bit is not compared. This module doesn't match other link layer frame, and
+is only valid in the
+.BR PREROUTING ,
+.BR INPUT
+and
+.BR FORWARD
+chains.
-This module matches the time IPv6 fragmentathion header
+This module matches the parameters in Fragment header.
.TP
-.BI "--fragid " "[!]" "id[:id]"
-Matches the given fragmentation ID (range).
+.BR "--fragid " "[!] \fIid\fP[:\fIid\fP]"
+Matches the given Identification or range of it.
.TP
-.BI "--fraglen " "[!]" "length"
-Matches the total length of this header.
+.BR "--fraglen " "[!] \fIlength\fP"
+This option cannot be used with kernel version 2.6.10 or later. The length of
+Fragment header is static and this option doesn't make sense.
.TP
-.BI "--fragres "
-Matches the reserved field, too.
+.BR "--fragres "
+Matches if the reserved fields are filled with zero.
.TP
-.BI "--fragfirst "
+.BR "--fragfirst "
Matches on the first fragment.
.TP
-.BI "[--fragmore]"
+.BR "[--fragmore]"
Matches if there are more fragments.
.TP
-.BI "[--fraglast]"
+.BR "[--fraglast]"
Matches if this is the last fragement.
This module matches a rate limit based on a fuzzy logic controller [FLC]
.TP
-.BI "--lower-limit "number"
+.BI "--lower-limit " "number"
Specifies the lower limit (in packets per second).
.TP
.BI "--upper-limit " "number"
-This module matches the IPv6 hop-by-hop header options
+This module matches the parameters in Hop-by-Hop Options header
.TP
-.BI "--hbh-len" "[!]" "length"
-Total length of this header
+.BR "--hbh-len " "[!] \fIlength\fP"
+Total length of this header in octets.
.TP
-.BI "--hbh-opts " "TYPE[:LEN],[,TYPE[:LEN]...]"
-Options and it's length (List).
+.BR "--hbh-opts " "\fItype\fP[:\fIlength\fP][,\fItype\fP[:\fIlength\fP]...]"
+numeric type of option and the length of the option data in octets.
-This module matches the HOPLIMIT field in the IPv6 header.
+This module matches the Hop Limit field in the IPv6 header.
.TP
-.BI "--hl-eq " "value"
-Matches if HOPLIMIT equals the given value.
+.BR "--hl-eq " "[!] \fIvalue\fP"
+Matches if Hop Limit equals \fIvalue\fP.
.TP
-.BI "--hl-lt " "ttl"
-Matches if HOPLIMIT is less than the given value.
+.BI "--hl-lt " "value"
+Matches if Hop Limit is less than \fIvalue\fP.
.TP
-.BI "--hl-gt " "ttl"
-Matches if HOPLIMIT is greater than the given value.
+.BI "--hl-gt " "value"
+Matches if Hop Limit is greater than \fIvalue\fP.
This extension is loaded if `--protocol ipv6-icmp' or `--protocol icmpv6' is
specified. It provides the following option:
.TP
-.BR "--icmpv6-type " "[!] \fItypename\fP"
-This allows specification of the ICMP type, which can be a numeric
-IPv6-ICMP type, or one of the IPv6-ICMP type names shown by the command
+.BR "--icmpv6-type " "[!] \fItype\fP[/\fIcode\fP]|\fItypename\fP"
+This allows specification of the ICMPv6 type, which can be a numeric
+ICMPv6
+.IR type ,
+.IR type
+and
+.IR code ,
+or one of the ICMPv6 type names shown by the command
.nf
ip6tables -p ipv6-icmp -h
.fi
-This module matches on IPv6 option headers
+This module matches IPv6 extension headers and/or upper layer header.
.TP
-.BI "--header " "[!]" "headers"
-Matches the given type of headers.
-Names: hop,dst,route,frag,auth,esp,none,proto
-Long Names: hop-by-hop,ipv6-opts,ipv6-route,ipv6-frag,ah,esp,ipv6-nonxt,protocol
-Numbers: 0,60,43,44,51,50,59
+.BR "--header " "[!] \fIheader\fP[,\fIheader\fP...]"
+Matches the packet which EXACTLY includes all specified headers. The headers
+encapsulated with ESP header are out of scope.
+.IR header
+can be
+.IR hop | hop-by-hop
+(Hop-by-Hop Options header),
+.IR dst
+(Destination Options header),
+.IR route
+(Routing header),
+.IR frag
+(Fragment header),
+.IR auth
+(Authentication header),
+.IR esp
+(Encapsulating Security Payload header),
+.IR none
+(No Next header) which matches 59 in the 'Next Header field' of IPv6 header or any IPv6 extension headers, or
+.IR proto
+which matches any upper layer protocol header. A protocol name from /etc/protocols and numeric value also allowed. The number 255 is equivalent to
+.IR proto .
.TP
-.BI "--soft"
-The header CONTAINS the specified extensions.
+.BR "[--soft]"
+Matches if the packet includes all specified headers with
+.BR --header ,
+AT LEAST.
parse_length(const char *s)
{
- int len;
+ unsigned int len;
if (string_to_number(s, 0, 0xFFFF, &len) == -1)
exit_error(PARAMETER_PROBLEM, "length invalid: `%s'\n", s);
-This module matches the length of a packet against a specific value
-or range of values.
+This module matches the length of the IPv6 payload in octets, or range of it.
+IPv6 header itself isn't counted.
.TP
-.BR "--length " "\fIlength\fP[:\fIlength\fP]"
+.BR "--length " "[!] \fIlength\fP[:\fIlength\fP]"
target below).
.TP
.BR "--mark " "\fIvalue\fP[/\fImask\fP]"
-Matches packets with the given unsigned mark value (if a mask is
-specified, this is logically ANDed with the mask before the
+Matches packets with the given unsigned mark value (if a \fImask\fP is
+specified, this is logically ANDed with the \fImask\fP before the
comparison).
This module matches a set of source or destination ports. Up to 15
ports can be specified. A port range (port:port) counts as two
-ports. It can only be used in conjunction with
+ports, but range isn't supported now. It can only be used in conjunction
+with
.B "-p tcp"
or
.BR "-p udp" .
This module attempts to match various characteristics of the packet
creator, for locally-generated packets. It is only valid in the
.B OUTPUT
-chain, and even this some packets (such as ICMP ping responses) may
+chain, and even this some packets (such as ICMPv6 ping responses) may
have no owner, and hence never match. This is regarded as experimental.
.TP
.BI "--uid-owner " "userid"
if (*flags & IP6T_PHYSDEV_OP_IN)
goto multiple_use;
check_inverse(optarg, &invert, &optind, 0);
- parse_interface(argv[optind-1], info->physindev, info->in_mask);
+ parse_interface(argv[optind-1], info->physindev,
+ (unsigned char *)info->in_mask);
if (invert)
info->invert |= IP6T_PHYSDEV_OP_IN;
info->bitmask |= IP6T_PHYSDEV_OP_IN;
goto multiple_use;
check_inverse(optarg, &invert, &optind, 0);
parse_interface(argv[optind-1], info->physoutdev,
- info->out_mask);
+ (unsigned char *)info->out_mask);
if (invert)
info->invert |= IP6T_PHYSDEV_OP_OUT;
info->bitmask |= IP6T_PHYSDEV_OP_OUT;
a transparent bridging IP firewall and is only useful for kernel versions
above version 2.5.44.
.TP
-.B --physdev-in name
+.BR --physdev-in " [!] \fIname\fP"
Name of a bridge port via which a packet is received (only for
packets entering the
.BR INPUT ,
interface which begins with this name will match. If the packet didn't arrive
through a bridge device, this packet won't match this option, unless '!' is used.
.TP
-.B --physdev-out name
+.BR --physdev-out " [!] \fIname\fP"
Name of a bridge port via which a packet is going to be sent (for packets
entering the
.BR FORWARD ,
the output device will be, then the packet won't match this option, unless
'!' is used.
.TP
-.B --physdev-is-in
+.RB "[!] " --physdev-is-in
Matches if the packet has entered through a bridge interface.
.TP
-.B --physdev-is-out
+.RB "[!] " --physdev-is-out
Matches if the packet will leave through a bridge interface.
.TP
-.B --physdev-is-bridged
+.RB "[!] " --physdev-is-bridged
Matches if the packet is being bridged and therefore is not being routed.
This is only useful in the FORWARD and POSTROUTING chains.
Match on IPv6 routing header
.TP
-.BI "--rt-type " "[!]" "type"
+.BR "--rt-type" " [!] \fItype\fP"
Match the type (numeric).
.TP
-.BI "--rt-segsleft" "[!]" "num[:num]"
+.BR "--rt-segsleft" " [!] \fInum\fP[:\fInum\fP]"
Match the `segments left' field (range).
.TP
-.BI "--rt-len" "[!]" "length"
-Match the length of this header
+.BR "--rt-len" " [!] \fIlength\fP"
+Match the length of this header.
.TP
-.BI "--rt-0-res"
+.BR "--rt-0-res"
Match the reserved field, too (type=0)
.TP
-.BI "--rt-0-addrs ADDR[,ADDR...]
+.BR "--rt-0-addrs" " \fIADDR\fP[,\fIADDR\fP...]"
Match type=0 addresses (list).
.TP
-.BI "--rt-0-not-strict"
+.BR "--rt-0-not-strict"
List of type=0 addresses is not a strict list.
{
}
-int string_to_priority(const unsigned char *s, unsigned int *p)
+int string_to_priority(const char *s, unsigned int *p)
{
unsigned int i, j;
" --clustermac <mac> Set clusterIP MAC address\n"
" --total-nodes <num> Set number of total nodes in cluster\n"
" --local-node <num> Set the local node number\n"
-" --hash-init\n"
+" --hash-init <num> Set init value of the Jenkins hash\n"
"\n",
IPTABLES_VERSION);
}
+#define PARAM_NEW 0x0001
+#define PARAM_HMODE 0x0002
+#define PARAM_MAC 0x0004
+#define PARAM_TOTALNODE 0x0008
+#define PARAM_LOCALNODE 0x0010
+#define PARAM_HASHINIT 0x0020
+
static struct option opts[] = {
{ "new", 0, 0, '1' },
{ "hashmode", 1, 0, '2' },
{ "clustermac", 1, 0, '3' },
{ "total-nodes", 1, 0, '4' },
{ "local-node", 1, 0, '5' },
+ { "hash-init", 1, 0, '6' },
{ 0 }
};
}
}
-#define PARAM_NEW 0x0001
-#define PARAM_HMODE 0x0002
-#define PARAM_MAC 0x0004
-#define PARAM_TOTALNODE 0x0008
-#define PARAM_LOCALNODE 0x0010
-
static int
parse(int c, char **argv, int invert, unsigned int *flags,
const struct ipt_entry *entry,
exit_error(PARAMETER_PROBLEM, "Can only specify MAC combined with `--new'\n");
if (*flags & PARAM_MAC)
exit_error(PARAMETER_PROBLEM, "Can only specify MAC once\n");
- parse_mac(optarg, cipinfo->clustermac);
+ parse_mac(optarg, (char *)cipinfo->clustermac);
if (!(cipinfo->clustermac[0] & 0x01))
exit_error(PARAMETER_PROBLEM, "MAC has to be a multicast ethernet address\n");
*flags |= PARAM_MAC;
cipinfo->local_nodes[0] = (u_int16_t)num;
*flags |= PARAM_LOCALNODE;
break;
+ case '6':
+ if (!(*flags & PARAM_NEW))
+ exit_error(PARAMETER_PROBLEM, "Can only specify hash init value combined with `--new'\n");
+ if (*flags & PARAM_HASHINIT)
+ exit_error(PARAMETER_PROBLEM, "Can specify hash init value only once\n");
+ if (string_to_number(optarg, 0, UINT_MAX, &num) < 0)
+ exit_error(PARAMETER_PROBLEM, "Unable to parse `%s'\n", optarg);
+ cipinfo->hash_initval = num;
+ *flags |= PARAM_HASHINIT;
+ break;
default:
return 0;
}
if (flags == 0)
return;
- if (flags == (PARAM_NEW|PARAM_HMODE|PARAM_MAC|PARAM_TOTALNODE|PARAM_LOCALNODE))
+ if ((flags & (PARAM_NEW|PARAM_HMODE|PARAM_MAC|PARAM_TOTALNODE|PARAM_LOCALNODE))
+ == (PARAM_NEW|PARAM_HMODE|PARAM_MAC|PARAM_TOTALNODE|PARAM_LOCALNODE))
return;
exit_error(PARAMETER_PROBLEM, "CLUSTERIP target: Invalid parameter combination\n");
return;
}
- printf("CLUSTERIP hashmode=%s clustermac=%s total_nodes=%u local_node=%u ",
+ printf("CLUSTERIP hashmode=%s clustermac=%s total_nodes=%u local_node=%u hash_init=%u",
hashmode2str(cipinfo->hash_mode),
mac2str(cipinfo->clustermac),
cipinfo->num_total_nodes,
- cipinfo->local_nodes[0]);
+ cipinfo->local_nodes[0],
+ cipinfo->hash_initval);
}
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
{
- /*
- const struct ipt_connmark_target_info *markinfo =
- (const struct ipt_connmark_target_info *)target->data;
+ const struct ipt_clusterip_tgt_info *cipinfo =
+ (const struct ipt_clusterip_tgt_info *)target->data;
- switch (markinfo->mode) {
- case IPT_CONNMARK_SET:
- printf("--set-mark 0x%lx ", markinfo->mark);
- break;
- case IPT_CONNMARK_SAVE:
- printf("--save-mark ");
- break;
- case IPT_CONNMARK_RESTORE:
- printf("--restore-mark ");
- break;
- default:
- printf("ERROR: UNKNOWN CONNMARK MODE ");
- break;
- }
- */
+ /* if this is not a new entry, we don't need to save target
+ * parameters */
+ if (!cipinfo->flags & CLUSTERIP_FLAG_NEW)
+ return;
+
+ printf("--new --hashmode %s --clustermac %s --total-nodes %d --local-node %d --hash-init %u",
+ hashmode2str(cipinfo->hash_mode),
+ mac2str(cipinfo->clustermac),
+ cipinfo->num_total_nodes,
+ cipinfo->local_nodes[0],
+ cipinfo->hash_initval);
}
static struct iptables_target clusterip = {
struct ipt_connmark_target_info *markinfo
= (struct ipt_connmark_target_info *)(*target)->data;
-#ifdef KERNEL_64_USERSPACE_32
- markinfo->mask = ~0ULL;
-#else
- markinfo->mask = ~0UL;
-#endif
+ markinfo->mask = 0xffffffffUL;
switch (c) {
char *end;
case '1':
markinfo->mode = IPT_CONNMARK_SET;
-#ifdef KERNEL_64_USERSPACE_32
- markinfo->mark = strtoull(optarg, &end, 0);
- if (*end == '/' && end[1] != '\0')
- markinfo->mask = strtoull(end+1, &end, 0);
-#else
+
markinfo->mark = strtoul(optarg, &end, 0);
if (*end == '/' && end[1] != '\0')
markinfo->mask = strtoul(end+1, &end, 0);
-#endif
+
if (*end != '\0' || end == optarg)
exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
if (*flags)
if (!*flags)
exit_error(PARAMETER_PROBLEM,
"CONNMARK target: Can't specify --mask without a operation");
-#ifdef KERNEL_64_USERSPACE_32
- markinfo->mask = strtoull(optarg, &end, 0);
-#else
markinfo->mask = strtoul(optarg, &end, 0);
-#endif
+
if (*end != '\0' || end == optarg)
exit_error(PARAMETER_PROBLEM, "Bad MASK value `%s'", optarg);
break;
"CONNMARK target: No operation specified");
}
-#ifdef KERNEL_64_USERSPACE_32
-static void
-print_mark(unsigned long long mark)
-{
- printf("0x%llx", mark);
-}
-
-static void
-print_mask(const char *text, unsigned long long mask)
-{
- if (mask != ~0ULL)
- printf("%s0x%llx", text, mask);
-}
-
-#else
-
static void
print_mark(unsigned long mark)
{
static void
print_mask(const char *text, unsigned long mask)
{
- if (mask != ~0UL)
+ if (mask != 0xffffffffUL)
printf("%s0x%lx", text, mask);
}
-#endif
/* Prints out the target info. */
int portok;
if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP)
+ || entry->ip.proto == IPPROTO_UDP
+ || entry->ip.proto == IPPROTO_ICMP)
portok = 1;
else
portok = 0;
exit_error(PARAMETER_PROBLEM,
"Unexpected `!' after --to-destination");
+ if (*flags) {
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version > LINUX_VERSION(2, 6, 10))
+ exit_error(PARAMETER_PROBLEM,
+ "Multiple --to-destination not supported");
+ }
*target = parse_to(optarg, portok, info);
*flags = 1;
return 1;
modified.
.RS
.PP
-You can add several --to-destination options. If you specify more
-than one destination address, either via an address range or multiple
---to-destination options, a simple round-robin (one after another in
-cycle) load balancing takes place between these adresses.
+In Kernels up to 2.6.10 you can add several --to-destination options. For
+those kernels, if you specify more than one destination address, either via an
+address range or multiple --to-destination options, a simple round-robin (one
+after another in cycle) load balancing takes place between these addresses.
+Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+anymore.
+
};
static void
-parse_dscp(const unsigned char *s, struct ipt_DSCP_info *dinfo)
+parse_dscp(const char *s, struct ipt_DSCP_info *dinfo)
{
unsigned int dscp;
static void
-parse_class(const unsigned char *s, struct ipt_DSCP_info *dinfo)
+parse_class(const char *s, struct ipt_DSCP_info *dinfo)
{
unsigned int dscp = class_to_dscp(s);
= (struct ip_nat_multi_range *)(*target)->data;
if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP)
+ || entry->ip.proto == IPPROTO_UDP
+ || entry->ip.proto == IPPROTO_ICMP)
portok = 1;
else
portok = 0;
+++ /dev/null
-/* Shared library add-on to iptables to add IP pool mangling target. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <ctype.h>
-
-#include <iptables.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ip_nat_rule.h>
-#include <linux/netfilter_ipv4/ip_pool.h>
-#include <linux/netfilter_ipv4/ipt_pool.h>
-
-#include <libippool/ip_pool_support.h>
-
-/* FIXME --RR */
-#define ip_pool_init ip_POOL_init
-#define ip_pool_get_index ip_POOL_get_index
-#define ip_pool_get_name ip_POOL_get_name
-#include "../ippool/libippool.c"
-
-/* Function which prints out usage message. */
-static void
-help(void)
-{
- printf(
-"POOL v%s options:\n"
-" --add-srcip <pool>\n"
-" --del-srcip <pool>\n"
-" --add-dstip <pool>\n"
-" --del-dstip <pool>\n"
-" add/del src/dst IP from pool.\n\n",
-IPTABLES_VERSION);
-}
-
-static struct option opts[] = {
- { "add-srcip", 1, 0, '1' },
- { "del-srcip", 1, 0, '2' },
- { "add-dstip", 1, 0, '3' },
- { "del-dstip", 1, 0, '4' },
- { 0 }
-};
-
-/* Initialize the target. */
-static void
-init(struct ipt_entry_target *target, unsigned int *nfcache)
-{
- struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data;
-
- ipi->src = ipi->dst = IP_POOL_NONE;
- ipi->flags = 0;
-
-}
-
-/* Function which parses command options; returns true if it
- ate an option */
-static int
-parse(int c, char **argv, int invert, unsigned int *flags,
- const struct ipt_entry *entry,
- struct ipt_entry_target **target)
-{
- struct ipt_pool_info *ipi = (struct ipt_pool_info *) (*target)->data;
- switch (c) {
- case '1': /* --add-srcip <pool> */
- ipi->src = ip_pool_get_index(optarg);
- ipi->flags &= ~IPT_POOL_DEL_SRC;
- break;
- case '2': /* --del-srcip <pool> */
- ipi->src = ip_pool_get_index(optarg);
- ipi->flags |= IPT_POOL_DEL_SRC;
- break;
- case '3': /* --add-dstip <pool> */
- ipi->dst = ip_pool_get_index(optarg);
- ipi->flags &= ~IPT_POOL_DEL_DST;
- break;
- case '4': /* --del-dstip <pool> */
- ipi->dst = ip_pool_get_index(optarg);
- ipi->flags |= IPT_POOL_DEL_DST;
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-/* Final check; don't care. */
-static void final_check(unsigned int flags)
-{
-}
-
-/* Prints out the targinfo. */
-static void
-print(const struct ipt_ip *ip,
- const struct ipt_entry_target *target,
- int numeric)
-{
- char buf[256];
- struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data;
-
- printf("POOL");
- if (ipi->src != IP_POOL_NONE) {
- printf(" --%s-srcip %s",
- (ipi->flags & IPT_POOL_DEL_SRC) ? "del" : "add",
- ip_pool_get_name(buf, sizeof(buf), ipi->src, numeric));
- }
- if (ipi->dst != IP_POOL_NONE) {
- printf(" --%s-dstip %s",
- (ipi->flags & IPT_POOL_DEL_DST) ? "del" : "add",
- ip_pool_get_name(buf, sizeof(buf), ipi->dst, numeric));
- }
-}
-
-/* Saves the union ipt_targinfo in parsable form to stdout. */
-static void
-save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
-{
- char buf[256];
- struct ipt_pool_info *ipi = (struct ipt_pool_info *) target->data;
-
- printf("-j POOL");
- if (ipi->src != IP_POOL_NONE) {
- printf(" --%s-srcip %s",
- (ipi->flags & IPT_POOL_DEL_SRC) ? "del" : "add",
- ip_pool_get_name(buf, sizeof(buf), ipi->src, 0));
- }
- if (ipi->dst != IP_POOL_NONE) {
- printf(" --%s-dstip %s",
- (ipi->flags & IPT_POOL_DEL_DST) ? "del" : "add",
- ip_pool_get_name(buf, sizeof(buf), ipi->dst, 0));
- }
-}
-
-static struct iptables_target ipt_pool_target = {
- .next = NULL,
- .name = "POOL",
- .version = IPTABLES_VERSION,
- .size = IPT_ALIGN(sizeof(struct ipt_pool_info)),
- .userspacesize = IPT_ALIGN(sizeof(struct ipt_pool_info)),
- .help = &help,
- .init = &init,
- .parse = &parse,
- .final_check = &final_check,
- .print = &print,
- .save = &save,
- .extra_opts = opts
-};
-
-void _init(void)
-{
- register_target(&ipt_pool_target);
-}
int portok;
if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP)
+ || entry->ip.proto == IPPROTO_UDP
+ || entry->ip.proto == IPPROTO_ICMP)
portok = 1;
else
portok = 0;
IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"},
{"icmp-host-prohibited", "host-prohib",
IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"},
- {"tcp-reset", "tcp-reset",
+ {"tcp-reset", "tcp-rst",
IPT_TCP_RESET, "TCP RST packet"},
{"icmp-admin-prohibited", "admin-prohib",
IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"}
int portok;
if (entry->ip.proto == IPPROTO_TCP
- || entry->ip.proto == IPPROTO_UDP)
+ || entry->ip.proto == IPPROTO_UDP
+ || entry->ip.proto == IPPROTO_ICMP)
portok = 1;
else
portok = 0;
exit_error(PARAMETER_PROBLEM,
"Unexpected `!' after --to-source");
+ if (*flags) {
+ if (!kernel_version)
+ get_kernel_version();
+ if (kernel_version > LINUX_VERSION(2, 6, 10))
+ exit_error(PARAMETER_PROBLEM,
+ "Multiple --to-source not supported");
+ }
*target = parse_to(optarg, portok, info);
*flags = 1;
return 1;
1024 or above. Where possible, no port alteration will occur.
.RS
.PP
-You can add several --to-source options. If you specify more
-than one source address, either via an address range or multiple
---to-source options, a simple round-robin (one after another in
-cycle) takes place between these adresses.
+In Kernels up to 2.6.10, you can add several --to-source options. For those
+kernels, if you specify more than one source address, either via an address
+range or multiple --to-source options, a simple round-robin (one after another
+in cycle) takes place between these addresses.
+Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+anymore.
outgoing interface's MTU minus 40). Of course, it can only be used
in conjunction with
.BR "-p tcp" .
+It is only valid in the
+.BR mangle
+table.
.br
This target is used to overcome criminally braindead ISPs or servers
which block ICMP Fragmentation Needed packets. The symptoms of this
Workaround: activate this option and add a rule to your firewall
configuration like:
.nf
- iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \\
+ iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \\
-j TCPMSS --clamp-mss-to-pmtu
.fi
.TP
}
static void
-parse_tos(const unsigned char *s, struct ipt_tos_target_info *info)
+parse_tos(const char *s, struct ipt_tos_target_info *info)
{
unsigned int i, tos;
-This module matches the SPIs in AH header of IPSec packets.
+This module matches the SPIs in Authentication header of IPsec packets.
.TP
.BR "--ahspi " "[!] \fIspi\fP[:\fIspi\fP]"
};
static void
-parse_comment(const unsigned char *s, struct ipt_comment_info *info)
+parse_comment(const char *s, struct ipt_comment_info *info)
{
int slen = strlen(s);
exit_error(PARAMETER_PROBLEM,
"COMMENT must be shorter than %i characters", IPT_MAX_COMMENT_LEN);
}
- strcpy(info->comment, s);
+ strcpy((char *)info->comment, s);
}
/* Function which parses command options; returns true if it
This matches if a specific /proc filename is '0' or '1'.
.TP
-.BI "--condition " "[!] filename"
+.BI "--condition " "[!] \fIfilename\fP"
Match on boolean value stored in /proc/net/ipt_condition/filename file
break;
case '3':
if (!strcmp(optarg, "packets"))
- sinfo->what = IPT_CONNBYTES_WHAT_PKTS;
+ sinfo->what = IPT_CONNBYTES_PKTS;
else if (!strcmp(optarg, "bytes"))
- sinfo->what = IPT_CONNBYTES_WHAT_BYTES;
+ sinfo->what = IPT_CONNBYTES_BYTES;
else if (!strcmp(optarg, "avgpkt"))
- sinfo->what = IPT_CONNBYTES_WHAT_AVGPKT;
+ sinfo->what = IPT_CONNBYTES_AVGPKT;
else
exit_error(PARAMETER_PROBLEM,
"Unknown --connbytes-mode `%s'", optarg);
{
if (flags != 7)
exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes'"
- "`--connbytes-direction' and `--connbytes-mode'");
+ "`--connbytes-dir' and `--connbytes-mode'");
}
static void print_mode(struct ipt_connbytes_info *sinfo)
{
switch (sinfo->what) {
- case IPT_CONNBYTES_WHAT_PKTS:
+ case IPT_CONNBYTES_PKTS:
fputs("packets ", stdout);
break;
- case IPT_CONNBYTES_WHAT_BYTES:
+ case IPT_CONNBYTES_BYTES:
fputs("bytes ", stdout);
break;
- case IPT_CONNBYTES_WHAT_AVGPKT:
+ case IPT_CONNBYTES_AVGPKT:
fputs("avgpkt ", stdout);
break;
default:
fputs("--connbytes-mode ", stdout);
print_mode(sinfo);
- fputs("--connbytes-direction ", stdout);
+ fputs("--connbytes-dir ", stdout);
print_direction(sinfo);
}
char *end;
case '1':
check_inverse(optarg, &invert, &optind, 0);
-#ifdef KERNEL_64_USERSPACE_32
- markinfo->mark = strtoull(optarg, &end, 0);
- markinfo->mask = ~0ULL;
- if (*end == '/')
- markinfo->mask = strtoull(end+1, &end, 0);
-#else
+
markinfo->mark = strtoul(optarg, &end, 0);
- markinfo->mask = ~0UL;
+ markinfo->mask = 0xffffffffUL;
+
if (*end == '/')
markinfo->mask = strtoul(end+1, &end, 0);
-#endif
+
if (*end != '\0' || end == optarg)
exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
if (invert)
return 1;
}
-#ifdef KERNEL_64_USERSPACE_32
-static void
-print_mark(unsigned long long mark, unsigned long long mask, int numeric)
-{
- if(mask != ~0ULL)
- printf("0x%llx/0x%llx ", mark, mask);
- else
- printf("0x%llx ", mark);
-}
-#else
static void
print_mark(unsigned long mark, unsigned long mask, int numeric)
{
- if(mask != ~0UL)
+ if(mask != 0xffffffffUL)
printf("0x%lx/0x%lx ", mark, mask);
else
printf("0x%lx ", mark);
}
-#endif
/* Final check; must have specified --mark. */
static void
{
char buf[BUFSIZ];
- if (inv)
- fputc('!', stdout);
+ if (inv)
+ printf("! ");
if (mask->s_addr == 0L && !numeric)
printf("%s ", "anywhere");
print_state(sinfo->statemask);
}
+ if(sinfo->flags & IPT_CONNTRACK_PROTO) {
+ printf("%sctproto ", optpfx);
+ if (sinfo->invflags & IPT_CONNTRACK_PROTO)
+ printf("! ");
+ printf("%u ", sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum);
+ }
+
if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) {
printf("%sctorigsrc ", optpfx);
};
static void
-parse_dscp(const unsigned char *s, struct ipt_dscp_info *dinfo)
+parse_dscp(const char *s, struct ipt_dscp_info *dinfo)
{
unsigned int dscp;
destination IP or per destination port base. As opposed to the `limit' match,
every destination ip / destination port has it's own limit.
.TP
+THIS MODULE IS DEPRECATED AND HAS BEEN REPLACED BY ``hashlimit''
+.TP
.BI "--dstlimit " "avg"
Maximum average match rate (packets per second unless followed by /sec /minute /hour /day postfixes).
.TP
-This module matches the SPIs in ESP header of IPSec packets.
+This module matches the SPIs in ESP header of IPsec packets.
.TP
.BR "--espspi " "[!] \fIspi\fP[:\fIspi\fP]"
This module matches a rate limit based on a fuzzy logic controller [FLC]
.TP
-.BI "--lower-limit "number"
+.BI "--lower-limit " "number"
Specifies the lower limit (in packets per second).
.TP
.BI "--upper-limit " "number"
This module matches the length of a packet against a specific value
or range of values.
.TP
-.BR "--length " "\fIlength\fP[:\fIlength\fP]"
+.BR "--length " "[!] \fIlength\fP[:\fIlength\fP]"
target below).
.TP
.BR "--mark " "\fIvalue\fP[/\fImask\fP]"
-Matches packets with the given unsigned mark value (if a mask is
-specified, this is logically ANDed with the mask before the
+Matches packets with the given unsigned mark value (if a \fImask\fP is
+specified, this is logically ANDed with the \fImask\fP before the
comparison).
if (*flags & IPT_PHYSDEV_OP_IN)
goto multiple_use;
check_inverse(optarg, &invert, &optind, 0);
- parse_interface(argv[optind-1], info->physindev, info->in_mask);
+ parse_interface(argv[optind-1], info->physindev,
+ (unsigned char *)info->in_mask);
if (invert)
info->invert |= IPT_PHYSDEV_OP_IN;
info->bitmask |= IPT_PHYSDEV_OP_IN;
goto multiple_use;
check_inverse(optarg, &invert, &optind, 0);
parse_interface(argv[optind-1], info->physoutdev,
- info->out_mask);
+ (unsigned char *)info->out_mask);
if (invert)
info->invert |= IPT_PHYSDEV_OP_OUT;
info->bitmask |= IPT_PHYSDEV_OP_OUT;
a transparent bridging IP firewall and is only useful for kernel versions
above version 2.5.44.
.TP
-.B --physdev-in name
+.BR --physdev-in " [!] \fIname\fP"
Name of a bridge port via which a packet is received (only for
packets entering the
.BR INPUT ,
interface which begins with this name will match. If the packet didn't arrive
through a bridge device, this packet won't match this option, unless '!' is used.
.TP
-.B --physdev-out name
+.BR --physdev-out " [!] \fIname\fP"
Name of a bridge port via which a packet is going to be sent (for packets
entering the
.BR FORWARD ,
the output device will be, then the packet won't match this option, unless
'!' is used.
.TP
-.B --physdev-is-in
+.RB "[!] " --physdev-is-in
Matches if the packet has entered through a bridge interface.
.TP
-.B --physdev-is-out
+.RB "[!] " --physdev-is-out
Matches if the packet will leave through a bridge interface.
.TP
-.B --physdev-is-bridged
+.RB "[!] " --physdev-is-bridged
Matches if the packet is being bridged and therefore is not being routed.
This is only useful in the FORWARD and POSTROUTING chains.
+++ /dev/null
-/* Shared library add-on to iptables to add IP address pool matching. */
-#include <stdio.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <ctype.h>
-
-#include <iptables.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ipt_pool.h>
-
-#include <libippool/ip_pool_support.h>
-
-/* FIXME --RR */
-#include "../ippool/libippool.c"
-
-/* Function which prints out usage message. */
-static void
-help(void)
-{
- printf(
-"pool v%s options:\n"
-" [!] --srcpool NAME|INDEX\n"
-" [!] --dstpool NAME|INDEX\n"
-" Pool index (or name from %s) to match\n"
-"\n", IPTABLES_VERSION, IPPOOL_CONF);
-}
-
-static struct option opts[] = {
- { "srcpool", 1, 0, '1' },
- { "dstpool", 1, 0, '2' },
- {0}
-};
-
-/* Initialize the match. */
-static void
-init(struct ipt_entry_match *match, unsigned int *nfcache)
-{
- struct ipt_pool_info *info =
- (struct ipt_pool_info *)match->data;
-
- info->src = IP_POOL_NONE;
- info->dst = IP_POOL_NONE;
- info->flags = 0;
-}
-
-/* Function which parses command options; returns true if it ate an option */
-static int
-parse(int c, char **argv, int invert, unsigned int *flags,
- const struct ipt_entry *entry,
- unsigned int *nfcache,
- struct ipt_entry_match **match)
-{
- struct ipt_pool_info *info =
- (struct ipt_pool_info *)(*match)->data;
-
- switch (c) {
- case '1':
- check_inverse(optarg, &invert, &optind, 0);
- info->src = ip_pool_get_index(argv[optind-1]);
- if (invert) info->flags |= IPT_POOL_INV_SRC;
- *flags = 1;
- break;
- case '2':
- check_inverse(optarg, &invert, &optind, 0);
- info->dst = ip_pool_get_index(argv[optind-1]);
- if (invert) info->flags |= IPT_POOL_INV_DST;
- *flags = 1;
- break;
-
- default:
- return 0;
- }
-
- return 1;
-}
-
-/* Final check; must have specified --srcpool or --dstpool. */
-static void final_check(unsigned int flags)
-{
- if (!flags)
- exit_error(PARAMETER_PROBLEM, "You must specify either `--srcpool or --dstpool'");
-}
-
-/* Prints out the matchinfo. */
-static void
-print(const struct ipt_ip *ip,
- const struct ipt_entry_match *match,
- int numeric)
-{
- char buf[256];
- struct ipt_pool_info *info =
- (struct ipt_pool_info *)match->data;
-
- if (info->src != IP_POOL_NONE)
- printf("%ssrcpool %s ",
- (info->flags & IPT_POOL_INV_SRC) ? "!" : "",
- ip_pool_get_name(buf, sizeof(buf), info->src, 0));
- if (info->dst != IP_POOL_NONE)
- printf("%sdstpool %s ",
- (info->flags & IPT_POOL_INV_DST) ? "!" : "",
- ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
-}
-
-/* Saves the matchinfo in parsable form to stdout. */
-static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
-{
- char buf[256];
- struct ipt_pool_info *info =
- (struct ipt_pool_info *)match->data;
-
- if (info->src != IP_POOL_NONE)
- printf("%s--srcpool %s ",
- (info->flags & IPT_POOL_INV_SRC) ? "! " : "",
- ip_pool_get_name(buf, sizeof(buf), info->src, 0));
- if (info->dst != IP_POOL_NONE)
- printf("%s--dstpool %s ",
- (info->flags & IPT_POOL_INV_DST) ? "! " : "",
- ip_pool_get_name(buf, sizeof(buf), info->dst, 0));
-}
-
-static struct iptables_match pool = {
- .next = NULL,
- .name = "pool",
- .version = IPTABLES_VERSION,
- .size = IPT_ALIGN(sizeof(struct ipt_pool_info)),
- .userspacesize = IPT_ALIGN(sizeof(struct ipt_pool_info)),
- .help = &help,
- .init = &init,
- .parse = &parse,
- .final_check = &final_check,
- .print = &print,
- .save = &save,
- .extra_opts = opts
-};
-
-void _init(void)
-{
- register_match(&pool);
-}
}
-static int k_atoi(signed char *string)
+static int k_atoi(char *string)
{
unsigned int result = 0;
int maxoctet = IPT_RPC_CHAR_LEN;
#include <iptables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
#include <linux/netfilter_ipv4/ipt_sctp.h>
+/* Some ZS!#@:$%*#$! has replaced the ELEMCOUNT macro in ipt_sctp.h with
+ * ARRAY_SIZE without noticing that this file is used from userserspace,
+ * and userspace doesn't have ARRAY_SIZE */
+
+#ifndef ELEMCOUNT
+#define ELEMCOUNT ARRAY_SIZE
+#endif
+
#if 0
#define DEBUGP(format, first...) printf(format, ##first)
#define static
*
* Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
*
+ * 2005-08-05 Pablo Neira Ayuso <pablo@eurodev.net>
+ * - reimplemented to use new string matching iptables match
+ * - add functionality to match packets by using window offsets
+ * - add functionality to select the string matching algorithm
+ *
* ChangeLog
* 29.12.2003: Michael Rash <mbr@cipherdyne.org>
* Fixed iptables save/restore for ascii strings
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
-
#include <iptables.h>
+#include <stddef.h>
#include <linux/netfilter_ipv4/ipt_string.h>
-
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"STRING match v%s options:\n"
+"--from Offset to start searching from\n"
+"--to Offset to stop searching\n"
+"--algo Algorithm\n"
"--string [!] string Match a string in a packet\n"
"--hex-string [!] string Match a hex string in a packet\n",
IPTABLES_VERSION);
}
-
static struct option opts[] = {
- { .name = "string", .has_arg = 1, .flag = 0, .val = '1' },
- { .name = "hex-string", .has_arg = 1, .flag = 0, .val = '2' },
- { .name = 0 }
+ { "from", 1, 0, '1' },
+ { "to", 1, 0, '2' },
+ { "algo", 1, 0, '3' },
+ { "string", 1, 0, '4' },
+ { "hex-string", 1, 0, '5' },
+ {0}
};
static void
-parse_string(const unsigned char *s, struct ipt_string_info *info)
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+ struct ipt_string_info *i = (struct ipt_string_info *) m->data;
+
+ if (i->to_offset == 0)
+ i->to_offset = (u_int16_t) ~0UL;
+}
+
+static void
+parse_string(const char *s, struct ipt_string_info *info)
{
- if (strlen(s) <= BM_MAX_NLEN) strcpy(info->string, s);
- else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
+ if (strlen(s) <= IPT_STRING_MAX_PATTERN_SIZE) {
+ strncpy(info->pattern, s, IPT_STRING_MAX_PATTERN_SIZE);
+ info->patlen = strlen(s);
+ return;
+ }
+ exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
}
+static void
+parse_algo(const char *s, struct ipt_string_info *info)
+{
+ if (strlen(s) <= IPT_STRING_MAX_ALGO_NAME_SIZE) {
+ strncpy(info->algo, s, IPT_STRING_MAX_ALGO_NAME_SIZE);
+ return;
+ }
+ exit_error(PARAMETER_PROBLEM, "ALGO too long `%s'", s);
+}
static void
-parse_hex_string(const unsigned char *s, struct ipt_string_info *info)
+parse_hex_string(const char *s, struct ipt_string_info *info)
{
int i=0, slen, sindex=0, schar;
short hex_f = 0, literal_f = 0;
exit_error(PARAMETER_PROBLEM,
"Bad literal placement at end of string");
}
- info->string[sindex] = s[i+1];
+ info->pattern[sindex] = s[i+1];
i += 2; /* skip over literal char */
literal_f = 0;
} else if (hex_f) {
if (! sscanf(hextmp, "%x", &schar))
exit_error(PARAMETER_PROBLEM,
"Invalid hex char `%c'", s[i]);
- info->string[sindex] = (char) schar;
+ info->pattern[sindex] = (char) schar;
if (s[i+2] == ' ')
i += 3; /* spaces included in the hex block */
else
i += 2;
} else { /* the char is not part of hex data, so just copy */
- info->string[sindex] = s[i];
+ info->pattern[sindex] = s[i];
i++;
}
- if (sindex > BM_MAX_NLEN)
+ if (sindex > IPT_STRING_MAX_PATTERN_SIZE)
exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
sindex++;
}
- info->len = sindex;
+ info->patlen = sindex;
}
+#define STRING 0x1
+#define ALGO 0x2
+#define FROM 0x4
+#define TO 0x8
/* Function which parses command options; returns true if it
ate an option */
switch (c) {
case '1':
- if (*flags)
+ if (*flags & FROM)
exit_error(PARAMETER_PROBLEM,
- "Can't specify multiple strings");
-
+ "Can't specify multiple --from");
+ stringinfo->from_offset = atoi(optarg);
+ *flags |= FROM;
+ break;
+ case '2':
+ if (*flags & TO)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify multiple --to");
+ stringinfo->to_offset = atoi(optarg);
+ *flags |= TO;
+ break;
+ case '3':
+ if (*flags & ALGO)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify multiple --algo");
+ parse_algo(optarg, stringinfo);
+ *flags |= ALGO;
+ break;
+ case '4':
+ if (*flags & STRING)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify multiple --string");
check_inverse(optarg, &invert, &optind, 0);
parse_string(argv[optind-1], stringinfo);
if (invert)
stringinfo->invert = 1;
- stringinfo->len=strlen((char *)&stringinfo->string);
- *flags = 1;
+ stringinfo->patlen=strlen((char *)&stringinfo->pattern);
+ *flags |= STRING;
break;
- case '2':
- if (*flags)
+ case '5':
+ if (*flags & STRING)
exit_error(PARAMETER_PROBLEM,
- "Can't specify multiple strings");
+ "Can't specify multiple --hex-string");
check_inverse(optarg, &invert, &optind, 0);
parse_hex_string(argv[optind-1], stringinfo); /* sets length */
if (invert)
stringinfo->invert = 1;
- *flags = 1;
+ *flags |= STRING;
break;
default:
static void
final_check(unsigned int flags)
{
- if (!flags)
+ if (!(flags & STRING))
+ exit_error(PARAMETER_PROBLEM,
+ "STRING match: You must specify `--string' or "
+ "`--hex-string'");
+ if (!(flags & ALGO))
exit_error(PARAMETER_PROBLEM,
- "STRING match: You must specify `--string' or `--hex-string'");
+ "STRING match: You must specify `--algo'");
}
/* Test to see if the string contains non-printable chars or quotes */
const struct ipt_string_info *info =
(const struct ipt_string_info*) match->data;
- if (is_hex_string(info->string, info->len)) {
+ if (is_hex_string(info->pattern, info->patlen)) {
printf("STRING match %s", (info->invert) ? "!" : "");
- print_hex_string(info->string, info->len);
+ print_hex_string(info->pattern, info->patlen);
} else {
printf("STRING match %s", (info->invert) ? "!" : "");
- print_string(info->string, info->len);
+ print_string(info->pattern, info->patlen);
}
+ printf("ALGO name %s ", info->algo);
+ if (info->from_offset != 0)
+ printf("FROM %u ", info->from_offset);
+ if (info->to_offset != 0)
+ printf("TO %u", info->to_offset);
}
const struct ipt_string_info *info =
(const struct ipt_string_info*) match->data;
- if (is_hex_string(info->string, info->len)) {
+ if (is_hex_string(info->pattern, info->patlen)) {
printf("--hex-string %s", (info->invert) ? "! ": "");
- print_hex_string(info->string, info->len);
+ print_hex_string(info->pattern, info->patlen);
} else {
printf("--string %s", (info->invert) ? "! ": "");
- print_string(info->string, info->len);
+ print_string(info->pattern, info->patlen);
}
+ printf("--algo %s ", info->algo);
+ if (info->from_offset != 0)
+ printf("--from %u ", info->from_offset);
+ if (info->to_offset != 0)
+ printf("--to %u ", info->to_offset);
}
static struct iptables_match string = {
- .name = "string",
- .version = IPTABLES_VERSION,
- .size = IPT_ALIGN(sizeof(struct ipt_string_info)),
- .userspacesize = IPT_ALIGN(sizeof(struct ipt_string_info)),
- .help = &help,
- .parse = &parse,
- .final_check = &final_check,
- .print = &print,
- .save = &save,
- .extra_opts = opts
+ .name = "string",
+ .version = IPTABLES_VERSION,
+ .size = IPT_ALIGN(sizeof(struct ipt_string_info)),
+ .userspacesize = offsetof(struct ipt_string_info, config),
+ .help = help,
+ .init = init,
+ .parse = parse,
+ .final_check = final_check,
+ .print = print,
+ .save = save,
+ .extra_opts = opts
};
};
static void
-parse_tos(const unsigned char *s, struct ipt_tos_info *info)
+parse_tos(const char *s, struct ipt_tos_info *info)
{
unsigned int i;
unsigned int tos;
/* Shared library add-on to iptables to add TTL matching support
* (C) 2000 by Harald Welte <laforge@gnumonks.org>
*
- * $Id: libipt_ttl.c 3687 2005-02-14 13:13:04Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=kaber/emailAddress=kaber@netfilter.org $
+ * $Id: libipt_ttl.c,v 1.1.1.3 2006/07/28 14:34:27 mlhuang Exp $
*
* This program is released under the terms of GNU GPL */
struct ipt_entry_match **match)
{
struct ipt_ttl_info *info = (struct ipt_ttl_info *) (*match)->data;
- int value;
+ unsigned int value;
check_inverse(optarg, &invert, &optind, 0);
- if (string_to_number(optarg, 0, 255, &value) == -1)
- exit_error(PARAMETER_PROBLEM,
- "ttl: Expected value between 0 and 255");
-
switch (c) {
case '2':
+ if (string_to_number(optarg, 0, 255, &value) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "ttl: Expected value between 0 and 255");
+
if (invert)
info->mode = IPT_TTL_NE;
else
info->ttl = value;
break;
case '3':
+ if (string_to_number(optarg, 0, 255, &value) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "ttl: Expected value between 0 and 255");
+
if (invert)
exit_error(PARAMETER_PROBLEM,
"ttl: unexpected `!'");
info->ttl = value;
break;
case '4':
+ if (string_to_number(optarg, 0, 255, &value) == -1)
+ exit_error(PARAMETER_PROBLEM,
+ "ttl: Expected value between 0 and 255");
+
if (invert)
exit_error(PARAMETER_PROBLEM,
"ttl: unexpected `!'");
enum ip6t_tryload {
DONT_LOAD,
+ DURING_LOAD,
TRY_LOAD,
LOAD_MUST_SUCCEED
};
enum ipt_tryload {
DONT_LOAD,
+ DURING_LOAD,
TRY_LOAD,
LOAD_MUST_SUCCEED
};
iptc_handle_t *handle);
extern int for_each_chain(int (*fn)(const ipt_chainlabel, int, iptc_handle_t *),
int verbose, int builtinstoo, iptc_handle_t *handle);
+
+/* kernel revision handling */
+extern int kernel_version;
+extern void get_kernel_version(void);
+#define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z)
+#define LINUX_VERSION_MAJOR(x) (((x)>>16) & 0xFF)
+#define LINUX_VERSION_MINOR(x) (((x)>> 8) & 0xFF)
+#define LINUX_VERSION_PATCH(x) ( (x) & 0xFF)
+
#endif /*_IPTABLES_USER_H*/
PARAMETER_PROBLEM,
VERSION_PROBLEM
};
+
+/* this is a special 64bit data type that is 8-byte aligned */
+#define aligned_u64 unsigned long long __attribute__((aligned(8)))
+
extern void exit_printhelp() __attribute__((noreturn));
extern void exit_tryhelp(int) __attribute__((noreturn));
int check_inverse(const char option[], int *invert, int *optind, int argc);
+++ /dev/null
-/* support function prototypes for IP pool management (config file, mostly) */
-#ifndef _IP_POOL_SUPPORT_H
-#define _IP_POOL_SUPPORT_H
-
-#include <iptables.h>
-#include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/ip_pool.h>
-
-#ifndef IPPOOL_CONF
-#define IPPOOL_CONF "/etc/ippool.conf"
-#endif
-
-/* called just to draw in this support .o */
-void ip_pool_init(void);
-
-/* given a pool name (or number), return pool index, possibly reading .conf */
-ip_pool_t ip_pool_get_index(char *name);
-
-/* given a pool index, and a buffer to store a name, search for the index
- * in the .conf file, and give the textual name, if present; if not, the
- * numeric index is returned. If numeric_flag == 1, the numeric index is
- * always returned
- */
-char *ip_pool_get_name(char *buf, int size, ip_pool_t index, int numeric_flag);
-
-#endif /*_IP_POOL_SUPPORT_H*/
#define KERNEL_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)) || !defined IPS_EXPECTED
#define IPS_EXPECTED (1 << 0)
#define IPS_SEEN_REPLY (1 << 1)
#define IPS_ASSURED (1 << 2)
-.TH IP6TABLES 8 "Mar 09, 2002" "" ""
+.TH IP6TABLES 8 "Jan 22, 2006" "" ""
.\"
.\" Man page written by Andras Kis-Szabo <kisza@sch.bme.hu>
.\" It is based on iptables man page.
.I DROP
means to drop the packet on the floor.
.I QUEUE
-means to pass the packet to userspace (if supported by the kernel).
+means to pass the packet to userspace. (How the packet can be received
+by a userspace process differs by the particular queue handler. 2.4.x
+and 2.6.x kernels up to 2.6.13 include the
+.B
+ip_queue
+queue handler. Kernels 2.6.14 and later additionally include the
+.B
+nfnetlink_queue
+queue handler. Packets with a target of QUEUE will be sent to queue number '0'
+in this case. Please also see the
+.B
+NFQUEUE
+target as described later in this man page.)
.I RETURN
means stop traversing this chain and resume at the next rule in the
previous (calling) chain. If the end of a built-in chain is reached
(for altering packets being routed through the box), and
.B POSTROUTING
(for altering packets as they are about to go out).
+.TP
+.BR "raw" :
+This table is used mainly for configuring exemptions from connection
+tracking in combination with the NOTRACK target. It registers at the netfilter
+hooks with higher priority and is thus called before nf_conntrack, or any other
+IP6 tables. It provides the following built-in chains:
+.B PREROUTING
+(for packets arriving via any network interface)
+.B OUTPUT
+(for packets generated by local processes)
.RE
.SH OPTIONS
The options that are recognized by
The specified protocol can be one of
.IR tcp ,
.IR udp ,
-.IR ipv6-icmp|icmpv6 ,
-or
+.IR icmpv6 ,
+.IR esp ,
.IR all ,
or it can be a numeric value, representing one of these protocols or a
-different one. A protocol name from /etc/protocols is also allowed.
+different one. A protocol name from /etc/protocols is also allowed.
+But IPv6 extension headers except
+.IR esp
+are not allowed.
+.IR esp ,
+and
+.IR ipv6-nonext
+can be used with Kernel version 2.6.11 or later.
A "!" argument before the protocol inverts the
test. The number zero is equivalent to
.IR all .
to invert the sense of the match.
.\" @MATCH@
.SS ah
-This module matches the SPIs in AH header of IPSec packets.
+This module matches the parameters in Authentication header of IPsec packets.
.TP
.BR "--ahspi " "[!] \fIspi\fP[:\fIspi\fP]"
+Matches SPI.
+.TP
+.BR "--ahlen " "[!] \fIlength"
+Total length of this header in octets.
+.TP
+.BI "--ahres"
+Matches if the reserved field is filled with zero.
.SS condition
This matches if a specific /proc filename is '0' or '1'.
.TP
-.BI "--condition " "[!] filename"
+.BR "--condition " "[!] \fIfilename"
Match on boolean value stored in /proc/net/ip6t_condition/filename file
.SS dst
-This module matches the IPv6 destination header options
+This module matches the parameters in Destination Options header
.TP
-.BI "--dst-len" "[!]" "length"
-Total length of this header
+.BR "--dst-len " "[!] \fIlength"
+Total length of this header in octets.
.TP
-.BI "--dst-opts " "TYPE[:LEN],[,TYPE[:LEN]...]"
-Options and it's length (List).
+.BR "--dst-opts " "\fItype\fP[:\fIlength\fP][,\fItype\fP[:\fIlength\fP]...]"
+numeric type of option and the length of the option data in octets.
.SS esp
-This module matches the SPIs in ESP header of IPSec packets.
+This module matches the SPIs in ESP header of IPsec packets.
.TP
.BR "--espspi " "[!] \fIspi\fP[:\fIspi\fP]"
.SS eui64
-This module matches the EUI64 part of a stateless autoconfigured IPv6 address. It compares the source MAC address with the lower 64 bits of the IPv6 address.
+This module matches the EUI-64 part of a stateless autoconfigured IPv6 address.
+It compares the EUI-64 derived from the source MAC address in Ehternet frame
+with the lower 64 bits of the IPv6 source address. But "Universal/Local"
+bit is not compared. This module doesn't match other link layer frame, and
+is only valid in the
+.BR PREROUTING ,
+.BR INPUT
+and
+.BR FORWARD
+chains.
.SS frag
-This module matches the time IPv6 fragmentathion header
+This module matches the parameters in Fragment header.
.TP
-.BI "--fragid " "[!]" "id[:id]"
-Matches the given fragmentation ID (range).
+.BR "--fragid " "[!] \fIid\fP[:\fIid\fP]"
+Matches the given Identification or range of it.
.TP
-.BI "--fraglen " "[!]" "length"
-Matches the total length of this header.
+.BR "--fraglen " "[!] \fIlength\fP"
+This option cannot be used with kernel version 2.6.10 or later. The length of
+Fragment header is static and this option doesn't make sense.
.TP
-.BI "--fragres "
-Matches the reserved field, too.
+.BR "--fragres "
+Matches if the reserved fields are filled with zero.
.TP
-.BI "--fragfirst "
+.BR "--fragfirst "
Matches on the first fragment.
.TP
-.BI "[--fragmore]"
+.BR "[--fragmore]"
Matches if there are more fragments.
.TP
-.BI "[--fraglast]"
+.BR "[--fraglast]"
Matches if this is the last fragement.
.SS fuzzy
This module matches a rate limit based on a fuzzy logic controller [FLC]
.TP
-.BI "--lower-limit "number"
+.BI "--lower-limit " "number"
Specifies the lower limit (in packets per second).
.TP
.BI "--upper-limit " "number"
Specifies the upper limit (in packets per second).
.SS hbh
-This module matches the IPv6 hop-by-hop header options
+This module matches the parameters in Hop-by-Hop Options header
.TP
-.BI "--hbh-len" "[!]" "length"
-Total length of this header
+.BR "--hbh-len " "[!] \fIlength\fP"
+Total length of this header in octets.
.TP
-.BI "--hbh-opts " "TYPE[:LEN],[,TYPE[:LEN]...]"
-Options and it's length (List).
+.BR "--hbh-opts " "\fItype\fP[:\fIlength\fP][,\fItype\fP[:\fIlength\fP]...]"
+numeric type of option and the length of the option data in octets.
.SS hl
-This module matches the HOPLIMIT field in the IPv6 header.
+This module matches the Hop Limit field in the IPv6 header.
.TP
-.BI "--hl-eq " "value"
-Matches if HOPLIMIT equals the given value.
+.BR "--hl-eq " "[!] \fIvalue\fP"
+Matches if Hop Limit equals \fIvalue\fP.
.TP
-.BI "--hl-lt " "ttl"
-Matches if HOPLIMIT is less than the given value.
+.BI "--hl-lt " "value"
+Matches if Hop Limit is less than \fIvalue\fP.
.TP
-.BI "--hl-gt " "ttl"
-Matches if HOPLIMIT is greater than the given value.
+.BI "--hl-gt " "value"
+Matches if Hop Limit is greater than \fIvalue\fP.
.SS icmpv6
This extension is loaded if `--protocol ipv6-icmp' or `--protocol icmpv6' is
specified. It provides the following option:
.TP
-.BR "--icmpv6-type " "[!] \fItypename\fP"
-This allows specification of the ICMP type, which can be a numeric
-IPv6-ICMP type, or one of the IPv6-ICMP type names shown by the command
+.BR "--icmpv6-type " "[!] \fItype\fP[/\fIcode\fP]|\fItypename\fP"
+This allows specification of the ICMPv6 type, which can be a numeric
+ICMPv6
+.IR type ,
+.IR type
+and
+.IR code ,
+or one of the ICMPv6 type names shown by the command
.nf
ip6tables -p ipv6-icmp -h
.fi
.SS ipv6header
-This module matches on IPv6 option headers
-.TP
-.BI "--header " "[!]" "headers"
-Matches the given type of headers.
-Names: hop,dst,route,frag,auth,esp,none,proto
-Long Names: hop-by-hop,ipv6-opts,ipv6-route,ipv6-frag,ah,esp,ipv6-nonxt,protocol
-Numbers: 0,60,43,44,51,50,59
-.TP
-.BI "--soft"
-The header CONTAINS the specified extensions.
+This module matches IPv6 extension headers and/or upper layer header.
+.TP
+.BR "--header " "[!] \fIheader\fP[,\fIheader\fP...]"
+Matches the packet which EXACTLY includes all specified headers. The headers
+encapsulated with ESP header are out of scope.
+.IR header
+can be
+.IR hop | hop-by-hop
+(Hop-by-Hop Options header),
+.IR dst
+(Destination Options header),
+.IR route
+(Routing header),
+.IR frag
+(Fragment header),
+.IR auth
+(Authentication header),
+.IR esp
+(Encapsulating Security Payload header),
+.IR none
+(No Next header) which matches 59 in the 'Next Header field' of IPv6 header or any IPv6 extension headers, or
+.IR proto
+which matches any upper layer protocol header. A protocol name from /etc/protocols and numeric value also allowed. The number 255 is equivalent to
+.IR proto .
+.TP
+.BR "[--soft]"
+Matches if the packet includes all specified headers with
+.BR --header ,
+AT LEAST.
.SS length
-This module matches the length of a packet against a specific value
-or range of values.
+This module matches the length of the IPv6 payload in octets, or range of it.
+IPv6 header itself isn't counted.
.TP
-.BR "--length " "\fIlength\fP[:\fIlength\fP]"
+.BR "--length " "[!] \fIlength\fP[:\fIlength\fP]"
.SS limit
This module matches at a limited rate using a token bucket filter.
A rule using this extension will match until this limit is reached
target below).
.TP
.BR "--mark " "\fIvalue\fP[/\fImask\fP]"
-Matches packets with the given unsigned mark value (if a mask is
-specified, this is logically ANDed with the mask before the
+Matches packets with the given unsigned mark value (if a \fImask\fP is
+specified, this is logically ANDed with the \fImask\fP before the
comparison).
.SS multiport
This module matches a set of source or destination ports. Up to 15
ports can be specified. A port range (port:port) counts as two
-ports. It can only be used in conjunction with
+ports, but range isn't supported now. It can only be used in conjunction
+with
.B "-p tcp"
or
.BR "-p udp" .
This module attempts to match various characteristics of the packet
creator, for locally-generated packets. It is only valid in the
.B OUTPUT
-chain, and even this some packets (such as ICMP ping responses) may
+chain, and even this some packets (such as ICMPv6 ping responses) may
have no owner, and hence never match. This is regarded as experimental.
.TP
.BI "--uid-owner " "userid"
a transparent bridging IP firewall and is only useful for kernel versions
above version 2.5.44.
.TP
-.B --physdev-in name
+.BR --physdev-in " [!] \fIname\fP"
Name of a bridge port via which a packet is received (only for
packets entering the
.BR INPUT ,
interface which begins with this name will match. If the packet didn't arrive
through a bridge device, this packet won't match this option, unless '!' is used.
.TP
-.B --physdev-out name
+.BR --physdev-out " [!] \fIname\fP"
Name of a bridge port via which a packet is going to be sent (for packets
entering the
.BR FORWARD ,
the output device will be, then the packet won't match this option, unless
'!' is used.
.TP
-.B --physdev-is-in
+.RB "[!] " --physdev-is-in
Matches if the packet has entered through a bridge interface.
.TP
-.B --physdev-is-out
+.RB "[!] " --physdev-is-out
Matches if the packet will leave through a bridge interface.
.TP
-.B --physdev-is-bridged
+.RB "[!] " --physdev-is-bridged
Matches if the packet is being bridged and therefore is not being routed.
This is only useful in the FORWARD and POSTROUTING chains.
+.SS policy
+This modules matches the policy used by IPsec for handling a packet.
+.TP
+.BI "--dir " "in|out"
+Used to select whether to match the policy used for decapsulation or the
+policy that will be used for encapsulation.
+.B in
+is valid in the
+.B PREROUTING, INPUT and FORWARD
+chains,
+.B out
+is valid in the
+.B POSTROUTING, OUTPUT and FORWARD
+chains.
+.TP
+.BI "--pol " "none|ipsec"
+Matches if the packet is subject to IPsec processing.
+.TP
+.BI "--strict"
+Selects whether to match the exact policy or match if any rule of
+the policy matches the given policy.
+.TP
+.BI "--reqid " "id"
+Matches the reqid of the policy rule. The reqid can be specified with
+.B setkey(8)
+using
+.B unique:id
+as level.
+.TP
+.BI "--spi " "spi"
+Matches the SPI of the SA.
+.TP
+.BI "--proto " "ah|esp|ipcomp"
+Matches the encapsulation protocol.
+.TP
+.BI "--mode " "tunnel|transport"
+Matches the encapsulation mode.
+.TP
+.BI "--tunnel-src " "addr[/mask]"
+Matches the source end-point address of a tunnel mode SA.
+Only valid with --mode tunnel.
+.TP
+.BI "--tunnel-dst " "addr[/mask]"
+Matches the destination end-point address of a tunnel mode SA.
+Only valid with --mode tunnel.
+.TP
+.BI "--next"
+Start the next element in the policy specification. Can only be used with
+--strict
.SS random
This module randomly matches a certain percentage of all packets.
.TP
.SS rt
Match on IPv6 routing header
.TP
-.BI "--rt-type " "[!]" "type"
+.BR "--rt-type" " [!] \fItype\fP"
Match the type (numeric).
.TP
-.BI "--rt-segsleft" "[!]" "num[:num]"
+.BR "--rt-segsleft" " [!] \fInum\fP[:\fInum\fP]"
Match the `segments left' field (range).
.TP
-.BI "--rt-len" "[!]" "length"
-Match the length of this header
+.BR "--rt-len" " [!] \fIlength\fP"
+Match the length of this header.
.TP
-.BI "--rt-0-res"
+.BR "--rt-0-res"
Match the reserved field, too (type=0)
.TP
-.BI "--rt-0-addrs ADDR[,ADDR...]
+.BR "--rt-0-addrs" " \fIADDR\fP[,\fIADDR\fP...]"
Match type=0 addresses (list).
.TP
-.BI "--rt-0-not-strict"
+.BR "--rt-0-not-strict"
List of type=0 addresses is not a strict list.
.SS tcp
These extensions are loaded if `--protocol tcp' is specified. It
in the standard distribution.
.\" @TARGET@
.SS HL
-This is used to modify the IPv6 HOPLIMIT header field. The HOPLIMIT field is
-similar to what is known as TTL value in IPv4. Setting or incrementing the
-HOPLIMIT field can potentially be very dangerous, so it should be avoided at
-any cost.
-.TP
-.B Don't ever set or increment the value on packets that leave your local network!
+This is used to modify the Hop Limit field in IPv6 header. The Hop Limit field
+is similar to what is known as TTL value in IPv4. Setting or incrementing the
+Hop Limit field can potentially be very dangerous, so it should be avoided at
+any cost. This target is only valid in
.B mangle
table.
.TP
+.B Don't ever set or increment the value on packets that leave your local network!
+.TP
.BI "--hl-set " "value"
-Set the HOPLIMIT value to `value'.
+Set the Hop Limit to `value'.
.TP
.BI "--hl-dec " "value"
-Decrement the HOPLIMIT value `value' times.
+Decrement the Hop Limit `value' times.
.TP
.BI "--hl-inc " "value"
-Increment the HOPLIMIT value `value' times.
+Increment the Hop Limit `value' times.
.SS LOG
Turn on kernel logging of matching packets. When this option is set
for a rule, the Linux kernel will print some information on all
table.
.TP
.BI "--set-mark " "mark"
+.SS NFQUEUE
+This target is an extension of the QUEUE target. As opposed to QUEUE, it allows
+you to put a packet into any specific queue, identified by its 16-bit queue
+number.
+.TP
+.BR "--queue-num " "\fIvalue"
+This specifies the QUEUE number to use. Valud queue numbers are 0 to 65535. The default value is 0.
+.TP
+It can only be used with Kernel versions 2.6.14 or later, since it requires
+the
+.B
+nfnetlink_queue
+kernel support.
.SS REJECT
This is used to send back an error packet in response to the matched
packet: otherwise it is equivalent to
.B " icmp6-port-unreachable"
.B " port-unreach"
.fi
-which return the appropriate IPv6-ICMP error message (\fBport-unreach\fP is
+which return the appropriate ICMPv6 error message (\fBport-unreach\fP is
the default). Finally, the option
.B tcp-reset
can be used on rules which only match the TCP protocol: this causes a
.I ident
(113/tcp) probes which frequently occur when sending mail to broken mail
hosts (which won't accept your mail otherwise).
+.B tcp-reset
+can only be used with kernel versions 2.6.14 or latter.
.SS ROUTE
This is used to explicitly override the core network stack's routing decision.
.BR ip6tables-restore(8),
.BR iptables (8),
.BR iptables-save (8),
-.BR iptables-restore (8).
+.BR iptables-restore (8),
+.BR libipq (3).
.P
The packet-filtering-HOWTO details iptables usage for
packet filtering, the NAT-HOWTO details NAT,
.PP
Jozsef Kadlecsik wrote the REJECT target.
.PP
-Harald Welte wrote the ULOG target, TTL match+target and libipulog.
+Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, aswell as TTL match+target and libipulog.
.PP
The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik,
James Morris, Harald Welte and Rusty Russell.
-.TH IP6TABLES 8 "Mar 09, 2002" "" ""
+.TH IP6TABLES 8 "Jan 22, 2006" "" ""
.\"
.\" Man page written by Andras Kis-Szabo <kisza@sch.bme.hu>
.\" It is based on iptables man page.
.I DROP
means to drop the packet on the floor.
.I QUEUE
-means to pass the packet to userspace (if supported by the kernel).
+means to pass the packet to userspace. (How the packet can be received
+by a userspace process differs by the particular queue handler. 2.4.x
+and 2.6.x kernels up to 2.6.13 include the
+.B
+ip_queue
+queue handler. Kernels 2.6.14 and later additionally include the
+.B
+nfnetlink_queue
+queue handler. Packets with a target of QUEUE will be sent to queue number '0'
+in this case. Please also see the
+.B
+NFQUEUE
+target as described later in this man page.)
.I RETURN
means stop traversing this chain and resume at the next rule in the
previous (calling) chain. If the end of a built-in chain is reached
(for altering packets being routed through the box), and
.B POSTROUTING
(for altering packets as they are about to go out).
+.TP
+.BR "raw" :
+This table is used mainly for configuring exemptions from connection
+tracking in combination with the NOTRACK target. It registers at the netfilter
+hooks with higher priority and is thus called before nf_conntrack, or any other
+IP6 tables. It provides the following built-in chains:
+.B PREROUTING
+(for packets arriving via any network interface)
+.B OUTPUT
+(for packets generated by local processes)
.RE
.SH OPTIONS
The options that are recognized by
The specified protocol can be one of
.IR tcp ,
.IR udp ,
-.IR ipv6-icmp|icmpv6 ,
-or
+.IR icmpv6 ,
+.IR esp ,
.IR all ,
or it can be a numeric value, representing one of these protocols or a
-different one. A protocol name from /etc/protocols is also allowed.
+different one. A protocol name from /etc/protocols is also allowed.
+But IPv6 extension headers except
+.IR esp
+are not allowed.
+.IR esp ,
+and
+.IR ipv6-nonext
+can be used with Kernel version 2.6.11 or later.
A "!" argument before the protocol inverts the
test. The number zero is equivalent to
.IR all .
.BR ip6tables-restore(8),
.BR iptables (8),
.BR iptables-save (8),
-.BR iptables-restore (8).
+.BR iptables-restore (8),
+.BR libipq (3).
.P
The packet-filtering-HOWTO details iptables usage for
packet filtering, the NAT-HOWTO details NAT,
.PP
Jozsef Kadlecsik wrote the REJECT target.
.PP
-Harald Welte wrote the ULOG target, TTL match+target and libipulog.
+Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, aswell as TTL match+target and libipulog.
.PP
The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik,
James Morris, Harald Welte and Rusty Russell.
}
static void
-add_command(int *cmd, const int newcmd, const int othercmds, int invert)
+add_command(unsigned int *cmd, const int newcmd, const int othercmds,
+ int invert)
{
if (invert)
exit_error(PARAMETER_PROBLEM, "unexpected ! flag");
}
#ifndef NO_SHARED_LIBS
- if (!ptr && tryload != DONT_LOAD) {
+ if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) {
char path[strlen(lib_dir) + sizeof("/libip6t_.so")
+ strlen(name)];
if (!icmphack)
}
#ifndef NO_SHARED_LIBS
- if (!ptr && tryload != DONT_LOAD) {
+ if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) {
char path[strlen(lib_dir) + sizeof("/libip6t_.so")
+ strlen(name)];
sprintf(path, "%s/libip6t_%s.so", lib_dir, name);
unsigned int num_old, num_new, i;
struct option *merge;
- /* Release previous options merged if any */
- free_opts(0);
-
for (num_old = 0; oldopts[num_old].name; num_old++);
for (num_new = 0; newopts[num_new].name; num_new++);
merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
memcpy(merge, oldopts, num_old * sizeof(struct option));
+ free_opts(0); /* Release previous options merged if any */
for (i = 0; i < num_new; i++) {
merge[num_old + i] = newopts[i];
merge[num_old + i].val += *option_offset;
exit(1);
}
- if (find_match(me->name, DONT_LOAD, NULL)) {
+ if (find_match(me->name, DURING_LOAD, NULL)) {
fprintf(stderr, "%s: match `%s' already registered.\n",
program_name, me->name);
exit(1);
exit(1);
}
- if (find_target(me->name, DONT_LOAD)) {
+ if (find_target(me->name, DURING_LOAD)) {
fprintf(stderr, "%s: target `%s' already registered.\n",
program_name, me->name);
exit(1);
+++ /dev/null
-EXTRAS+=$(shell [ -f $(KERNEL_DIR)/include/linux/netfilter_ipv4/ip_pool.h ] && echo ippool/libippool.a ippool/ippool)
-
-ifndef TOPLEVEL_INCLUDED
-local:
- cd .. && $(MAKE) $(KERN_TARGETS) $(SHARED_LIBS) $(EXTRAS)
-
-else
-EXTRA_DEPENDS+=$(shell [ -f $(KERNEL_DIR)/include/linux/netfilter_ipv4/ip_pool.h ] && echo ippool/libippool.d)
-
-ippool/libippool.a: ippool/libippool.a(ippool/libippool.o)
-
-ippool/libippool.d: %.d: %.c
- @-$(CC) -M -MG $(CFLAGS) $< | sed -e 's@^.*\.o:@$*.d $*.a($*.o):@' > $@
-
-ippool/ippool.o: ippool/ippool.c
-ippool/ippool: ippool/ippool.o ippool/libippool.a
- $(CC) $(CFLAGS) -o $@ $^
-endif
+++ /dev/null
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <arpa/inet.h>
-#include <linux/netfilter_ipv4/ip_pool.h>
-#include <libippool/ip_pool_support.h>
-
-/* translate errnos, as returned by our *sockopt() functions */
-static char *errno2msg(int op, int err)
-{
- switch(err) {
- case ERANGE:
- return "Address out of pool range";
- }
- return strerror(err);
-}
-
-static void usage(char *msg)
-{
- if (msg) fprintf(stderr, "ERROR: %s\n", msg);
- fprintf(stderr,
-"Usage: ippool [-LADCNF] [POOL] [args]\n"
-"The POOL argument is either a number, or a name from %s\n"
-, IPPOOL_CONF);
- fprintf(stderr,
-"ippool [-n] [-l|-L POOL] [-u] [-v]\n"
- "\tLists all (-l), or a single (-L) pool.\n"
- "\tWith -u, summarized usage counts are listed.\n"
- "\tWith -v, each pool membership is shown, one per line.\n"
-"ippool [-n] [-f|-F [POOL]]\n"
- "\tflushes POOL (or all pools.)\n"
-"ippool [-n] [-x|-X [POOL]]\n"
- "\tremoves POOL (or all pools.)\n"
-"ippool [-n] -B\n"
- "\tcreates all fully specified pools found in the config file.\n"
-"ippool [-n] -N POOL [-t type] [FIRST LAST]\n"
- "\tcreates POOL of IP addresses FIRST to LAST (inclusive). If a\n"
- "\tpool name from the config file %s is used, type and\n"
- "\taddress information can be defined there. The -t argument\n"
- "\tgives the type (default bitmap).\n"
-"ippool [-n] -A POOL ADDR\n"
- "\tadds ADDR to POOL\n"
-"ippool [-n] -D POOL ADDR\n"
- "\tremoves ADDR from POOL\n"
-"ippool [-n] -C POOL ADDR\n"
- "\ttests ADDR against membership in POOL\n"
-, IPPOOL_CONF);
- exit(1);
-}
-
-/* config file parsing */
-
-#define IP_POOL_T_NONE 0
-#define IP_POOL_T_BITMAP 1
-
-static int conf_type = IP_POOL_T_NONE;
-static unsigned long conf_addr = 0;
-static unsigned long conf_addr2 = 0;
-
-#define SCAN_EOF (IP_POOL_NONE-1)
-
-static ip_pool_t get_index_line(
- FILE *fp,
- char **namep,
- char **typep,
- char **argp
-) {
- char *p;
- ip_pool_t index;
- static char buf[256];
-
- if (namep) *namep = 0;
- if (typep) *typep = 0;
- if (argp) *argp = 0;
-
- if (!fgets(buf, sizeof(buf), fp)) return SCAN_EOF;
-
- p = strtok(buf, " \t\n");
- if (!p || *p == '#') return IP_POOL_NONE;
- index = atoi(p);
-
- p = strtok(0, " \t\n");
- if (!p || *p == '#') return index;
- if (namep) *namep = p;
-
- p = strtok(0, " \t\n");
- if (!p || *p == '#') return index;
- if (typep) *typep = p;
-
- p = strtok(0, "#\n");
- if (argp) *argp = p;
-
- return index;
-}
-
-static ip_pool_t get_index(char *name)
-{
- FILE *fp;
- char *poolname, *type, *arg, *p;
- ip_pool_t res;
-
- if (isdigit(*name))
- return atoi(name);
- fp = fopen(IPPOOL_CONF, "r");
- if (!fp) {
- fprintf(stderr, "cannot open %s - no pool names", IPPOOL_CONF);
- exit(1);
- }
- while (SCAN_EOF != (res=get_index_line(fp, &poolname, &type, &arg))) {
- if (poolname && 0 == strcmp(poolname, name)) {
- if (!type || (0 == strcmp(type, "bitmap"))) {
- conf_type = IP_POOL_T_BITMAP;
- p = strtok(arg, " \t");
- if (p) {
- conf_addr = inet_addr(p);
- p = strtok(0, " \t");
- if (p)
- conf_addr2 = inet_addr(p);
- else
- conf_addr = 0;
- }
- }
- break;
- }
- }
- fclose(fp);
- if (res == SCAN_EOF) {
- fprintf(stderr, "pool '%s' not found in %s\n",
- name, IPPOOL_CONF);
- exit(1);
- }
- return res;
-}
-
-static char *get_name(ip_pool_t index)
-{
- FILE *fp;
- static char sbuf[256];
- int ok = 0;
-
- fp = fopen(IPPOOL_CONF, "r");
- if (fp) {
- while (fgets(sbuf, sizeof(sbuf), fp)) {
- char *p = strtok(sbuf, " \t\n");
-
- if (!p || *p == '#') continue;
- if (index != atoi(p)) continue;
- p = strtok(0, " \t\n");
- if (!p || *p == '#') continue;
- memmove(sbuf, p, strlen(p)+1);
- ok = 1;
- break;
- }
- fclose(fp);
- }
- if (!ok) sprintf(sbuf, "%d", index);
- return sbuf;
-}
-
-/* user/kernel interaction */
-
-static int fd = -1;
-static int flag_n = 0; /* do not do anything; just brag about it */
-static int flag_v = 0; /* be verbose (list members) */
-static int flag_q = 0; /* be quiet */
-static int flag_u = 0; /* show usage counts in listings */
-static char *flag_t = "bitmap"; /* pool type */
-
-static ip_pool_t high_nr(void)
-{
- struct ip_pool_request req;
- int reqlen = sizeof(req);
-
- req.op = IP_POOL_HIGH_NR;
- if (0 > getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen)) {
- fprintf(stderr,
- "IP_POOL_HIGH_NR failed: %s\n",
- errno2msg(IP_POOL_HIGH_NR, errno));
- exit(1);
- }
- return req.index;
-}
-
-static void do_list(ip_pool_t pool)
-{
- struct ip_pool_request req;
- int reqlen = sizeof(req);
- u_int32_t first_ip;
- u_int32_t last_ip;
-
- req.op = IP_POOL_LOOKUP;
- req.index = pool;
- req.addr = req.addr2 = 0;
- reqlen = sizeof(req);
- if (0 == getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen)) {
- struct in_addr ina;
- ina.s_addr = req.addr;
- printf("%s %s", get_name(req.index), inet_ntoa(ina));
- ina.s_addr = req.addr2;
- printf(" %s", inet_ntoa(ina));
- first_ip = ntohl(req.addr);
- last_ip = ntohl(req.addr2);
- if (flag_u) {
- req.op = IP_POOL_USAGE;
- req.index = pool;
- reqlen = sizeof(req);
- if (0 == getsockopt(fd, SOL_IP, SO_IP_POOL,
- &req, &reqlen)) {
- printf(" %d %d", req.addr, req.addr2);
- } else {
- printf(" - -");
- }
- }
- printf("\n");
- if (flag_v) {
- while (first_ip <= last_ip) {
- req.op = IP_POOL_TEST_ADDR;
- req.index = pool;
- ina.s_addr = req.addr = htonl(first_ip);
- reqlen = sizeof(req);
- if (0 == getsockopt(fd, SOL_IP, SO_IP_POOL,
- &req, &reqlen)) {
- if (req.addr) printf("\t%s\n",
- inet_ntoa(ina));
- }
- first_ip++;
- }
- }
- }
-}
-
-static void do_list_all(void)
-{
- ip_pool_t i, highest = high_nr();
-
- for (i=0; i<=highest; i++)
- do_list(i);
-}
-
-static void do_flush(ip_pool_t pool)
-{
- struct ip_pool_request req;
- int reqlen = sizeof(req);
-
- req.op = IP_POOL_FLUSH;
- req.index = pool;
- if (flag_n) {
- printf("ippool -F %d\n", req.index);
- return;
- }
- if (0 > getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen)) {
- int err = errno;
- fprintf(stderr,
- "IP_POOL_FLUSH %s failed: %s\n",
- get_name(pool), errno2msg(IP_POOL_FLUSH, err));
- exit(1);
- }
-}
-
-static void do_flush_all(void)
-{
- ip_pool_t i, highest = high_nr();
-
- for (i=0; i<=highest; i++)
- do_flush(i);
-}
-
-static void do_destroy(ip_pool_t pool)
-{
- struct ip_pool_request req;
- int reqlen = sizeof(req);
-
- req.op = IP_POOL_DESTROY;
- req.index = pool;
- if (flag_n) {
- printf("ippool -X %d\n", req.index);
- return;
- }
- if (0 > getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen)) {
- int err = errno;
- fprintf(stderr,
- "IP_POOL_DESTROY %s failed: %s\n",
- get_name(pool), errno2msg(IP_POOL_DESTROY, err));
- exit(1);
- }
-}
-
-static void do_destroy_all(void)
-{
- ip_pool_t i, highest = high_nr();
-
- for (i=0; i<=highest; i++)
- do_destroy(i);
-}
-
-static int do_adddel(ip_pool_t pool, char *straddr, int op)
-{
- struct ip_pool_request req;
- int res;
- int reqlen = sizeof(req);
-
- req.op = op;
- req.index = pool;
- req.addr = inet_addr(straddr);
- req.addr2 = 0;
- if (flag_n) {
- printf("ippool -%c %s %s\n",
- (op == IP_POOL_ADD_ADDR) ? 'A' : 'D',
- get_name(req.index), straddr);
- return 0;
- }
- res = getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen);
- if (0 > res) {
- int err = errno;
- fprintf(stderr,
- "IP_POOL_ADD/DEL %s in %s failed: %s\n",
- straddr, get_name(pool), errno2msg(op, err));
- exit(1);
- }
- if (!flag_q)
- printf("%s %s %d %d\n", get_name(pool), straddr, req.addr,
- op == IP_POOL_ADD_ADDR ? 1 : 0);
- return req.addr;
-}
-
-static int do_check(ip_pool_t pool, char *straddr)
-{
- struct ip_pool_request req;
- int reqlen = sizeof(req);
-
- req.op = IP_POOL_TEST_ADDR;
- req.index = pool;
- req.addr = inet_addr(straddr);
- if (0 > getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen)) {
- int err = errno;
- fprintf(stderr,
- "IP_POOL_TEST_ADDR %s in %s failed: %s\n",
- straddr, get_name(pool),
- errno2msg(IP_POOL_TEST_ADDR, err));
- exit(1);
- }
- if (!flag_q)
- printf("%s %s %d\n", get_name(req.index), straddr, req.addr);
- return !req.addr;
-}
-
-static void do_new(ip_pool_t pool, int argc, char **argv)
-{
- struct ip_pool_request req;
- int reqlen = sizeof(req);
-
- req.op = IP_POOL_INIT;
- req.index = pool;
- if (argc >= 2) {
- conf_type = IP_POOL_T_BITMAP;
- conf_addr = inet_addr(argv[0]);
- conf_addr2 = inet_addr(argv[1]);
- }
- if (conf_type != IP_POOL_T_BITMAP || conf_addr == 0 || conf_addr2 == 0)
- usage("bad pool specification");
- req.addr = conf_addr;
- req.addr2 = conf_addr2;
- if (flag_n) {
- printf("ippool -N %s [-T %s] ...\n", get_name(pool),
- conf_type == IP_POOL_T_BITMAP
- ? "bitmap"
- : "???");
- return;
- }
- if (0 > getsockopt(fd, SOL_IP, SO_IP_POOL, &req, &reqlen)) {
- struct in_addr ina;
- int err = errno;
- ina.s_addr = conf_addr;
- fprintf(stderr,
- "IP_POOL_INIT %s [%s-",
- get_name(pool), inet_ntoa(ina));
- ina.s_addr = conf_addr2;
- fprintf(stderr,
- "%s] failed: %s\n",
- inet_ntoa(ina), errno2msg(IP_POOL_INIT, err));
- exit(1);
- }
-}
-
-static void do_new_all(void)
-{
- FILE *fp;
- char *poolname, *type, *arg, *p;
- int res;
-
- fp = fopen(IPPOOL_CONF, "r");
- if (!fp) {
- fprintf(stderr, "cannot open %s - no pool names", IPPOOL_CONF);
- exit(1);
- }
- while (SCAN_EOF != (res=get_index_line(fp, &poolname, &type, &arg))) {
- if (poolname && type && (0 == strcmp(type, "bitmap"))) {
- conf_type = IP_POOL_T_BITMAP;
- p = strtok(arg, " \t");
- if (p) {
- conf_addr = inet_addr(p);
- p = strtok(0, " \t");
- if (p)
- conf_addr2 = inet_addr(p);
- else
- conf_addr = 0;
- }
- if (conf_addr != 0) {
- if (flag_v)
- printf("ippool -N %s (%s) [%s]\n",
- poolname, type, arg);
- do_new(res, 0, 0);
- }
- }
- }
- fclose(fp);
-}
-
-int main(int argc, char **argv)
-{
- int opt;
- int op;
-#define OP_NONE 0
-#define OP_LIST 1
-#define OP_LIST_ALL 2
-#define OP_FLUSH 3
-#define OP_FLUSH_ALL 4
-#define OP_DESTROY 5
-#define OP_DESTROY_ALL 6
-#define OP_ADD 7
-#define OP_DEL 8
-#define OP_CHECK 9
-#define OP_NEW 10
-#define OP_NEW_ALL 11
-#define OP_HIGHEST 12
- char *op_pool;
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- fprintf(stderr, "cannot get DGRAM socket: %s\n",
- strerror(errno));
- exit(1);
- }
- op_pool = 0;
- op = OP_NONE;
- /* GRRR. I thought getopt() would allow an "L*" specifier, for an -L
- * taking an optional argument. Does not work. Bad.
- * Adding -l for -L without argument, also -f/-F and -x/-X.
- */
- while (EOF != (opt=getopt( argc, argv, "HhnvuqA:D:C:N:t:L:F:X:lfxB")))
- switch(opt) {
- case 'l':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_LIST_ALL;
- break;
- case 'L':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_LIST;
- op_pool = optarg;
- break;
- case 'f':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_FLUSH_ALL;
- break;
- case 'F':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_FLUSH;
- op_pool = optarg;
- break;
- case 'x':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_DESTROY_ALL;
- break;
- case 'X':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_DESTROY;
- op_pool = optarg;
- break;
- case 'A':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_ADD;
- op_pool = optarg;
- break;
- case 'D':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_DEL;
- op_pool = optarg;
- break;
- case 'C':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_CHECK;
- op_pool = optarg;
- break;
- case 'B':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_NEW_ALL;
- break;
- case 'N':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_NEW;
- op_pool = optarg;
- break;
- case 'H':
- if (op != OP_NONE) usage("conflicting operations");
- op = OP_HIGHEST;
- break;
- case 't':
- flag_t = optarg;
- break;
- case 'n':
- flag_n = 1;
- break;
- case 'v':
- flag_v = 1;
- break;
- case 'u':
- flag_u = 1;
- break;
- case 'q':
- flag_q = 1;
- break;
- case 'h':
- usage(0);
- default:
- usage("bad option");
- }
- if (op == OP_NONE)
- usage("no operation specified");
- if (op == OP_LIST_ALL) {
- do_list_all();
- return 0;
- }
- if (op == OP_LIST) {
- do_list(get_index(op_pool));
- return 0;
- }
- if (op == OP_FLUSH_ALL) {
- do_flush_all();
- return 0;
- }
- if (op == OP_FLUSH) {
- do_flush(get_index(op_pool));
- return 0;
- }
- if (op == OP_DESTROY_ALL) {
- do_destroy_all();
- return 0;
- }
- if (op == OP_DESTROY) {
- do_destroy(get_index(op_pool));
- return 0;
- }
- if (op == OP_CHECK) {
- if (optind >= argc)
- usage("missing address to check");
- return do_check(get_index(op_pool), argv[optind]);
- }
- if (op == OP_NEW_ALL) {
- do_new_all();
- return 0;
- }
- if (op == OP_NEW) {
- do_new(get_index(op_pool), argc-optind, argv+optind);
- return 0;
- }
- if (op == OP_ADD) {
- if (optind >= argc)
- usage("missing address to add");
- return do_adddel(get_index(op_pool),
- argv[optind], IP_POOL_ADD_ADDR);
- }
- if (op == OP_DEL) {
- if (optind >= argc)
- usage("missing address to delete");
- return do_adddel(get_index(op_pool),
- argv[optind], IP_POOL_DEL_ADDR);
- }
- if (op == OP_HIGHEST) {
- printf("%d\n", high_nr());
- return 0;
- }
- usage("no operation specified");
- return 0;
-}
+++ /dev/null
-/* support functions for ip_pool modules */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include <libippool/ip_pool_support.h>
-
-void ip_pool_init(void)
-{
-}
-
-ip_pool_t ip_pool_get_index(char *name)
-{
- FILE *fp;
- char buf[256];
-
- if (isdigit(*name))
- return atoi(name);
- fp = fopen(IPPOOL_CONF, "r");
- if (!fp) exit_error(PARAMETER_PROBLEM,
- "cannot open %s - no pool names", IPPOOL_CONF);
- while (fgets(buf, sizeof(buf), fp)) {
- char *p = strtok(buf, " \t\n");
- ip_pool_t index;
-
- if (!p || *p == '#') continue;
- index = atoi(p);
- p = strtok(0, " \t\n");
- if (p && 0 == strcmp(p, name)) {
- fclose(fp);
- return index;
- }
- }
- exit_error(PARAMETER_PROBLEM,
- "pool '%s' not found in %s\n", name, IPPOOL_CONF);
-}
-
-char *ip_pool_get_name(char *buf, int size, ip_pool_t index, int numeric)
-{
- FILE *fp;
- int ok = 0;
-
- /* make sure we have enough room, at least for a %d */
- if (size < 16)
- exit_error(PARAMETER_PROBLEM,
- "ip_pool_support:get_name buf too small (%d vs. 16)\n",
- size);
- if (numeric)
- goto do_numeric;
- fp = fopen(IPPOOL_CONF, "r");
- if (fp) {
- while (fgets(buf, size, fp)) {
- char *p = strtok(buf, " \t\n");
-
- if (!p || *p == '#') continue;
- if (index != atoi(p)) continue;
- p = strtok(0, " \t\n");
- if (!p || *p == '#') continue;
- memmove(buf, p, strlen(p)+1);
- ok = 1;
- break;
- }
- fclose(fp);
- }
- if (!ok) {
-do_numeric:
- sprintf(buf, "%d", index);
- }
- return buf;
-}
/* Print target name */
target_name = iptc_get_target(e, h);
if (target_name && (*target_name != '\0'))
+#ifdef IPT_F_GOTO
+ printf("-%c %s ", e->ip.flags & IPT_F_GOTO ? 'g' : 'j', target_name);
+#else
printf("-j %s ", target_name);
+#endif
/* Print targinfo part */
t = ipt_get_target((struct ipt_entry *)e);
.I DROP
means to drop the packet on the floor.
.I QUEUE
-means to pass the packet to userspace (if supported by the kernel).
+means to pass the packet to userspace. (How the packet can be received
+by a userspace process differs by the particular queue handler. 2.4.x
+and 2.6.x kernels up to 2.6.13 include the
+.B
+ip_queue
+queue handler. Kernels 2.6.14 and later additionally include the
+.B
+nfnetlink_queue
+queue handler. Packets with a target of QUEUE will be sent to queue number '0'
+in this case. Please also see the
+.B
+NFQUEUE
+target as described later in this man page.)
.I RETURN
means stop traversing this chain and resume at the next rule in the
previous (calling) chain. If the end of a built-in chain is reached
.TP
.BR "-X, --delete-chain " "[\fIchain\fP]"
Delete the optional user-defined chain specified. There must be no references
-to the chain. If there are, you must delete or replace the referring
-rules before the chain can be deleted. If no argument is given, it
-will attempt to delete every non-builtin chain in the table.
+to the chain. If there are, you must delete or replace the referring rules
+before the chain can be deleted. The chain must be empty, i.e. not contain
+any rules. If no argument is given, it will attempt to delete every
+non-builtin chain in the table.
.TP
.BI "-P, --policy " "chain target"
Set the policy for the chain to the given target. See the section
the fate of the packet immediately, or an extension (see
.B EXTENSIONS
below). If this
-option is omitted in a rule, then matching the rule will have no
+option is omitted in a rule (and
+.B -g
+is not used), then matching the rule will have no
effect on the packet's fate, but the counters on the rule will be
incremented.
.TP
+.BI "-g, --goto " "chain"
+This specifies that the processing should continue in a user
+specified chain. Unlike the --jump option return will not continue
+processing in this chain but instead in the chain that called us via
+--jump.
+.TP
.BR "-i, --in-interface " "[!] \fIname\fP"
Name of an interface via which a packet was received (only for
packets entering the
.BI "--dst-type " "type"
Matches if the destination address is of given type
.SS ah
-This module matches the SPIs in AH header of IPSec packets.
+This module matches the SPIs in Authentication header of IPsec packets.
.TP
.BR "--ahspi " "[!] \fIspi\fP[:\fIspi\fP]"
.SS childlevel
.SS condition
This matches if a specific /proc filename is '0' or '1'.
.TP
-.BI "--condition " "[!] filename"
+.BI "--condition " "[!] \fIfilename\fP"
Match on boolean value stored in /proc/net/ipt_condition/filename file
.SS connbytes
Match by how many bytes or packets a connection (or one of the two
.BI "--ctexpire " "\fItime\fP[\fI:time\fP]"
Match remaining lifetime in seconds against given value
or range of values (inclusive)
+.SS dccp
+.TP
+\fB--source-port\fR,\fB--sport \fR[\fB!\fR] \fIport\fR[\fB:\fIport\fR]
+.TP
+\fB--destination-port\fR,\fB--dport \fR[\fB!\fR] \fIport\fR[\fB:\fIport\fR]
+.TP
+\fB--dccp-types\fR [\fB!\fR] \fImask\fP
+Match when the DCCP packet type is one of 'mask'. 'mask' is a comma-separated
+list of packet types. Packet types are:
+.BR "REQUEST RESPONSE DATA ACK DATAACK CLOSEREQ CLOSE RESET SYNC SYNCACK INVALID" .
+.TP
+\fB--dccp-option\fR [\fB!\fR\] \fInumber\fP
+Match if DCP option set.
.SS dscp
This module matches the 6 bit DSCP field within the TOS field in the
IP header. DSCP has superseded TOS within the IETF.
destination IP or per destination port base. As opposed to the `limit' match,
every destination ip / destination port has it's own limit.
.TP
+THIS MODULE IS DEPRECATED AND HAS BEEN REPLACED BY ``hashlimit''
+.TP
.BI "--dstlimit " "avg"
Maximum average match rate (packets per second unless followed by /sec /minute /hour /day postfixes).
.TP
This matches a particular IPv4 ECT (ECN-Capable Transport). You have to specify
a number between `0' and `3'.
.SS esp
-This module matches the SPIs in ESP header of IPSec packets.
+This module matches the SPIs in ESP header of IPsec packets.
.TP
.BR "--espspi " "[!] \fIspi\fP[:\fIspi\fP]"
.SS fuzzy
This module matches a rate limit based on a fuzzy logic controller [FLC]
.TP
-.BI "--lower-limit "number"
+.BI "--lower-limit " "number"
Specifies the lower limit (in packets per second).
.TP
.BI "--upper-limit " "number"
This module matches the length of a packet against a specific value
or range of values.
.TP
-.BR "--length " "\fIlength\fP[:\fIlength\fP]"
+.BR "--length " "[!] \fIlength\fP[:\fIlength\fP]"
.SS limit
This module matches at a limited rate using a token bucket filter.
A rule using this extension will match until this limit is reached
target below).
.TP
.BR "--mark " "\fIvalue\fP[/\fImask\fP]"
-Matches packets with the given unsigned mark value (if a mask is
-specified, this is logically ANDed with the mask before the
+Matches packets with the given unsigned mark value (if a \fImask\fP is
+specified, this is logically ANDed with the \fImask\fP before the
comparison).
.SS mport
This module matches a set of source or destination ports. Up to 15
a transparent bridging IP firewall and is only useful for kernel versions
above version 2.5.44.
.TP
-.B --physdev-in name
+.BR --physdev-in " [!] \fIname\fP"
Name of a bridge port via which a packet is received (only for
packets entering the
.BR INPUT ,
interface which begins with this name will match. If the packet didn't arrive
through a bridge device, this packet won't match this option, unless '!' is used.
.TP
-.B --physdev-out name
+.BR --physdev-out " [!] \fIname\fP"
Name of a bridge port via which a packet is going to be sent (for packets
entering the
.BR FORWARD ,
the output device will be, then the packet won't match this option, unless
'!' is used.
.TP
-.B --physdev-is-in
+.RB "[!] " --physdev-is-in
Matches if the packet has entered through a bridge interface.
.TP
-.B --physdev-is-out
+.RB "[!] " --physdev-is-out
Matches if the packet will leave through a bridge interface.
.TP
-.B --physdev-is-bridged
+.RB "[!] " --physdev-is-bridged
Matches if the packet is being bridged and therefore is not being routed.
This is only useful in the FORWARD and POSTROUTING chains.
.SS pkttype
This module matches the link-layer packet type.
.TP
.BI "--pkt-type " "[\fIunicast\fP|\fIbroadcast\fP|\fImulticast\fP]"
+.SS policy
+This modules matches the policy used by IPsec for handling a packet.
+.TP
+.BI "--dir " "in|out"
+Used to select whether to match the policy used for decapsulation or the
+policy that will be used for encapsulation.
+.B in
+is valid in the
+.B PREROUTING, INPUT and FORWARD
+chains,
+.B out
+is valid in the
+.B POSTROUTING, OUTPUT and FORWARD
+chains.
+.TP
+.BI "--pol " "none|ipsec"
+Matches if the packet is subject to IPsec processing.
+.TP
+.BI "--strict"
+Selects whether to match the exact policy or match if any rule of
+the policy matches the given policy.
+.TP
+.BI "--reqid " "id"
+Matches the reqid of the policy rule. The reqid can be specified with
+.B setkey(8)
+using
+.B unique:id
+as level.
+.TP
+.BI "--spi " "spi"
+Matches the SPI of the SA.
+.TP
+.BI "--proto " "ah|esp|ipcomp"
+Matches the encapsulation protocol.
+.TP
+.BI "--mode " "tunnel|transport"
+Matches the encapsulation mode.
+.TP
+.BI "--tunnel-src " "addr[/mask]"
+Matches the source end-point address of a tunnel mode SA.
+Only valid with --mode tunnel.
+.TP
+.BI "--tunnel-dst " "addr[/mask]"
+Matches the destination end-point address of a tunnel mode SA.
+Only valid with --mode tunnel.
+.TP
+.BI "--next"
+Start the next element in the policy specification. Can only be used with
+--strict
.SS psd
Attempt to detect TCP and UDP port scans. This match was derived from
Solar Designer's scanlogd.
meaning that the packet is starting a new connection, but is
associated with an existing connection, such as an FTP data transfer,
or an ICMP error.
+.SS string
+This modules matches a given string by using some pattern matching strategy. It requires a linux kernel >= 2.6.14.
+.TP
+.BI "--algo " "bm|kmp"
+Select the pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris)
+.TP
+.BI "--from " "offset"
+Set the offset from which it starts looking for any matching. If not passed, default is 0.
+.TP
+.BI "--to " "offset"
+Set the offset from which it starts looking for any matching. If not passed, default is the packet size.
+.TP
+.BI "--string " "pattern"
+Matches the given pattern.
+.BI "--hex-string " "pattern"
+Matches the given pattern in hex notation.
.SS tcp
These extensions are loaded if `--protocol tcp' is specified. It
provides the following options:
modified.
.RS
.PP
-You can add several --to-destination options. If you specify more
-than one destination address, either via an address range or multiple
---to-destination options, a simple round-robin (one after another in
-cycle) load balancing takes place between these adresses.
+In Kernels up to 2.6.10 you can add several --to-destination options. For
+those kernels, if you specify more than one destination address, either via an
+address range or multiple --to-destination options, a simple round-robin (one
+after another in cycle) load balancing takes place between these addresses.
+Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+anymore.
+
.SS DSCP
This target allows to alter the value of the DSCP bits within the TOS
header of the IPv4 packet. As this manipulates a packet, it can only
Network address to map to. The resulting address will be constructed in the
following way: All 'one' bits in the mask are filled in from the new `address'.
All bits that are zero in the mask are filled in from the original address.
+.SS NFQUEUE
+This target is an extension of the QUEUE target. As opposed to QUEUE, it allows
+you to put a packet into any specific queue, identified by its 16-bit queue
+number.
+.TP
+.BR "--queue-num " "\fIvalue"
+This specifies the QUEUE number to use. Valud queue numbers are 0 to 65535. The default value is 0.
+.TP
+It can only be used with Kernel versions 2.6.14 or later, since it requires
+the
+.B
+nfnetlink_queue
+kernel support.
.SS NOTRACK
This target disables connection tracking for all packets matching that rule.
.TP
1024 or above. Where possible, no port alteration will occur.
.RS
.PP
-You can add several --to-source options. If you specify more
-than one source address, either via an address range or multiple
---to-source options, a simple round-robin (one after another in
-cycle) takes place between these adresses.
+In Kernels up to 2.6.10, you can add several --to-source options. For those
+kernels, if you specify more than one source address, either via an address
+range or multiple --to-source options, a simple round-robin (one after another
+in cycle) takes place between these addresses.
+Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges
+anymore.
.SS TARPIT
Captures and holds incoming TCP connections using no local
per-connection resources. Connections are accepted, but immediately
outgoing interface's MTU minus 40). Of course, it can only be used
in conjunction with
.BR "-p tcp" .
+It is only valid in the
+.BR mangle
+table.
.br
This target is used to overcome criminally braindead ISPs or servers
which block ICMP Fragmentation Needed packets. The symptoms of this
Workaround: activate this option and add a rule to your firewall
configuration like:
.nf
- iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \\
+ iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \\
-j TCPMSS --clamp-mss-to-pmtu
.fi
.TP
.BR iptables-restore (8),
.BR ip6tables (8),
.BR ip6tables-save (8),
-.BR ip6tables-restore (8).
+.BR ip6tables-restore (8),
+.BR libipq (3).
.P
The packet-filtering-HOWTO details iptables usage for
packet filtering, the NAT-HOWTO details NAT,
See
.BR "http://www.netfilter.org/" .
.SH AUTHORS
-Rusty Russell wrote iptables, in early consultation with Michael
+Rusty Russell originally wrote iptables, in early consultation with Michael
Neuling.
.PP
Marc Boucher made Rusty abandon ipnatctl by lobbying for a generic packet
.PP
Jozsef Kadlecsik wrote the REJECT target.
.PP
-Harald Welte wrote the ULOG target, TTL, DSCP, ECN matches and targets.
+Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, as well as the TTL, DSCP, ECN matches and targets.
.PP
The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik,
Patrick McHardy, James Morris, Harald Welte and Rusty Russell.
.PP
-Man page written by Herve Eychenne <rv@wallfire.org>.
+Man page originally written by Herve Eychenne <rv@wallfire.org>.
.\" .. and did I mention that we are incredibly cool people?
.\" .. sexy, too ..
.\" .. witty, charming, powerful ..
.I DROP
means to drop the packet on the floor.
.I QUEUE
-means to pass the packet to userspace (if supported by the kernel).
+means to pass the packet to userspace. (How the packet can be received
+by a userspace process differs by the particular queue handler. 2.4.x
+and 2.6.x kernels up to 2.6.13 include the
+.B
+ip_queue
+queue handler. Kernels 2.6.14 and later additionally include the
+.B
+nfnetlink_queue
+queue handler. Packets with a target of QUEUE will be sent to queue number '0'
+in this case. Please also see the
+.B
+NFQUEUE
+target as described later in this man page.)
.I RETURN
means stop traversing this chain and resume at the next rule in the
previous (calling) chain. If the end of a built-in chain is reached
.TP
.BR "-X, --delete-chain " "[\fIchain\fP]"
Delete the optional user-defined chain specified. There must be no references
-to the chain. If there are, you must delete or replace the referring
-rules before the chain can be deleted. If no argument is given, it
-will attempt to delete every non-builtin chain in the table.
+to the chain. If there are, you must delete or replace the referring rules
+before the chain can be deleted. The chain must be empty, i.e. not contain
+any rules. If no argument is given, it will attempt to delete every
+non-builtin chain in the table.
.TP
.BI "-P, --policy " "chain target"
Set the policy for the chain to the given target. See the section
the fate of the packet immediately, or an extension (see
.B EXTENSIONS
below). If this
-option is omitted in a rule, then matching the rule will have no
+option is omitted in a rule (and
+.B -g
+is not used), then matching the rule will have no
effect on the packet's fate, but the counters on the rule will be
incremented.
.TP
+.BI "-g, --goto " "chain"
+This specifies that the processing should continue in a user
+specified chain. Unlike the --jump option return will not continue
+processing in this chain but instead in the chain that called us via
+--jump.
+.TP
.BR "-i, --in-interface " "[!] \fIname\fP"
Name of an interface via which a packet was received (only for
packets entering the
.BR iptables-restore (8),
.BR ip6tables (8),
.BR ip6tables-save (8),
-.BR ip6tables-restore (8).
+.BR ip6tables-restore (8),
+.BR libipq (3).
.P
The packet-filtering-HOWTO details iptables usage for
packet filtering, the NAT-HOWTO details NAT,
See
.BR "http://www.netfilter.org/" .
.SH AUTHORS
-Rusty Russell wrote iptables, in early consultation with Michael
+Rusty Russell originally wrote iptables, in early consultation with Michael
Neuling.
.PP
Marc Boucher made Rusty abandon ipnatctl by lobbying for a generic packet
.PP
Jozsef Kadlecsik wrote the REJECT target.
.PP
-Harald Welte wrote the ULOG target, TTL, DSCP, ECN matches and targets.
+Harald Welte wrote the ULOG and NFQUEUE target, the new libiptc, as well as the TTL, DSCP, ECN matches and targets.
.PP
The Netfilter Core Team is: Marc Boucher, Martin Josefsson, Jozsef Kadlecsik,
Patrick McHardy, James Morris, Harald Welte and Rusty Russell.
.PP
-Man page written by Herve Eychenne <rv@wallfire.org>.
+Man page originally written by Herve Eychenne <rv@wallfire.org>.
.\" .. and did I mention that we are incredibly cool people?
.\" .. sexy, too ..
.\" .. witty, charming, powerful ..
#include <iptables.h>
#include <fcntl.h>
#include <sys/wait.h>
+#include <sys/utsname.h>
#ifndef TRUE
#define TRUE 1
{ "line-numbers", 0, 0, '0' },
{ "modprobe", 1, 0, 'M' },
{ "set-counters", 1, 0, 'c' },
+ { "goto", 1, 0, 'g' },
{ 0 }
};
const char *program_name;
char *lib_dir;
+int kernel_version;
+
/* Keeping track of external matches and targets: linked lists. */
struct iptables_match *iptables_matches = NULL;
struct iptables_target *iptables_targets = NULL;
" network interface name ([+] for wildcard)\n"
" --jump -j target\n"
" target for rule (may load target extension)\n"
+#ifdef IPT_F_GOTO
+" --goto -g chain\n"
+" jump to chain with no return\n"
+#endif
" --match -m match\n"
" extended match (may load extension)\n"
" --numeric -n numeric output of addresses and ports\n"
}
static void
-add_command(int *cmd, const int newcmd, const int othercmds, int invert)
+add_command(unsigned int *cmd, const int newcmd, const int othercmds,
+ int invert)
{
if (invert)
exit_error(PARAMETER_PROBLEM, "unexpected ! flag");
}
#ifndef NO_SHARED_LIBS
- if (!ptr && tryload != DONT_LOAD) {
+ if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) {
char path[strlen(lib_dir) + sizeof("/libipt_.so")
+ strlen(name)];
sprintf(path, "%s/libipt_%s.so", lib_dir, name);
}
#ifndef NO_SHARED_LIBS
- if (!ptr && tryload != DONT_LOAD) {
+ if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) {
char path[strlen(lib_dir) + sizeof("/libipt_.so")
+ strlen(name)];
sprintf(path, "%s/libipt_%s.so", lib_dir, name);
unsigned int num_old, num_new, i;
struct option *merge;
- /* Release previous options merged if any */
- free_opts(0);
-
for (num_old = 0; oldopts[num_old].name; num_old++);
for (num_new = 0; newopts[num_new].name; num_new++);
merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
memcpy(merge, oldopts, num_old * sizeof(struct option));
+ free_opts(0); /* Release previous options merged if any */
for (i = 0; i < num_new; i++) {
merge[num_old + i] = newopts[i];
merge[num_old + i].val += *option_offset;
exit(1);
}
- old = find_match(me->name, DONT_LOAD, NULL);
+ old = find_match(me->name, DURING_LOAD, NULL);
if (old) {
if (old->revision == me->revision) {
fprintf(stderr,
exit(1);
}
- old = find_target(me->name, DONT_LOAD);
+ old = find_target(me->name, DURING_LOAD);
if (old) {
struct iptables_target **i;
if (format & FMT_NOTABLE)
fputs(" ", stdout);
+#ifdef IPT_F_GOTO
+ if(fw->ip.flags & IPT_F_GOTO)
+ printf("[goto] ");
+#endif
+
IPT_MATCH_ITERATE(fw, print_match, &fw->ip, format & FMT_NUMERIC);
if (target) {
name[IPT_FUNCTION_MAXNAMELEN - 1] = revision;
}
+void
+get_kernel_version(void) {
+ static struct utsname uts;
+ int x = 0, y = 0, z = 0;
+
+ if (uname(&uts) == -1) {
+ fprintf(stderr, "Unable to retrieve kernel version.\n");
+ free_opts(1);
+ exit(1);
+ }
+
+ sscanf(uts.release, "%d.%d.%d", &x, &y, &z);
+ kernel_version = LINUX_VERSION(x, y, z);
+}
+
int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
{
struct ipt_entry fw, *e = NULL;
opterr = 0;
while ((c = getopt_long(argc, argv,
- "-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:",
+ "-A:D:R:I:L::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:",
opts, NULL)) != -1) {
switch (c) {
/*
dhostnetworkmask = argv[optind-1];
break;
+#ifdef IPT_F_GOTO
+ case 'g':
+ set_option(&options, OPT_JUMP, &fw.ip.invflags,
+ invert);
+ fw.ip.flags |= IPT_F_GOTO;
+ jumpto = parse_target(optarg);
+ break;
+#endif
+
case 'j':
set_option(&options, OPT_JUMP, &fw.ip.invflags,
invert);
target->t = fw_calloc(1, size);
target->t->u.target_size = size;
strcpy(target->t->u.user.name, jumpto);
- set_revision(target->t->u.user.name, target->revision);
+ if (!iptc_is_chain(jumpto, *handle))
+ set_revision(target->t->u.user.name,
+ target->revision);
if (target->init != NULL)
target->init(target->t, &fw.nfcache);
}
* We cannot know if the plugin is corrupt, non
* existant OR if the user just misspelled a
* chain. */
+#ifdef IPT_F_GOTO
+ if (fw.ip.flags & IPT_F_GOTO)
+ exit_error(PARAMETER_PROBLEM,
+ "goto '%s' is not a chain\n", jumpto);
+#endif
find_target(jumpto, LOAD_MUST_SUCCEED);
} else {
e = generate_entry(&fw, matches, target->t);
%define name iptables
-%define version 1.3.2
-%define release 20050720.1%{?pldistro:.%{pldistro}}%{?date:.%{date}}
+%define version 1.3.5
+%define release 1%{?pldistro:.%{pldistro}}%{?date:.%{date}}
Vendor: PlanetLab
Packager: PlanetLab Central <support@planet-lab.org>
unsigned char *buf, size_t len,
int timeout)
{
- int addrlen, status;
+ unsigned int addrlen;
+ int status;
struct nlmsghdr *nlh;
if (len < sizeof(struct nlmsgerr)) {
-/* Library which manipulates firewall rules. Version $Revision: 3756 $ */
+/* Library which manipulates firewall rules. Version $Revision: 1.1.1.3 $ */
/* Architecture of firewall rules is as follows:
*
/* sort only user defined chains */
if (!c->hooknum) {
list_for_each_entry(tmp, &h->chains, list) {
- if (strcmp(c->name, tmp->name) <= 0) {
+ if (!tmp->hooknum && strcmp(c->name, tmp->name) <= 0) {
list_add(&c->list, tmp->list.prev);
return;
}
/* calculate offset and number for every rule in the cache */
static int iptcc_compile_chain_offsets(TC_HANDLE_T h, struct chain_head *c,
- int *offset, int *num)
+ unsigned int *offset, unsigned int *num)
{
struct rule_head *r;
{
TC_HANDLE_T h;
STRUCT_GETINFO info;
- int tmp;
+ unsigned int tmp;
socklen_t s;
iptc_fn = TC_INIT;
new_number = iptcc_compile_table_prep(*handle, &new_size);
if (new_number < 0) {
errno = ENOMEM;
- return 0;
+ goto out_zero;
}
repl = malloc(sizeof(*repl) + new_size);
if (!repl) {
errno = ENOMEM;
- return 0;
+ goto out_zero;
}
memset(repl, 0, sizeof(*repl) + new_size);
repl->counters = malloc(sizeof(STRUCT_COUNTERS)
* (*handle)->info.num_entries);
if (!repl->counters) {
- free(repl);
errno = ENOMEM;
- return 0;
+ goto out_free_repl;
}
/* These are the counters we're going to put back, later. */
newcounters = malloc(counterlen);
if (!newcounters) {
- free(repl->counters);
- free(repl);
errno = ENOMEM;
- return 0;
+ goto out_free_repl_counters;
}
memset(newcounters, 0, counterlen);
ret = iptcc_compile_table(*handle, repl);
if (ret < 0) {
errno = ret;
- free(repl->counters);
- free(repl);
- return 0;
+ goto out_free_newcounters;
}
}
#endif
- if (setsockopt(sockfd, TC_IPPROTO, SO_SET_REPLACE, repl,
- sizeof(*repl) + repl->size) < 0) {
- free(repl->counters);
- free(repl);
- free(newcounters);
- return 0;
+ ret = setsockopt(sockfd, TC_IPPROTO, SO_SET_REPLACE, repl,
+ sizeof(*repl) + repl->size);
+ if (ret < 0) {
+ errno = ret;
+ goto out_free_newcounters;
}
/* Put counters back. */
}
#endif
- if (setsockopt(sockfd, TC_IPPROTO, SO_SET_ADD_COUNTERS,
- newcounters, counterlen) < 0) {
- free(repl->counters);
- free(repl);
- free(newcounters);
- return 0;
+ ret = setsockopt(sockfd, TC_IPPROTO, SO_SET_ADD_COUNTERS,
+ newcounters, counterlen);
+ if (ret < 0) {
+ errno = ret;
+ goto out_free_newcounters;
}
free(repl->counters);
free(repl);
free(newcounters);
- finished:
+finished:
TC_FREE(handle);
return 1;
+
+out_free_newcounters:
+ free(newcounters);
+out_free_repl_counters:
+ free(repl->counters);
+out_free_repl:
+ free(repl);
+out_zero:
+ return 0;
}
/* Get raw socket. */