]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Added "--server-bridge" (without parameters) to enable
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Sat, 2 Aug 2008 08:02:53 +0000 (08:02 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Sat, 2 Aug 2008 08:02:53 +0000 (08:02 +0000)
DHCP proxy mode:  Configure server mode for ethernet
bridging using a DHCP-proxy, where clients talk to the
OpenVPN server-side DHCP server to receive their IP address
allocation and DNS server addresses.

Added "--route-gateway dhcp", to enable the extraction
of the gateway address from a DHCP negotiation with the
OpenVPN server-side LAN.

Modified client.conf and server.conf to reflect new option
modes.

Incremented version to 2.1_rc9a.

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

14 files changed:
Makefile.am
dhcp.c [new file with mode: 0644]
dhcp.h [new file with mode: 0644]
forward.c
forward.h
helper.c
openvpn.8
options.c
options.h
route.c
route.h
sample-config-files/client.conf
sample-config-files/server.conf
version.m4

index 16ed4e3b0260be076363b23298fd4bb5438fbb44..b4da7714daee9e4d00e2509a9a2412740c02db4c 100644 (file)
@@ -79,6 +79,7 @@ openvpn_SOURCES = \
        circ_list.h \
        common.h \
        crypto.c crypto.h \
+       dhcp.c dhcp.h \
        errlevel.h \
        error.c error.h \
        event.c event.h \
diff --git a/dhcp.c b/dhcp.c
new file mode 100644 (file)
index 0000000..5f1694c
--- /dev/null
+++ b/dhcp.c
@@ -0,0 +1,183 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single TCP/UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2002-2008 Telethra, Inc. <sales@openvpn.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "syshead.h"
+
+#include "dhcp.h"
+#include "socket.h"
+#include "error.h"
+
+#include "memdbg.h"
+
+static int
+get_dhcp_message_type (const struct dhcp *dhcp, const int optlen)
+{
+  const uint8_t *p = (uint8_t *) (dhcp + 1);
+  int i;
+
+  for (i = 0; i < optlen; ++i)
+    {
+      const uint8_t type = p[i];
+      const int room = optlen - i;
+      if (type == DHCP_END)           /* didn't find what we were looking for */
+       return -1;
+      else if (type == DHCP_PAD)      /* no-operation */
+       ;
+      else if (type == DHCP_MSG_TYPE) /* what we are looking for */
+       {
+         if (room >= 3)
+           {
+             if (p[i+1] == 1)        /* option length should be 1 */
+               return p[i+2];        /* return message type */
+           }
+         return -1;
+       }
+      else                            /* some other option */
+       {
+         if (room >= 2)
+           {
+             const int len = p[i+1]; /* get option length */
+             i += (len + 1);         /* advance to next option */
+           }
+       }
+    }
+  return -1;
+}
+
+static in_addr_t
+do_extract (struct dhcp *dhcp, const int optlen)
+{
+  uint8_t *p = (uint8_t *) (dhcp + 1);
+  int i;
+  in_addr_t ret = 0;
+
+  for (i = 0; i < optlen; ++i)
+    {
+      const uint8_t type = p[i];
+      const int room = optlen - i;
+      if (type == DHCP_END)
+       break;
+      else if (type == DHCP_PAD)
+       ;
+      else if (type == DHCP_ROUTER)
+       {
+         if (room >= 2)
+           {
+             const int len = p[i+1]; /* get option length */
+             if (len <= (room-2))
+               {
+                 if (!ret && len >= 4 && (len & 3) == 0)
+                   {
+                     memcpy (&ret, p+i+2, 4);      /* get router IP address */
+                     ret = ntohl (ret);
+                   }
+                 memset (p+i, DHCP_PAD, len+2);    /* delete the router option by padding it out */
+               }
+             i += (len + 1);         /* advance to next option */
+           }
+       }
+      else                            /* some other option */
+       {
+         if (room >= 2)
+           {
+             const int len = p[i+1]; /* get option length */
+             i += (len + 1);         /* advance to next option */
+           }
+       }
+    }
+  return ret;
+}
+
+static uint16_t
+udp_checksum (const uint8_t *buf,
+             const int len_udp,
+             const uint8_t *src_addr,
+             const uint8_t *dest_addr)
+{
+  uint16_t word16;
+  uint32_t sum = 0;
+  int i;
+       
+  /* make 16 bit words out of every two adjacent 8 bit words and  */
+  /* calculate the sum of all 16 bit words */
+  for (i = 0; i < len_udp; i += 2){
+    word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0);
+    sum += word16;
+  }
+
+  /* add the UDP pseudo header which contains the IP source and destination addresses */
+  for (i = 0; i < 4; i += 2){
+    word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF);
+    sum += word16;
+  }
+  for (i = 0; i < 4; i += 2){
+    word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF);
+    sum += word16;     
+  }
+
+  /* the protocol number and the length of the UDP packet */
+  sum += (uint16_t) OPENVPN_IPPROTO_UDP + (uint16_t) len_udp;
+
+  /* keep only the last 16 bits of the 32 bit calculated sum and add the carries */
+  while (sum >> 16)
+    sum = (sum & 0xFFFF) + (sum >> 16);
+               
+  /* Take the one's complement of sum */
+  return ((uint16_t) ~sum);
+}
+
+in_addr_t
+dhcp_extract_router_msg (struct buffer *ipbuf)
+{
+  struct dhcp_full *df = (struct dhcp_full *) BPTR (ipbuf);
+  const int optlen = BLEN (ipbuf) - (sizeof (struct openvpn_iphdr) + sizeof (struct openvpn_udphdr) + sizeof (struct dhcp));
+
+  if (optlen >= 0
+      && df->ip.protocol == OPENVPN_IPPROTO_UDP
+      && df->udp.source == htons (BOOTPS_PORT)
+      && df->udp.dest == htons (BOOTPC_PORT)
+      && df->dhcp.op == BOOTREPLY
+      && get_dhcp_message_type (&df->dhcp, optlen) == DHCPACK)
+    {
+      /* get the router IP address while padding out all DHCP router options */
+      const in_addr_t ret = do_extract (&df->dhcp, optlen);
+
+      /* recompute the UDP checksum */
+      df->udp.check = htons (udp_checksum ((uint8_t *) &df->udp, 
+                                          sizeof (struct openvpn_udphdr) + sizeof (struct dhcp) + optlen,
+                                          (uint8_t *)&df->ip.saddr,
+                                          (uint8_t *)&df->ip.daddr));
+
+      if (ret)
+       {
+         struct gc_arena gc = gc_new ();
+         msg (D_ROUTE, "Extracted DHCP router address: %s", print_in_addr_t (ret, 0, &gc));
+         gc_free (&gc);
+       }
+
+      return ret;
+    }
+  else
+    return 0;
+}
diff --git a/dhcp.h b/dhcp.h
new file mode 100644 (file)
index 0000000..aff5909
--- /dev/null
+++ b/dhcp.h
@@ -0,0 +1,87 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single TCP/UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2002-2008 Telethra, Inc. <sales@openvpn.net>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef DHCP_H
+#define DHCP_H
+
+#include "common.h"
+#include "buffer.h"
+#include "proto.h"
+
+#pragma pack(1)
+
+/* DHCP Option types */
+#define DHCP_PAD          0
+#define DHCP_ROUTER       3
+#define DHCP_MSG_TYPE    53  /* message type (u8) */
+#define DHCP_END        255
+
+/* DHCP Messages types */
+#define DHCPDISCOVER 1
+#define DHCPOFFER    2
+#define DHCPREQUEST  3
+#define DHCPDECLINE  4
+#define DHCPACK      5
+#define DHCPNAK      6
+#define DHCPRELEASE  7
+#define DHCPINFORM   8
+
+/* DHCP UDP port numbers */
+#define BOOTPS_PORT 67
+#define BOOTPC_PORT 68
+
+struct dhcp {
+# define BOOTREQUEST 1
+# define BOOTREPLY   2
+  uint8_t op;          /* message op */
+
+  uint8_t  htype;      /* hardware address type (e.g. '1' = 10Mb Ethernet) */
+  uint8_t  hlen;       /* hardware address length (e.g. '6' for 10Mb Ethernet) */
+  uint8_t  hops;       /* client sets to 0, may be used by relay agents */
+  uint32_t xid;        /* transaction ID, chosen by client */
+  uint16_t secs;       /* seconds since request process began, set by client */
+  uint16_t flags;
+  uint32_t ciaddr;     /* client IP address, client sets if known */
+  uint32_t yiaddr;     /* 'your' IP address -- server's response to client */
+  uint32_t siaddr;     /* server IP address */
+  uint32_t giaddr;     /* relay agent IP address */
+  uint8_t  chaddr[16]; /* client hardware address */
+  uint8_t  sname[64];  /* optional server host name */
+  uint8_t  file[128];  /* boot file name */
+  uint32_t magic;      /* must be 0x63825363 (network order) */
+};
+
+struct dhcp_full {
+  struct openvpn_iphdr ip;
+  struct openvpn_udphdr udp;
+  struct dhcp dhcp;
+# define DHCP_OPTIONS_BUFFER_SIZE 256
+  uint8_t options[DHCP_OPTIONS_BUFFER_SIZE];
+};
+
+#pragma pack()
+
+in_addr_t dhcp_extract_router_msg (struct buffer *ipbuf);
+
+#endif
index 045eb30cb27a4badb2c5f876d808717a02d7e5ba..8967e6ec5134e7d39fd2def1783482a2c92319df 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -31,6 +31,7 @@
 #include "mss.h"
 #include "event.h"
 #include "ps.h"
