summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking/libc/getnameinfo.c
blob: 415f150a82b62b7c66546bd8bf91ce0f64a3803b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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;
}