@@ -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
17891804bool
17901805tun_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-
28772800void
28782801open_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-
30272874void
30282875open_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