add ntfs.sys standalone driver target, change default usb vhd layout formatting to ntfs, implement Fat32CreateDir for directory creation support in the fat32 file system driver, add a dedicated HAL serial output endpoint for COM1 writes in hal_serial.c and subscribe serial to HAL text streams, introduce waitable kernel timers with KeTimerCreate, KeTimerSet, and KeTimerCancel alongside spinlock-protected global timer list initialization and scheduler tick tracking, implement SyscallWriteFileAsync system call for asynchronous non-blocking file writes, refactor NetSocketConnect and NetSocketSendTo to use generic SYS_SOCKET_ADDRESS_K structures instead of being hardcoded to IPv4, update gethostbyname and DNS name resolution to support IPv6 parsing via ResolveNameFamily, update tcpserve.exe with -4 and -6 command-line flags to accept and display IPv6 addresses, append size and version headers to all kernel telemetry and statistics structures including SYS_PMM_STATS, SYS_CPU_STATS, and SYS_SCHEDULER_STATS, update winmm timeGetTime to look up high-resolution hardware frequencies via SysGetTickFrequency, integrate 14 native smoke test applications.
This commit is contained in:
1 parent
2c4a68a75f
commit
ed3d065abd
156 files changed
+10509
-2643
No files matched your search
@@ -32,12 +32,12 @@ typedef struct sys_mbox* sys_mbox_t;
|
||||
#define sys_mbox_set_invalid_val(mbox) do { (mbox) = NULL; } while (0)
|
||||
|
||||
/*
|
||||
* lwIP only treats sys_thread_t as an opaque handle. Keep it pointer-sized.
|
||||
* lwIP only treats sys_thread_t as an opaque handle. Keep it pointer-sized.
|
||||
*
|
||||
* Do NOT make this a by-value incomplete struct. MSVC may compile callers
|
||||
* Do NOT make this a by-value incomplete struct. MSVC may compile callers
|
||||
* that see only the incomplete type with a hidden struct-return parameter,
|
||||
* which shifts sys_thread_new(name, thread, arg, ...) so the callee receives
|
||||
* thread == name and arg == thread. The first tcpip_thread then jumps into
|
||||
* thread == name and arg == thread. The first tcpip_thread then jumps into
|
||||
* the literal string "tcpip" as code.
|
||||
*/
|
||||
typedef void* sys_thread_t;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/*
|
||||
* lwipopts.h - kernel port configuration for lwIP 2.2.1.
|
||||
*
|
||||
* This is intentionally a practical first configuration: IPv4, ARP, ICMP,
|
||||
* UDP, TCP, DHCP, DNS and netconn are enabled; IPv6, PPP,
|
||||
* SNMP, lwIP's POSIX socket API, and app protocols stay off.
|
||||
* This is intentionally a practical first configuration: IPv4, IPv6, ARP,
|
||||
* ICMP, ICMPv6, UDP, TCP, DHCP, DNS and netconn are enabled; PPP, SNMP,
|
||||
* lwIP's POSIX socket API, and app protocols stay off.
|
||||
*/
|
||||
|
||||
#define NO_SYS 0
|
||||
@@ -28,10 +28,11 @@
|
||||
#define MEMP_NUM_SYS_TIMEOUT 32
|
||||
|
||||
#define LWIP_IPV4 1
|
||||
#define LWIP_IPV6 0
|
||||
#define LWIP_IPV6 1
|
||||
#define LWIP_ARP 1
|
||||
#define LWIP_ETHERNET 1
|
||||
#define LWIP_ICMP 1
|
||||
#define LWIP_ICMP6 1
|
||||
#define LWIP_IGMP 0
|
||||
#define LWIP_RAW 1
|
||||
#define LWIP_UDP 1
|
||||
@@ -39,6 +40,10 @@
|
||||
#define LWIP_DHCP 1
|
||||
#define LWIP_AUTOIP 0
|
||||
#define LWIP_DNS 1
|
||||
#define LWIP_ND6_QUEUEING 1
|
||||
#define LWIP_IPV6_AUTOCONFIG 1
|
||||
#define LWIP_IPV6_MLD 1
|
||||
#define MEMP_NUM_ND6_QUEUE 8
|
||||
|
||||
#define TCP_MSS 1460
|
||||
#define TCP_WND (4 * TCP_MSS)
|
||||
@@ -81,6 +86,8 @@
|
||||
#define CHECKSUM_CHECK_IP 1
|
||||
#define CHECKSUM_CHECK_UDP 1
|
||||
#define CHECKSUM_CHECK_TCP 1
|
||||
#define CHECKSUM_GEN_ICMP6 1
|
||||
#define CHECKSUM_CHECK_ICMP6 1
|
||||
|
||||
#define LWIP_TIMERS 1
|
||||
#define LWIP_TCPIP_TIMEOUT 1
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
/*
|
||||
* Minimal freestanding stdlib shim for lwIP.
|
||||
*
|
||||
* lwIP 2.2.1 includes <stdlib.h> in a couple of files only for atoi(). If MSVC
|
||||
* lwIP 2.2.1 includes <stdlib.h> in a couple of files only for atoi(). If MSVC
|
||||
* finds the UCRT header, it drags errno.h into the kernel build and then lwIP's
|
||||
* own errno values collide with UCRT's. Put this header first in lwIP's include
|
||||
* own errno values collide with UCRT's. Put this header first in lwIP's include
|
||||
* path so those sources stay freestanding.
|
||||
*/
|
||||
static __inline int atoi(const char* s) {
|
||||
|
||||
@@ -39,6 +39,18 @@ third_party/lwip/src/core/ipv4/ip4_frag.c
|
||||
third_party/lwip/src/core/ipv4/ip4.c
|
||||
third_party/lwip/src/core/ipv4/ip4_addr.c
|
||||
|
||||
|
||||
# IPv6
|
||||
third_party/lwip/src/core/ipv6/dhcp6.c
|
||||
third_party/lwip/src/core/ipv6/ethip6.c
|
||||
third_party/lwip/src/core/ipv6/icmp6.c
|
||||
third_party/lwip/src/core/ipv6/inet6.c
|
||||
third_party/lwip/src/core/ipv6/ip6_frag.c
|
||||
third_party/lwip/src/core/ipv6/ip6.c
|
||||
third_party/lwip/src/core/ipv6/ip6_addr.c
|
||||
third_party/lwip/src/core/ipv6/mld6.c
|
||||
third_party/lwip/src/core/ipv6/nd6.c
|
||||
|
||||
# netconn/socket API
|
||||
third_party/lwip/src/api/api_lib.c
|
||||
third_party/lwip/src/api/api_msg.c
|
||||
|
||||
@@ -22,13 +22,16 @@
|
||||
#include <lwip/netif.h>
|
||||
#include <lwip/pbuf.h>
|
||||
#include <lwip/etharp.h>
|
||||
#include <lwip/ethip6.h>
|
||||
#include <lwip/dhcp.h>
|
||||
#include <lwip/dns.h>
|
||||
#include <lwip/ip4_addr.h>
|
||||
#include <lwip/ip6_addr.h>
|
||||
#include <lwip/ip_addr.h>
|
||||
#include <lwip/api.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/prot/ip.h>
|
||||
#include <lwip/prot/ip6.h>
|
||||
#include <netif/ethernet.h>
|
||||
|
||||
#define LWIP_MAX_NETIFS 8u
|
||||
@@ -42,12 +45,18 @@
|
||||
|
||||
typedef struct LWIP_NETIF_CONFIG {
|
||||
uint8_t UseDhcp;
|
||||
uint8_t HasDns;
|
||||
uint8_t HasDns4;
|
||||
uint8_t EnableIpv6;
|
||||
uint8_t Ipv6Autoconfig;
|
||||
uint8_t HasStaticIpv6;
|
||||
uint8_t HasDns6;
|
||||
char Section[64];
|
||||
ip4_addr_t Address;
|
||||
ip4_addr_t Netmask;
|
||||
ip4_addr_t Gateway;
|
||||
ip4_addr_t Dns;
|
||||
ip4_addr_t Dns4;
|
||||
ip6_addr_t Address6;
|
||||
ip6_addr_t Dns6;
|
||||
} LWIP_NETIF_CONFIG;
|
||||
|
||||
typedef struct LWIP_BINDING {
|
||||
@@ -94,19 +103,19 @@ static KSTATUS LwipProviderAttachDevice(NET_DEVICE* device);
|
||||
static KSTATUS LwipProviderReceiveFrame(NET_DEVICE* device, const void* frame, size_t length);
|
||||
static KSTATUS LwipProviderSocketCreate(uint32_t domain, uint32_t type, uint32_t protocol, void** outSocket);
|
||||
static void LwipProviderSocketClose(void* socket);
|
||||
static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_IPV4_K* address, size_t addressSize);
|
||||
static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_K* address, size_t addressSize);
|
||||
static KSTATUS LwipProviderListen(void* socket, uint32_t backlog);
|
||||
static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_ADDRESS_IPV4_K* remoteOut);
|
||||
static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_IPV4_K* address, size_t addressSize);
|
||||
static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_ADDRESS_K* remoteOut);
|
||||
static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* address, size_t addressSize);
|
||||
static KSTATUS LwipProviderSend(void* socket, const void* buffer, size_t length, uint32_t flags, size_t* sentOut);
|
||||
static KSTATUS LwipProviderReceive(void* socket, void* buffer, size_t length, uint32_t flags, size_t* receivedOut);
|
||||
static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t length, uint32_t flags, const SYS_SOCKET_ADDRESS_IPV4_K* remote, size_t remoteSize, size_t* sentOut);
|
||||
static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length, uint32_t flags, SYS_SOCKET_ADDRESS_IPV4_K* remoteOut, size_t* receivedOut);
|
||||
static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t length, uint32_t flags, const SYS_SOCKET_ADDRESS_K* remote, size_t remoteSize, size_t* sentOut);
|
||||
static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length, uint32_t flags, SYS_SOCKET_ADDRESS_K* remoteOut, size_t* receivedOut);
|
||||
static KSTATUS LwipProviderShutdown(void* socket, uint32_t how);
|
||||
static KSTATUS LwipProviderSetOption(void* socket, uint32_t option, const void* value, size_t valueSize);
|
||||
static KSTATUS LwipProviderGetOption(void* socket, uint32_t option, void* value, size_t valueSize, size_t* actualSizeOut);
|
||||
static KSTATUS LwipProviderPoll(void* socket, uint32_t events, uint32_t* returnedEventsOut);
|
||||
static KSTATUS LwipProviderResolveHostIpv4(const char* name, SYS_SOCKET_ADDRESS_IPV4_K* addressOut);
|
||||
static KSTATUS LwipProviderResolveHost(const char* name, uint32_t family, SYS_SOCKET_ADDRESS_K* addressOut);
|
||||
|
||||
static const NET_STACK_PROVIDER gLwipProvider = {
|
||||
NET_STACK_PROVIDER_VERSION,
|
||||
@@ -127,7 +136,7 @@ static const NET_STACK_PROVIDER gLwipProvider = {
|
||||
LwipProviderSetOption,
|
||||
LwipProviderGetOption,
|
||||
LwipProviderPoll,
|
||||
LwipProviderResolveHostIpv4,
|
||||
LwipProviderResolveHost,
|
||||
};
|
||||
|
||||
// Implements the err To Status operation.
|
||||
@@ -137,7 +146,7 @@ static KSTATUS LwipErrToStatus(err_t err) {
|
||||
case ERR_MEM: return STATUS_NO_MEMORY;
|
||||
case ERR_BUF: return STATUS_BUFFER_TOO_SMALL;
|
||||
case ERR_TIMEOUT: return STATUS_TIMEOUT;
|
||||
case ERR_WOULDBLOCK:return STATUS_TIMEOUT;
|
||||
case ERR_WOULDBLOCK:return STATUS_WOULD_BLOCK;
|
||||
case ERR_RTE: return STATUS_NOT_FOUND;
|
||||
case ERR_VAL: return STATUS_INVALID_PARAMETER;
|
||||
case ERR_ARG: return STATUS_INVALID_PARAMETER;
|
||||
@@ -209,6 +218,57 @@ static KSTATUS LwipGetSettingIpv4(const char* section, const char* key,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static KSTATUS LwipGetSettingIpv6(const char* section, const char* key,
|
||||
ip6_addr_t* out, int required) {
|
||||
char value[LWIP_SETTINGS_VALUE_MAX];
|
||||
KSTATUS st = KeGetSettingString(section, key, value, sizeof(value));
|
||||
if (st == STATUS_NOT_FOUND && !required)
|
||||
return STATUS_NOT_FOUND;
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
if (!ip6addr_aton(value, out)) {
|
||||
DbgPrint("lwIP: invalid IPv6 setting [%s] %s=%s\n", section, key, value);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static KSTATUS LwipLoadIpv6Config(const char* section, LWIP_NETIF_CONFIG* cfg) {
|
||||
char mode[LWIP_SETTINGS_VALUE_MAX];
|
||||
KSTATUS st = KeGetSettingString(section, "ipv6", mode, sizeof(mode));
|
||||
if (st == STATUS_NOT_FOUND) {
|
||||
cfg->EnableIpv6 = 1;
|
||||
cfg->Ipv6Autoconfig = 1;
|
||||
} else if (!KSUCCESS(st)) {
|
||||
return st;
|
||||
} else if (strcmp(mode, "off") == 0 || strcmp(mode, "disabled") == 0) {
|
||||
cfg->EnableIpv6 = 0;
|
||||
} else if (strcmp(mode, "auto") == 0) {
|
||||
cfg->EnableIpv6 = 1;
|
||||
cfg->Ipv6Autoconfig = 1;
|
||||
} else if (strcmp(mode, "static") == 0) {
|
||||
cfg->EnableIpv6 = 1;
|
||||
cfg->HasStaticIpv6 = 1;
|
||||
st = LwipGetSettingIpv6(section, "address6", &cfg->Address6, 1);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
} else {
|
||||
DbgPrint("lwIP: invalid IPv6 mode [%s] ipv6=%s\n", section, mode);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!cfg->EnableIpv6)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
st = LwipGetSettingIpv6(section, "dns6", &cfg->Dns6, 0);
|
||||
if (KSUCCESS(st))
|
||||
cfg->HasDns6 = 1;
|
||||
else if (st != STATUS_NOT_FOUND)
|
||||
return st;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Copies section Name.
|
||||
static KSTATUS LwipCopySectionName(char* out, size_t outSize, const char* prefix, const char* name) {
|
||||
if (!out || !outSize || !prefix || !name)
|
||||
@@ -248,20 +308,20 @@ static KSTATUS LwipLoadConfigFromSection(const char* section, LWIP_NETIF_CONFIG*
|
||||
if (!KSUCCESS(st)) return st;
|
||||
st = LwipGetSettingIpv4(section, "gateway", &cfg->Gateway, 1);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
st = LwipGetSettingIpv4(section, "dns", &cfg->Dns, 1);
|
||||
st = LwipGetSettingIpv4(section, "dns", &cfg->Dns4, 1);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
cfg->HasDns = 1;
|
||||
return STATUS_SUCCESS;
|
||||
cfg->HasDns4 = 1;
|
||||
return LwipLoadIpv6Config(section, cfg);
|
||||
}
|
||||
|
||||
if (strcmp(mode, "dhcp") == 0) {
|
||||
cfg->UseDhcp = 1;
|
||||
st = LwipGetSettingIpv4(section, "dns", &cfg->Dns, 0);
|
||||
st = LwipGetSettingIpv4(section, "dns", &cfg->Dns4, 0);
|
||||
if (KSUCCESS(st))
|
||||
cfg->HasDns = 1;
|
||||
cfg->HasDns4 = 1;
|
||||
else if (st != STATUS_NOT_FOUND)
|
||||
return st;
|
||||
return STATUS_SUCCESS;
|
||||
return LwipLoadIpv6Config(section, cfg);
|
||||
}
|
||||
|
||||
DbgPrint("lwIP: invalid network mode [%s] mode=%s\n", section, mode);
|
||||
@@ -372,18 +432,71 @@ static KSTATUS LwipSocketAllocateWithConn(uint32_t domain, uint32_t type, uint32
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int LwipSocketAddressValid(const SYS_SOCKET_ADDRESS_K* address, size_t addressSize) {
|
||||
if (!address || addressSize < sizeof(SYS_SOCKET_ADDRESS_K))
|
||||
return 0;
|
||||
if (address->Size < sizeof(SYS_SOCKET_ADDRESS_K))
|
||||
return 0;
|
||||
return address->Family == SYS_AF_INET || address->Family == SYS_AF_INET6;
|
||||
}
|
||||
|
||||
static int LwipSocketFamilyMatches(const LWIP_PROVIDER_SOCKET* s, const SYS_SOCKET_ADDRESS_K* address) {
|
||||
if (!s || !address)
|
||||
return 0;
|
||||
if (s->Domain == SYS_AF_INET)
|
||||
return address->Family == SYS_AF_INET;
|
||||
if (s->Domain == SYS_AF_INET6)
|
||||
return address->Family == SYS_AF_INET6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implements the socket Make Ip operation.
|
||||
static void LwipSocketMakeIp(const SYS_SOCKET_ADDRESS_IPV4_K* address, ip_addr_t* out) {
|
||||
IP_ADDR4(out, address->Address[0], address->Address[1], address->Address[2], address->Address[3]);
|
||||
static KSTATUS LwipSocketMakeIp(const SYS_SOCKET_ADDRESS_K* address, ip_addr_t* out) {
|
||||
if (!address || !out)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (address->Family == SYS_AF_INET) {
|
||||
IP_ADDR4(out, address->Address[0], address->Address[1], address->Address[2], address->Address[3]);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
if (address->Family == SYS_AF_INET6) {
|
||||
uint32_t a0 = ((uint32_t)address->Address[0] << 24) | ((uint32_t)address->Address[1] << 16) |
|
||||
((uint32_t)address->Address[2] << 8) | (uint32_t)address->Address[3];
|
||||
uint32_t a1 = ((uint32_t)address->Address[4] << 24) | ((uint32_t)address->Address[5] << 16) |
|
||||
((uint32_t)address->Address[6] << 8) | (uint32_t)address->Address[7];
|
||||
uint32_t a2 = ((uint32_t)address->Address[8] << 24) | ((uint32_t)address->Address[9] << 16) |
|
||||
((uint32_t)address->Address[10] << 8) | (uint32_t)address->Address[11];
|
||||
uint32_t a3 = ((uint32_t)address->Address[12] << 24) | ((uint32_t)address->Address[13] << 16) |
|
||||
((uint32_t)address->Address[14] << 8) | (uint32_t)address->Address[15];
|
||||
IP_ADDR6_HOST(out, a0, a1, a2, a3);
|
||||
ip6_addr_set_zone(ip_2_ip6(out), (u8_t)address->ScopeId);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// Implements the socket Fill Address operation.
|
||||
static void LwipSocketFillAddress(SYS_SOCKET_ADDRESS_IPV4_K* out, const ip_addr_t* ip, u16_t port) {
|
||||
static void LwipSocketFillAddress(SYS_SOCKET_ADDRESS_K* out, const ip_addr_t* ip, u16_t port) {
|
||||
if (!out)
|
||||
return;
|
||||
memset(out, 0, sizeof(*out));
|
||||
out->Family = SYS_AF_INET;
|
||||
out->Size = sizeof(*out);
|
||||
out->Port = port;
|
||||
if (!ip)
|
||||
return;
|
||||
if (IP_IS_V6(ip)) {
|
||||
out->Family = SYS_AF_INET6;
|
||||
out->ScopeId = ip6_addr_zone(ip_2_ip6(ip));
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
uint32_t word = lwip_htonl(ip_2_ip6(ip)->addr[i]);
|
||||
out->Address[i * 4 + 0] = (uint8_t)(word >> 24);
|
||||
out->Address[i * 4 + 1] = (uint8_t)(word >> 16);
|
||||
out->Address[i * 4 + 2] = (uint8_t)(word >> 8);
|
||||
out->Address[i * 4 + 3] = (uint8_t)word;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
out->Family = SYS_AF_INET;
|
||||
out->Address[0] = (uint8_t)ip4_addr1(ip_2_ip4(ip));
|
||||
out->Address[1] = (uint8_t)ip4_addr2(ip_2_ip4(ip));
|
||||
out->Address[2] = (uint8_t)ip4_addr3(ip_2_ip4(ip));
|
||||
@@ -428,11 +541,17 @@ static err_t LwipNetifInit(struct netif* netif) {
|
||||
netif->name[0] = 'e';
|
||||
netif->name[1] = 'n';
|
||||
netif->output = etharp_output;
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif
|
||||
netif->linkoutput = LwipLowLevelOutput;
|
||||
netif->mtu = (u16_t)(device->Mtu ? device->Mtu : NET_MTU_ETHERNET);
|
||||
netif->hwaddr_len = NET_ETHERNET_ADDRESS_LENGTH;
|
||||
memcpy(netif->hwaddr, device->HardwareAddress, NET_ETHERNET_ADDRESS_LENGTH);
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;
|
||||
#if LWIP_IPV6_MLD
|
||||
netif->flags |= NETIF_FLAG_MLD6;
|
||||
#endif
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@@ -476,12 +595,29 @@ static void LwipAttachCallback(void* arg) {
|
||||
if (netif_default == NULL)
|
||||
netif_set_default(n);
|
||||
|
||||
if (b->Config.HasDns) {
|
||||
if (b->Config.HasDns4) {
|
||||
ip_addr_t dns;
|
||||
ip_addr_copy_from_ip4(dns, b->Config.Dns);
|
||||
ip_addr_copy_from_ip4(dns, b->Config.Dns4);
|
||||
dns_setserver(0, &dns);
|
||||
}
|
||||
|
||||
#if LWIP_IPV6
|
||||
if (b->Config.EnableIpv6) {
|
||||
netif_create_ip6_linklocal_address(n, 1);
|
||||
if (b->Config.Ipv6Autoconfig)
|
||||
n->ip6_autoconfig_enabled = 1;
|
||||
if (b->Config.HasStaticIpv6) {
|
||||
netif_ip6_addr_set(n, 1, &b->Config.Address6);
|
||||
netif_ip6_addr_set_state(n, 1, IP6_ADDR_PREFERRED);
|
||||
}
|
||||
if (b->Config.HasDns6) {
|
||||
ip_addr_t dns6;
|
||||
ip_addr_copy_from_ip6(dns6, b->Config.Dns6);
|
||||
dns_setserver(1, &dns6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (b->Config.UseDhcp) {
|
||||
#if LWIP_DHCP
|
||||
err_t dhcpErr = dhcp_start(n);
|
||||
@@ -586,11 +722,12 @@ static KSTATUS LwipProviderAttachDevice(NET_DEVICE* device) {
|
||||
}
|
||||
|
||||
gBindings[device->Index] = b;
|
||||
DbgPrint("lwIP: attached %s as netif %c%c%u using [%s] mode=%s\n",
|
||||
DbgPrint("lwIP: attached %s as netif %c%c%u using [%s] mode=%s ipv6=%s\n",
|
||||
device->Name,
|
||||
b->Netif.name[0], b->Netif.name[1], b->Netif.num,
|
||||
b->Config.Section,
|
||||
b->Config.UseDhcp ? "dhcp" : "static");
|
||||
b->Config.UseDhcp ? "dhcp" : "static",
|
||||
b->Config.EnableIpv6 ? (b->Config.HasStaticIpv6 ? "static" : "auto") : "off");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -636,26 +773,27 @@ static KSTATUS LwipProviderSocketCreate(uint32_t domain, uint32_t type, uint32_t
|
||||
|
||||
if (!gLwipInitialized)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
if (domain != SYS_AF_INET)
|
||||
if (domain != SYS_AF_INET && domain != SYS_AF_INET6)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
int ipv6 = domain == SYS_AF_INET6;
|
||||
enum netconn_type netconnType;
|
||||
u8_t rawProtocol = 0;
|
||||
if (type == SYS_SOCK_STREAM) {
|
||||
if (protocol != 0 && protocol != SYS_IPPROTO_TCP)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
netconnType = NETCONN_TCP;
|
||||
netconnType = ipv6 ? NETCONN_TCP_IPV6 : NETCONN_TCP;
|
||||
protocol = SYS_IPPROTO_TCP;
|
||||
} else if (type == SYS_SOCK_DGRAM) {
|
||||
if (protocol != 0 && protocol != SYS_IPPROTO_UDP)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
netconnType = NETCONN_UDP;
|
||||
netconnType = ipv6 ? NETCONN_UDP_IPV6 : NETCONN_UDP;
|
||||
protocol = SYS_IPPROTO_UDP;
|
||||
} else if (type == SYS_SOCK_RAW) {
|
||||
if (protocol != SYS_IPPROTO_ICMP)
|
||||
if ((!ipv6 && protocol != SYS_IPPROTO_ICMP) || (ipv6 && protocol != SYS_IPPROTO_ICMPV6))
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
netconnType = NETCONN_RAW;
|
||||
rawProtocol = IP_PROTO_ICMP;
|
||||
netconnType = ipv6 ? NETCONN_RAW_IPV6 : NETCONN_RAW;
|
||||
rawProtocol = ipv6 ? IP6_NEXTH_ICMP6 : IP_PROTO_ICMP;
|
||||
} else {
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
@@ -703,15 +841,15 @@ static void LwipProviderSocketClose(void* socket) {
|
||||
}
|
||||
|
||||
// Implements the provider Bind operation.
|
||||
static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_IPV4_K* address, size_t addressSize) {
|
||||
static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_K* address, size_t addressSize) {
|
||||
LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket;
|
||||
if (!s || !address)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (addressSize < sizeof(SYS_SOCKET_ADDRESS_IPV4_K))
|
||||
if (!LwipSocketAddressValid(address, addressSize))
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
if ((s->Type != SYS_SOCK_STREAM && s->Type != SYS_SOCK_DGRAM) || !s->Conn)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (address->Family != SYS_AF_INET)
|
||||
if (!LwipSocketFamilyMatches(s, address))
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
KSTATUS st = LwipSocketLock(s);
|
||||
@@ -724,7 +862,11 @@ static KSTATUS LwipProviderBind(void* socket, const SYS_SOCKET_ADDRESS_IPV4_K* a
|
||||
}
|
||||
|
||||
ip_addr_t ip;
|
||||
LwipSocketMakeIp(address, &ip);
|
||||
st = LwipSocketMakeIp(address, &ip);
|
||||
if (!KSUCCESS(st)) {
|
||||
LwipSocketUnlock(s);
|
||||
return st;
|
||||
}
|
||||
err_t err = netconn_bind(s->Conn, &ip, address->Port);
|
||||
if (err == ERR_OK)
|
||||
s->Bound = 1;
|
||||
@@ -763,7 +905,7 @@ static KSTATUS LwipProviderListen(void* socket, uint32_t backlog) {
|
||||
}
|
||||
|
||||
// Implements the provider Accept operation.
|
||||
static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_ADDRESS_IPV4_K* remoteOut) {
|
||||
static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_ADDRESS_K* remoteOut) {
|
||||
LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket;
|
||||
if (!s || !acceptedOut)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
@@ -807,11 +949,12 @@ static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_A
|
||||
ip_addr_t peerIp;
|
||||
u16_t peerPort = 0;
|
||||
err = netconn_peer(acceptedConn, &peerIp, &peerPort);
|
||||
if (err == ERR_OK && IP_IS_V4(&peerIp)) {
|
||||
if (err == ERR_OK) {
|
||||
LwipSocketFillAddress(remoteOut, &peerIp, peerPort);
|
||||
} else {
|
||||
memset(remoteOut, 0, sizeof(*remoteOut));
|
||||
remoteOut->Family = SYS_AF_INET;
|
||||
remoteOut->Size = sizeof(*remoteOut);
|
||||
remoteOut->Family = s->Domain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,15 +963,15 @@ static KSTATUS LwipProviderAccept(void* socket, void** acceptedOut, SYS_SOCKET_A
|
||||
}
|
||||
|
||||
// Implements the provider Connect operation.
|
||||
static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_IPV4_K* address, size_t addressSize) {
|
||||
static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_K* address, size_t addressSize) {
|
||||
LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket;
|
||||
if (!s || !address)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (addressSize < sizeof(SYS_SOCKET_ADDRESS_IPV4_K))
|
||||
if (!LwipSocketAddressValid(address, addressSize))
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
if ((s->Type != SYS_SOCK_STREAM && s->Type != SYS_SOCK_DGRAM) || !s->Conn)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (address->Family != SYS_AF_INET)
|
||||
if (!LwipSocketFamilyMatches(s, address))
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
KSTATUS st = LwipSocketLock(s);
|
||||
@@ -845,7 +988,11 @@ static KSTATUS LwipProviderConnect(void* socket, const SYS_SOCKET_ADDRESS_IPV4_K
|
||||
}
|
||||
|
||||
ip_addr_t ip;
|
||||
LwipSocketMakeIp(address, &ip);
|
||||
st = LwipSocketMakeIp(address, &ip);
|
||||
if (!KSUCCESS(st)) {
|
||||
LwipSocketUnlock(s);
|
||||
return st;
|
||||
}
|
||||
|
||||
err_t err = netconn_connect(s->Conn, &ip, address->Port);
|
||||
if (err == ERR_OK)
|
||||
@@ -1007,13 +1154,13 @@ static KSTATUS LwipProviderReceive(void* socket, void* buffer, size_t length, ui
|
||||
}
|
||||
|
||||
static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t length, uint32_t flags,
|
||||
const SYS_SOCKET_ADDRESS_IPV4_K* remote, size_t remoteSize, size_t* sentOut) {
|
||||
const SYS_SOCKET_ADDRESS_K* remote, size_t remoteSize, size_t* sentOut) {
|
||||
LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket;
|
||||
if (sentOut)
|
||||
*sentOut = 0;
|
||||
if (!s || (!buffer && length) || !remote)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (remoteSize < sizeof(SYS_SOCKET_ADDRESS_IPV4_K))
|
||||
if (!LwipSocketAddressValid(remote, remoteSize))
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
if (flags != 0)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
@@ -1021,7 +1168,7 @@ static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t lengt
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (s->Type == SYS_SOCK_RAW && length > LWIP_PROVIDER_SOCKET_RAW_MAX_BYTES)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (remote->Family != SYS_AF_INET)
|
||||
if (!LwipSocketFamilyMatches(s, remote))
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
if (length == 0)
|
||||
return STATUS_SUCCESS;
|
||||
@@ -1046,8 +1193,11 @@ static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t lengt
|
||||
err_t err = netbuf_ref(nb, buffer, (u16_t)length);
|
||||
if (err == ERR_OK) {
|
||||
ip_addr_t ip;
|
||||
LwipSocketMakeIp(remote, &ip);
|
||||
err = netconn_sendto(s->Conn, nb, &ip, remote->Port);
|
||||
KSTATUS makeStatus = LwipSocketMakeIp(remote, &ip);
|
||||
if (KSUCCESS(makeStatus))
|
||||
err = netconn_sendto(s->Conn, nb, &ip, remote->Port);
|
||||
else
|
||||
err = ERR_ARG;
|
||||
}
|
||||
netbuf_delete(nb);
|
||||
|
||||
@@ -1059,7 +1209,7 @@ static KSTATUS LwipProviderSendTo(void* socket, const void* buffer, size_t lengt
|
||||
}
|
||||
|
||||
static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length, uint32_t flags,
|
||||
SYS_SOCKET_ADDRESS_IPV4_K* remoteOut, size_t* receivedOut) {
|
||||
SYS_SOCKET_ADDRESS_K* remoteOut, size_t* receivedOut) {
|
||||
LWIP_PROVIDER_SOCKET* s = (LWIP_PROVIDER_SOCKET*)socket;
|
||||
if (receivedOut)
|
||||
*receivedOut = 0;
|
||||
@@ -1114,11 +1264,12 @@ static KSTATUS LwipProviderReceiveFrom(void* socket, void* buffer, size_t length
|
||||
|
||||
if (remoteOut) {
|
||||
const ip_addr_t* from = netbuf_fromaddr(nb);
|
||||
if (from && IP_IS_V4(from)) {
|
||||
if (from) {
|
||||
LwipSocketFillAddress(remoteOut, from, netbuf_fromport(nb));
|
||||
} else {
|
||||
memset(remoteOut, 0, sizeof(*remoteOut));
|
||||
remoteOut->Family = SYS_AF_INET;
|
||||
remoteOut->Size = sizeof(*remoteOut);
|
||||
remoteOut->Family = s->Domain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1271,27 +1422,30 @@ static KSTATUS LwipProviderShutdown(void* socket, uint32_t how) {
|
||||
return LwipErrToStatus(err);
|
||||
}
|
||||
|
||||
// Implements the provider Resolve Host Ipv4 operation.
|
||||
static KSTATUS LwipProviderResolveHostIpv4(const char* name, SYS_SOCKET_ADDRESS_IPV4_K* addressOut) {
|
||||
// Implements the provider Resolve Host operation.
|
||||
static KSTATUS LwipProviderResolveHost(const char* name, uint32_t family, SYS_SOCKET_ADDRESS_K* addressOut) {
|
||||
if (!name || !addressOut)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (!gLwipInitialized)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
u8_t dnsType;
|
||||
if (family == SYS_AF_INET)
|
||||
dnsType = NETCONN_DNS_IPV4;
|
||||
else if (family == SYS_AF_INET6)
|
||||
dnsType = NETCONN_DNS_IPV6;
|
||||
else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
ip_addr_t resolved;
|
||||
err_t err = netconn_gethostbyname_addrtype(name, &resolved, NETCONN_DNS_IPV4);
|
||||
err_t err = netconn_gethostbyname_addrtype(name, &resolved, dnsType);
|
||||
if (err != ERR_OK)
|
||||
return LwipErrToStatus(err);
|
||||
if (!IP_IS_V4(&resolved))
|
||||
if ((family == SYS_AF_INET && !IP_IS_V4(&resolved)) ||
|
||||
(family == SYS_AF_INET6 && !IP_IS_V6(&resolved)))
|
||||
return STATUS_NOT_FOUND;
|
||||
|
||||
memset(addressOut, 0, sizeof(*addressOut));
|
||||
addressOut->Family = SYS_AF_INET;
|
||||
addressOut->Port = 0;
|
||||
addressOut->Address[0] = (uint8_t)ip4_addr1(ip_2_ip4(&resolved));
|
||||
addressOut->Address[1] = (uint8_t)ip4_addr2(ip_2_ip4(&resolved));
|
||||
addressOut->Address[2] = (uint8_t)ip4_addr3(ip_2_ip4(&resolved));
|
||||
addressOut->Address[3] = (uint8_t)ip4_addr4(ip_2_ip4(&resolved));
|
||||
LwipSocketFillAddress(addressOut, &resolved, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_disable)
|
||||
#pragma intrinsic(_enable)
|
||||
#include <ntlite/ddi/hal_api.h>
|
||||
#include <lwip/opt.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <lwip/err.h>
|
||||
@@ -41,7 +40,6 @@ struct sys_mbox {
|
||||
uint32_t Valid;
|
||||
};
|
||||
|
||||
|
||||
static uint64_t (*gLwipQueryTicksUs)(void) = 0;
|
||||
static uint32_t gRandState = 0x4b4e4554u; // 'KNET'
|
||||
|
||||
@@ -70,7 +68,7 @@ u32_t sys_jiffies(void) {
|
||||
return sys_now();
|
||||
}
|
||||
|
||||
// lwIP's core/sys.c provides sys_msleep() when it is not a macro. Do not
|
||||
// lwIP's core/sys.c provides sys_msleep() when it is not a macro. Do not
|
||||
// define it here as well, or MSVC links both sys.obj and lwip_sys_arch.obj
|
||||
// with a duplicate sys_msleep symbol.
|
||||
|
||||
@@ -360,15 +358,10 @@ sys_thread_t sys_thread_new(const char* name, lwip_thread_fn thread, void* arg,
|
||||
}
|
||||
|
||||
sys_prot_t sys_arch_protect(void) {
|
||||
uintptr_t flags = __readeflags();
|
||||
_disable();
|
||||
return (sys_prot_t)flags;
|
||||
return (sys_prot_t)HalDisableInterrupts();
|
||||
}
|
||||
|
||||
// Implements the sys arch unprotect operation.
|
||||
// Restores the interrupt state saved by sys_arch_protect.
|
||||
void sys_arch_unprotect(sys_prot_t pval) {
|
||||
if (((uintptr_t)pval) & 0x200u)
|
||||
_enable();
|
||||
else
|
||||
_disable();
|
||||
HalRestoreInterrupts((uintptr_t)pval);
|
||||
}
|
||||
Reference in new issue
Block a user