+#include "dhcp.h"
 
 #include "memdbg.h"
 
@@ -976,6 +977,8 @@ process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf)
   if (!c->options.passtos)
     flags &= ~PIPV4_PASSTOS;
 #endif
+  if (!c->options.route_gateway_via_dhcp || !route_list_default_gateway_needed (c->c1.route_list))
+    flags &= ~PIPV4_EXTRACT_DHCP_ROUTER;
 
   if (buf->len > 0)
     {
@@ -1001,6 +1004,13 @@ process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf)
              /* possibly alter the TCP MSS */
              if (flags & PIPV4_MSSFIX)
                mss_fixup (&ipbuf, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame)));
+
+             /* possibly extract a DHCP router message */
+             if (flags & PIPV4_EXTRACT_DHCP_ROUTER)
+               {
+                 const in_addr_t dhcp_router = dhcp_extract_router_msg (&ipbuf);
+                 route_list_add_default_gateway (c->c1.route_list, c->c2.es, dhcp_router);
+               }
            }
        }
     }
@@ -1149,7 +1159,7 @@ process_outgoing_tun (struct context *c)
    * The --mssfix option requires
    * us to examine the IPv4 header.
    */
-  process_ipv4_header (c, PIPV4_MSSFIX|PIPV4_OUTGOING, &c->c2.to_tun);
+  process_ipv4_header (c, PIPV4_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_OUTGOING, &c->c2.to_tun);
 
   if (c->c2.to_tun.len <= MAX_RW_SIZE_TUN (&c->c2.frame))
     {
index 6ed29b33f6c9b5a96177196852e16ab252767ef9..c5d516855a31ef8cdd5de1c769f0a0a2f69a95d3 100644 (file)
--- a/forward.h
+++ b/forward.h
@@ -75,6 +75,7 @@ bool send_control_channel_string (struct context *c, const char *str, int msglev
 #define PIPV4_PASSTOS         (1<<0)
 #define PIPV4_MSSFIX          (1<<1)
 #define PIPV4_OUTGOING        (1<<2)
+#define PIPV4_EXTRACT_DHCP_ROUTER (1<<3)
 
 void process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf);
 
index 2974f42d12a6a670361c813a95839be5889dc32d..f21d07e1d477b5d5ff9f7cece0ebe63f34f4beae 100644 (file)
--- a/helper.c
+++ b/helper.c
@@ -53,6 +53,14 @@ print_opt_route_gateway (const in_addr_t route_gateway, struct gc_arena *gc)
   return BSTR (&out);
 }
 
