xref: /minix3/minix/lib/libc/sys/getpeername.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #include <sys/cdefs.h>
2*433d6423SLionel Sambuc #include "namespace.h"
3*433d6423SLionel Sambuc 
4*433d6423SLionel Sambuc #include <errno.h>
5*433d6423SLionel Sambuc #include <stdio.h>
6*433d6423SLionel Sambuc #include <string.h>
7*433d6423SLionel Sambuc #include <sys/ioctl.h>
8*433d6423SLionel Sambuc #include <sys/socket.h>
9*433d6423SLionel Sambuc #include <netinet/in.h>
10*433d6423SLionel Sambuc 
11*433d6423SLionel Sambuc #include <net/gen/in.h>
12*433d6423SLionel Sambuc #include <net/gen/tcp.h>
13*433d6423SLionel Sambuc #include <net/gen/tcp_io.h>
14*433d6423SLionel Sambuc #include <net/gen/udp.h>
15*433d6423SLionel Sambuc #include <net/gen/udp_io.h>
16*433d6423SLionel Sambuc #include <sys/un.h>
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc #define DEBUG 0
19*433d6423SLionel Sambuc 
20*433d6423SLionel Sambuc static int _tcp_getpeername(int sock, struct sockaddr *__restrict address,
21*433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp);
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc static int _udp_getpeername(int sock, struct sockaddr *__restrict address,
24*433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_udpopt_t *tcpconfp);
25*433d6423SLionel Sambuc 
26*433d6423SLionel Sambuc static int _uds_getpeername(int sock, struct sockaddr *__restrict address,
27*433d6423SLionel Sambuc 	socklen_t *__restrict address_len, struct sockaddr_un *uds_addr);
28*433d6423SLionel Sambuc 
29*433d6423SLionel Sambuc int getpeername(int sock, struct sockaddr *__restrict address,
30*433d6423SLionel Sambuc 	socklen_t *__restrict address_len)
31*433d6423SLionel Sambuc {
32*433d6423SLionel Sambuc 	int r;
33*433d6423SLionel Sambuc 	nwio_tcpconf_t tcpconf;
34*433d6423SLionel Sambuc 	nwio_udpopt_t udpopt;
35*433d6423SLionel Sambuc 	struct sockaddr_un uds_addr;
36*433d6423SLionel Sambuc 
37*433d6423SLionel Sambuc 	r= ioctl(sock, NWIOGTCPCONF, &tcpconf);
38*433d6423SLionel Sambuc 	if (r != -1 || errno != ENOTTY)
39*433d6423SLionel Sambuc 	{
40*433d6423SLionel Sambuc 		if (r == -1)
41*433d6423SLionel Sambuc 		{
42*433d6423SLionel Sambuc 			/* Bad file descriptor */
43*433d6423SLionel Sambuc 			return -1;
44*433d6423SLionel Sambuc 		}
45*433d6423SLionel Sambuc 		return _tcp_getpeername(sock, address, address_len,
46*433d6423SLionel Sambuc 			&tcpconf);
47*433d6423SLionel Sambuc 	}
48*433d6423SLionel Sambuc 
49*433d6423SLionel Sambuc 	r= ioctl(sock, NWIOGUDPOPT, &udpopt);
50*433d6423SLionel Sambuc 	if (r != -1 || errno != ENOTTY)
51*433d6423SLionel Sambuc 	{
52*433d6423SLionel Sambuc 		if (r == -1)
53*433d6423SLionel Sambuc 		{
54*433d6423SLionel Sambuc 			/* Bad file descriptor */
55*433d6423SLionel Sambuc 			return -1;
56*433d6423SLionel Sambuc 		}
57*433d6423SLionel Sambuc 		return _udp_getpeername(sock, address, address_len,
58*433d6423SLionel Sambuc 			&udpopt);
59*433d6423SLionel Sambuc 	}
60*433d6423SLionel Sambuc 
61*433d6423SLionel Sambuc 	r= ioctl(sock, NWIOGUDSPADDR, &uds_addr);
62*433d6423SLionel Sambuc 	if (r != -1 || errno != ENOTTY)
63*433d6423SLionel Sambuc 	{
64*433d6423SLionel Sambuc 		if (r == -1)
65*433d6423SLionel Sambuc 		{
66*433d6423SLionel Sambuc 			/* Bad file descriptor */
67*433d6423SLionel Sambuc 			return -1;
68*433d6423SLionel Sambuc 		}
69*433d6423SLionel Sambuc 		return _uds_getpeername(sock, address, address_len,
70*433d6423SLionel Sambuc 			&uds_addr);
71*433d6423SLionel Sambuc 	}
72*433d6423SLionel Sambuc 
73*433d6423SLionel Sambuc 
74*433d6423SLionel Sambuc #if DEBUG
75*433d6423SLionel Sambuc 	fprintf(stderr, "getpeername: not implemented for fd %d\n", sock);
76*433d6423SLionel Sambuc #endif
77*433d6423SLionel Sambuc 	errno= ENOSYS;
78*433d6423SLionel Sambuc 	return -1;
79*433d6423SLionel Sambuc }
80*433d6423SLionel Sambuc 
81*433d6423SLionel Sambuc static int _tcp_getpeername(int sock, struct sockaddr *__restrict address,
82*433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_tcpconf_t *tcpconfp)
83*433d6423SLionel Sambuc {
84*433d6423SLionel Sambuc 	socklen_t len;
85*433d6423SLionel Sambuc 	struct sockaddr_in sin;
86*433d6423SLionel Sambuc 
87*433d6423SLionel Sambuc 	if (tcpconfp->nwtc_remaddr == 0 ||
88*433d6423SLionel Sambuc 		tcpconfp->nwtc_remport == 0)
89*433d6423SLionel Sambuc 	{
90*433d6423SLionel Sambuc 		errno= ENOTCONN;
91*433d6423SLionel Sambuc 		return -1;
92*433d6423SLionel Sambuc 	}
93*433d6423SLionel Sambuc 
94*433d6423SLionel Sambuc 	memset(&sin, '\0', sizeof(sin));
95*433d6423SLionel Sambuc 	sin.sin_family= AF_INET;
96*433d6423SLionel Sambuc 	sin.sin_addr.s_addr= tcpconfp->nwtc_remaddr;
97*433d6423SLionel Sambuc 	sin.sin_port= tcpconfp->nwtc_remport;
98*433d6423SLionel Sambuc 	sin.sin_len = sizeof(sin);
99*433d6423SLionel Sambuc 
100*433d6423SLionel Sambuc 	len= *address_len;
101*433d6423SLionel Sambuc 	if (len > sizeof(sin))
102*433d6423SLionel Sambuc 		len= sizeof(sin);
103*433d6423SLionel Sambuc 	memcpy(address, &sin, len);
104*433d6423SLionel Sambuc 	*address_len= len;
105*433d6423SLionel Sambuc 
106*433d6423SLionel Sambuc 	return 0;
107*433d6423SLionel Sambuc }
108*433d6423SLionel Sambuc 
109*433d6423SLionel Sambuc static int _udp_getpeername(int sock, struct sockaddr *__restrict address,
110*433d6423SLionel Sambuc 	socklen_t *__restrict address_len, nwio_udpopt_t *udpopt)
111*433d6423SLionel Sambuc {
112*433d6423SLionel Sambuc 	socklen_t len;
113*433d6423SLionel Sambuc 	struct sockaddr_in sin;
114*433d6423SLionel Sambuc 
115*433d6423SLionel Sambuc 	if (udpopt->nwuo_remaddr == 0 ||
116*433d6423SLionel Sambuc 		udpopt->nwuo_remport == 0)
117*433d6423SLionel Sambuc 	{
118*433d6423SLionel Sambuc 		errno= ENOTCONN;
119*433d6423SLionel Sambuc 		return -1;
120*433d6423SLionel Sambuc 	}
121*433d6423SLionel Sambuc 
122*433d6423SLionel Sambuc 	memset(&sin, '\0', sizeof(sin));
123*433d6423SLionel Sambuc 	sin.sin_family= AF_INET;
124*433d6423SLionel Sambuc 	sin.sin_addr.s_addr= udpopt->nwuo_remaddr;
125*433d6423SLionel Sambuc 	sin.sin_port= udpopt->nwuo_remport;
126*433d6423SLionel Sambuc 	sin.sin_len = sizeof(sin);
127*433d6423SLionel Sambuc 
128*433d6423SLionel Sambuc 	len= *address_len;
129*433d6423SLionel Sambuc 	if (len > sizeof(sin))
130*433d6423SLionel Sambuc 		len= sizeof(sin);
131*433d6423SLionel Sambuc 	memcpy(address, &sin, len);
132*433d6423SLionel Sambuc 	*address_len= len;
133*433d6423SLionel Sambuc 
134*433d6423SLionel Sambuc 	return 0;
135*433d6423SLionel Sambuc }
136*433d6423SLionel Sambuc 
137*433d6423SLionel Sambuc static int _uds_getpeername(int sock, struct sockaddr *__restrict address,
138*433d6423SLionel Sambuc 	socklen_t *__restrict address_len, struct sockaddr_un *uds_addr)
139*433d6423SLionel Sambuc {
140*433d6423SLionel Sambuc 	socklen_t len;
141*433d6423SLionel Sambuc 
142*433d6423SLionel Sambuc 	if (uds_addr->sun_family != AF_UNIX)
143*433d6423SLionel Sambuc 	{
144*433d6423SLionel Sambuc 		errno= ENOTCONN;
145*433d6423SLionel Sambuc 		return -1;
146*433d6423SLionel Sambuc 	}
147*433d6423SLionel Sambuc 
148*433d6423SLionel Sambuc 	len= *address_len;
149*433d6423SLionel Sambuc 	if (len > sizeof(struct sockaddr_un))
150*433d6423SLionel Sambuc 		len = sizeof(struct sockaddr_un);
151*433d6423SLionel Sambuc 
152*433d6423SLionel Sambuc 	memcpy(address, uds_addr, len);
153*433d6423SLionel Sambuc 	*address_len= len;
154*433d6423SLionel Sambuc 
155*433d6423SLionel Sambuc 	return 0;
156*433d6423SLionel Sambuc }
157