rtt更新
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -138,6 +138,8 @@ struct at_socket
|
||||
uint16_t sendevent;
|
||||
/* error happened for this socket, set by event_callback() */
|
||||
uint16_t errevent;
|
||||
/* Last UDP connect address */
|
||||
struct sockaddr last_udp_adr;
|
||||
|
||||
#ifdef SAL_USING_POSIX
|
||||
rt_wqueue_t wait_head;
|
||||
@@ -166,6 +168,7 @@ int at_recv(int socket, void *mem, size_t len, int flags);
|
||||
int at_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen);
|
||||
int at_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen);
|
||||
struct hostent *at_gethostbyname(const char *name);
|
||||
int at_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
|
||||
int at_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
|
||||
void at_freeaddrinfo(struct addrinfo *ai);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2025, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2025, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -10,6 +10,7 @@
|
||||
* 2018-08-17 chenyong multiple client support
|
||||
* 2021-03-17 Meco Man fix a buf of leaking memory
|
||||
* 2021-07-14 Sszl fix a buf of leaking memory
|
||||
* 2025-01-02 dongly support SERIAL_V2
|
||||
*/
|
||||
|
||||
#include <at.h>
|
||||
@@ -960,6 +961,10 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
|
||||
RT_ASSERT(client->device->type == RT_Device_Class_Char);
|
||||
|
||||
rt_device_set_rx_indicate(client->device, at_client_rx_ind);
|
||||
|
||||
#ifdef RT_USING_SERIAL_V2
|
||||
open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_NON_BLOCKING);
|
||||
#else
|
||||
/* using DMA mode first */
|
||||
open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
|
||||
/* using interrupt mode when DMA mode not supported */
|
||||
@@ -967,6 +972,7 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu
|
||||
{
|
||||
open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||
}
|
||||
#endif /* RT_USING_SERIAL_V2 */
|
||||
RT_ASSERT(open_result == RT_EOK);
|
||||
}
|
||||
else
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2025, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -7,6 +7,7 @@
|
||||
* Date Author Notes
|
||||
* 2018-03-30 chenyong first version
|
||||
* 2018-04-14 chenyong modify parse arguments
|
||||
* 2025-01-02 dongly support SERIAL_V2
|
||||
*/
|
||||
|
||||
#include <at.h>
|
||||
@@ -565,6 +566,10 @@ int at_server_init(void)
|
||||
RT_ASSERT(at_server_local->device->type == RT_Device_Class_Char);
|
||||
|
||||
rt_device_set_rx_indicate(at_server_local->device, at_rx_ind);
|
||||
|
||||
#ifdef RT_USING_SERIAL_V2
|
||||
open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_NON_BLOCKING);
|
||||
#else
|
||||
/* using DMA mode first */
|
||||
open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
|
||||
/* using interrupt mode when DMA mode not supported */
|
||||
@@ -572,6 +577,7 @@ int at_server_init(void)
|
||||
{
|
||||
open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
|
||||
}
|
||||
#endif /* RT_USING_SERIAL_V2 */
|
||||
RT_ASSERT(open_result == RT_EOK);
|
||||
}
|
||||
else
|
||||
|
@@ -736,7 +736,7 @@ void dhcpd_start(const char *netif_name)
|
||||
DEBUG_PRINTF("ip_start: [%s]\r\n", str_tmp);
|
||||
sprintf(p, "%d", DHCPD_CLIENT_IP_MAX);
|
||||
ip4addr_aton(str_tmp, &ip_end);
|
||||
DEBUG_PRINTF("ip_start: [%s]\r\n", str_tmp);
|
||||
DEBUG_PRINTF("ip_end: [%s]\r\n", str_tmp);
|
||||
|
||||
res = dhcp_server_start(netif, &ip_start, &ip_end);
|
||||
if (res != 0)
|
||||
|
@@ -281,6 +281,10 @@ if RT_USING_LWIP
|
||||
endif
|
||||
endif
|
||||
|
||||
config RT_LWIP_ENABLE_USER_HOOKS
|
||||
bool "Enable user-defined LWIP hooks"
|
||||
default n
|
||||
|
||||
menuconfig RT_LWIP_DEBUG
|
||||
bool "Enable lwIP Debugging Options"
|
||||
default n
|
||||
|
@@ -99,6 +99,10 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef RT_USING_NETDEV
|
||||
#include "netdev.h"
|
||||
#endif
|
||||
|
||||
/** Random generator function to create random TXIDs and source ports for queries */
|
||||
#ifndef DNS_RAND_TXID
|
||||
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0)
|
||||
@@ -300,7 +304,9 @@ static u8_t dns_last_pcb_idx;
|
||||
static u8_t dns_seqno;
|
||||
static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
|
||||
static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS];
|
||||
#ifndef RT_USING_NETDEV
|
||||
static ip_addr_t dns_servers[DNS_MAX_SERVERS];
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV4
|
||||
const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT;
|
||||
@@ -364,21 +370,25 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
|
||||
{
|
||||
if (numdns < DNS_MAX_SERVERS) {
|
||||
if (dnsserver != NULL) {
|
||||
dns_servers[numdns] = (*dnsserver);
|
||||
|
||||
#ifdef RT_USING_NETDEV
|
||||
extern struct netif *netif_list;
|
||||
extern struct netdev *netdev_get_by_name(const char *name);
|
||||
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||
struct netif *netif = NULL;
|
||||
|
||||
/* set network interface device DNS server address */
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
|
||||
netdev_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
|
||||
}
|
||||
#else
|
||||
dns_servers[numdns] = (*dnsserver);
|
||||
#endif /* RT_USING_NETDEV */
|
||||
} else {
|
||||
#ifdef RT_USING_NETDEV
|
||||
struct netif *netif = NULL;
|
||||
for (netif = netif_list; netif != NULL; netif = netif->next) {
|
||||
netdev_set_dns_server(netdev_get_by_name(netif->name), numdns, IP_ADDR_ANY);
|
||||
}
|
||||
#else
|
||||
dns_servers[numdns] = *IP_ADDR_ANY;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -395,7 +405,11 @@ const ip_addr_t *
|
||||
dns_getserver(u8_t numdns)
|
||||
{
|
||||
if (numdns < DNS_MAX_SERVERS) {
|
||||
#ifdef RT_USING_NETDEV
|
||||
return &netdev_default->dns_servers[numdns];
|
||||
#else
|
||||
return &dns_servers[numdns];
|
||||
#endif
|
||||
} else {
|
||||
return IP_ADDR_ANY;
|
||||
}
|
||||
@@ -770,11 +784,19 @@ dns_send(u8_t idx)
|
||||
u8_t n;
|
||||
u8_t pcb_idx;
|
||||
struct dns_table_entry *entry = &dns_table[idx];
|
||||
const ip_addr_t *dns_addr;
|
||||
|
||||
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
|
||||
(u16_t)(entry->server_idx), entry->name));
|
||||
LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS);
|
||||
if (ip_addr_isany_val(dns_servers[entry->server_idx])
|
||||
|
||||
#ifdef RT_USING_NETDEV
|
||||
dns_addr = &netdev_default->dns_servers[entry->server_idx];
|
||||
#else
|
||||
dns_addr = &dns_servers[entry->server_idx];
|
||||
#endif
|
||||
|
||||
if (ip_addr_isany(dns_addr)
|
||||
#if LWIP_DNS_SUPPORT_MDNS_QUERIES
|
||||
&& !entry->is_mdns
|
||||
#endif
|
||||
@@ -859,7 +881,11 @@ dns_send(u8_t idx)
|
||||
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||
{
|
||||
dst_port = DNS_SERVER_PORT;
|
||||
dst = &dns_servers[entry->server_idx];
|
||||
dst = dns_addr;
|
||||
#ifdef RT_USING_NETDEV
|
||||
/* set netif index for this pcb, specify the network interface corresponding to the DNS server */
|
||||
dns_pcbs[pcb_idx]->netif_idx = netif_get_index((struct netif *)netdev_default->user_data);
|
||||
#endif
|
||||
}
|
||||
err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port);
|
||||
|
||||
@@ -1040,8 +1066,15 @@ dns_backupserver_available(struct dns_table_entry *pentry)
|
||||
u8_t ret = 0;
|
||||
|
||||
if (pentry) {
|
||||
if ((pentry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[pentry->server_idx + 1])) {
|
||||
ret = 1;
|
||||
if ((pentry->server_idx + 1 < DNS_MAX_SERVERS)) {
|
||||
#ifdef RT_USING_NETDEV
|
||||
const ip_addr_t *dns_addr = &netdev_default->dns_servers[pentry->server_idx + 1];
|
||||
#else
|
||||
const ip_addr_t *dns_addr = &dns_servers[pentry->server_idx + 1];
|
||||
#endif
|
||||
if (!ip_addr_isany(dns_addr)) {
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1230,9 +1263,14 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr,
|
||||
if (!entry->is_mdns)
|
||||
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||
{
|
||||
#ifdef RT_USING_NETDEV
|
||||
const ip_addr_t *dns_addr = &netdev_default->dns_servers[entry->server_idx];
|
||||
#else
|
||||
const ip_addr_t *dns_addr = &dns_servers[entry->server_idx];
|
||||
#endif
|
||||
/* Check whether response comes from the same network address to which the
|
||||
question was sent. (RFC 5452) */
|
||||
if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) {
|
||||
if (!ip_addr_cmp(addr, dns_addr)) {
|
||||
goto ignore_packet; /* ignore this packet */
|
||||
}
|
||||
}
|
||||
@@ -1631,8 +1669,13 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call
|
||||
if (!is_mdns)
|
||||
#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */
|
||||
{
|
||||
#ifdef RT_USING_NETDEV
|
||||
const ip_addr_t *dns_addr = &netdev_default->dns_servers[0];
|
||||
#else
|
||||
const ip_addr_t *dns_addr = &dns_servers[0];
|
||||
#endif
|
||||
/* prevent calling found callback if no server is set, return error instead */
|
||||
if (ip_addr_isany_val(dns_servers[0])) {
|
||||
if (ip_addr_isany(dns_addr)) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
}
|
||||
|
@@ -673,7 +673,16 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in)
|
||||
for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
|
||||
ip_addr_t dns_addr;
|
||||
ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
|
||||
#ifdef RT_USING_NETDEV
|
||||
extern struct netdev *netdev_get_by_name(const char *name);
|
||||
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||
/* Here we only need to set the dns server of the corresponding network device,
|
||||
* but do not need to configure all network devices.
|
||||
*/
|
||||
netdev_set_dns_server(netdev_get_by_name(netif->name), n, &dns_addr);
|
||||
#else
|
||||
dns_setserver(n, &dns_addr);
|
||||
#endif
|
||||
}
|
||||
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
|
||||
}
|
||||
|
@@ -538,7 +538,16 @@ dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in)
|
||||
}
|
||||
ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN, netif);
|
||||
/* @todo: do we need a different offset than DHCP(v4)? */
|
||||
#ifdef RT_USING_NETDEV
|
||||
extern struct netdev *netdev_get_by_name(const char *name);
|
||||
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||
/* Here we only need to set the dns server of the corresponding network device,
|
||||
* but do not need to configure all network devices.
|
||||
*/
|
||||
netdev_set_dns_server(netdev_get_by_name(netif->name), n, &dns_addr);
|
||||
#else
|
||||
dns_setserver(n, &dns_addr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* @ todo: parse and set Domain Search List */
|
||||
|
@@ -776,14 +776,32 @@ nd6_input(struct pbuf *p, struct netif *inp)
|
||||
|
||||
if (htonl(rdnss_opt->lifetime) > 0) {
|
||||
/* TODO implement Lifetime > 0 */
|
||||
#ifdef RT_USING_NETDEV
|
||||
extern struct netdev *netdev_get_by_name(const char *name);
|
||||
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||
/* Here we only need to set the dns server of the corresponding network device,
|
||||
* but do not need to configure all network devices.
|
||||
*/
|
||||
netdev_set_dns_server(netdev_get_by_name(inp->name), rdnss_server_idx++, &rdnss_address);
|
||||
#else
|
||||
dns_setserver(rdnss_server_idx++, &rdnss_address);
|
||||
#endif
|
||||
} else {
|
||||
/* TODO implement DNS removal in dns.c */
|
||||
u8_t s;
|
||||
for (s = 0; s < DNS_MAX_SERVERS; s++) {
|
||||
const ip_addr_t *addr = dns_getserver(s);
|
||||
if(ip_addr_cmp(addr, &rdnss_address)) {
|
||||
dns_setserver(s, NULL);
|
||||
#ifdef RT_USING_NETDEV
|
||||
extern struct netdev *netdev_get_by_name(const char *name);
|
||||
extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||
/* Here we only need to set the dns server of the corresponding network device,
|
||||
* but do not need to configure all network devices.
|
||||
*/
|
||||
netdev_set_dns_server(netdev_get_by_name(inp->name), s, IP_ADDR_ANY);
|
||||
#else
|
||||
dns_setserver(s, IP_ADDR_ANY);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -495,6 +495,18 @@ typedef struct fd_set
|
||||
/* poll-related defines and types */
|
||||
/* @todo: find a better way to guard the definition of these defines and types if already defined */
|
||||
#if !defined(POLLIN) && !defined(POLLOUT)
|
||||
#ifdef RT_USING_MUSLLIBC
|
||||
#define POLLIN 0x001 /**< There is data to read. */
|
||||
#define POLLPRI 0x002 /**< There is urgent data to read. */
|
||||
#define POLLOUT 0x004 /**< Writing is now possible. */
|
||||
#define POLLERR 0x008 /**< Error condition. */
|
||||
#define POLLHUP 0x010 /**< Hang up. */
|
||||
#define POLLNVAL 0x020 /**< Invalid polling request. */
|
||||
#define POLLRDNORM 0x040 /**< Normal data may be read. */
|
||||
#define POLLRDBAND 0x080 /**< Priority data may be read. */
|
||||
#define POLLWRNORM 0x100 /**< Writing normal data is possible. */
|
||||
#define POLLWRBAND 0x200 /**< Writing priority data is possible. */
|
||||
#else
|
||||
#define POLLIN 0x1
|
||||
#define POLLOUT 0x2
|
||||
#define POLLERR 0x4
|
||||
@@ -506,6 +518,7 @@ typedef struct fd_set
|
||||
#define POLLWRNORM 0x80
|
||||
#define POLLWRBAND 0x100
|
||||
#define POLLHUP 0x200
|
||||
#endif /* RT_USING_MUSLLIBC */
|
||||
typedef unsigned int nfds_t;
|
||||
struct pollfd
|
||||
{
|
||||
|
@@ -24,7 +24,8 @@
|
||||
*
|
||||
******************************************************************************
|
||||
* REVISION HISTORY
|
||||
*
|
||||
* 24-09-12 Evlers <1425295900@qq.com>
|
||||
* add support for independent dns services for multiple network devices
|
||||
* 03-01-01 Marc Boucher <marc@mbsi.ca>
|
||||
* Ported to lwIP.
|
||||
* 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
|
||||
@@ -134,6 +135,9 @@
|
||||
#if PPP_IPV6_SUPPORT
|
||||
#include "netif/ppp/ipv6cp.h"
|
||||
#endif /* PPP_IPV6_SUPPORT */
|
||||
#ifdef RT_USING_NETDEV
|
||||
#include "netdev.h"
|
||||
#endif /* RT_USING_NETDEV */
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
@@ -1109,9 +1113,20 @@ int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
|
||||
ip_addr_set_ip4_u32_val(ns, ns1);
|
||||
#ifdef RT_USING_NETDEV
|
||||
/* Here we only need to set the dns server of the corresponding network device,
|
||||
* but do not need to configure all network cards.
|
||||
*/
|
||||
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 0, &ns);
|
||||
#else
|
||||
dns_setserver(0, &ns);
|
||||
#endif
|
||||
ip_addr_set_ip4_u32_val(ns, ns2);
|
||||
#ifdef RT_USING_NETDEV
|
||||
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 1, &ns);
|
||||
#else
|
||||
dns_setserver(1, &ns);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1127,12 +1142,20 @@ int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
|
||||
nsa = dns_getserver(0);
|
||||
ip_addr_set_ip4_u32_val(nsb, ns1);
|
||||
if (ip_addr_cmp(nsa, &nsb)) {
|
||||
#ifdef RT_USING_NETDEV
|
||||
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 0, IP_ADDR_ANY);
|
||||
#else
|
||||
dns_setserver(0, IP_ADDR_ANY);
|
||||
#endif
|
||||
}
|
||||
nsa = dns_getserver(1);
|
||||
ip_addr_set_ip4_u32_val(nsb, ns2);
|
||||
if (ip_addr_cmp(nsa, &nsb)) {
|
||||
#ifdef RT_USING_NETDEV
|
||||
netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 1, IP_ADDR_ANY);
|
||||
#else
|
||||
dns_setserver(1, IP_ADDR_ANY);
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@
|
||||
* 2018-11-02 MurphyZhao port to lwIP 2.1.0
|
||||
* 2021-09-07 Grissiom fix eth_tx_msg ack bug
|
||||
* 2022-02-22 xiangxistu integrate v1.4.1 v2.0.3 and v2.1.2 porting layer
|
||||
* 2024-09-12 Evlers add support for independent dns services for multiple network devices
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -169,8 +170,11 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
|
||||
}
|
||||
|
||||
#ifdef RT_LWIP_DNS
|
||||
static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server)
|
||||
static int lwip_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server)
|
||||
{
|
||||
#if RT_USING_LWIP_VER_NUM >= 0x20102
|
||||
netdev_low_level_set_dns_server(netdev, dns_num, dns_server);
|
||||
#else
|
||||
#if LWIP_VERSION_MAJOR == 1U /* v1.x */
|
||||
extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver);
|
||||
#else /* >=2.x */
|
||||
@@ -178,6 +182,7 @@ static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_
|
||||
#endif /* LWIP_VERSION_MAJOR == 1U */
|
||||
|
||||
dns_setserver(dns_num, dns_server);
|
||||
#endif /* RT_USING_LWIP_VER_NUM >= 0x20102 */
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* RT_LWIP_DNS */
|
||||
@@ -421,6 +426,11 @@ static int netdev_add(struct netif *lwip_netif)
|
||||
netdev->gw = lwip_netif->gw;
|
||||
netdev->netmask = lwip_netif->netmask;
|
||||
|
||||
#ifdef NETDEV_USING_LINK_STATUS_CALLBACK
|
||||
extern void netdev_status_change(struct netdev *netdev, enum netdev_cb_type type);
|
||||
netdev_set_status_callback(netdev, netdev_status_change);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -654,4 +654,15 @@
|
||||
#endif
|
||||
#endif /* RT_USING_LWIP_VER_NUM >= 0x20000 */
|
||||
|
||||
#ifdef RT_LWIP_ENABLE_USER_HOOKS
|
||||
/**
|
||||
* This hook provides flexibility for handling unknown Ethernet protocols.
|
||||
*
|
||||
* For example, you can define how to handle packets of unknown types,
|
||||
* such as forwarding them to another interface, discarding them,
|
||||
* or passing them to an application for further processing.
|
||||
*/
|
||||
#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL lwip_hook_unknown_eth_protocol
|
||||
#endif /* RT_LWIP_ENABLE_USER_HOOKS */
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
||||
|
@@ -19,7 +19,11 @@ if RT_USING_NETDEV
|
||||
config NETDEV_USING_AUTO_DEFAULT
|
||||
bool "Enable default netdev automatic change features"
|
||||
default y
|
||||
|
||||
|
||||
config NETDEV_USING_LINK_STATUS_CALLBACK
|
||||
bool "Enable netdev callback on link status change"
|
||||
default n
|
||||
|
||||
config NETDEV_USING_IPV6
|
||||
bool "Enable IPV6 protocol support"
|
||||
default n
|
||||
|
@@ -101,6 +101,8 @@ struct netdev
|
||||
netdev_callback_fn status_callback; /* network interface device flags change callback */
|
||||
netdev_callback_fn addr_callback; /* network interface device address information change callback */
|
||||
|
||||
int ifindex; /* network interface device ifindex */
|
||||
|
||||
#ifdef RT_USING_SAL
|
||||
void *sal_user_data; /* user-specific data for SAL */
|
||||
#endif /* RT_USING_SAL */
|
||||
@@ -111,8 +113,6 @@ struct netdev
|
||||
extern struct netdev *netdev_list;
|
||||
/* The default network interface device */
|
||||
extern struct netdev *netdev_default;
|
||||
/* The local virtual network device */
|
||||
extern struct netdev *netdev_lo;
|
||||
/* The network interface device ping response object */
|
||||
struct netdev_ping_resp
|
||||
{
|
||||
@@ -153,10 +153,14 @@ int netdev_unregister(struct netdev *netdev);
|
||||
struct netdev *netdev_get_first_by_flags(uint16_t flags);
|
||||
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr);
|
||||
struct netdev *netdev_get_by_name(const char *name);
|
||||
struct netdev *netdev_get_by_ifindex(int ifindex);
|
||||
#ifdef RT_USING_SAL
|
||||
struct netdev *netdev_get_by_family(int family);
|
||||
int netdev_family_get(struct netdev *netdev);
|
||||
#endif /* RT_USING_SAL */
|
||||
#if defined(SAL_USING_AF_NETLINK)
|
||||
int netdev_getnetdev(struct msg_buf *msg, int (*cb)(struct msg_buf *m_buf, struct netdev *nd, int nd_num, int index, int ipvx));
|
||||
#endif
|
||||
|
||||
/* Set default network interface device in list */
|
||||
void netdev_set_default(struct netdev *netdev);
|
||||
|
@@ -35,12 +35,11 @@
|
||||
struct netdev *netdev_list = RT_NULL;
|
||||
/* The default network interface device */
|
||||
struct netdev *netdev_default = RT_NULL;
|
||||
/* The local virtual network device */
|
||||
struct netdev *netdev_lo = RT_NULL;
|
||||
/* The global network register callback */
|
||||
static netdev_callback_fn g_netdev_register_callback = RT_NULL;
|
||||
static netdev_callback_fn g_netdev_default_change_callback = RT_NULL;
|
||||
static RT_DEFINE_SPINLOCK(_spinlock);
|
||||
static int netdev_num;
|
||||
|
||||
/**
|
||||
* This function will register network interface device and
|
||||
@@ -55,7 +54,6 @@ static RT_DEFINE_SPINLOCK(_spinlock);
|
||||
*/
|
||||
int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_uint16_t flags_mask;
|
||||
rt_uint16_t index;
|
||||
|
||||
@@ -103,7 +101,7 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
||||
/* initialize current network interface device single list */
|
||||
rt_slist_init(&(netdev->list));
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
if (netdev_list == RT_NULL)
|
||||
{
|
||||
@@ -115,7 +113,10 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
||||
rt_slist_append(&(netdev_list->list), &(netdev->list));
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
netdev_num++;
|
||||
netdev->ifindex = netdev_num;
|
||||
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
if (netdev_default == RT_NULL)
|
||||
{
|
||||
@@ -146,7 +147,6 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
||||
*/
|
||||
int netdev_unregister(struct netdev *netdev)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
struct netdev *cur_netdev = RT_NULL;
|
||||
|
||||
@@ -157,7 +157,7 @@ int netdev_unregister(struct netdev *netdev)
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
@@ -188,7 +188,7 @@ int netdev_unregister(struct netdev *netdev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
#if defined(SAL_USING_AF_NETLINK)
|
||||
rtnl_ip_notify(netdev, RTM_DELLINK);
|
||||
@@ -233,7 +233,6 @@ void netdev_set_register_callback(netdev_callback_fn register_callback)
|
||||
*/
|
||||
struct netdev *netdev_get_first_by_flags(uint16_t flags)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
@@ -242,19 +241,19 @@ struct netdev *netdev_get_first_by_flags(uint16_t flags)
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
netdev = rt_slist_entry(node, struct netdev, list);
|
||||
if (netdev && (netdev->flags & flags) != 0)
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
@@ -270,7 +269,6 @@ struct netdev *netdev_get_first_by_flags(uint16_t flags)
|
||||
*/
|
||||
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
@@ -279,19 +277,19 @@ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
netdev = rt_slist_entry(node, struct netdev, list);
|
||||
if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr))
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
@@ -307,7 +305,6 @@ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
|
||||
*/
|
||||
struct netdev *netdev_get_by_name(const char *name)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
@@ -316,19 +313,55 @@ struct netdev *netdev_get_by_name(const char *name)
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
netdev = rt_slist_entry(node, struct netdev, list);
|
||||
if (netdev && (rt_strncmp(netdev->name, name, rt_strlen(name) < RT_NAME_MAX ? rt_strlen(name) : RT_NAME_MAX) == 0))
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get network interface device
|
||||
* in network interface device list by netdev ifindex.
|
||||
*
|
||||
* @param ifindex the ifindex of network interface device
|
||||
*
|
||||
* @return != NULL: network interface device object
|
||||
* NULL: get failed
|
||||
*/
|
||||
struct netdev *netdev_get_by_ifindex(int ifindex)
|
||||
{
|
||||
rt_slist_t *node = RT_NULL;
|
||||
struct netdev *netdev = RT_NULL;
|
||||
|
||||
if (netdev_list == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
netdev = rt_slist_entry(node, struct netdev, list);
|
||||
if (netdev && (netdev->ifindex == ifindex))
|
||||
{
|
||||
rt_spin_unlock(&_spinlock);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
@@ -345,7 +378,6 @@ struct netdev *netdev_get_by_name(const char *name)
|
||||
*/
|
||||
struct netdev *netdev_get_by_family(int family)
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_slist_t *node = RT_NULL;
|
||||
struct netdev *netdev = RT_NULL;
|
||||
struct sal_proto_family *pf = RT_NULL;
|
||||
@@ -355,7 +387,7 @@ struct netdev *netdev_get_by_family(int family)
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_spin_lock(&_spinlock);
|
||||
|
||||
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
|
||||
{
|
||||
@@ -363,7 +395,7 @@ struct netdev *netdev_get_by_family(int family)
|
||||
pf = (struct sal_proto_family *) netdev->sal_user_data;
|
||||
if (pf && pf->skt_ops && pf->family == family && netdev_is_up(netdev))
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
@@ -374,12 +406,12 @@ struct netdev *netdev_get_by_family(int family)
|
||||
pf = (struct sal_proto_family *) netdev->sal_user_data;
|
||||
if (pf && pf->skt_ops && pf->sec_family == family && netdev_is_up(netdev))
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
@@ -400,6 +432,44 @@ int netdev_family_get(struct netdev *netdev)
|
||||
|
||||
#endif /* RT_USING_SAL */
|
||||
|
||||
#if defined(SAL_USING_AF_NETLINK)
|
||||
int netdev_getnetdev(struct msg_buf *msg, int (*cb)(struct msg_buf *m_buf, struct netdev *nd, int nd_num, int index, int ipvx))
|
||||
{
|
||||
struct netdev *cur_nd_list = netdev_list;
|
||||
struct netdev *nd_node;
|
||||
int nd_num = 0;
|
||||
int err = 0;
|
||||
|
||||
if (cur_nd_list == RT_NULL)
|
||||
return 0;
|
||||
|
||||
rt_spin_lock(&_spinlock);
|
||||
nd_num = rt_slist_len(&cur_nd_list->list) + 1;
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
err = cb(msg, cur_nd_list, nd_num, nd.ifindex, ROUTE_IPV4_TRUE);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
||||
rt_spin_lock(&_spinlock);
|
||||
rt_slist_for_each_entry(nd_node, &(cur_nd_list->list), list)
|
||||
{
|
||||
rt_spin_unlock(&_spinlock);
|
||||
err = cb(msg, nd_node, nd_num, nd.ifindex, ROUTE_IPV4_TRUE);
|
||||
if (err < 0)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_spin_lock(&_spinlock);
|
||||
}
|
||||
rt_spin_unlock(&_spinlock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function will set default network interface device.
|
||||
*
|
||||
|
@@ -99,7 +99,7 @@ static const struct sal_socket_ops at_socket_ops =
|
||||
static const struct sal_netdb_ops at_netdb_ops =
|
||||
{
|
||||
at_gethostbyname,
|
||||
NULL,
|
||||
at_gethostbyname_r,
|
||||
at_getaddrinfo,
|
||||
at_freeaddrinfo,
|
||||
};
|
||||
|
@@ -10,16 +10,16 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef SAL_USING_POSIX
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include <lwip/api.h>
|
||||
#include <lwip/init.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
#ifdef SAL_USING_POSIX
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include <sal_low_lvl.h>
|
||||
#include <af_inet.h>
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2024 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -16,6 +16,31 @@
|
||||
#include <sys/errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/**
|
||||
* @brief Accepts an incoming connection on a listening socket.
|
||||
*
|
||||
* This function extracts the first connection request from the queue of pending connections for
|
||||
* the listening socket specified by 's' and creates a new socket for the connection.
|
||||
*
|
||||
* @param s The file descriptor of the listening socket. This socket must be created with
|
||||
* 'socket()', bound with 'bind()', and set to listen with 'listen()'.
|
||||
* @param addr A pointer to a 'sockaddr' structure that will receive the address of the connecting entity.
|
||||
* This structure is filled with the address of the client once the connection is accepted.
|
||||
* Can be 'NULL' if the address is not needed.
|
||||
* @param addrlen A pointer to a variable containing the size of 'addr'. When the function returns, this
|
||||
* variable will hold the actual size of the address returned. Can be 'NULL' if 'addr' is 'NULL'.
|
||||
*
|
||||
* @return On success, returns a new file descriptor for the accepted connection. On failure, returns '-1'
|
||||
* and sets errno to indicate the error.
|
||||
*
|
||||
* @note The original socket 's' remains open and continues to listen for additional incoming connections.
|
||||
* The returned file descriptor is used for communication with the connected client.
|
||||
*
|
||||
* @see socket() Creates a socket for accepting connections.
|
||||
* @see bind() Binds the socket to a local address.
|
||||
* @see listen() Sets the socket to listen for incoming connections.
|
||||
* @see close()/closesocket() Closes a socket when it is no longer needed.
|
||||
*/
|
||||
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
int new_socket = -1;
|
||||
@@ -71,6 +96,27 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
}
|
||||
RTM_EXPORT(accept);
|
||||
|
||||
/**
|
||||
* @brief Binds a socket to a specific local address and port.
|
||||
*
|
||||
* This function assigns a local address to a socket, defined by the 'name' parameter.
|
||||
* The address allows the socket to receive data sent to this address.
|
||||
*
|
||||
* @param s The file descriptor of the socket to bind.
|
||||
* @param name A pointer to a 'sockaddr' structure that specifies the address to bind to.
|
||||
* The structure varies based on the address family, such as 'sockaddr_in' for IPv4.
|
||||
* @param namelen The length of the 'sockaddr' structure pointed to by 'name', in bytes.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The socket must be created with 'socket()' before calling 'bind()'.
|
||||
* Binding is typically used for server sockets, specifying the local IP and port to listen on.
|
||||
* If the port is set to '0', the system assigns an available port automatically.
|
||||
*
|
||||
* @see socket() Creates a socket for binding.
|
||||
* @see listen() Prepares the socket to listen for incoming connections after binding.
|
||||
* @see accept() Accepts connections on a bound and listening socket.
|
||||
*/
|
||||
int bind(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -79,6 +125,30 @@ int bind(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
}
|
||||
RTM_EXPORT(bind);
|
||||
|
||||
/**
|
||||
* @brief Shuts down part of a full-duplex connection on a socket.
|
||||
*
|
||||
* This function disables further sends or receives on the specified socket, depending on the value
|
||||
* of the 'how' parameter. It does not close the socket, which must still be closed separately using
|
||||
* 'close()' or 'closesocket()'.
|
||||
*
|
||||
* @param s The file descriptor of the socket to shut down.
|
||||
* @param how Specifies the type of shutdown to perform. The 'how' parameter can be one of the following:
|
||||
* - 'SHUT_RD': Disables further reading on the socket. The socket will not receive data.
|
||||
* - 'SHUT_WR': Disables further writing on the socket. The socket will not send data.
|
||||
* - 'SHUT_RDWR': Disables both reading and writing on the socket. The socket will be fully shut down.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'shutdown()' function is used to gracefully close a socket in one or both directions
|
||||
* (read/write). It is commonly used in scenarios like closing the write side of a TCP connection
|
||||
* when a server has finished sending data but still expects to receive data.
|
||||
*
|
||||
* @see socket() Creates the socket used for communication.
|
||||
* @see close()/closesocket() Closes the socket after the shutdown is complete.
|
||||
* @see recv() Receives data on a socket.
|
||||
* @see send() Sends data on a socket.
|
||||
*/
|
||||
int shutdown(int s, int how)
|
||||
{
|
||||
int error = 0;
|
||||
@@ -113,6 +183,28 @@ int shutdown(int s, int how)
|
||||
}
|
||||
RTM_EXPORT(shutdown);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the address of the peer connected to a socket.
|
||||
*
|
||||
* This function obtains the address of the peer (remote end) connected to the socket 's'.
|
||||
* It is typically used on connected sockets (e.g., TCP) to retrieve information about the peer.
|
||||
*
|
||||
* @param s The file descriptor of the connected socket.
|
||||
* @param name A pointer to a 'sockaddr' structure that will be filled with the address of the peer.
|
||||
* The structure type (e.g., 'sockaddr_in' for IPv4) depends on the address family of the socket.
|
||||
* @param namelen A pointer to a variable that initially specifies the size of the 'name' structure.
|
||||
* On return, it contains the actual size of the address returned.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'getpeername()' function is useful for retrieving information about the remote end of a connection,
|
||||
* such as the IP address and port of a peer in a TCP connection. This function is only valid for sockets
|
||||
* that are in a connected state.
|
||||
*
|
||||
* @see socket() Creates the socket used for the connection.
|
||||
* @see connect() Connects the socket to a remote address.
|
||||
* @see getsockname() Retrieves the local address of a socket.
|
||||
*/
|
||||
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -121,6 +213,29 @@ int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
}
|
||||
RTM_EXPORT(getpeername);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the local address of a socket.
|
||||
*
|
||||
* This function obtains the local address (IP address and port) associated with the socket 's'.
|
||||
* It is typically used to determine the local address and port of a bound or connected socket.
|
||||
*
|
||||
* @param s The file descriptor of the socket.
|
||||
* @param name A pointer to a 'sockaddr' structure that will be filled with the local address
|
||||
* of the socket. The structure type (e.g., 'sockaddr_in' for IPv4) depends on the
|
||||
* address family of the socket.
|
||||
* @param namelen A pointer to a variable that initially specifies the size of the 'name' structure.
|
||||
* Upon return, this variable contains the actual size of the address returned.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'getsockname()' function is useful for retrieving the local address information of a socket,
|
||||
* which can be especially useful in cases where the socket was bound with an ephemeral port (port 0),
|
||||
* allowing you to discover the actual port number assigned by the system.
|
||||
*
|
||||
* @see socket() Creates the socket for communication.
|
||||
* @see bind() Binds the socket to a specific local address.
|
||||
* @see getpeername() Retrieves the address of the peer connected to a socket.
|
||||
*/
|
||||
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -129,6 +244,34 @@ int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
}
|
||||
RTM_EXPORT(getsockname);
|
||||
|
||||
/**
|
||||
* @brief Retrieves options for a socket.
|
||||
*
|
||||
* This function retrieves the current value for a specified option on a socket, identified
|
||||
* by the file descriptor 's'. The option is specified by the 'level' and 'optname' parameters.
|
||||
*
|
||||
* @param s The file descriptor of the socket from which to retrieve the option.
|
||||
* @param level The protocol level at which the option resides. Common levels include:
|
||||
* - 'SOL_SOCKET': To retrieve socket-level options.
|
||||
* - 'IPPROTO_IP': To retrieve IPv4 options.
|
||||
* - 'IPPROTO_TCP': To retrieve TCP options.
|
||||
* @param optname The name of the option to retrieve. Some common options include:
|
||||
* - 'SO_REUSEADDR': Checks if address reuse is enabled.
|
||||
* - 'SO_RCVBUF': Retrieves the receive buffer size.
|
||||
* - 'TCP_NODELAY': Checks if Nagle's algorithm is disabled for TCP sockets.
|
||||
* @param optval A pointer to a buffer where the value of the option will be stored.
|
||||
* The buffer must be large enough to hold the option value.
|
||||
* @param optlen A pointer to a variable that initially specifies the size of 'optval'.
|
||||
* On return, it contains the actual size of the option value returned.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'getsockopt()' function is useful for inspecting socket configuration and current settings.
|
||||
* It can provide information about options such as buffer sizes, timeouts, and protocol-specific features.
|
||||
*
|
||||
* @see socket() Creates the socket to retrieve options from.
|
||||
* @see setsockopt() Sets options for the socket.
|
||||
*/
|
||||
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -137,6 +280,35 @@ int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
}
|
||||
RTM_EXPORT(getsockopt);
|
||||
|
||||
/**
|
||||
* @brief Sets options on a socket.
|
||||
*
|
||||
* This function sets the specified option for the socket referenced by the file descriptor 's'.
|
||||
* Socket options affect the behavior of the socket and are specified by the 'level' and 'optname' parameters.
|
||||
*
|
||||
* @param s The file descriptor of the socket on which to set the option.
|
||||
* @param level The protocol level at which the option resides. Common levels include:
|
||||
* - 'SOL_SOCKET': To configure socket-level options.
|
||||
* - 'IPPROTO_IP': To configure IPv4 options.
|
||||
* - 'IPPROTO_TCP': To configure TCP options.
|
||||
* @param optname The name of the option to set. Some common options include:
|
||||
* - 'SO_REUSEADDR': Allows reuse of local addresses.
|
||||
* - 'SO_RCVBUF': Sets the receive buffer size.
|
||||
* - 'TCP_NODELAY': Disables Nagle's algorithm for TCP sockets.
|
||||
* @param optval A pointer to the buffer containing the value to set for the specified option.
|
||||
* The type of data in this buffer depends on the option being set.
|
||||
* @param optlen The size, in bytes, of the option value pointed to by 'optval'.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'setsockopt()' function is useful for configuring various socket behaviors, such as
|
||||
* setting timeouts, buffer sizes, and enabling or disabling certain protocol features.
|
||||
* The changes may affect socket performance and resource usage.
|
||||
*
|
||||
* @see socket() Creates the socket to configure.
|
||||
* @see getsockopt() Retrieves options set on the socket.
|
||||
* @see bind() Binds the socket to a local address.
|
||||
*/
|
||||
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -145,6 +317,29 @@ int setsockopt(int s, int level, int optname, const void *optval, socklen_t optl
|
||||
}
|
||||
RTM_EXPORT(setsockopt);
|
||||
|
||||
/**
|
||||
* @brief Initiates a connection on a socket.
|
||||
*
|
||||
* This function connects the socket specified by 's' to the server address specified by 'name'.
|
||||
* The socket must have been created with 'socket()' and, for some types of sockets, may need
|
||||
* to be bound to a local address with 'bind()' before calling 'connect()'.
|
||||
*
|
||||
* @param s The file descriptor of the socket to connect.
|
||||
* @param name A pointer to a 'sockaddr' structure that specifies the address of the server to connect to.
|
||||
* The specific structure (e.g., 'sockaddr_in' for IPv4) depends on the address family.
|
||||
* @param namelen The length, in bytes, of the address structure pointed to by 'name'.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note 'connect()' is typically used by client sockets to establish a connection with a server.
|
||||
* For connection-oriented protocols (e.g., TCP), this initiates the connection handshake.
|
||||
* For connectionless protocols (e.g., UDP), it defines a fixed peer address.
|
||||
*
|
||||
* @see socket() Creates the socket to be connected.
|
||||
* @see bind() Binds the socket to a local address (optional for client sockets).
|
||||
* @see accept() Used by server sockets to accept incoming connections.
|
||||
* @see close()/closesocket() Closes the socket when done.
|
||||
*/
|
||||
int connect(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -152,6 +347,26 @@ int connect(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
}
|
||||
RTM_EXPORT(connect);
|
||||
|
||||
/**
|
||||
* @brief Marks a socket as a passive socket, ready to accept incoming connections.
|
||||
*
|
||||
* This function prepares a socket to accept incoming connection requests. The socket
|
||||
* must first be created with 'socket()' and bound to a local address with 'bind()'.
|
||||
*
|
||||
* @param s The file descriptor of the socket to set to listening mode.
|
||||
* @param backlog The maximum number of pending connections that can be queued for acceptance.
|
||||
* If more incoming connections arrive than the backlog limit, they may be rejected
|
||||
* or ignored until the server accepts some of the pending connections.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note After calling 'listen()', the socket can be used with 'accept()' to handle connection requests.
|
||||
* The backlog size affects how many connections can wait to be accepted before being rejected.
|
||||
*
|
||||
* @see socket() Creates the socket.
|
||||
* @see bind() Binds the socket to a specific address.
|
||||
* @see accept() Accepts a pending connection request on the listening socket.
|
||||
*/
|
||||
int listen(int s, int backlog)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -160,6 +375,31 @@ int listen(int s, int backlog)
|
||||
}
|
||||
RTM_EXPORT(listen);
|
||||
|
||||
/**
|
||||
* @brief Receives data from a connected socket.
|
||||
*
|
||||
* This function reads data from a connected socket and stores it in the specified buffer.
|
||||
* It is typically used with connection-oriented protocols (e.g., TCP).
|
||||
*
|
||||
* @param s The file descriptor of the connected socket to receive data from.
|
||||
* @param mem A pointer to the buffer where the received data will be stored.
|
||||
* @param len The maximum number of bytes to read into the buffer.
|
||||
* @param flags Specifies the behavior of the receive operation. Common flags include:
|
||||
* - '0': Default operation.
|
||||
* - 'MSG_DONTWAIT': Non-blocking operation.
|
||||
* - 'MSG_PEEK': Peeks at the incoming data without removing it from the queue.
|
||||
*
|
||||
* @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
* A return value of '0' indicates that the connection has been closed by the remote peer.
|
||||
*
|
||||
* @note The 'recv()' function may not receive all the requested bytes in a single call.
|
||||
* Multiple calls to 'recv()' may be needed to read the complete data.
|
||||
*
|
||||
* @see socket() Creates the socket to be used for receiving data.
|
||||
* @see connect() Connects the socket to a remote address (for connection-oriented protocols).
|
||||
* @see recvfrom() Receives data from a specific address, typically used with connectionless sockets.
|
||||
* @see send() Sends data on a connected socket.
|
||||
*/
|
||||
int recv(int s, void *mem, size_t len, int flags)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -168,6 +408,36 @@ int recv(int s, void *mem, size_t len, int flags)
|
||||
}
|
||||
RTM_EXPORT(recv);
|
||||
|
||||
/**
|
||||
* @brief Sends a message on a socket.
|
||||
*
|
||||
* The 'sendmsg()' function sends data on the socket 's' using the structured data in the 'msghdr'
|
||||
* structure. This function is commonly used for sending complex messages with multiple buffers,
|
||||
* control information, or for working with datagram sockets.
|
||||
*
|
||||
* @param s The file descriptor of the socket to send the message on.
|
||||
* @param message A pointer to an 'msghdr' structure, which contains the data, address, and control information:
|
||||
* - 'msg_name': Optional destination address (used for connectionless sockets).
|
||||
* - 'msg_namelen': Size of the destination address.
|
||||
* - 'msg_iov': An array of 'iovec' structures that point to the data buffers to be sent.
|
||||
* - 'msg_iovlen': The number of elements in the 'msg_iov' array.
|
||||
* - 'msg_control': Optional ancillary data, such as file descriptors for UNIX domain sockets.
|
||||
* - 'msg_controllen': The size of the ancillary data buffer.
|
||||
* - 'msg_flags': Flags related to the message.
|
||||
* @param flags Specifies how the message should be sent. Common flags include:
|
||||
* - 'MSG_DONTWAIT': Sends the message in non-blocking mode.
|
||||
* - 'MSG_EOR': Indicates the end of a record (for record-oriented sockets).
|
||||
*
|
||||
* @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'sendmsg()' function is useful for sending messages with multiple buffers or ancillary data,
|
||||
* allowing flexible communication options such as attaching file descriptors. This function can be
|
||||
* used with both connection-oriented and connectionless sockets.
|
||||
*
|
||||
* @see recvmsg() Receives a message from a socket.
|
||||
* @see send() Sends data on a socket.
|
||||
* @see socket() Creates the socket to use with 'sendmsg()'.
|
||||
*/
|
||||
int sendmsg(int s, const struct msghdr *message, int flags)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -176,6 +446,38 @@ int sendmsg(int s, const struct msghdr *message, int flags)
|
||||
}
|
||||
RTM_EXPORT(sendmsg);
|
||||
|
||||
/**
|
||||
* @brief Receives a message from a socket.
|
||||
*
|
||||
* The 'recvmsg()' function receives data from the socket 's' into the buffers described by
|
||||
* the 'msghdr' structure. This function allows for complex data structures, including multiple
|
||||
* data buffers and optional control information.
|
||||
*
|
||||
* @param s The file descriptor of the socket to receive data from.
|
||||
* @param message A pointer to an 'msghdr' structure, which will be filled with the received data and
|
||||
* information. The structure contains:
|
||||
* - 'msg_name': A buffer for the source address (used for connectionless sockets).
|
||||
* - 'msg_namelen': Specifies the size of the 'msg_name' buffer.
|
||||
* - 'msg_iov': An array of 'iovec' structures that point to the buffers to store received data.
|
||||
* - 'msg_iovlen': The number of elements in the 'msg_iov' array.
|
||||
* - 'msg_control': A buffer for ancillary data, such as received file descriptors.
|
||||
* - 'msg_controllen': The size of the ancillary data buffer.
|
||||
* - 'msg_flags': Flags set by the 'recvmsg()' call to indicate the message status.
|
||||
* @param flags Specifies how the message should be received. Common flags include:
|
||||
* - 'MSG_DONTWAIT': Receives the message in non-blocking mode.
|
||||
* - 'MSG_PEEK': Peeks at the incoming message without removing it from the queue.
|
||||
* - 'MSG_WAITALL': Waits for the full amount of data to be received.
|
||||
*
|
||||
* @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The 'recvmsg()' function is useful for receiving messages with multiple buffers or ancillary data.
|
||||
* It can be used with both connection-oriented and connectionless sockets, making it versatile for
|
||||
* different communication needs.
|
||||
*
|
||||
* @see sendmsg() Sends a message on a socket.
|
||||
* @see recv() Receives data on a socket.
|
||||
* @see socket() Creates the socket used with 'recvmsg()'.
|
||||
*/
|
||||
int recvmsg(int s, struct msghdr *message, int flags)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -184,6 +486,36 @@ int recvmsg(int s, struct msghdr *message, int flags)
|
||||
}
|
||||
RTM_EXPORT(recvmsg);
|
||||
|
||||
/**
|
||||
* @brief Receives data from a specific address using an unconnected socket.
|
||||
*
|
||||
* This function reads data from a socket and stores it in the specified buffer. It is commonly used
|
||||
* with connectionless protocols (e.g., UDP) to receive data from a specific source address.
|
||||
*
|
||||
* @param s The file descriptor of the socket to receive data from.
|
||||
* @param mem A pointer to the buffer where the received data will be stored.
|
||||
* @param len The maximum number of bytes to read into the buffer.
|
||||
* @param flags Specifies the behavior of the receive operation. Common flags include:
|
||||
* - '0': Default operation.
|
||||
* - 'MSG_DONTWAIT': Non-blocking operation.
|
||||
* - 'MSG_PEEK': Peeks at the incoming data without removing it from the queue.
|
||||
* @param from A pointer to a 'sockaddr' structure that will be filled with the address of the
|
||||
* sending entity. This is the source address from which the data was received.
|
||||
* @param fromlen A pointer to a variable that initially contains the size of the 'from' structure.
|
||||
* Upon return, this variable will hold the actual size of the address returned.
|
||||
*
|
||||
* @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
* A return value of '0' indicates that the connection has been closed by the remote peer.
|
||||
*
|
||||
* @note The 'recvfrom()' function is useful for receiving data from an arbitrary source address,
|
||||
* which makes it especially suited for connectionless protocols where the peer's address may vary.
|
||||
* The 'from' parameter is filled with the sender's address, which can be useful for identifying
|
||||
* the origin of the data.
|
||||
*
|
||||
* @see socket() Creates the socket used for receiving data.
|
||||
* @see sendto() Sends data to a specific address, typically used with connectionless sockets.
|
||||
* @see recv() Receives data on a connected socket.
|
||||
*/
|
||||
int recvfrom(int s, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
@@ -193,6 +525,32 @@ int recvfrom(int s, void *mem, size_t len, int flags,
|
||||
}
|
||||
RTM_EXPORT(recvfrom);
|
||||
|
||||
/**
|
||||
* @brief Sends data on a connected socket.
|
||||
*
|
||||
* This function sends data to a connected socket, specified by the file descriptor 's'.
|
||||
* It is typically used with connection-oriented protocols (e.g., TCP).
|
||||
*
|
||||
* @param s The file descriptor of the socket to send data on.
|
||||
* The socket must be connected to a remote peer.
|
||||
* @param dataptr A pointer to the buffer containing the data to send.
|
||||
* @param size The size, in bytes, of the data to be sent from the buffer.
|
||||
* @param flags Specifies the behavior of the send operation. Common flags include:
|
||||
* - '0': Default operation.
|
||||
* - 'MSG_DONTWAIT': Non-blocking operation.
|
||||
* - 'MSG_NOSIGNAL': Prevents the sending of 'SIGPIPE' on errors.
|
||||
*
|
||||
* @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
* If the connection is closed by the remote peer, the return value may be '0'.
|
||||
*
|
||||
* @note The 'send()' function does not guarantee that all data will be sent in a single call.
|
||||
* If fewer bytes are sent than requested, the remaining data should be sent in subsequent calls.
|
||||
*
|
||||
* @see socket() Creates the socket to be used for sending data.
|
||||
* @see connect() Connects the socket to a remote address (for connection-oriented protocols).
|
||||
* @see sendto() Sends data to a specific address, typically used with connectionless sockets.
|
||||
* @see recv() Receives data from a connected socket.
|
||||
*/
|
||||
int send(int s, const void *dataptr, size_t size, int flags)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
@@ -201,6 +559,34 @@ int send(int s, const void *dataptr, size_t size, int flags)
|
||||
}
|
||||
RTM_EXPORT(send);
|
||||
|
||||
/**
|
||||
* @brief Sends data to a specific address using an unconnected socket.
|
||||
*
|
||||
* This function is typically used with connectionless protocols (e.g., UDP) to send data
|
||||
* to a specific destination address, as specified by 'to'.
|
||||
*
|
||||
* @param s The file descriptor of the socket to send data on.
|
||||
* @param dataptr A pointer to the buffer containing the data to be sent.
|
||||
* @param size The size, in bytes, of the data to be sent from the buffer.
|
||||
* @param flags Specifies the behavior of the send operation. Common flags include:
|
||||
* - '0': Default operation.
|
||||
* - 'MSG_DONTWAIT': Non-blocking operation.
|
||||
* - 'MSG_NOSIGNAL': Prevents the sending of 'SIGPIPE' on errors.
|
||||
* @param to A pointer to a 'sockaddr' structure that specifies the destination address.
|
||||
* The structure type (e.g., 'sockaddr_in' for IPv4) depends on the address family.
|
||||
* @param tolen The length, in bytes, of the address structure pointed to by 'to'.
|
||||
*
|
||||
* @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note Unlike 'send()', 'sendto()' can specify a target address for each message, allowing it to be used
|
||||
* for both connected and unconnected sockets. In connectionless protocols, 'sendto()' is commonly
|
||||
* used without prior calls to 'connect()'.
|
||||
*
|
||||
* @see socket() Creates the socket used for sending data.
|
||||
* @see recvfrom() Receives data from a specific address, typically used with connectionless sockets.
|
||||
* @see connect() Optional for connection-oriented protocols.
|
||||
* @see send() Sends data on a connected socket.
|
||||
*/
|
||||
int sendto(int s, const void *dataptr, size_t size, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
@@ -210,6 +596,38 @@ int sendto(int s, const void *dataptr, size_t size, int flags,
|
||||
}
|
||||
RTM_EXPORT(sendto);
|
||||
|
||||
/**
|
||||
* @brief Creates a network socket.
|
||||
*
|
||||
* This function creates a socket and returns a file descriptor that can be used for network communication.
|
||||
*
|
||||
* @param domain The communication protocol family (address family) that defines the socket's protocol.
|
||||
* Common values include:
|
||||
* - 'AF_INET': IPv4
|
||||
* - 'AF_INET6': IPv6
|
||||
* - 'AF_UNIX': Local communication (inter-process communication on the same machine)
|
||||
* - 'AF_AT': AT socket
|
||||
* - 'AF_WIZ': WIZnet
|
||||
* @param type The type of socket, which determines the characteristics of data transmission.
|
||||
* Common values include:
|
||||
* - 'SOCK_STREAM': Connection-oriented byte stream communication (e.g., TCP)
|
||||
* - 'SOCK_DGRAM': Connectionless datagram communication (e.g., UDP)
|
||||
* - 'SOCK_RAW': Provides raw network protocol access
|
||||
* @param protocol Specifies the protocol to be used with the socket. It is usually set to '0',
|
||||
* which allows the system to choose the default protocol:
|
||||
* - For 'SOCK_STREAM', the default is TCP.
|
||||
* - For 'SOCK_DGRAM', the default is UDP.
|
||||
*
|
||||
* @return On success, returns a file descriptor (a non-negative integer) representing the socket.
|
||||
* On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note The created socket can be used for binding, listening, receiving, and sending data.
|
||||
*
|
||||
* @see bind() Used to bind the socket to a local address.
|
||||
* @see listen() Used to set the socket to listen for incoming connections.
|
||||
* @see accept() Used to accept incoming connection requests.
|
||||
* @see connect() Used to connect to a remote host.
|
||||
*/
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
/* create a BSD socket */
|
||||
@@ -262,6 +680,25 @@ int socket(int domain, int type, int protocol)
|
||||
}
|
||||
RTM_EXPORT(socket);
|
||||
|
||||
/**
|
||||
* @brief Closes a socket.
|
||||
*
|
||||
* This function closes the socket specified by the file descriptor 's'. Once closed, the socket
|
||||
* can no longer be used for communication. Any pending data that has not been transmitted may be lost.
|
||||
*
|
||||
* @param s The file descriptor of the socket to close.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error.
|
||||
*
|
||||
* @note After calling 'closesocket()', the socket descriptor becomes invalid. The socket cannot
|
||||
* be used for further communication or operations. It is important to close sockets when they are no longer needed
|
||||
* to release system resources.
|
||||
*
|
||||
* @see socket() Creates a socket.
|
||||
* @see shutdown() Shuts down the socket for reading and/or writing, without closing it.
|
||||
* @see recv() Receives data from a socket.
|
||||
* @see send() Sends data on a socket.
|
||||
*/
|
||||
int closesocket(int s)
|
||||
{
|
||||
int error = 0;
|
||||
@@ -305,7 +742,32 @@ int closesocket(int s)
|
||||
}
|
||||
RTM_EXPORT(closesocket);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates a pair of connected sockets.
|
||||
*
|
||||
* The 'socketpair()' function creates two connected sockets, which can be used for bidirectional
|
||||
* communication between processes or threads on the same machine. This is commonly used for inter-process
|
||||
* communication (IPC) in UNIX-like operating systems.
|
||||
*
|
||||
* @param domain The communication domain (or protocol family). Typically, 'AF_UNIX' (or 'AF_LOCAL')
|
||||
* is used to create sockets for local communication.
|
||||
* @param type The type of socket to be created. Common values include:
|
||||
* - 'SOCK_STREAM': Provides reliable, connection-oriented communication.
|
||||
* - 'SOCK_DGRAM': Provides connectionless, unreliable communication.
|
||||
* @param protocol The protocol to be used with the sockets. Normally set to '0' to use the default protocol
|
||||
* for the specified 'domain' and 'type'.
|
||||
* @param fds An array of two integers where the file descriptors for the two connected sockets will be stored.
|
||||
* After a successful call, 'fds[0]' and 'fds[1]' represent the two ends of the socket pair.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets 'errno' to indicate the error.
|
||||
*
|
||||
* @note The 'socketpair()' function is commonly used to create a communication channel between two processes
|
||||
* (parent and child after 'fork()') or two threads. Data written to one socket is available for reading
|
||||
* from the other. It is primarily supported on UNIX-like systems and may not be available on Windows.
|
||||
*
|
||||
* @see socket() Creates a single socket for network communication.
|
||||
* @see pipe() Creates an unidirectional communication channel between processes.
|
||||
*/
|
||||
int socketpair(int domain, int type, int protocol, int *fds)
|
||||
{
|
||||
rt_err_t ret = 0;
|
||||
@@ -342,6 +804,32 @@ int socketpair(int domain, int type, int protocol, int *fds)
|
||||
}
|
||||
RTM_EXPORT(socketpair);
|
||||
|
||||
/**
|
||||
* @brief Controls socket I/O modes.
|
||||
*
|
||||
* The 'ioctlsocket()' function manipulates the I/O mode of the socket specified by the file descriptor 's'.
|
||||
* It is primarily used to enable or disable non-blocking mode on a socket or to perform other socket-specific
|
||||
* operations.
|
||||
*
|
||||
* @param s The file descriptor of the socket to control.
|
||||
* @param cmd The command that specifies the operation to perform. Some common commands include:
|
||||
* - 'FIONBIO': Enables or disables non-blocking mode. Setting 'arg' to a non-zero value
|
||||
* enables non-blocking mode; setting it to zero disables it.
|
||||
* - 'FIONREAD': Retrieves the number of bytes available to read, storing the result in 'arg'.
|
||||
* @param arg A pointer to an argument for the command. The type and meaning of this argument depend on the
|
||||
* specified command ('cmd'). For example, in non-blocking mode ('FIONBIO'), it points to a 'long'
|
||||
* that is either non-zero (to enable) or zero (to disable) non-blocking mode.
|
||||
*
|
||||
* @return Returns '0' on success. On failure, returns '-1' and sets errno (or 'WSAGetLastError()' on Windows) to indicate the error.
|
||||
*
|
||||
* @note This function is specific to Windows environments and is a part of the Winsock API. It performs
|
||||
* similar functionality to the 'fcntl()' function on UNIX-like systems.
|
||||
* The 'ioctlsocket()' function allows for various socket manipulations that affect how the socket
|
||||
* operates in certain conditions, such as setting it to non-blocking mode.
|
||||
*
|
||||
* @see socket() Creates a socket to use with 'ioctlsocket()'.
|
||||
* @see fcntl() Performs similar operations on UNIX-like systems.
|
||||
*/
|
||||
int ioctlsocket(int s, long cmd, void *arg)
|
||||
{
|
||||
int socket = dfs_net_getsocket(s);
|
||||
|
@@ -444,11 +444,6 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r
|
||||
struct netdev *netdev = RT_NULL;
|
||||
rt_bool_t flag = RT_FALSE;
|
||||
|
||||
if (family == AF_UNIX)
|
||||
{
|
||||
netdv_def = netdev_lo;
|
||||
}
|
||||
|
||||
if (family < 0 || family > AF_MAX)
|
||||
{
|
||||
return -1;
|
||||
@@ -684,7 +679,8 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
|
||||
|
||||
addr_un = (struct sockaddr_un *)name;
|
||||
|
||||
if ((addr_un->sa_family != AF_UNIX) && (addr_un->sa_family != AF_NETLINK))
|
||||
#define IS_INET_ADDR_FAMILY(_af) ((_af) == AF_INET) || ((_af) == AF_INET6)
|
||||
if (IS_INET_ADDR_FAMILY(name->sa_family))
|
||||
{
|
||||
/* bind network interface by ip address */
|
||||
sal_sockaddr_to_ipaddr(name, &input_ipaddr);
|
||||
@@ -910,11 +906,11 @@ int sal_sendmsg(int socket, const struct msghdr *message, int flags)
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, sendmsg);
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, sendmsg))
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send))
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = proto_tls->ops->sendmsg(sock->user_data_tls, message, flags)) < 0)
|
||||
if ((ret = proto_tls->ops->send(sock->user_data_tls, message, flags)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -943,11 +939,11 @@ int sal_recvmsg(int socket, struct msghdr *message, int flags)
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, recvmsg);
|
||||
|
||||
#ifdef SAL_USING_TLS
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recvmsg))
|
||||
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv))
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = proto_tls->ops->recvmsg(sock->user_data_tls, message, flags)) < 0)
|
||||
if ((ret = proto_tls->ops->recv(sock->user_data_tls, message, flags)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -1171,12 +1167,9 @@ int sal_ioctlsocket(int socket, long cmd, void *arg)
|
||||
/* get the socket object by socket descriptor */
|
||||
SAL_SOCKET_OBJ_GET(sock, socket);
|
||||
|
||||
/* check the network interface socket opreation */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, ioctlsocket);
|
||||
|
||||
struct sal_ifreq *ifr = (struct sal_ifreq *)arg;
|
||||
|
||||
if((sock->domain == AF_INET)&&(sock->netdev)&&(ifr != RT_NULL))
|
||||
if (ifr != RT_NULL)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
@@ -1474,10 +1467,24 @@ int sal_ioctlsocket(int socket, long cmd, void *arg)
|
||||
ifconf_tmp->ifc_ifcu.ifcu_buf = ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size;
|
||||
return 0;
|
||||
}
|
||||
case SIOCGIFINDEX:
|
||||
{
|
||||
netdev = netdev_get_by_name(ifr->ifr_ifrn.ifrn_name);
|
||||
if (netdev)
|
||||
{
|
||||
ifr->ifr_ifru.ifru_ivalue = netdev->ifindex;
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check the network interface socket opreation */
|
||||
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, ioctlsocket);
|
||||
|
||||
return pf->skt_ops->ioctlsocket((int)(size_t)sock->user_data, cmd, arg);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user