Browse code

Added "redirect-private" option which allows private subnets to be pushed to the client in such a way that they don't accidently obscure critical local addresses such as the DHCP server address and DNS server addresses.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@4436 e7ae566f-a301-0410-adde-c780ea21d3b5

james authored on 2009/05/23 19:30:10
Showing 3 changed files
... ...
@@ -182,7 +182,7 @@ static const char usage_message[] =
182 182
   "                  by server EXCEPT for routes.\n"
183 183
   "--allow-pull-fqdn : Allow client to pull DNS names from server for\n"
184 184
   "                    --ifconfig, --route, and --route-gateway.\n"
185
-  "--redirect-gateway [flags]: (Experimental) Automatically execute routing\n"
185
+  "--redirect-gateway [flags]: Automatically execute routing\n"
186 186
   "                  commands to redirect all outgoing IP traffic through the\n"
187 187
   "                  VPN.  Add 'local' flag if both " PACKAGE_NAME " servers are directly\n"
188 188
   "                  connected via a common subnet, such as with WiFi.\n"
... ...
@@ -190,6 +190,8 @@ static const char usage_message[] =
190 190
   "                  and 128.0.0.0/1 rather than 0.0.0.0/0.  Add 'bypass-dhcp'\n"
191 191
   "                  flag to add a direct route to DHCP server, bypassing tunnel.\n"
192 192
   "                  Add 'bypass-dns' flag to similarly bypass tunnel for DNS.\n"
193
+  "--redirect-private [flags]: Like --redirect-gateway, but omit actually changing\n"
194
+  "                  the default gateway.  Useful when pushing private subnets.\n"
193 195
   "--setenv name value : Set a custom environmental variable to pass to script.\n"
194 196
   "--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n"
195 197
   "                  directives for future OpenVPN versions to be ignored.\n"
... ...
@@ -4391,13 +4393,15 @@ add_option (struct options *options,
4391 4391
       VERIFY_PERMISSION (OPT_P_GENERAL);
4392 4392
       options->allow_pull_fqdn = true;
4393 4393
     }
