net/netfilter: Add filter table in iptables.
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
f7181676b7
commit
9637c10696
@ -58,6 +58,10 @@
|
|||||||
#define IPT_INV_PROTO XT_INV_PROTO
|
#define IPT_INV_PROTO XT_INV_PROTO
|
||||||
#define IPT_INV_MASK 0x7F /* All possible flag bits mask. */
|
#define IPT_INV_MASK 0x7F /* All possible flag bits mask. */
|
||||||
|
|
||||||
|
/* Values for "inv" field for struct ipt_icmp. */
|
||||||
|
|
||||||
|
#define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */
|
||||||
|
|
||||||
/* Standard return verdict, or do jump. */
|
/* Standard return verdict, or do jump. */
|
||||||
|
|
||||||
#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
|
#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
|
||||||
@ -78,8 +82,10 @@
|
|||||||
(entry) = (FAR struct ipt_entry *) \
|
(entry) = (FAR struct ipt_entry *) \
|
||||||
((FAR uint8_t *)(entry) + (entry)->next_offset))
|
((FAR uint8_t *)(entry) + (entry)->next_offset))
|
||||||
|
|
||||||
/* Get pointer to target from an entry pointer. */
|
/* Get pointer to match / target from an entry pointer. */
|
||||||
|
|
||||||
|
#define IPT_MATCH(e) \
|
||||||
|
((FAR struct xt_entry_match *)((FAR struct ipt_entry *)(e) + 1))
|
||||||
#define IPT_TARGET(e) \
|
#define IPT_TARGET(e) \
|
||||||
((FAR struct xt_entry_target *)((FAR uint8_t *)(e) + (e)->target_offset))
|
((FAR struct xt_entry_target *)((FAR uint8_t *)(e) + (e)->target_offset))
|
||||||
|
|
||||||
@ -88,9 +94,10 @@
|
|||||||
#define IPT_FILL_ENTRY(e, target_name) \
|
#define IPT_FILL_ENTRY(e, target_name) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
(e)->entry.target_offset = sizeof((e)->entry); \
|
(e)->entry.target_offset = offsetof(typeof(*(e)), target); \
|
||||||
(e)->entry.next_offset = sizeof(*(e)); \
|
(e)->entry.next_offset = sizeof(*(e)); \
|
||||||
(e)->target.target.u.target_size = sizeof(*(e)) - sizeof((e)->entry); \
|
(e)->target.target.u.target_size = sizeof(*(e)) - \
|
||||||
|
(e)->entry.target_offset; \
|
||||||
strlcpy((e)->target.target.u.user.name, (target_name), \
|
strlcpy((e)->target.target.u.user.name, (target_name), \
|
||||||
sizeof((e)->target.target.u.user.name)); \
|
sizeof((e)->target.target.u.user.name)); \
|
||||||
} \
|
} \
|
||||||
@ -269,6 +276,15 @@ struct ipt_get_entries
|
|||||||
struct ipt_entry entrytable[0];
|
struct ipt_entry entrytable[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ICMP matching stuff */
|
||||||
|
|
||||||
|
struct ipt_icmp
|
||||||
|
{
|
||||||
|
uint8_t type; /* type to match */
|
||||||
|
uint8_t code[2]; /* range of code */
|
||||||
|
uint8_t invflags; /* Inverse flags */
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Inline functions
|
* Inline functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -39,9 +39,36 @@
|
|||||||
|
|
||||||
#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
|
#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
|
||||||
|
|
||||||
|
/* Values for "inv" field in struct xt_tcp. */
|
||||||
|
|
||||||
|
#define XT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */
|
||||||
|
#define XT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */
|
||||||
|
#define XT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */
|
||||||
|
#define XT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */
|
||||||
|
#define XT_TCP_INV_MASK 0x0F /* All possible flags. */
|
||||||
|
|
||||||
|
/* Values for "invflags" field in struct xt_udp. */
|
||||||
|
|
||||||
|
#define XT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */
|
||||||
|
#define XT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */
|
||||||
|
#define XT_UDP_INV_MASK 0x03 /* All possible flags. */
|
||||||
|
|
||||||
|
/* Target names */
|
||||||
|
|
||||||
#define XT_STANDARD_TARGET "" /* Standard return verdict, or do jump. */
|
#define XT_STANDARD_TARGET "" /* Standard return verdict, or do jump. */
|
||||||
#define XT_ERROR_TARGET "ERROR"
|
#define XT_ERROR_TARGET "ERROR"
|
||||||
#define XT_MASQUERADE_TARGET "MASQUERADE"
|
#define XT_MASQUERADE_TARGET "MASQUERADE"
|
||||||
|
#define XT_REJECT_TARGET "REJECT"
|
||||||
|
|
||||||
|
/* Match name to simplify our code */
|
||||||
|
|
||||||
|
#define XT_MATCH_NAME_TCP "tcp"
|
||||||
|
#define XT_MATCH_NAME_UDP "udp"
|
||||||
|
#define XT_MATCH_NAME_ICMP "icmp"
|
||||||
|
|
||||||
|
/* Table name to simplify our code */
|
||||||
|
|
||||||
|
#define XT_TABLE_NAME_FILTER "filter"
|
||||||
|
|
||||||
/* For standard target */
|
/* For standard target */
|
||||||
|
|
||||||
@ -156,4 +183,25 @@ struct xt_entry_match
|
|||||||
unsigned char data[1];
|
unsigned char data[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TCP matching stuff */
|
||||||
|
|
||||||
|
struct xt_tcp
|
||||||
|
{
|
||||||
|
uint16_t spts[2]; /* Source port range. */
|
||||||
|
uint16_t dpts[2]; /* Destination port range. */
|
||||||
|
uint8_t option; /* TCP Option iff non-zero */
|
||||||
|
uint8_t flg_mask; /* TCP flags mask byte */
|
||||||
|
uint8_t flg_cmp; /* TCP flags compare byte */
|
||||||
|
uint8_t invflags; /* Inverse flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* UDP matching stuff */
|
||||||
|
|
||||||
|
struct xt_udp
|
||||||
|
{
|
||||||
|
uint16_t spts[2]; /* Source port range. */
|
||||||
|
uint16_t dpts[2]; /* Destination port range. */
|
||||||
|
uint8_t invflags; /* Inverse flags */
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_NET_NETFILTER_X_TABLES_H */
|
#endif /* __INCLUDE_NUTTX_NET_NETFILTER_X_TABLES_H */
|
||||||
|
@ -28,5 +28,9 @@ if(CONFIG_NET_IPTABLES)
|
|||||||
list(APPEND SRCS ipt_nat.c)
|
list(APPEND SRCS ipt_nat.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_NET_IPFILTER)
|
||||||
|
list(APPEND SRCS ipt_filter.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_sources(net PRIVATE ${SRCS})
|
target_sources(net PRIVATE ${SRCS})
|
||||||
endif()
|
endif()
|
||||||
|
@ -8,6 +8,6 @@ config NET_IPTABLES
|
|||||||
default y
|
default y
|
||||||
depends on NET_IPv4
|
depends on NET_IPv4
|
||||||
depends on NET_SOCKOPTS
|
depends on NET_SOCKOPTS
|
||||||
depends on NET_NAT # May change dependency if we have firewall later.
|
depends on NET_NAT || NET_IPFILTER
|
||||||
---help---
|
---help---
|
||||||
Enable or disable iptables compatible interface (for NAT).
|
Enable or disable iptables compatible interface (for NAT).
|
||||||
|
@ -28,6 +28,10 @@ ifeq ($(CONFIG_NET_NAT),y)
|
|||||||
NET_CSRCS += ipt_nat.c
|
NET_CSRCS += ipt_nat.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_NET_IPFILTER),y)
|
||||||
|
NET_CSRCS += ipt_filter.c
|
||||||
|
endif
|
||||||
|
|
||||||
# Include Netfilter build support
|
# Include Netfilter build support
|
||||||
|
|
||||||
DEPPATH += --dep-path netfilter
|
DEPPATH += --dep-path netfilter
|
||||||
|
408
net/netfilter/ipt_filter.c
Normal file
408
net/netfilter/ipt_filter.c
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* net/netfilter/ipt_filter.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/net/netfilter/ip_tables.h>
|
||||||
|
#include <nuttx/net/netfilter/x_tables.h>
|
||||||
|
|
||||||
|
#include "ipfilter/ipfilter.h"
|
||||||
|
#include "netdev/netdev.h"
|
||||||
|
#include "netfilter/iptables.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
|
||||||
|
(1 << NF_INET_FORWARD) | \
|
||||||
|
(1 << NF_INET_LOCAL_OUT))
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: convert_chain
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Convert iptables chain to ipfilter chain.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static enum ipfilter_chain_e convert_chain(enum nf_inet_hooks hook)
|
||||||
|
{
|
||||||
|
switch (hook)
|
||||||
|
{
|
||||||
|
case NF_INET_LOCAL_IN:
|
||||||
|
return IPFILTER_CHAIN_INPUT;
|
||||||
|
|
||||||
|
case NF_INET_FORWARD:
|
||||||
|
return IPFILTER_CHAIN_FORWARD;
|
||||||
|
|
||||||
|
case NF_INET_LOCAL_OUT:
|
||||||
|
default:
|
||||||
|
return IPFILTER_CHAIN_OUTPUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: convert_invflags
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Convert iptables invflags to ipfilter invflags.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* entry - The ipfilter entry to be filled.
|
||||||
|
* invflags - The iptables invflags to be converted.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void convert_invflags(FAR struct ipfilter_entry_s *entry,
|
||||||
|
uint8_t invflags)
|
||||||
|
{
|
||||||
|
entry->inv_indev = !!(invflags & IPT_INV_VIA_IN);
|
||||||
|
entry->inv_outdev = !!(invflags & IPT_INV_VIA_OUT);
|
||||||
|
entry->inv_proto = !!(invflags & IPT_INV_PROTO);
|
||||||
|
entry->inv_srcip = !!(invflags & IPT_INV_SRCIP);
|
||||||
|
entry->inv_dstip = !!(invflags & IPT_INV_DSTIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: convert_tcpudp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Convert iptables tcp/udp match to ipfilter entry.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* entry - The ipfilter entry to be filled.
|
||||||
|
* spts - The source ports to be converted.
|
||||||
|
* dpts - The destination ports to be converted.
|
||||||
|
* invflags - The iptables tcp/udp invflags to be converted.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void convert_tcpudp(FAR struct ipfilter_entry_s *entry,
|
||||||
|
uint16_t spts[2], uint16_t dpts[2],
|
||||||
|
uint8_t invflags)
|
||||||
|
{
|
||||||
|
entry->match.tcpudp.sports[0] = spts[0];
|
||||||
|
entry->match.tcpudp.sports[1] = spts[1];
|
||||||
|
entry->match.tcpudp.dports[0] = dpts[0];
|
||||||
|
entry->match.tcpudp.dports[1] = dpts[1];
|
||||||
|
|
||||||
|
entry->inv_sport = !!(invflags & XT_TCP_INV_SRCPT);
|
||||||
|
entry->inv_dport = !!(invflags & XT_TCP_INV_DSTPT);
|
||||||
|
|
||||||
|
entry->match_tcpudp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: convert_icmp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Convert iptables icmp match to ipfilter entry.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* entry - The ipfilter entry to be filled.
|
||||||
|
* type - The icmp type to be converted.
|
||||||
|
* invflags - The iptables icmp invflags to be converted.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void convert_icmp(FAR struct ipfilter_entry_s *entry, uint8_t type,
|
||||||
|
uint8_t invflags)
|
||||||
|
{
|
||||||
|
entry->match.icmp.type = type;
|
||||||
|
entry->inv_icmp = !!(invflags & IPT_ICMP_INV);
|
||||||
|
entry->match_icmp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: convert_target
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Convert iptables target to ipfilter target.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* target - The iptables target to be converted.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The converted ipfilter target.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint8_t convert_target(FAR const struct xt_entry_target *target)
|
||||||
|
{
|
||||||
|
if (strcmp(target->u.user.name, XT_REJECT_TARGET) == 0)
|
||||||
|
{
|
||||||
|
return IPFILTER_TARGET_REJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(target->u.user.name, XT_STANDARD_TARGET) == 0)
|
||||||
|
{
|
||||||
|
int verdict = ((FAR const struct xt_standard_target *)target)->verdict;
|
||||||
|
verdict = -verdict - 1;
|
||||||
|
|
||||||
|
if (verdict == NF_ACCEPT)
|
||||||
|
{
|
||||||
|
return IPFILTER_TARGET_ACCEPT;
|
||||||
|
}
|
||||||
|
else if (verdict == NF_DROP)
|
||||||
|
{
|
||||||
|
return IPFILTER_TARGET_DROP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nwarn("WARNING: Unsupported target %s\n", target->u.user.name);
|
||||||
|
return IPFILTER_TARGET_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: convert_entry
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Convert iptables entry to ipfilter entry.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* entry - The iptables entry to be converted.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* The converted ipfilter entry.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct ipv4_filter_entry_s *
|
||||||
|
convert_entry(FAR const struct ipt_entry *entry)
|
||||||
|
{
|
||||||
|
FAR const struct xt_entry_match *match;
|
||||||
|
FAR const struct xt_entry_target *target;
|
||||||
|
FAR struct ipv4_filter_entry_s *filter =
|
||||||
|
(FAR struct ipv4_filter_entry_s *)ipfilter_cfg_alloc(PF_INET);
|
||||||
|
if (filter == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
match = IPT_MATCH(entry);
|
||||||
|
target = IPT_TARGET(entry);
|
||||||
|
|
||||||
|
/* Convert common fields */
|
||||||
|
|
||||||
|
filter->sip = entry->ip.src.s_addr;
|
||||||
|
filter->dip = entry->ip.dst.s_addr;
|
||||||
|
filter->smsk = entry->ip.smsk.s_addr;
|
||||||
|
filter->dmsk = entry->ip.dmsk.s_addr;
|
||||||
|
|
||||||
|
filter->common.indev = netdev_findbyname(entry->ip.iniface);
|
||||||
|
filter->common.outdev = netdev_findbyname(entry->ip.outiface);
|
||||||
|
filter->common.proto = entry->ip.proto;
|
||||||
|
filter->common.target = convert_target(target);
|
||||||
|
|
||||||
|
convert_invflags(&filter->common, entry->ip.invflags);
|
||||||
|
|
||||||
|
/* Convert match fields */
|
||||||
|
|
||||||
|
if (entry->target_offset < sizeof(struct xt_entry_match))
|
||||||
|
{
|
||||||
|
ninfo("No match inside entry, skip match conversion.\n");
|
||||||
|
goto skip_match;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (entry->ip.proto)
|
||||||
|
{
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
if (strcmp(match->u.user.name, XT_MATCH_NAME_TCP) == 0)
|
||||||
|
{
|
||||||
|
FAR struct xt_tcp *tcp = (FAR struct xt_tcp *)(match + 1);
|
||||||
|
convert_tcpudp(&filter->common, tcp->spts, tcp->dpts,
|
||||||
|
tcp->invflags);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
if (strcmp(match->u.user.name, XT_MATCH_NAME_TCP) == 0)
|
||||||
|
{
|
||||||
|
FAR struct xt_udp *udp = (FAR struct xt_udp *)(match + 1);
|
||||||
|
convert_tcpudp(&filter->common, udp->spts, udp->dpts,
|
||||||
|
udp->invflags);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_ICMP:
|
||||||
|
if (strcmp(match->u.user.name, XT_MATCH_NAME_ICMP) == 0)
|
||||||
|
{
|
||||||
|
FAR struct ipt_icmp *icmp = (FAR struct ipt_icmp *)(match + 1);
|
||||||
|
convert_icmp(&filter->common, icmp->type, icmp->invflags);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_match:
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: adjust_filter
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Adjust filter config according to the iptables config.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* repl - The config got from user space to control filter table.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void adjust_filter(FAR const struct ipt_replace *repl)
|
||||||
|
{
|
||||||
|
FAR const struct ipt_entry *entry;
|
||||||
|
FAR const uint8_t *head;
|
||||||
|
enum ipfilter_chain_e chain;
|
||||||
|
enum nf_inet_hooks hook;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
for (hook = NF_INET_LOCAL_IN; hook <= NF_INET_LOCAL_OUT; hook++)
|
||||||
|
{
|
||||||
|
/* Clear all filter config first. */
|
||||||
|
|
||||||
|
chain = convert_chain(hook);
|
||||||
|
ipfilter_cfg_clear(PF_INET, chain);
|
||||||
|
|
||||||
|
/* Set filter config according to iptables config. */
|
||||||
|
|
||||||
|
head = (FAR const uint8_t *)repl->entries + repl->hook_entry[hook];
|
||||||
|
size = repl->underflow[hook] - repl->hook_entry[hook];
|
||||||
|
|
||||||
|
/* We need the underflow entry as the default of the chain. */
|
||||||
|
|
||||||
|
size++;
|
||||||
|
|
||||||
|
ipt_entry_for_every(entry, head, size)
|
||||||
|
{
|
||||||
|
FAR struct ipv4_filter_entry_s *filter = convert_entry(entry);
|
||||||
|
if (filter != NULL)
|
||||||
|
{
|
||||||
|
ipfilter_cfg_add(&filter->common, PF_INET, chain);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Failed to convert entry!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ipt_filter_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Init filter table data.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct ipt_replace *ipt_filter_init(void)
|
||||||
|
{
|
||||||
|
return ipt_alloc_table(XT_TABLE_NAME_FILTER, FILTER_VALID_HOOKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ipt_filter_apply
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Try to apply filter rules, will do nothing if failed.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* repl - The config got from user space to control filter table.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int ipt_filter_apply(FAR const struct ipt_replace *repl)
|
||||||
|
{
|
||||||
|
FAR const struct ipt_entry *entry;
|
||||||
|
FAR const struct xt_entry_match *match;
|
||||||
|
FAR const struct xt_entry_target *target;
|
||||||
|
|
||||||
|
/* Check config first. */
|
||||||
|
|
||||||
|
ipt_entry_for_every(entry, repl->entries, repl->size)
|
||||||
|
{
|
||||||
|
match = IPT_MATCH(entry);
|
||||||
|
target = IPT_TARGET(entry);
|
||||||
|
|
||||||
|
/* Check match type matches the protocol */
|
||||||
|
|
||||||
|
if (entry->target_offset >= sizeof(struct xt_entry_match))
|
||||||
|
{
|
||||||
|
if (strcmp(match->u.user.name, XT_MATCH_NAME_TCP) == 0 &&
|
||||||
|
entry->ip.proto != IPPROTO_TCP)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: TCP match for non-TCP protocol\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(match->u.user.name, XT_MATCH_NAME_UDP) == 0 &&
|
||||||
|
entry->ip.proto != IPPROTO_UDP)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: UDP match for non-UDP protocol\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(match->u.user.name, XT_MATCH_NAME_ICMP) == 0 &&
|
||||||
|
entry->ip.proto != IPPROTO_ICMP)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: ICMP match for non-ICMP protocol\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check target type */
|
||||||
|
|
||||||
|
if (strcmp(target->u.user.name, XT_REJECT_TARGET) != 0 &&
|
||||||
|
strcmp(target->u.user.name, XT_STANDARD_TARGET) != 0 &&
|
||||||
|
strcmp(target->u.user.name, XT_ERROR_TARGET) != 0)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Unsupported target %s\n", target->u.user.name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set config table into ip filter. */
|
||||||
|
|
||||||
|
adjust_filter(repl);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
@ -81,6 +81,9 @@ static struct ipt_table_s g_tables[] =
|
|||||||
#ifdef CONFIG_NET_NAT
|
#ifdef CONFIG_NET_NAT
|
||||||
{NULL, ipt_nat_init, ipt_nat_apply},
|
{NULL, ipt_nat_init, ipt_nat_apply},
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_NET_IPFILTER
|
||||||
|
{NULL, ipt_filter_init, ipt_filter_apply},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -105,5 +105,32 @@ FAR struct ipt_replace *ipt_nat_init(void);
|
|||||||
int ipt_nat_apply(FAR const struct ipt_replace *repl);
|
int ipt_nat_apply(FAR const struct ipt_replace *repl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ipt_filter_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Init filter table data.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPFILTER
|
||||||
|
FAR struct ipt_replace *ipt_filter_init(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ipt_filter_apply
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Try to apply filter rules, will do nothing if failed.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* repl - The config got from user space to control filter table.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPFILTER
|
||||||
|
int ipt_filter_apply(FAR const struct ipt_replace *repl);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_NET_IPTABLES */
|
#endif /* CONFIG_NET_IPTABLES */
|
||||||
#endif /* __NET_NETFILTER_IPTABLES_H */
|
#endif /* __NET_NETFILTER_IPTABLES_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user