Skip to content

Commit 6c7489e

Browse files
flichtenheldcron2
authored andcommitted
tun: Refactor BSD write_tun/read_tun
There was a lot of duplicated code, merge it together. Change-Id: Ifd9384287648d1f37a625d9ed6a09733208fa56c Signed-off-by: Frank Lichtenheld <[email protected]> Acked-by: Gert Doering <[email protected]> Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1378 Message-Id: <[email protected]> URL: https://www.mail-archive.com/[email protected]/msg34946.html Signed-off-by: Gert Doering <[email protected]>
1 parent d3e03b9 commit 6c7489e

File tree

1 file changed

+26
-233
lines changed

1 file changed

+26
-233
lines changed

src/openvpn/tun.c

Lines changed: 26 additions & 233 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,10 +1685,10 @@ clear_tuntap(struct tuntap *tuntap)
16851685
#endif
16861686
}
16871687

1688-
#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1688+
#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
16891689

16901690
/*
1691-
* OpenBSD and Mac OS X when using utun
1691+
* BSDs and Mac OS X when using utun
16921692
* have a slightly incompatible TUN device from
16931693
* the rest of the world, in that it prepends a
16941694
* uint32 to the beginning of the IP header
@@ -1699,10 +1699,8 @@ clear_tuntap(struct tuntap *tuntap)
16991699
* We strip off this field on reads and
17001700
* put it back on writes.
17011701
*
1702-
* I have not tested TAP devices on OpenBSD,
1703-
* but I have conditionalized the special
1704-
* TUN handling code described above to
1705-
* go away for TAP devices.
1702+
* For TAP devices, this is not needed and must
1703+
* not be done.
17061704
*/
17071705

17081706
#include <netinet/ip.h>
@@ -1733,11 +1731,9 @@ write_tun_header(struct tuntap *tt, uint8_t *buf, int len)
17331731
{
17341732
u_int32_t type;
17351733
struct iovec iv[2];
1736-
struct openvpn_iphdr *iph;
1734+
struct ip *iph = (struct ip *)buf;
17371735

1738-
iph = (struct openvpn_iphdr *)buf;
1739-
1740-
if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)
1736+
if (iph->ip_v == 6)
17411737
{
17421738
type = htonl(AF_INET6);
17431739
}
@@ -1784,7 +1780,26 @@ read_tun_header(struct tuntap *tt, uint8_t *buf, int len)
17841780
#pragma GCC diagnostic pop
17851781
#endif
17861782

1787-
#endif /* if defined (TARGET_OPENBSD) || defined(TARGET_DARWIN) */
1783+
/* For MacOS this extra handling is conditional on the UTUN driver.
1784+
* So it needs its own read_tun()/write_tun() with the necessary
1785+
* checks. They are located in the macOS-specific section below.
1786+
*/
1787+
#if !defined(TARGET_DARWIN)
1788+
int
1789+
write_tun(struct tuntap *tt, uint8_t *buf, int len)
1790+
{
1791+
return write_tun_header(tt, buf, len);
1792+
}
1793+
1794+
int
1795+
read_tun(struct tuntap *tt, uint8_t *buf, int len)
1796+
{
1797+
return read_tun_header(tt, buf, len);
1798+
}
1799+
#endif
1800+
1801+
1802+
#endif /* defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || defined(TARGET_NETBSD) || if defined (TARGET_OPENBSD) || defined(TARGET_DARWIN) */
17881803

17891804
bool
17901805
tun_name_is_fixed(const char *dev)
@@ -2679,18 +2694,6 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
26792694
argv_free(&argv);
26802695
}
26812696

2682-
int
2683-
write_tun(struct tuntap *tt, uint8_t *buf, int len)
2684-
{
2685-
return write_tun_header(tt, buf, len);
2686-
}
2687-
2688-
int
2689-
read_tun(struct tuntap *tt, uint8_t *buf, int len)
2690-
{
2691-
return read_tun_header(tt, buf, len);
2692-
}
2693-
26942697
#elif defined(TARGET_NETBSD)
26952698