4394
-  else if (streq (p[0], "redirect-gateway"))
4394
+  else if (streq (p[0], "redirect-gateway") || streq (p[0], "redirect-private"))
4395 4395
     {
4396 4396
       int j;
4397 4397
       VERIFY_PERMISSION (OPT_P_ROUTE);
4398 4398
       rol_check_alloc (options);
4399 4399
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
4400 4400
 	{
4401
+	  if (streq (p[0], "redirect-gateway"))
4402
+	    options->routes->flags |= RG_REROUTE_GW;
4401 4403
 	  if (streq (p[j], "local"))
4402 4404
 	    options->routes->flags |= RG_LOCAL;
4403 4405
 	  else if (streq (p[j], "def1"))
... ...
@@ -4408,7 +4412,7 @@ add_option (struct options *options,
4408 4408
 	    options->routes->flags |= RG_BYPASS_DNS;
4409 4409
 	  else
4410 4410
 	    {
4411
-	      msg (msglevel, "unknown --redirect-gateway flag: %s", p[j]);
4411
+	      msg (msglevel, "unknown --%s flag: %s", p[0], p[j]);
4412 4412
 	      goto err;
4413 4413
 	    }
4414 4414
 	}
... ...
@@ -543,18 +543,83 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
543 543
 	  /* route DHCP/DNS server traffic through original default gateway */
544 544
 	  add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es);
545 545
 
546
+	  if (rl->flags & RG_REROUTE_GW)
547
+	    {
548
+	      if (rl->flags & RG_DEF1)
549
+		{
550
+		  /* add new default route (1st component) */
551
+		  add_route3 (0x00000000,
552
+			      0x80000000,
553
+			      rl->spec.remote_endpoint,
554
+			      tt,
555
+			      flags,
556
+			      es);
557
+
558
+		  /* add new default route (2nd component) */
559
+		  add_route3 (0x80000000,
560
+			      0x80000000,
561
+			      rl->spec.remote_endpoint,
562
+			      tt,
563
+			      flags,
564
+			      es);
565
+		}
566
+	      else
567
+		{
568
+		  /* delete default route */
569
+		  del_route3 (0,
570
+			      0,
571
+			      rl->spec.net_gateway,
572
+			      tt,
573
+			      flags,
574
+			      es);
575
+
576
+		  /* add new default route */
577
+		  add_route3 (0,
578
+			      0,
579
+			      rl->spec.remote_endpoint,
580
+			      tt,
581
+			      flags,
582
+			      es);
583
+		}
584
+	    }
585
+
586
+	  /* set a flag so we can undo later */
587
+	  rl->did_redirect_default_gateway = true;
588
+	}
589
+    }
590
+}
591
+
592
+static void
593
+undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
594
+{
595
+  if (rl->did_redirect_default_gateway)
596
+    {
597
+      /* delete remote host route */
598
+      if (!(rl->flags & RG_LOCAL))
599
+	del_route3 (rl->spec.remote_host,
600
+		    ~0,
601
+		    rl->spec.net_gateway,
602
+		    tt,
603
+		    flags,
604
+		    es);
605
+
606
+      /* delete special DHCP/DNS bypass route */
607
+      del_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es);
608
+
609
+      if (rl->flags & RG_REROUTE_GW)
610
+	{
546 611
 	  if (rl->flags & RG_DEF1)
547 612
 	    {
548
-	      /* add new default route (1st component) */
549
-	      add_route3 (0x00000000,
613
+	      /* delete default route (1st component) */
614
+	      del_route3 (0x00000000,
550 615
 			  0x80000000,
551 616
 			  rl->spec.remote_endpoint,
552 617
 			  tt,
553 618
 			  flags,
554 619
 			  es);
555 620
 
556
-	      /* add new default route (2nd component) */
557
-	      add_route3 (0x80000000,
621
+	      /* delete default route (2nd component) */
622
+	      del_route3 (0x80000000,
558 623
 			  0x80000000,
559 624
 			  rl->spec.remote_endpoint,
560 625
 			  tt,
... ...
@@ -566,78 +631,19 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u
566 566
 	      /* delete default route */
567 567
 	      del_route3 (0,
568 568
 			  0,
569
-			  rl->spec.net_gateway,
569
+			  rl->spec.remote_endpoint,
570 570
 			  tt,
571 571
 			  flags,
572 572
 			  es);
573 573
 
574
-	      /* add new default route */
574
+	      /* restore original default route */
575 575
 	      add_route3 (0,
576 576
 			  0,
577
-			  rl->spec.remote_endpoint,
577
+			  rl->spec.net_gateway,
578 578
 			  tt,
579 579
 			  flags,
580 580
 			  es);
581 581
 	    }
582
-
583
-	  /* set a flag so we can undo later */
584
-	  rl->did_redirect_default_gateway = true;
585
-	}
586
-    }
587
-}
588
-
589
-static void
590
-undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
591
-{
592
-  if (rl->did_redirect_default_gateway)
593
-    {
594
-      /* delete remote host route */
595
-      if (!(rl->flags & RG_LOCAL))
596
-	del_route3 (rl->spec.remote_host,
597
-		    ~0,
598
-		    rl->spec.net_gateway,
599
-		    tt,
600
-		    flags,
601
-		    es);
602
-
603
-      /* delete special DHCP/DNS bypass route */
604
-      del_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es);
605
-
606
-      if (rl->flags & RG_DEF1)
607
-	{
608
-	  /* delete default route (1st component) */
609
-	  del_route3 (0x00000000,
610
-		      0x80000000,
611
-		      rl->spec.remote_endpoint,
612
-		      tt,
613
-		      flags,
614
-		      es);
615
-
616
-	  /* delete default route (2nd component) */
617
-	  del_route3 (0x80000000,
618
-		      0x80000000,
619
-		      rl->spec.remote_endpoint,
620
-		      tt,
621
-		      flags,
622
-		      es);
623
-	}
624
-      else
625
-	{
626
-	  /* delete default route */
627
-	  del_route3 (0,
628
-		      0,
629
-		      rl->spec.remote_endpoint,
630
-		      tt,
631
-		      flags,
632
-		      es);
633
-
634
-	  /* restore original default route */
635
-	  add_route3 (0,
636
-		      0,
637
-		      rl->spec.net_gateway,
638
-		      tt,
639
-		      flags,
640
-		      es);
641 582
 	}
642 583
 
643 584
       rl->did_redirect_default_gateway = false;
... ...
@@ -82,6 +82,7 @@ struct route_option {
82 82
 #define RG_DEF1           (1<<2)
83 83
 #define RG_BYPASS_DHCP    (1<<3)
84 84
 #define RG_BYPASS_DNS     (1<<4)
85
+#define RG_REROUTE_GW     (1<<5)
85 86
 
86 87
 struct route_option_list {
87 88
   int n;