commit e2512ce0ae25d86a305ee0165826b990ab395be4 Author: Maximilian Wilhelm Date: Thu Jul 26 01:08:57 2007 +0200 Applied patch 4 from Neil Williams. As was hinted at with the previous patch, this patch introduces a new config option "net-type". It can be either "ptp" or "subnet". If net-type is not explicitly given then: if "dev" is "tun", "net-type" will be "ptp" if "dev" is "tap", "net-type" will be "subnet" If it is given, then it overrides that default. Probably the most useful usage is to set "net-type subnet" when using "dev tap". This allows you to have a simple subnet of all openvpn clients talking to a given server, and provides some guarantees that only the client allocated a particular IP address will be able to use it. I'm am not sure how this will work with OPENBSD, NETBSD, or DARWIN as tun.c doesn't seem to be able to ifconfig these with subnets. It definitely works for Linux and should work for WIN32 and FREEBSD. This patch doesn't include any updates to documentation. If you are happy to accept it, I will update the relevant documentation and send you that patch. Thanks, NeilBrown -- http://sourceforge.net/mailarchive/forum.php?thread_name=16645.49196.829476.656946%40cse.unsw.edu.au&forum_name=openvpn-devel Signed-off-by: Maximilian Wilhelm diff --git a/init.c b/init.c index 842c941..087ce72 100644 --- a/init.c +++ b/init.c @@ -551,7 +551,7 @@ do_init_route_list (const struct options *options, struct env_set *es) { const char *gw = NULL; - int net = dev_to_net (dev_type_enum (options->dev, options->dev_type)); + int net = net_type_enum (options->net_type); if (net == NET_TYPE_PTP) gw = options->ifconfig_remote_netmask; @@ -688,6 +688,7 @@ do_init_tun (struct context *c) c->options.dev_type, c->options.ifconfig_local, c->options.ifconfig_remote_netmask, + c->options.net_type, addr_host (&c->c1.link_socket_addr.local), addr_host (&c->c1.link_socket_addr.remote), !c->options.ifconfig_nowarn, diff --git a/multi.c b/multi.c index efd0336..df24ae0 100644 --- a/multi.c +++ b/multi.c @@ -212,7 +212,7 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa /* * Get tun/tap/null device type */ - net = dev_to_net (dev_type_enum (t->options.dev, t->options.dev_type)); + net = net_type_enum (t->options.net_type); /* * Init our multi_context object. diff --git a/options.c b/options.c index 3d1eb54..3f12bf3 100644 --- a/options.c +++ b/options.c @@ -129,6 +129,7 @@ static const char usage_message[] = " does not begin with \"tun\" or \"tap\".\n" "--dev-node node : Explicitly set the device node rather than using\n" " /dev/net/tun, /dev/tun, /dev/tap, etc.\n" + "--net-type ptp|subnet : Override default network type\n" "--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n" "--ifconfig l rn : TUN: configure device to use IP address l as a local\n" " endpoint and rn as a remote endpoint. l & rn should be\n" @@ -959,6 +960,7 @@ show_settings (const struct options *o) SHOW_STR (dev); SHOW_STR (dev_type); SHOW_STR (dev_node); + SHOW_STR (net_type); SHOW_BOOL (tun_ipv6); SHOW_STR (ifconfig_local); SHOW_STR (ifconfig_remote_netmask); @@ -1197,6 +1199,16 @@ options_postprocess (struct options *options, bool first_time) */ dev = dev_type_enum (options->dev, options->dev_type); + if (options->net_type == NULL) + switch(dev) + { + case DEV_TYPE_TUN: options->net_type = "ptp"; break; + case DEV_TYPE_TAP: options->net_type = "subnet"; break; + default: options->net_type = "ptp"; break; + } + if (strcmp(options->net_type, "ptp") && + strcmp(options->net_type, "subnet")) + msg (M_USAGE, "Options error: --net-type must be 'ptp' or 'subnet'"); /* * Fill in default port number for --remote list */ @@ -1782,6 +1794,7 @@ options_string (const struct options *o, { struct buffer out = alloc_buf (OPTION_LINE_SIZE); bool tt_local = false; + const char *s; buf_printf (&out, "V4"); @@ -1789,7 +1802,10 @@ options_string (const struct options *o, * Tunnel Options */ - buf_printf (&out, ",dev-type %s", dev_type_string (o->dev, o->dev_type)); + buf_printf (&out, ",dev-type %s", (s = dev_type_string (o->dev, o->dev_type))); + if ((strcmp(s,"tun")==0 && strcmp(o->net_type, "ptp") != 0) || + (strcmp(s,"tap")==0 && strcmp(o->net_type, "subnet") != 0)) + buf_printf (&out, ",net-type %s", o->net_type); buf_printf (&out, ",link-mtu %d", EXPANDED_SIZE (frame)); buf_printf (&out, ",tun-mtu %d", PAYLOAD_SIZE (frame)); buf_printf (&out, ",proto %s", proto2ascii (proto_remote (o->proto, remote), true)); @@ -1806,6 +1822,7 @@ options_string (const struct options *o, o->dev_type, o->ifconfig_local, o->ifconfig_remote_netmask, + o->net_type, (in_addr_t)0, (in_addr_t)0, false, @@ -2802,6 +2819,12 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->dev_node = p[1]; } + else if (streq (p[0], "net-type") && p[1]) + { + ++i; + VERIFY_PERMISSION (OPT_P_GENERAL); + options->net_type = p[1]; + } else if (streq (p[0], "tun-ipv6")) { VERIFY_PERMISSION (OPT_P_UP); diff --git a/options.h b/options.h index c7294be..0a38290 100644 --- a/options.h +++ b/options.h @@ -123,6 +123,7 @@ struct options const char *dev; const char *dev_type; const char *dev_node; + const char *net_type; const char *ifconfig_local; const char *ifconfig_remote_netmask; bool ifconfig_noexec; @@ -409,7 +410,6 @@ struct options int route_method; #endif }; - #define streq(x, y) (!strcmp((x), (y))) /* diff --git a/tun.c b/tun.c index 8e5026a..df3d227 100644 --- a/tun.c +++ b/tun.c @@ -92,6 +92,16 @@ dev_type_string (const char *dev, const char *dev_type) } } +int +net_type_enum (const char *net) +{ + if (strcmp(net, "ptp") == 0) + return NET_TYPE_PTP; + else if (strcmp(net, "subnet") == 0) + return NET_TYPE_SUBNET; + return NET_TYPE_UNDEF; +} + const char * dev_component_in_dev_node (const char *dev_node) { @@ -356,6 +366,7 @@ init_tun (const char *dev, /* --dev option */ const char *dev_type, /* --dev-type option */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + const char *net_type, /* --net-type option */ in_addr_t local_public, in_addr_t remote_public, const bool strict_warn, @@ -368,6 +379,7 @@ init_tun (const char *dev, /* --dev option */ clear_tuntap (tt); tt->type = dev_type_enum (dev, dev_type); + tt->nettype = net_type_enum (net_type); if (ifconfig_local_parm && ifconfig_remote_netmask_parm) { diff --git a/tun.h b/tun.h index 483c55b..7b23117 100644 --- a/tun.h +++ b/tun.h @@ -119,19 +119,12 @@ struct tuntap_options { #define NET_TYPE_PTP 2 /* two IP addresses */ #define NET_TYPE_SUBNET 3 /* an IP address and a subnet mask */ -static inline dev_to_net(int dev) -{ - /* values for NET_TYPE cunning chosen to match - * DEV_TYPE for which they match - */ - return dev; -} - struct tuntap { # define TUNNEL_TYPE(tt) ((tt) ? ((tt)->type) : DEV_TYPE_UNDEF) -# define NET_TYPE(tt) (dev_to_net(TUNNEL_TYPE(tt))) +# define NET_TYPE(tt) ((tt) ? (tt)->nettype :NET_TYPE_UNDEF) int type; /* DEV_TYPE_x as defined in proto.h */ + int nettype; /* NET_TYPE_x */ bool did_ifconfig_setup; bool did_ifconfig; @@ -219,6 +212,7 @@ struct tuntap *init_tun (const char *dev, /* --dev option */ const char *dev_type, /* --dev-type option */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ + const char *net_type, /* --net-type option */ in_addr_t local_public, in_addr_t remote_public, const bool strict_warn,