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:
maksw committed 2026-06-26 15:18:48 +02:00
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;
+11 -4
View File
@@ -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
+2 -2
View File
@@ -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) {
+12
View File
@@ -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
+214 -60
View File
@@ -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 -12
View File
@@ -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);
}