Skip to content
Permalink
Browse files

net: utils: Add userspace support to net_addr_ntop/pton()

Allow userspace application call net_addr_ntop() and
net_addr_pton() functions.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
  • Loading branch information...
jukkar authored and andrewboie committed Jun 12, 2019
1 parent eb018f8 commit 5d13df9c3b41a2d46b888daa0db7d9c4a9d6cf69
Showing with 88 additions and 7 deletions.
  1. +5 −3 include/net/net_ip.h
  2. +83 −4 subsys/net/ip/utils.c
@@ -1173,7 +1173,7 @@ struct sockaddr_can_ptr *net_can_ptr(const struct sockaddr_ptr *addr)
*
* @return 0 if ok, < 0 if error
*/
int net_addr_pton(sa_family_t family, const char *src, void *dst);
__syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);

/**
* @brief Convert IP address to string form.
@@ -1186,8 +1186,8 @@ int net_addr_pton(sa_family_t family, const char *src, void *dst);
*
* @return dst pointer if ok, NULL if error
*/
char *net_addr_ntop(sa_family_t family, const void *src,
char *dst, size_t size);
__syscall char *net_addr_ntop(sa_family_t family, const void *src,
char *dst, size_t size);

/**
* @brief Parse a string that contains either IPv4 or IPv6 address
@@ -1324,6 +1324,8 @@ static inline u8_t net_priority2vlan(enum net_priority priority)
}
#endif

#include <syscalls/net_ip.h>

/**
* @}
*/
@@ -12,7 +12,9 @@
#include <logging/log.h>
LOG_MODULE_REGISTER(net_utils, CONFIG_NET_UTILS_LOG_LEVEL);

#include <kernel.h>
#include <stdlib.h>
#include <syscall_handler.h>
#include <zephyr/types.h>
#include <stdbool.h>
#include <string.h>
@@ -137,8 +139,8 @@ static int net_value_to_udec(char *buf, u32_t value, int precision)
return buf - start;
}

char *net_addr_ntop(sa_family_t family, const void *src,
char *dst, size_t size)
char *z_impl_net_addr_ntop(sa_family_t family, const void *src,
char *dst, size_t size)
{
struct in_addr *addr;
struct in6_addr *addr6;
@@ -270,8 +272,42 @@ char *net_addr_ntop(sa_family_t family, const void *src,
return dst;
}

int net_addr_pton(sa_family_t family, const char *src,
void *dst)
#if defined(CONFIG_USERSPACE)
Z_SYSCALL_HANDLER(net_addr_ntop, family, src, dst, size)
{
char str[INET6_ADDRSTRLEN];
struct in6_addr addr6;
struct in_addr addr4;
char *out;
const void *addr;

Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, size));

if (family == AF_INET) {
Z_OOPS(z_user_from_copy(&addr4, (const void *)src,
sizeof(addr4)));
addr = &addr4;
} else if (family == AF_INET6) {
Z_OOPS(z_user_from_copy(&addr6, (const void *)src,
sizeof(addr6)));
addr = &addr6;
} else {
return 0;
}

out = z_impl_net_addr_ntop(family, addr, str, sizeof(str));
if (!out) {
return 0;
}

Z_OOPS(z_user_to_copy((void *)dst, str, MIN(size, sizeof(str))));

return (int)dst;
}
#endif /* CONFIG_USERSPACE */

int z_impl_net_addr_pton(sa_family_t family, const char *src,
void *dst)
{
if (family == AF_INET) {
struct in_addr *addr = (struct in_addr *)dst;
@@ -403,6 +439,49 @@ int net_addr_pton(sa_family_t family, const char *src,
return 0;
}

#if defined(CONFIG_USERSPACE)
Z_SYSCALL_HANDLER(net_addr_pton, family, src, dst)
{
char str[INET6_ADDRSTRLEN];
struct in6_addr addr6;
struct in_addr addr4;
void *addr;
size_t size;
size_t nlen;
int err;

if (family == AF_INET) {
size = sizeof(struct in_addr);
addr = &addr4;
} else if (family == AF_INET6) {
size = sizeof(struct in6_addr);
addr = &addr6;
} else {
return -EINVAL;
}

memset(str, 0, sizeof(str));

nlen = z_user_string_nlen((const char *)src, sizeof(str), &err);
if (err) {
return -EINVAL;
}

Z_OOPS(Z_SYSCALL_MEMORY_WRITE(dst, size));
Z_OOPS(Z_SYSCALL_MEMORY_READ(src, nlen));
Z_OOPS(z_user_from_copy(str, (const void *)src, nlen));

err = z_impl_net_addr_pton(family, str, addr);
if (err) {
return err;
}

Z_OOPS(z_user_to_copy((void *)src, addr, size));

return 0;
}
#endif /* CONFIG_USERSPACE */

static u16_t calc_chksum(u16_t sum, const u8_t *data, size_t len)
{
const u8_t *end;

0 comments on commit 5d13df9

Please sign in to comment.
You can’t perform that action at this time.