Browse code

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

james authored on 2006/04/14 06:09:04
Showing 9 changed files
... ...
@@ -15,7 +15,10 @@ $Id$
15 15
 
16 16
 * Added --route-metric option to set a default route metric
17 17
   for --route (Roy Marples).
18
-	
18
+
19
+* Added --lladdr option to specify the link layer (MAC) address
20
+  for the tap interface on non-Windows platforms (Roy Marples).
21
+
19 22
 2006.04.12 -- Version 2.1-beta13
20 23
 
21 24
 * Code added in 2.1-beta7 and 2.0.6-rc1 to extend byte counters
... ...
@@ -50,6 +50,7 @@ openvpn_SOURCES = \
50 50
 	fragment.c fragment.h \
51 51
 	gremlin.c gremlin.h \
52 52
 	helper.c helper.h \
53
+	lladdr.c lladdr.h \
53 54
 	init.c init.h \
54 55
 	integer.h \
55 56
         interval.c interval.h \
... ...
@@ -40,6 +40,7 @@
40 40
 #include "gremlin.h"
41 41
 #include "pkcs11.h"
42 42
 #include "ps.h"
43
+#include "lladdr.h"
43 44
 
44 45
 #include "memdbg.h"
45 46
 
... ...
@@ -425,6 +426,8 @@ do_persist_tuntap (const struct options *options)
425 425
 	     "options --mktun or --rmtun should only be used together with --dev");
426 426
       tuncfg (options->dev, options->dev_type, options->dev_node,
427 427
 	      options->tun_ipv6, options->persist_mode);
428
+      if (options->persist_mode && options->lladdr)
429
+        set_lladdr(options->dev, options->lladdr, NULL);
428 430
       return true;
429 431
     }
430 432
 #endif
... ...
@@ -836,6 +839,10 @@ do_open_tun (struct context *c)
836 836
       open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
837 837
 		c->options.tun_ipv6, c->c1.tuntap);
838 838
 
839
+      /* set the hardware address */
840
+      if (c->options.lladdr)
841
+	  set_lladdr(c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es);
842
+
839 843
       /* do ifconfig */
840 844
       if (!c->options.ifconfig_noexec
841 845
 	  && ifconfig_order () == IFCONFIG_AFTER_TUN_OPEN)
842 846
new file mode 100644
... ...
@@ -0,0 +1,58 @@
0
+/*
1
+ * Support routine for configuring link layer address 
2
+ */
3
+
4
+#ifdef WIN32
5
+#include "config-win32.h"
6
+#else
7
+#include "config.h"
8
+#endif
9
+
10
+#include "syshead.h"
11
+#include "error.h"
12
+#include "misc.h"
13
+
14
+int set_lladdr(const char *ifname, const char *lladdr,
15
+		const struct env_set *es)
16
+{
17
+  char cmd[256];
18
+
19
+  if (!ifname || !lladdr)
20
+    return -1;
21
+  
22
+#if defined(TARGET_LINUX)
23
+#ifdef CONFIG_FEATURE_IPROUTE
24
+  openvpn_snprintf (cmd, sizeof (cmd),
25
+		    IPROUTE_PATH " link set addr %s dev %s",
26
+		    lladdr, ifname);
27
+#else
28
+  openvpn_snprintf (cmd, sizeof (cmd),
29
+		    IFCONFIG_PATH " %s hw ether %s",
30
+		    ifname, lladdr);
31
+#endif
32
+#elif defined(TARGET_SOLARIS)
33
+  openvpn_snprintf (cmd, sizeof (cmd),
34
+		    IFCONFIG_PATH " %s ether %s",
35
+		    ifname, lladdr);
36
+#elif defined(TARGET_OPENBSD)
37
+  openvpn_snprintf (cmd, sizeof (cmd),
38
+		    IFCONFIG_PATH " %s lladdr %s",
39
+		    ifname, lladdr);
40
+#elif defined(TARGET_DARWIN)
41
+  openvpn_snprintf (cmd, sizeof (cmd),
42
+		    IFCONFIG_PATH " %s lladdr %s",
43
+		    ifname, lladdr);
44
+#elif defined(TARGET_FREEBSD)
45
+  openvpn_snprintf (cmd, sizeof (cmd),
46
+		    IFCONFIG_PATH " %s ether %s",
47
+		    ifname, lladdr);
48
+#else
49
+      msg (M_WARN, "Sorry, but I don't know how to configure link layer addresses on this operating system.");
50
+      return -1;
51
+#endif
52
+
53
+  int r = system_check (cmd, es, M_WARN, "ERROR: Unable to set link layer address.");
54
+  if (r)
55
+    msg (M_INFO, "TUN/TAP link layer address set to %s", lladdr);
56
+  return r;
57
+}
0 58
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+/*
1
+ * Support routine for configuring link layer address 
2
+ */
3
+
4
+#include "misc.h"
5
+
6
+int set_lladdr(const char *ifname, const char *lladdr,
7
+		const struct env_set *es);
... ...
@@ -82,6 +82,7 @@ HEADERS = \
82 82
 	integer.h \
