summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking/libc/getnameinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libnetworking/libc/getnameinfo.c')
-rw-r--r--cpukit/libnetworking/libc/getnameinfo.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/cpukit/libnetworking/libc/getnameinfo.c b/cpukit/libnetworking/libc/getnameinfo.c
new file mode 100644
index 0000000000..415f150a82
--- /dev/null
+++ b/cpukit/libnetworking/libc/getnameinfo.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node,
+ size_t nodelen, char *service, size_t servicelen, int flags)
+{
+ int af;
+ const struct sockaddr_in *sa_in = (const struct sockaddr_in *)sa;
+
+ (void) salen;
+
+ af = sa->sa_family;
+ if (af != AF_INET) {
+ return EAI_FAMILY;
+ }
+
+ if ((flags & NI_NAMEREQD) != 0) {
+ return EAI_NONAME;
+ }
+
+ /* FIXME: This return just the address value. Try resolving instead. */
+ if (node != NULL && nodelen > 0) {
+ const void *addr = &sa_in->sin_addr;
+
+ if(inet_ntop(af, addr, node, nodelen) == NULL) {
+ return EAI_FAIL;
+ }
+ }
+
+ if (service != NULL && servicelen > 0) {
+ in_port_t port = sa_in->sin_port;
+ int rv;
+
+ rv = snprintf(service, servicelen, "%u", port);
+ if (rv <= 0) {
+ return EAI_FAIL;
+ } else if ((unsigned)rv >= servicelen) {
+ return EAI_OVERFLOW;
+ }
+ }
+
+ return 0;
+}