+static const char *
+print_opt_route_gateway_dhcp (struct gc_arena *gc)
+{
+  struct buffer out = alloc_buf_gc (32, gc);
+  buf_printf (&out, "route-gateway dhcp");
+  return BSTR (&out);
+}
+
 static const char *
 print_opt_route (const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
 {
@@ -170,7 +178,7 @@ helper_client_server (struct options *o)
       if (o->client)
        msg (M_USAGE, "--server and --client cannot be used together");
 
-      if (o->server_bridge_defined)
+      if (o->server_bridge_defined || o->server_bridge_proxy_dhcp)
        msg (M_USAGE, "--server and --server-bridge cannot be used together");
 
       if (o->shared_secret_file)
@@ -295,8 +303,19 @@ helper_client_server (struct options *o)
    *
    * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
    * push "route-gateway 10.8.0.4"
+   *
+   * OR
+   *
+   * server-bridge
+   *
+   * EXPANDS TO:
+   *
+   * mode server
+   * tls-server
+   *
+   * push "route-gateway dhcp"
    */
-  else if (o->server_bridge_defined)
+  else if (o->server_bridge_defined | o->server_bridge_proxy_dhcp)
     {
       if (o->client)
        msg (M_USAGE, "--server-bridge and --client cannot be used together");
@@ -310,18 +329,29 @@ helper_client_server (struct options *o)
       if (dev != DEV_TYPE_TAP)
        msg (M_USAGE, "--server-bridge directive only makes sense with --dev tap");
 
-      verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_start, o->server_bridge_netmask); 
-      verify_common_subnet ("--server-bridge", o->server_bridge_pool_start, o->server_bridge_pool_end, o->server_bridge_netmask); 
-      verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_end, o->server_bridge_netmask); 
+      if (o->server_bridge_defined)
+       {
+         verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_start, o->server_bridge_netmask); 
+         verify_common_subnet ("--server-bridge", o->server_bridge_pool_start, o->server_bridge_pool_end, o->server_bridge_netmask); 
+         verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_end, o->server_bridge_netmask); 
+       }
 
       o->mode = MODE_SERVER;
       o->tls_server = true;