83 83
 	interval.h \
84 84
 	list.h \
85
+	lladdr.h \
85 86
 	lzo.h \
86 87
 	manage.h \
87 88
 	mbuf.h \
... ...
@@ -139,6 +140,7 @@ OBJS =  base64.o \
139 139
 	init.o \
140 140
 	interval.o \
141 141
         list.o \
142
+	lladdr.o \
142 143
 	lzo.o \
143 144
 	manage.o \
144 145
 	mbuf.o \
... ...
@@ -70,6 +70,7 @@ openvpn \- secure IP tunnel daemon.
70 70
 [\ \fB\-\-dev\fR\ \fItunX\ |\ tapX\fR\ ]
71 71
 [\ \fB\-\-dev\-type\fR\ \fIdevice\-type\fR\ ]
72 72
 [\ \fB\-\-dev\-node\fR\ \fInode\fR\ ]
73
+[\ \fB\-\-lladdr\fR\ \fIaddress\fR\ ]
73 74
 .in -4
74 75
 .ti +4
75 76
 .hy
... ...
@@ -918,6 +919,10 @@ to enumerate all available TAP-Win32
918 918
 adapters and will show both the network
919 919
 connections control panel name and the GUID for
920 920
 each TAP-Win32 adapter.
921
+.TP
922
+.B --lladdr address
923
+Specify the link layer address, more commonly known as the MAC address.
924
+Only applied to TAP devices.
921 925
 .\"*********************************************************
922 926
 .TP
923 927
 .B --ifconfig l rn
... ...
@@ -147,6 +147,7 @@ static const char usage_message[] =
147 147
   "                  does not begin with \"tun\" or \"tap\".\n"
148 148
   "--dev-node node : Explicitly set the device node rather than using\n"
149 149
   "                  /dev/net/tun, /dev/tun, /dev/tap, etc.\n"
150
+  "--lladdr hw     : Set the link layer address of the tap device.\n"
150 151
   "--topology t    : Set --dev tun topology: 'net30', 'p2p', or 'subnet'.\n"
151 152
   "--tun-ipv6      : Build tun link capable of forwarding IPv6 traffic.\n"
152 153
   "--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)
1070 1070
   SHOW_STR (dev);
1071 1071
   SHOW_STR (dev_type);
1072 1072
   SHOW_STR (dev_node);
1073
+  SHOW_STR (lladdr);
1073 1074
   SHOW_INT (topology);
1074 1075
   SHOW_BOOL (tun_ipv6);
1075 1076
   SHOW_STR (ifconfig_local);
... ...
@@ -1403,6 +1405,10 @@ options_postprocess (struct options *options, bool first_time)
1403 1403
   if (options->inetd == INETD_NOWAIT && dev != DEV_TYPE_TAP)
1404 1404
     msg (M_USAGE, "--inetd nowait only makes sense in --dev tap mode");
1405 1405
 
1406
+
1407
+  if (options->lladdr && dev != DEV_TYPE_TAP)
1408
+    msg (M_USAGE, "--lladdr can only be used in --dev tap mode");
1409
+ 
1406 1410
   /*
1407 1411
    * In forking TCP server mode, you don't need to ifconfig
1408 1412
    * the tap device (the assumption is that it will be bridged).
... ...
@@ -3217,6 +3223,11 @@ add_option (struct options *options,
3217 3217
       VERIFY_PERMISSION (OPT_P_GENERAL);
3218 3218
       options->dev_node = p[1];
3219 3219
     }
3220
+  else if (streq (p[0], "lladdr") && p[1])
3221
+    {
3222
+      VERIFY_PERMISSION (OPT_P_UP);
3223
+      options->lladdr = p[1];
3224
+    }
3220 3225
   else if (streq (p[0], "topology") && p[1])
3221 3226
     {
3222 3227
       VERIFY_PERMISSION (OPT_P_UP);
... ...
@@ -125,6 +125,7 @@ struct options
125 125
   const char *dev;
126 126
   const char *dev_type;
127 127
   const char *dev_node;
128
+  const char *lladdr;
128 129
   int topology; /* one of the TOP_x values from proto.h */
129 130
   const char *ifconfig_local;
130 131
   const char *ifconfig_remote_netmask;