From d6d0193ba7086d2e06d3d367004aa0a859331cd0 Mon Sep 17 00:00:00 2001 From: pengtian Date: Sun, 12 Apr 2020 01:06:37 +0800 Subject: [PATCH 01/21] feature: add tun2tap support --- src/Makefile.am | 2 +- src/openvpn/Makefile.am | 1 + src/openvpn/errlevel.h | 1 + src/openvpn/forward.c | 7 +- src/openvpn/forward.h | 1 + src/openvpn/init.c | 55 ++++++++++- src/openvpn/misc.h | 9 ++ src/openvpn/multi.c | 9 +- src/openvpn/options.c | 8 +- src/openvpn/options.h | 3 +- src/openvpn/tun.h | 2 +- src/openvpn/tun2tap.c | 196 ++++++++++++++++++++++++++++++++++++++++ src/openvpn/tun2tap.h | 44 +++++++++ 13 files changed, 328 insertions(+), 10 deletions(-) create mode 100644 src/openvpn/tun2tap.c create mode 100644 src/openvpn/tun2tap.h diff --git a/src/Makefile.am b/src/Makefile.am index 313d289fc8c..815c5792b2a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,4 +12,4 @@ MAINTAINERCLEANFILES = \ $(srcdir)/Makefile.in -SUBDIRS = compat openvpn openvpnmsica openvpnserv plugins tapctl +SUBDIRS = compat openvpn openvpnmsica openvpnserv plugins tapctl diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index f0e0ad237d0..9a628234543 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -126,6 +126,7 @@ openvpn_SOURCES = \ syshead.h \ tls_crypt.c tls_crypt.h \ tun.c tun.h \ + tun2tap.c tun2tap.h \ vlan.c vlan.h \ win32.h win32.c \ cryptoapi.h cryptoapi.c diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h index e448fc370dc..67470120a33 100644 --- a/src/openvpn/errlevel.h +++ b/src/openvpn/errlevel.h @@ -149,6 +149,7 @@ #define D_PUSH_DEBUG LOGLEV(7, 73, M_DEBUG) /* show push/pull debugging info */ #define D_VLAN_DEBUG LOGLEV(7, 74, M_DEBUG) /* show VLAN tagging/untagging debug info */ +#define D_TUN2TAP LOGLEV(7, 75, M_DEBUG) /* PING send/receive messages */ #define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */ #define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */ diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index ea10f0bf5c3..ce0e743ac4c 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -951,7 +951,6 @@ read_incoming_link(struct context *c) status = link_socket_read(c->c2.link_socket, &c->c2.buf, &c->c2.from); - if (socket_connection_reset(c->c2.link_socket, status)) { #if PORT_SHARE @@ -1278,6 +1277,7 @@ read_incoming_tun(struct context *c) ASSERT(buf_init(&c->c2.buf, FRAME_HEADROOM(&c->c2.frame))); ASSERT(buf_safe(&c->c2.buf, MAX_RW_SIZE_TUN(&c->c2.frame))); c->c2.buf.len = read_tun(c->c1.tuntap, BPTR(&c->c2.buf), MAX_RW_SIZE_TUN(&c->c2.frame)); + check_tun2tap_send(c, TUN2TAP_FLAG_ENCAP); #endif #ifdef PACKET_TRUNCATION_CHECK @@ -1893,6 +1893,10 @@ process_outgoing_tun(struct context *c) &c->c2.n_trunc_tun_write); #endif + if(!check_tun2tap_send(c, TUN2TAP_FLAG_DECAP)){ + goto over; + } + #ifdef _WIN32 size = write_tun_buffered(c->c1.tuntap, &c->c2.to_tun); #else @@ -1933,6 +1937,7 @@ process_outgoing_tun(struct context *c) MAX_RW_SIZE_TUN(&c->c2.frame)); } +over: buf_reset(&c->c2.to_tun); perf_pop(); diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h index b711ff0024a..8e422705994 100644 --- a/src/openvpn/forward.h +++ b/src/openvpn/forward.h @@ -50,6 +50,7 @@ #include "openvpn.h" #include "occ.h" #include "ping.h" +#include "tun2tap.h" #define IOW_TO_TUN (1<<0) #define IOW_TO_LINK (1<<1) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 824b6667d4b..d78c6a0f620 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1819,10 +1819,63 @@ do_open_tun(struct context *c) open_tun(c->options.dev, c->options.dev_type, c->options.dev_node, c->c1.tuntap); + /* + * detect tun2tap + */ + if (c->options.tun2tap && TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TUN && !c->options.lladdr){ + uint8_t mac_addr[OPENVPN_ETH_ALEN] = {0}; + uint8_t buf[4*OPENVPN_ETH_ALEN] = {0}; + int i = 0; + int offset = 0; + random_hex(mac_addr, OPENVPN_ETH_ALEN); + mac_addr[0] &= ~(mac_addr[0] & 1); + for(; i < OPENVPN_ETH_ALEN; i++){ + if (i != OPENVPN_ETH_ALEN - 1){ + offset += sprintf(buf+offset, "%02x:", mac_addr[i]); + } else { + offset += sprintf(buf+offset, "%02x", mac_addr[i]); + } + } + c->options.lladdr = malloc(strlen(buf)); + memcpy(c->options.lladdr, buf, strlen(buf)); + } /* set the hardware address */ if (c->options.lladdr) { - set_lladdr(c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es); + uint8_t *buf = strdup(c->options.lladdr); + uint8_t mac_addr[OPENVPN_ETH_ALEN] = {0}; + int len = strlen(buf); + while(len-- > 0){ + if (buf[len] >= 'A' && buf[len] <= 'Z'){ + // x-X=z-Z => x=z-Z+X + buf[len] += 'a'- 'A'; + } + } + sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x" + , &mac_addr[0] + , &mac_addr[1] + , &mac_addr[2] + , &mac_addr[3] + , &mac_addr[4] + , &mac_addr[5] + ); + printf("local addr is: %02x:%02x:%02x:%02x:%02x:%02x\n" + , mac_addr[0] + , mac_addr[1] + , mac_addr[2] + , mac_addr[3] + , mac_addr[4] + , mac_addr[5] + ); + memcpy(c->options.lladdr_v, mac_addr, sizeof(mac_addr)); + if (c->options.tun2tap && (mac_addr[0] & 1)){ + msg(M_INFO, "mac %s is mcast addr (mac[0]&1 == true)", buf); + ASSERT(0); + } + + if (TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TAP) + set_lladdr(c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es); + free(buf); } /* do ifconfig */ diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 991b7df21b8..9769619dc38 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -175,4 +175,13 @@ void output_peer_info_env(struct env_set *es, const char *peer_info); #endif /* P2MP_SERVER */ +#define random_hex(buf, _sz) { \ + int sz = _sz; \ + srand(time(NULL)); \ + while (sz-- > 0){ \ + buf[sz] = rand()%256; \ + } \ +} + + #endif /* ifndef MISC_H */ diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index da0aeebaed3..cccf883aa76 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -297,7 +297,7 @@ void multi_init(struct multi_context *m, struct context *t, bool tcp_mode, int thread_mode) { int dev = DEV_TYPE_UNDEF; - + msg(D_MULTI_LOW, "MULTI: multi_init called, r=%d v=%d", t->options.real_hash_size, t->options.virtual_hash_size); @@ -2564,7 +2564,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst } perf_pop(); - if (TUNNEL_TYPE(m->top.c1.tuntap) == DEV_TYPE_TUN) + if (TUNNEL_TYPE(m->top.c1.tuntap) == DEV_TYPE_TUN && !m->top.options.tun2tap) { /* extract packet source and dest addresses */ mroute_flags = mroute_extract_addr_from_packet(&src, @@ -2642,8 +2642,11 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst } #endif } - else if (TUNNEL_TYPE(m->top.c1.tuntap) == DEV_TYPE_TAP) + else if (TUNNEL_TYPE(m->top.c1.tuntap) == DEV_TYPE_TAP || m->top.options.tun2tap) { + if (m->top.options.tun2tap){ + printf("pesudo tap dev\n"); + } uint16_t vid = 0; #ifdef ENABLE_PF struct mroute_addr edest; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 49df8df15a5..81677b9186b 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -2072,9 +2072,9 @@ options_postprocess_verify_ce(const struct options *options, const struct connec } - if (options->lladdr && dev != DEV_TYPE_TAP) + if (options->lladdr && (dev == DEV_TYPE_TUN && !options->tun2tap) && dev != DEV_TYPE_TAP) { - msg(M_USAGE, "--lladdr can only be used in --dev tap mode"); + msg(M_USAGE, "--lladdr can only be used in --dev tap mode or tun2tap"); } /* @@ -5399,6 +5399,10 @@ add_option(struct options *options, goto err; } } + else if (streq(p[0], "tun2tap") && !p[1]) + { + options->tun2tap = true; + } else if (streq(p[0], "topology") && p[1] && !p[2]) { VERIFY_PERMISSION(OPT_P_UP); diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 2f1f6faf13e..7a635099ed7 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -213,7 +213,7 @@ struct options /* persist parms */ bool persist_config; int persist_mode; - + bool tun2tap; const char *key_pass_file; bool show_ciphers; bool show_digests; @@ -248,6 +248,7 @@ struct options const char *dev_type; const char *dev_node; const char *lladdr; + uint8_t lladdr_v[OPENVPN_ETH_ALEN]; int topology; /* one of the TOP_x values from proto.h */ const char *ifconfig_local; const char *ifconfig_remote_netmask; diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index b38e7e90bff..c730ceddebb 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -149,7 +149,6 @@ struct tuntap #define TUNNEL_TOPOLOGY(tt) ((tt) ? ((tt)->topology) : TOP_UNDEF) int topology; /* one of the TOP_x values */ - bool did_ifconfig_setup; bool did_ifconfig_ipv6_setup; @@ -168,6 +167,7 @@ struct tuntap struct in6_addr local_ipv6; struct in6_addr remote_ipv6; + uint8_t remote_mac_addr[OPENVPN_ETH_ALEN]; int netbits_ipv6; #ifdef _WIN32 diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c new file mode 100644 index 00000000000..bfe15bd7416 --- /dev/null +++ b/src/openvpn/tun2tap.c @@ -0,0 +1,196 @@ +/* + * 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-2018 OpenVPN Inc + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* +Author: pengtianabc@hotmail.com +Date: 2020-4-12 11:17:33 +Function: simulate arp logical for tun device on client +TODO: ship for server, but i think that not worth +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" +// #include "openvpn.h" +#include "tun2tap.h" + +#include "memdbg.h" + +static inline void dump_hex(const uint8_t *buf, int len, char *name){ + int i = 0; + printf("===buf name:%s, len:%d==\n", name, len); + for(; i < len; i++){ + printf("%02x", buf[i]); + } + printf("\n======================\n"); +} + +/* + * Should we handle arp to the remote? + */ +bool +check_tun2tap_send_dowork(struct context *c, int flag) +{ + int ret = true; + if (!c->options.tun2tap){ + return ret; + } + if (TUN2TAP_FLAG_ENCAP == flag){ + dmsg(D_TUN2TAP, "TUN2TAP: encap data from tun"); + // read from tun, check and send arp to link + if ( BLEN(&c->c2.buf) >= sizeof(struct openvpn_iphdr)){ + struct openvpn_ethhdr hdr = {0}; + struct openvpn_iphdr *ip_hdr = BPTR(&c->c2.buf); + struct openvpn_ipv6hdr *ipv6_hdr = BPTR(&c->c2.buf); + int v = OPENVPN_IPH_GET_VER(ip_hdr->version_len); + memcpy(hdr.dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); + memcpy(hdr.source, c->options.lladdr_v, OPENVPN_ETH_ALEN); + + if (0 == memcmp(hdr.dest, "\x00\x00\x00\x00\x00\x00", sizeof("\x00\x00\x00\x00\x00\x00") - 1)){ + // build request + // overwirte arp to buf + struct openvpn_arp arp = { 0 }; + arp.mac_addr_type = htons(0x0001); + arp.proto_addr_type = htons(0x0800); + arp.mac_addr_size = 0x06; + arp.proto_addr_size = 0x04; + arp.arp_command = htons(ARP_REQUEST); + memcpy(arp.mac_src, hdr.source, OPENVPN_ETH_ALEN); + memcpy(arp.mac_dest, "\x00\x00\x00\x00\x00\x00", OPENVPN_ETH_ALEN); + memcpy(hdr.dest, "\xff\xff\xff\xff\xff\xff", OPENVPN_ETH_ALEN); + hdr.proto = htons(OPENVPN_ETH_P_ARP); + switch (v) + { + case 4: + arp.ip_src = ip_hdr->saddr; + arp.ip_dest = ip_hdr->daddr; + break; + case 6: + // hdr.proto = htons(OPENVPN_ETH_P_IPV6); + // memcpy(&arp.ip_src, &ipv6_hdr->saddr, sizeof(ipv6_hdr->saddr)); + // memcpy(&arp.ip_dest, &ipv6_hdr->daddr, sizeof(ipv6_hdr->daddr)); + default: + break; + } + buf_clear(&c->c2.buf); + buf_write(&c->c2.buf, &hdr, sizeof(hdr)); + buf_write(&c->c2.buf, &arp, sizeof(arp)); + } else { + switch (v) + { + case 4: + hdr.proto = htons(OPENVPN_ETH_P_IPV4); + break; + case 6: + hdr.proto = htons(OPENVPN_ETH_P_IPV6); + default: + break; + } + ASSERT(buf_write_prepend(&c->c2.buf, &hdr, sizeof(hdr))); + } + dmsg(D_TUN2TAP, "dest addr is: %02x:%02x:%02x:%02x:%02x:%02x" + , hdr.dest[0] + , hdr.dest[1] + , hdr.dest[2] + , hdr.dest[3] + , hdr.dest[4] + , hdr.dest[5] + ); + dmsg(D_TUN2TAP, "source addr is: %02x:%02x:%02x:%02x:%02x:%02x" + , hdr.source[0] + , hdr.source[1] + , hdr.source[2] + , hdr.source[3] + , hdr.source[4] + , hdr.source[5] + ); + } + } else if (TUN2TAP_FLAG_DECAP == flag){ + dmsg(D_TUN2TAP, "TUN2TAP: decap data to tun"); + // will write to tun, check is arp request, and save remote addr + if (BLEN(&c->c2.buf) >= sizeof(struct openvpn_ethhdr)){ + struct openvpn_ethhdr *hdr = (struct openvpn_ethhdr *) BPTR(&c->c2.buf); + memcpy(c->c1.tuntap->remote_mac_addr, hdr->source, OPENVPN_ETH_ALEN); + dmsg(D_TUN2TAP, "saved remote mac: %02x:%02x:%02x:%02x:%02x:%02x" + , c->c1.tuntap->remote_mac_addr[0] + , c->c1.tuntap->remote_mac_addr[1] + , c->c1.tuntap->remote_mac_addr[2] + , c->c1.tuntap->remote_mac_addr[3] + , c->c1.tuntap->remote_mac_addr[4] + , c->c1.tuntap->remote_mac_addr[5] + ); + if (hdr->proto == htons(OPENVPN_ETH_P_ARP)){ + if (BLEN(&c->c2.buf) >= sizeof(struct openvpn_ethhdr) + sizeof(struct openvpn_arp)){ + struct openvpn_arp *arp_in = (struct openvpn_arp *)(BPTR(&c->c2.buf) + sizeof(struct openvpn_ethhdr)); + if (arp_in->arp_command == htons(ARP_REPLY)){ + dmsg(D_TUN2TAP, "TUN2TAP: ignore arp reply"); + buf_clear(&c->c2.buf); + ret = false; + } else if (arp_in->arp_command == htons(ARP_REQUEST) ){ + if (arp_in->ip_dest == htonl(c->c1.tuntap->local)){ + // build reply + // write arp to link + struct openvpn_ethhdr hdr_out = { + .proto=htons(OPENVPN_ETH_P_ARP) + }; + struct openvpn_arp arp_out = { 0 }; + arp_out.mac_addr_type = htons(0x0001); + arp_out.proto_addr_type = htons(0x0800); + arp_out.mac_addr_size = 0x06; + arp_out.proto_addr_size = 0x04; + arp_out.arp_command = htons(ARP_REPLY); + memcpy(arp_out.mac_src, c->options.lladdr_v, OPENVPN_ETH_ALEN); + memcpy(arp_out.mac_dest, arp_in->mac_src, OPENVPN_ETH_ALEN); + memcpy(hdr_out.source, c->options.lladdr_v, OPENVPN_ETH_ALEN); + memcpy(hdr_out.dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); + arp_out.ip_src = arp_in->ip_dest; + arp_out.ip_dest = arp_in->ip_src; + buf_clear(&c->c2.buf); + // dump_hex(BPTR(&c->c2.buf), BLEN(&c->c2.buf), "after clear"); + buf_write(&c->c2.buf, &hdr_out, sizeof(hdr_out)); + // dump_hex(BPTR(&c->c2.buf), BLEN(&c->c2.buf), "after write ether"); + buf_write(&c->c2.buf, &arp_out, sizeof(arp_out)); + // dump_hex(BPTR(&c->c2.buf), BLEN(&c->c2.buf), "after write arp"); + encrypt_sign(c, true); + dmsg(D_TUN2TAP, "TUN2TAP: build arp reply success"); + } else { + dmsg(D_TUN2TAP, "TUN2TAP: ignore any arp request not to me dest:%x me:%x", ntohl(arp_in->ip_dest), c->c1.tuntap->local); + buf_clear(&c->c2.buf); + ret = false; + } + } else{ + dmsg(D_TUN2TAP, "TUN2TAP: ignore uknown arp type: %x", ntohs(arp_in->arp_command)); + buf_clear(&c->c2.buf); + ret = false; + } + } + } else { + buf_advance(&c->c2.to_tun, sizeof(struct openvpn_ethhdr)); + } + } + } + return ret; +} diff --git a/src/openvpn/tun2tap.h b/src/openvpn/tun2tap.h new file mode 100644 index 00000000000..fc23fa36ea7 --- /dev/null +++ b/src/openvpn/tun2tap.h @@ -0,0 +1,44 @@ +/* + * 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-2018 OpenVPN Inc + * + * 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; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* +Author: pengtianabc@hotmail.com +*/ + +#ifndef TUN2TAP_H +#define TUN2TAP_H + +#include "init.h" +#define TUN2TAP_FLAG_ENCAP 1 +#define TUN2TAP_FLAG_DECAP (1<<1) + +/* + * Should we convert tun2tap for the remote? + */ +static inline bool +check_tun2tap_send(struct context *c, int flag) +{ + bool check_tun2tap_send_dowork(struct context *c, int flag); + return check_tun2tap_send_dowork(c, flag); +} + +#endif /* ifndef TUN2TAP_H */ From 92c449d61dfe186e5eb36f1b90f17de720e27a2b Mon Sep 17 00:00:00 2001 From: pengtian Date: Mon, 20 Apr 2020 12:47:11 +0800 Subject: [PATCH 02/21] Update errlevel.h typo of tun2tap --- src/openvpn/errlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openvpn/errlevel.h b/src/openvpn/errlevel.h index 67470120a33..620e4c0c211 100644 --- a/src/openvpn/errlevel.h +++ b/src/openvpn/errlevel.h @@ -149,7 +149,7 @@ #define D_PUSH_DEBUG LOGLEV(7, 73, M_DEBUG) /* show push/pull debugging info */ #define D_VLAN_DEBUG LOGLEV(7, 74, M_DEBUG) /* show VLAN tagging/untagging debug info */ -#define D_TUN2TAP LOGLEV(7, 75, M_DEBUG) /* PING send/receive messages */ +#define D_TUN2TAP LOGLEV(7, 75, M_DEBUG) /* show tun2tap debug messages */ #define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */ #define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */ From 39f149062dcba8bf4030d6c659282ba8b4fe92fc Mon Sep 17 00:00:00 2001 From: pengtian Date: Mon, 20 Apr 2020 16:57:06 +0800 Subject: [PATCH 03/21] Fix coding style --- src/openvpn/forward.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 8f1bf3a3cdd..f5c80f1cc1c 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -1894,8 +1894,9 @@ process_outgoing_tun(struct context *c) &c->c2.n_trunc_tun_write); #endif - if(!check_tun2tap_send(c, TUN2TAP_FLAG_DECAP)){ - goto over; + if (!check_tun2tap_send(c, TUN2TAP_FLAG_DECAP)) + { + goto cleanup; } #ifdef _WIN32 @@ -1938,7 +1939,7 @@ process_outgoing_tun(struct context *c) MAX_RW_SIZE_TUN(&c->c2.frame)); } -over: +cleanup: buf_reset(&c->c2.to_tun); perf_pop(); From 908921fee6e465a2f27eff84ee76cf0746fe2326 Mon Sep 17 00:00:00 2001 From: pengtianabc Date: Mon, 20 Apr 2020 21:00:06 +0800 Subject: [PATCH 04/21] Beautify code and add annotation --- .gitignore | 1 + src/openvpn/init.c | 27 +++++++++++++++---- src/openvpn/misc.h | 11 +------- src/openvpn/multi.c | 3 --- src/openvpn/openvpn.c | 3 +++ src/openvpn/options.c | 1 + src/openvpn/tun2tap.c | 61 +++++++++---------------------------------- src/openvpn/tun2tap.h | 4 +-- 8 files changed, 42 insertions(+), 69 deletions(-) diff --git a/.gitignore b/.gitignore index 0d68ec4bb8e..52322c48b94 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,4 @@ nbproject test-driver compile stamp-h2 +.vscode/settings.json diff --git a/src/openvpn/init.c b/src/openvpn/init.c index d3e8b5ad6ec..bdbddf93378 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1122,6 +1122,19 @@ do_genkey(const struct options *options) } } +/* +* post check for tun2tap +*/ +void +do_check_tun2tap(const struct options *options) +{ + if (options && options->tun2tap && options->dev != DEV_TYPE_TUN) + { + msg(M_FATAL|M_OPTERR, + "options --tun2tap should only be used in tun mode"); + } +} + /* * Persistent TUN/TAP device management mode? */ @@ -1827,8 +1840,12 @@ do_open_tun(struct context *c) uint8_t buf[4*OPENVPN_ETH_ALEN] = {0}; int i = 0; int offset = 0; - random_hex(mac_addr, OPENVPN_ETH_ALEN); - mac_addr[0] &= ~(mac_addr[0] & 1); + ASSERT(rand_bytes(mac_addr, OPENVPN_ETH_ALEN)); + /* magic mac addr: 00:cc:xx:xx:xx:xx */ + mac_addr[0] = 0; + mac_addr[1] = 0; + mac_addr[2] = 'c'; + mac_addr[3] = 'c'; for(; i < OPENVPN_ETH_ALEN; i++){ if (i != OPENVPN_ETH_ALEN - 1){ offset += sprintf(buf+offset, "%02x:", mac_addr[i]); @@ -1847,7 +1864,7 @@ do_open_tun(struct context *c) int len = strlen(buf); while(len-- > 0){ if (buf[len] >= 'A' && buf[len] <= 'Z'){ - // x-X=z-Z => x=z-Z+X + /* x-X=z-Z => x=z-Z+X */ buf[len] += 'a'- 'A'; } } @@ -1859,7 +1876,7 @@ do_open_tun(struct context *c) , &mac_addr[4] , &mac_addr[5] ); - printf("local addr is: %02x:%02x:%02x:%02x:%02x:%02x\n" + dmsg(D_TUN2TAP, "local addr is: %02x:%02x:%02x:%02x:%02x:%02x" , mac_addr[0] , mac_addr[1] , mac_addr[2] @@ -1872,7 +1889,7 @@ do_open_tun(struct context *c) msg(M_INFO, "mac %s is mcast addr (mac[0]&1 == true)", buf); ASSERT(0); } - + /* set_lladdr is use command to set mac address for interface, we cant set mac for tun device */ if (TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TAP) set_lladdr(c->c1.tuntap->actual_name, c->options.lladdr, c->c2.es); free(buf); diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 798a23b011f..5917d8c6e5c 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -175,16 +175,7 @@ void output_peer_info_env(struct env_set *es, const char *peer_info); #endif /* P2MP_SERVER */ - -#define random_hex(buf, _sz) { \ - int sz = _sz; \ - srand(time(NULL)); \ - while (sz-- > 0){ \ - buf[sz] = rand()%256; \ - } \ -} - -/** +/* * Returns the occurrences of 'delimiter' in a string +1 * This is typically used to find out the number elements in a * cipher string or similar that is separated by : like diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 66f0e735ec7..508a352a781 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2667,9 +2667,6 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst } else if (TUNNEL_TYPE(m->top.c1.tuntap) == DEV_TYPE_TAP || m->top.options.tun2tap) { - if (m->top.options.tun2tap){ - printf("pesudo tap dev\n"); - } uint16_t vid = 0; #ifdef ENABLE_PF struct mroute_addr edest; diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c index a58d50756c6..712b0ed6d02 100644 --- a/src/openvpn/openvpn.c +++ b/src/openvpn/openvpn.c @@ -235,6 +235,9 @@ openvpn_main(int argc, char *argv[]) break; } + /* check tun2tap for tun mode */ + do_check_tun2tap(&c.options); + /* tun/tap persist command? */ if (do_persist_tuntap(&c.options, &c.net_ctx)) { diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 37018e88f35..f7a2a8d0eb7 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -5403,6 +5403,7 @@ add_option(struct options *options, } else if (streq(p[0], "tun2tap") && !p[1]) { + /* check in post do_xxxx */ options->tun2tap = true; } else if (streq(p[0], "topology") && p[1] && !p[2]) diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index bfe15bd7416..478eeb1be67 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -34,25 +34,15 @@ TODO: ship for server, but i think that not worth #endif #include "syshead.h" -// #include "openvpn.h" #include "tun2tap.h" #include "memdbg.h" -static inline void dump_hex(const uint8_t *buf, int len, char *name){ - int i = 0; - printf("===buf name:%s, len:%d==\n", name, len); - for(; i < len; i++){ - printf("%02x", buf[i]); - } - printf("\n======================\n"); -} - /* - * Should we handle arp to the remote? + * arp check and build for tun */ bool -check_tun2tap_send_dowork(struct context *c, int flag) +check_tun2tap_arp_dowork(struct context *c, int flag) { int ret = true; if (!c->options.tun2tap){ @@ -60,7 +50,7 @@ check_tun2tap_send_dowork(struct context *c, int flag) } if (TUN2TAP_FLAG_ENCAP == flag){ dmsg(D_TUN2TAP, "TUN2TAP: encap data from tun"); - // read from tun, check and send arp to link + /* read from tun, check and send arp to link */ if ( BLEN(&c->c2.buf) >= sizeof(struct openvpn_iphdr)){ struct openvpn_ethhdr hdr = {0}; struct openvpn_iphdr *ip_hdr = BPTR(&c->c2.buf); @@ -68,10 +58,11 @@ check_tun2tap_send_dowork(struct context *c, int flag) int v = OPENVPN_IPH_GET_VER(ip_hdr->version_len); memcpy(hdr.dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); memcpy(hdr.source, c->options.lladdr_v, OPENVPN_ETH_ALEN); - + /* + * if client send the first packet to server after connected, remote_mac_addr is zero + * so we build a arp request to replace this packet. + */ if (0 == memcmp(hdr.dest, "\x00\x00\x00\x00\x00\x00", sizeof("\x00\x00\x00\x00\x00\x00") - 1)){ - // build request - // overwirte arp to buf struct openvpn_arp arp = { 0 }; arp.mac_addr_type = htons(0x0001); arp.proto_addr_type = htons(0x0800); @@ -89,9 +80,7 @@ check_tun2tap_send_dowork(struct context *c, int flag) arp.ip_dest = ip_hdr->daddr; break; case 6: - // hdr.proto = htons(OPENVPN_ETH_P_IPV6); - // memcpy(&arp.ip_src, &ipv6_hdr->saddr, sizeof(ipv6_hdr->saddr)); - // memcpy(&arp.ip_dest, &ipv6_hdr->daddr, sizeof(ipv6_hdr->daddr)); + /* do nothing, arp has been removed in ipv6 */ default: break; } @@ -111,37 +100,13 @@ check_tun2tap_send_dowork(struct context *c, int flag) } ASSERT(buf_write_prepend(&c->c2.buf, &hdr, sizeof(hdr))); } - dmsg(D_TUN2TAP, "dest addr is: %02x:%02x:%02x:%02x:%02x:%02x" - , hdr.dest[0] - , hdr.dest[1] - , hdr.dest[2] - , hdr.dest[3] - , hdr.dest[4] - , hdr.dest[5] - ); - dmsg(D_TUN2TAP, "source addr is: %02x:%02x:%02x:%02x:%02x:%02x" - , hdr.source[0] - , hdr.source[1] - , hdr.source[2] - , hdr.source[3] - , hdr.source[4] - , hdr.source[5] - ); } } else if (TUN2TAP_FLAG_DECAP == flag){ dmsg(D_TUN2TAP, "TUN2TAP: decap data to tun"); - // will write to tun, check is arp request, and save remote addr + /* will write to tun, check is arp request, and save remote addr */ if (BLEN(&c->c2.buf) >= sizeof(struct openvpn_ethhdr)){ struct openvpn_ethhdr *hdr = (struct openvpn_ethhdr *) BPTR(&c->c2.buf); memcpy(c->c1.tuntap->remote_mac_addr, hdr->source, OPENVPN_ETH_ALEN); - dmsg(D_TUN2TAP, "saved remote mac: %02x:%02x:%02x:%02x:%02x:%02x" - , c->c1.tuntap->remote_mac_addr[0] - , c->c1.tuntap->remote_mac_addr[1] - , c->c1.tuntap->remote_mac_addr[2] - , c->c1.tuntap->remote_mac_addr[3] - , c->c1.tuntap->remote_mac_addr[4] - , c->c1.tuntap->remote_mac_addr[5] - ); if (hdr->proto == htons(OPENVPN_ETH_P_ARP)){ if (BLEN(&c->c2.buf) >= sizeof(struct openvpn_ethhdr) + sizeof(struct openvpn_arp)){ struct openvpn_arp *arp_in = (struct openvpn_arp *)(BPTR(&c->c2.buf) + sizeof(struct openvpn_ethhdr)); @@ -151,8 +116,9 @@ check_tun2tap_send_dowork(struct context *c, int flag) ret = false; } else if (arp_in->arp_command == htons(ARP_REQUEST) ){ if (arp_in->ip_dest == htonl(c->c1.tuntap->local)){ - // build reply - // write arp to link + /* + * build reply and write arp to link + */ struct openvpn_ethhdr hdr_out = { .proto=htons(OPENVPN_ETH_P_ARP) }; @@ -169,11 +135,8 @@ check_tun2tap_send_dowork(struct context *c, int flag) arp_out.ip_src = arp_in->ip_dest; arp_out.ip_dest = arp_in->ip_src; buf_clear(&c->c2.buf); - // dump_hex(BPTR(&c->c2.buf), BLEN(&c->c2.buf), "after clear"); buf_write(&c->c2.buf, &hdr_out, sizeof(hdr_out)); - // dump_hex(BPTR(&c->c2.buf), BLEN(&c->c2.buf), "after write ether"); buf_write(&c->c2.buf, &arp_out, sizeof(arp_out)); - // dump_hex(BPTR(&c->c2.buf), BLEN(&c->c2.buf), "after write arp"); encrypt_sign(c, true); dmsg(D_TUN2TAP, "TUN2TAP: build arp reply success"); } else { diff --git a/src/openvpn/tun2tap.h b/src/openvpn/tun2tap.h index fc23fa36ea7..84c353e1855 100644 --- a/src/openvpn/tun2tap.h +++ b/src/openvpn/tun2tap.h @@ -37,8 +37,8 @@ Author: pengtianabc@hotmail.com static inline bool check_tun2tap_send(struct context *c, int flag) { - bool check_tun2tap_send_dowork(struct context *c, int flag); - return check_tun2tap_send_dowork(c, flag); + bool check_tun2tap_arp_dowork(struct context *c, int flag); + return check_tun2tap_arp_dowork(c, flag); } #endif /* ifndef TUN2TAP_H */ From 4b81cd1ba6e5c198bf094b73d25d8cf9653b7719 Mon Sep 17 00:00:00 2001 From: pengtianabc Date: Mon, 20 Apr 2020 21:04:14 +0800 Subject: [PATCH 05/21] Update annotation --- src/openvpn/tun2tap.c | 11 +++++------ src/openvpn/tun2tap.h | 7 +++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index 478eeb1be67..3c73f7c4fb0 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -19,12 +19,11 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* -Author: pengtianabc@hotmail.com -Date: 2020-4-12 11:17:33 -Function: simulate arp logical for tun device on client -TODO: ship for server, but i think that not worth + * + * Author: pengtianabc@hotmail.com + * Date: 2020-4-12 11:17:33 + * Function: simulate arp logical for tun device on client + * TODO: ship for server, but i think that not worth, most server is on linux that easy to use tap */ #ifdef HAVE_CONFIG_H diff --git a/src/openvpn/tun2tap.h b/src/openvpn/tun2tap.h index 84c353e1855..57ff53e4e51 100644 --- a/src/openvpn/tun2tap.h +++ b/src/openvpn/tun2tap.h @@ -19,10 +19,9 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Author: pengtianabc@hotmail.com */ -/* -Author: pengtianabc@hotmail.com -*/ #ifndef TUN2TAP_H #define TUN2TAP_H @@ -32,7 +31,7 @@ Author: pengtianabc@hotmail.com #define TUN2TAP_FLAG_DECAP (1<<1) /* - * Should we convert tun2tap for the remote? + * arp check and build for tun */ static inline bool check_tun2tap_send(struct context *c, int flag) From 164c3049ea49a72222a807a1644b68aef75170bc Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 10:10:05 +0800 Subject: [PATCH 06/21] Add headers include --- src/openvpn/forward.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index bf76c3e9907..e0369a590db 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -42,6 +42,7 @@ #include "dhcp.h" #include "common.h" #include "ssl_verify.h" +#include "tun2tap.h" #include "memdbg.h" From 1784aa2298da38d93888b51149888c4fd5f11931 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 10:33:41 +0800 Subject: [PATCH 07/21] Update --- src/openvpn/init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 7c68ed885f2..79e4512f4a3 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1132,7 +1132,7 @@ do_genkey(const struct options *options) void do_check_tun2tap(const struct options *options) { - if (options && options->tun2tap && options->dev != DEV_TYPE_TUN) + if (options && options->tun2tap && dev_type_enum(options->dev, options->dev_type) != DEV_TYPE_TUN) { msg(M_FATAL|M_OPTERR, "options --tun2tap should only be used in tun mode"); @@ -1840,8 +1840,8 @@ do_open_tun(struct context *c) * detect tun2tap */ if (c->options.tun2tap && TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TUN && !c->options.lladdr){ - uint8_t mac_addr[OPENVPN_ETH_ALEN] = {0}; - uint8_t buf[4*OPENVPN_ETH_ALEN] = {0}; + unsigned char mac_addr[OPENVPN_ETH_ALEN] = {0}; + unsigned char buf[4*OPENVPN_ETH_ALEN] = {0}; int i = 0; int offset = 0; ASSERT(rand_bytes(mac_addr, OPENVPN_ETH_ALEN)); @@ -1863,8 +1863,8 @@ do_open_tun(struct context *c) /* set the hardware address */ if (c->options.lladdr) { - uint8_t *buf = strdup(c->options.lladdr); - uint8_t mac_addr[OPENVPN_ETH_ALEN] = {0}; + unsigned char *buf = strdup(c->options.lladdr); + unsigned char mac_addr[OPENVPN_ETH_ALEN] = {0}; int len = strlen(buf); while(len-- > 0){ if (buf[len] >= 'A' && buf[len] <= 'Z'){ From 08d31f22bc4ae789a0d911a8e4f12ddf7908b5ca Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 10:53:33 +0800 Subject: [PATCH 08/21] Update --- src/openvpn/init.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 79e4512f4a3..c08f2a83ae3 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1840,8 +1840,8 @@ do_open_tun(struct context *c) * detect tun2tap */ if (c->options.tun2tap && TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TUN && !c->options.lladdr){ - unsigned char mac_addr[OPENVPN_ETH_ALEN] = {0}; - unsigned char buf[4*OPENVPN_ETH_ALEN] = {0}; + char mac_addr[OPENVPN_ETH_ALEN] = {0}; + char buf[4*OPENVPN_ETH_ALEN] = {0}; int i = 0; int offset = 0; ASSERT(rand_bytes(mac_addr, OPENVPN_ETH_ALEN)); @@ -1852,9 +1852,9 @@ do_open_tun(struct context *c) mac_addr[3] = 'c'; for(; i < OPENVPN_ETH_ALEN; i++){ if (i != OPENVPN_ETH_ALEN - 1){ - offset += sprintf(buf+offset, "%02x:", mac_addr[i]); + offset += sprintf(buf+offset, "%02x:", (unsigned char)mac_addr[i]); } else { - offset += sprintf(buf+offset, "%02x", mac_addr[i]); + offset += sprintf(buf+offset, "%02x", (unsigned char)mac_addr[i]); } } c->options.lladdr = malloc(strlen(buf)); @@ -1863,8 +1863,8 @@ do_open_tun(struct context *c) /* set the hardware address */ if (c->options.lladdr) { - unsigned char *buf = strdup(c->options.lladdr); - unsigned char mac_addr[OPENVPN_ETH_ALEN] = {0}; + char *buf = strdup(c->options.lladdr); + char mac_addr[OPENVPN_ETH_ALEN] = {0}; int len = strlen(buf); while(len-- > 0){ if (buf[len] >= 'A' && buf[len] <= 'Z'){ @@ -1881,12 +1881,12 @@ do_open_tun(struct context *c) , &mac_addr[5] ); dmsg(D_TUN2TAP, "local addr is: %02x:%02x:%02x:%02x:%02x:%02x" - , mac_addr[0] - , mac_addr[1] - , mac_addr[2] - , mac_addr[3] - , mac_addr[4] - , mac_addr[5] + , (unsigned char)mac_addr[0] + , (unsigned char)mac_addr[1] + , (unsigned char)mac_addr[2] + , (unsigned char)mac_addr[3] + , (unsigned char)mac_addr[4] + , (unsigned char)mac_addr[5] ); memcpy(c->options.lladdr_v, mac_addr, sizeof(mac_addr)); if (c->options.tun2tap && (mac_addr[0] & 1)){ From ac92b2a6197254c1b69a5944540a05d36a0f3647 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 11:05:52 +0800 Subject: [PATCH 09/21] Update --- src/openvpn/init.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c08f2a83ae3..1e6d9daa951 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1844,7 +1844,7 @@ do_open_tun(struct context *c) char buf[4*OPENVPN_ETH_ALEN] = {0}; int i = 0; int offset = 0; - ASSERT(rand_bytes(mac_addr, OPENVPN_ETH_ALEN)); + ASSERT(rand_bytes((unsigned char *)mac_addr, OPENVPN_ETH_ALEN)); /* magic mac addr: 00:cc:xx:xx:xx:xx */ mac_addr[0] = 0; mac_addr[1] = 0; @@ -1863,8 +1863,10 @@ do_open_tun(struct context *c) /* set the hardware address */ if (c->options.lladdr) { + int i = 0; char *buf = strdup(c->options.lladdr); char mac_addr[OPENVPN_ETH_ALEN] = {0}; + unsigned int mac_addr_tmp[OPENVPN_ETH_ALEN] = {0}; int len = strlen(buf); while(len-- > 0){ if (buf[len] >= 'A' && buf[len] <= 'Z'){ @@ -1873,13 +1875,18 @@ do_open_tun(struct context *c) } } sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x" - , &mac_addr[0] - , &mac_addr[1] - , &mac_addr[2] - , &mac_addr[3] - , &mac_addr[4] - , &mac_addr[5] + , &mac_addr_tmp[0] + , &mac_addr_tmp[1] + , &mac_addr_tmp[2] + , &mac_addr_tmp[3] + , &mac_addr_tmp[4] + , &mac_addr_tmp[5] ); + while(i < OPENVPN_ETH_ALEN) + { + mac_addr[i] = 0xff & mac_addr_tmp[i]; + i++; + } dmsg(D_TUN2TAP, "local addr is: %02x:%02x:%02x:%02x:%02x:%02x" , (unsigned char)mac_addr[0] , (unsigned char)mac_addr[1] From 974d9bb7c963695ffed70fb614bfee2e0e819292 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 11:57:55 +0800 Subject: [PATCH 10/21] Update --- src/openvpn/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 1e6d9daa951..777337d7a75 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1857,8 +1857,8 @@ do_open_tun(struct context *c) offset += sprintf(buf+offset, "%02x", (unsigned char)mac_addr[i]); } } - c->options.lladdr = malloc(strlen(buf)); - memcpy(c->options.lladdr, buf, strlen(buf)); + c->options.lladdr = malloc(strlen((const char *)buf)); + memcpy(c->options.lladdr, buf, strlen((const char *)buf)); } /* set the hardware address */ if (c->options.lladdr) From d2a7d4bfbbd80ed6ee02d52dd13982a100fc0f77 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 12:58:29 +0800 Subject: [PATCH 11/21] Update for CI --- src/openvpn/init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 777337d7a75..44a4e3cd8ea 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1840,6 +1840,7 @@ do_open_tun(struct context *c) * detect tun2tap */ if (c->options.tun2tap && TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TUN && !c->options.lladdr){ + char *lladdr_tmp = NULL; char mac_addr[OPENVPN_ETH_ALEN] = {0}; char buf[4*OPENVPN_ETH_ALEN] = {0}; int i = 0; @@ -1857,8 +1858,10 @@ do_open_tun(struct context *c) offset += sprintf(buf+offset, "%02x", (unsigned char)mac_addr[i]); } } - c->options.lladdr = malloc(strlen((const char *)buf)); - memcpy(c->options.lladdr, buf, strlen((const char *)buf)); + lladdr_tmp = (char *)malloc(strlen((const char *)buf) + 1); + memcpy(lladdr_tmp, buf, strlen((const char *)buf)); + laddr_tmp[strlen((const char *)buf)] = 0; + c->options.lladdr = lladdr_tmp; } /* set the hardware address */ if (c->options.lladdr) From f096043fc4766cde124556ee045d23a7ed530024 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 13:39:19 +0800 Subject: [PATCH 12/21] Update for CI --- src/openvpn/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 44a4e3cd8ea..803427bcb32 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1860,7 +1860,7 @@ do_open_tun(struct context *c) } lladdr_tmp = (char *)malloc(strlen((const char *)buf) + 1); memcpy(lladdr_tmp, buf, strlen((const char *)buf)); - laddr_tmp[strlen((const char *)buf)] = 0; + lladdr_tmp[strlen((const char *)buf)] = 0; c->options.lladdr = lladdr_tmp; } /* set the hardware address */ From a7d5a3b5e147ad471b2fc71fff49760cd188c1a0 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 13:45:02 +0800 Subject: [PATCH 13/21] Update for CI --- src/openvpn/init.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openvpn/init.h b/src/openvpn/init.h index 0e6258f0b8d..94aae9c53b8 100644 --- a/src/openvpn/init.h +++ b/src/openvpn/init.h @@ -56,6 +56,8 @@ bool print_openssl_info(const struct options *options); bool do_genkey(const struct options *options); +void do_check_tun2tap(const struct options *options); + bool do_persist_tuntap(const struct options *options, openvpn_net_ctx_t *ctx); bool possibly_become_daemon(const struct options *options); From 2f079b4f0ef3a98a1f6a9920484ec0c6fa9cac73 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 13:51:37 +0800 Subject: [PATCH 14/21] Update for CI --- src/openvpn/tun2tap.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/openvpn/tun2tap.h b/src/openvpn/tun2tap.h index 57ff53e4e51..5c64daec0ec 100644 --- a/src/openvpn/tun2tap.h +++ b/src/openvpn/tun2tap.h @@ -27,6 +27,7 @@ #define TUN2TAP_H #include "init.h" +#include "forward.h" #define TUN2TAP_FLAG_ENCAP 1 #define TUN2TAP_FLAG_DECAP (1<<1) From d1f35ffd2a1c5fe75b557b70b27bc5301cf340d0 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 13:58:08 +0800 Subject: [PATCH 15/21] Update for CI --- src/openvpn/tun2tap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index 3c73f7c4fb0..f2c6df74dc0 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -52,8 +52,8 @@ check_tun2tap_arp_dowork(struct context *c, int flag) /* read from tun, check and send arp to link */ if ( BLEN(&c->c2.buf) >= sizeof(struct openvpn_iphdr)){ struct openvpn_ethhdr hdr = {0}; - struct openvpn_iphdr *ip_hdr = BPTR(&c->c2.buf); - struct openvpn_ipv6hdr *ipv6_hdr = BPTR(&c->c2.buf); + struct openvpn_iphdr *ip_hdr = (struct openvpn_iphdr *)BPTR(&c->c2.buf); + struct openvpn_ipv6hdr *ipv6_hdr = (struct openvpn_ipv6hdr *)BPTR(&c->c2.buf); int v = OPENVPN_IPH_GET_VER(ip_hdr->version_len); memcpy(hdr.dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); memcpy(hdr.source, c->options.lladdr_v, OPENVPN_ETH_ALEN); From c094bf80499d6c24e04937e9356d02ef5ea87510 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 14:01:52 +0800 Subject: [PATCH 16/21] Update for CI --- src/openvpn/tun2tap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index f2c6df74dc0..11261c1d0e7 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -53,7 +53,9 @@ check_tun2tap_arp_dowork(struct context *c, int flag) if ( BLEN(&c->c2.buf) >= sizeof(struct openvpn_iphdr)){ struct openvpn_ethhdr hdr = {0}; struct openvpn_iphdr *ip_hdr = (struct openvpn_iphdr *)BPTR(&c->c2.buf); + /* struct openvpn_ipv6hdr *ipv6_hdr = (struct openvpn_ipv6hdr *)BPTR(&c->c2.buf); + */ int v = OPENVPN_IPH_GET_VER(ip_hdr->version_len); memcpy(hdr.dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); memcpy(hdr.source, c->options.lladdr_v, OPENVPN_ETH_ALEN); From 84d1bcb238e7aa4d6438e0e3f3b3d7310d2c7c1a Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 14:30:47 +0800 Subject: [PATCH 17/21] Update for CI Windows --- src/openvpn/openvpn.vcxproj | 1 + src/openvpn/openvpn.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj index 53ac5482a58..160eaca3c11 100644 --- a/src/openvpn/openvpn.vcxproj +++ b/src/openvpn/openvpn.vcxproj @@ -288,6 +288,7 @@ + diff --git a/src/openvpn/openvpn.vcxproj.filters b/src/openvpn/openvpn.vcxproj.filters index 80eb52b3895..e7eda488c0b 100644 --- a/src/openvpn/openvpn.vcxproj.filters +++ b/src/openvpn/openvpn.vcxproj.filters @@ -204,6 +204,9 @@ Source Files + + Source Files + Source Files From 2fd9c084762f789e48990349cdf5308520fd07ee Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 6 Aug 2020 14:59:48 +0800 Subject: [PATCH 18/21] Update for CI Windows --- src/openvpn/openvpn.vcxproj | 1 + src/openvpn/openvpn.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/openvpn/openvpn.vcxproj b/src/openvpn/openvpn.vcxproj index 160eaca3c11..7df558e9ad9 100644 --- a/src/openvpn/openvpn.vcxproj +++ b/src/openvpn/openvpn.vcxproj @@ -198,6 +198,7 @@ + diff --git a/src/openvpn/openvpn.vcxproj.filters b/src/openvpn/openvpn.vcxproj.filters index e7eda488c0b..1c505041c06 100644 --- a/src/openvpn/openvpn.vcxproj.filters +++ b/src/openvpn/openvpn.vcxproj.filters @@ -482,6 +482,9 @@ Header Files + + Header Files + Header Files From b86d65138954c52b513a890b6c967fd03aa75dd9 Mon Sep 17 00:00:00 2001 From: pengtian Date: Thu, 22 Sep 2022 01:24:29 +0800 Subject: [PATCH 19/21] Bugfix for tun2tap --- src/openvpn/init.c | 5 +++-- src/openvpn/options.c | 7 +++++++ src/openvpn/tun.c | 30 +++++++++++++++++++----------- src/openvpn/tun.h | 3 +++ src/openvpn/tun2tap.c | 6 +++++- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 803427bcb32..66cf92739a2 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1731,6 +1731,7 @@ do_init_tun(struct context *c) c->c1.tuntap = init_tun(c->options.dev, c->options.dev_type, c->options.topology, + c->options.tun2tap, c->options.ifconfig_local, c->options.ifconfig_remote_netmask, c->options.ifconfig_ipv6_local, @@ -1839,7 +1840,7 @@ do_open_tun(struct context *c) /* * detect tun2tap */ - if (c->options.tun2tap && TUNNEL_TYPE(c->c1.tuntap) == DEV_TYPE_TUN && !c->options.lladdr){ + if (c->c1.tuntap->tun2tap && !c->options.lladdr){ char *lladdr_tmp = NULL; char mac_addr[OPENVPN_ETH_ALEN] = {0}; char buf[4*OPENVPN_ETH_ALEN] = {0}; @@ -1899,7 +1900,7 @@ do_open_tun(struct context *c) , (unsigned char)mac_addr[5] ); memcpy(c->options.lladdr_v, mac_addr, sizeof(mac_addr)); - if (c->options.tun2tap && (mac_addr[0] & 1)){ + if (c->c1.tuntap->tun2tap && (mac_addr[0] & 1)){ msg(M_INFO, "mac %s is mcast addr (mac[0]&1 == true)", buf); ASSERT(0); } diff --git a/src/openvpn/options.c b/src/openvpn/options.c index ad6812f6bb5..ed200f96b78 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -3703,6 +3703,7 @@ options_string(const struct options *o, tt = init_tun(o->dev, o->dev_type, o->topology, + o->tun2tap, o->ifconfig_local, o->ifconfig_remote_netmask, o->ifconfig_ipv6_local, @@ -3727,6 +3728,12 @@ options_string(const struct options *o, buf_printf(&out, ",ifconfig %s", ios); } } + + if (tt && tt->tun2tap) + { + buf_printf(&out, ",tun2tap"); + } + if (tt_local) { free(tt); diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 8e692977e98..f26b03b8f2d 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -556,7 +556,7 @@ is_tun_p2p(const struct tuntap *tt) bool tun = false; if (tt->type == DEV_TYPE_TAP - || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET) + || (tt->type == DEV_TYPE_TUN && (tt->topology == TOP_SUBNET || tt->tun2tap)) || tt->type == DEV_TYPE_NULL) { tun = false; @@ -624,6 +624,7 @@ struct tuntap * init_tun(const char *dev, /* --dev option */ const char *dev_type, /* --dev-type option */ int topology, /* one of the TOP_x values */ + const bool tun2tap, /* --tun2tap */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 IPv6 */ @@ -644,6 +645,13 @@ init_tun(const char *dev, /* --dev option */ tt->type = dev_type_enum(dev, dev_type); tt->topology = topology; + if (tt->type == DEV_TYPE_TUN) + { + tt->tun2tap = tun2tap; + } else { + tt->tun2tap = false; + } + if (ifconfig_local_parm && ifconfig_remote_netmask_parm) { bool tun = false; @@ -1150,7 +1158,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, argv_printf(&argv, "%s %s netmask 255.255.255.255", IFCONFIG_PATH, ifname); } - else if (tt->topology == TOP_SUBNET) + else if (tt->topology == TOP_SUBNET || tt->tun2tap) { argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local, @@ -1169,7 +1177,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, solaris_error_close(tt, es, ifname, false); } - if (!tun && tt->topology == TOP_SUBNET) + if (!tun && (tt->topology == TOP_SUBNET || tt->tun2tap)) { /* Add a network route for the local tun interface */ struct route_ipv4 r; @@ -1200,7 +1208,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu); } - else if (tt->topology == TOP_SUBNET) + else if (tt->topology == TOP_SUBNET || tt->tun2tap) { remote_end = create_arbitrary_remote( tt ); argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up -link0", @@ -1218,7 +1226,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, openvpn_execve_check(&argv, es, S_FATAL, "OpenBSD ifconfig failed"); /* Add a network route for the local tun interface */ - if (!tun && tt->topology == TOP_SUBNET) + if (!tun && (tt->topology == TOP_SUBNET || tt->tun2tap)) { struct route_ipv4 r; CLEAR(r); @@ -1238,7 +1246,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu); } - else if (tt->topology == TOP_SUBNET) + else if (tt->topology == TOP_SUBNET || tt->tun2tap) { remote_end = create_arbitrary_remote(tt); argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH, @@ -1260,7 +1268,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, openvpn_execve_check(&argv, es, S_FATAL, "NetBSD ifconfig failed"); /* Add a network route for the local tun interface */ - if (!tun && tt->topology == TOP_SUBNET) + if (!tun && (tt->topology == TOP_SUBNET || tt->tun2tap)) { struct route_ipv4 r; CLEAR(r); @@ -1292,7 +1300,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, } else { - if (tt->topology == TOP_SUBNET) + if (tt->topology == TOP_SUBNET || tt->tun2tap) { argv_printf(&argv, "%s %s %s %s netmask %s mtu %d up", IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_local, @@ -1310,7 +1318,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, openvpn_execve_check(&argv, es, S_FATAL, "Mac OS X ifconfig failed"); /* Add a network route for the local tun interface */ - if (!tun && tt->topology == TOP_SUBNET) + if (!tun && (tt->topology == TOP_SUBNET || tt->tun2tap)) { struct route_ipv4 r; CLEAR(r); @@ -1332,7 +1340,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, IFCONFIG_PATH, ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu); } - else if (tt->topology == TOP_SUBNET) + else if (tt->topology == TOP_SUBNET || tt->tun2tap) { remote_end = create_arbitrary_remote( tt ); argv_printf(&argv, "%s %s %s %s mtu %d netmask %s up", IFCONFIG_PATH, @@ -1349,7 +1357,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, openvpn_execve_check(&argv, es, S_FATAL, "FreeBSD ifconfig failed"); /* Add a network route for the local tun interface */ - if (!tun && tt->topology == TOP_SUBNET) + if (!tun && (tt->topology == TOP_SUBNET || tt->tun2tap)) { struct route_ipv4 r; CLEAR(r); diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index c730ceddebb..6d7b9e594ba 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -156,6 +156,8 @@ struct tuntap struct tuntap_options options; /* options set on command line */ + bool tun2tap; /* options set on --tun2tap for tun mode */ + char *actual_name; /* actual name of TUN/TAP dev, usually including unit number */ /* number of TX buffers */ @@ -263,6 +265,7 @@ const char *guess_tuntap_dev(const char *dev, struct tuntap *init_tun(const char *dev, /* --dev option */ const char *dev_type, /* --dev-type option */ int topology, /* one of the TOP_x values */ + const bool tun2tap, /* --tun2tap */ const char *ifconfig_local_parm, /* --ifconfig parm 1 */ const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 / IPv6 */ diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index 11261c1d0e7..ee5d2458dbf 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -109,6 +109,7 @@ check_tun2tap_arp_dowork(struct context *c, int flag) struct openvpn_ethhdr *hdr = (struct openvpn_ethhdr *) BPTR(&c->c2.buf); memcpy(c->c1.tuntap->remote_mac_addr, hdr->source, OPENVPN_ETH_ALEN); if (hdr->proto == htons(OPENVPN_ETH_P_ARP)){ + dmsg(D_TUN2TAP, "TUN2TAP: processing arp from tun"); if (BLEN(&c->c2.buf) >= sizeof(struct openvpn_ethhdr) + sizeof(struct openvpn_arp)){ struct openvpn_arp *arp_in = (struct openvpn_arp *)(BPTR(&c->c2.buf) + sizeof(struct openvpn_ethhdr)); if (arp_in->arp_command == htons(ARP_REPLY)){ @@ -136,10 +137,12 @@ check_tun2tap_arp_dowork(struct context *c, int flag) arp_out.ip_src = arp_in->ip_dest; arp_out.ip_dest = arp_in->ip_src; buf_clear(&c->c2.buf); + ASSERT(buf_init(&c->c2.buf, FRAME_HEADROOM(&c->c2.frame))); + ASSERT(buf_safe(&c->c2.buf, MAX_RW_SIZE_TUN(&c->c2.frame))); buf_write(&c->c2.buf, &hdr_out, sizeof(hdr_out)); buf_write(&c->c2.buf, &arp_out, sizeof(arp_out)); - encrypt_sign(c, true); dmsg(D_TUN2TAP, "TUN2TAP: build arp reply success"); + encrypt_sign(c, true); } else { dmsg(D_TUN2TAP, "TUN2TAP: ignore any arp request not to me dest:%x me:%x", ntohl(arp_in->ip_dest), c->c1.tuntap->local); buf_clear(&c->c2.buf); @@ -152,6 +155,7 @@ check_tun2tap_arp_dowork(struct context *c, int flag) } } } else { + dmsg(D_TUN2TAP, "TUN2TAP: trim ethhdr for tun"); buf_advance(&c->c2.to_tun, sizeof(struct openvpn_ethhdr)); } } From 9545ddc7d5fe4759e49a0d7ccb88bfeb3e6259e9 Mon Sep 17 00:00:00 2001 From: pengtian Date: Fri, 23 Sep 2022 01:26:48 +0800 Subject: [PATCH 20/21] Extract arp reply function --- src/openvpn/tun2tap.c | 47 ++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index ee5d2458dbf..34533a557b5 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -37,6 +37,29 @@ #include "memdbg.h" +void build_arp_reply(struct context *c, struct openvpn_ethhdr *hdr_out, struct openvpn_arp *arp_in, struct openvpn_arp *arp_out); +void build_arp_reply(struct context *c, struct openvpn_ethhdr *hdr_out, struct openvpn_arp *arp_in, struct openvpn_arp *arp_out) +{ + if (!c || !hdr_out || !arp_in || !arp_out) + { + return; + } + memset(hdr_out, 0, sizeof(*hdr_out)); + memset(arp_out, 0, sizeof(*arp_out)); + hdr_out->proto = htons(OPENVPN_ETH_P_ARP); + arp_out->mac_addr_type = htons(0x0001); + arp_out->proto_addr_type = htons(0x0800); + arp_out->mac_addr_size = 0x06; + arp_out->proto_addr_size = 0x04; + arp_out->arp_command = htons(ARP_REPLY); + memcpy(arp_out->mac_src, c->options.lladdr_v, OPENVPN_ETH_ALEN); + memcpy(arp_out->mac_dest, arp_in->mac_src, OPENVPN_ETH_ALEN); + memcpy(hdr_out->source, c->options.lladdr_v, OPENVPN_ETH_ALEN); + memcpy(hdr_out->dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); + arp_out->ip_src = arp_in->ip_dest; + arp_out->ip_dest = arp_in->ip_src; +} + /* * arp check and build for tun */ @@ -81,7 +104,11 @@ check_tun2tap_arp_dowork(struct context *c, int flag) arp.ip_dest = ip_hdr->daddr; break; case 6: - /* do nothing, arp has been removed in ipv6 */ + /* + do nothing, arp has been removed in ipv6 + so we will not receive any ipv6 packet without mac + this case will never in + */ default: break; } @@ -121,21 +148,9 @@ check_tun2tap_arp_dowork(struct context *c, int flag) /* * build reply and write arp to link */ - struct openvpn_ethhdr hdr_out = { - .proto=htons(OPENVPN_ETH_P_ARP) - }; - struct openvpn_arp arp_out = { 0 }; - arp_out.mac_addr_type = htons(0x0001); - arp_out.proto_addr_type = htons(0x0800); - arp_out.mac_addr_size = 0x06; - arp_out.proto_addr_size = 0x04; - arp_out.arp_command = htons(ARP_REPLY); - memcpy(arp_out.mac_src, c->options.lladdr_v, OPENVPN_ETH_ALEN); - memcpy(arp_out.mac_dest, arp_in->mac_src, OPENVPN_ETH_ALEN); - memcpy(hdr_out.source, c->options.lladdr_v, OPENVPN_ETH_ALEN); - memcpy(hdr_out.dest, c->c1.tuntap->remote_mac_addr, OPENVPN_ETH_ALEN); - arp_out.ip_src = arp_in->ip_dest; - arp_out.ip_dest = arp_in->ip_src; + struct openvpn_ethhdr hdr_out; + struct openvpn_arp arp_out; + build_arp_reply(c, &hdr_out, arp_in, &arp_out); buf_clear(&c->c2.buf); ASSERT(buf_init(&c->c2.buf, FRAME_HEADROOM(&c->c2.frame))); ASSERT(buf_safe(&c->c2.buf, MAX_RW_SIZE_TUN(&c->c2.frame))); From 1850423fc899ab952afcbdeb68cdbe772c0bfc91 Mon Sep 17 00:00:00 2001 From: pengtian Date: Fri, 23 Sep 2022 01:28:54 +0800 Subject: [PATCH 21/21] Update memcpy param --- src/openvpn/tun2tap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openvpn/tun2tap.c b/src/openvpn/tun2tap.c index 34533a557b5..5ca5378d9ca 100644 --- a/src/openvpn/tun2tap.c +++ b/src/openvpn/tun2tap.c @@ -86,7 +86,7 @@ check_tun2tap_arp_dowork(struct context *c, int flag) * if client send the first packet to server after connected, remote_mac_addr is zero * so we build a arp request to replace this packet. */ - if (0 == memcmp(hdr.dest, "\x00\x00\x00\x00\x00\x00", sizeof("\x00\x00\x00\x00\x00\x00") - 1)){ + if (0 == memcmp(hdr.dest, "\x00\x00\x00\x00\x00\x00", OPENVPN_ETH_ALEN)){ struct openvpn_arp arp = { 0 }; arp.mac_addr_type = htons(0x0001); arp.proto_addr_type = htons(0x0800);