-      o->ifconfig_pool_defined = true;
-      o->ifconfig_pool_start = o->server_bridge_pool_start;
-      o->ifconfig_pool_end = o->server_bridge_pool_end;
-      ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
-      o->ifconfig_pool_netmask = o->server_bridge_netmask;
-      push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE);
+
+      if (o->server_bridge_defined)
+       {
+         o->ifconfig_pool_defined = true;
+         o->ifconfig_pool_start = o->server_bridge_pool_start;
+         o->ifconfig_pool_end = o->server_bridge_pool_end;
+         ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
+         o->ifconfig_pool_netmask = o->server_bridge_netmask;
+         push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE);
+       }
+      else if (o->server_bridge_proxy_dhcp)
+       {
+         push_option (o, print_opt_route_gateway_dhcp (&o->gc), M_USAGE);
+       }
     }
   else
 #endif /* P2MP_SERVER */
index b9f0016eb1ef783d81a960965917908679595569..c9920c64be6c8eefbb7901ed8db5f9bdf1549070 100644 (file)
--- a/openvpn.8
+++ b/openvpn.8
@@ -1214,11 +1214,18 @@ table (not supported on all OSes).
 address if OpenVPN is being run in client mode, and is undefined in server mode.
 .\"*********************************************************
 .TP
-.B --route-gateway gw
+.B --route-gateway gw|'dhcp'
 Specify a default gateway
 .B gw
 for use with
 .B --route.
+
+If
+.B dhcp
+is specified as the parameter,
+the gateway address will be extracted from a DHCP
+negotiation with the OpenVPN server-side LAN.
+.\"*********************************************************
 .TP
 .B --route-metric m
 Specify a default metric
@@ -2607,13 +2614,23 @@ if you are ethernet bridging.  Use
 instead.
 .\"*********************************************************
 .TP
-.B --server-bridge gateway netmask pool-start-IP pool-end-IP
+.B --server-bridge [ gateway netmask pool-start-IP pool-end-IP ]
 
 A helper directive similar to
 .B --server
 which is designed to simplify the configuration
 of OpenVPN's server mode in ethernet bridging configurations.
 
+If
+.B --server-bridge
+is used without any parameters, it will enable a DHCP-proxy
+mode, where connecting OpenVPN clients will receive an IP
+address for their TAP adapter from the DHCP server running
+on the OpenVPN server-side LAN.
+Note that only clients that support
+the binding of a DHCP client with the TAP adapter (such as
+Windows) can support this mode.
+
 To configure ethernet bridging, you 
 must first use your OS's bridging capability
 to bridge the TAP interface with the ethernet
@@ -2662,6 +2679,23 @@ push "route-gateway 10.8.0.4"
 .LP
 .RE
 .fi
+
+In another example,
+.B --server-bridge
+(without parameters) expands as follows:
+
+.RS
+.ft 3
+.nf
+.sp
+mode server
+tls-server
+
+push "route-gateway dhcp"
+.ft
+.LP
+.RE
+.fi
 .\"*********************************************************
 .TP
 .B --push "option"
