mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
sim: Add a netdev backed by VPNKit
This commit is contained in:
committed by
Xiang Xiao
parent
124c00b661
commit
a5f8b20fcd
+21
-1
@@ -117,15 +117,35 @@ config SIM_NETDEV
|
|||||||
select ARCH_HAVE_NETDEV_STATISTICS
|
select ARCH_HAVE_NETDEV_STATISTICS
|
||||||
select SCHED_LPWORK
|
select SCHED_LPWORK
|
||||||
select SIM_WALLTIME
|
select SIM_WALLTIME
|
||||||
|
---help---
|
||||||
|
Build in support for a simulated network device.
|
||||||
|
|
||||||
|
if SIM_NETDEV
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Simulated Network Device Type"
|
||||||
|
default SIM_NETDEV_TAP
|
||||||
|
|
||||||
|
config SIM_NETDEV_TAP
|
||||||
|
bool "Simulated Network Device with TAP/WPCAP"
|
||||||
---help---
|
---help---
|
||||||
Build in support for a simulated network device using a TAP device on Linux or
|
Build in support for a simulated network device using a TAP device on Linux or
|
||||||
WPCAP on Windows.
|
WPCAP on Windows.
|
||||||
|
|
||||||
|
config SIM_NETDEV_VPNKIT
|
||||||
|
bool "Simulated Network Device with VPNKit"
|
||||||
|
---help---
|
||||||
|
Build in support for a simulated network device using VPNKit.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
if HOST_LINUX
|
if HOST_LINUX
|
||||||
choice
|
choice
|
||||||
prompt "Simulation Network Type"
|
prompt "Simulation Network Type"
|
||||||
default SIM_NET_HOST_ROUTE
|
default SIM_NET_HOST_ROUTE
|
||||||
depends on SIM_NETDEV
|
depends on SIM_NETDEV_TAP
|
||||||
|
|
||||||
config SIM_NET_HOST_ROUTE
|
config SIM_NET_HOST_ROUTE
|
||||||
bool "Use local host route"
|
bool "Use local host route"
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ ifeq ($(CONFIG_ARCH_ROMGETC),y)
|
|||||||
CSRCS += up_romgetc.c
|
CSRCS += up_romgetc.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SIM_NETDEV),y)
|
ifeq ($(CONFIG_SIM_NETDEV_TAP),y)
|
||||||
CSRCS += up_netdriver.c
|
CSRCS += up_netdriver.c
|
||||||
HOSTCFLAGS += -DNETDEV_BUFSIZE=$(CONFIG_NET_ETH_PKTSIZE)
|
HOSTCFLAGS += -DNETDEV_BUFSIZE=$(CONFIG_NET_ETH_PKTSIZE)
|
||||||
ifneq ($(HOSTOS),Cygwin)
|
ifneq ($(HOSTOS),Cygwin)
|
||||||
@@ -173,7 +173,12 @@ else # HOSTOS != Cygwin
|
|||||||
HOSTSRCS += up_wpcap.c
|
HOSTSRCS += up_wpcap.c
|
||||||
DRVLIB = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a
|
DRVLIB = /lib/w32api/libws2_32.a /lib/w32api/libiphlpapi.a
|
||||||
endif # HOSTOS != Cygwin
|
endif # HOSTOS != Cygwin
|
||||||
endif # CONFIG_SIM_NETDEV
|
else ifeq ($(CONFIG_SIM_NETDEV_VPNKIT),y)
|
||||||
|
CSRCS += up_netdriver.c
|
||||||
|
HOSTSRCS += up_vpnkit.c
|
||||||
|
VPATH += :sim/vpnkit
|
||||||
|
HOSTSRCS += protocol.c negotiate.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_RPTUN),y)
|
ifeq ($(CONFIG_RPTUN),y)
|
||||||
CSRCS += up_rptun.c
|
CSRCS += up_rptun.c
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ FAR struct ioexpander_dev_s *sim_ioexpander_initialize(void);
|
|||||||
|
|
||||||
/* up_tapdev.c **************************************************************/
|
/* up_tapdev.c **************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SIM_NETDEV) && !defined(__CYGWIN__)
|
#if defined(CONFIG_SIM_NETDEV_TAP) && !defined(__CYGWIN__)
|
||||||
void tapdev_init(void);
|
void tapdev_init(void);
|
||||||
int tapdev_avail(void);
|
int tapdev_avail(void);
|
||||||
unsigned int tapdev_read(unsigned char *buf, unsigned int buflen);
|
unsigned int tapdev_read(unsigned char *buf, unsigned int buflen);
|
||||||
@@ -332,7 +332,7 @@ void tapdev_ifdown(void);
|
|||||||
|
|
||||||
/* up_wpcap.c ***************************************************************/
|
/* up_wpcap.c ***************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_SIM_NETDEV) && defined(__CYGWIN__)
|
#if defined(CONFIG_SIM_NETDEV_TAP) && defined(__CYGWIN__)
|
||||||
void wpcap_init(void);
|
void wpcap_init(void);
|
||||||
unsigned int wpcap_read(unsigned char *buf, unsigned int buflen);
|
unsigned int wpcap_read(unsigned char *buf, unsigned int buflen);
|
||||||
void wpcap_send(unsigned char *buf, unsigned int buflen);
|
void wpcap_send(unsigned char *buf, unsigned int buflen);
|
||||||
@@ -345,6 +345,24 @@ void wpcap_send(unsigned char *buf, unsigned int buflen);
|
|||||||
# define netdev_ifdown() {}
|
# define netdev_ifdown() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* up_vpnkit.c **************************************************************/
|
||||||
|
|
||||||
|
#if defined(CONFIG_SIM_NETDEV_VPNKIT)
|
||||||
|
void vpnkit_init(void);
|
||||||
|
int vpnkit_avail(void);
|
||||||
|
unsigned int vpnkit_read(unsigned char *buf, unsigned int buflen);
|
||||||
|
void vpnkit_send(unsigned char *buf, unsigned int buflen);
|
||||||
|
void vpnkit_ifup(in_addr_t ifaddr);
|
||||||
|
void vpnkit_ifdown(void);
|
||||||
|
|
||||||
|
# define netdev_init() vpnkit_init()
|
||||||
|
# define netdev_avail() vpnkit_avail()
|
||||||
|
# define netdev_read(buf,buflen) vpnkit_read(buf,buflen)
|
||||||
|
# define netdev_send(buf,buflen) vpnkit_send(buf,buflen)
|
||||||
|
# define netdev_ifup(ifaddr) vpnkit_ifup(ifaddr)
|
||||||
|
# define netdev_ifdown() vpnkit_ifdown()
|
||||||
|
#endif
|
||||||
|
|
||||||
/* up_netdriver.c ***********************************************************/
|
/* up_netdriver.c ***********************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SIM_NETDEV
|
#ifdef CONFIG_SIM_NETDEV
|
||||||
|
|||||||
@@ -0,0 +1,259 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/sim/src/sim/up_vpnkit.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
/* XXX broken api: mixing nuttx and host in_addr_t */
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <poll.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "vpnkit/protocol.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define ERROR(fmt, ...) \
|
||||||
|
fprintf(stderr, "up_vpnkit: " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#define INFO(fmt, ...) \
|
||||||
|
fprintf(stderr, "up_vpnkit: " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#define DEBUG(fmt, ...)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static const char *g_vpnkit_socket_path = "/tmp/vpnkit-nuttx"; /* XXX config */
|
||||||
|
static struct vif_info g_vifinfo;
|
||||||
|
static int g_vpnkit_fd = -1;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int negotiate(int fd, struct vif_info *vif);
|
||||||
|
void netdriver_setmacaddr(unsigned char *macaddr);
|
||||||
|
|
||||||
|
static void vpnkit_connect()
|
||||||
|
{
|
||||||
|
struct sockaddr_un sun;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (g_vpnkit_fd != -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
ERROR("failed to create a socket");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&sun, 0, sizeof(sun));
|
||||||
|
sun.sun_family = AF_UNIX;
|
||||||
|
strncpy(sun.sun_path, g_vpnkit_socket_path, sizeof(sun.sun_path) - 1);
|
||||||
|
|
||||||
|
if (connect(fd, (const struct sockaddr *)&sun, sizeof(sun)) == -1)
|
||||||
|
{
|
||||||
|
ERROR("failed to connect to the vpnkit socket %s",
|
||||||
|
g_vpnkit_socket_path);
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negotiate(fd, &g_vifinfo))
|
||||||
|
{
|
||||||
|
ERROR("failed to negotiate with vpnkit");
|
||||||
|
close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO("Successfully negotiated with vpnkit");
|
||||||
|
g_vpnkit_fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vpnkit_disconnect()
|
||||||
|
{
|
||||||
|
if (g_vpnkit_fd == -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO("disconnecting from vpnkit");
|
||||||
|
close(g_vpnkit_fd);
|
||||||
|
g_vpnkit_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vpnkit_init
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void vpnkit_init(void)
|
||||||
|
{
|
||||||
|
vpnkit_connect();
|
||||||
|
netdriver_setmacaddr(g_vifinfo.mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vpnkit_avail
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int vpnkit_avail(void)
|
||||||
|
{
|
||||||
|
struct pollfd pfd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
vpnkit_connect();
|
||||||
|
memset(&pfd, 0, sizeof(pfd));
|
||||||
|
pfd.fd = g_vpnkit_fd;
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
ret = poll(&pfd, 1, 0);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
ERROR("poll failed on vpnkit socket");
|
||||||
|
vpnkit_disconnect();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (ret != 0)
|
||||||
|
{
|
||||||
|
DEBUG("vpnkit_avail is returning 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vpnkit_read
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
unsigned int vpnkit_read(unsigned char *buf, unsigned int buflen)
|
||||||
|
{
|
||||||
|
uint8_t header[2]; /* 16-bit payload length in little endian */
|
||||||
|
size_t packet_len;
|
||||||
|
ssize_t ret;
|
||||||
|
DEBUG("vpnkit_read called");
|
||||||
|
|
||||||
|
vpnkit_connect();
|
||||||
|
ret = really_read(g_vpnkit_fd, header, sizeof(header));
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
ERROR("failed to read packet header");
|
||||||
|
vpnkit_disconnect();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet_len = (header[1] << 8) | header[0];
|
||||||
|
if (packet_len > buflen)
|
||||||
|
{
|
||||||
|
INFO("packet larger (%zu) than buffer size (%u)", packet_len, buflen);
|
||||||
|
|
||||||
|
/* XXX it's better to drop this particular packet it. */
|
||||||
|
|
||||||
|
vpnkit_disconnect();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = really_read(g_vpnkit_fd, buf, packet_len);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
ERROR("failed to read packet");
|
||||||
|
vpnkit_disconnect();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("a packet received (size %zu)", packet_len);
|
||||||
|
return packet_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vpnkit_send
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void vpnkit_send(unsigned char *buf, unsigned int buflen)
|
||||||
|
{
|
||||||
|
uint8_t header[2]; /* 16-bit payload length in little endian */
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
DEBUG("vpnkit_send called");
|
||||||
|
vpnkit_connect();
|
||||||
|
header[0] = buflen & 0xff;
|
||||||
|
header[1] = (buflen >> 8) & 0xff;
|
||||||
|
ret = really_write(g_vpnkit_fd, header, sizeof(header));
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
ERROR("failed to write packet header");
|
||||||
|
vpnkit_disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = really_write(g_vpnkit_fd, buf, buflen);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
ERROR("failed to write packet payload");
|
||||||
|
vpnkit_disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("a packet sent (size %u)", buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vpnkit_ifup
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void vpnkit_ifup(in_addr_t ifaddr)
|
||||||
|
{
|
||||||
|
DEBUG("vpnkit_ifup called");
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vpnkit_ifdown
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void vpnkit_ifdown(void)
|
||||||
|
{
|
||||||
|
DEBUG("vpnkit_ifdown called");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user