diff --git a/Documentation/applications/netutils/netlib/index.rst b/Documentation/applications/netutils/netlib/index.rst index 6099b31da45d7..ee12c5b6fbfb4 100644 --- a/Documentation/applications/netutils/netlib/index.rst +++ b/Documentation/applications/netutils/netlib/index.rst @@ -1,3 +1,653 @@ ================================== ``netlib`` Network support library ================================== + +The ``netlib`` library provides a collection of network utility functions +for managing network interfaces, IP addresses, routing tables, and other +network-related operations. These functions are defined in +``netutils/netlib.h`` and are intended for internal use by NuttX applications. + +Device Management +================== + + - :c:func:`netlib_get_devices` + +.. c:function:: ssize_t netlib_get_devices(struct netlib_device_s *devlist, unsigned int nentries, sa_family_t family) + + Get a list of all network devices. + + :param devlist: Pointer to an array of ``netlib_device_s`` structures to + receive the device list. + :param nentries: Maximum number of entries in the array. + :param family: Address family filter (``AF_INET``, ``AF_INET6``, or + ``AF_UNSPEC`` for all). + + :return: Number of devices returned on success; -1 on error with ``errno`` + set appropriately. + +Address Conversion Functions +============================= + + - :c:func:`netlib_ipv4addrconv` + - :c:func:`netlib_ethaddrconv` + +.. c:function:: bool netlib_ipv4addrconv(const char *addrstr, uint8_t *addr) + + Convert a textual representation of an IPv4 address to a numerical + representation. This function takes an IP address in the form ``a.b.c.d`` + and converts it into a 4-byte array. + + :param addrstr: A pointer to a string containing the IP address in textual form. + :param addr: A pointer to a 4-byte array that will be filled with the + numerical representation of the address. + + :return: ``true`` if the IP address was parsed successfully; ``false`` otherwise. + +.. c:function:: bool netlib_ethaddrconv(const char *hwstr, uint8_t *hw) + + Convert a textual representation of an Ethernet MAC address to a numerical + representation. + + :param hwstr: A pointer to a string containing the MAC address in textual form + (e.g., ``"00:11:22:33:44:55"``). + :param hw: A pointer to a byte array that will be filled with the numerical + representation of the MAC address. + + :return: ``true`` if the MAC address was parsed successfully; ``false`` otherwise. + +MAC Address Management +======================= + + - :c:func:`netlib_setmacaddr` + - :c:func:`netlib_getmacaddr` + +.. c:function:: int netlib_setmacaddr(const char *ifname, const uint8_t *macaddr) + + Set the MAC address for an Ethernet network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param macaddr: Pointer to a 6-byte array containing the MAC address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_getmacaddr(const char *ifname, uint8_t *macaddr) + + Get the MAC address of an Ethernet network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param macaddr: Pointer to a 6-byte array to receive the MAC address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +IPv4 Address Management +======================== + + - :c:func:`netlib_set_ipv4addr` + - :c:func:`netlib_get_ipv4addr` + - :c:func:`netlib_set_dripv4addr` + - :c:func:`netlib_get_dripv4addr` + - :c:func:`netlib_set_ipv4netmask` + - :c:func:`netlib_get_ipv4netmask` + - :c:func:`netlib_ipv4adaptor` + +.. c:function:: int netlib_set_ipv4addr(const char *ifname, const struct in_addr *addr) + + Set the IPv4 address for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in_addr`` structure containing the IPv4 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_get_ipv4addr(const char *ifname, struct in_addr *addr) + + Get the IPv4 address of a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in_addr`` structure to receive the IPv4 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_set_dripv4addr(const char *ifname, const struct in_addr *addr) + + Set the default router (gateway) IPv4 address for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in_addr`` structure containing the gateway address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_get_dripv4addr(const char *ifname, struct in_addr *addr) + + Get the default router (gateway) IPv4 address of a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in_addr`` structure to receive the gateway address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_set_ipv4netmask(const char *ifname, const struct in_addr *addr) + + Set the IPv4 netmask for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in_addr`` structure containing the netmask. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_get_ipv4netmask(const char *ifname, struct in_addr *addr) + + Get the IPv4 netmask of a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in_addr`` structure to receive the netmask. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_ipv4adaptor(in_addr_t destipaddr, in_addr_t *srcipaddr) + + Find the appropriate source IPv4 address to use for communicating with a + destination address. + + :param destipaddr: Destination IPv4 address (in network byte order). + :param srcipaddr: Pointer to receive the source IPv4 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +IPv6 Address Management +======================== + + - :c:func:`netlib_set_ipv6addr` + - :c:func:`netlib_get_ipv6addr` + - :c:func:`netlib_add_ipv6addr` + - :c:func:`netlib_del_ipv6addr` + - :c:func:`netlib_set_dripv6addr` + - :c:func:`netlib_set_ipv6netmask` + - :c:func:`netlib_ipv6adaptor` + - :c:func:`netlib_ipv6netmask2prefix` + - :c:func:`netlib_prefix2ipv6netmask` + +.. c:function:: int netlib_set_ipv6addr(const char *ifname, const struct in6_addr *addr) + + Set the IPv6 address for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). Can include slot + number for multiple addresses (e.g., ``"eth0:0"``). + :param addr: Pointer to an ``in6_addr`` structure containing the IPv6 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_get_ipv6addr(const char *ifname, struct in6_addr *addr) + + Get the IPv6 address of a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). Can include slot + number for multiple addresses (e.g., ``"eth0:0"``). + :param addr: Pointer to an ``in6_addr`` structure to receive the IPv6 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_add_ipv6addr(const char *ifname, const struct in6_addr *addr, uint8_t preflen) + + Add an IPv6 address to a network interface. This function is recommended for + managing multiple IPv6 addresses on a single interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in6_addr`` structure containing the IPv6 address. + :param preflen: Prefix length (0-128). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_del_ipv6addr(const char *ifname, const struct in6_addr *addr, uint8_t preflen) + + Remove an IPv6 address from a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in6_addr`` structure containing the IPv6 address + to remove. + :param preflen: Prefix length (0-128). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_set_dripv6addr(const char *ifname, const struct in6_addr *addr) + + Set the default router (gateway) IPv6 address for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in6_addr`` structure containing the gateway address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_set_ipv6netmask(const char *ifname, const struct in6_addr *addr) + + Set the IPv6 netmask for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param addr: Pointer to an ``in6_addr`` structure containing the netmask. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_ipv6adaptor(const struct in6_addr *destipaddr, struct in6_addr *srcipaddr) + + Find the appropriate source IPv6 address to use for communicating with a + destination address. + + :param destipaddr: Pointer to the destination IPv6 address. + :param srcipaddr: Pointer to receive the source IPv6 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: uint8_t netlib_ipv6netmask2prefix(const uint16_t *mask) + + Convert an IPv6 netmask to a prefix length. + + :param mask: Pointer to a 16-bit array representing the netmask. + + :return: Prefix length (0-128). + +.. c:function:: void netlib_prefix2ipv6netmask(uint8_t preflen, struct in6_addr *netmask) + + Convert a prefix length to an IPv6 netmask. + + :param preflen: Prefix length (0-128). + :param netmask: Pointer to an ``in6_addr`` structure to receive the netmask. + +Network Interface Management +============================= + + - :c:func:`netlib_getifstatus` + - :c:func:`netlib_ifup` + - :c:func:`netlib_ifdown` + - :c:func:`netlib_set_mtu` + +.. c:function:: int netlib_getifstatus(const char *ifname, uint8_t *flags) + + Get the status flags of a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param flags: Pointer to receive the interface flags. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_ifup(const char *ifname) + + Bring a network interface up (activate it). + + :param ifname: Network interface name (e.g., ``"eth0"``). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_ifdown(const char *ifname) + + Bring a network interface down (deactivate it). + + :param ifname: Network interface name (e.g., ``"eth0"``). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_set_mtu(const char *ifname, int mtu) + + Set the Maximum Transmission Unit (MTU) for a network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + :param mtu: MTU value in bytes. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +ARP Table Support +================== + + - :c:func:`netlib_set_arpmapping` + - :c:func:`netlib_get_arpmapping` + - :c:func:`netlib_del_arpmapping` + - :c:func:`netlib_get_arptable` + +.. c:function:: int netlib_set_arpmapping(const struct sockaddr_in *inaddr, const uint8_t *macaddr, const char *ifname) + + Add or update an ARP table entry mapping an IPv4 address to a MAC address. + + :param inaddr: Pointer to a ``sockaddr_in`` structure containing the IPv4 address. + :param macaddr: Pointer to a 6-byte array containing the MAC address. + :param ifname: Network interface name (e.g., ``"eth0"``), or NULL for any interface. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_get_arpmapping(const struct sockaddr_in *inaddr, uint8_t *macaddr, const char *ifname) + + Retrieve the MAC address associated with an IPv4 address from the ARP table. + + :param inaddr: Pointer to a ``sockaddr_in`` structure containing the IPv4 address. + :param macaddr: Pointer to a 6-byte array to receive the MAC address. + :param ifname: Network interface name (e.g., ``"eth0"``), or NULL for any interface. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_del_arpmapping(const struct sockaddr_in *inaddr, const char *ifname) + + Delete an entry from the ARP table. + + :param inaddr: Pointer to a ``sockaddr_in`` structure containing the IPv4 address. + :param ifname: Network interface name (e.g., ``"eth0"``), or NULL for any interface. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: ssize_t netlib_get_arptable(struct arpreq *arptab, unsigned int nentries) + + Retrieve the entire ARP table. + + :param arptab: Pointer to an array of ``arpreq`` structures to receive the + ARP table entries. + :param nentries: Maximum number of entries in the array. + + :return: Number of entries returned on success; -1 on error with ``errno`` + set appropriately. + +Routing Table Support +====================== + + - :c:func:`netlib_ipv4router` + - :c:func:`netlib_ipv6router` + - :c:func:`netlib_open_ipv4route` + - :c:func:`netlib_close_ipv4route` + - :c:func:`netlib_read_ipv4route` + - :c:func:`netlib_open_ipv6route` + - :c:func:`netlib_close_ipv6route` + - :c:func:`netlib_read_ipv6route` + - :c:func:`netlib_get_route` + +.. c:function:: int netlib_ipv4router(const struct in_addr *destipaddr, struct in_addr *router) + + Find the router (gateway) address to use for reaching a destination IPv4 address. + + :param destipaddr: Pointer to the destination IPv4 address. + :param router: Pointer to receive the router IPv4 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_ipv6router(const struct in6_addr *destipaddr, struct in6_addr *router) + + Find the router (gateway) address to use for reaching a destination IPv6 address. + + :param destipaddr: Pointer to the destination IPv6 address. + :param router: Pointer to receive the router IPv6 address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: FILE *netlib_open_ipv4route(void) + + Open the IPv4 routing table for reading. This is a macro that opens + ``/proc/net/route/ipv4``. + + :return: File pointer on success; NULL on error. + +.. c:function:: void netlib_close_ipv4route(FILE *stream) + + Close the IPv4 routing table file. This is a macro that calls ``fclose()``. + + :param stream: File pointer returned by ``netlib_open_ipv4route()``. + +.. c:function:: ssize_t netlib_read_ipv4route(FILE *stream, struct netlib_ipv4_route_s *route) + + Read one entry from the IPv4 routing table. + + :param stream: File pointer returned by ``netlib_open_ipv4route()``. + :param route: Pointer to a ``netlib_ipv4_route_s`` structure to receive the + route entry. + + :return: 1 on success; 0 on end of file; -1 on error. + +.. c:function:: FILE *netlib_open_ipv6route(void) + + Open the IPv6 routing table for reading. This is a macro that opens + ``/proc/net/route/ipv6``. + + :return: File pointer on success; NULL on error. + +.. c:function:: void netlib_close_ipv6route(FILE *stream) + + Close the IPv6 routing table file. This is a macro that calls ``fclose()``. + + :param stream: File pointer returned by ``netlib_open_ipv6route()``. + +.. c:function:: ssize_t netlib_read_ipv6route(FILE *stream, struct netlib_ipv6_route_s *route) + + Read one entry from the IPv6 routing table. + + :param stream: File pointer returned by ``netlib_open_ipv6route()``. + :param route: Pointer to a ``netlib_ipv6_route_s`` structure to receive the + route entry. + + :return: 1 on success; 0 on end of file; -1 on error. + +.. c:function:: ssize_t netlib_get_route(struct rtentry *rtelist, unsigned int nentries, sa_family_t family) + + Retrieve routing table entries using Netlink. + + :param rtelist: Pointer to an array of ``rtentry`` structures to receive the + routing entries. + :param nentries: Maximum number of entries in the array. + :param family: Address family filter (``AF_INET``, ``AF_INET6``, or + ``AF_UNSPEC`` for all). + + :return: Number of entries returned on success; -1 on error with ``errno`` + set appropriately. + +DHCP Support +============= + + - :c:func:`netlib_obtain_ipv4addr` + - :c:func:`netlib_icmpv6_autoconfiguration` + - :c:func:`netlib_obtain_ipv6addr` + +.. c:function:: int netlib_obtain_ipv4addr(const char *ifname) + + Obtain an IPv4 address via DHCP for the specified network interface. This + function blocks until an address is obtained or an error occurs. + + :param ifname: Network interface name (e.g., ``"eth0"``). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_icmpv6_autoconfiguration(const char *ifname) + + Perform IPv6 stateless address autoconfiguration (SLAAC) for the specified + network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_obtain_ipv6addr(const char *ifname) + + Obtain an IPv6 address via DHCPv6 for the specified network interface. + + :param ifname: Network interface name (e.g., ``"eth0"``). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +DNS Server Address Management +=============================== + + - :c:func:`netlib_set_ipv4dnsaddr` + - :c:func:`netlib_del_ipv4dnsaddr` + - :c:func:`netlib_del_ipv4dnsaddr_by_index` + - :c:func:`netlib_set_ipv6dnsaddr` + - :c:func:`netlib_del_ipv6dnsaddr` + - :c:func:`netlib_del_ipv6dnsaddr_by_index` + +.. c:function:: int netlib_set_ipv4dnsaddr(const struct in_addr *inaddr) + + Add an IPv4 DNS server address to the resolver configuration. + + :param inaddr: Pointer to an ``in_addr`` structure containing the DNS server + address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_del_ipv4dnsaddr(const struct in_addr *inaddr) + + Remove an IPv4 DNS server address from the resolver configuration. + + :param inaddr: Pointer to an ``in_addr`` structure containing the DNS server + address to remove. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_del_ipv4dnsaddr_by_index(int index) + + Remove an IPv4 DNS server from the resolver configuration by index. + + :param index: Index of the DNS server to remove (0-based). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_set_ipv6dnsaddr(const struct in6_addr *inaddr) + + Add an IPv6 DNS server address to the resolver configuration. + + :param inaddr: Pointer to an ``in6_addr`` structure containing the DNS server + address. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_del_ipv6dnsaddr(const struct in6_addr *inaddr) + + Remove an IPv6 DNS server address from the resolver configuration. + + :param inaddr: Pointer to an ``in6_addr`` structure containing the DNS server + address to remove. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_del_ipv6dnsaddr_by_index(int index) + + Remove an IPv6 DNS server from the resolver configuration by index. + + :param index: Index of the DNS server to remove (0-based). + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +Wireless Configuration +======================= + + - :c:func:`netlib_getessid` + - :c:func:`netlib_setessid` + +.. c:function:: int netlib_getessid(const char *ifname, char *essid, size_t idlen) + + Get the ESSID (network name) of a wireless network interface. + + :param ifname: Wireless network interface name (e.g., ``"wlan0"``). + :param essid: Buffer to receive the ESSID string. + :param idlen: Size of the buffer. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_setessid(const char *ifname, const char *essid) + + Set the ESSID (network name) for a wireless network interface. + + :param ifname: Wireless network interface name (e.g., ``"wlan0"``). + :param essid: ESSID string to set. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +URL Parsing +============ + + - :c:func:`netlib_parsehttpurl` + - :c:func:`netlib_parseurl` + +.. c:function:: int netlib_parsehttpurl(const char *url, uint16_t *port, char *hostname, int hostlen, char *filename, int namelen) + + Parse an HTTP URL into its components. + + :param url: URL string to parse (e.g., ``"http://example.com:8080/path/file"``). + :param port: Pointer to receive the port number (default 80 if not specified). + :param hostname: Buffer to receive the hostname. + :param hostlen: Size of the hostname buffer. + :param filename: Buffer to receive the path/filename. + :param namelen: Size of the filename buffer. + + :return: 0 on success; -1 on error. + +.. c:function:: int netlib_parseurl(const char *str, struct url_s *url) + + Parse a generic URL into its components. This function handles various URL + schemes beyond HTTP. + + :param str: URL string to parse. + :param url: Pointer to a ``url_s`` structure to receive the parsed components. + + :return: 0 on success; -1 on error. + +Server Support +=============== + + - :c:func:`netlib_listenon` + - :c:func:`netlib_server` + +.. c:function:: int netlib_listenon(uint16_t portno) + + Create a TCP socket and listen on the specified port. This is a convenience + function for setting up a server socket. + + :param portno: Port number to listen on. + + :return: Socket descriptor on success; -1 on error with ``errno`` set + appropriately. + +.. c:function:: void netlib_server(uint16_t portno, pthread_startroutine_t handler, int stacksize) + + Create a simple server that listens on the specified port and spawns a new + thread for each connection using the provided handler function. + + :param portno: Port number to listen on. + :param handler: Function to call for each new connection. The handler receives + the client socket descriptor as an argument. + :param stacksize: Stack size for handler threads. + +Neighbor Table (IPv6) +====================== + + - :c:func:`netlib_get_nbtable` + +.. c:function:: ssize_t netlib_get_nbtable(struct neighbor_entry_s *nbtab, unsigned int nentries) + + Retrieve the IPv6 neighbor table (similar to ARP for IPv4). + + :param nbtab: Pointer to an array of ``neighbor_entry_s`` structures to + receive the neighbor table entries. + :param nentries: Maximum number of entries in the array. + + :return: Number of entries returned on success; -1 on error with ``errno`` + set appropriately. + +Connection Tracking (Netfilter) +================================= + + - :c:func:`netlib_get_conntrack` + - :c:func:`netlib_parse_conntrack` + +.. c:function:: int netlib_get_conntrack(sa_family_t family, netlib_conntrack_cb_t cb) + + Retrieve connection tracking entries from the kernel's connection tracking + table. + + :param family: Address family filter (``AF_INET``, ``AF_INET6``, or + ``AF_UNSPEC`` for all). + :param cb: Callback function to invoke for each connection. The callback + receives a pointer to a ``netlib_conntrack_s`` structure. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + +.. c:function:: int netlib_parse_conntrack(const struct nlmsghdr *nlh, size_t len, struct netlib_conntrack_s *ct) + + Parse a Netlink message containing connection tracking information. + + :param nlh: Pointer to the Netlink message header. + :param len: Length of the message. + :param ct: Pointer to a ``netlib_conntrack_s`` structure to receive the + parsed connection information. + + :return: 0 on success; -1 on error. diff --git a/Documentation/reference/user/11_network.rst b/Documentation/reference/user/11_network.rst index a7d3ac47dca43..1d25ff39504db 100644 --- a/Documentation/reference/user/11_network.rst +++ b/Documentation/reference/user/11_network.rst @@ -413,3 +413,114 @@ the following paragraphs. - ``NOBUFS``. Insufficient resources are available in the system to complete the call. +============= +DNS Functions +============= + +NuttX provides DNS resolver functions for configuring and managing DNS +servers. These functions are defined in ``nuttx/net/dns.h`` and allow +applications to add, remove, and query DNS nameservers. + + - :c:func:`dns_add_nameserver` + - :c:func:`dns_del_nameserver` + - :c:func:`dns_del_nameserver_by_index` + - :c:func:`dns_default_nameserver` + - :c:func:`dns_foreach_nameserver` + - :c:func:`dns_register_notify` + - :c:func:`dns_unregister_notify` + - :c:func:`dns_set_queryfamily` + +.. c:function:: int dns_add_nameserver(const struct sockaddr *addr, socklen_t addrlen); + + Configure a DNS server to use for queries. Set the port number to zero + to use the default DNS server port (53). + + :param addr: Address of the DNS server (sockaddr_in or sockaddr_in6). + :param addrlen: Length of the address structure. + + :return: 0 on success; -1 on error with ``errno`` set appropriately: + + - ``EINVAL``. Invalid argument. + - ``ENOMEM``. Insufficient memory to add the new DNS server. + +.. c:function:: int dns_del_nameserver(const struct sockaddr *addr, socklen_t addrlen); + + Remove a DNS server from the list by address. + + :param addr: Address of the DNS server to remove. + :param addrlen: Length of the address structure. + + :return: 0 on success; -1 on error with ``errno`` set appropriately: + + - ``EINVAL``. Invalid argument. + - ``ENOENT``. The specified DNS server was not found. + +.. c:function:: int dns_del_nameserver_by_index(int index); + + Remove a DNS server from the list by index (0-based). + + :param index: Index of the DNS server in the list (0-based). + + :return: 0 on success; -1 on error with ``errno`` set appropriately: + + - ``EINVAL``. Invalid index. + +.. c:function:: int dns_default_nameserver(void); + + Reset the resolver to use only the default DNS server, if any. This function + clears all added DNS servers and restores the default configuration. + + :return: 0 on success; -1 on error. + +.. c:function:: int dns_foreach_nameserver(dns_callback_t callback, void *arg); + + Traverse each nameserver entry and perform the provided callback. + + :param callback: Callback function to invoke for each DNS server. The callback + prototype is: ``int (*callback)(void *arg, struct sockaddr *addr, socklen_t addrlen)`` + :param arg: User argument to pass to the callback function. + + :return: 0 on success; -1 on error with ``errno`` set appropriately. + If the callback returns a non-zero value, traversal stops and that value is returned. + + - ``EINVAL``. Callback function pointer is NULL. + +.. c:function:: int dns_register_notify(dns_callback_t callback, void *arg); + + Register a callback function to receive nameserver change notifications. When the + DNS server list changes (servers added or removed), registered callbacks will be invoked. + + :param callback: Callback function to invoke on nameserver changes. + :param arg: User argument to pass to the callback function. + + :return: 0 on success; -1 on error with ``errno`` set appropriately: + + - ``EINVAL``. Callback function pointer is NULL. + - ``ENOMEM``. Insufficient memory to register the notification. + +.. c:function:: int dns_unregister_notify(dns_callback_t callback, void *arg); + + Unsubscribe from nameserver change notifications. + + :param callback: Callback function to unregister. + :param arg: User argument provided during registration. + + :return: 0 on success; -1 on error with ``errno`` set appropriately: + + - ``EINVAL``. Callback function pointer is NULL. + - ``ENOENT``. The specified callback was not found. + +.. c:function:: int dns_set_queryfamily(sa_family_t family); + + Configure the address family to be used for queries. + + :param family: Address family, can be: + + - ``AF_INET``: Use IPv4 for DNS queries. + - ``AF_INET6``: Use IPv6 for DNS queries. + - ``AF_UNSPEC``: Automatic selection (prefer IPv6, fallback to IPv4). + + :return: 0 on success; -1 on error with ``errno`` set appropriately: + + - ``EINVAL``. Unsupported address family. + diff --git a/include/nuttx/net/dns.h b/include/nuttx/net/dns.h index a5267deedfb5a..08a842c8de659 100644 --- a/include/nuttx/net/dns.h +++ b/include/nuttx/net/dns.h @@ -2,7 +2,10 @@ * include/nuttx/net/dns.h * * SPDX-License-Identifier: BSD-3-Clause - * SPDX-FileCopyrightText: 2007-2009, 2011-2012, 2014-2015, 2018 Gregory Nutt. All rights reserved. + * SPDX-FileCopyrightText: 2018 Gregory Nutt. All rights reserved. + * SPDX-FileCopyrightText: 2014-2015 Gregory Nutt. All rights reserved. + * SPDX-FileCopyrightText: 2011-2012 Gregory Nutt. All rights reserved. + * SPDX-FileCopyrightText: 2007-2009 Gregory Nutt. All rights reserved. * SPDX-FileCopyrightText: 2002-2003, Adam Dunkels. All rights reserved. * SPDX-FileContributor: Gregory Nutt * SPDX-FileContributor: Adam Dunkels @@ -203,6 +206,26 @@ extern "C" int dns_add_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen); +/**************************************************************************** + * Name: dns_del_nameserver + * + * Description: + * Remove a DNS server from the list by address. + * + ****************************************************************************/ + +int dns_del_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen); + +/**************************************************************************** + * Name: dns_del_nameserver_by_index + * + * Description: + * Remove a DNS server from the list by index (0-based). + * + ****************************************************************************/ + +int dns_del_nameserver_by_index(int index); + /**************************************************************************** * Name: dns_default_nameserver * diff --git a/libs/libc/netdb/CMakeLists.txt b/libs/libc/netdb/CMakeLists.txt index f522c647a92b9..cf063f00797fb 100644 --- a/libs/libc/netdb/CMakeLists.txt +++ b/libs/libc/netdb/CMakeLists.txt @@ -59,7 +59,8 @@ if(CONFIG_LIBC_NETDB) if(CONFIG_NETDB_DNSCLIENT) list(APPEND SRCS lib_dnsinit.c lib_dnsbind.c lib_dnsquery.c) - list(APPEND SRCS lib_dnsaddserver.c lib_dnsdefaultserver.c) + list(APPEND SRCS lib_dnsaddserver.c lib_dnsdelserver.c + lib_dnsdefaultserver.c) list(APPEND SRCS lib_dnsforeach.c lib_dnsnotify.c) list(APPEND SRCS lib_dnsqueryfamily.c) diff --git a/libs/libc/netdb/Make.defs b/libs/libc/netdb/Make.defs index 39f7beef4cde1..95aac44cc73b1 100644 --- a/libs/libc/netdb/Make.defs +++ b/libs/libc/netdb/Make.defs @@ -44,7 +44,7 @@ endif ifeq ($(CONFIG_NETDB_DNSCLIENT),y) CSRCS += lib_dnsinit.c lib_dnsbind.c lib_dnsquery.c -CSRCS += lib_dnsaddserver.c lib_dnsdefaultserver.c +CSRCS += lib_dnsaddserver.c lib_dnsdelserver.c lib_dnsdefaultserver.c CSRCS += lib_dnsforeach.c lib_dnsnotify.c CSRCS += lib_dnsqueryfamily.c diff --git a/libs/libc/netdb/lib_dnsdelserver.c b/libs/libc/netdb/lib_dnsdelserver.c new file mode 100644 index 0000000000000..4da5f813d07e5 --- /dev/null +++ b/libs/libc/netdb/lib_dnsdelserver.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * libs/libc/netdb/lib_dnsdelserver.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "netdb/lib_dns.h" + +#ifdef CONFIG_NETDB_DNSCLIENT + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifndef CONFIG_NETDB_RESOLVCONF + +static int dns_find_nameserver_index(FAR const struct sockaddr *addr, + socklen_t addrlen) +{ + size_t cmplen = 0; + int i; + +#ifdef CONFIG_NET_IPv4 + if (addr->sa_family == AF_INET) + { + cmplen = sizeof(struct sockaddr_in); + } +#endif + +#ifdef CONFIG_NET_IPv6 + if (addr->sa_family == AF_INET6) + { + cmplen = sizeof(struct sockaddr_in6); + } +#endif + + if (cmplen == 0) + { + /* Unsupported address family */ + + return -ENOSYS; + } + + if (addrlen < cmplen) + { + return -EINVAL; + } + + dns_lock(); + + /* Search for the matching nameserver in the array */ + + for (i = 0; i < g_dns_nservers; i++) + { + if (g_dns_servers[i].addr.sa_family == addr->sa_family) + { +#ifdef CONFIG_NET_IPv4 + if (addr->sa_family == AF_INET) + { + FAR struct sockaddr_in *in1 = + (FAR struct sockaddr_in *)&g_dns_servers[i].addr; + FAR struct sockaddr_in *in2 = + (FAR struct sockaddr_in *)addr; + + /* Compare only the IP address part, ignore port and padding */ + + if (net_ipv4addr_cmp(in1->sin_addr.s_addr, + in2->sin_addr.s_addr)) + { + dns_unlock(); + return i; + } + } +#endif + +#ifdef CONFIG_NET_IPv6 + if (addr->sa_family == AF_INET6) + { + FAR struct sockaddr_in6 *in6_1 = + (FAR struct sockaddr_in6 *)&g_dns_servers[i].addr; + FAR struct sockaddr_in6 *in6_2 = + (FAR struct sockaddr_in6 *)addr; + + /* Compare only the IPv6 address part */ + + if (net_ipv6addr_cmp(in6_1->sin6_addr.s6_addr, + in6_2->sin6_addr.s6_addr)) + { + dns_unlock(); + return i; + } + } +#endif + } + } + + dns_unlock(); + return -ENOENT; +} + +#endif /* !CONFIG_NETDB_RESOLVCONF */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dns_del_nameserver + * + * Description: + * Remove a DNS server from the list by matching the address + * + ****************************************************************************/ + +#ifdef CONFIG_NETDB_RESOLVCONF + +int dns_del_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) +{ + /* Not implemented for CONFIG_NETDB_RESOLVCONF */ + + return -ENOSYS; +} + +int dns_del_nameserver_by_index(int index) +{ + /* For resolv.conf mode, removing requires rewriting the file */ + + return -ENOSYS; +} + +#else /* !CONFIG_NETDB_RESOLVCONF */ + +int dns_del_nameserver(FAR const struct sockaddr *addr, socklen_t addrlen) +{ + int index; + + if (addr == NULL) + { + return -EINVAL; + } + + /* Find the nameserver in the array */ + + index = dns_find_nameserver_index(addr, addrlen); + if (index < 0) + { + return index; /* Return the error code */ + } + + /* Remove the server by index */ + + return dns_del_nameserver_by_index(index); +} + +int dns_del_nameserver_by_index(int index) +{ + int i; + + if (index < 0 || index >= CONFIG_NETDB_DNSSERVER_NAMESERVERS) + { + return -EINVAL; + } + + dns_lock(); + + if (index >= g_dns_nservers) + { + dns_unlock(); + return -ENOENT; + } + + /* Shift all subsequent entries down by one position */ + + for (i = index; i < g_dns_nservers - 1; i++) + { + memcpy(&g_dns_servers[i], &g_dns_servers[i + 1], + sizeof(union dns_addr_u)); + } + + memset(&g_dns_servers[g_dns_nservers - 1], 0, sizeof(union dns_addr_u)); + + /* Decrement the server count */ + + g_dns_nservers--; + + dns_unlock(); + +#if CONFIG_NETDB_DNSCLIENT_ENTRIES > 0 + /* Clear the DNS cache after removing a server */ + + dns_clear_answer(); +#endif + + return OK; +} + +#endif /* CONFIG_NETDB_RESOLVCONF */ +#endif /* CONFIG_NETDB_DNSCLIENT */