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
This commit is contained in:
Yaroslav Tykhiy 2001-12-29 09:24:18 +00:00
parent 18f2fb66c6
commit d0ebc0d2f1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=88665

View File

@ -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 @@ ip_input(struct mbuf *m)
* 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 @@ ip_input(struct mbuf *m)
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 @@ ip_dooptions(m)
/*
* Not acting as a router, so silently drop.
*/
#ifdef IPSTEALTH
dropit:
#endif
ipstat.ips_cantforward++;
m_freem(m);
return (1);
@ -1290,6 +1319,10 @@ ip_dooptions(m)
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 @@ ip_dooptions(m)
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;