index 68a36c2c2652d3b4a1f31881fd36c73b4a6601f9..ccbbffae6e540e8e25fac0d08998afc1f79f56d0 100644 (file)
--- a/options.c
+++ b/options.c
@@ -169,7 +169,7 @@ static const char usage_message[] =
   "                  netmask default: 255.255.255.255\n"
   "                  gateway default: taken from --route-gateway or --ifconfig\n"
   "                  Specify default by leaving blank or setting to \"nil\".\n"
-  "--route-gateway gw : Specify a default gateway for use with --route.\n"
+  "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
   "--route-metric m : Specify a default metric for use with --route.\n"
   "--route-delay n [w] : Delay n seconds after connection initiation before\n"
   "                  adding routes (may be 0).  If not specified, routes will\n"
@@ -339,7 +339,7 @@ static const char usage_message[] =
   "\n"
   "Multi-Client Server options (when --mode server is used):\n"
   "--server network netmask : Helper option to easily configure server mode.\n"
-  "--server-bridge IP netmask pool-start-IP pool-end-IP : Helper option to\n"
+  "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n"
   "                    easily configure ethernet bridging server mode.\n"
   "--push \"option\" : Push a config file option back to the peer for remote\n"
   "                  execution.  Peer must specify --pull in its config file.\n"
@@ -1226,6 +1226,7 @@ show_settings (const struct options *o)
   SHOW_INT (route_delay_window);
   SHOW_BOOL (route_delay_defined);
   SHOW_BOOL (route_nopull);
+  SHOW_BOOL (route_gateway_via_dhcp);
   if (o->routes)
     print_route_options (o->routes, D_SHOW_PARMS);
 
