blob: 695eff784e06cb221ad2dfe590f6306911d793a9 [file] [log] [blame]
/*
* Copyright (c) 2024, Friedt Professional Engineering Services, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <zephyr/net/net_if.h>
#include <zephyr/posix/arpa/inet.h>
#include <zephyr/posix/netinet/in.h>
#include <zephyr/posix/net/if.h>
in_addr_t inet_addr(const char *cp)
{
int val = 0;
int len = 0;
int dots = 0;
int digits = 0;
/* error checking */
if (cp == NULL) {
return -1;
}
for (int i = 0, subdigits = 0; i <= INET_ADDRSTRLEN; ++i, ++len) {
if (subdigits > 3) {
return -1;
}
if (cp[i] == '\0') {
break;
} else if (cp[i] == '.') {
if (subdigits == 0) {
return -1;
}
++dots;
subdigits = 0;
continue;
} else if (isdigit((int)cp[i])) {
++digits;
++subdigits;
continue;
} else if (isspace((int)cp[i])) {
break;
}
return -1;
}
if (dots != 3 || digits < 4) {
return -1;
}
/* conversion */
for (int i = 0, tmp = 0; i < len; ++i, ++cp) {
if (*cp != '.') {
tmp *= 10;
tmp += *cp - '0';
}
if (*cp == '.' || i == len - 1) {
val <<= 8;
val |= tmp;
tmp = 0;
}
}
return htonl(val);
}
char *inet_ntoa(struct in_addr in)
{
static char buf[INET_ADDRSTRLEN];
unsigned char *bytes = (unsigned char *)&in.s_addr;
snprintf(buf, sizeof(buf), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
return buf;
}
char *if_indextoname(unsigned int ifindex, char *ifname)
{
int ret;
if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
errno = ENOTSUP;
return NULL;
}
ret = net_if_get_name(net_if_get_by_index(ifindex), ifname, IF_NAMESIZE);
if (ret < 0) {
errno = ENXIO;
return NULL;
}
return ifname;
}
void if_freenameindex(struct if_nameindex *ptr)
{
size_t n;
if (ptr == NULL || !IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
return;
}
NET_IFACE_COUNT(&n);
for (size_t i = 0; i < n; ++i) {
if (IS_ENABLED(CONFIG_NET_INTERFACE_NAME) && ptr[i].if_name != NULL) {
free(ptr[i].if_name);
}
}
free(ptr);
}
struct if_nameindex *if_nameindex(void)
{
size_t n;
char *name;
struct if_nameindex *ni;
if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
errno = ENOTSUP;
return NULL;
}
/* FIXME: would be nice to use this without malloc */
NET_IFACE_COUNT(&n);
ni = malloc((n + 1) * sizeof(*ni));
if (ni == NULL) {
goto return_err;
}
for (size_t i = 0; i < n; ++i) {
ni[i].if_index = i + 1;
ni[i].if_name = malloc(IF_NAMESIZE);
if (ni[i].if_name == NULL) {
goto return_err;
}
name = if_indextoname(i + 1, ni[i].if_name);
__ASSERT_NO_MSG(name != NULL);
}
ni[n].if_index = 0;
ni[n].if_name = NULL;
return ni;
return_err:
if_freenameindex(ni);
errno = ENOBUFS;
return NULL;
}
unsigned int if_nametoindex(const char *ifname)
{
int ret;
if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
return 0;
}
ret = net_if_get_by_name(ifname);
if (ret < 0) {
return 0;
}
return ret;
}
void endhostent(void)
{
}
void endnetent(void)
{
}
void endprotoent(void)
{
}
void endservent(void)
{
}
struct hostent *gethostent(void)
{
return NULL;
}
struct netent *getnetbyaddr(uint32_t net, int type)
{
ARG_UNUSED(net);
ARG_UNUSED(type);
return NULL;
}
struct netent *getnetbyname(const char *name)
{
ARG_UNUSED(name);
return NULL;
}
struct netent *getnetent(void)
{
return NULL;
}
struct protoent *getprotobyname(const char *name)
{
ARG_UNUSED(name);
return NULL;
}
struct protoent *getprotobynumber(int proto)
{
ARG_UNUSED(proto);
return NULL;
}
struct protoent *getprotoent(void)
{
return NULL;
}
struct servent *getservbyname(const char *name, const char *proto)
{
ARG_UNUSED(name);
ARG_UNUSED(proto);
return NULL;
}
struct servent *getservbyport(int port, const char *proto)
{
ARG_UNUSED(port);
ARG_UNUSED(proto);
return NULL;
}
struct servent *getservent(void)
{
return NULL;
}
void sethostent(int stayopen)
{
ARG_UNUSED(stayopen);
}
void setnetent(int stayopen)
{
ARG_UNUSED(stayopen);
}
void setprotoent(int stayopen)
{
ARG_UNUSED(stayopen);
}
void setservent(int stayopen)
{
ARG_UNUSED(stayopen);
}
int sockatmark(int s)
{
ARG_UNUSED(s);
errno = ENOSYS;
return -1;
}