aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Yonan <james@openvpn.net>2011-02-14 03:46:37 +0000
committerJames Yonan <james@openvpn.net>2011-02-14 03:46:37 +0000
commit6a8ea97069b8edb4a50744faae3bab8ecd931840 (patch)
tree4cfa15f9c70376ff4b99cd6eb2c5e2d9f216a9fe
parentFixed minor compile issue triggered on builds where (diff)
downloadopenvpn-6a8ea97069b8edb4a50744faae3bab8ecd931840.tar.xz
Implemented get_default_gateway_mac_addr for Mac OS X (previously,
was only defined for Windows and Linux). This enables OS X to report the MAC address of the default gateway to the server for ID purposes when client-side --push-peer-info option is specified. Also, minor fix to OS X get_default_gateway function: * include net/route.h directly rather than selectively paste stuff from it into route.c git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@6925 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--init.c21
-rw-r--r--route.c161
-rw-r--r--version.m42
3 files changed, 125 insertions, 59 deletions
diff --git a/init.c b/init.c
index 7f072ae..70357e1 100644
--- a/init.c
+++ b/init.c
@@ -600,6 +600,27 @@ init_static (void)
return false;
#endif
+#ifdef TEST_GET_DEFAULT_GATEWAY
+ {
+ struct gc_arena gc = gc_new ();
+ in_addr_t addr;
+ char macaddr[6];
+
+ if (get_default_gateway(&addr, NULL))
+ msg (M_INFO, "GW %s", print_in_addr_t(addr, 0, &gc));
+ else
+ msg (M_INFO, "GDG ERROR");
+
+ if (get_default_gateway_mac_addr(macaddr))
+ msg (M_INFO, "MAC %s", format_hex_ex (macaddr, 6, 0, 1, ":", &gc));
+ else
+ msg (M_INFO, "GDGMA ERROR");
+
+ gc_free (&gc);
+ return false;
+ }
+#endif
+
#ifdef GEN_PATH_TEST
{
struct gc_arena gc = gc_new ();
diff --git a/route.c b/route.c
index 20f62d5..711f7f9 100644
--- a/route.c
+++ b/route.c
@@ -1791,70 +1791,26 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <net/route.h>
+#include <net/if_dl.h>
-/* all of this is taken from <net/route.h> in Darwin */
-#define RTA_DST 0x1
-#define RTA_GATEWAY 0x2
-#define RTA_NETMASK 0x4
-
-#define RTM_GET 0x4
-#define RTM_VERSION 5
-
-#define RTF_UP 0x1
-#define RTF_GATEWAY 0x2
-
-/*
- * These numbers are used by reliable protocols for determining
- * retransmission behavior and are included in the routing structure.
- */
-struct rt_metrics {
- u_long rmx_locks; /* Kernel must leave these values alone */
- u_long rmx_mtu; /* MTU for this path */
- u_long rmx_hopcount; /* max hops expected */
- u_long rmx_expire; /* lifetime for route, e.g. redirect */
- u_long rmx_recvpipe; /* inbound delay-bandwidth product */
- u_long rmx_sendpipe; /* outbound delay-bandwidth product */
- u_long rmx_ssthresh; /* outbound gateway buffer limit */
- u_long rmx_rtt; /* estimated round trip time */
- u_long rmx_rttvar; /* estimated rtt variance */
- u_long rmx_pksent; /* packets sent using this route */
- u_long rmx_filler[4]; /* will be used for T/TCP later */
-};
-
-/*
- * Structures for routing messages.
- */
-struct rt_msghdr {
- u_short rtm_msglen; /* to skip over non-understood messages */
- u_char rtm_version; /* future binary compatibility */
- u_char rtm_type; /* message type */
- u_short rtm_index; /* index for associated ifp */
- int rtm_flags; /* flags, incl. kern & message, e.g. DONE */
- int rtm_addrs; /* bitmask identifying sockaddrs in msg */
- pid_t rtm_pid; /* identify sender */
- int rtm_seq; /* for sender to identify action */
- int rtm_errno; /* why failed */
- int rtm_use; /* from rtentry */
- u_long rtm_inits; /* which metrics we are initializing */
- struct rt_metrics rtm_rmx; /* metrics themselves */
-};
-
-struct {
+struct rtmsg {
struct rt_msghdr m_rtm;
char m_space[512];
-} m_rtmsg;
+};
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-bool
-get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+static bool
+get_default_gateway_ex (in_addr_t *ret, in_addr_t *netmask, char **ifname)
{
struct gc_arena gc = gc_new ();
+ struct rtmsg m_rtmsg;
int s, seq, l, pid, rtm_addrs, i;
struct sockaddr so_dst, so_mask;
char *cp = m_rtmsg.m_space;
- struct sockaddr *gate = NULL, *sa;
+ struct sockaddr *gate = NULL, *ifp = NULL, *sa;
struct rt_msghdr *rtm_aux;
#define NEXTADDR(w, u) \
@@ -1868,8 +1824,9 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
pid = getpid();
seq = 0;
- rtm_addrs = RTA_DST | RTA_NETMASK;
+ rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
+ bzero(&m_rtmsg, sizeof(m_rtmsg));
bzero(&so_dst, sizeof(so_dst));
bzero(&so_mask, sizeof(so_mask));
bzero(&rtm, sizeof(struct rt_msghdr));
@@ -1911,11 +1868,16 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
cp = ((char *)(rtm_aux + 1));
if (rtm_aux->rtm_addrs) {
for (i = 1; i; i <<= 1)
- if (i & rtm_aux->rtm_addrs) {
- sa = (struct sockaddr *)cp;
- if (i == RTA_GATEWAY )
- gate = sa;
- ADVANCE(cp, sa);
+ {
+ if (i & rtm_aux->rtm_addrs)
+ {
+ sa = (struct sockaddr *)cp;
+ if (i == RTA_GATEWAY )
+ gate = sa;
+ else if (i == RTA_IFP)
+ ifp = sa;
+ ADVANCE(cp, sa);
+ }
}
}
else
@@ -1938,6 +1900,16 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
*netmask = 0xFFFFFF00; // FIXME -- get the real netmask of the adapter containing the default gateway
}
+ if (ifp && ifname)
+ {
+ struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
+ char *name = malloc(adl->sdl_nlen+1);
+ check_malloc_return(name);
+ memcpy(name, adl->sdl_data, adl->sdl_nlen);
+ name[adl->sdl_nlen] = '\0';
+ *ifname = name;
+ }
+
gc_free (&gc);
return true;
}
@@ -1948,6 +1920,12 @@ get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
}
}
+bool
+get_default_gateway (in_addr_t *ret, in_addr_t *netmask)
+{
+ return get_default_gateway_ex(ret, netmask, NULL);
+}
+
#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
#include <sys/types.h>
@@ -2353,6 +2331,73 @@ get_default_gateway_mac_addr (unsigned char *macaddr)
return false;
}
+#elif defined(TARGET_DARWIN)
+
+bool
+get_default_gateway_mac_addr (unsigned char *macaddr)
+{
+# define max(a,b) ((a) > (b) ? (a) : (b))
+ struct gc_arena gc = gc_new ();
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ char *buffer, *cp;
+ bool status = false;
+ in_addr_t gw = 0;
+ char *ifname = NULL;
+ int sockfd = -1;
+ const int bufsize = 4096;
+
+ if (!get_default_gateway_ex (&gw, NULL, &ifname)) /* get interface name of default gateway */
+ {
+ msg (M_WARN, "GDGMA: get_default_gateway_ex failed");
+ goto done;
+ }
+
+ if (!ifname)
+ {
+ msg (M_WARN, "GDGMA: cannot get default gateway ifname");
+ goto done;
+ }
+
+ buffer = (char *) gc_malloc (bufsize, false, &gc);
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0)
+ {
+ msg (M_WARN, "GDGMA: socket failed");
+ goto done;
+ }
+
+ ifc.ifc_len = bufsize;
+ ifc.ifc_buf = buffer;
+
+ if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
+ {
+ msg (M_WARN, "GDGMA: ioctl failed");
+ goto done;
+ }
+
+ for (cp = buffer; cp < buffer + bufsize; )
+ {
+ ifr = (struct ifreq *)cp;
+ if (ifr->ifr_addr.sa_family == AF_LINK && !strncmp(ifr->ifr_name, ifname, IFNAMSIZ))
+ {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
+ memcpy(macaddr, LLADDR(sdl), 6);
+ status = true;
+ }
+ cp += sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
+ }
+
+ done:
+ if (sockfd >= 0)
+ close (sockfd);
+ free (ifname);
+ gc_free (&gc);
+ return status;
+# undef max
+}
+
#else
bool
diff --git a/version.m4 b/version.m4
index 6d51fb6..2ca0739 100644
--- a/version.m4
+++ b/version.m4
@@ -1,5 +1,5 @@
dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1.3f])
+define(PRODUCT_VERSION,[2.1.3g])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])