summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2007-06-16 00:34:44 +0000
committerChristian Pointner <equinox@anytun.org>2007-06-16 00:34:44 +0000
commit8e8ce31dc422c0116ae2866d5874ef70fbb21f57 (patch)
tree63b8cfd55cf7bd5b4fd920d6b28dda579dca5029
parentfixed checkin (diff)
removed openvpn source files
tundevice can now be compiled added main added some helper classes
-rw-r--r--Makefile43
-rw-r--r--anytun.cpp58
-rw-r--r--buffer.cpp111
-rw-r--r--buffer.h55
-rw-r--r--datatypes.h48
-rw-r--r--openvpn/basic.h41
-rw-r--r--openvpn/buffer.h712
-rw-r--r--openvpn/common.h76
-rw-r--r--openvpn/event.h157
-rw-r--r--openvpn/integer.h114
-rw-r--r--openvpn/interval.h239
-rw-r--r--openvpn/misc.h257
-rw-r--r--openvpn/mtu.h304
-rw-r--r--openvpn/otime.h206
-rw-r--r--openvpn/perf.h82
-rw-r--r--openvpn/proto.h163
-rw-r--r--openvpn/sig.h100
-rw-r--r--openvpn/status.h95
-rw-r--r--openvpn/thread.h235
-rw-r--r--openvpn/tun.c3446
-rw-r--r--openvpn/tun.h413
-rwxr-xr-xopenvpn/win32.h251
-rw-r--r--threadutils.hpp174
-rw-r--r--tunDevice.cpp59
-rw-r--r--tunDevice.h9
25 files changed, 541 insertions, 6907 deletions
diff --git a/Makefile b/Makefile
index 35e62b2..31ed266 100644
--- a/Makefile
+++ b/Makefile
@@ -1,21 +1,50 @@
C = gcc
+CFLAGS = -g -Wall
C++ = g++
-CCFLAGS = -Wall
-LDFLAGS = #-lpthread #-static
+CCFLAGS = -g -Wall
+LD = g++
+LDFLAGS = -g -O2 -ldl
-OBJS = tunDevice.o tun.c
+OPENVPNDEPS = openvpn/tun.o \
+ openvpn/error.o \
+ openvpn/socket.o \
+ openvpn/buffer.o \
+ openvpn/misc.o \
+ openvpn/manage.o \
+ openvpn/fdmisc.o \
+ openvpn/otime.o \
+ openvpn/options.o \
+ openvpn/mtu.o \
+ openvpn/plugin.o \
+ openvpn/sig.o \
+ openvpn/proxy.o \
+ openvpn/socks.o \
+ openvpn/status.o \
+ openvpn/event.o \
+ openvpn/route.o \
+ openvpn/helper.o \
+ openvpn/init.o \
+ openvpn/interval.o \
+ openvpn/base64.o \
+ openvpn/shaper.o \
+ openvpn/fragment.o
+
+OBJS = anytun.o tunDevice.o buffer.o $(OPENVPNDEPS)
EXECUTABLE = anytun
all: $(EXECUTABLE)
anytun: $(OBJS)
- $(C++) $(OBJS) -o $@ $(LDFLAGS)
+ $(LD) $(OBJS) -o $@ $(LDFLAGS)
+
+tunDevice.o: tunDevice.cpp tunDevice.h
+ $(C++) $(CCFLAGS) $< -c
-tunDevice.o: tunDevice.cpp tunDevice.h openvpn/tun.h
+Buffer.o: buffer.cpp buffer.h
$(C++) $(CCFLAGS) $< -c
-tun.o: openvpn/tun.c openvpn/tun.h
- $(C) $(CCFLAGS) $< -c
+anytun.o: anytun.cpp
+ $(C++) $(CCFLAGS) $< -c
clean:
rm -f *.o
diff --git a/anytun.cpp b/anytun.cpp
new file mode 100644
index 0000000..02f0192
--- /dev/null
+++ b/anytun.cpp
@@ -0,0 +1,58 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <iostream>
+
+#include "datatypes.h"
+
+#include "buffer.h"
+
+int main(int argc, char* argv[])
+{
+ std::cout << "anytun - secure anycast tunneling protocol" << std::endl;
+
+ u_int8_t test[100];
+ for(int i=0;i<100;++i)
+ test[i] = i;
+
+
+ Buffer a(test, 100);
+ Buffer b(a);
+ Buffer c;
+
+ c = b;
+
+ c.resize(500);
+
+ for(unsigned int i=0;i<c.getLength();++i)
+ c[i] = i;
+
+ return 0;
+}
diff --git a/buffer.cpp b/buffer.cpp
new file mode 100644
index 0000000..8632d34
--- /dev/null
+++ b/buffer.cpp
@@ -0,0 +1,111 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string>
+
+#include "datatypes.h"
+
+#include "buffer.h"
+
+Buffer::Buffer() : buf_(0), length_(0)
+{
+}
+
+Buffer::Buffer(u_int8_t* data, u_int32_t length) : length_(length)
+{
+ buf_ = new u_int8_t[length_];
+ if(buf_)
+ std::memcpy(buf_, data, length_);
+ else
+ length_ = 0;
+}
+
+Buffer::~Buffer()
+{
+ if(buf_)
+ delete[] buf_;
+}
+
+Buffer::Buffer(const Buffer &src) : length_(src.length_)
+{
+ buf_ = new u_int8_t[length_];
+ if(buf_)
+ std::memcpy(buf_, src.buf_, length_);
+ else
+ length_ = 0;
+}
+
+void Buffer::operator=(const Buffer &src)
+{
+ if(buf_)
+ delete[] buf_;
+
+ length_ = src.length_;
+
+ buf_ = new u_int8_t[length_];
+ if(buf_)
+ std::memcpy(buf_, src.buf_, length_);
+ else
+ length_ = 0;
+}
+
+u_int32_t Buffer::resize(u_int32_t new_length)
+{
+ if(length_ == new_length)
+ return length_;
+
+ u_int8_t *tmp = new u_int8_t[new_length];
+ if(!tmp)
+ return length_;
+
+ if(buf_)
+ {
+ std::memcpy(tmp, buf_, length_);
+ delete[] buf_;
+ }
+
+ length_ = new_length;
+ buf_ = tmp;
+}
+
+u_int32_t Buffer::getLength() const
+{
+ return length_;
+}
+
+u_int8_t* Buffer::getBuf()
+{
+ return buf_;
+}
+
+Buffer::operator u_int8_t*( )
+{
+ return buf_;
+}
diff --git a/buffer.h b/buffer.h
new file mode 100644
index 0000000..a68258b
--- /dev/null
+++ b/buffer.h
@@ -0,0 +1,55 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _BUFFER_H_
+#define _BUFFER_H_
+
+class Buffer
+{
+public:
+ Buffer();
+ Buffer(u_int8_t* data, u_int32_t length);
+ ~Buffer();
+ Buffer(const Buffer &src);
+ void operator=(const Buffer &src);
+
+ u_int32_t resize(u_int32_t new_length);
+ u_int32_t getLength() const;
+ u_int8_t* getBuf();
+ operator u_int8_t*( );
+
+protected:
+
+ u_int32_t length_;
+ u_int8_t *buf_;
+};
+
+
+#endif
diff --git a/datatypes.h b/datatypes.h
new file mode 100644
index 0000000..62fda83
--- /dev/null
+++ b/datatypes.h
@@ -0,0 +1,48 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _DATATYPES_H_
+#define _DATATYPES_H_
+
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+
+typedef signed short int16;
+typedef unsigned short u_int16_t;
+
+typedef signed int int32;
+typedef unsigned int u_int32_t;
+
+typedef signed long long int64_t;
+typedef unsigned long long u_int64_t;
+
+typedef u_int32_t auth_tag_t;
+
+#endif
diff --git a/openvpn/basic.h b/openvpn/basic.h
deleted file mode 100644
index cde638e..0000000
--- a/openvpn/basic.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef BASIC_H
-#define BASIC_H
-
-/* bool definitions */
-#define bool int
-#define true 1
-#define false 0
-
-#define BOOL_CAST(x) ((x) ? (true) : (false))
-
-/* size of an array */
-#define SIZE(x) (sizeof(x)/sizeof(x[0]))
-
-/* clear an object */
-#define CLEAR(x) memset(&(x), 0, sizeof(x))
-
-#endif
diff --git a/openvpn/buffer.h b/openvpn/buffer.h
deleted file mode 100644
index 1e5266b..0000000
--- a/openvpn/buffer.h
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef BUFFER_H
-#define BUFFER_H
-
-#include "basic.h"
-#include "thread.h"
-
-/*
- * Define verify_align function, otherwise
- * it will be a noop.
- */
-/* #define VERIFY_ALIGNMENT */
-
-/*
- * Keep track of source file/line of buf_init calls
- */
-#ifdef VERIFY_ALIGNMENT
-#define BUF_INIT_TRACKING
-#endif
-
-/* basic buffer class for OpenVPN */
-
-struct buffer
-{
- int capacity; /* size of buffer allocated by malloc */
- int offset; /* data starts at data + offset, offset > 0 to allow for efficient prepending */
- int len; /* length of data that starts at data + offset */
- uint8_t *data;
-
-#ifdef BUF_INIT_TRACKING
- const char *debug_file;
- int debug_line;
-#endif
-};
-
-/* for garbage collection */
-
-struct gc_entry
-{
- struct gc_entry *next;
-};
-
-struct gc_arena
-{
- struct gc_entry *list;
-};
-
-#define BPTR(buf) ((buf)->data + (buf)->offset)
-#define BEND(buf) (BPTR(buf) + (buf)->len)
-#define BLAST(buf) (((buf)->data && (buf)->len) ? (BPTR(buf) + (buf)->len - 1) : NULL)
-#define BLEN(buf) ((buf)->len)
-#define BDEF(buf) ((buf)->data != NULL)
-#define BSTR(buf) ((char *)BPTR(buf))
-#define BCAP(buf) (buf_forward_capacity (buf))
-
-void buf_clear (struct buffer *buf);
-
-struct buffer clear_buf (void);
-void free_buf (struct buffer *buf);
-
-bool buf_assign (struct buffer *dest, const struct buffer *src);
-
-
-
-/* for dmalloc debugging */
-
-#ifdef DMALLOC
-
-#define alloc_buf(size) alloc_buf_debug (size, __FILE__, __LINE__)
-#define alloc_buf_gc(size, gc) alloc_buf_gc_debug (size, gc, __FILE__, __LINE__);
-#define clone_buf(buf) clone_buf_debug (buf, __FILE__, __LINE__);
-#define gc_malloc(size, clear, arena) gc_malloc_debug (size, clear, arena, __FILE__, __LINE__)
-#define string_alloc(str, gc) string_alloc_debug (str, gc, __FILE__, __LINE__)
-#define string_alloc_buf(str, gc) string_alloc_buf_debug (str, gc, __FILE__, __LINE__)
-
-struct buffer alloc_buf_debug (size_t size, const char *file, int line);
-struct buffer alloc_buf_gc_debug (size_t size, struct gc_arena *gc, const char *file, int line);
-struct buffer clone_buf_debug (const struct buffer* buf, const char *file, int line);
-void *gc_malloc_debug (size_t size, bool clear, struct gc_arena *a, const char *file, int line);
-char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file, int line);
-struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line);
-
-#else
-
-struct buffer alloc_buf (size_t size);
-struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
-struct buffer clone_buf (const struct buffer* buf);
-void *gc_malloc (size_t size, bool clear, struct gc_arena *a);
-char *string_alloc (const char *str, struct gc_arena *gc);
-struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
-
-#endif
-
-#ifdef BUF_INIT_TRACKING
-#define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
-bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
-#else
-#define buf_init(buf, offset) buf_init_dowork (buf, offset)
-#endif
-
-
-/* inline functions */
-
-static inline void
-buf_reset (struct buffer *buf)
-{
- buf->capacity = 0;
- buf->offset = 0;
- buf->len = 0;
- buf->data = NULL;
-}
-
-static inline bool
-buf_init_dowork (struct buffer *buf, int offset)
-{
- if (offset < 0 || offset > buf->capacity || buf->data == NULL)
- return false;
- buf->len = 0;
- buf->offset = offset;
- return true;
-}
-
-static inline bool
-buf_defined (struct buffer *buf)
-{
- return buf->data != NULL;
-}
-
-static inline void
-buf_set_write (struct buffer *buf, uint8_t *data, int size)
-{
- buf->len = 0;
- buf->offset = 0;
- buf->capacity = size;
- buf->data = data;
- if (size > 0 && data)
- *data = 0;
-}
-
-static inline void
-buf_set_read (struct buffer *buf, const uint8_t *data, int size)
-{
- buf->len = buf->capacity = size;
- buf->offset = 0;
- buf->data = (uint8_t *)data;
-}
-
-/* Like strncpy but makes sure dest is always null terminated */
-static inline void
-strncpynt (char *dest, const char *src, size_t maxlen)
-{
- strncpy (dest, src, maxlen);
- if (maxlen > 0)
- dest[maxlen - 1] = 0;
-}
-
-/* return true if string contains at least one numerical digit */
-static inline bool
-has_digit (const char* src)
-{
- char c;
- while ((c = *src++))
- {
- if (isdigit(c))
- return true;
- }
- return false;
-}
-
-/*
- * printf append to a buffer with overflow check
- */
-void buf_printf (struct buffer *buf, const char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format (printf, 2, 3)))
-#endif
- ;
-
-/*
- * Like snprintf but guarantees null termination for size > 0
- */
-int openvpn_snprintf(char *str, size_t size, const char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format (printf, 3, 4)))
-#endif
- ;
-
-/*
- * remove/add trailing characters
- */
-
-void buf_null_terminate (struct buffer *buf);
-void buf_chomp (struct buffer *buf);
-void buf_rmtail (struct buffer *buf, uint8_t remove);
-
-/*
- * non-buffer string functions
- */
-void chomp (char *str);
-void string_null_terminate (char *str, int len, int capacity);
-
-/*
- * Write string in buf to file descriptor fd.
- * NOTE: requires that string be null terminated.
- */
-void buf_write_string_file (const struct buffer *buf, const char *filename, int fd);
-
-/*
- * write a string to the end of a buffer that was
- * truncated by buf_printf
- */
-void buf_catrunc (struct buffer *buf, const char *str);
-
-/*
- * convert a multi-line output to one line
- */
-void convert_to_one_line (struct buffer *buf);
-
-/*
- * Parse a string based on a given delimiter char
- */
-bool buf_parse (struct buffer *buf, const int delim, char *line, const int size);
-
-/*
- * Hex dump -- Output a binary buffer to a hex string and return it.
- */
-char *
-format_hex_ex (const uint8_t *data, int size, int maxoutput,
- int space_break, const char* separator,
- struct gc_arena *gc);
-
-static inline char *
-format_hex (const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
-{
- return format_hex_ex (data, size, maxoutput, 4, " ", gc);
-}
-
-/*
- * Return a buffer that is a subset of another buffer.
- */
-struct buffer buf_sub (struct buffer *buf, int size, bool prepend);
-
-/*
- * Check if sufficient space to append to buffer.
- */
-
-static inline bool
-buf_safe (const struct buffer *buf, int len)
-{
- return len >= 0 && buf->offset + buf->len + len <= buf->capacity;
-}
-
-static inline bool
-buf_safe_bidir (const struct buffer *buf, int len)
-{
- const int newlen = buf->len + len;
- return newlen >= 0 && buf->offset + newlen <= buf->capacity;
-}
-
-static inline int
-buf_forward_capacity (const struct buffer *buf)
-{
- int ret = buf->capacity - (buf->offset + buf->len);
- if (ret < 0)
- ret = 0;
- return ret;
-}
-
-static inline int
-buf_forward_capacity_total (const struct buffer *buf)
-{
- int ret = buf->capacity - buf->offset;
- if (ret < 0)
- ret = 0;
- return ret;
-}
-
-static inline int
-buf_reverse_capacity (const struct buffer *buf)
-{
- return buf->offset;
-}
-
-static inline bool
-buf_inc_len (struct buffer *buf, int inc)
-{
- if (!buf_safe_bidir (buf, inc))
- return false;
- buf->len += inc;
- return true;
-}
-
-/*
- * Make space to prepend to a buffer.
- * Return NULL if no space.
- */
-
-static inline uint8_t *
-buf_prepend (struct buffer *buf, int size)
-{
- if (size < 0 || size > buf->offset)
- return NULL;
- buf->offset -= size;
- buf->len += size;
- return BPTR (buf);
-}
-
-static inline bool
-buf_advance (struct buffer *buf, int size)
-{
- if (size < 0 || buf->len < size)
- return false;
- buf->offset += size;
- buf->len -= size;
- return true;
-}
-
-/*
- * Return a pointer to allocated space inside a buffer.
- * Return NULL if no space.
- */
-
-static inline uint8_t *
-buf_write_alloc (struct buffer *buf, int size)
-{
- uint8_t *ret;
- if (!buf_safe (buf, size))
- return NULL;
- ret = BPTR (buf) + buf->len;
- buf->len += size;
- return ret;
-}
-
-static inline uint8_t *
-buf_write_alloc_prepend (struct buffer *buf, int size, bool prepend)
-{
- return prepend ? buf_prepend (buf, size) : buf_write_alloc (buf, size);
-}
-
-static inline uint8_t *
-buf_read_alloc (struct buffer *buf, int size)
-{
- uint8_t *ret;
- if (size < 0 || buf->len < size)
- return NULL;
- ret = BPTR (buf);
- buf->offset += size;
- buf->len -= size;
- return ret;
-}
-
-static inline bool
-buf_write (struct buffer *dest, const void *src, int size)
-{
- uint8_t *cp = buf_write_alloc (dest, size);
- if (!cp)
- return false;
- memcpy (cp, src, size);
- return true;
-}
-
-static inline bool
-buf_write_prepend (struct buffer *dest, const void *src, int size)
-{
- uint8_t *cp = buf_prepend (dest, size);
- if (!cp)
- return false;
- memcpy (cp, src, size);
- return true;
-}
-
-static inline bool
-buf_write_u8 (struct buffer *dest, int data)
-{
- uint8_t u8 = (uint8_t) data;
- return buf_write (dest, &u8, sizeof (uint8_t));
-}
-
-static inline bool
-buf_write_u16 (struct buffer *dest, int data)
-{
- uint16_t u16 = htons ((uint16_t) data);
- return buf_write (dest, &u16, sizeof (uint16_t));
-}
-
-static inline bool
-buf_write_u32 (struct buffer *dest, int data)
-{
- uint32_t u32 = htonl ((uint32_t) data);
- return buf_write (dest, &u32, sizeof (uint32_t));
-}
-
-static inline bool
-buf_copy (struct buffer *dest, const struct buffer *src)
-{
- return buf_write (dest, BPTR (src), BLEN (src));
-}
-
-static inline bool
-buf_copy_n (struct buffer *dest, struct buffer *src, int n)
-{
- uint8_t *cp = buf_read_alloc (src, n);
- if (!cp)
- return false;
- return buf_write (dest, cp, n);
-}
-
-static inline bool
-buf_copy_range (struct buffer *dest,
- int dest_index,
- const struct buffer *src,
- int src_index,
- int src_len)
-{
- if (src_index < 0
- || src_len < 0
- || src_index + src_len > src->len
- || dest_index < 0
- || dest->offset + dest_index + src_len > dest->capacity)
- return false;
- memcpy (dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
- if (dest_index + src_len > dest->len)
- dest->len = dest_index + src_len;
- return true;
-}
-
-/* truncate src to len, copy excess data beyond len to dest */
-static inline bool
-buf_copy_excess (struct buffer *dest,
- struct buffer *src,
- int len)
-{
- if (len < 0)
- return false;
- if (src->len > len)
- {
- struct buffer b = *src;
- src->len = len;
- if (!buf_advance (&b, len))
- return false;
- return buf_copy (dest, &b);
- }
- else
- {
- return true;
- }
-}
-
-static inline bool
-buf_read (struct buffer *src, void *dest, int size)
-{
- uint8_t *cp = buf_read_alloc (src, size);
- if (!cp)
- return false;
- memcpy (dest, cp, size);
- return true;
-}
-
-static inline int
-buf_read_u8 (struct buffer *buf)
-{
- int ret;
- if (BLEN (buf) < 1)
- return -1;
- ret = *BPTR(buf);
- buf_advance (buf, 1);
- return ret;
-}
-
-static inline int
-buf_read_u16 (struct buffer *buf)
-{
- uint16_t ret;
- if (!buf_read (buf, &ret, sizeof (uint16_t)))
- return -1;
- return ntohs (ret);
-}
-
-static inline uint32_t
-buf_read_u32 (struct buffer *buf, bool *good)
-{
- uint32_t ret;
- if (!buf_read (buf, &ret, sizeof (uint32_t)))
- {
- if (good)
- *good = false;
- return 0;
- }
- else
- {
- if (good)
- *good = true;
- return ntohl (ret);
- }
-}
-
-static inline bool
-buf_string_match (const struct buffer *src, const void *match, int size)
-{
- if (size != src->len)
- return false;
- return memcmp (BPTR (src), match, size) == 0;
-}
-
-static inline bool
-buf_string_match_head (const struct buffer *src, const void *match, int size)
-{
- if (size < 0 || size > src->len)
- return false;
- return memcmp (BPTR (src), match, size) == 0;
-}
-
-bool buf_string_match_head_str (const struct buffer *src, const char *match);
-bool buf_string_compare_advance (struct buffer *src, const char *match);
-int buf_substring_len (const struct buffer *buf, int delim);
-
-/*
- * Bitwise operations
- */
-static inline void
-xor (uint8_t *dest, const uint8_t *src, int len)
-{
- while (len-- > 0)
- *dest++ ^= *src++;
-}
-
-/*
- * Classify and mutate strings based on character types.
- */
-
-/*#define CHARACTER_CLASS_DEBUG*/
-
-/* character classes */
-
-#define CC_ANY (1<<0)
-#define CC_NULL (1<<1)
-
-#define CC_ALNUM (1<<2)
-#define CC_ALPHA (1<<3)
-#define CC_ASCII (1<<4)
-#define CC_CNTRL (1<<5)
-#define CC_DIGIT (1<<6)
-#define CC_PRINT (1<<7)
-#define CC_PUNCT (1<<8)
-#define CC_SPACE (1<<9)
-#define CC_XDIGIT (1<<10)
-
-#define CC_BLANK (1<<11)
-#define CC_NEWLINE (1<<12)
-#define CC_CR (1<<13)
-
-#define CC_BACKSLASH (1<<14)
-#define CC_UNDERBAR (1<<15)
-#define CC_DASH (1<<16)
-#define CC_DOT (1<<17)
-#define CC_COMMA (1<<18)
-#define CC_COLON (1<<19)
-#define CC_SLASH (1<<20)
-#define CC_SINGLE_QUOTE (1<<21)
-#define CC_DOUBLE_QUOTE (1<<22)
-#define CC_REVERSE_QUOTE (1<<23)
-#define CC_AT (1<<24)
-#define CC_EQUAL (1<<25)
-
-/* macro classes */
-#define CC_NAME (CC_ALNUM|CC_UNDERBAR)
-#define CC_CRLF (CC_CR|CC_NEWLINE)
-
-bool char_class (const char c, const unsigned int flags);
-bool string_class (const char *str, const unsigned int inclusive, const unsigned int exclusive);
-bool string_mod (char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
-
-const char *string_mod_const (const char *str,
- const unsigned int inclusive,
- const unsigned int exclusive,
- const char replace,
- struct gc_arena *gc);
-
-#ifdef CHARACTER_CLASS_DEBUG
-void character_class_debug (void);
-#endif
-
-/*
- * Verify that a pointer is correctly aligned
- */
-#ifdef VERIFY_ALIGNMENT
- void valign4 (const struct buffer *buf, const char *file, const int line);
-# define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
-#else
-# define verify_align_4(ptr)
-#endif
-
-/*
- * Very basic garbage collection, mostly for routines that return
- * char ptrs to malloced strings.
- */
-
-void x_gc_free (struct gc_arena *a);
-
-static inline void
-gc_init (struct gc_arena *a)
-{
- a->list = NULL;
-}
-
-static inline void
-gc_detach (struct gc_arena *a)
-{
- gc_init (a);
-}
-
-static inline struct gc_arena
-gc_new (void)
-{
- struct gc_arena ret;
- ret.list = NULL;
- return ret;
-}
-
-static inline void
-gc_free (struct gc_arena *a)
-{
- if (a->list)
- x_gc_free (a);
-}
-
-static inline void
-gc_reset (struct gc_arena *a)
-{
- gc_free (a);
-}
-
-/*
- * Allocate memory to hold a structure
- */
-
-void out_of_memory (void);
-
-#define ALLOC_OBJ(dptr, type) \
-{ \
- check_malloc_return ((dptr) = (type *) malloc (sizeof (type))); \
-}
-
-#define ALLOC_OBJ_CLEAR(dptr, type) \
-{ \
- ALLOC_OBJ (dptr, type); \
- memset ((dptr), 0, sizeof(type)); \
-}
-
-#define ALLOC_ARRAY(dptr, type, n) \
-{ \
- check_malloc_return ((dptr) = (type *) malloc (sizeof (type) * (n))); \
-}
-
-#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
-{ \
- (dptr) = (type *) gc_malloc (sizeof (type) * (n), false, (gc)); \
-}
-
-#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
-{ \
- ALLOC_ARRAY (dptr, type, n); \
- memset ((dptr), 0, (sizeof(type) * (n))); \
-}
-
-#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
-{ \
- (dptr) = (type *) gc_malloc (sizeof (type) * (n), true, (gc)); \
-}
-
-#define ALLOC_OBJ_GC(dptr, type, gc) \
-{ \
- (dptr) = (type *) gc_malloc (sizeof (type), false, (gc)); \
-}
-
-#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
-{ \
- (dptr) = (type *) gc_malloc (sizeof (type), true, (gc)); \
-}
-
-static inline void
-check_malloc_return (void *p)
-{
- void out_of_memory (void);
- if (!p)
- out_of_memory ();
-}
-
-#endif /* BUFFER_H */
diff --git a/openvpn/common.h b/openvpn/common.h
deleted file mode 100644
index 70efdbf..0000000
--- a/openvpn/common.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef COMMON_H
-#define COMMON_H
-
-/*
- * Statistics counters and associated printf formats.
- */
-#ifdef USE_64_BIT_COUNTERS
- typedef unsigned long long int counter_type;
-# ifdef WIN32
-# define counter_format "%I64u"
-# else
-# define counter_format "%llu"
-# endif
-#else
- typedef unsigned int counter_type;
-# define counter_format "%u"
-#endif
-
-/*
- * Time intervals
- */
-typedef int interval_t;
-
-/*
- * Used as an upper bound for timeouts.
- */
-#define BIG_TIMEOUT (60*60*24*7) /* one week (in seconds) */
-
-/*
- * Printf formats for special types
- */
-#define ptr_format "0x%08lx"
-#define time_format "%lu"
-#define fragment_header_format "0x%08x"
-
-/* these are used to cast the arguments
- * and MUST match the formats above */
-typedef unsigned long time_type;
-typedef unsigned long ptr_type;
-
-/* the --client-config-dir default file */
-#define CCD_DEFAULT "DEFAULT"
-
-/*
- * This parameter controls the TLS channel buffer size. Among
- * other things, this buffer must be large enough to contain
- * the full --push/--pull list. If you increase it, do so
- * on both server and client.
- */
-#define TLS_CHANNEL_BUF_SIZE 1024
-
-#endif
diff --git a/openvpn/event.h b/openvpn/event.h
deleted file mode 100644
index 314ef4c..0000000
--- a/openvpn/event.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef EVENT_H
-#define EVENT_H
-
-#include "win32.h"
-#include "sig.h"
-#include "perf.h"
-
-/*
- * rwflags passed to event_ctl and returned by
- * struct event_set_return.
- */
-#define EVENT_READ (1<<0)
-#define EVENT_WRITE (1<<1)
-
-/*
- * Initialization flags passed to event_set_init
- */
-#define EVENT_METHOD_US_TIMEOUT (1<<0)
-#define EVENT_METHOD_FAST (1<<1)
-
-#ifdef WIN32
-
-typedef const struct rw_handle *event_t;
-
-#define UNDEFINED_EVENT (NULL)
-
-#else
-
-typedef int event_t;
-
-#define UNDEFINED_EVENT (-1)
-
-#endif
-
-struct event_set;
-struct event_set_return;
-
-struct event_set_functions
-{
- void (*free)(struct event_set *es);
- void (*reset)(struct event_set *es);
- void (*del)(struct event_set *es, event_t event);
- void (*ctl)(struct event_set *es, event_t event, unsigned int rwflags, void *arg);
-
- /*
- * Return status for wait:
- * -1 on signal or error
- * 0 on timeout
- * length of event_set_return if at least 1 event is returned
- */
- int (*wait)(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen);
-};
-
-struct event_set_return
-{
- unsigned int rwflags;
- void *arg;
-};
-
-struct event_set
-{
- struct event_set_functions func;
-};
-
-/*
- * maxevents on input: desired max number of event_t descriptors
- * simultaneously set with event_ctl
- * maxevents on output: may be modified down, depending on limitations
- * of underlying API
- * flags: EVENT_METHOD_x flags
- */
-struct event_set *event_set_init (int *maxevents, unsigned int flags);
-
-static inline void
-event_free (struct event_set *es)
-{
- (*es->func.free)(es);
-}
-
-static inline void
-event_reset (struct event_set *es)
-{
- (*es->func.reset)(es);
-}
-
-static inline void
-event_del (struct event_set *es, event_t event)
-{
- (*es->func.del)(es, event);
-}
-
-static inline void
-event_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg)
-{
- (*es->func.ctl)(es, event, rwflags, arg);
-}
-
-static inline int
-event_wait (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
-{
- int ret;
- perf_push (PERF_IO_WAIT);
- ret = (*es->func.wait)(es, tv, out, outlen);
- perf_pop ();
- return ret;
-}
-
-static inline void
-event_set_return_init (struct event_set_return *esr)
-{
- esr->rwflags = 0;
- esr->arg = NULL;
-}
-
-#ifdef WIN32
-
-static inline void
-wait_signal (struct event_set *es, void *arg)
-{
- if (HANDLE_DEFINED (win32_signal.in.read))
- event_ctl (es, &win32_signal.in, EVENT_READ, arg);
-}
-
-#else
-
-static inline void
-wait_signal (struct event_set *es, void *arg)
-{
-}
-
-#endif
-
-#endif
diff --git a/openvpn/integer.h b/openvpn/integer.h
deleted file mode 100644
index 68cf40f..0000000
--- a/openvpn/integer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef INTEGER_H
-#define INTEGER_H
-
-#include "error.h"
-
-/*
- * min/max functions
- */
-
-static inline int
-max_int (int x, int y)
-{
- if (x > y)
- return x;
- else
- return y;
-}
-
-static inline int
-min_int (int x, int y)
-{
- if (x < y)
- return x;
- else
- return y;
-}
-
-static inline int
-constrain_int (int x, int min, int max)
-{
- if (min > max)
- return min;
- if (x < min)
- return min;
- else if (x > max)
- return max;
- else
- return x;
-}
-
-/*
- * Functions used for circular buffer index arithmetic.
- */
-
-/*
- * Return x - y on a circle of circumference mod by shortest path.
- *
- * 0 <= x < mod
- * 0 <= y < mod
- */
-static inline int
-modulo_subtract(int x, int y, int mod)
-{
- const int d1 = x - y;
- const int d2 = (x > y ? -mod : mod) + d1;
- ASSERT (0 <= x && x < mod && 0 <= y && y < mod);
- return abs(d1) > abs(d2) ? d2 : d1;
-}
-
-/*
- * Return x + y on a circle of circumference mod.
- *
- * 0 <= x < mod
- * -mod <= y <= mod
- */
-static inline int
-modulo_add(int x, int y, int mod)
-{
- int sum = x + y;
- ASSERT (0 <= x && x < mod && -mod <= y && y <= mod);
- if (sum >= mod)
- sum -= mod;
- if (sum < 0)
- sum += mod;
- return sum;
-}
-
-static inline int
-index_verify (int index, int size, const char *file, int line)
-{
- if (index < 0 || index >= size)
- msg (M_FATAL, "Assertion Failed: Array index=%d out of bounds for array size=%d in %s:%d",
- index,
- size,
- file,
- line);
- return index;
-}
-
-#endif
diff --git a/openvpn/interval.h b/openvpn/interval.h
deleted file mode 100644
index 9845066..0000000
--- a/openvpn/interval.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * The interval_ routines are designed to optimize the calling of a routine
- * (normally tls_multi_process()) which can be called less frequently
- * between triggers.
- */
-
-#ifndef INTERVAL_H
-#define INTERVAL_H
-
-#include "otime.h"
-
-#define INTERVAL_DEBUG 0
-
-/*
- * Designed to limit calls to expensive functions that need to be called
- * regularly.
- */
-
-struct interval
-{
- interval_t refresh;
- interval_t horizon;
- time_t future_trigger;
- time_t last_action;
- time_t last_test_true;
-};
-
-void interval_init (struct interval *top, int horizon, int refresh);
-
-/*
- * IF
- * last_action less than horizon seconds ago
- * OR last_test_true more than refresh seconds ago
- * OR hit future_trigger
- * THEN
- * return true
- * ELSE
- * set wakeup to the number of seconds until a true return
- * return false
- */
-
-static inline bool
-interval_test (struct interval* top)
-{
- bool trigger = false;
- const time_t local_now = now;
-
- if (top->future_trigger && local_now >= top->future_trigger)
- {
- trigger = true;
- top->future_trigger = 0;
- }
-
- if (top->last_action + top->horizon > local_now ||
- top->last_test_true + top->refresh <= local_now ||
- trigger)
- {
- top->last_test_true = local_now;
-#if INTERVAL_DEBUG
- dmsg (D_INTERVAL, "INTERVAL interval_test true");
-#endif
- return true;
- }
- else
- {
- return false;
- }
-}
-
-static inline void
-interval_schedule_wakeup (struct interval* top, interval_t *wakeup)
-{
- const time_t local_now = now;
- interval_earliest_wakeup (wakeup, top->last_test_true + top->refresh, local_now);
- interval_earliest_wakeup (wakeup, top->future_trigger, local_now);
-#if INTERVAL_DEBUG
- dmsg (D_INTERVAL, "INTERVAL interval_schedule wakeup=%d", (int)*wakeup);
-#endif
-}
-
-/*
- * In wakeup seconds, interval_test will return true once.
- */
-static inline void
-interval_future_trigger (struct interval* top, interval_t wakeup) {
- if (wakeup)
- {
-#if INTERVAL_DEBUG
- dmsg (D_INTERVAL, "INTERVAL interval_future_trigger %d", (int)wakeup);
-#endif
- top->future_trigger = now + wakeup;
- }
-}
-
-/*
- * Once an action is triggered, interval_test will remain true for
- * horizon seconds.
- */
-static inline void
-interval_action (struct interval* top)
-{
-#if INTERVAL_DEBUG
- dmsg (D_INTERVAL, "INTERVAL action");
-#endif
- top->last_action = now;
-}
-
-/*
- * Measure when n seconds beyond an event have elapsed
- */
-
-struct event_timeout
-{
- bool defined;
- interval_t n;
- time_t last; /* time of last event */
-};
-
-static inline bool
-event_timeout_defined (const struct event_timeout* et)
-{
- return et->defined;
-}
-
-static inline void
-event_timeout_clear (struct event_timeout* et)
-{
- et->defined = false;
- et->n = 0;
- et->last = 0;
-}
-
-static inline struct event_timeout
-event_timeout_clear_ret ()
-{
- struct event_timeout ret;
- event_timeout_clear (&ret);
- return ret;
-}
-
-static inline void
-event_timeout_init (struct event_timeout* et, interval_t n, const time_t local_now)
-{
- et->defined = true;
- et->n = (n >= 0) ? n : 0;
- et->last = local_now;
-}
-
-static inline void
-event_timeout_reset (struct event_timeout* et)
-{
- if (et->defined)
- et->last = now;
-}
-
-/*
- * This is the principal function for testing and triggering recurring
- * timers and will return true on a timer signal event.
- * If et_const_retry == ETT_DEFAULT and a signal occurs,
- * the function will return true and *et will be armed for the
- * next event. If et_const_retry >= 0 and a signal occurs,
- * *et will not be touched, but *tv will be set to
- * minimum (*tv, et_const_retry) for a future re-test,
- * and the function will return true.
- */
-
-#define ETT_DEFAULT (-1)
-
-bool event_timeout_trigger (struct event_timeout *et,
- struct timeval *tv,
- const int et_const_retry);
-
-/*
- * Measure time intervals in microseconds
- */
-
-#define USEC_TIMER_MAX 60 /* maximum interval size in seconds */
-
-#define USEC_TIMER_MAX_USEC (USEC_TIMER_MAX * 1000000)
-
-struct usec_timer {
- struct timeval start;
- struct timeval end;
-};
-
-#ifdef HAVE_GETTIMEOFDAY
-
-static inline void
-usec_timer_start (struct usec_timer *obj)
-{
- CLEAR (*obj);
- gettimeofday (&obj->start, NULL);
-}
-
-static inline void
-usec_timer_end (struct usec_timer *obj)
-{
- gettimeofday (&obj->end, NULL);
-}
-
-#endif /* HAVE_GETTIMEOFDAY */
-
-static inline bool
-usec_timer_interval_defined (struct usec_timer *obj)
-{
- return obj->start.tv_sec && obj->end.tv_sec;
-}
-
-static inline int
-usec_timer_interval (struct usec_timer *obj)
-{
- return tv_subtract (&obj->end, &obj->start, USEC_TIMER_MAX);
-}
-
-#endif /* INTERVAL_H */
diff --git a/openvpn/misc.h b/openvpn/misc.h
deleted file mode 100644
index 00ddae8..0000000
--- a/openvpn/misc.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef MISC_H
-#define MISC_H
-
-#include "basic.h"
-#include "common.h"
-#include "integer.h"
-#include "buffer.h"
-
-/* socket descriptor passed by inetd/xinetd server to us */
-#define INETD_SOCKET_DESCRIPTOR 0
-
-/* forward declarations */
-struct plugin_list;
-
-/*
- * Handle environmental variable lists
- */
-
-struct env_item {
- char *string;
- struct env_item *next;
-};
-
-struct env_set {
- struct gc_arena *gc;
- struct env_item *list;
-};
-
-/* Get/Set UID of process */
-
-struct user_state {
-#if defined(HAVE_GETPWNAM) && defined(HAVE_SETUID)
- const char *username;
- struct passwd *pw;
-#else
- int dummy;
-#endif
-};
-
-bool get_user (const char *username, struct user_state *state);
-void set_user (const struct user_state *state);
-
-/* Get/Set GID of process */
-
-struct group_state {
-#if defined(HAVE_GETGRNAM) && defined(HAVE_SETGID)
- const char *groupname;
- struct group *gr;
-#else
- int dummy;
-#endif
-};
-
-bool get_group (const char *groupname, struct group_state *state);
-void set_group (const struct group_state *state);
-
-void set_nice (int niceval);
-void do_chroot (const char *path);
-
-void run_up_down (const char *command,
- const struct plugin_list *plugins,
- int plugin_type,
- const char *arg,
- int tun_mtu,
- int link_mtu,
- const char *ifconfig_local,
- const char* ifconfig_remote,
- const char *context,
- const char *signal_text,
- const char *script_type,
- struct env_set *es);
-
-/* workspace for get_pid_file/write_pid */
-struct pid_state {
- FILE *fp;
- const char *filename;
-};
-
-void get_pid_file (const char* filename, struct pid_state *state);
-void write_pid (const struct pid_state *state);
-unsigned int openvpn_getpid (void);
-
-void do_mlockall (bool print_msg); /* Disable paging */
-
-#ifndef HAVE_DAEMON
-int daemon (int nochdir, int noclose);
-#endif
-
-/* check file protections */
-void warn_if_group_others_accessible(const char* filename);
-
-/* system flags */
-#define S_SCRIPT (1<<0)
-#define S_FATAL (1<<1)
-
-/* wrapper around the system() call. */
-int openvpn_system (const char *command, const struct env_set *es, unsigned int flags);
-
-/* interpret the status code returned by system() */
-bool system_ok(int);
-int system_executed (int stat);
-const char *system_error_message (int, struct gc_arena *gc);
-
-/* run system() with error check, return true if success,
- false if error, exit if error and fatal==true */
-bool system_check (const char *command, const struct env_set *es, unsigned int flags, const char *error_message);
-
-#ifdef HAVE_STRERROR
-/* a thread-safe version of strerror */
-const char* strerror_ts (int errnum, struct gc_arena *gc);
-#endif
-
-/* Set standard file descriptors to /dev/null */
-void set_std_files_to_null (bool stdin_only);
-
-/* Wrapper for chdir library function */
-int openvpn_chdir (const char* dir);
-
-/* dup inetd/xinetd socket descriptor and save */
-extern int inetd_socket_descriptor;
-void save_inetd_socket_descriptor (void);
-
-/* init random() function, only used as source for weak random numbers, when !USE_CRYPTO */
-void init_random_seed(void);
-
-/* set/delete environmental variable */
-void setenv_str_ex (struct env_set *es,
- const char *name,
- const char *value,
- const unsigned int name_include,
- const unsigned int name_exclude,
- const char name_replace,
- const unsigned int value_include,
- const unsigned int value_exclude,
- const char value_replace);
-
-void setenv_counter (struct env_set *es, const char *name, counter_type value);
-void setenv_int (struct env_set *es, const char *name, int value);
-void setenv_str (struct env_set *es, const char *name, const char *value);
-void setenv_del (struct env_set *es, const char *name);
-
-/* struct env_set functions */
-
-struct env_set *env_set_create (struct gc_arena *gc);
-bool env_set_del (struct env_set *es, const char *str);
-void env_set_add (struct env_set *es, const char *str);
-
-void env_set_print (int msglevel, const struct env_set *es);
-
-void env_set_inherit (struct env_set *es, const struct env_set *src);
-
-void env_set_add_to_environment (const struct env_set *es);
-void env_set_remove_from_environment (const struct env_set *es);
-
-/* Make arrays of strings */
-
-const char **make_env_array (const struct env_set *es, struct gc_arena *gc);
-const char **make_arg_array (const char *first, const char *parms, struct gc_arena *gc);
-
-/* convert netmasks for iproute2 */
-int count_netmask_bits(const char *);
-unsigned int count_bits(unsigned int );
-
-/* go to sleep for n milliseconds */
-void sleep_milliseconds (unsigned int n);
-
-/* go to sleep indefinitely */
-void sleep_until_signal (void);
-
-/* an analogue to the random() function, but use OpenSSL functions if available */
-#ifdef USE_CRYPTO
-long int get_random(void);
-#else
-#define get_random random
-#endif
-
-/* return true if filename can be opened for read */
-bool test_file (const char *filename);
-
-/* create a temporary filename in directory */
-const char *create_temp_filename (const char *directory, struct gc_arena *gc);
-
-/* put a directory and filename together */
-const char *gen_path (const char *directory, const char *filename, struct gc_arena *gc);
-
-/* delete a file, return true if succeeded */
-bool delete_file (const char *filename);
-
-/* return the next largest power of 2 */
-unsigned int adjust_power_of_2 (unsigned int u);
-
-/*
- * Get and store a username/password
- */
-
-struct user_pass
-{
- bool defined;
- bool nocache;
-
-/* max length of username/password */
-# define USER_PASS_LEN 128
- char username[USER_PASS_LEN];
- char password[USER_PASS_LEN];
-};
-
-bool get_console_input (const char *prompt, const bool echo, char *input, const int capacity);
-
-#define GET_USER_PASS_MANAGEMENT (1<<0)
-#define GET_USER_PASS_SENSITIVE (1<<1)
-
-void get_user_pass (struct user_pass *up,
- const char *auth_file,
- const bool password_only,
- const char *prefix,
- const unsigned int flags);
-
-void purge_user_pass (struct user_pass *up, const bool force);
-
-/*
- * Process string received by untrusted peer before
- * printing to console or log file.
- * Assumes that string has been null terminated.
- */
-const char *safe_print (const char *str, struct gc_arena *gc);
-
-/*
- * A sleep function that services the management layer for n
- * seconds rather than doing nothing.
- */
-void openvpn_sleep (const int n);
-
-#endif
diff --git a/openvpn/mtu.h b/openvpn/mtu.h
deleted file mode 100644
index 3c53a26..0000000
--- a/openvpn/mtu.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef MTU_H
-#define MTU_H
-
-#include "buffer.h"
-
-/*
- *
- * Packet maninipulation routes such as encrypt, decrypt, compress, decompress
- * are passed a frame buffer that looks like this:
- *
- * [extra_frame bytes] [mtu bytes] [extra_frame_bytes] [compression overflow bytes]
- * ^
- * Pointer passed to function points here so that routine
- * can make use of extra_frame bytes before pointer
- * to prepend headers, etc.
- *
- * extra_frame bytes is large enough for all encryption related overhead.
- *
- * mtu bytes will be the MTU size set in the ifconfig statement that configures
- * the TUN or TAP device such as:
- *
- * ifconfig $1 10.1.0.2 pointopoint 10.1.0.1 mtu 1450
- *
- * Compression overflow bytes is the worst-case size expansion that would be
- * expected if we tried to compress mtu + extra_frame bytes of uncompressible data.
- */
-
-/*
- * Standard ethernet MTU
- */
-#define ETHERNET_MTU 1500
-
-/*
- * It is a fatal error if mtu is less than
- * this value for tun device.
- */
-#define TUN_MTU_MIN 100
-
-/*
- * Default MTU of network over which tunnel data will pass by TCP/UDP.
- */
-#define LINK_MTU_DEFAULT 1500
-
-/*
- * Default MTU of tunnel device.
- */
-#define TUN_MTU_DEFAULT 1500
-
-/*
- * MTU Defaults for TAP devices
- */
-#define TAP_MTU_EXTRA_DEFAULT 32
-
-/*
- * Default MSSFIX value, used for reducing TCP MTU size
- */
-#define MSSFIX_DEFAULT 1450
-
-/*
- * Alignment of payload data such as IP packet or
- * ethernet frame.
- */
-#define PAYLOAD_ALIGN 4
-
-struct frame {
- /*
- * Maximum datagram size to be sent over the tunnel TCP/UDP channel.
- */
- int link_mtu;
- int link_mtu_dynamic;
-
- /*
- * How many extra bytes might each subsystem (crypto, TLS, or, compression)
- * add to frame in worst case?
- *
- * mtu + extra_frame = MTU of TCP/UDP transport
- */
- int extra_frame;
-
- /*
- * Worst case size added to internal buffer due to functions
- * such as compression which can potentially expand the size of uncompressible
- * data.
- */
- int extra_buffer;
-
- /*
- * Max number of bytes in excess of tun mtu size that we might read
- * or write from TUN/TAP device.
- */
- int extra_tun;
-
- /*
- * Max number of bytes in excess of link mtu size that we might read
- * or write from UDP/TCP link.
- */
- int extra_link;
-
- /*
- * Alignment control
- */
-# define FRAME_HEADROOM_MARKER_DECRYPT (1<<0)
-# define FRAME_HEADROOM_MARKER_FRAGMENT (1<<1)
-# define FRAME_HEADROOM_MARKER_READ_LINK (1<<2)
-# define FRAME_HEADROOM_MARKER_READ_STREAM (1<<3)
- unsigned int align_flags;
- int align_adjust;
-};
-
-/* Routines which read struct frame should use the macros below */
-
-/*
- * Overhead added to packet payload due to encapsulation
- */
-#define EXTRA_FRAME(f) ((f)->extra_frame)
-
-/*
- * Delta between tun payload size and final TCP/UDP datagram size
- * (not including extra_link additions)
- */
-#define TUN_LINK_DELTA(f) ((f)->extra_frame + (f)->extra_tun)
-
-/*
- * This is the size to "ifconfig" the tun or tap device.
- */
-#define TUN_MTU_SIZE(f) ((f)->link_mtu - TUN_LINK_DELTA(f))
-#define TUN_MTU_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - TUN_LINK_DELTA(f))
-
-/*
- * This is the maximum packet size that we need to be able to
- * read from or write to a tun or tap device. For example,
- * a tap device ifconfiged to an MTU of 1200 might actually want
- * to return a packet size of 1214 on a read().
- */
-#define PAYLOAD_SIZE(f) ((f)->link_mtu - (f)->extra_frame)
-#define PAYLOAD_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - (f)->extra_frame)
-
-/*
- * Max size of a payload packet after encryption, compression, etc.
- * overhead is added.
- */
-#define EXPANDED_SIZE(f) ((f)->link_mtu)
-#define EXPANDED_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic)
-#define EXPANDED_SIZE_MIN(f) (TUN_MTU_MIN + TUN_LINK_DELTA(f))
-
-/*
- * These values are used as maximum size constraints
- * on read() or write() from TUN/TAP device or TCP/UDP port.
- */
-#define MAX_RW_SIZE_TUN(f) (PAYLOAD_SIZE(f))
-#define MAX_RW_SIZE_LINK(f) (EXPANDED_SIZE(f) + (f)->extra_link)
-
-/*
- * Control buffer headroom allocations to allow for efficient prepending.
- */
-#define FRAME_HEADROOM_BASE(f) (TUN_LINK_DELTA(f) + (f)->extra_buffer + (f)->extra_link)
-#define FRAME_HEADROOM(f) frame_headroom(f, 0)
-#define FRAME_HEADROOM_ADJ(f, fm) frame_headroom(f, fm)
-
-/*
- * Max size of a buffer used to build a packet for output to
- * the TCP/UDP port.
- */
-#define BUF_SIZE(f) (TUN_MTU_SIZE(f) + FRAME_HEADROOM_BASE(f) * 2)
-
-/*
- * Function prototypes.
- */
-
-void frame_finalize (struct frame *frame,
- bool link_mtu_defined,
- int link_mtu,
- bool tun_mtu_defined,
- int tun_mtu);
-
-void frame_subtract_extra (struct frame *frame, const struct frame *src);
-
-void frame_print (const struct frame *frame,
- int level,
- const char *prefix);
-
-void set_mtu_discover_type (int sd, int mtu_type);
-int translate_mtu_discover_type_name (const char *name);
-
-/*
- * frame_set_mtu_dynamic and flags
- */
-
-#define SET_MTU_TUN (1<<0) /* use tun/tap rather than link sizing */
-#define SET_MTU_UPPER_BOUND (1<<1) /* only decrease dynamic MTU */
-
-void frame_set_mtu_dynamic (struct frame *frame, int mtu, unsigned int flags);
-
-/*
- * allocate a buffer for socket or tun layer
- */
-void alloc_buf_sock_tun (struct buffer *buf,
- const struct frame *frame,
- const bool tuntap_buffer,
- const unsigned int align_mask);
-
-/*
- * EXTENDED_SOCKET_ERROR_CAPABILITY functions -- print extra error info
- * on socket errors, such as PMTU size. As of 2003.05.11, only works
- * on Linux 2.4+.
- */
-
-#if EXTENDED_SOCKET_ERROR_CAPABILITY
-
-void set_sock_extended_error_passing (int sd);
-const char *format_extended_socket_error (int fd, int *mtu, struct gc_arena *gc);
-
-#endif
-
-/*
- * Calculate a starting offset into a buffer object, dealing with
- * headroom and alignment issues.
- */
-static inline int
-frame_headroom (const struct frame *f, const unsigned int flag_mask)
-{
- const int offset = FRAME_HEADROOM_BASE (f);
- const int adjust = (flag_mask & f->align_flags) ? f->align_adjust : 0;
- const int delta = ((PAYLOAD_ALIGN << 24) - (offset + adjust)) & (PAYLOAD_ALIGN - 1);
- return offset + delta;
-}
-
-/*
- * frame member adjustment functions
- */
-
-static inline void
-frame_add_to_extra_frame (struct frame *frame, const int increment)
-{
- frame->extra_frame += increment;
-}
-
-static inline void
-frame_add_to_extra_tun (struct frame *frame, const int increment)
-{
- frame->extra_tun += increment;
-}
-
-static inline void
-frame_add_to_extra_link (struct frame *frame, const int increment)
-{
- frame->extra_link += increment;
-}
-
-static inline void
-frame_add_to_extra_buffer (struct frame *frame, const int increment)
-{
- frame->extra_buffer += increment;
-}
-
-static inline void
-frame_add_to_align_adjust (struct frame *frame, const int increment)
-{
- frame->align_adjust += increment;
-}
-
-static inline void
-frame_align_to_extra_frame (struct frame *frame)
-{
- frame->align_adjust = frame->extra_frame + frame->extra_link;
-}
-
-static inline void
-frame_or_align_flags (struct frame *frame, const unsigned int flag_mask)
-{
- frame->align_flags |= flag_mask;
-}
-
-static inline bool
-frame_defined (const struct frame *frame)
-{
- return frame->link_mtu > 0;
-}
-
-#endif
diff --git a/openvpn/otime.h b/openvpn/otime.h
deleted file mode 100644
index 974d0af..0000000
--- a/openvpn/otime.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef OTIME_H
-#define OTIME_H
-
-#include "common.h"
-#include "integer.h"
-#include "buffer.h"
-#include "thread.h"
-
-struct frequency_limit
-{
- int max;
- int per;
- int n;
- time_t reset;
-};
-
-struct frequency_limit *frequency_limit_init (int max, int per);
-void frequency_limit_free (struct frequency_limit *f);
-bool frequency_limit_event_allowed (struct frequency_limit *f);
-
-#ifdef WIN32
-int gettimeofday(struct timeval *tv, void *tz);
-#endif
-
-/* format a time_t as ascii, or use current time if 0 */
-const char* time_string (time_t t, int usec, bool show_usec, struct gc_arena *gc);
-
-/* struct timeval functions */
-
-const char *tv_string (const struct timeval *tv, struct gc_arena *gc);
-const char *tv_string_abs (const struct timeval *tv, struct gc_arena *gc);
-
-extern volatile time_t now; /* updated frequently to time(NULL) */
-
-static inline void
-update_time (void)
-{
- const time_t real_time = time (NULL);
- if (real_time != now)
- now = real_time;
-}
-
-static inline void
-tv_clear (struct timeval *tv)
-{
- tv->tv_sec = 0;
- tv->tv_usec = 0;
-}
-
-static inline bool
-tv_defined (const struct timeval *tv)
-{
- return tv->tv_sec > 0 && tv->tv_usec > 0;
-}
-
-/* return tv1 - tv2 in usec, constrained by max_seconds */
-static inline int
-tv_subtract (const struct timeval *tv1, const struct timeval *tv2, const unsigned int max_seconds)
-{
- const int max_usec = max_seconds * 1000000;
- const int sec_diff = tv1->tv_sec - tv2->tv_sec;
-
- if (sec_diff > ((int)max_seconds + 10))
- return max_usec;
- else if (sec_diff < -((int)max_seconds + 10))
- return -max_usec;
- return constrain_int (sec_diff * 1000000 + (tv1->tv_usec - tv2->tv_usec), -max_usec, max_usec);
-}
-
-static inline void
-tv_add (struct timeval *dest, const struct timeval *src)
-{
- dest->tv_sec += src->tv_sec;
- dest->tv_usec += src->tv_usec;
- dest->tv_sec += (dest->tv_usec >> 20);
- dest->tv_usec &= 0x000FFFFF;
- if (dest->tv_usec >= 1000000)
- {
- dest->tv_usec -= 1000000;
- dest->tv_sec += 1;
- }
-}
-
-static inline bool
-tv_lt (const struct timeval *t1, const struct timeval *t2)
-{
- if (t1->tv_sec < t2->tv_sec)
- return true;
- else if (t1->tv_sec > t2->tv_sec)
- return false;
- else
- return t1->tv_usec < t2->tv_usec;
-}
-
-static inline bool
-tv_le (const struct timeval *t1, const struct timeval *t2)
-{
- if (t1->tv_sec < t2->tv_sec)
- return true;
- else if (t1->tv_sec > t2->tv_sec)
- return false;
- else
- return t1->tv_usec <= t2->tv_usec;
-}
-
-static inline bool
-tv_ge (const struct timeval *t1, const struct timeval *t2)
-{
- if (t1->tv_sec > t2->tv_sec)
- return true;
- else if (t1->tv_sec < t2->tv_sec)
- return false;
- else
- return t1->tv_usec >= t2->tv_usec;
-}
-
-static inline bool
-tv_gt (const struct timeval *t1, const struct timeval *t2)
-{
- if (t1->tv_sec > t2->tv_sec)
- return true;
- else if (t1->tv_sec < t2->tv_sec)
- return false;
- else
- return t1->tv_usec > t2->tv_usec;
-}
-
-static inline bool
-tv_eq (const struct timeval *t1, const struct timeval *t2)
-{
- return t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec;
-}
-
-static inline void
-tv_delta (struct timeval *dest, const struct timeval *t1, const struct timeval *t2)
-{
- int sec = t2->tv_sec - t1->tv_sec;
- int usec = t2->tv_usec - t1->tv_usec;
-
- while (usec < 0)
- {
- usec += 1000000;
- sec -= 1;
- }
-
- if (sec < 0)
- usec = sec = 0;
-
- dest->tv_sec = sec;
- dest->tv_usec = usec;
-}
-
-#define TV_WITHIN_SIGMA_MAX_SEC 600
-#define TV_WITHIN_SIGMA_MAX_USEC (TV_WITHIN_SIGMA_MAX_SEC * 1000000)
-
-/*
- * Is t1 and t2 within sigma microseconds of each other?
- */
-static inline bool
-tv_within_sigma (const struct timeval *t1, const struct timeval *t2, unsigned int sigma)
-{
- const int delta = tv_subtract (t1, t2, TV_WITHIN_SIGMA_MAX_SEC); /* sigma should be less than 10 minutes */
- return -(int)sigma <= delta && delta <= (int)sigma;
-}
-
-/*
- * Used to determine in how many seconds we should be
- * called again.
- */
-static inline void
-interval_earliest_wakeup (interval_t *wakeup, time_t at, time_t current) {
- if (at > current)
- {
- const interval_t delta = (interval_t) (at - current);
- if (delta < *wakeup)
- *wakeup = delta;
- if (*wakeup < 0)
- *wakeup = 0;
- }
-}
-
-#endif
diff --git a/openvpn/perf.h b/openvpn/perf.h
deleted file mode 100644
index 6080886..0000000
--- a/openvpn/perf.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * The interval_ routines are designed to optimize the calling of a routine
- * (normally tls_multi_process()) which can be called less frequently
- * between triggers.
- */
-
-#ifndef PERF_H
-#define PERF_H
-
-/*#define ENABLE_PERFORMANCE_METRICS*/
-
-/*
- * Metrics
- */
-#define PERF_BIO_READ_PLAINTEXT 0
-#define PERF_BIO_WRITE_PLAINTEXT 1
-#define PERF_BIO_READ_CIPHERTEXT 2
-#define PERF_BIO_WRITE_CIPHERTEXT 3
-#define PERF_TLS_MULTI_PROCESS 4
-#define PERF_IO_WAIT 5
-#define PERF_EVENT_LOOP 6
-#define PERF_MULTI_CREATE_INSTANCE 7
-#define PERF_MULTI_CLOSE_INSTANCE 8
-#define PERF_MULTI_SHOW_STATS 9
-#define PERF_MULTI_BCAST 10
-#define PERF_MULTI_MCAST 11
-#define PERF_SCRIPT 12
-#define PERF_READ_IN_LINK 13
-#define PERF_PROC_IN_LINK 14
-#define PERF_READ_IN_TUN 15
-#define PERF_PROC_IN_TUN 16
-#define PERF_PROC_OUT_LINK 17
-#define PERF_PROC_OUT_TUN 18
-#define PERF_PROC_OUT_TUN_MTCP 19
-#define PERF_N 20
-
-#ifdef ENABLE_PERFORMANCE_METRICS
-
-#include "basic.h"
-
-/*
- * Stack size
- */
-#define STACK_N 64
-
-void perf_push (int type);
-void perf_pop (void);
-void perf_output_results (void);
-
-#else
-
-static inline void perf_push (int type) {}
-static inline void perf_pop (void) {}
-static inline void perf_output_results (void) {}
-
-#endif
-
-#endif
diff --git a/openvpn/proto.h b/openvpn/proto.h
deleted file mode 100644
index 440d3d1..0000000
--- a/openvpn/proto.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PROTO_H
-#define PROTO_H
-
-#include "buffer.h"
-
-/*
- * Tunnel types
- */
-#define DEV_TYPE_UNDEF 0
-#define DEV_TYPE_NULL 1
-#define DEV_TYPE_TUN 2 /* point-to-point IP tunnel */
-#define DEV_TYPE_TAP 3 /* ethernet (802.3) tunnel */
-
-/*
- * IP and Ethernet protocol structs. For portability,
- * OpenVPN needs its own definitions of these structs, and
- * names have been adjusted to avoid collisions with
- * native structs.
- */
-
-#define OPENVPN_ETH_ALEN 6 /* ethernet address length */
-struct openvpn_ethhdr
-{
- uint8_t dest[OPENVPN_ETH_ALEN]; /* destination ethernet addr */
- uint8_t source[OPENVPN_ETH_ALEN]; /* source ethernet addr */
-
-# define OPENVPN_ETH_P_IPV4 0x0800 /* IPv4 protocol */
-# define OPENVPN_ETH_P_IPV6 0x86DD /* IPv6 protocol */
-# define OPENVPN_ETH_P_ARP 0x0806 /* ARP protocol */
- uint16_t proto; /* packet type ID field */
-};
-
-struct openvpn_iphdr {
-# define OPENVPN_IPH_GET_VER(v) (((v) >> 4) & 0x0F)
-# define OPENVPN_IPH_GET_LEN(v) (((v) & 0x0F) << 2)
- uint8_t version_len;
-
- uint8_t tos;
- uint16_t tot_len;
- uint16_t id;
-
-# define OPENVPN_IP_OFFMASK 0x1fff
- uint16_t frag_off;
-
- uint8_t ttl;
-
-# define OPENVPN_IPPROTO_IGMP 2 /* IGMP protocol */
-# define OPENVPN_IPPROTO_TCP 6 /* TCP protocol */
-# define OPENVPN_IPPROTO_UDP 17 /* UDP protocol */
- uint8_t protocol;
-
- uint16_t check;
- uint32_t saddr;
- uint32_t daddr;
- /*The options start here. */
-};
-
-/*
- * UDP header
- */
-struct openvpn_udphdr {
- uint16_t source;
- uint16_t dest;
- uint16_t len;
- uint16_t check;
-};
-
-/*
- * TCP header, per RFC 793.
- */
-struct openvpn_tcphdr {
- uint16_t source; /* source port */
- uint16_t dest; /* destination port */
- uint32_t seq; /* sequence number */
- uint32_t ack_seq; /* acknowledgement number */
-
-# define OPENVPN_TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2)
- uint8_t doff_res;
-
-# define OPENVPN_TCPH_FIN_MASK (1<<0)
-# define OPENVPN_TCPH_SYN_MASK (1<<1)
-# define OPENVPN_TCPH_RST_MASK (1<<2)
-# define OPENVPN_TCPH_PSH_MASK (1<<3)
-# define OPENVPN_TCPH_ACK_MASK (1<<4)
-# define OPENVPN_TCPH_URG_MASK (1<<5)
-# define OPENVPN_TCPH_ECE_MASK (1<<6)
-# define OPENVPN_TCPH_CWR_MASK (1<<7)
- uint8_t flags;
-
- uint16_t window;
- uint16_t check;
- uint16_t urg_ptr;
-};
-
-#define OPENVPN_TCPOPT_EOL 0
-#define OPENVPN_TCPOPT_NOP 1
-#define OPENVPN_TCPOPT_MAXSEG 2
-#define OPENVPN_TCPOLEN_MAXSEG 4
-
-/*
- * The following macro is used to update an
- * internet checksum. "acc" is a 32-bit
- * accumulation of all the changes to the
- * checksum (adding in old 16-bit words and
- * subtracting out new words), and "cksum"
- * is the checksum value to be updated.
- */
-#define ADJUST_CHECKSUM(acc, cksum) { \
- (acc) += (cksum); \
- if ((acc) < 0) { \
- (acc) = -(acc); \
- (acc) = ((acc) >> 16) + ((acc) & 0xffff); \
- (acc) += (acc) >> 16; \
- (cksum) = (uint16_t) ~(acc); \
- } else { \
- (acc) = ((acc) >> 16) + ((acc) & 0xffff); \
- (acc) += (acc) >> 16; \
- (cksum) = (uint16_t) (acc); \
- } \
-}
-
-/*
- * We are in a "liberal" position with respect to MSS,
- * i.e. we assume that MSS can be calculated from MTU
- * by subtracting out only the IP and TCP header sizes
- * without options.
- *
- * (RFC 879, section 7).
- */
-#define MTU_TO_MSS(mtu) (mtu - sizeof(struct openvpn_iphdr) \
- - sizeof(struct openvpn_tcphdr))
-
-/*
- * If raw tunnel packet is IPv4, return true and increment
- * buffer offset to start of IP header.
- */
-bool is_ipv4 (int tunnel_type, struct buffer *buf);
-
-#endif
diff --git a/openvpn/sig.h b/openvpn/sig.h
deleted file mode 100644
index dd17c40..0000000
--- a/openvpn/sig.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef SIG_H
-#define SIG_H
-
-#include "status.h"
-#include "win32.h"
-
-/*
- * Signal information, including signal code
- * and descriptive text.
- */
-struct signal_info
-{
- volatile int signal_received;
- volatile bool hard;
- const char *signal_text;
-};
-
-#define IS_SIG(c) ((c)->sig->signal_received)
-
-struct context;
-
-extern struct signal_info siginfo_static;
-
-int parse_signal (const char *signame);
-const char *signal_name (const int sig, const bool upper);
-const char *signal_description (const int signum, const char *sigtext);
-void throw_signal (const int signum);
-
-void pre_init_signal_catch (void);
-void post_init_signal_catch (void);
-
-void print_signal (const struct signal_info *si, const char *title, int msglevel);
-void print_status (const struct context *c, struct status_output *so);
-
-void remap_signal (struct context *c);
-
-void signal_restart_status (const struct signal_info *si);
-
-bool process_signal (struct context *c);
-
-#ifdef ENABLE_OCC
-void process_explicit_exit_notification_timer_wakeup (struct context *c);
-#endif
-
-#ifdef WIN32
-
-static inline void
-get_signal (volatile int *sig)
-{
- *sig = win32_signal_get (&win32_signal);
-}
-
-static inline void
-halt_non_edge_triggered_signals (void)
-{
- win32_signal_close (&win32_signal);
-}
-
-#else
-
-static inline void
-get_signal (volatile int *sig)
-{
- const int i = siginfo_static.signal_received;
- if (i)
- *sig = i;
-}
-
-static inline void
-halt_non_edge_triggered_signals (void)
-{
-}
-
-#endif
-
-#endif
diff --git a/openvpn/status.h b/openvpn/status.h
deleted file mode 100644
index be3c3f3..0000000
--- a/openvpn/status.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef STATUS_H
-#define STATUS_H
-
-#include "interval.h"
-
-/*
- * virtual function interface for status output
- */
-struct virtual_output {
- void *arg;
- unsigned int flags_default;
- void (*func) (void *arg, const unsigned int flags, const char *str);
-};
-
-static inline void
-virtual_output_print (const struct virtual_output *vo, const unsigned int flags, const char *str)
-{
- (*vo->func) (vo->arg, flags, str);
-}
-
-/*
- * printf-style interface for inputting/outputting status info
- */
-
-struct status_output
-{
-# define STATUS_OUTPUT_READ (1<<0)
-# define STATUS_OUTPUT_WRITE (1<<1)
- unsigned int flags;
-
- char *filename;
- int fd;
- int msglevel;
- const struct virtual_output *vout;
-
- struct buffer read_buf;
-
- struct event_timeout et;
-
- bool errors;
-};
-
-struct status_output *status_open (const char *filename,
- const int refresh_freq,
- const int msglevel,
- const struct virtual_output *vout,
- const unsigned int flags);
-
-bool status_trigger_tv (struct status_output *so, struct timeval *tv);
-bool status_trigger (struct status_output *so);
-void status_reset (struct status_output *so);
-void status_flush (struct status_output *so);
-bool status_close (struct status_output *so);
-void status_printf (struct status_output *so, const char *format, ...)
-#ifdef __GNUC__
- __attribute__ ((format (printf, 2, 3)))
-#endif
- ;
-
-bool status_read (struct status_output *so, struct buffer *buf);
-
-static inline unsigned int
-status_rw_flags (const struct status_output *so)
-{
- if (so)
- return so->flags;
- else
- return 0;
-}
-
-#endif
diff --git a/openvpn/thread.h b/openvpn/thread.h
deleted file mode 100644
index ecc3616..0000000
--- a/openvpn/thread.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef THREAD_H
-#define THREAD_H
-
-#include "basic.h"
-#include "common.h"
-
-/*
- * OpenVPN static mutex locks, by mutex type
- */
-#define L_UNUSED 0
-#define L_CTIME 1
-#define L_INET_NTOA 2
-#define L_MSG 3
-#define L_STRERR 4
-#define L_PUTENV 5
-#define L_PRNG 6
-#define L_GETTIMEOFDAY 7
-#define L_ENV_SET 8
-#define L_SYSTEM 9
-#define L_CREATE_TEMP 10
-#define L_PLUGIN 11
-#define N_MUTEXES 12
-
-#ifdef USE_PTHREAD
-
-#define MAX_THREADS 50
-
-#define CACHE_LINE_SIZE 128
-
-/*
- * Improve SMP performance by making sure that each
- * mutex resides in its own cache line.
- */
-struct sparse_mutex
-{
- pthread_mutex_t mutex;
- uint8_t dummy [CACHE_LINE_SIZE - sizeof (pthread_mutex_t)];
-};
-
-typedef pthread_t openvpn_thread_t;
-
-extern bool pthread_initialized;
-
-extern struct sparse_mutex mutex_array[N_MUTEXES];
-
-#define MUTEX_DEFINE(lock) pthread_mutex_t lock
-#define MUTEX_PTR_DEFINE(lock) pthread_mutex_t *lock
-
-static inline bool
-openvpn_thread_enabled (void)
-{
- return pthread_initialized;
-}
-
-static inline openvpn_thread_t
-openvpn_thread_self (void)
-{
- return pthread_initialized ? pthread_self() : 0;
-}
-
-static inline void
-mutex_init (pthread_mutex_t *mutex)
-{
- if (mutex)
- pthread_mutex_init (mutex, NULL);
-}
-
-static inline void
-mutex_destroy (pthread_mutex_t *mutex)
-{
- if (mutex)
- pthread_mutex_destroy (mutex);
-}
-
-static inline void
-mutex_lock (pthread_mutex_t *mutex)
-{
- if (pthread_initialized && mutex)
- pthread_mutex_lock (mutex);
-}
-
-static inline bool
-mutex_trylock (pthread_mutex_t *mutex)
-{
- if (pthread_initialized && mutex)
- return pthread_mutex_trylock (mutex) == 0;
- else
- return true;
-}
-
-static inline void
-mutex_unlock (pthread_mutex_t *mutex)
-{
- if (pthread_initialized && mutex)
- {
- pthread_mutex_unlock (mutex);
-#if 1 /* JYFIXME: if race conditions exist, make them more likely to occur */
- sleep (0);
-#endif
- }
-}
-
-static inline void
-mutex_cycle (pthread_mutex_t *mutex)
-{
- if (pthread_initialized && mutex)
- {
- pthread_mutex_unlock (mutex);
- sleep (0);
- pthread_mutex_lock (mutex);
- }
-}
-
-static inline void
-mutex_lock_static (int type)
-{
- mutex_lock (&mutex_array[type].mutex);
-}
-
-static inline void
-mutex_unlock_static (int type)
-{
- mutex_unlock (&mutex_array[type].mutex);
-}
-
-static inline void
-mutex_cycle_static (int type)
-{
- mutex_cycle (&mutex_array[type].mutex);
-}
-
-void openvpn_thread_init (void);
-void openvpn_thread_cleanup (void);
-
-openvpn_thread_t openvpn_thread_create (void *(*start_routine) (void *), void* arg);
-void openvpn_thread_join (openvpn_thread_t id);
-
-#else /* USE_PTHREAD */
-
-typedef int openvpn_thread_t;
-
-#if defined(_MSC_VER) || PEDANTIC
-
-#define MUTEX_DEFINE(lock) int eat_semicolon
-#define MUTEX_PTR_DEFINE(lock) int eat_semicolon
-
-#else
-
-#define MUTEX_DEFINE(lock)
-#define MUTEX_PTR_DEFINE(lock)
-
-#endif
-
-#define mutex_init(m)
-#define mutex_destroy(m)
-#define mutex_lock(m)
-#define mutex_trylock(m) (true)
-#define mutex_unlock(m)
-#define mutex_cycle(m)
-
-static inline bool
-openvpn_thread_enabled (void)
-{
- return false;
-}
-
-static inline openvpn_thread_t
-openvpn_thread_self (void)
-{
- return 0;
-}
-
-static inline void
-openvpn_thread_init (void)
-{
-}
-
-static inline void
-openvpn_thread_cleanup (void)
-{
-}
-
-static inline openvpn_thread_t
-openvpn_thread_create (void *(*start_routine) (void *), void* arg)
-{
- return 0;
-}
-
-static inline void
-work_thread_join (openvpn_thread_t id)
-{
-}
-
-static inline void
-mutex_lock_static (int type)
-{
-}
-
-static inline void
-mutex_unlock_static (int type)
-{
-}
-
-static inline void
-mutex_cycle_static (int type)
-{
-}
-
-#endif /* USE_PTHREAD */
-
-#endif /* THREAD_H */
diff --git a/openvpn/tun.c b/openvpn/tun.c
deleted file mode 100644
index e904a0c..0000000
--- a/openvpn/tun.c
+++ /dev/null
@@ -1,3446 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Support routines for configuring and accessing TUN/TAP
- * virtual network adapters.
- *
- * This file is based on the TUN/TAP driver interface routines
- * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>.
- */
-
-#ifdef WIN32
-#include "config-win32.h"
-#else
-#include "config.h"
-#endif
-
-#include "syshead.h"
-
-#include "tun.h"
-#include "fdmisc.h"
-#include "common.h"
-#include "misc.h"
-#include "socket.h"
-#include "manage.h"
-
-#include "memdbg.h"
-
-#ifdef TARGET_SOLARIS
-static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual);
-#endif
-
-bool
-is_dev_type (const char *dev, const char *dev_type, const char *match_type)
-{
- ASSERT (match_type);
- if (!dev)
- return false;
- if (dev_type)
- return !strcmp (dev_type, match_type);
- else
- return !strncmp (dev, match_type, strlen (match_type));
-}
-
-int
-dev_type_enum (const char *dev, const char *dev_type)
-{
- if (is_dev_type (dev, dev_type, "tun"))
- return DEV_TYPE_TUN;
- else if (is_dev_type (dev, dev_type, "tap"))
- return DEV_TYPE_TAP;
- else if (is_dev_type (dev, dev_type, "null"))
- return DEV_TYPE_NULL;
- else
- return DEV_TYPE_UNDEF;
-}
-
-const char *
-dev_type_string (const char *dev, const char *dev_type)
-{
- switch (dev_type_enum (dev, dev_type))
- {
- case DEV_TYPE_TUN:
- return "tun";
- case DEV_TYPE_TAP:
- return "tap";
- case DEV_TYPE_NULL:
- return "null";
- default:
- return "[unknown-dev-type]";
- }
-}
-
-const char *
-dev_component_in_dev_node (const char *dev_node)
-{
- const char *ret;
- const int dirsep = OS_SPECIFIC_DIRSEP;
-
- if (dev_node)
- {
- ret = strrchr (dev_node, dirsep);
- if (ret && *ret)
- ++ret;
- else
- ret = dev_node;
- if (*ret)
- return ret;
- }
- return NULL;
-}
-
-/*
- * Try to predict the actual TUN/TAP device instance name,
- * before the device is actually opened.
- */
-const char *
-guess_tuntap_dev (const char *dev,
- const char *dev_type,
- const char *dev_node,
- struct gc_arena *gc)
-{
-#ifdef WIN32
- const int dt = dev_type_enum (dev, dev_type);
- if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP)
- {
- return get_netsh_id (dev_node, gc);
- }
-#endif
-
- /* default case */
- return dev;
-}
-
-/*
- * Called by the open_tun function of OSes to check if we
- * explicitly support IPv6.
- *
- * In this context, explicit means that the OS expects us to
- * do something special to the tun socket in order to support
- * IPv6, i.e. it is not transparent.
- *
- * ipv6_explicitly_supported should be set to false if we don't
- * have any explicit IPv6 code in the tun device handler.
- *
- * If ipv6_explicitly_supported is true, then we have explicit
- * OS-specific tun dev code for handling IPv6. If so, tt->ipv6
- * is set according to the --tun-ipv6 command line option.
- */
-static void
-ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt)
-{
- tt->ipv6 = false;
- if (ipv6_explicitly_supported)
- tt->ipv6 = ipv6;
- else if (ipv6)
- msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
-}
-
-/* --ifconfig-nowarn disables some options sanity checking */
-static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
-
-/*
- * If !tun, make sure ifconfig_remote_netmask looks
- * like a netmask.
- *
- * If tun, make sure ifconfig_remote_netmask looks
- * like an IPv4 address.
- */
-static void
-ifconfig_sanity_check (bool tun, in_addr_t addr)
-{
- struct gc_arena gc = gc_new ();
- const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
- if (tun)
- {
- if (looks_like_netmask)
- msg (M_WARN, "WARNING: Since you are using --dev tun, the second argument to --ifconfig must be an IP address. You are using something (%s) that looks more like a netmask. %s",
- print_in_addr_t (addr, 0, &gc),
- ifconfig_warn_how_to_silence);
- }
- else /* tap */
- {
- if (!looks_like_netmask)
- msg (M_WARN, "WARNING: Since you are using --dev tap, the second argument to --ifconfig must be a netmask, for example something like 255.255.255.0. %s",
- ifconfig_warn_how_to_silence);
- }
- gc_free (&gc);
-}
-
-/*
- * For TAP-style devices, generate a broadcast address.
- */
-static in_addr_t
-generate_ifconfig_broadcast_addr (in_addr_t local,
- in_addr_t netmask)
-{
- return local | ~netmask;
-}
-
-/*
- * Check that --local and --remote addresses do not
- * clash with ifconfig addresses or subnet.
- */
-static void
-check_addr_clash (const char *name,
- int type,
- in_addr_t public,
- in_addr_t local,
- in_addr_t remote_netmask)
-{
- struct gc_arena gc = gc_new ();
-#if 0
- msg (M_INFO, "CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
- type,
- print_in_addr_t (public, 0, &gc),
- print_in_addr_t (local, 0, &gc),
- print_in_addr_t (remote_netmask, 0, &gc));
-#endif
-
- if (public)
- {
- if (type == DEV_TYPE_TUN)
- {
- const in_addr_t test_netmask = 0xFFFFFF00;
- const in_addr_t public_net = public & test_netmask;
- const in_addr_t local_net = local & test_netmask;
- const in_addr_t remote_net = remote_netmask & test_netmask;
-
- if (public == local || public == remote_netmask)
- msg (M_WARN,
- "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
- name,
- print_in_addr_t (public, 0, &gc),
- print_in_addr_t (local, 0, &gc),
- print_in_addr_t (remote_netmask, 0, &gc),
- ifconfig_warn_how_to_silence);
-
- if (public_net == local_net || public_net == remote_net)
- msg (M_WARN,
- "WARNING: potential conflict between --%s address [%s] and --ifconfig address pair [%s, %s] -- this is a warning only that is triggered when local/remote addresses exist within the same /24 subnet as --ifconfig endpoints. %s",
- name,
- print_in_addr_t (public, 0, &gc),
- print_in_addr_t (local, 0, &gc),
- print_in_addr_t (remote_netmask, 0, &gc),
- ifconfig_warn_how_to_silence);
- }
- else if (type == DEV_TYPE_TAP)
- {
- const in_addr_t public_network = public & remote_netmask;
- const in_addr_t virtual_network = local & remote_netmask;
- if (public_network == virtual_network)
- msg (M_WARN,
- "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
- name,
- print_in_addr_t (public, 0, &gc),
- print_in_addr_t (local, 0, &gc),
- print_in_addr_t (remote_netmask, 0, &gc),
- ifconfig_warn_how_to_silence);
- }
- }
- gc_free (&gc);
-}
-
-/*
- * Complain if --dev tap and --ifconfig is used on an OS for which
- * we don't have a custom tap ifconfig template below.
- */
-static void
-no_tap_ifconfig ()
-{
- msg (M_FATAL, "Sorry but you cannot use --dev tap and --ifconfig together on this OS because I have not yet been programmed to understand the appropriate ifconfig syntax to use for TAP-style devices on this OS. Your best alternative is to use an --up script and do the ifconfig command manually.");
-}
-
-/*
- * Return a string to be used for options compatibility check
- * between peers.
- */
-const char *
-ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, struct gc_arena *gc)
-{
- struct buffer out = alloc_buf_gc (256, gc);
- if (tt->did_ifconfig_setup && !disable)
- {
- if (tt->type == DEV_TYPE_TUN)
- {
- const char *l, *r;
- if (remote)
- {
- r = print_in_addr_t (tt->local, 0, gc);
- l = print_in_addr_t (tt->remote_netmask, 0, gc);
- }
- else
- {
- l = print_in_addr_t (tt->local, 0, gc);
- r = print_in_addr_t (tt->remote_netmask, 0, gc);
- }
- buf_printf (&out, "%s %s", r, l);
- }
- else if (tt->type == DEV_TYPE_TAP)
- {
- buf_printf (&out, "%s %s",
- print_in_addr_t (tt->local & tt->remote_netmask, 0, gc),
- print_in_addr_t (tt->remote_netmask, 0, gc));
- }
- else
- buf_printf (&out, "[undef]");
- }
- return BSTR (&out);
-}
-
-/*
- * Return a status string describing wait state.
- */
-const char *
-tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
-{
- struct buffer out = alloc_buf_gc (64, gc);
- if (tt)
- {
- if (rwflags & EVENT_READ)
- {
- buf_printf (&out, "T%s",
- (tt->rwflags_debug & EVENT_READ) ? "R" : "r");
-#ifdef WIN32
- buf_printf (&out, "%s",
- overlapped_io_state_ascii (&tt->reads));
-#endif
- }
- if (rwflags & EVENT_WRITE)
- {
- buf_printf (&out, "T%s",
- (tt->rwflags_debug & EVENT_WRITE) ? "W" : "w");
-#ifdef WIN32
- buf_printf (&out, "%s",
- overlapped_io_state_ascii (&tt->writes));
-#endif
- }
- }
- else
- {
- buf_printf (&out, "T?");
- }
- return BSTR (&out);
-}
-
-/*
- * Init tun/tap object.
- *
- * Set up tuntap structure for ifconfig,
- * but don't execute yet.
- */
-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 */
- in_addr_t local_public,
- in_addr_t remote_public,
- const bool strict_warn,
- struct env_set *es)
-{
- struct gc_arena gc = gc_new ();
- struct tuntap *tt;
-
- ALLOC_OBJ (tt, struct tuntap);
- clear_tuntap (tt);
-
- tt->type = dev_type_enum (dev, dev_type);
-
- if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
- {
- bool tun = false;
- const char *ifconfig_local = NULL;
- const char *ifconfig_remote_netmask = NULL;
- const char *ifconfig_broadcast = NULL;
-
- /*
- * We only handle TUN/TAP devices here, not --dev null devices.
- */
- if (tt->type == DEV_TYPE_TUN)
- tun = true;
- else if (tt->type == DEV_TYPE_TAP)
- tun = false;
- else
- msg (M_FATAL, "'%s' is not a TUN/TAP device. The --ifconfig option works only for TUN/TAP devices.", dev);
-
- /*
- * Convert arguments to binary IPv4 addresses.
- */
-
- tt->local = getaddr (
- GETADDR_RESOLVE
- | GETADDR_HOST_ORDER
- | GETADDR_FATAL_ON_SIGNAL
- | GETADDR_FATAL,
- ifconfig_local_parm,
- 0,
- NULL,
- NULL);
-
- tt->remote_netmask = getaddr (
- (tun ? GETADDR_RESOLVE : 0)
- | GETADDR_HOST_ORDER
- | GETADDR_FATAL_ON_SIGNAL
- | GETADDR_FATAL,
- ifconfig_remote_netmask_parm,
- 0,
- NULL,
- NULL);
-
- /*
- * Look for common errors in --ifconfig parms
- */
- if (strict_warn)
- {
- ifconfig_sanity_check (tun, tt->remote_netmask);
-
- /*
- * If local_public or remote_public addresses are defined,
- * make sure they do not clash with our virtual subnet.
- */
-
- check_addr_clash ("local",
- tt->type,
- local_public,
- tt->local,
- tt->remote_netmask);
-
- check_addr_clash ("remote",
- tt->type,
- remote_public,
- tt->local,
- tt->remote_netmask);
- }
-
- /*
- * Set ifconfig parameters
- */
- ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
- ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
-
- /*
- * If TAP-style interface, generate broadcast address.
- */
- if (!tun)
- {
- tt->broadcast = generate_ifconfig_broadcast_addr (tt->local, tt->remote_netmask);
- ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
- }
-
- /*
- * Set environmental variables with ifconfig parameters.
- */
- if (es)
- {
- setenv_str (es, "ifconfig_local", ifconfig_local);
- if (tun)
- {
- setenv_str (es, "ifconfig_remote", ifconfig_remote_netmask);
- }
- else
- {
- setenv_str (es, "ifconfig_netmask", ifconfig_remote_netmask);
- setenv_str (es, "ifconfig_broadcast", ifconfig_broadcast);
- }
- }
-
- tt->did_ifconfig_setup = true;
- }
- gc_free (&gc);
- return tt;
-}
-
-/*
- * Platform specific tun initializations
- */
-void
-init_tun_post (struct tuntap *tt,
- const struct frame *frame,
- const struct tuntap_options *options)
-{
- tt->options = *options;
-#ifdef WIN32
- overlapped_io_init (&tt->reads, frame, FALSE, true);
- overlapped_io_init (&tt->writes, frame, TRUE, true);
- tt->rw_handle.read = tt->reads.overlapped.hEvent;
- tt->rw_handle.write = tt->writes.overlapped.hEvent;
- tt->adapter_index = ~0;
-#endif
-}
-
-/* execute the ifconfig command through the shell */
-void
-do_ifconfig (struct tuntap *tt,
- const char *actual, /* actual device name */
- int tun_mtu,
- const struct env_set *es)
-{
- struct gc_arena gc = gc_new ();
-
- if (tt->did_ifconfig_setup)
- {
- bool tun = false;
- const char *ifconfig_local = NULL;
- const char *ifconfig_remote_netmask = NULL;
- const char *ifconfig_broadcast = NULL;
- char command_line[256];
-
- /*
- * We only handle TUN/TAP devices here, not --dev null devices.
- */
- if (tt->type == DEV_TYPE_TUN)
- tun = true;
- else if (tt->type == DEV_TYPE_TAP)
- tun = false;
- else
- ASSERT (0); /* should have been caught in init_tun */
-
- /*
- * Set ifconfig parameters
- */
- ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
- ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
-
- /*
- * If TAP-style device, generate broadcast address.
- */
- if (!tun)
- ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
-
-#ifdef ENABLE_MANAGEMENT
- if (management)
- {
- management_set_state (management,
- OPENVPN_STATE_ASSIGN_IP,
- NULL,
- tt->local);
- }
-#endif
-
-
-#if defined(TARGET_LINUX)
-#ifdef CONFIG_FEATURE_IPROUTE
- /*
- * Set the MTU for the device
- */
- openvpn_snprintf (command_line, sizeof (command_line),
- IPROUTE_PATH " link set dev %s up mtu %d",
- actual,
- tun_mtu
- );
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "Linux ip link set failed");
-
- if (tun) {
-
- /*
- * Set the address for the device
- */
- openvpn_snprintf (command_line, sizeof (command_line),
- IPROUTE_PATH " addr add dev %s local %s peer %s",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask
- );
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
- } else {
- openvpn_snprintf (command_line, sizeof (command_line),
- IPROUTE_PATH " addr add dev %s %s/%d broadcast %s",
- actual,
- ifconfig_local,
- count_netmask_bits(ifconfig_remote_netmask),
- ifconfig_broadcast
- );
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "Linux ip addr add failed");
- }
- tt->did_ifconfig = true;
-#else
- if (tun)
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s pointopoint %s mtu %d",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
- else
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s netmask %s mtu %d broadcast %s",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu,
- ifconfig_broadcast
- );
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "Linux ifconfig failed");
- tt->did_ifconfig = true;
-
-#endif /*CONFIG_FEATURE_IPROUTE*/
-#elif defined(TARGET_SOLARIS)
-
- /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
- * example:
- * ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
- * ifconfig tun2 netmask 255.255.255.255
- */
- if (tun)
- {
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s %s mtu %d up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
-
- msg (M_INFO, "%s", command_line);
- if (!system_check (command_line, es, 0, "Solaris ifconfig phase-1 failed"))
- solaris_error_close (tt, es, actual);
-
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s netmask 255.255.255.255",
- actual
- );
- }
- else
- no_tap_ifconfig ();
-
- msg (M_INFO, "%s", command_line);
- if (!system_check (command_line, es, 0, "Solaris ifconfig phase-2 failed"))
- solaris_error_close (tt, es, actual);
-
- tt->did_ifconfig = true;
-
-#elif defined(TARGET_OPENBSD)
-
- /*
- * OpenBSD tun devices appear to be persistent by default. It seems in order
- * to make this work correctly, we need to delete the previous instance
- * (if it exists), and re-ifconfig. Let me know if you know a better way.
- */
-
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s destroy",
- actual);
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, 0, NULL);
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s create",
- actual);
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, 0, NULL);
- msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
-
- /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
- if (tun)
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
- else
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s netmask %s mtu %d broadcast %s link0",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu,
- ifconfig_broadcast
- );
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "OpenBSD ifconfig failed");
- tt->did_ifconfig = true;
-
-#elif defined(TARGET_NETBSD)
-
- if (tun)
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
- else
- /*
- * NetBSD has distinct tun and tap devices
- * so we don't need the "link0" extra parameter to specify we want to do
- * tunneling at the ethernet level
- */
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s netmask %s mtu %d broadcast %s",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu,
- ifconfig_broadcast
- );
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "NetBSD ifconfig failed");
- tt->did_ifconfig = true;
-
-#elif defined(TARGET_DARWIN)
-
- /*
- * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
- */
-
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s delete",
- actual);
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, 0, NULL);
- msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
-
-
- /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
- if (tun)
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
- else
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s netmask %s mtu %d up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
-
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "Mac OS X ifconfig failed");
- tt->did_ifconfig = true;
-
-#elif defined(TARGET_FREEBSD)
-
- /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
- if (tun)
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s %s mtu %d netmask 255.255.255.255 up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
- else
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s %s netmask %s mtu %d up",
- actual,
- ifconfig_local,
- ifconfig_remote_netmask,
- tun_mtu
- );
-
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "FreeBSD ifconfig failed");
- tt->did_ifconfig = true;
-
-#elif defined (WIN32)
- {
- const char *netmask;
-
- /*
- * Make sure that both ifconfig addresses are part of the
- * same .252 subnet.
- */
- if (tun)
- {
- verify_255_255_255_252 (tt->local, tt->remote_netmask);
- tt->adapter_netmask = ~3;
- netmask = print_in_addr_t (tt->adapter_netmask, 0, &gc);
- }
- else
- {
- netmask = ifconfig_remote_netmask;
- tt->adapter_netmask = tt->remote_netmask;
- }
-
- /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */
- openvpn_snprintf (command_line, sizeof (command_line),
- "netsh interface ip set address \"%s\" static %s %s",
- actual,
- ifconfig_local,
- netmask);
-
- switch (tt->options.ip_win32_type)
- {
- case IPW32_SET_MANUAL:
- msg (M_INFO, "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
- actual,
- ifconfig_local,
- netmask);
- break;
- case IPW32_SET_NETSH:
- if (!strcmp (actual, "NULL"))
- msg (M_FATAL, "Error: When using --ip-win32 netsh, if you have more than one TAP-Win32 adapter, you must also specify --dev-node");
- netcmd_semaphore_lock ();
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, S_FATAL, "ERROR: netsh command failed");
- netcmd_semaphore_release ();
- break;
- }
- tt->did_ifconfig = true;
- }
-
-#else
- msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script.");
-#endif
- }
- gc_free (&gc);
-}
-
-void
-clear_tuntap (struct tuntap *tuntap)
-{
- CLEAR (*tuntap);
-#ifdef WIN32
- tuntap->hand = NULL;
-#else
- tuntap->fd = -1;
-#endif
-#ifdef TARGET_SOLARIS
- tuntap->ip_fd = -1;
-#endif
- tuntap->ipv6 = false;
-}
-
-static void
-open_null (struct tuntap *tt)
-{
- tt->actual_name = string_alloc ("null", NULL);
-}
-
-#ifndef WIN32
-static void
-open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
- bool ipv6, bool ipv6_explicitly_supported, bool dynamic,
- struct tuntap *tt)
-{
- char tunname[256];
- char dynamic_name[256];
- bool dynamic_opened = false;
-
- ipv6_support (ipv6, ipv6_explicitly_supported, tt);
-
- if (tt->type == DEV_TYPE_NULL)
- {
- open_null (tt);
- }
- else
- {
- /*
- * --dev-node specified, so open an explicit device node
- */
- if (dev_node)
- {
- openvpn_snprintf (tunname, sizeof (tunname), "%s", dev_node);
- }
- else
- {
- /*
- * dynamic open is indicated by --dev specified without
- * explicit unit number. Try opening /dev/[dev]n
- * where n = [0, 255].
- */
- if (dynamic && !has_digit(dev))
- {
- int i;
- for (i = 0; i < 256; ++i)
- {
- openvpn_snprintf (tunname, sizeof (tunname),
- "/dev/%s%d", dev, i);
- openvpn_snprintf (dynamic_name, sizeof (dynamic_name),
- "%s%d", dev, i);
- if ((tt->fd = open (tunname, O_RDWR)) > 0)
- {
- dynamic_opened = true;
- break;
- }
- msg (D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
- }
- if (!dynamic_opened)
- msg (M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
- }
- /*
- * explicit unit number specified
- */
- else
- {
- openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
- }
- }
-
- if (!dynamic_opened)
- {
- if ((tt->fd = open (tunname, O_RDWR)) < 0)
- msg (M_ERR, "Cannot open TUN/TAP dev %s", tunname);
- }
-
- set_nonblock (tt->fd);
- set_cloexec (tt->fd); /* don't pass fd to scripts */
- msg (M_INFO, "TUN/TAP device %s opened", tunname);
-
- /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
- tt->actual_name = string_alloc (dynamic_opened ? dynamic_name : dev, NULL);
- }
-}
-
-static void
-close_tun_generic (struct tuntap *tt)
-{
- if (tt->fd >= 0)
- close (tt->fd);
- if (tt->actual_name)
- free (tt->actual_name);
- clear_tuntap (tt);
-}
-
-#endif
-
-#if defined(TARGET_LINUX)
-
-#ifdef HAVE_LINUX_IF_TUN_H /* New driver support */
-
-#ifndef HAVE_LINUX_SOCKIOS_H
-#error header file linux/sockios.h required
-#endif
-
-#if defined(HAVE_TUN_PI) && defined(HAVE_IPHDR) && defined(HAVE_IOVEC) && defined(ETH_P_IPV6) && defined(ETH_P_IP) && defined(HAVE_READV) && defined(HAVE_WRITEV)
-#define LINUX_IPV6 1
-/* #warning IPv6 ON */
-#else
-#define LINUX_IPV6 0
-/* #warning IPv6 OFF */
-#endif
-
-#if !PEDANTIC
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- struct ifreq ifr;
-
- /*
- * Set tt->ipv6 to true if
- * (a) we have the capability of supporting --tun-ipv6, and
- * (b) --tun-ipv6 was specified.
- */
- ipv6_support (ipv6, LINUX_IPV6, tt);
-
- /*
- * We handle --dev null specially, we do not open /dev/null for this.
- */
- if (tt->type == DEV_TYPE_NULL)
- {
- open_null (tt);
- }
- else
- {
- /*
- * Process --dev-node
- */
- const char *node = dev_node;
- if (!node)
- node = "/dev/net/tun";
-
- /*
- * Open the interface
- */
- if ((tt->fd = open (node, O_RDWR)) < 0)
- {
- msg (M_WARN | M_ERRNO, "Note: Cannot open TUN/TAP dev %s", node);
- goto linux_2_2_fallback;
- }
-
- /*
- * Process --tun-ipv6
- */
- CLEAR (ifr);
- if (!tt->ipv6)
- ifr.ifr_flags = IFF_NO_PI;
-
-#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
- ifr.ifr_flags |= IFF_ONE_QUEUE;
-#endif
-
- /*
- * Figure out if tun or tap device
- */
- if (tt->type == DEV_TYPE_TUN)
- {
- ifr.ifr_flags |= IFF_TUN;
- }
- else if (tt->type == DEV_TYPE_TAP)
- {
- ifr.ifr_flags |= IFF_TAP;
- }
- else
- {
- msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
- dev);
- }
-
- /*
- * Set an explicit name, if --dev is not tun or tap
- */
- if (strcmp(dev, "tun") && strcmp(dev, "tap"))
- strncpynt (ifr.ifr_name, dev, IFNAMSIZ);
-
- /*
- * Use special ioctl that configures tun/tap device with the parms
- * we set in ifr
- */
- if (ioctl (tt->fd, TUNSETIFF, (void *) &ifr) < 0)
- {
- msg (M_WARN | M_ERRNO, "Note: Cannot ioctl TUNSETIFF %s", dev);
- goto linux_2_2_fallback;
- }
-
- msg (M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
-
- /*
- * Try making the TX send queue bigger
- */
-#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
- {
- struct ifreq netifr;
- int ctl_fd;
-
- if ((ctl_fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0)
- {
- CLEAR (netifr);
- strncpynt (netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
- netifr.ifr_qlen = tt->options.txqueuelen;
- if (ioctl (ctl_fd, SIOCSIFTXQLEN, (void *) &netifr) >= 0)
- msg (D_OSBUF, "TUN/TAP TX queue length set to %d", tt->options.txqueuelen);
- else
- msg (M_WARN | M_ERRNO, "Note: Cannot set tx queue length on %s", ifr.ifr_name);
- close (ctl_fd);
- }
- else
- {
- msg (M_WARN | M_ERRNO, "Note: Cannot open control socket on %s", ifr.ifr_name);
- }
- }
-#endif
-
- set_nonblock (tt->fd);
- set_cloexec (tt->fd);
- tt->actual_name = string_alloc (ifr.ifr_name, NULL);
- }
- return;
-
- linux_2_2_fallback:
- msg (M_INFO, "Note: Attempting fallback to kernel 2.2 TUN/TAP interface");
- if (tt->fd >= 0)
- {
- close (tt->fd);
- tt->fd = -1;
- }
- open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
-}
-
-#else
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- ASSERT (0);
-}
-
-#endif
-
-#else
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
-}
-
-#endif /* HAVE_LINUX_IF_TUN_H */
-
-#ifdef TUNSETPERSIST
-
-void
-tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode)
-{
- struct tuntap *tt;
-
- ALLOC_OBJ (tt, struct tuntap);
- clear_tuntap (tt);
- tt->type = dev_type_enum (dev, dev_type);
- open_tun (dev, dev_type, dev_node, ipv6, tt);
- if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
- msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
- close_tun (tt);
- msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
-}
-
-#endif /* TUNSETPERSIST */
-
-void
-close_tun (struct tuntap *tt)
-{
- if (tt)
- {
- close_tun_generic (tt);
- free (tt);
- }
-}
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
-#if LINUX_IPV6
- if (tt->ipv6)
- {
- struct tun_pi pi;
- struct iphdr *iph;
- struct iovec vect[2];
- int ret;
-
- iph = (struct iphdr *)buf;
-
- pi.flags = 0;
-
- if(iph->version == 6)
- pi.proto = htons(ETH_P_IPV6);
- else
- pi.proto = htons(ETH_P_IP);
-
- vect[0].iov_len = sizeof(pi);
- vect[0].iov_base = &pi;
- vect[1].iov_len = len;
- vect[1].iov_base = buf;
-
- ret = writev(tt->fd, vect, 2);
- return(ret - sizeof(pi));
- }
- else
-#endif
- return write (tt->fd, buf, len);
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
-#if LINUX_IPV6
- if (tt->ipv6)
- {
- struct iovec vect[2];
- struct tun_pi pi;
- int ret;
-
- vect[0].iov_len = sizeof(pi);
- vect[0].iov_base = &pi;
- vect[1].iov_len = len;
- vect[1].iov_base = buf;
-
- ret = readv(tt->fd, vect, 2);
- return(ret - sizeof(pi));
- }
- else
-#endif
- return read (tt->fd, buf, len);
-}
-
-#elif defined(TARGET_SOLARIS)
-
-#ifndef TUNNEWPPA
-#error I need the symbol TUNNEWPPA from net/if_tun.h
-#endif
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- int if_fd, muxid, ppa = -1;
- struct ifreq ifr;
- const char *ptr;
- const char *ip_node;
- const char *dev_tuntap_type;
- int link_type;
- bool is_tun;
-
- ipv6_support (ipv6, false, tt);
-
- if (tt->type == DEV_TYPE_NULL)
- {
- open_null (tt);
- return;
- }
-
- if (tt->type == DEV_TYPE_TUN)
- {
- ip_node = "/dev/udp";
- if (!dev_node)
- dev_node = "/dev/tun";
- dev_tuntap_type = "tun";
- link_type = I_PLINK;
- is_tun = true;
- }
- else if (tt->type == DEV_TYPE_TAP)
- {
- ip_node = "/dev/ip";
- if (!dev_node)
- dev_node = "/dev/tap";
- dev_tuntap_type = "tap";
- link_type = I_PLINK; /* was: I_LINK */
- is_tun = false;
- }
- else
- {
- msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
- dev);
- }
-
- /* get unit number */
- if (*dev)
- {
- ptr = dev;
- while (*ptr && !isdigit ((int) *ptr))
- ptr++;
- ppa = atoi (ptr);
- }
-
- if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0)
- msg (M_ERR, "Can't open %s", ip_node);
-
- if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0)
- msg (M_ERR, "Can't open %s", dev_node);
-
- /* Assign a new PPA and get its unit number. */
- if ((ppa = ioctl (tt->fd, TUNNEWPPA, ppa)) < 0)
- msg (M_ERR, "Can't assign new interface");
-
- if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
- msg (M_ERR, "Can't open %s (2)", dev_node);
-
- if (ioctl (if_fd, I_PUSH, "ip") < 0)
- msg (M_ERR, "Can't push IP module");
-
- /* Assign ppa according to the unit number returned by tun device */
- if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0)
- msg (M_ERR, "Can't set PPA %d", ppa);
-
- if ((muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
- msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
-
- close (if_fd);
-
- tt->actual_name = (char *) malloc (32);
- check_malloc_return (tt->actual_name);
-
- openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
-
- CLEAR (ifr);
- strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
- ifr.ifr_ip_muxid = muxid;
-
- if (ioctl (tt->ip_fd, SIOCSIFMUXID, &ifr) < 0)
- {
- ioctl (tt->ip_fd, I_PUNLINK, muxid);
- msg (M_ERR, "Can't set multiplexor id");
- }
-
- set_nonblock (tt->fd);
- set_cloexec (tt->fd);
- set_cloexec (tt->ip_fd);
-
- msg (M_INFO, "TUN/TAP device %s opened", tt->actual_name);
-}
-
-static void
-solaris_close_tun (struct tuntap *tt)
-{
- if (tt)
- {
- if (tt->ip_fd >= 0)
- {
- struct ifreq ifr;
- CLEAR (ifr);
- strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
-
- if (ioctl (tt->ip_fd, SIOCGIFFLAGS, &ifr) < 0)
- msg (M_WARN | M_ERRNO, "Can't get iface flags");
-
- if (ioctl (tt->ip_fd, SIOCGIFMUXID, &ifr) < 0)
- msg (M_WARN | M_ERRNO, "Can't get multiplexor id");
-
- if (ioctl (tt->ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0)
- msg (M_WARN | M_ERRNO, "Can't unlink interface");
-
- close (tt->ip_fd);
- tt->ip_fd = -1;
- }
-
- if (tt->fd >= 0)
- {
- close (tt->fd);
- tt->fd = -1;
- }
- }
-}
-
-/*
- * Close TUN device.
- */
-void
-close_tun (struct tuntap *tt)
-{
- if (tt)
- {
- solaris_close_tun (tt);
-
- if (tt->actual_name)
- free (tt->actual_name);
-
- clear_tuntap (tt);
- free (tt);
- }
-}
-
-static void
-solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual)
-{
- char command_line[256];
-
- openvpn_snprintf (command_line, sizeof (command_line),
- IFCONFIG_PATH " %s unplumb",
- actual);
-
- msg (M_INFO, "%s", command_line);
- system_check (command_line, es, 0, "Solaris ifconfig unplumb failed");
- close_tun (tt);
- msg (M_FATAL, "Solaris ifconfig failed");
-}
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- struct strbuf sbuf;
- sbuf.len = len;
- sbuf.buf = (char *)buf;
- return putmsg (tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- struct strbuf sbuf;
- int f = 0;
-
- sbuf.maxlen = len;
- sbuf.buf = (char *)buf;
- return getmsg (tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
-}
-
-#elif defined(TARGET_OPENBSD)
-
-#if !defined(HAVE_READV) || !defined(HAVE_WRITEV)
-#error openbsd build requires readv & writev library functions
-#endif
-
-/*
- * OpenBSD has a slightly incompatible TUN device from
- * the rest of the world, in that it prepends a
- * uint32 to the beginning of the IP header
- * to designate the protocol (why not just
- * look at the version field in the IP header to
- * determine v4 or v6?).
- *
- * We strip off this field on reads and
- * put it back on writes.
- *
- * I have not tested TAP devices on OpenBSD,
- * but I have conditionalized the special
- * TUN handling code described above to
- * go away for TAP devices.
- */
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
-
- /* Enable multicast on the interface */
- if (tt->fd >= 0)
- {
- struct tuninfo info;
-
- if (ioctl (tt->fd, TUNGIFINFO, &info) < 0) {
- msg (M_WARN | M_ERRNO, "Can't get interface info: %s",
- strerror(errno));
- }
-
- info.flags |= IFF_MULTICAST;
-
- if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) {
- msg (M_WARN | M_ERRNO, "Can't set interface info: %s",
- strerror(errno));
- }
- }
-}
-
-void
-close_tun (struct tuntap* tt)
-{
- if (tt)
- {
- close_tun_generic (tt);
- free (tt);
- }
-}
-
-static inline int
-openbsd_modify_read_write_return (int len)
-{
- if (len > 0)
- return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
- else
- return len;
-}
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- if (tt->type == DEV_TYPE_TUN)
- {
- u_int32_t type;
- struct iovec iv[2];
- struct ip *iph;
-
- iph = (struct ip *) buf;
-
- if (tt->ipv6 && iph->ip_v == 6)
- type = htonl (AF_INET6);
- else
- type = htonl (AF_INET);
-
- iv[0].iov_base = &type;
- iv[0].iov_len = sizeof (type);
- iv[1].iov_base = buf;
- iv[1].iov_len = len;
-
- return openbsd_modify_read_write_return (writev (tt->fd, iv, 2));
- }
- else
- return write (tt->fd, buf, len);
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- if (tt->type == DEV_TYPE_TUN)
- {
- u_int32_t type;
- struct iovec iv[2];
-
- iv[0].iov_base = &type;
- iv[0].iov_len = sizeof (type);
- iv[1].iov_base = buf;
- iv[1].iov_len = len;
-
- return openbsd_modify_read_write_return (readv (tt->fd, iv, 2));
- }
- else
- return read (tt->fd, buf, len);
-}
-
-#elif defined(TARGET_NETBSD)
-
-/*
- * NetBSD does not support IPv6 on tun out of the box,
- * but there exists a patch. When this patch is applied,
- * only two things are left to openvpn:
- * 1. Activate multicasting (this has already been done
- * before by the kernel, but we make sure that nobody
- * has deactivated multicasting inbetween.
- * 2. Deactivate "link layer mode" (otherwise NetBSD
- * prepends the address family to the packet, and we
- * would run into the same trouble as with OpenBSD.
- */
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
- if (tt->fd >= 0)
- {
- int i = IFF_POINTOPOINT|IFF_MULTICAST;
- ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */
- i = 0;
- ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */
- }
-}
-
-void
-close_tun (struct tuntap *tt)
-{
- if (tt)
- {
- close_tun_generic (tt);
- free (tt);
- }
-}
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- return write (tt->fd, buf, len);
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- return read (tt->fd, buf, len);
-}
-
-#elif defined(TARGET_FREEBSD)
-
-static inline int
-freebsd_modify_read_write_return (int len)
-{
- if (len > 0)
- return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
- else
- return len;
-}
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
-
- if (tt->fd >= 0)
- {
- int i = 0;
-
- /* Disable extended modes */
- ioctl (tt->fd, TUNSLMODE, &i);
- i = 1;
- ioctl (tt->fd, TUNSIFHEAD, &i);
- }
-}
-
-void
-close_tun (struct tuntap *tt)
-{
- if (tt)
- {
- close_tun_generic (tt);
- free (tt);
- }
-}
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- if (tt->type == DEV_TYPE_TUN)
- {
- u_int32_t type;
- struct iovec iv[2];
- struct ip *iph;
-
- iph = (struct ip *) buf;
-
- if (tt->ipv6 && iph->ip_v == 6)
- type = htonl (AF_INET6);
- else
- type = htonl (AF_INET);
-
- iv[0].iov_base = (char *)&type;
- iv[0].iov_len = sizeof (type);
- iv[1].iov_base = buf;
- iv[1].iov_len = len;
-
- return freebsd_modify_read_write_return (writev (tt->fd, iv, 2));
- }
- else
- return write (tt->fd, buf, len);
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- if (tt->type == DEV_TYPE_TUN)
- {
- u_int32_t type;
- struct iovec iv[2];
-
- iv[0].iov_base = (char *)&type;
- iv[0].iov_len = sizeof (type);
- iv[1].iov_base = buf;
- iv[1].iov_len = len;
-
- return freebsd_modify_read_write_return (readv (tt->fd, iv, 2));
- }
- else
- return read (tt->fd, buf, len);
-}
-
-#elif defined(WIN32)
-
-int
-tun_read_queue (struct tuntap *tt, int maxsize)
-{
- if (tt->reads.iostate == IOSTATE_INITIAL)
- {
- DWORD len;
- BOOL status;
- int err;
-
- /* reset buf to its initial state */
- tt->reads.buf = tt->reads.buf_init;
-
- len = maxsize ? maxsize : BLEN (&tt->reads.buf);
- ASSERT (len <= BLEN (&tt->reads.buf));
-
- /* the overlapped read will signal this event on I/O completion */
- ASSERT (ResetEvent (tt->reads.overlapped.hEvent));
-
- status = ReadFile(
- tt->hand,
- BPTR (&tt->reads.buf),
- len,
- &tt->reads.size,
- &tt->reads.overlapped
- );
-
- if (status) /* operation completed immediately? */
- {
- /* since we got an immediate return, we must signal the event object ourselves */
- ASSERT (SetEvent (tt->reads.overlapped.hEvent));
-
- tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
- tt->reads.status = 0;
-
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read immediate return [%d,%d]",
- (int) len,
- (int) tt->reads.size);
- }
- else
- {
- err = GetLastError ();
- if (err == ERROR_IO_PENDING) /* operation queued? */
- {
- tt->reads.iostate = IOSTATE_QUEUED;
- tt->reads.status = err;
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read queued [%d]",
- (int) len);
- }
- else /* error occurred */
- {
- struct gc_arena gc = gc_new ();
- ASSERT (SetEvent (tt->reads.overlapped.hEvent));
- tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
- tt->reads.status = err;
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read error [%d] : %s",
- (int) len,
- strerror_win32 (status, &gc));
- gc_free (&gc);
- }
- }
- }
- return tt->reads.iostate;
-}
-
-int
-tun_write_queue (struct tuntap *tt, struct buffer *buf)
-{
- if (tt->writes.iostate == IOSTATE_INITIAL)
- {
- BOOL status;
- int err;
-
- /* make a private copy of buf */
- tt->writes.buf = tt->writes.buf_init;
- tt->writes.buf.len = 0;
- ASSERT (buf_copy (&tt->writes.buf, buf));
-
- /* the overlapped write will signal this event on I/O completion */
- ASSERT (ResetEvent (tt->writes.overlapped.hEvent));
-
- status = WriteFile(
- tt->hand,
- BPTR (&tt->writes.buf),
- BLEN (&tt->writes.buf),
- &tt->writes.size,
- &tt->writes.overlapped
- );
-
- if (status) /* operation completed immediately? */
- {
- tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
-
- /* since we got an immediate return, we must signal the event object ourselves */
- ASSERT (SetEvent (tt->writes.overlapped.hEvent));
-
- tt->writes.status = 0;
-
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write immediate return [%d,%d]",
- BLEN (&tt->writes.buf),
- (int) tt->writes.size);
- }
- else
- {
- err = GetLastError ();
- if (err == ERROR_IO_PENDING) /* operation queued? */
- {
- tt->writes.iostate = IOSTATE_QUEUED;
- tt->writes.status = err;
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write queued [%d]",
- BLEN (&tt->writes.buf));
- }
- else /* error occurred */
- {
- struct gc_arena gc = gc_new ();
- ASSERT (SetEvent (tt->writes.overlapped.hEvent));
- tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
- tt->writes.status = err;
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write error [%d] : %s",
- BLEN (&tt->writes.buf),
- strerror_win32 (err, &gc));
- gc_free (&gc);
- }
- }
- }
- return tt->writes.iostate;
-}
-
-int
-tun_finalize (
- HANDLE h,
- struct overlapped_io *io,
- struct buffer *buf)
-{
- int ret = -1;
- BOOL status;
-
- switch (io->iostate)
- {
- case IOSTATE_QUEUED:
- status = GetOverlappedResult(
- h,
- &io->overlapped,
- &io->size,
- FALSE
- );
- if (status)
- {
- /* successful return for a queued operation */
- if (buf)
- *buf = io->buf;
- ret = io->size;
- io->iostate = IOSTATE_INITIAL;
- ASSERT (ResetEvent (io->overlapped.hEvent));
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion success [%d]", ret);
- }
- else
- {
- /* error during a queued operation */
- ret = -1;
- if (GetLastError() != ERROR_IO_INCOMPLETE)
- {
- /* if no error (i.e. just not finished yet),
- then DON'T execute this code */
- io->iostate = IOSTATE_INITIAL;
- ASSERT (ResetEvent (io->overlapped.hEvent));
- msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion error");
- }
- }
- break;
-
- case IOSTATE_IMMEDIATE_RETURN:
- io->iostate = IOSTATE_INITIAL;
- ASSERT (ResetEvent (io->overlapped.hEvent));
- if (io->status)
- {
- /* error return for a non-queued operation */
- SetLastError (io->status);
- ret = -1;
- msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion non-queued error");
- }
- else
- {
- /* successful return for a non-queued operation */
- if (buf)
- *buf = io->buf;
- ret = io->size;
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion non-queued success [%d]", ret);
- }
- break;
-
- case IOSTATE_INITIAL: /* were we called without proper queueing? */
- SetLastError (ERROR_INVALID_FUNCTION);
- ret = -1;
- dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion BAD STATE");
- break;
-
- default:
- ASSERT (0);
- }
-
- if (buf)
- buf->len = ret;
- return ret;
-}
-
-const struct tap_reg *
-get_tap_reg (struct gc_arena *gc)
-{
- HKEY adapter_key;
- LONG status;
- DWORD len;
- struct tap_reg *first = NULL;
- struct tap_reg *last = NULL;
- int i = 0;
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- ADAPTER_KEY,
- 0,
- KEY_READ,
- &adapter_key);
-
- if (status != ERROR_SUCCESS)
- msg (M_FATAL, "Error opening registry key: %s", ADAPTER_KEY);
-
- while (true)
- {
- char enum_name[256];
- char unit_string[256];
- HKEY unit_key;
- char component_id_string[] = "ComponentId";
- char component_id[256];
- char net_cfg_instance_id_string[] = "NetCfgInstanceId";
- char net_cfg_instance_id[256];
- DWORD data_type;
-
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
- adapter_key,
- i,
- enum_name,
- &len,
- NULL,
- NULL,
- NULL,
- NULL);
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS)
- msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
- ADAPTER_KEY);
-
- openvpn_snprintf (unit_string, sizeof(unit_string), "%s\\%s",
- ADAPTER_KEY, enum_name);
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- unit_string,
- 0,
- KEY_READ,
- &unit_key);
-
- if (status != ERROR_SUCCESS)
- dmsg (D_REGISTRY, "Error opening registry key: %s", unit_string);
- else
- {
- len = sizeof (component_id);
- status = RegQueryValueEx(
- unit_key,
- component_id_string,
- NULL,
- &data_type,
- component_id,
- &len);
-
- if (status != ERROR_SUCCESS || data_type != REG_SZ)
- dmsg (D_REGISTRY, "Error opening registry key: %s\\%s",
- unit_string, component_id_string);
- else
- {
- len = sizeof (net_cfg_instance_id);
- status = RegQueryValueEx(
- unit_key,
- net_cfg_instance_id_string,
- NULL,
- &data_type,
- net_cfg_instance_id,
- &len);
-
- if (status == ERROR_SUCCESS && data_type == REG_SZ)
- {
- if (!strcmp (component_id, TAP_COMPONENT_ID))
- {
- struct tap_reg *reg;
- ALLOC_OBJ_CLEAR_GC (reg, struct tap_reg, gc);
- reg->guid = string_alloc (net_cfg_instance_id, gc);
-
- /* link into return list */
- if (!first)
- first = reg;
- if (last)
- last->next = reg;
- last = reg;
- }
- }
- }
- RegCloseKey (unit_key);
- }
- ++i;
- }
-
- RegCloseKey (adapter_key);
- return first;
-}
-
-const struct panel_reg *
-get_panel_reg (struct gc_arena *gc)
-{
- LONG status;
- HKEY network_connections_key;
- DWORD len;
- struct panel_reg *first = NULL;
- struct panel_reg *last = NULL;
- int i = 0;
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- NETWORK_CONNECTIONS_KEY,
- 0,
- KEY_READ,
- &network_connections_key);
-
- if (status != ERROR_SUCCESS)
- msg (M_FATAL, "Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
-
- while (true)
- {
- char enum_name[256];
- char connection_string[256];
- HKEY connection_key;
- char name_data[256];
- DWORD name_type;
- const char name_string[] = "Name";
-
- len = sizeof (enum_name);
- status = RegEnumKeyEx(
- network_connections_key,
- i,
- enum_name,
- &len,
- NULL,
- NULL,
- NULL,
- NULL);
- if (status == ERROR_NO_MORE_ITEMS)
- break;
- else if (status != ERROR_SUCCESS)
- msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
- NETWORK_CONNECTIONS_KEY);
-
- openvpn_snprintf (connection_string, sizeof(connection_string),
- "%s\\%s\\Connection",
- NETWORK_CONNECTIONS_KEY, enum_name);
-
- status = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- connection_string,
- 0,
- KEY_READ,
- &connection_key);
-
- if (status != ERROR_SUCCESS)
- dmsg (D_REGISTRY, "Error opening registry key: %s", connection_string);
- else
- {
- len = sizeof (name_data);
- status = RegQueryValueEx(
- connection_key,
- name_string,
- NULL,
- &name_type,
- name_data,
- &len);
-
- if (status != ERROR_SUCCESS || name_type != REG_SZ)
- dmsg (D_REGISTRY, "Error opening registry key: %s\\%s\\%s",
- NETWORK_CONNECTIONS_KEY, connection_string, name_string);
- else
- {
- struct panel_reg *reg;
-
- ALLOC_OBJ_CLEAR_GC (reg, struct panel_reg, gc);
- reg->name = string_alloc (name_data, gc);
- reg->guid = string_alloc (enum_name, gc);
-
- /* link into return list */
- if (!first)
- first = reg;
- if (last)
- last->next = reg;
- last = reg;
- }
- RegCloseKey (connection_key);
- }
- ++i;
- }
-
- RegCloseKey (network_connections_key);
-
- return first;
-}
-
-/*
- * Check that two addresses are part of the same 255.255.255.252 subnet.
- */
-void
-verify_255_255_255_252 (in_addr_t local, in_addr_t remote)
-{
- struct gc_arena gc = gc_new ();
- const unsigned int mask = 3;
- const char *err = NULL;
-
- if (local == remote)
- {
- err = "must be different";
- goto error;
- }
- if ((local & (~mask)) != (remote & (~mask)))
- {
- err = "must exist within the same 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
- goto error;
- }
- if ((local & mask) == 0
- || (local & mask) == 3
- || (remote & mask) == 0
- || (remote & mask) == 3)
- {
- err = "cannot use the first or last address within a given 255.255.255.252 subnet. This is a limitation of --dev tun when used with the TAP-WIN32 driver";
- goto error;
- }
-
- gc_free (&gc);
- return;
-
- error:
- msg (M_FATAL, "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s]. The local and remote VPN endpoints %s. Try '" PACKAGE " --show-valid-subnets' option for more info.",
- print_in_addr_t (local, 0, &gc),
- print_in_addr_t (remote, 0, &gc),
- err);
- gc_free (&gc);
-}
-
-void show_valid_win32_tun_subnets (void)
-{
- int i;
- int col = 0;
-
- printf ("On Windows, point-to-point IP support (i.e. --dev tun)\n");
- printf ("is emulated by the TAP-Win32 driver. The major limitation\n");
- printf ("imposed by this approach is that the --ifconfig local and\n");
- printf ("remote endpoints must be part of the same 255.255.255.252\n");
- printf ("subnet. The following list shows examples of endpoint\n");
- printf ("pairs which satisfy this requirement. Only the final\n");
- printf ("component of the IP address pairs is at issue.\n\n");
- printf ("As an example, the following option would be correct:\n");
- printf (" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
- printf (" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
- printf ("because [5,6] is part of the below list.\n\n");
-
- for (i = 0; i < 256; i += 4)
- {
- printf("[%3d,%3d] ", i+1, i+2);
- if (++col > 4)
- {
- col = 0;
- printf ("\n");
- }
- }
- if (col)
- printf ("\n");
-}
-
-void
-show_tap_win32_adapters (int msglev, int warnlev)
-{
- struct gc_arena gc = gc_new ();
-
- bool warn_panel_null = false;
- bool warn_panel_dup = false;
- bool warn_tap_dup = false;
-
- int links;
-
- const struct tap_reg *tr;
- const struct tap_reg *tr1;
- const struct panel_reg *pr;
-
- const struct tap_reg *tap_reg = get_tap_reg (&gc);
- const struct panel_reg *panel_reg = get_panel_reg (&gc);
-
- msg (msglev, "Available TAP-WIN32 adapters [name, GUID]:");
-
- /* loop through each TAP-Win32 adapter registry entry */
- for (tr = tap_reg; tr != NULL; tr = tr->next)
- {
- links = 0;
-
- /* loop through each network connections entry in the control panel */
- for (pr = panel_reg; pr != NULL; pr = pr->next)
- {
- if (!strcmp (tr->guid, pr->guid))
- {
- msg (msglev, "'%s' %s", pr->name, tr->guid);
- ++links;
- }
- }
-
- if (links > 1)
- {
- warn_panel_dup = true;
- }
- else if (links == 0)
- {
- /* a TAP adapter exists without a link from the network
- connections control panel */
- warn_panel_null = true;
- msg (msglev, "[NULL] %s", tr->guid);
- }
- }
-
- /* check for TAP-Win32 adapter duplicated GUIDs */
- for (tr = tap_reg; tr != NULL; tr = tr->next)
- {
- for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
- {
- if (tr != tr1 && !strcmp (tr->guid, tr1->guid))
- warn_tap_dup = true;
- }
- }
-
- /* warn on registry inconsistencies */
- if (warn_tap_dup)
- msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate GUIDs");
-
- if (warn_panel_dup)
- msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate links from the Network Connections control panel");
-
- if (warn_panel_null)
- msg (warnlev, "WARNING: Some TAP-Win32 adapters have no link from the Network Connections control panel");
-
- gc_free (&gc);
-}
-
-/*
- * Confirm that GUID is a TAP-Win32 adapter.
- */
-static bool
-is_tap_win32 (const char *guid, const struct tap_reg *tap_reg)
-{
- const struct tap_reg *tr;
-
- for (tr = tap_reg; tr != NULL; tr = tr->next)
- {
- if (guid && !strcmp (tr->guid, guid))
- return true;
- }
-
- return false;
-}
-
-static const char *
-guid_to_name (const char *guid, const struct panel_reg *panel_reg)
-{
- const struct panel_reg *pr;
-
- for (pr = panel_reg; pr != NULL; pr = pr->next)
- {
- if (guid && !strcmp (pr->guid, guid))
- return pr->name;
- }
-
- return NULL;
-}
-
-static const char *
-name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
-{
- const struct panel_reg *pr;
-
- for (pr = panel_reg; pr != NULL; pr = pr->next)
- {
- if (name && !strcmp (pr->name, name) && is_tap_win32 (pr->guid, tap_reg))
- return pr->guid;
- }
-
- return NULL;
-}
-
-static void
-at_least_one_tap_win32 (const struct tap_reg *tap_reg)
-{
- if (!tap_reg)
- msg (M_FATAL, "There are no TAP-Win32 adapters on this system. You should be able to create a TAP-Win32 adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Win32 virtual ethernet adapter.");
-}
-
-/*
- * Get an adapter GUID and optional actual_name from the
- * registry for the TAP device # = device_number.
- */
-static const char *
-get_unspecified_device_guid (const int device_number,
- char *actual_name,
- int actual_name_size,
- const struct tap_reg *tap_reg_src,
- const struct panel_reg *panel_reg_src,
- struct gc_arena *gc)
-{
- const struct tap_reg *tap_reg = tap_reg_src;
- struct buffer ret = clear_buf ();
- struct buffer actual = clear_buf ();
- int i;
-
- ASSERT (device_number >= 0);
-
- /* Make sure we have at least one TAP adapter */
- if (!tap_reg)
- return NULL;
-
- /* The actual_name output buffer may be NULL */
- if (actual_name)
- {
- ASSERT (actual_name_size > 0);
- buf_set_write (&actual, actual_name, actual_name_size);
- }
-
- /* Move on to specified device number */
- for (i = 0; i < device_number; i++)
- {
- tap_reg = tap_reg->next;
- if (!tap_reg)
- return NULL;
- }
-
- /* Save Network Panel name (if exists) in actual_name */
- if (actual_name)
- {
- const char *act = guid_to_name (tap_reg->guid, panel_reg_src);
- if (act)
- buf_printf (&actual, "%s", act);
- else
- buf_printf (&actual, "NULL");
- }
-
- /* Save GUID for return value */
- ret = alloc_buf_gc (256, gc);
- buf_printf (&ret, "%s", tap_reg->guid);
- return BSTR (&ret);
-}
-
-/*
- * Lookup a --dev-node adapter name in the registry
- * returning the GUID and optional actual_name.
- */
-static const char *
-get_device_guid (const char *name,
- char *actual_name,
- int actual_name_size,
- const struct tap_reg *tap_reg,
- const struct panel_reg *panel_reg,
- struct gc_arena *gc)
-{
- struct buffer ret = alloc_buf_gc (256, gc);
- struct buffer actual = clear_buf ();
-
- /* Make sure we have at least one TAP adapter */
- if (!tap_reg)
- return NULL;
-
- /* The actual_name output buffer may be NULL */
- if (actual_name)
- {
- ASSERT (actual_name_size > 0);
- buf_set_write (&actual, actual_name, actual_name_size);
- }
-
- /* Check if GUID was explicitly specified as --dev-node parameter */
- if (is_tap_win32 (name, tap_reg))
- {
- const char *act = guid_to_name (name, panel_reg);
- buf_printf (&ret, "%s", name);
- if (act)
- buf_printf (&actual, "%s", act);
- else
- buf_printf (&actual, "NULL");
- return BSTR (&ret);
- }
-
- /* Lookup TAP adapter in network connections list */
- {
- const char *guid = name_to_guid (name, tap_reg, panel_reg);
- if (guid)
- {
- buf_printf (&actual, "%s", name);
- buf_printf (&ret, "%s", guid);
- return BSTR (&ret);
- }
- }
-
- return NULL;
-}
-
-/*
- * Return a TAP name for netsh commands.
- */
-const char *
-get_netsh_id (const char *dev_node, struct gc_arena *gc)
-{
- const struct tap_reg *tap_reg = get_tap_reg (gc);
- const struct panel_reg *panel_reg = get_panel_reg (gc);
- struct buffer actual = alloc_buf_gc (256, gc);
- const char *guid;
-
- at_least_one_tap_win32 (tap_reg);
-
- if (dev_node)
- {
- guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
- }
- else
- {
- guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
-
- if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */
- guid = NULL;
- }
-
- if (!guid)
- return "NULL"; /* not found */
- else if (strcmp (BPTR (&actual), "NULL"))
- return BPTR (&actual); /* control panel name */
- else
- return guid; /* no control panel name, return GUID instead */
-}
-
-/*
- * Get adapter info list
- */
-const IP_ADAPTER_INFO *
-get_adapter_info_list (struct gc_arena *gc)
-{
- ULONG size = 0;
- IP_ADAPTER_INFO *pi = NULL;
- DWORD status;
-
- if ((status = GetAdaptersInfo (NULL, &size)) != ERROR_BUFFER_OVERFLOW)
- {
- msg (M_INFO, "GetAdaptersInfo #1 failed (status=%u) : %s",
- (unsigned int)status,
- strerror_win32 (status, gc));
- }
- else
- {
- pi = (PIP_ADAPTER_INFO) gc_malloc (size, false, gc);
- if ((status = GetAdaptersInfo (pi, &size)) == NO_ERROR)
- return pi;
- else
- {
- msg (M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s",
- (unsigned int)status,
- strerror_win32 (status, gc));
- }
- }
- return pi;
-}
-
-static const IP_INTERFACE_INFO *
-get_interface_info_list (struct gc_arena *gc)
-{
- ULONG size = 0;
- IP_INTERFACE_INFO *ii = NULL;
- DWORD status;
-
- if ((status = GetInterfaceInfo (NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
- {
- msg (M_INFO, "GetInterfaceInfo #1 failed (status=%u) : %s",
- (unsigned int)status,
- strerror_win32 (status, gc));
- }
- else
- {
- ii = (PIP_INTERFACE_INFO) gc_malloc (size, false, gc);
- if ((status = GetInterfaceInfo (ii, &size)) == NO_ERROR)
- return ii;
- else
- {
- msg (M_INFO, "GetInterfaceInfo #2 failed (status=%u) : %s",
- (unsigned int)status,
- strerror_win32 (status, gc));
- }
- }
- return ii;
-}
-
-static const IP_ADAPTER_INDEX_MAP *
-get_interface_info (DWORD index, struct gc_arena *gc)
-{
- const IP_INTERFACE_INFO *list = get_interface_info_list (gc);
- if (list)
- {
- int i;
- for (i = 0; i < list->NumAdapters; ++i)
- {
- const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
- if (index == inter->Index)
- return inter;
- }
- }
- return NULL;
-}
-
-/*
- * Given an adapter index, return a pointer to the
- * IP_ADAPTER_INFO structure for that adapter.
- */
-
-static const IP_ADAPTER_INFO *
-get_adapter (const IP_ADAPTER_INFO *ai, DWORD index)
-{
- if (ai && index != (DWORD)~0)
- {
- const IP_ADAPTER_INFO *a;
-
- /* find index in the linked list */
- for (a = ai; a != NULL; a = a->Next)
- {
- if (a->Index == index)
- return a;
- }
- }
- return NULL;
-}
-
-static const IP_ADAPTER_INFO *
-get_adapter_info (DWORD index, struct gc_arena *gc)
-{
- return get_adapter (get_adapter_info_list (gc), index);
-}
-
-static int
-get_adapter_n_ip_netmask (const IP_ADAPTER_INFO *ai)
-{
- if (ai)
- {
- int n = 0;
- const IP_ADDR_STRING *ip = &ai->IpAddressList;
-
- while (ip)
- {
- ++n;
- ip = ip->Next;
- }
- return n;
- }
- else
- return 0;
-}
-
-static bool
-get_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
-{
- bool ret = false;
- *ip = 0;
- *netmask = 0;
-
- if (ai)
- {
- const IP_ADDR_STRING *iplist = &ai->IpAddressList;
- int i = 0;
-
- while (iplist)
- {
- if (i == n)
- break;
- ++i;
- iplist = iplist->Next;
- }
-
- if (iplist)
- {
- const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
- const char *ip_str = iplist->IpAddress.String;
- const char *netmask_str = iplist->IpMask.String;
- bool succeed1 = false;
- bool succeed2 = false;
-
- if (ip_str && netmask_str && strlen (ip_str) && strlen (netmask_str))
- {
- *ip = getaddr (getaddr_flags, ip_str, 0, &succeed1, NULL);
- *netmask = getaddr (getaddr_flags, netmask_str, 0, &succeed2, NULL);
- ret = (succeed1 == true && succeed2 == true);
- }
- }
- }
-
- return ret;
-}
-
-const IP_ADAPTER_INFO *
-get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
-{
- if (list && tt)
- return get_adapter (list, tt->adapter_index);
- else
- return NULL;
-}
-
-bool
-is_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
-{
- int i;
- bool ret = false;
-
- const IP_ADAPTER_INFO *ai = get_tun_adapter (tt, list);
-
- if (ai)
- {
- const int n = get_adapter_n_ip_netmask (ai);
-
- /* loop once for every IP/netmask assigned to adapter */
- for (i = 0; i < n; ++i)
- {
- in_addr_t ip, netmask;
- if (get_adapter_ip_netmask (ai, i, &ip, &netmask))
- {
- if (tt->local && tt->adapter_netmask)
- {
- /* wait for our --ifconfig parms to match the actual adapter parms */
- if (tt->local == ip && tt->adapter_netmask == netmask)
- ret = true;
- }
- else
- {
- /* --ifconfig was not defined, maybe using a real DHCP server */
- if (ip && netmask)
- ret = true;
- }
- }
- }
- }
- else
- ret = true; /* this can occur when TAP adapter is bridged */
-
- return ret;
-}
-
-bool
-is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
-{
- int i;
- bool ret = false;
-
- if (highest_netmask)
- *highest_netmask = 0;
-
- if (ai)
- {
- const int n = get_adapter_n_ip_netmask (ai);
- for (i = 0; i < n; ++i)
- {
- in_addr_t adapter_ip, adapter_netmask;
- if (get_adapter_ip_netmask (ai, i, &adapter_ip, &adapter_netmask))
- {
- if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
- {
- if (highest_netmask && adapter_netmask > *highest_netmask)
- *highest_netmask = adapter_netmask;
- ret = true;
- }
- }
- }
- }
- return ret;
-}
-
-DWORD
-adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count)
-{
- struct gc_arena gc = gc_new ();
- DWORD ret = ~0;
- in_addr_t highest_netmask = 0;
- bool first = true;
-
- if (count)
- *count = 0;
-
- while (list)
- {
- in_addr_t hn;
-
- if (is_ip_in_adapter_subnet (list, ip, &hn))
- {
- if (first || hn > highest_netmask)
- {
- highest_netmask = hn;
- if (count)
- *count = 1;
- ret = list->Index;
- first = false;
- }
- else if (hn == highest_netmask)
- {
- if (count)
- ++*count;
- }
- }
- list = list->Next;
- }
-
- dmsg (D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d",
- print_in_addr_t (ip, 0, &gc),
- print_in_addr_t (highest_netmask, 0, &gc),
- (int)ret,
- count ? *count : -1);
-
- if (ret == ~0 && count)
- *count = 0;
-
- gc_free (&gc);
- return ret;
-}
-
-/*
- * Given an adapter index, return true if the adapter
- * is DHCP disabled.
- */
-static bool
-dhcp_disabled (DWORD index)
-{
- struct gc_arena gc = gc_new ();
- const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc);
- bool ret = false;
-
- if (ai && !ai->DhcpEnabled)
- ret = true;
-
- gc_free (&gc);
- return ret;
-}
-
-/*
- * Delete all temporary address/netmask pairs which were added
- * to adapter (given by index) by previous calls to AddIPAddress.
- */
-static void
-delete_temp_addresses (DWORD index)
-{
- struct gc_arena gc = gc_new ();
- const IP_ADAPTER_INFO *a = get_adapter_info (index, &gc);
-
- if (a)
- {
- const IP_ADDR_STRING *ip = &a->IpAddressList;
- while (ip)
- {
- DWORD status;
- const DWORD context = ip->Context;
-
- if ((status = DeleteIPAddress ((ULONG) context)) == NO_ERROR)
- {
- msg (M_INFO, "Successfully deleted previously set dynamic IP/netmask: %s/%s",
- ip->IpAddress.String,
- ip->IpMask.String);
- }
- else
- {
- const char *empty = "0.0.0.0";
- if (strcmp (ip->IpAddress.String, empty)
- || strcmp (ip->IpMask.String, empty))
- msg (M_INFO, "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
- ip->IpAddress.String,
- ip->IpMask.String,
- (unsigned int)status);
- }
- ip = ip->Next;
- }
- }
- gc_free (&gc);
-}
-
-/*
- * Get interface index for use with IP Helper API functions.
- */
-static DWORD
-get_interface_index (const char *guid)
-{
- struct gc_arena gc = gc_new ();
- ULONG index;
- DWORD status;
- wchar_t wbuf[256];
- snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid);
- wbuf [SIZE(wbuf) - 1] = 0;
- if ((status = GetAdapterIndex (wbuf, &index)) != NO_ERROR)
- {
- msg (M_INFO, "NOTE: could not get adapter index for %S, status=%u : %s",
- wbuf,
- (unsigned int)status,
- strerror_win32 (status, &gc));
- gc_free (&gc);
- return (DWORD)~0;
- }
- else
- {
- gc_free (&gc);
- return index;
- }
-}
-
-/*
- * Return a string representing a PIP_ADDR_STRING
- */
-static const char *
-format_ip_addr_string (const IP_ADDR_STRING *ip, struct gc_arena *gc)
-{
- struct buffer out = alloc_buf_gc (256, gc);
- while (ip)
- {
- buf_printf (&out, "%s", ip->IpAddress.String);
- if (strlen (ip->IpMask.String))
- {
- buf_printf (&out, "/");
- buf_printf (&out, "%s", ip->IpMask.String);
- }
- buf_printf (&out, " ");
- ip = ip->Next;
- }
- return BSTR (&out);
-}
-
-/*
- * Show info for a single adapter
- */
-static void
-show_adapter (int msglev, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
-{
- msg (msglev, "%s", a->Description);
- msg (msglev, " Index = %d", (int)a->Index);
- msg (msglev, " GUID = %s", a->AdapterName);
- msg (msglev, " IP = %s", format_ip_addr_string (&a->IpAddressList, gc));
- msg (msglev, " MAC = %s", format_hex_ex (a->Address, a->AddressLength, 0, 1, ":", gc));
- msg (msglev, " GATEWAY = %s", format_ip_addr_string (&a->GatewayList, gc));
- if (a->DhcpEnabled)
- {
- msg (msglev, " DHCP SERV = %s", format_ip_addr_string (&a->DhcpServer, gc));
- msg (msglev, " DHCP LEASE OBTAINED = %s", time_string (a->LeaseObtained, 0, false, gc));
- msg (msglev, " DHCP LEASE EXPIRES = %s", time_string (a->LeaseExpires, 0, false, gc));
- }
- if (a->HaveWins)
- {
- msg (msglev, " PRI WINS = %s", format_ip_addr_string (&a->PrimaryWinsServer, gc));
- msg (msglev, " SEC WINS = %s", format_ip_addr_string (&a->SecondaryWinsServer, gc));
- }
-}
-
-/*
- * Show current adapter list
- */
-void
-show_adapters (int msglev)
-{
- struct gc_arena gc = gc_new ();
- const IP_ADAPTER_INFO *ai = get_adapter_info_list (&gc);
-
- msg (msglev, "SYSTEM ADAPTER LIST");
- if (ai)
- {
- const IP_ADAPTER_INFO *a;
-
- /* find index in the linked list */
- for (a = ai; a != NULL; a = a->Next)
- {
- show_adapter (msglev, a, &gc);
- }
- }
- gc_free (&gc);
-}
-
-/*
- * DHCP release/renewal
- */
-
-bool
-dhcp_release (const struct tuntap *tt)
-{
- struct gc_arena gc = gc_new ();
- bool ret = false;
- if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
- {
- const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (tt->adapter_index, &gc);
- if (inter)
- {
- DWORD status = IpReleaseAddress ((IP_ADAPTER_INDEX_MAP *)inter);
- if (status == NO_ERROR)
- {
- msg (D_TUNTAP_INFO, "TAP: DHCP address released");
- ret = true;
- }
- else
- msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Win32 adapter failed: %s (code=%u)",
- strerror_win32 (status, &gc),
- (unsigned int)status);
- }
- }
- gc_free (&gc);
- return ret;
-}
-
-bool
-dhcp_renew (const struct tuntap *tt)
-{
- struct gc_arena gc = gc_new ();
- bool ret = false;
- if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
- {
- const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (tt->adapter_index, &gc);
- if (inter)
- {
- DWORD status = IpRenewAddress ((IP_ADAPTER_INDEX_MAP *)inter);
- if (status == NO_ERROR)
- {
- msg (D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
- ret = true;
- }
- else
- msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Win32 adapter: %s (code=%u)",
- strerror_win32 (status, &gc),
- (unsigned int)status);
- }
- }
- gc_free (&gc);
- return ret;
-}
-
-/*
- * Convert DHCP options from the command line / config file
- * into a raw DHCP-format options string.
- */
-
-static void
-write_dhcp_u8 (struct buffer *buf, const int type, const int data)
-{
- if (!buf_safe (buf, 3))
- msg (M_FATAL, "write_dhcp_u8: buffer overflow building DHCP options");
- buf_write_u8 (buf, type);
- buf_write_u8 (buf, 1);
- buf_write_u8 (buf, data);
-}
-
-static void
-write_dhcp_u32_array (struct buffer *buf, const int type, const uint32_t *data, const unsigned int len)
-{
- if (len > 0)
- {
- int i;
- const int size = len * sizeof (uint32_t);
-
- if (!buf_safe (buf, 2 + size))
- msg (M_FATAL, "write_dhcp_u32_array: buffer overflow building DHCP options");
- if (size < 1 || size > 255)
- msg (M_FATAL, "write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
- buf_write_u8 (buf, type);
- buf_write_u8 (buf, size);
- for (i = 0; i < len; ++i)
- buf_write_u32 (buf, data[i]);
- }
-}
-
-static void
-write_dhcp_str (struct buffer *buf, const int type, const char *str)
-{
- const int len = strlen (str);
- if (!buf_safe (buf, 2 + len))
- msg (M_FATAL, "write_dhcp_str: buffer overflow building DHCP options");
- if (len < 1 || len > 255)
- msg (M_FATAL, "write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes", str);
- buf_write_u8 (buf, type);
- buf_write_u8 (buf, len);
- buf_write (buf, str, len);
-}
-
-static void
-build_dhcp_options_string (struct buffer *buf, const struct tuntap_options *o)
-{
- if (o->domain)
- write_dhcp_str (buf, 15, o->domain);
-
- if (o->netbios_scope)
- write_dhcp_str (buf, 47, o->netbios_scope);
-
- if (o->netbios_node_type)
- write_dhcp_u8 (buf, 46, o->netbios_node_type);
-
- write_dhcp_u32_array (buf, 6, (uint32_t*)o->dns, o->dns_len);
- write_dhcp_u32_array (buf, 44, (uint32_t*)o->wins, o->wins_len);
- write_dhcp_u32_array (buf, 42, (uint32_t*)o->ntp, o->ntp_len);
- write_dhcp_u32_array (buf, 45, (uint32_t*)o->nbdd, o->nbdd_len);
-
- /* the MS DHCP server option 'Disable Netbios-over-TCP/IP
- is implemented as vendor option 001, value 002.
- A value of 001 means 'leave NBT alone' which is the default */
- if (o->disable_nbt)
- {
- buf_write_u8 (buf, 43);
- buf_write_u8 (buf, 6); /* total length field */
- buf_write_u8 (buf, 0x001);
- buf_write_u8 (buf, 4); /* length of the vendor specified field */
- buf_write_u32 (buf, 0x002);
- }
-}
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- struct gc_arena gc = gc_new ();
- char device_path[256];
- const char *device_guid = NULL;
- DWORD len;
-
- /*netcmd_semaphore_lock ();*/
-
- ipv6_support (ipv6, false, tt);
-
- if (tt->type == DEV_TYPE_NULL)
- {
- open_null (tt);
- gc_free (&gc);
- return;
- }
- else if (tt->type == DEV_TYPE_TAP || tt->type == DEV_TYPE_TUN)
- {
- ;
- }
- else
- {
- msg (M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
- }
-
- /*
- * Lookup the device name in the registry, using the --dev-node high level name.
- */
- {
- const struct tap_reg *tap_reg = get_tap_reg (&gc);
- const struct panel_reg *panel_reg = get_panel_reg (&gc);
- char guid_buffer[256];
-
- at_least_one_tap_win32 (tap_reg);
-
- if (dev_node)
- {
- /* Get the device GUID for the device specified with --dev-node. */
- device_guid = get_device_guid (dev_node, guid_buffer, sizeof (guid_buffer), tap_reg, panel_reg, &gc);
-
- if (!device_guid)
- msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node);
-
- /* Open Windows TAP-Win32 adapter */
- openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
- USERMODEDEVICEDIR,
- device_guid,
- TAPSUFFIX);
-
- tt->hand = CreateFile (
- device_path,
- GENERIC_READ | GENERIC_WRITE,
- 0, /* was: FILE_SHARE_READ */
- 0,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
- 0
- );
-
- if (tt->hand == INVALID_HANDLE_VALUE)
- msg (M_ERR, "CreateFile failed on TAP device: %s", device_path);
- }
- else
- {
- int device_number = 0;
-
- /* Try opening all TAP devices until we find one available */
- while (true)
- {
- device_guid = get_unspecified_device_guid (device_number,
- guid_buffer,
- sizeof (guid_buffer),
- tap_reg,
- panel_reg,
- &gc);
-
- if (!device_guid)
- msg (M_FATAL, "All TAP-Win32 adapters on this system are currently in use.");
-
- /* Open Windows TAP-Win32 adapter */
- openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
- USERMODEDEVICEDIR,
- device_guid,
- TAPSUFFIX);
-
- tt->hand = CreateFile (
- device_path,
- GENERIC_READ | GENERIC_WRITE,
- 0, /* was: FILE_SHARE_READ */
- 0,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
- 0
- );
-
- if (tt->hand == INVALID_HANDLE_VALUE)
- msg (D_TUNTAP_INFO, "CreateFile failed on TAP device: %s", device_path);
- else
- break;
-
- device_number++;
- }
- }
-
- /* translate high-level device name into a device instance
- GUID using the registry */
- tt->actual_name = string_alloc (guid_buffer, NULL);
- }
-
- msg (M_INFO, "TAP-WIN32 device [%s] opened: %s", tt->actual_name, device_path);
-
- /* get driver version info */
- {
- ULONG info[3];
- CLEAR (info);
- if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_VERSION,
- &info, sizeof (info),
- &info, sizeof (info), &len, NULL))
- {
- msg (D_TUNTAP_INFO, "TAP-Win32 Driver Version %d.%d %s",
- (int) info[0],
- (int) info[1],
- (info[2] ? "(DEBUG)" : ""));
-
- }
- if ( !(info[0] > TAP_WIN32_MIN_MAJOR
- || (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) )
- msg (M_FATAL, "ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
- TAP_WIN32_MIN_MAJOR,
- TAP_WIN32_MIN_MINOR);
- }
-
- /* get driver MTU */
- {
- ULONG mtu;
- if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_MTU,
- &mtu, sizeof (mtu),
- &mtu, sizeof (mtu), &len, NULL))
- {
- tt->post_open_mtu = (int) mtu;
- msg (D_MTU_INFO, "TAP-Win32 MTU=%d", (int) mtu);
- }
- }
-
- /* set point-to-point mode if TUN device */
-
- if (tt->type == DEV_TYPE_TUN)
- {
- in_addr_t ep[2];
- ep[0] = htonl (tt->local);
- ep[1] = htonl (tt->remote_netmask);
- if (!tt->did_ifconfig_setup)
- {
- msg (M_FATAL, "ERROR: --dev tun also requires --ifconfig");
- }
- if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_POINT_TO_POINT,
- ep, sizeof (ep),
- ep, sizeof (ep), &len, NULL))
- msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
- }
-
- /* should we tell the TAP-Win32 driver to masquerade as a DHCP server as a means
- of setting the adapter address? */
- if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ)
- {
- uint32_t ep[4];
-
- /* We will answer DHCP requests with a reply to set IP/subnet to these values */
- ep[0] = htonl (tt->local);
- ep[1] = htonl (tt->adapter_netmask);
-
- /* At what IP address should the DHCP server masquerade at? */
- if (tt->type == DEV_TYPE_TUN)
- {
- ep[2] = htonl (tt->remote_netmask);
- if (tt->options.dhcp_masq_custom_offset)
- msg (M_WARN, "WARNING: because you are using '--dev tun' mode, the '--ip-win32 dynamic [offset]' option is ignoring the offset parameter");
- }
- else
- {
- in_addr_t dsa; /* DHCP server addr */
-
- ASSERT (tt->type == DEV_TYPE_TAP);
-
- if (tt->options.dhcp_masq_offset < 0)
- dsa = (tt->local | (~tt->adapter_netmask)) + tt->options.dhcp_masq_offset;
- else
- dsa = (tt->local & tt->adapter_netmask) + tt->options.dhcp_masq_offset;
-
- if (dsa == tt->local)
- msg (M_FATAL, "ERROR: There is a clash between the --ifconfig local address and the internal DHCP server address -- both are set to %s -- please use the --ip-win32 dynamic option to choose a different free address from the --ifconfig subnet for the internal DHCP server", print_in_addr_t (dsa, 0, &gc));
-
- if ((tt->local & tt->adapter_netmask) != (dsa & tt->adapter_netmask))
- msg (M_FATAL, "ERROR: --tap-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
-
- ep[2] = htonl (dsa);
- }
-
- /* lease time in seconds */
- ep[3] = (uint32_t) tt->options.dhcp_lease_time;
-
- ASSERT (ep[3] > 0);
-
- if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_MASQ,
- ep, sizeof (ep),
- ep, sizeof (ep), &len, NULL))
- msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set TAP_IOCTL_CONFIG_DHCP_MASQ mode");
-
- msg (M_INFO, "Notified TAP-Win32 driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
- print_in_addr_t (tt->local, 0, &gc),
- print_in_addr_t (tt->adapter_netmask, 0, &gc),
- device_guid,
- print_in_addr_t (ep[2], IA_NET_ORDER, &gc),
- ep[3]
- );
-
- /* user-supplied DHCP options capability */
- if (tt->options.dhcp_options)
- {
- struct buffer buf = alloc_buf (256);
- build_dhcp_options_string (&buf, &tt->options);
- msg (D_DHCP_OPT, "DHCP option string: %s", format_hex (BPTR (&buf), BLEN (&buf), 0, &gc));
- if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_SET_OPT,
- BPTR (&buf), BLEN (&buf),
- BPTR (&buf), BLEN (&buf), &len, NULL))
- msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a TAP_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
- free_buf (&buf);
- }
- }
-
- /* set driver media status to 'connected' */
- {
- ULONG status = TRUE;
- if (!DeviceIoControl (tt->hand, TAP_IOCTL_SET_MEDIA_STATUS,
- &status, sizeof (status),
- &status, sizeof (status), &len, NULL))
- msg (M_WARN, "WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
- }
-
- /* possible wait for adapter to come up */
- {
- int s = tt->options.tap_sleep;
- if (s > 0)
- {
- msg (M_INFO, "Sleeping for %d seconds...", s);
- openvpn_sleep (s);
- }
- }
-
- /* possibly use IP Helper API to set IP address on adapter */
- {
- DWORD index = get_interface_index (device_guid);
- tt->adapter_index = index;
-
- /* flush arp cache */
- if (index != (DWORD)~0)
- {
- DWORD status;
-
- if ((status = FlushIpNetTable (index)) == NO_ERROR)
- msg (M_INFO, "Successful ARP Flush on interface [%u] %s",
- (unsigned int)index,
- device_guid);
- else
- msg (M_WARN, "NOTE: FlushIpNetTable failed on interface [%u] %s (status=%u) : %s",
- (unsigned int)index,
- device_guid,
- (unsigned int)status,
- strerror_win32 (status, &gc));
- }
-
- /*
- * If the TAP-Win32 driver is masquerading as a DHCP server
- * make sure the TCP/IP properties for the adapter are
- * set correctly.
- */
- if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ)
- {
- /* check dhcp enable status */
- if (dhcp_disabled (index))
- msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'");
-
- /* force an explicit DHCP lease renewal on TAP adapter? */
- if (tt->options.dhcp_pre_release)
- dhcp_release (tt);
- if (tt->options.dhcp_renew)
- dhcp_renew (tt);
- }
-
- if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_IPAPI)
- {
- DWORD status;
- const char *error_suffix = "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
-
- /* couldn't get adapter index */
- if (index == (DWORD)~0)
- {
- msg (M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s",
- device_guid,
- error_suffix);
- }
-
- /* check dhcp enable status */
- if (dhcp_disabled (index))
- msg (M_WARN, "NOTE: You have selected (explicitly or by default) '--ip-win32 ipapi', which has a better chance of working correctly if the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'");
-
- /* delete previously added IP addresses which were not
- correctly deleted */
- delete_temp_addresses (index);
-
- /* add a new IP address */
- if ((status = AddIPAddress (htonl(tt->local),
- htonl(tt->adapter_netmask),
- index,
- &tt->ipapi_context,
- &tt->ipapi_instance)) == NO_ERROR)
- msg (M_INFO, "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
- print_in_addr_t (tt->local, 0, &gc),
- print_in_addr_t (tt->adapter_netmask, 0, &gc),
- device_guid
- );
- else
- msg (M_FATAL, "ERROR: AddIPAddress %s/%s failed on interface %s, index=%d, status=%u (windows error: '%s') -- %s",
- print_in_addr_t (tt->local, 0, &gc),
- print_in_addr_t (tt->adapter_netmask, 0, &gc),
- device_guid,
- (int)index,
- (unsigned int)status,
- strerror_win32 (status, &gc),
- error_suffix);
- tt->ipapi_context_defined = true;
- }
- }
- /*netcmd_semaphore_release ();*/
- gc_free (&gc);
-}
-
-const char *
-tap_win32_getinfo (const struct tuntap *tt, struct gc_arena *gc)
-{
- if (tt && tt->hand != NULL)
- {
- struct buffer out = alloc_buf_gc (256, gc);
- DWORD len;
- if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_INFO,
- BSTR (&out), BCAP (&out),
- BSTR (&out), BCAP (&out),
- &len, NULL))
- {
- return BSTR (&out);
- }
- }
- return NULL;
-}
-
-void
-tun_show_debug (struct tuntap *tt)
-{
- if (tt && tt->hand != NULL)
- {
- struct buffer out = alloc_buf (1024);
- DWORD len;
- while (DeviceIoControl (tt->hand, TAP_IOCTL_GET_LOG_LINE,
- BSTR (&out), BCAP (&out),
- BSTR (&out), BCAP (&out),
- &len, NULL))
- {
- msg (D_TAP_WIN32_DEBUG, "TAP-Win32: %s", BSTR (&out));
- }
- free_buf (&out);
- }
-}
-
-void
-close_tun (struct tuntap *tt)
-{
- struct gc_arena gc = gc_new ();
-
- if (tt)
- {
-#if 1
- if (tt->ipapi_context_defined)
- {
- DWORD status;
- if ((status = DeleteIPAddress (tt->ipapi_context)) != NO_ERROR)
- {
- msg (M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Win32 adapter, status=%u : %s",
- (unsigned int)tt->ipapi_context,
- (unsigned int)status,
- strerror_win32 (status, &gc));
- }
- }
-#endif
-
- if (tt->options.dhcp_release)
- dhcp_release (tt);
-
- if (tt->hand != NULL)
- {
- dmsg (D_WIN32_IO_LOW, "Attempting CancelIO on TAP-Win32 adapter");
- if (!CancelIo (tt->hand))
- msg (M_WARN | M_ERRNO, "Warning: CancelIO failed on TAP-Win32 adapter");
- }
-
- dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped read event on TAP-Win32 adapter");
- overlapped_io_close (&tt->reads);
-
- dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped write event on TAP-Win32 adapter");
- overlapped_io_close (&tt->writes);
-
- if (tt->hand != NULL)
- {
- dmsg (D_WIN32_IO_LOW, "Attempting CloseHandle on TAP-Win32 adapter");
- if (!CloseHandle (tt->hand))
- msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on TAP-Win32 adapter");
- }
-
- if (tt->actual_name)
- free (tt->actual_name);
-
- clear_tuntap (tt);
- free (tt);
- }
- gc_free (&gc);
-}
-
-/*
- * Convert --ip-win32 constants between index and ascii form.
- */
-
-struct ipset_names {
- const char *short_form;
-};
-
-/* Indexed by IPW32_SET_x */
-static const struct ipset_names ipset_names[] = {
- {"manual"},
- {"netsh"},
- {"ipapi"},
- {"dynamic"}
-};
-
-int
-ascii2ipset (const char* name)
-{
- int i;
- ASSERT (IPW32_SET_N == SIZE (ipset_names));
- for (i = 0; i < IPW32_SET_N; ++i)
- if (!strcmp (name, ipset_names[i].short_form))
- return i;
- return -1;
-}
-
-const char *
-ipset2ascii (int index)
-{
- ASSERT (IPW32_SET_N == SIZE (ipset_names));
- if (index < 0 || index >= IPW32_SET_N)
- return "[unknown --ip-win32 type]";
- else
- return ipset_names[index].short_form;
-}
-
-const char *
-ipset2ascii_all (struct gc_arena *gc)
-{
- struct buffer out = alloc_buf_gc (256, gc);
- int i;
-
- ASSERT (IPW32_SET_N == SIZE (ipset_names));
- for (i = 0; i < IPW32_SET_N; ++i)
- {
- if (i)
- buf_printf(&out, " ");
- buf_printf(&out, "[%s]", ipset2ascii(i));
- }
- return BSTR (&out);
-}
-
-#else /* generic */
-
-void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
-{
- open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
-}
-
-void
-close_tun (struct tuntap* tt)
-{
- if (tt)
- {
- close_tun_generic (tt);
- free (tt);
- }
-}
-
-int
-write_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- return write (tt->fd, buf, len);
-}
-
-int
-read_tun (struct tuntap* tt, uint8_t *buf, int len)
-{
- return read (tt->fd, buf, len);
-}
-
-#endif
diff --git a/openvpn/tun.h b/openvpn/tun.h
deleted file mode 100644
index 76c4867..0000000
--- a/openvpn/tun.h
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef TUN_H
-#define TUN_H
-
-#ifdef WIN32
-#include <winioctl.h>
-#include "tap-win32/common.h"
-#endif
-
-#include "buffer.h"
-#include "error.h"
-#include "mtu.h"
-#include "win32.h"
-#include "event.h"
-#include "proto.h"
-#include "misc.h"
-
-#ifdef WIN32
-
-struct tuntap_options {
- /* --ip-win32 options */
- bool ip_win32_defined;
-
-# define IPW32_SET_MANUAL 0 /* "--ip-win32 manual" */
-# define IPW32_SET_NETSH 1 /* "--ip-win32 netsh" */
-# define IPW32_SET_IPAPI 2 /* "--ip-win32 ipapi" */
-# define IPW32_SET_DHCP_MASQ 3 /* "--ip-win32 dynamic" */
-# define IPW32_SET_N 4
- int ip_win32_type;
-
- /* --ip-win32 dynamic options */
- bool dhcp_masq_custom_offset;
- int dhcp_masq_offset;
- int dhcp_lease_time;
-
- /* --tap-sleep option */
- int tap_sleep;
-
- /* --dhcp-option options */
-
- bool dhcp_options;
-
- const char *domain; /* DOMAIN (15) */
-
- const char *netbios_scope; /* NBS (47) */
-
- int netbios_node_type; /* NBT 1,2,4,8 (46) */
-
-#define N_DHCP_ADDR 4 /* Max # of addresses allowed for
- DNS, WINS, etc. */
-
- /* DNS (6) */
- in_addr_t dns[N_DHCP_ADDR];
- int dns_len;
-
- /* WINS (44) */
- in_addr_t wins[N_DHCP_ADDR];
- int wins_len;
-
- /* NTP (42) */
- in_addr_t ntp[N_DHCP_ADDR];
- int ntp_len;
-
- /* NBDD (45) */
- in_addr_t nbdd[N_DHCP_ADDR];
- int nbdd_len;
-
- /* DISABLE_NBT (43, Vendor option 001) */
- bool disable_nbt;
-
- bool dhcp_renew;
- bool dhcp_pre_release;
- bool dhcp_release;
-};
-
-#elif TARGET_LINUX
-
-struct tuntap_options {
- int txqueuelen;
-};
-
-#else
-
-struct tuntap_options {
- int dummy; /* not used */
-};
-
-#endif
-
-/*
- * Define a TUN/TAP dev.
- */
-
-struct tuntap
-{
-# define TUNNEL_TYPE(tt) ((tt) ? ((tt)->type) : DEV_TYPE_UNDEF)
- int type; /* DEV_TYPE_x as defined in proto.h */
-
- bool did_ifconfig_setup;
- bool did_ifconfig;
-
- bool ipv6;
-
- struct tuntap_options options; /* options set on command line */
-
- char *actual_name; /* actual name of TUN/TAP dev, usually including unit number */
-
- /* number of TX buffers */
- int txqueuelen;
-
- /* ifconfig parameters */
- in_addr_t local;
- in_addr_t remote_netmask;
- in_addr_t broadcast;
-
-#ifdef WIN32
- HANDLE hand;
- struct overlapped_io reads;
- struct overlapped_io writes;
- struct rw_handle rw_handle;
-
- /* used for setting interface address via IP Helper API
- or DHCP masquerade */
- bool ipapi_context_defined;
- ULONG ipapi_context;
- ULONG ipapi_instance;
- in_addr_t adapter_netmask;
-
- /* Windows adapter index for TAP-Win32 adapter,
- ~0 if undefined */
- DWORD adapter_index;
-#else
- int fd; /* file descriptor for TUN/TAP dev */
-#endif
-
-#ifdef TARGET_SOLARIS
- int ip_fd;
-#endif
-
- /* used for printing status info only */
- unsigned int rwflags_debug;
-
- /* Some TUN/TAP drivers like to be ioctled for mtu
- after open */
- int post_open_mtu;
-};
-
-static inline bool
-tuntap_defined (const struct tuntap *tt)
-{
-#ifdef WIN32
- return tt && tt->hand != NULL;
-#else
- return tt && tt->fd >= 0;
-#endif
-}
-
-/*
- * Function prototypes
- */
-
-void clear_tuntap (struct tuntap *tuntap);
-
-void open_tun (const char *dev, const char *dev_type, const char *dev_node,
- bool ipv6, struct tuntap *tt);
-
-void close_tun (struct tuntap *tt);
-
-int write_tun (struct tuntap* tt, uint8_t *buf, int len);
-
-int read_tun (struct tuntap* tt, uint8_t *buf, int len);
-
-void tuncfg (const char *dev, const char *dev_type, const char *dev_node,
- bool ipv6, int persist_mode);
-
-const char *guess_tuntap_dev (const char *dev,
- const char *dev_type,
- const char *dev_node,
- struct gc_arena *gc);
-
-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 */
- in_addr_t local_public,
- in_addr_t remote_public,
- const bool strict_warn,
- struct env_set *es);
-
-void init_tun_post (struct tuntap *tt,
- const struct frame *frame,
- const struct tuntap_options *options);
-
-void do_ifconfig (struct tuntap *tt,
- const char *actual, /* actual device name */
- int tun_mtu,
- const struct env_set *es);
-
-const char *dev_component_in_dev_node (const char *dev_node);
-
-bool is_dev_type (const char *dev, const char *dev_type, const char *match_type);
-int dev_type_enum (const char *dev, const char *dev_type);
-const char *dev_type_string (const char *dev, const char *dev_type);
-
-const char *ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, struct gc_arena *gc);
-
-/*
- * Inline functions
- */
-
-static inline void
-tun_adjust_frame_parameters (struct frame* frame, int size)
-{
- frame_add_to_extra_tun (frame, size);
-}
-
-/*
- * Should ifconfig be called before or after
- * tun dev open?
- */
-
-#define IFCONFIG_BEFORE_TUN_OPEN 0
-#define IFCONFIG_AFTER_TUN_OPEN 1
-
-#define IFCONFIG_DEFAULT IFCONFIG_AFTER_TUN_OPEN
-
-static inline int
-ifconfig_order(void)
-{
-#if defined(TARGET_LINUX)
- return IFCONFIG_AFTER_TUN_OPEN;
-#elif defined(TARGET_SOLARIS)
- return IFCONFIG_AFTER_TUN_OPEN;
-#elif defined(TARGET_OPENBSD)
- return IFCONFIG_BEFORE_TUN_OPEN;
-#elif defined(TARGET_DARWIN)
- return IFCONFIG_AFTER_TUN_OPEN;
-#elif defined(TARGET_NETBSD)
- return IFCONFIG_AFTER_TUN_OPEN;
-#elif defined(WIN32)
- return IFCONFIG_BEFORE_TUN_OPEN;
-#else
- return IFCONFIG_DEFAULT;
-#endif
-}
-
-#ifdef WIN32
-
-#define TUN_PASS_BUFFER
-
-struct tap_reg
-{
- const char *guid;
- struct tap_reg *next;
-};
-
-struct panel_reg
-{
- const char *name;
- const char *guid;
- struct panel_reg *next;
-};
-
-int ascii2ipset (const char* name);
-const char *ipset2ascii (int index);
-const char *ipset2ascii_all (struct gc_arena *gc);
-
-void verify_255_255_255_252 (in_addr_t local, in_addr_t remote);
-
-const IP_ADAPTER_INFO *get_adapter_info_list (struct gc_arena *gc);
-const IP_ADAPTER_INFO *get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list);
-bool is_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list);
-bool is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask);
-DWORD adapter_index_of_ip (const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count);
-
-void show_tap_win32_adapters (int msglev, int warnlev);
-void show_adapters (int msglev);
-
-void show_valid_win32_tun_subnets (void);
-const char *tap_win32_getinfo (const struct tuntap *tt, struct gc_arena *gc);
-void tun_show_debug (struct tuntap *tt);
-
-bool dhcp_release (const struct tuntap *tt);
-bool dhcp_renew (const struct tuntap *tt);
-
-int tun_read_queue (struct tuntap *tt, int maxsize);
-int tun_write_queue (struct tuntap *tt, struct buffer *buf);
-int tun_finalize (HANDLE h, struct overlapped_io *io, struct buffer *buf);
-
-const char *get_netsh_id (const char *dev_node, struct gc_arena *gc);
-
-static inline bool
-tuntap_stop (int status)
-{
- /*
- * This corresponds to the STATUS_NO_SUCH_DEVICE
- * error in tapdrvr.c.
- */
- if (status < 0)
- {
- return openvpn_errno () == ERROR_FILE_NOT_FOUND;
- }
- return false;
-}
-
-static inline int
-tun_write_win32 (struct tuntap *tt, struct buffer *buf)
-{
- int err = 0;
- int status = 0;
- if (overlapped_io_active (&tt->writes))
- {
- status = tun_finalize (tt->hand, &tt->writes, NULL);
- if (status < 0)
- err = GetLastError ();
- }
- tun_write_queue (tt, buf);
- if (status < 0)
- {
- SetLastError (err);
- return status;
- }
- else
- return BLEN (buf);
-}
-
-static inline int
-read_tun_buffered (struct tuntap *tt, struct buffer *buf, int maxsize)
-{
- return tun_finalize (tt->hand, &tt->reads, buf);
-}
-
-static inline int
-write_tun_buffered (struct tuntap *tt, struct buffer *buf)
-{
- return tun_write_win32 (tt, buf);
-}
-
-#else
-
-static inline bool
-tuntap_stop (int status)
-{
- return false;
-}
-
-#endif
-
-/*
- * TUN/TAP I/O wait functions
- */
-
-static inline event_t
-tun_event_handle (const struct tuntap *tt)
-{
-#ifdef WIN32
- return &tt->rw_handle;
-#else
- return tt->fd;
-#endif
-}
-
-static inline unsigned int
-tun_set (struct tuntap *tt,
- struct event_set *es,
- unsigned int rwflags,
- void *arg,
- unsigned int *persistent)
-{
- if (tuntap_defined (tt))
- {
- /* if persistent is defined, call event_ctl only if rwflags has changed since last call */
- if (!persistent || *persistent != rwflags)
- {
- event_ctl (es, tun_event_handle (tt), rwflags, arg);
- if (persistent)
- *persistent = rwflags;
- }
-#ifdef WIN32
- if (rwflags & EVENT_READ)
- tun_read_queue (tt, 0);
-#endif
- tt->rwflags_debug = rwflags;
- }
- return rwflags;
-}
-
-const char *tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc);
-
-#endif /* TUN_H */
diff --git a/openvpn/win32.h b/openvpn/win32.h
deleted file mode 100755
index 12af854..0000000
--- a/openvpn/win32.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef WIN32
-#ifndef OPENVPN_WIN32_H
-#define OPENVPN_WIN32_H
-
-#include "mtu.h"
-
-/*
- * Win32-specific OpenVPN code, targetted at the mingw
- * development environment.
- */
-
-void init_win32 (void);
-void uninit_win32 (void);
-
-void set_pause_exit_win32 (void);
-
-/*
- * Use keyboard input or events
- * to simulate incoming signals
- */
-
-#define SIGUSR1 1
-#define SIGUSR2 2
-#define SIGHUP 3
-#define SIGTERM 4
-#define SIGINT 5
-
-struct security_attributes
-{
- SECURITY_ATTRIBUTES sa;
- SECURITY_DESCRIPTOR sd;
-};
-
-#define HANDLE_DEFINED(h) ((h) != NULL && (h) != INVALID_HANDLE_VALUE)
-
-/*
- * Save old window title.
- */
-struct window_title
-{
- bool saved;
- char old_window_title [256];
-};
-
-struct rw_handle {
- HANDLE read;
- HANDLE write;
-};
-
-/*
- * Event-based notification of incoming TCP connections
- */
-
-#define NE32_PERSIST_EVENT (1<<0)
-#define NE32_WRITE_EVENT (1<<1)
-
-static inline bool
-defined_net_event_win32 (const struct rw_handle *event)
-{
- return event->read != NULL;
-}
-
-void init_net_event_win32 (struct rw_handle *event, long network_events, socket_descriptor_t sd, unsigned int flags);
-long reset_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd);
-void close_net_event_win32 (struct rw_handle *event, socket_descriptor_t sd, unsigned int flags);
-
-/*
- * A stateful variant of the net_event_win32 functions above
- */
-
-struct net_event_win32
-{
- struct rw_handle handle;
- socket_descriptor_t sd;
- long event_mask;
-};
-
-void net_event_win32_init (struct net_event_win32 *ne);
-void net_event_win32_start (struct net_event_win32 *ne, long network_events, socket_descriptor_t sd);
-void net_event_win32_reset (struct net_event_win32 *ne);
-void net_event_win32_reset_write (struct net_event_win32 *ne);
-void net_event_win32_stop (struct net_event_win32 *ne);
-void net_event_win32_close (struct net_event_win32 *ne);
-
-static bool
-net_event_win32_defined (const struct net_event_win32 *ne)
-{
- return defined_net_event_win32 (&ne->handle);
-}
-
-static inline struct rw_handle *
-net_event_win32_get_event (struct net_event_win32 *ne)
-{
- return &ne->handle;
-}
-
-static inline long
-net_event_win32_get_event_mask (const struct net_event_win32 *ne)
-{
- return ne->event_mask;
-}
-
-static inline void
-net_event_win32_clear_selected_events (struct net_event_win32 *ne, long selected_events)
-{
- ne->event_mask &= ~selected_events;
-}
-
-/*
- * Signal handling
- */
-struct win32_signal {
-# define WSO_MODE_UNDEF 0
-# define WSO_MODE_SERVICE 1
-# define WSO_MODE_CONSOLE 2
- int mode;
- struct rw_handle in;
- DWORD console_mode_save;
- bool console_mode_save_defined;
-};
-
-extern struct win32_signal win32_signal; /* static/global */
-extern struct window_title window_title; /* static/global */
-
-void win32_signal_clear (struct win32_signal *ws);
-
-/* win32_signal_open startup type */
-#define WSO_NOFORCE 0
-#define WSO_FORCE_SERVICE 1
-#define WSO_FORCE_CONSOLE 2
-
-void win32_signal_open (struct win32_signal *ws,
- int force, /* set to WSO force parm */
- const char *exit_event_name,
- bool exit_event_initial_state);
-
-void win32_signal_close (struct win32_signal *ws);
-
-int win32_signal_get (struct win32_signal *ws);
-
-void win32_pause (struct win32_signal *ws);
-
-/*
- * Set the text on the window title bar
- */
-
-void window_title_clear (struct window_title *wt);
-void window_title_save (struct window_title *wt);
-void window_title_restore (const struct window_title *wt);
-void window_title_generate (const char *title);
-
-/*
- * We try to do all Win32 I/O using overlapped
- * (i.e. asynchronous) I/O for a performance win.
- */
-struct overlapped_io {
-# define IOSTATE_INITIAL 0
-# define IOSTATE_QUEUED 1 /* overlapped I/O has been queued */
-# define IOSTATE_IMMEDIATE_RETURN 2 /* I/O function returned immediately without queueing */
- int iostate;
- OVERLAPPED overlapped;
- DWORD size;
- DWORD flags;
- int status;
- bool addr_defined;
- struct sockaddr_in addr;
- int addrlen;
- struct buffer buf_init;
- struct buffer buf;
-};
-
-void overlapped_io_init (struct overlapped_io *o,
- const struct frame *frame,
- BOOL event_state,
- bool tuntap_buffer);
-
-void overlapped_io_close (struct overlapped_io *o);
-
-static inline bool
-overlapped_io_active (struct overlapped_io *o)
-{
- return o->iostate == IOSTATE_QUEUED || o->iostate == IOSTATE_IMMEDIATE_RETURN;
-}
-
-char *overlapped_io_state_ascii (const struct overlapped_io *o);
-
-/*
- * Use to control access to resources that only one
- * OpenVPN process on a given machine can access at
- * a given time.
- */
-
-struct semaphore
-{
- const char *name;
- bool locked;
- HANDLE hand;
-};
-
-void semaphore_clear (struct semaphore *s);
-void semaphore_open (struct semaphore *s, const char *name);
-bool semaphore_lock (struct semaphore *s, int timeout_milliseconds);
-void semaphore_release (struct semaphore *s);
-void semaphore_close (struct semaphore *s);
-
-/*
- * Special global semaphore used to protect network
- * shell commands from simultaneous instantiation.
- *
- * It seems you can't run more than one instance
- * of netsh on the same machine at the same time.
- */
-
-extern struct semaphore netcmd_semaphore;
-void netcmd_semaphore_init (void);
-void netcmd_semaphore_close (void);
-void netcmd_semaphore_lock (void);
-void netcmd_semaphore_release (void);
-
-bool get_console_input_win32 (const char *prompt, const bool echo, char *input, const int capacity);
-char *getpass (const char *prompt);
-
-/* Set Win32 security attributes structure to allow all access */
-bool init_security_attributes_allow_all (struct security_attributes *obj);
-
-#endif
-#endif
diff --git a/threadutils.hpp b/threadutils.hpp
new file mode 100644
index 0000000..ad45f68
--- /dev/null
+++ b/threadutils.hpp
@@ -0,0 +1,174 @@
+/*
+ * anytun
+ *
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methodes used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007 anytun.org <satp@wirdorange.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _THREADUTILS_HPP_
+#define _THREADUTILS_HPP_
+
+#include <stdexcept>
+#include <semaphore.h>
+
+class Mutex
+{
+public:
+ Mutex()
+ {
+ if(pthread_mutex_init(&mutex,NULL))
+ throw std::runtime_error("can't create mutex");
+ }
+
+ ~Mutex()
+ {
+ pthread_mutex_destroy(&mutex);
+ }
+
+private:
+ Mutex(const Mutex& src);
+ void operator=(const Mutex& src);
+
+ void lock()
+ {
+ if(pthread_mutex_lock(&mutex))
+ throw std::runtime_error("can't lock mutex");
+ }
+
+ void unlock()
+ {
+ if(pthread_mutex_unlock(&mutex))
+ throw std::runtime_error("can't unlock mutex");
+ }
+ friend class Lock;
+ friend class Condition;
+ pthread_mutex_t mutex;
+};
+
+
+class Lock
+{
+public:
+ Lock(Mutex &m) : mutex(m)
+ {
+ mutex.lock();
+ }
+
+ ~Lock()
+ {
+ mutex.unlock();
+ }
+
+private:
+ Lock(const Lock& src);
+ void operator=(const Lock& src);
+
+ Mutex &mutex;
+};
+
+class Condition
+{
+public:
+ Condition()
+ {
+ if(pthread_cond_init(&cond, NULL))
+ throw std::runtime_error("can't create condition");
+ }
+
+ ~Condition()
+ {
+ pthread_cond_destroy(&cond);
+ }
+
+ void wait()
+ {
+ mutex.lock();
+ if(pthread_cond_wait(&cond, &mutex.mutex))
+ {
+ mutex.unlock();
+ throw std::runtime_error("error on waiting for condition");
+ }
+ mutex.unlock();
+ }
+
+ void signal()
+ {
+ mutex.lock();
+ if(pthread_cond_signal(&cond))
+ {
+ mutex.unlock();
+ throw std::runtime_error("can't signal condition");
+ }
+ mutex.unlock();
+ }
+
+ void broadcast()
+ {
+ mutex.lock();
+ if(pthread_cond_broadcast(&cond))
+ {
+ mutex.unlock();
+ throw std::runtime_error("can't broadcast condition");
+ }
+ mutex.unlock();
+ }
+
+private:
+ pthread_cond_t cond;
+ Mutex mutex;
+};
+
+class Semaphore
+{
+public:
+ Semaphore(unsigned int initVal=0)
+ {
+ if(sem_init(&sem, 0, initVal))
+ throw std::runtime_error("can't create semaphore");
+ }
+
+ ~Semaphore()
+ {
+ sem_destroy(&sem);
+ }
+
+ void down()
+ {
+ if(sem_wait(&sem))
+ throw std::runtime_error("error on semaphore down");
+ }
+
+ void up()
+ {
+ if(sem_post(&sem))
+ throw std::runtime_error("error on semaphore up");
+ }
+
+private:
+ sem_t sem;
+};
+
+#endif
diff --git a/tunDevice.cpp b/tunDevice.cpp
index e0fc270..b42e6ce 100644
--- a/tunDevice.cpp
+++ b/tunDevice.cpp
@@ -27,28 +27,75 @@
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+extern "C" {
+#include "openvpn/config.h"
+#include "openvpn/syshead.h"
#include "openvpn/tun.h"
+}
+
#include "tunDevice.h"
-TunDevice::TunDevice(string dev_name)
+TunDevice::TunDevice(const char* dev)
{
-// dev = init_tun(dev_name.c_str(), ... );
+ dev_ = NULL;
+
+
+// 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 */
+// in_addr_t local_public,
+// in_addr_t remote_public,
+// const bool strict_warn,
+// struct env_set *es)
+
+// init_tun_post (struct tuntap *tt,
+// const struct frame *frame,
+// const struct tuntap_options *options)
+
+
+// open_tun (const char *dev, const char *dev_type, const char *dev_node, false, dev_)
+
+//------------------------
+// c->c1.tuntap = init_tun (c->options.dev,
+// c->options.dev_type,
+// c->options.ifconfig_local,
+// c->options.ifconfig_remote_netmask,
+// addr_host (&c->c1.link_socket_addr.local),
+// addr_host (&c->c1.link_socket_addr.remote),
+// !c->options.ifconfig_nowarn,
+// c->c2.es);
+
+// init_tun_post (c->c1.tuntap,
+// &c->c2.frame,
+// &c->options.tuntap_options);
+
+// dev_ = init_tun(dev,
+
+
}
TunDevice::~TunDevice()
{
- close_tun(dev);
+ if(dev_)
+ close_tun(dev_);
+
}
int TunDevice::read(uint8_t *buf, int len)
{
- return read_tun(dev, buf, len);
+ if(!dev_)
+ return -1;
+
+ return read_tun(dev_, buf, len);
}
int TunDevice::write(uint8_t *buf, int len)
{
- return write_tun(dev, buf, len);
+ if(!dev_)
+ return -1;
+
+ return write_tun(dev_, buf, len);
}
diff --git a/tunDevice.h b/tunDevice.h
index 5602f90..487167a 100644
--- a/tunDevice.h
+++ b/tunDevice.h
@@ -28,12 +28,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "openvpn/tun.h"
+#ifndef _TUNDEVICE_H_
+#define _TUNDEVICE_H_
class TunDevice
{
public:
- TunDevice(string dev_name);
+ TunDevice(const char* dev);
~TunDevice();
int read(uint8_t *buf, int len);
@@ -44,4 +45,6 @@ private:
TunDevice(const TunDevice &src);
struct tuntap *dev_;
-}
+};
+
+#endif