summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-04-13 21:09:04 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-04-13 21:09:04 +0000
commite12fe2864a30f4e5b6c77fcf6128be7a6266d73e (patch)
tree2b2e445fb562542bd9c3c0e0e8eabb05e4145539
parent40ac3d7ac1cb29bf5d482e162c102c56a5e2e5e6 (diff)
downloadopenvpn-e12fe2864a30f4e5b6c77fcf6128be7a6266d73e.tar.gz
openvpn-e12fe2864a30f4e5b6c77fcf6128be7a6266d73e.tar.xz
openvpn-e12fe2864a30f4e5b6c77fcf6128be7a6266d73e.zip
Added --lladdr option to specify the link layer (MAC) address
for the tap interface on non-Windows platforms (Roy Marples). git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1012 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--ChangeLog5
-rw-r--r--Makefile.am1
-rw-r--r--init.c7
-rw-r--r--lladdr.c58
-rw-r--r--lladdr.h8
-rwxr-xr-xmakefile.w322
-rw-r--r--openvpn.85
-rw-r--r--options.c11
-rw-r--r--options.h1
9 files changed, 97 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index a83ae01..a4285db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,7 +15,10 @@ $Id$
* Added --route-metric option to set a default route metric
for --route (Roy Marples).
-
+
+* Added --lladdr option to specify the link layer (MAC) address
+ for the tap interface on non-Windows platforms (Roy Marples).
+
2006.04.12 -- Version 2.1-beta13
* Code added in 2.1-beta7 and 2.0.6-rc1 to extend byte counters
diff --git a/Makefile.am b/Makefile.am
index 85c0c4f..36e2cf9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@ openvpn_SOURCES = \
fragment.c fragment.h \
gremlin.c gremlin.h \
helper.c helper.h \
+ lladdr.c lladdr.h \
init.c init.h \
integer.h \
interval.c interval.h \
diff --git a/init.c b/init.c
index 0bc5219..d23272c 100644
--- a/init.c
+++ b/init.c
@@ -40,6 +40,7 @@
#include "gremlin.h"
#include "pkcs11.h"
#include "ps.h"
+#include "lladdr.h"
#include "memdbg.h"
@@ -425,6 +426,8 @@ do_persist_tuntap (const struct options *options)
"options --mktun or --rmtun should only be used together with --dev");
tuncfg (options->dev, options->dev_type, options->dev_node,
options->tun_ipv6, options->persist_mode);
+ if (options->persist_mode && options->lladdr)
+ set_lladdr(options->dev, options->lladdr, NULL);
return true;
}
#endif
@@ -836,6 +839,10 @@ do_open_tun (struct context *c)
open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
c->options.tun_ipv6, c->c1.tuntap);
+ /* set the hardware address */
+ if (c->options.lladdr)
+ set_lladdr(c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es);
+
/* do ifconfig */
if (!c->options.ifconfig_noexec
&& ifconfig_order () == IFCONFIG_AFTER_TUN_OPEN)
diff --git a/lladdr.c b/lladdr.c
new file mode 100644
index 0000000..d6fb0a6
--- /dev/null
+++ b/lladdr.c
@@ -0,0 +1,58 @@
+/*
+ * Support routine for configuring link layer address
+ */
+
+#ifdef WIN32
+#include "config-win32.h"
+#else
+#include "config.h"
+#endif
+
+#include "syshead.h"
+#include "error.h"
+#include "misc.h"
+
+int set_lladdr(const char *ifname, const char *lladdr,
+ const struct env_set *es)
+{
+ char cmd[256];
+
+ if (!ifname || !lladdr)
+ return -1;
+
+#if defined(TARGET_LINUX)
+#ifdef CONFIG_FEATURE_IPROUTE
+ openvpn_snprintf (cmd, sizeof (cmd),
+ IPROUTE_PATH " link set addr %s dev %s",
+ lladdr, ifname);
+#else
+ openvpn_snprintf (cmd, sizeof (cmd),
+ IFCONFIG_PATH " %s hw ether %s",
+ ifname, lladdr);
+#endif
+#elif defined(TARGET_SOLARIS)
+ openvpn_snprintf (cmd, sizeof (cmd),
+ IFCONFIG_PATH " %s ether %s",
+ ifname, lladdr);
+#elif defined(TARGET_OPENBSD)
+ openvpn_snprintf (cmd, sizeof (cmd),
+ IFCONFIG_PATH " %s lladdr %s",
+ ifname, lladdr);
+#elif defined(TARGET_DARWIN)
+ openvpn_snprintf (cmd, sizeof (cmd),
+ IFCONFIG_PATH " %s lladdr %s",
+ ifname, lladdr);
+#elif defined(TARGET_FREEBSD)
+ openvpn_snprintf (cmd, sizeof (cmd),
+ IFCONFIG_PATH " %s ether %s",
+ ifname, lladdr);
+#else
+ msg (M_WARN, "Sorry, but I don't know how to configure link layer addresses on this operating system.");
+ return -1;
+#endif
+
+ int r = system_check (cmd, es, M_WARN, "ERROR: Unable to set link layer address.");
+ if (r)
+ msg (M_INFO, "TUN/TAP link layer address set to %s", lladdr);
+ return r;
+}
diff --git a/lladdr.h b/lladdr.h
new file mode 100644
index 0000000..d6c4256
--- /dev/null
+++ b/lladdr.h
@@ -0,0 +1,8 @@
+/*
+ * Support routine for configuring link layer address
+ */
+
+#include "misc.h"
+
+int set_lladdr(const char *ifname, const char *lladdr,
+ const struct env_set *es);
diff --git a/makefile.w32 b/makefile.w32
index 22fbc28..bb9af54 100755
--- a/makefile.w32
+++ b/makefile.w32
@@ -82,6 +82,7 @@ HEADERS = \
integer.h \
interval.h \
list.h \
+ lladdr.h \
lzo.h \
manage.h \
mbuf.h \
@@ -139,6 +140,7 @@ OBJS = base64.o \
init.o \
interval.o \
list.o \
+ lladdr.o \
lzo.o \
manage.o \
mbuf.o \
diff --git a/openvpn.8 b/openvpn.8
index 7df156d..1c05fd2 100644
--- a/openvpn.8
+++ b/openvpn.8
@@ -70,6 +70,7 @@ openvpn \- secure IP tunnel daemon.
[\ \fB\-\-dev\fR\ \fItunX\ |\ tapX\fR\ ]
[\ \fB\-\-dev\-type\fR\ \fIdevice\-type\fR\ ]
[\ \fB\-\-dev\-node\fR\ \fInode\fR\ ]
+[\ \fB\-\-lladdr\fR\ \fIaddress\fR\ ]
.in -4
.ti +4
.hy
@@ -918,6 +919,10 @@ to enumerate all available TAP-Win32
adapters and will show both the network
connections control panel name and the GUID for
each TAP-Win32 adapter.
+.TP
+.B --lladdr address
+Specify the link layer address, more commonly known as the MAC address.
+Only applied to TAP devices.
.\"*********************************************************
.TP
.B --ifconfig l rn
diff --git a/options.c b/options.c
index effe1b1..8dcc645 100644
--- a/options.c
+++ b/options.c
@@ -147,6 +147,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"
+ "--lladdr hw : Set the link layer address of the tap device.\n"
"--topology t : Set --dev tun topology: 'net30', 'p2p', or 'subnet'.\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"
@@ -1070,6 +1071,7 @@ show_settings (const struct options *o)
SHOW_STR (dev);
SHOW_STR (dev_type);
SHOW_STR (dev_node);
+ SHOW_STR (lladdr);
SHOW_INT (topology);
SHOW_BOOL (tun_ipv6);
SHOW_STR (ifconfig_local);
@@ -1403,6 +1405,10 @@ options_postprocess (struct options *options, bool first_time)
if (options->inetd == INETD_NOWAIT && dev != DEV_TYPE_TAP)
msg (M_USAGE, "--inetd nowait only makes sense in --dev tap mode");
+
+ if (options->lladdr && dev != DEV_TYPE_TAP)
+ msg (M_USAGE, "--lladdr can only be used in --dev tap mode");
+
/*
* In forking TCP server mode, you don't need to ifconfig
* the tap device (the assumption is that it will be bridged).
@@ -3217,6 +3223,11 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL);
options->dev_node = p[1];
}
+ else if (streq (p[0], "lladdr") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_UP);
+ options->lladdr = p[1];
+ }
else if (streq (p[0], "topology") && p[1])
{
VERIFY_PERMISSION (OPT_P_UP);
diff --git a/options.h b/options.h
index b9dafe7..99e68a2 100644
--- a/options.h
+++ b/options.h
@@ -125,6 +125,7 @@ struct options
const char *dev;
const char *dev_type;
const char *dev_node;
+ const char *lladdr;
int topology; /* one of the TOP_x values from proto.h */
const char *ifconfig_local;
const char *ifconfig_remote_netmask;