26962699
/*
@@ -2792,88 +2795,8 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
27922795
argv_free(&argv);
27932796
}
27942797

2795-
static inline int
2796-
netbsd_modify_read_write_return(int len)
2797-
{
2798-
if (len > 0)
2799-
{
2800-
return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
2801-
}
2802-
else
2803-
{
2804-
return len;
2805-
}
2806-
}
2807-
2808-
int
2809-
write_tun(struct tuntap *tt, uint8_t *buf, int len)
2810-
{
2811-
if (tt->type == DEV_TYPE_TUN)
2812-
{
2813-
u_int32_t type;
2814-
struct iovec iv[2];
2815-
struct openvpn_iphdr *iph;
2816-
2817-
iph = (struct openvpn_iphdr *)buf;
2818-
2819-
if (OPENVPN_IPH_GET_VER(iph->version_len) == 6)
2820-
{
2821-
type = htonl(AF_INET6);
2822-
}
2823-
else
2824-
{
2825-
type = htonl(AF_INET);
2826-
}
2827-
2828-
iv[0].iov_base = (char *)&type;
2829-
iv[0].iov_len = sizeof(type);
2830-
iv[1].iov_base = buf;
2831-
iv[1].iov_len = len;
2832-
2833-
return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2834-
}
2835-
else
2836-
{
2837-
return write(tt->fd, buf, len);
2838-
}
2839-
}
2840-
2841-
int
2842-
read_tun(struct tuntap *tt, uint8_t *buf, int len)
2843-
{
2844-
if (tt->type == DEV_TYPE_TUN)
2845-
{
2846-
u_int32_t type;
2847-
struct iovec iv[2];
2848-
2849-
iv[0].iov_base = (char *)&type;
2850-
iv[0].iov_len = sizeof(type);
2851-
iv[1].iov_base = buf;
2852-
iv[1].iov_len = len;
2853-
2854-
return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
2855-
}
2856-
else
2857-
{
2858-
return read(tt->fd, buf, len);
2859-
}
2860-
}
2861-
28622798
#elif defined(TARGET_FREEBSD)
28632799

2864-
static inline int
2865-
freebsd_modify_read_write_return(int len)
2866-
{
2867-
if (len > 0)
2868-
{
2869-
return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
2870-
}
2871-
else
2872-
{
2873-
return len;
2874-
}
2875-
}
2876-
28772800
void
28782801
open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
28792802
openvpn_net_ctx_t *ctx)
@@ -2946,84 +2869,8 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
29462869
argv_free(&argv);
29472870
}
29482871

2949-
#if defined(__GNUC__) || defined(__clang__)
2950-
#pragma GCC diagnostic push
2951-
#pragma GCC diagnostic ignored "-Wconversion"
2952-
#endif
2953-
2954-
int
2955-
write_tun(struct tuntap *tt, uint8_t *buf, int len)
2956-
{
2957-
if (tt->type == DEV_TYPE_TUN)
2958-
{
2959-
u_int32_t type;
2960-
struct iovec iv[2];
2961-
struct ip *iph;
2962-
2963-
iph = (struct ip *)buf;
2964-
2965-
if (iph->ip_v == 6)
2966-
{
2967-
type = htonl(AF_INET6);
2968-
}
2969-
else
2970-
{
2971-
type = htonl(AF_INET);
2972-
}
2973-
2974-
iv[0].iov_base = (char *)&type;
2975-
iv[0].iov_len = sizeof(type);
2976-
iv[1].iov_base = buf;
2977-
iv[1].iov_len = len;
2978-
2979-
return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
2980-
}
2981-
else
2982-
{
2983-
return write(tt->fd, buf, len);
2984-
}
2985-
}
2986-
2987-
int
2988-
read_tun(struct tuntap *tt, uint8_t *buf, int len)
2989-
{
2990-
if (tt->type == DEV_TYPE_TUN)
2991-
{
2992-
u_int32_t type;
2993-
struct iovec iv[2];
2994-
2995-
iv[0].iov_base = (char *)&type;
2996-
iv[0].iov_len = sizeof(type);
2997-
iv[1].iov_base = buf;
2998-
iv[1].iov_len = len;
2999-
3000-
return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
3001-
}
3002-
else
3003-
{
3004-
return read(tt->fd, buf, len);
3005-
}
3006-
}
3007-
3008-
#if defined(__GNUC__) || defined(__clang__)
3009-
#pragma GCC diagnostic pop
3010-
#endif
3011-
30122872
#elif defined(TARGET_DRAGONFLY)
30132873

3014-
static inline int
3015-
dragonfly_modify_read_write_return(int len)
3016-
{
3017-
if (len > 0)
3018-
{
3019-
return len > sizeof(u_int32_t) ? len - sizeof(u_int32_t) : 0;
3020-
}
3021-
else
3022-
{
3023-
return len;
3024-
}
3025-
}
3026-
30272874
void
30282875
open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt,
30292876
openvpn_net_ctx_t *ctx)
@@ -3050,60 +2897,6 @@ close_tun(struct tuntap *tt, openvpn_net_ctx_t *ctx)
30502897
free(tt);
30512898
}
30522899

3053-
int
3054-
write_tun(struct tuntap *tt, uint8_t *buf, int len)
3055-
{
3056-
if (tt->type == DEV_TYPE_TUN)
3057-
{
3058-
u_int32_t type;
3059-
struct iovec iv[2];
3060-
struct ip *iph;
3061-
3062-
iph = (struct ip *)buf;
3063-
3064-
if (iph->ip_v == 6)
3065-
{
3066-
type = htonl(AF_INET6);
3067-
}
3068-
else
3069-
{
3070-
type = htonl(AF_INET);
3071-
}
3072-
3073-
iv[0].iov_base = (char *)&type;
3074-
iv[0].iov_len = sizeof(type);
3075-
iv[1].iov_base = buf;
3076-
iv[1].iov_len = len;
3077-
3078-
return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3079-
}
3080-
else
3081-
{
3082-
return write(tt->fd, buf, len);
3083-
}
3084-
}
3085-
3086-
int
3087-
read_tun(struct tuntap *tt, uint8_t *buf, int len)
3088-
{
3089-
if (tt->type == DEV_TYPE_TUN)
3090-
{
3091-
u_int32_t type;
3092-
struct iovec iv[2];
3093-
3094-
iv[0].iov_base = (char *)&type;
3095-
iv[0].iov_len = sizeof(type);
3096-
iv[1].iov_base = buf;
3097-
iv[1].iov_len = len;
3098-
3099-
return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3100-
}
3101-
else
3102-
{
3103-
return read(tt->fd, buf, len);
3104-
}
3105-
}
3106-
31072900
#elif defined(TARGET_DARWIN)
31082901

31092902
/* Darwin (MacOS X) is mostly "just use the generic stuff", but there

0 commit comments

Comments
 (0)