summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2004-04-23 14:28:38 +0000
committerandre <andre@FreeBSD.org>2004-04-23 14:28:38 +0000
commitd4f49f008f33c4f8764a222f33a2c7469a2bed19 (patch)
tree409e5a1193422d7cff37e0eac1786413b8e0b686 /sys/netinet
parente8723e5528fcaf8fa35c8432a0f4aedfe76cb723 (diff)
downloadFreeBSD-src-d4f49f008f33c4f8764a222f33a2c7469a2bed19.zip
FreeBSD-src-d4f49f008f33c4f8764a222f33a2c7469a2bed19.tar.gz
Add the option versrcreach to verify that a valid route to the
source address of a packet exists in the routing table. The default route is ignored because it would match everything and render the check pointless. This option is very useful for routers with a complete view of the Internet (BGP) in the routing table to reject packets with spoofed or unrouteable source addresses. Example: ipfw add 1000 deny ip from any to any not versrcreach also known in Cisco-speak as: ip verify unicast source reachable-via any Reviewed by: luigi
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.h1
-rw-r--r--sys/netinet/ip_fw2.c38
2 files changed, 32 insertions, 7 deletions
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 8e3047d..7258b6c 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -95,6 +95,7 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
O_TCPOPTS, /* arg1 = 2*u8 bitmap */
O_VERREVPATH, /* none */
+ O_VERSRCREACH, /* none */
O_PROBE_STATE, /* none */
O_KEEP_STATE, /* none */
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 7097b20..e440f01 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -439,21 +439,27 @@ iface_match(struct ifnet *ifp, ipfw_insn_if *cmd)
}
/*
+ * The verify_path function checks if a route to the src exists and
+ * if it is reachable via ifp (when provided).
+ *
* The 'verrevpath' option checks that the interface that an IP packet
* arrives on is the same interface that traffic destined for the
- * packet's source address would be routed out of. This is a measure
- * to block forged packets. This is also commonly known as "anti-spoofing"
- * or Unicast Reverse Path Forwarding (Unicast RFP) in Cisco-ese. The
- * name of the knob is purposely reminisent of the Cisco IOS command,
+ * packet's source address would be routed out of. The 'versrcreach'
+ * option just checks that the source address is reachable via any route
+ * (except default) in the routing table. These two are a measure to block
+ * forged packets. This is also commonly known as "anti-spoofing" or Unicast
+ * Reverse Path Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
+ * is purposely reminiscent of the Cisco IOS command,
*
* ip verify unicast reverse-path
+ * ip verify unicast source reachable-via any
*
* which implements the same functionality. But note that syntax is
* misleading. The check may be performed on all IP packets whether unicast,
* multicast, or broadcast.
*/
static int
-verify_rev_path(struct in_addr src, struct ifnet *ifp)
+verify_path(struct in_addr src, struct ifnet *ifp)
{
struct route ro;
struct sockaddr_in *dst;
@@ -468,10 +474,21 @@ verify_rev_path(struct in_addr src, struct ifnet *ifp)
if (ro.ro_rt == NULL)
return 0;
- if ((ifp == NULL) || (ro.ro_rt->rt_ifp->if_index != ifp->if_index)) {
+
+ /* if ifp is provided, check for equality with rtentry */
+ if (ifp != NULL && ro.ro_rt->rt_ifp != ifp) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* if no ifp provided, check if rtentry is not default route */
+ if (ifp == NULL &&
+ satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
RTFREE(ro.ro_rt);
return 0;
}
+
+ /* found valid route */
RTFREE(ro.ro_rt);
return 1;
}
@@ -1911,7 +1928,13 @@ check_body:
/* Outgoing packets automatically pass/match */
match = ((oif != NULL) ||
(m->m_pkthdr.rcvif == NULL) ||
- verify_rev_path(src_ip, m->m_pkthdr.rcvif));
+ verify_path(src_ip, m->m_pkthdr.rcvif));
+ break;
+
+ case O_VERSRCREACH:
+ /* Outgoing packets automatically pass/match */
+ match = ((oif != NULL) ||
+ verify_path(src_ip, NULL));
break;
case O_IPSEC:
@@ -2546,6 +2569,7 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_TCPOPTS:
case O_ESTAB:
case O_VERREVPATH:
+ case O_VERSRCREACH:
case O_IPSEC:
if (cmdlen != F_INSN_SIZE(ipfw_insn))
goto bad_size;
OpenPOWER on IntegriCloud