summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
authoryar <yar@FreeBSD.org>2001-12-29 09:24:18 +0000
committeryar <yar@FreeBSD.org>2001-12-29 09:24:18 +0000
commit11da1a2ed8b463e093c680c35028445124122f0c (patch)
tree3ef9bbfd815517e4c0297f1ea6c59d5190effd51 /sys/netinet/ip_input.c
parent734a071e5d7f49ac2440eb740f5df6c459da6796 (diff)
downloadFreeBSD-src-11da1a2ed8b463e093c680c35028445124122f0c.zip
FreeBSD-src-11da1a2ed8b463e093c680c35028445124122f0c.tar.gz
Don't reveal a router in the IPSTEALTH mode through IP options.
The following steps are involved: a) the IP options related to routing (LSRR and SSRR) are processed as though the router were a host, b) the other IP options are processed as usual only if the packet is destined for the router; otherwise they are ignored. PR: kern/23123 Discussed in: freebsd-hackers
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 91ed845..c75cd1b 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -211,7 +211,7 @@ static struct ip_srcrt {
struct sockaddr_in *ip_fw_fwd_addr;
static void save_rte __P((u_char *, struct in_addr));
-static int ip_dooptions __P((struct mbuf *));
+static int ip_dooptions __P((struct mbuf *, int));
static void ip_forward __P((struct mbuf *, int));
static void ip_freef __P((struct ipqhead *, struct ipq *));
#ifdef IPDIVERT
@@ -500,7 +500,7 @@ pass:
* to be sent and the original packet to be freed).
*/
ip_nhops = 0; /* for source routed packets */
- if (hlen > sizeof (struct ip) && ip_dooptions(m)) {
+ if (hlen > sizeof (struct ip) && ip_dooptions(m, 0)) {
#ifdef IPFIREWALL_FORWARD
ip_fw_fwd_addr = NULL;
#endif
@@ -658,6 +658,19 @@ pass:
return;
ours:
+#ifdef IPSTEALTH
+ /*
+ * IPSTEALTH: Process non-routing options only
+ * if the packet is destined for us.
+ */
+ if (ipstealth && hlen > sizeof (struct ip) && ip_dooptions(m, 1)) {
+#ifdef IPFIREWALL_FORWARD
+ ip_fw_fwd_addr = NULL;
+#endif
+ return;
+ }
+#endif /* IPSTEALTH */
+
/* Count the packet in the ip address stats */
if (ia != NULL) {
ia->ia_ifa.if_ipackets++;
@@ -1151,12 +1164,18 @@ ip_drain()
* Do option processing on a datagram,
* possibly discarding it if bad options are encountered,
* or forwarding it if source-routed.
+ * The pass argument is used when operating in the IPSTEALTH
+ * mode to tell what options to process:
+ * [LS]SRR (pass 0) or the others (pass 1).
+ * The reason for as many as two passes is that when doing IPSTEALTH,
+ * non-routing options should be processed only if the packet is for us.
* Returns 1 if packet has been forwarded/freed,
* 0 if the packet should be processed further.
*/
static int
-ip_dooptions(m)
+ip_dooptions(m, pass)
struct mbuf *m;
+ int pass;
{
register struct ip *ip = mtod(m, struct ip *);
register u_char *cp;
@@ -1201,6 +1220,10 @@ ip_dooptions(m)
*/
case IPOPT_LSRR:
case IPOPT_SSRR:
+#ifdef IPSTEALTH
+ if (ipstealth && pass > 0)
+ break;
+#endif
if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
code = &cp[IPOPT_OLEN] - (u_char *)ip;
goto bad;
@@ -1236,7 +1259,10 @@ ip_dooptions(m)
save_rte(cp, ip->ip_src);
break;
}
-
+#ifdef IPSTEALTH
+ if (ipstealth)
+ goto dropit;
+#endif
if (!ip_dosourceroute) {
if (ipforwarding) {
char buf[16]; /* aaa.bbb.ccc.ddd\0 */
@@ -1255,6 +1281,9 @@ nosourcerouting:
/*
* Not acting as a router, so silently drop.
*/
+#ifdef IPSTEALTH
+dropit:
+#endif
ipstat.ips_cantforward++;
m_freem(m);
return (1);
@@ -1290,6 +1319,10 @@ nosourcerouting:
break;
case IPOPT_RR:
+#ifdef IPSTEALTH
+ if (ipstealth && pass == 0)
+ break;
+#endif
if (optlen < IPOPT_OFFSET + sizeof(*cp)) {
code = &cp[IPOPT_OFFSET] - (u_char *)ip;
goto bad;
@@ -1323,6 +1356,10 @@ nosourcerouting:
break;
case IPOPT_TS:
+#ifdef IPSTEALTH
+ if (ipstealth && pass == 0)
+ break;
+#endif
code = cp - (u_char *)ip;
if (optlen < 4 || optlen > 40) {
code = &cp[IPOPT_OLEN] - (u_char *)ip;
OpenPOWER on IntegriCloud