@@ -1888,7 +1889,7 @@ static void
 options_postprocess_mutate_ce (struct options *o, struct connection_entry *ce)
 {
 #if P2MP_SERVER
-  if (o->server_defined || o->server_bridge_defined)
+  if (o->server_defined || o->server_bridge_defined || o->server_bridge_proxy_dhcp)
     {
       if (ce->proto == PROTO_TCPv4)
        ce->proto = PROTO_TCPv4_SERVER;
@@ -4237,14 +4238,21 @@ add_option (struct options *options,
   else if (streq (p[0], "route-gateway") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_ROUTE_EXTRAS);
-      if (ip_addr_dotted_quad_safe (p[1]) || is_special_addr (p[1]))
+      if (streq (p[1], "dhcp"))
        {
-         options->route_default_gateway = p[1];
+         options->route_gateway_via_dhcp = true;
        }
       else
        {
-         msg (msglevel, "route-gateway parm '%s' must be an IP address", p[1]);
-         goto err;
+         if (ip_addr_dotted_quad_safe (p[1]) || is_special_addr (p[1]))
+           {
+             options->route_default_gateway = p[1];
+           }
+         else
+           {
+             msg (msglevel, "route-gateway parm '%s' must be an IP address", p[1]);
+             goto err;
+           }
        }
     }
   else if (streq (p[0], "route-metric") && p[1])
@@ -4395,6 +4403,11 @@ add_option (struct options *options,
       options->server_bridge_pool_start = pool_start;
       options->server_bridge_pool_end = pool_end;
     }
+  else if (streq (p[0], "server-bridge") && !p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->server_bridge_proxy_dhcp = true;
+    }
   else if (streq (p[0], "push") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_PUSH);
index 34222e60835b1b57c0520277dde7f73163aea923..ea4d54e51be04ef0604f99c1ebfd3aeb8f415027 100644 (file)
--- a/options.h
+++ b/options.h
@@ -302,6 +302,7 @@ struct options
   bool route_delay_defined;
   struct route_option_list *routes;
   bool route_nopull;
+  bool route_gateway_via_dhcp;
 
 #ifdef ENABLE_OCC
   /* Enable options consistency check between peers */
@@ -340,6 +341,8 @@ struct options
 # define SF_NOPOOL (1<<0)
   unsigned int server_flags;
 
+  bool server_bridge_proxy_dhcp;
+
   bool server_bridge_defined;
   in_addr_t server_bridge_ip;
   in_addr_t server_bridge_netmask;
diff --git a/route.c b/route.c
index bc312e8edd91bdb792b91ffa6272fe9216c6b48d..e684d263218372aa3a9bc4cf25db20dfcdac86ec 100644 (file)
--- a/route.c
+++ b/route.c
@@ -335,6 +335,16 @@ clear_route_list (struct route_list *rl)
   CLEAR (*rl);
 }
 
+void
+route_list_add_default_gateway (struct route_list *rl,
+                               struct env_set *es,
+                               const in_addr_t addr)
+{
+  rl->spec.remote_endpoint = addr;
+  rl->spec.remote_endpoint_defined = true;
+  setenv_route_addr (es, "vpn_gateway", rl->spec.remote_endpoint, -1);
+}
+
 bool
 init_route_list (struct route_list *rl,
                 const struct route_option_list *opt,
diff --git a/route.h b/route.h
index 674d200acd623f968861aae605f46f9702b844f9..1a929bdf0fde94f4cac473e755ce245825a24b79 100644 (file)
--- a/route.h
+++ b/route.h
@@ -138,6 +138,10 @@ bool init_route_list (struct route_list *rl,
                      in_addr_t remote_host,
                      struct env_set *es);
 
+void route_list_add_default_gateway (struct route_list *rl,
+                                    struct env_set *es,
+                                    const in_addr_t addr);
+
 void add_routes (struct route_list *rl,
                 const struct tuntap *tt,
                 unsigned int flags,
@@ -186,4 +190,13 @@ netbits_to_netmask (const int netbits)
   return mask;
 }
 
+static inline bool
+route_list_default_gateway_needed (const struct route_list *rl)
+{
+  if (!rl)
+    return false;
+  else
+    return !rl->spec.remote_endpoint_defined;
+}
+
 #endif
index 9dd3a65ae861ebd1700cc647813b9268115ca810..58b2038bbdceecd2247e9b2d7d7a94d1b1d1d297 100644 (file)
@@ -100,7 +100,7 @@ key client.key
 # your server certificates with the nsCertType
 # field set to "server".  The build-key-server
 # script in the easy-rsa folder will do this.
-;ns-cert-type server
+ns-cert-type server
 
 # If a tls-auth key is used on the server
 # then every client must also have the key.
index f80ce8b17ae8a65251dc14f6edb727d023e394ea..f483b6bbd88528c7335da297b363a5cf81de6a8f 100644 (file)
@@ -114,6 +114,18 @@ ifconfig-pool-persist ipp.txt
 # out unless you are ethernet bridging.
 ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
 
+# Configure server mode for ethernet bridging
+# using a DHCP-proxy, where clients talk
+# to the OpenVPN server-side DHCP server
+# to receive their IP address allocation
+# and DNS server addresses.  You must first use
+# your OS's bridging capability to bridge the TAP
+# interface with the ethernet NIC interface.
+# Note: this mode only works on clients (such as
+# Windows), where the client-side TAP adapter is
+# bound to a DHCP client.
+;server-bridge
+
 # Push routes to the client to allow it
 # to reach other private subnets behind
 # the server.  Remember that these
@@ -170,22 +182,18 @@ ifconfig-pool-persist ipp.txt
 # all IP traffic such as web browsing and
 # and DNS lookups to go through the VPN
 # (The OpenVPN server machine may need to NAT
-# the TUN/TAP interface to the internet in
-# order for this to work properly).
-# CAVEAT: May break client's network config if
-# client's local DHCP server packets get routed
-# through the tunnel.  Solution: make sure
-# client's local DHCP server is reachable via
-# a more specific route than the default route
-# of 0.0.0.0/0.0.0.0.
-;push "redirect-gateway"
+# or bridge the TUN/TAP interface to the internet
+# in order for this to work properly).
+;push "redirect-gateway def1 bypass-dhcp"
 
 # Certain Windows-specific network settings
 # can be pushed to clients, such as DNS
 # or WINS server addresses.  CAVEAT:
 # http://openvpn.net/faq.html#dhcpcaveats
-;push "dhcp-option DNS 10.8.0.1"
-;push "dhcp-option WINS 10.8.0.1"
+# The addresses below refer to the public
+# DNS servers provided by opendns.com.
+;push "dhcp-option DNS 208.67.222.222"
+;push "dhcp-option DNS 208.67.220.220"
 
 # Uncomment this directive to allow different
 # clients to be able to "see" each other.
index 2122551ec74e914d94ab222ca3f624d8a6c72930..4020bba672a987c3a27e18e803bbbdf741698d19 100644 (file)
@@ -1,5 +1,5 @@
 dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1_rc9])
+define(PRODUCT_VERSION,[2.1_rc9a])
 dnl define the TAP version
 define(PRODUCT_TAP_ID,[tap0901])
 define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])