Репозитории ALT
S: | 2.5.8-alt1 |
5.1: | 2.1.4-alt0.M51.1 |
4.1: | 2.0.9-alt1.M41.1 |
4.0: | 2.0.9-alt1.M40.1 |
3.0: | 2.0-alt1 |
+backports: | 2.0.8-alt0.M30.1 |
Группа :: Система/Серверы
Пакет: openvpn
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: openvpn-2.0.9-alt-lladdr.patch
Скачать
Скачать
Backport 'lladdr' feature from 2.1, by Mykola S. Grechukh, gns@altlinux.org
http://git.altlinux.org/people/gns/packages/?p=openvpn.git;a=shortlog;h=refs/heads/lladdr
http://lists.altlinux.org/pipermail/devel/2009-June/171406.html
'llattr' option allows to specify the link layer address,
i.e. MAC address, for TAP devices.
--- ./Makefile.am.orig
+++ ./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 \
--- ./init.c.orig
+++ ./init.c
@@ -38,6 +38,7 @@
#include "otime.h"
#include "pool.h"
#include "gremlin.h"
+#include "lladdr.h"
#include "memdbg.h"
@@ -348,6 +349,9 @@ 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
@@ -742,6 +746,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)
--- ./dev/null
+++ ./lladdr.c
@@ -0,0 +1,61 @@
+/*
+ * Support routine for configuring link layer address
+ */
+
+#include "config.h"
+#include "syshead.h"
+#include "buffer.h"
+#include "error.h"
+#include "common.h"
+#include "misc.h"
+
+const char *iproute_path = "/sbin/ip";
+
+int set_lladdr(const char *ifname, const char *lladdr,
+ const struct env_set *es)
+{
+ char command_line[256];
+ int r;
+
+ if (!ifname || !lladdr)
+ return -1;
+
+#if defined(TARGET_LINUX)
+#ifdef CONFIG_FEATURE_IPROUTE
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s link set addr %s dev %s",
+ iproute_path, lladdr, ifname);
+#else
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s %s hw ether %s",
+ IFCONFIG_PATH,
+ ifname, lladdr);
+#endif
+#elif defined(TARGET_SOLARIS)
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s %s ether %s",
+ IFCONFIG_PATH,
+ ifname, lladdr);
+#elif defined(TARGET_OPENBSD)
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s %s lladdr %s",
+ IFCONFIG_PATH,
+ ifname, lladdr);
+#elif defined(TARGET_DARWIN)
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s %s lladdr %s",
+ IFCONFIG_PATH,
+ ifname, lladdr);
+#elif defined(TARGET_FREEBSD)
+ openvpn_snprintf (command_line, sizeof (command_line),
+ "%s %s ether %s",
+ IFCONFIG_PATH,
+ 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
+
+ msg (M_INFO, "%s", command_line);
+ system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
+}
--- /dev/null
+++ ./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);
--- ./openvpn.8.orig
+++ ./openvpn.8
@@ -798,6 +798,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
--- ./options.c.orig
+++ ./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"
+ "--lladdr hw : Set the link layer address of the tap device.\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 (lladdr);
SHOW_BOOL (tun_ipv6);
SHOW_STR (ifconfig_local);
SHOW_STR (ifconfig_remote_netmask);
@@ -1256,6 +1258,8 @@ options_postprocess (struct options *options, bool first_time)
*/
if (options->inetd == INETD_NOWAIT)
options->ifconfig_noexec = true;
+ if (options->lladdr && dev != DEV_TYPE_TAP)
+ msg (M_USAGE, "--lladdr can only be used in --dev tap mode");
/*
* Sanity check on TCP mode options
@@ -2802,6 +2806,17 @@ 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);
+ if (mac_addr_safe (p[1])) /* MAC address only */
+ options->lladdr = p[1];
+ else
+ {
+ msg (msglevel, "lladdr parm '%s' must be a MAC address", p[1]);
+ goto err;
+ }
+ }
else if (streq (p[0], "tun-ipv6"))
{
VERIFY_PERMISSION (OPT_P_UP);
--- ./options.h.orig
+++ ./options.h
@@ -123,6 +123,7 @@ struct options
const char *dev;
const char *dev_type;
const char *dev_node;
+ const char *lladdr;
const char *ifconfig_local;
const char *ifconfig_remote_netmask;
bool ifconfig_noexec;
--- ./socket.c.orig
+++ ./socket.c
@@ -234,6 +234,45 @@ openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr)
return OIA_HOSTNAME; /* probably a hostname */
}
+bool
+mac_addr_safe (const char *mac_addr)
+{
+ /* verify non-NULL */
+ if (!mac_addr)
+ return false;
+
+ /* verify length is within limits */
+ if (strlen (mac_addr) > 17)
+ return false;
+
+ /* verify that all chars are either alphanumeric or ':' and that no
+ alphanumeric substring is greater than 2 chars */
+ {
+ int nnum = 0;
+ const char *p = mac_addr;
+ int c;
+
+ while ((c = *p++))
+ {
+ if ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
+ {
+ ++nnum;
+ if (nnum > 2)
+ return false;
+ }
+ else if (c == ':')
+ {
+ nnum = 0;
+ }
+ else
+ return false;
+ }
+ }
+
+ /* error-checking is left to script invoked in lladdr.c */
+ return true;
+}
+
static void
update_remote (const char* host,
struct sockaddr_in *addr,
--- ./socket.h.orig
+++ ./socket.h
@@ -345,6 +345,8 @@ void remote_list_randomize (struct remote_list *l);
#define OIA_ERROR -1
int openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr);
+bool mac_addr_safe (const char *mac_addr);
+
socket_descriptor_t create_socket_tcp (void);
socket_descriptor_t socket_do_accept (socket_descriptor_t sd,