support webnet and add netdev for XiUOS
This commit is contained in:
parent
ae80ddab49
commit
a9df546950
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := netdev.c netdev_ipaddr.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,834 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-03-18 ChenYong First version
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file netdev.c
|
||||
* @brief functions of get device address
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-15
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <transform.h>
|
||||
|
||||
#include "../include/netdev_ipaddr.h"
|
||||
#include "../include/netdev.h"
|
||||
|
||||
|
||||
#define DBG_TAG "netdev"
|
||||
#define DBG_LVL DBG_INFO
|
||||
|
||||
|
||||
/* The list of network interface device */
|
||||
struct netdev *netdev_list = NULL;
|
||||
/* The default network interface device */
|
||||
struct netdev *netdev_default = NULL;
|
||||
|
||||
/**
|
||||
* following four functions are basic operations on linked lists
|
||||
*/
|
||||
void netdev_slist_init(netdev_slist_t *l)
|
||||
{
|
||||
l->next = NULL;
|
||||
}
|
||||
|
||||
void netdev_slist_append(netdev_slist_t *l, netdev_slist_t *n)
|
||||
{
|
||||
struct netdev_slist_node *node;
|
||||
|
||||
node = l;
|
||||
while (node->next) node = node->next;
|
||||
|
||||
/* append the node to the tail */
|
||||
node->next = n;
|
||||
n->next = NULL;
|
||||
}
|
||||
netdev_slist_t *netdev_slist_next(netdev_slist_t *n)
|
||||
{
|
||||
return n->next;
|
||||
}
|
||||
|
||||
|
||||
netdev_slist_t *netdev_slist_remove(netdev_slist_t *l, netdev_slist_t *n)
|
||||
{
|
||||
/* remove slist head */
|
||||
struct netdev_slist_node *node = l;
|
||||
while (node->next && node->next != n) node = node->next;
|
||||
|
||||
/* remove node */
|
||||
if (node->next != (netdev_slist_t *)0) node->next = node->next->next;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function will register network interface device and
|
||||
* add it to network interface device list.
|
||||
*
|
||||
* @param netdev the network interface device object
|
||||
* @param name the network interface device name
|
||||
* @param user_data user-specific data
|
||||
*
|
||||
* @return 0: registered successfully
|
||||
* -1: registered failed
|
||||
*/
|
||||
|
||||
int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
||||
{
|
||||
long level;
|
||||
uint16_t flags_mask;
|
||||
uint16_t index;
|
||||
|
||||
assert(netdev);
|
||||
assert(name);
|
||||
|
||||
/* clean network interface device */
|
||||
flags_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP;
|
||||
netdev->flags &= ~flags_mask;
|
||||
|
||||
ip_addr_set_zero(&(netdev->ip_addr));
|
||||
ip_addr_set_zero(&(netdev->netmask));
|
||||
ip_addr_set_zero(&(netdev->gw));
|
||||
|
||||
IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
|
||||
IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4);
|
||||
IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4);
|
||||
#if NETDEV_IPV6
|
||||
for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++)
|
||||
{
|
||||
ip_addr_set_zero(&(netdev->ip6_addr[index]));
|
||||
IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V6);
|
||||
}
|
||||
#endif /* NETDEV_IPV6 */
|
||||
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
|
||||
{
|
||||
ip_addr_set_zero(&(netdev->dns_servers[index]));
|
||||
IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
|
||||
}
|
||||
netdev->status_callback = NULL;
|
||||
netdev->addr_callback = NULL;
|
||||
|
||||
if(strlen(name) > NETDEV_NAME_MAX)
|
||||
{
|
||||
char netdev_name[NETDEV_NAME_MAX + 1] = {0};
|
||||
|
||||
strncpy(netdev_name, name, NETDEV_NAME_MAX);
|
||||
printf("netdev name[%s] length is so long that have been cut into [%s].", name, netdev_name);
|
||||
}
|
||||
|
||||
/* fill network interface device */
|
||||
strncpy(netdev->name, name, NETDEV_NAME_MAX);
|
||||
netdev->user_data = user_data;
|
||||
|
||||
/* initialize current network interface device single list */
|
||||
|
||||
|
||||
|
||||
|
||||
netdev_slist_init(&(netdev->list));
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
if (netdev_list == NULL)
|
||||
{
|
||||
netdev_list = netdev;
|
||||
netdev_default = netdev;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* tail insertion */
|
||||
netdev_slist_append(&(netdev_list->list), &(netdev->list));
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will unregister network interface device and
|
||||
* delete it from network interface device list.
|
||||
*
|
||||
* @param netdev the network interface device object
|
||||
*
|
||||
* @return 0: unregistered successfully
|
||||
* -1: unregistered failed
|
||||
*/
|
||||
int netdev_unregister(struct netdev *netdev)
|
||||
{
|
||||
long level;
|
||||
netdev_slist_t *node = NULL;
|
||||
struct netdev *cur_netdev = NULL;
|
||||
|
||||
assert(netdev);
|
||||
|
||||
if (netdev_list == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||
{
|
||||
cur_netdev = netdev_slist_entry(node, struct netdev, list);
|
||||
if (cur_netdev == netdev)
|
||||
{
|
||||
/* find this network interface device in network interface device list */
|
||||
if (netdev_list == netdev && netdev_slist_next(&netdev_list->list) == NULL)
|
||||
{
|
||||
netdev_list = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev_slist_remove(&(netdev_list->list), &(cur_netdev->list));
|
||||
}
|
||||
if (netdev_default == netdev)
|
||||
{
|
||||
netdev_default = netdev_list;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
if (cur_netdev == netdev)
|
||||
{
|
||||
|
||||
memset(netdev, 0, sizeof(*netdev));
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the first network interface device
|
||||
* with the flags in network interface device list.
|
||||
*
|
||||
* @param flags the network interface device flags
|
||||
*
|
||||
* @return != NULL: network interface device object
|
||||
* NULL: get failed
|
||||
*/
|
||||
struct netdev *netdev_get_first_by_flags(uint16_t flags)
|
||||
{
|
||||
long level;
|
||||
netdev_slist_t *node = NULL;
|
||||
struct netdev *netdev = NULL;
|
||||
|
||||
if (netdev_list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||
{
|
||||
netdev = netdev_slist_entry(node, struct netdev, list);
|
||||
if (netdev && (netdev->flags & flags) != 0)
|
||||
{
|
||||
CriticalAreaUnLock(level);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the first network interface device
|
||||
* in network interface device list by IP address.
|
||||
*
|
||||
* @param addr the network interface device IP address
|
||||
*
|
||||
* @return != NULL: network interface device object
|
||||
* NULL: get failed
|
||||
*/
|
||||
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
|
||||
{
|
||||
long level;
|
||||
netdev_slist_t *node = NULL;
|
||||
struct netdev *netdev = NULL;
|
||||
|
||||
if (netdev_list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||
{
|
||||
netdev = netdev_slist_entry(node, struct netdev, list);
|
||||
if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr))
|
||||
{
|
||||
CriticalAreaUnLock(level);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get network interface device
|
||||
* in network interface device list by netdev name.
|
||||
*
|
||||
* @param name the network interface device name
|
||||
*
|
||||
* @return != NULL: network interface device object
|
||||
* NULL: get failed
|
||||
*/
|
||||
struct netdev *netdev_get_by_name(const char *name)
|
||||
{
|
||||
long level;
|
||||
netdev_slist_t *node = NULL;
|
||||
struct netdev *netdev = NULL;
|
||||
|
||||
if (netdev_list == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
level = CriticalAreaLock();
|
||||
|
||||
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||
{
|
||||
netdev = netdev_slist_entry(node, struct netdev, list);
|
||||
if (netdev && (strncmp(netdev->name, name, strlen(netdev->name) < NETDEV_NAME_MAX ? strlen(netdev->name) : NETDEV_NAME_MAX) == 0))
|
||||
{
|
||||
CriticalAreaUnLock(level);
|
||||
return netdev;
|
||||
}
|
||||
}
|
||||
|
||||
CriticalAreaUnLock(level);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set default network interface device.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
*/
|
||||
void netdev_set_default(struct netdev *netdev)
|
||||
{
|
||||
if (netdev)
|
||||
{
|
||||
netdev_default = netdev;
|
||||
|
||||
if (netdev->ops->set_default)
|
||||
{
|
||||
/* set default network interface device in the current network stack */
|
||||
netdev->ops->set_default(netdev);
|
||||
}
|
||||
printf("Setting default network interface device name(%s) successfully.", netdev->name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will enable network interface device .
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
*
|
||||
* @return 0: set status successfully
|
||||
* -1: set status failed
|
||||
*/
|
||||
int netdev_set_up(struct netdev *netdev)
|
||||
{
|
||||
assert(netdev);
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_up)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set status.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* network interface device status flags check */
|
||||
if (netdev_is_up(netdev))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* execute enable network interface device operations by network interface device driver */
|
||||
return netdev->ops->set_up(netdev);
|
||||
}
|
||||
/**
|
||||
* This function will disable network interface device.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
*
|
||||
* @return 0: set status successfully
|
||||
* -1: set sttaus failed
|
||||
*/
|
||||
int netdev_set_down(struct netdev *netdev)
|
||||
{
|
||||
assert(netdev);
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_down)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set status.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* network interface device status flags check */
|
||||
if (!netdev_is_up(netdev))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* execute disable network interface device operations by network interface driver */
|
||||
return netdev->ops->set_down(netdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will control network interface device DHCP capability enable or disable.
|
||||
*
|
||||
* @param netdev the network interface device device to change
|
||||
* @param is_enable the new DHCP status
|
||||
*
|
||||
* @return 0: set DHCP status successfully
|
||||
* -1: set DHCP status failed
|
||||
*/
|
||||
int netdev_dhcp_enabled(struct netdev *netdev, _Bool is_enabled)
|
||||
{
|
||||
assert(netdev);
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_dhcp)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set DHCP status.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* network interface device DHCP flags check */
|
||||
if (netdev_is_dhcp_enabled(netdev) == is_enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* execute network interface device DHCP capability control operations */
|
||||
return netdev->ops->set_dhcp(netdev, is_enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device IP address.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param ipaddr the new IP address
|
||||
*
|
||||
* @return 0: set IP address successfully
|
||||
* -1: set IP address failed
|
||||
*/
|
||||
int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
|
||||
{
|
||||
assert(netdev);
|
||||
assert(ip_addr);
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_addr_info)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set IP address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (netdev_is_dhcp_enabled(netdev))
|
||||
{
|
||||
printf("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* execute network interface device set IP address operations */
|
||||
return netdev->ops->set_addr_info(netdev, (ip_addr_t *)ip_addr, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device netmask address.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param netmask the new netmask address
|
||||
*
|
||||
* @return 0: set netmask address successfully
|
||||
* -1: set netmask address failed
|
||||
*/
|
||||
int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
|
||||
{
|
||||
assert(netdev);
|
||||
assert(netmask);
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_addr_info)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set netmask address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (netdev_is_dhcp_enabled(netdev))
|
||||
{
|
||||
printf("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* execute network interface device set netmask address operations */
|
||||
return netdev->ops->set_addr_info(netdev, NULL, (ip_addr_t *)netmask, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device gateway address.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param gateway the new gateway address
|
||||
*
|
||||
* @return 0: set gateway address successfully
|
||||
* -1: set gateway address failed
|
||||
*/
|
||||
int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
|
||||
{
|
||||
assert(netdev);
|
||||
assert(gw);
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_addr_info)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set gateway address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (netdev_is_dhcp_enabled(netdev))
|
||||
{
|
||||
printf("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* execute network interface device set gateway address operations */
|
||||
return netdev->ops->set_addr_info(netdev, NULL, NULL, (ip_addr_t *)gw);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device DNS server address.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param dns_server the new DNS server address
|
||||
*
|
||||
* @return 0: set netmask address successfully
|
||||
* -1: set netmask address failed
|
||||
*/
|
||||
int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
|
||||
{
|
||||
assert(netdev);
|
||||
assert(dns_server);
|
||||
|
||||
if (dns_num >= NETDEV_DNS_SERVERS_NUM)
|
||||
{
|
||||
printf("The number of DNS servers(%d) set exceeds the maximum number(%d).", dns_num + 1, NETDEV_DNS_SERVERS_NUM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!netdev->ops || !netdev->ops->set_dns_server)
|
||||
{
|
||||
printf("The network interface device(%s) not support to set DNS server address.", netdev->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* execute network interface device set DNS server address operations */
|
||||
return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t *)dns_server);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set callback to be called when the network interface device status has been changed.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param status_callback the callback be called when the status has been changed.
|
||||
*/
|
||||
void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback)
|
||||
{
|
||||
assert(netdev);
|
||||
assert(status_callback);
|
||||
|
||||
netdev->status_callback = status_callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set callback to be called when the network interface device address has been changed.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param addr_callback the callback be called when the address has been changed.
|
||||
*/
|
||||
void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback)
|
||||
{
|
||||
assert(netdev);
|
||||
assert(addr_callback);
|
||||
|
||||
netdev->addr_callback = addr_callback;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will set network interface device IP address.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param ipaddr the new IP address
|
||||
*/
|
||||
void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
|
||||
{
|
||||
assert(ip_addr);
|
||||
|
||||
if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0)
|
||||
{
|
||||
ip_addr_copy(netdev->ip_addr, *ip_addr);
|
||||
|
||||
|
||||
|
||||
/* execute IP address change callback function */
|
||||
if (netdev->addr_callback)
|
||||
{
|
||||
netdev->addr_callback(netdev, NETDEV_CB_ADDR_IP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device netmask address.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param netmask the new netmask address
|
||||
*/
|
||||
void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
|
||||
{
|
||||
assert(netmask);
|
||||
|
||||
if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0)
|
||||
{
|
||||
ip_addr_copy(netdev->netmask, *netmask);
|
||||
|
||||
/* execute netmask address change callback function */
|
||||
if (netdev->addr_callback)
|
||||
{
|
||||
netdev->addr_callback(netdev, NETDEV_CB_ADDR_NETMASK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device gateway address.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param gateway the new gateway address
|
||||
*/
|
||||
void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
|
||||
{
|
||||
assert(gw);
|
||||
|
||||
if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0)
|
||||
{
|
||||
ip_addr_copy(netdev->gw, *gw);
|
||||
|
||||
|
||||
|
||||
/* execute gateway address change callback function */
|
||||
if (netdev->addr_callback)
|
||||
{
|
||||
netdev->addr_callback(netdev, NETDEV_CB_ADDR_GATEWAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device DNS server address.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param dns_server the new DNS server address
|
||||
*
|
||||
*/
|
||||
void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
|
||||
{
|
||||
unsigned int index;
|
||||
|
||||
assert(dns_server);
|
||||
|
||||
if (netdev == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* check DNS servers is exist */
|
||||
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
|
||||
{
|
||||
if (ip_addr_cmp(&(netdev->dns_servers[index]), dns_server))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dns_num < NETDEV_DNS_SERVERS_NUM)
|
||||
{
|
||||
ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
|
||||
|
||||
/* execute DNS servers address change callback function */
|
||||
if (netdev->addr_callback)
|
||||
{
|
||||
netdev->addr_callback(netdev, NETDEV_CB_ADDR_DNS_SERVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NETDEV_USING_AUTO_DEFAULT
|
||||
/* Change to the first link_up network interface device automatically */
|
||||
static void netdev_auto_change_default(struct netdev *netdev)
|
||||
{
|
||||
struct netdev *new_netdev = NULL;
|
||||
|
||||
if (memcmp(netdev, netdev_default, sizeof(struct netdev)) == 0)
|
||||
{
|
||||
new_netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
|
||||
if (new_netdev)
|
||||
{
|
||||
netdev_set_default(new_netdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NETDEV_USING_AUTO_DEFAULT */
|
||||
|
||||
/**
|
||||
* This function will set network interface device status.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param is_up the new status
|
||||
*/
|
||||
void netdev_low_level_set_status(struct netdev *netdev, _Bool is_up)
|
||||
{
|
||||
if (netdev && netdev_is_up(netdev) != is_up)
|
||||
{
|
||||
if (is_up)
|
||||
{
|
||||
netdev->flags |= NETDEV_FLAG_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->flags &= ~NETDEV_FLAG_UP;
|
||||
|
||||
#ifdef NETDEV_USING_AUTO_DEFAULT
|
||||
/* change to the first link_up network interface device automatically */
|
||||
netdev_auto_change_default(netdev);
|
||||
#endif /* NETDEV_USING_AUTO_DEFAULT */
|
||||
}
|
||||
|
||||
/* execute network interface device status change callback function */
|
||||
if (netdev->status_callback)
|
||||
{
|
||||
netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_UP : NETDEV_CB_STATUS_DOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device active link status.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param is_up the new link status
|
||||
*/
|
||||
void netdev_low_level_set_link_status(struct netdev *netdev, _Bool is_up)
|
||||
{
|
||||
if (netdev && netdev_is_link_up(netdev) != is_up)
|
||||
{
|
||||
if (is_up)
|
||||
{
|
||||
netdev->flags |= NETDEV_FLAG_LINK_UP;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->flags &= ~NETDEV_FLAG_LINK_UP;
|
||||
|
||||
/* set network interface device flags to internet down */
|
||||
netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
|
||||
|
||||
#ifdef NETDEV_USING_AUTO_DEFAULT
|
||||
/* change to the first link_up network interface device automatically */
|
||||
netdev_auto_change_default(netdev);
|
||||
#endif /* NETDEV_USING_AUTO_DEFAULT */
|
||||
}
|
||||
|
||||
/* execute link status change callback function */
|
||||
if (netdev->status_callback)
|
||||
{
|
||||
netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_LINK_UP : NETDEV_CB_STATUS_LINK_DOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device active internet status.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param is_up the new internet status
|
||||
*/
|
||||
void netdev_low_level_set_internet_status(struct netdev *netdev, _Bool is_up)
|
||||
{
|
||||
if (netdev && netdev_is_internet_up(netdev) != is_up)
|
||||
{
|
||||
if (is_up)
|
||||
{
|
||||
netdev->flags |= NETDEV_FLAG_INTERNET_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
|
||||
}
|
||||
|
||||
/* execute network interface device status change callback function */
|
||||
if (netdev->status_callback)
|
||||
{
|
||||
netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_INTERNET_UP : NETDEV_CB_STATUS_INTERNET_DOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will set network interface device DHCP status.
|
||||
* @NOTE it can only be called in the network interface device driver.
|
||||
*
|
||||
* @param netdev the network interface device to change
|
||||
* @param is_up the new DHCP status
|
||||
*/
|
||||
void netdev_low_level_set_dhcp_status(struct netdev *netdev, _Bool is_enable)
|
||||
{
|
||||
if (netdev && netdev_is_dhcp_enabled(netdev) != is_enable)
|
||||
{
|
||||
if (is_enable)
|
||||
{
|
||||
netdev->flags |= NETDEV_FLAG_DHCP;
|
||||
}
|
||||
else
|
||||
{
|
||||
netdev->flags &= ~NETDEV_FLAG_DHCP;
|
||||
}
|
||||
|
||||
/* execute DHCP status change callback function */
|
||||
if (netdev->status_callback)
|
||||
{
|
||||
netdev->status_callback(netdev, is_enable ? NETDEV_CB_STATUS_DHCP_ENABLE : NETDEV_CB_STATUS_DHCP_DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-05-18 ChenYong First version
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file netdev_ipaddr.c
|
||||
* @brief functions of get device address
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-15
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <transform.h>
|
||||
#include <netdev.h>
|
||||
#include <netdev_ipaddr.h>
|
||||
|
||||
|
||||
/* Here for now until needed in other places in lwIP */
|
||||
#ifndef isprint
|
||||
#define in_range(c, lo, up) ((uint8_t)c >= lo && (uint8_t)c <= up)
|
||||
#define isprint(c) in_range(c, 0x20, 0x7f)
|
||||
#define isdigit(c) in_range(c, '0', '9')
|
||||
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
|
||||
#define islower(c) in_range(c, 'a', 'z')
|
||||
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
|
||||
#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10)
|
||||
#endif
|
||||
|
||||
#if NETDEV_IPV4
|
||||
|
||||
/**
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
* of an Internet address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
* This replaces inet_addr, the return value from which
|
||||
* cannot distinguish between failure and a local broadcast address.
|
||||
*
|
||||
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
|
||||
* @param addr pointer to which to save the ip address in network order
|
||||
* @return 1 if cp could be converted to addr, 0 on failure
|
||||
*/
|
||||
int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr)
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t base;
|
||||
char c;
|
||||
uint32_t parts[4];
|
||||
uint32_t *pp = parts;
|
||||
|
||||
c = *cp;
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, 1-9=decimal.
|
||||
*/
|
||||
if (!isdigit(c))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
val = 0;
|
||||
base = 10;
|
||||
if (c == '0')
|
||||
{
|
||||
c = *++cp;
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
base = 16;
|
||||
c = *++cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
if (isdigit(c))
|
||||
{
|
||||
val = (val * base) + (uint32_t) (c - '0');
|
||||
c = *++cp;
|
||||
}
|
||||
else if (base == 16 && isxdigit(c))
|
||||
{
|
||||
val = (val << 4) | (uint32_t) (c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
c = *++cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == '.')
|
||||
{
|
||||
/*
|
||||
* Internet format:
|
||||
* a.b.c.d
|
||||
* a.b.c (with c treated as 16 bits)
|
||||
* a.b (with b treated as 24 bits)
|
||||
*/
|
||||
if (pp >= parts + 3)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*pp++ = val;
|
||||
c = *++cp;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (c != '\0' && !isspace(c))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
switch (pp - parts + 1)
|
||||
{
|
||||
|
||||
case 0:
|
||||
return 0; /* initial nondigit */
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffffUL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (parts[0] > 0xff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((parts[0] > 0xff) || (parts[1] > 0xff))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
if (addr)
|
||||
{
|
||||
ip4_addr_set_u32(addr, htonl(val));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
|
||||
*
|
||||
* @param addr ip address in network order to convert
|
||||
* @param buf target buffer where the string is stored
|
||||
* @param buflen length of buf
|
||||
* @return either pointer to buf which now holds the ASCII
|
||||
* representation of addr or NULL if buf was too small
|
||||
*/
|
||||
char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
|
||||
{
|
||||
uint32_t s_addr;
|
||||
char inv[3];
|
||||
char *rp;
|
||||
uint8_t *ap;
|
||||
uint8_t rem;
|
||||
uint8_t n;
|
||||
uint8_t i;
|
||||
int len = 0;
|
||||
|
||||
s_addr = ip4_addr_get_u32(addr);
|
||||
|
||||
rp = buf;
|
||||
ap = (uint8_t *) &s_addr;
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
rem = *ap % (uint8_t) 10;
|
||||
*ap /= (uint8_t) 10;
|
||||
inv[i++] = (char) ('0' + rem);
|
||||
} while (*ap);
|
||||
while (i--)
|
||||
{
|
||||
if (len++ >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*rp++ = inv[i];
|
||||
}
|
||||
if (len++ >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*rp++ = '.';
|
||||
ap++;
|
||||
}
|
||||
*--rp = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert numeric IP address into decimal dotted ASCII representation.
|
||||
* returns ptr to static buffer; not reentrant!
|
||||
*
|
||||
* @param addr ip address in network order to convert
|
||||
* @return pointer to a global static (!) buffer that holds the ASCII
|
||||
* representation of addr
|
||||
*/
|
||||
char *netdev_ip4addr_ntoa(const ip4_addr_t *addr)
|
||||
{
|
||||
static char str[IP4ADDR_STRLEN_MAX];
|
||||
return netdev_ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ascii internet address interpretation routine.
|
||||
* The value returned is in network order.
|
||||
*
|
||||
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
|
||||
* @return ip address in network order
|
||||
*/
|
||||
in_addr_t netdev_ipaddr_addr(const char *cp)
|
||||
{
|
||||
ip4_addr_t val;
|
||||
|
||||
if (netdev_ip4addr_aton(cp, &val)) {
|
||||
return ip4_addr_get_u32(&val);
|
||||
}
|
||||
return (IPADDR_NONE);
|
||||
}
|
||||
|
||||
#endif /* NETDEV_IPV4 */
|
||||
|
||||
|
||||
#if NETDEV_IPV6
|
||||
|
||||
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
||||
|
||||
/**
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
* of an IPv6 address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
*
|
||||
* @param cp IPv6 address in ascii representation (e.g. "FF01::1")
|
||||
* @param addr pointer to which to save the ip address in network order
|
||||
* @return 1 if cp could be converted to addr, 0 on failure
|
||||
*/
|
||||
int
|
||||
netdev_ip6addr_aton(const char *cp, ip6_addr_t *addr)
|
||||
{
|
||||
uint32_t addr_index, zero_blocks, current_block_index, current_block_value;
|
||||
const char *s;
|
||||
|
||||
/* Count the number of colons, to count the number of blocks in a "::" sequence
|
||||
zero_blocks may be 1 even if there are no :: sequences */
|
||||
zero_blocks = 8;
|
||||
for (s = cp; *s != 0; s++)
|
||||
{
|
||||
if (*s == ':')
|
||||
{
|
||||
zero_blocks--;
|
||||
}
|
||||
else if (!isxdigit(*s))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse each block */
|
||||
addr_index = 0;
|
||||
current_block_index = 0;
|
||||
current_block_value = 0;
|
||||
for (s = cp; *s != 0; s++)
|
||||
{
|
||||
if (*s == ':')
|
||||
{
|
||||
if (addr)
|
||||
{
|
||||
if (current_block_index & 0x1)
|
||||
{
|
||||
addr->addr[addr_index++] |= current_block_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr->addr[addr_index] = current_block_value << 16;
|
||||
}
|
||||
}
|
||||
current_block_index++;
|
||||
current_block_value = 0;
|
||||
if (current_block_index > 7)
|
||||
{
|
||||
/* address too long! */
|
||||
return 0;
|
||||
}
|
||||
if (s[1] == ':')
|
||||
{
|
||||
if (s[2] == ':')
|
||||
{
|
||||
/* invalid format: three successive colons */
|
||||
return 0;
|
||||
}
|
||||
s++;
|
||||
/* "::" found, set zeros */
|
||||
while (zero_blocks > 0)
|
||||
{
|
||||
zero_blocks--;
|
||||
if (current_block_index & 0x1)
|
||||
{
|
||||
addr_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr)
|
||||
{
|
||||
addr->addr[addr_index] = 0;
|
||||
}
|
||||
}
|
||||
current_block_index++;
|
||||
if (current_block_index > 7)
|
||||
{
|
||||
/* address too long! */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isxdigit(*s))
|
||||
{
|
||||
/* add current digit */
|
||||
current_block_value = (current_block_value << 4) +
|
||||
(isdigit(*s) ? (uint32_t)(*s - '0') : (uint32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A')));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unexpected digit, space? CRLF? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr)
|
||||
{
|
||||
if (current_block_index & 0x1)
|
||||
{
|
||||
addr->addr[addr_index++] |= current_block_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr->addr[addr_index] = current_block_value << 16;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to network byte order. */
|
||||
if (addr)
|
||||
{
|
||||
for (addr_index = 0; addr_index < 4; addr_index++)
|
||||
{
|
||||
addr->addr[addr_index] = htonl(addr->addr[addr_index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (current_block_index != 7)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
|
||||
*
|
||||
* @param addr ip6 address in network order to convert
|
||||
* @param buf target buffer where the string is stored
|
||||
* @param buflen length of buf
|
||||
* @return either pointer to buf which now holds the ASCII
|
||||
* representation of addr or NULL if buf was too small
|
||||
*/
|
||||
char *
|
||||
netdev_ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
|
||||
{
|
||||
uint32_t current_block_index, current_block_value, next_block_value;
|
||||
int32_t i;
|
||||
uint8_t zero_flag, empty_block_flag;
|
||||
|
||||
i = 0;
|
||||
empty_block_flag = 0; /* used to indicate a zero chain for "::' */
|
||||
|
||||
for (current_block_index = 0; current_block_index < 8; current_block_index++)
|
||||
{
|
||||
/* get the current 16-bit block */
|
||||
current_block_value = htonl(addr->addr[current_block_index >> 1]);
|
||||
if ((current_block_index & 0x1) == 0)
|
||||
{
|
||||
current_block_value = current_block_value >> 16;
|
||||
}
|
||||
current_block_value &= 0xffff;
|
||||
|
||||
/* Check for empty block. */
|
||||
if (current_block_value == 0)
|
||||
{
|
||||
if (current_block_index == 7 && empty_block_flag == 1)
|
||||
{
|
||||
/* special case, we must render a ':' for the last block. */
|
||||
buf[i++] = ':';
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (empty_block_flag == 0)
|
||||
{
|
||||
/* generate empty block "::", but only if more than one contiguous zero block,
|
||||
* according to current formatting suggestions RFC 5952. */
|
||||
next_block_value = htonl(addr->addr[(current_block_index + 1) >> 1]);
|
||||
if ((current_block_index & 0x1) == 0x01)
|
||||
{
|
||||
next_block_value = next_block_value >> 16;
|
||||
}
|
||||
next_block_value &= 0xffff;
|
||||
if (next_block_value == 0)
|
||||
{
|
||||
empty_block_flag = 1;
|
||||
buf[i++] = ':';
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
continue; /* move on to next block. */
|
||||
}
|
||||
}
|
||||
else if (empty_block_flag == 1)
|
||||
{
|
||||
/* move on to next block. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (empty_block_flag == 1)
|
||||
{
|
||||
/* Set this flag value so we don't produce multiple empty blocks. */
|
||||
empty_block_flag = 2;
|
||||
}
|
||||
|
||||
if (current_block_index > 0)
|
||||
{
|
||||
buf[i++] = ':';
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((current_block_value & 0xf000) == 0)
|
||||
{
|
||||
zero_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[i++] = xchar(((current_block_value & 0xf000) >> 12));
|
||||
zero_flag = 0;
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (((current_block_value & 0xf00) == 0) && (zero_flag))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[i++] = xchar(((current_block_value & 0xf00) >> 8));
|
||||
zero_flag = 0;
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (((current_block_value & 0xf0) == 0) && (zero_flag))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[i++] = xchar(((current_block_value & 0xf0) >> 4));
|
||||
zero_flag = 0;
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
buf[i++] = xchar((current_block_value & 0xf));
|
||||
if (i >= buflen)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
buf[i] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert numeric IPv6 address into ASCII representation.
|
||||
* returns ptr to static buffer; not reentrant!
|
||||
*
|
||||
* @param addr ip6 address in network order to convert
|
||||
* @return pointer to a global static (!) buffer that holds the ASCII
|
||||
* representation of addr
|
||||
*/
|
||||
char *
|
||||
netdev_ip6addr_ntoa(const ip6_addr_t *addr)
|
||||
{
|
||||
static char str[40];
|
||||
return netdev_ip6addr_ntoa_r(addr, str, 40);
|
||||
}
|
||||
|
||||
#endif /* NETDEV_IPV6 */
|
||||
|
||||
const char *
|
||||
netdev_inet_ntop(int af, const void *src, char *dst, int32_t size)
|
||||
{
|
||||
#define AF_INET 2
|
||||
//#define AF_INET6 10
|
||||
|
||||
const char *ret = NULL;
|
||||
int size_int = (int)size;
|
||||
if (size_int < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
switch (af)
|
||||
{
|
||||
#if NETDEV_IPV4
|
||||
case AF_INET:
|
||||
return netdev_ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int);
|
||||
#endif
|
||||
#if NETDEV_IPV6
|
||||
case AF_INET6:
|
||||
return netdev_ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
netdev_inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
#define AF_INET 2
|
||||
//#define AF_INET6 10
|
||||
|
||||
int err;
|
||||
switch (af)
|
||||
{
|
||||
#if NETDEV_IPV4
|
||||
case AF_INET:
|
||||
err = netdev_ip4addr_aton(src, (ip4_addr_t *)dst);
|
||||
break;
|
||||
#endif
|
||||
#if NETDEV_IPV6
|
||||
case AF_INET6:
|
||||
{
|
||||
/* convert into temporary variable since ip6_addr_t might be larger
|
||||
than in6_addr when scopes are enabled */
|
||||
ip6_addr_t addr;
|
||||
err = netdev_ip6addr_aton(src, &addr);
|
||||
if (err)
|
||||
{
|
||||
memcpy(dst, &addr.addr, sizeof(addr.addr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
Loading…
Reference in New Issue