9 #include <sys/socket.h>
10 #include <netinet/in.h>
12 #include <net/gen/in.h>
13 #include <net/gen/tcp.h>
14 #include <net/gen/tcp_io.h>
15 #include <net/gen/udp.h>
16 #include <net/gen/udp_io.h>
19 static int _tcp_getpeername(int sock
, struct sockaddr
*__restrict address
,
20 socklen_t
*__restrict address_len
, nwio_tcpconf_t
*tcpconfp
);
22 static int _udp_getpeername(int sock
, struct sockaddr
*__restrict address
,
23 socklen_t
*__restrict address_len
, nwio_udpopt_t
*tcpconfp
);
25 static int _uds_getpeername(int sock
, struct sockaddr
*__restrict address
,
26 socklen_t
*__restrict address_len
, struct sockaddr_un
*uds_addr
);
29 * Get the remote address of a socket.
32 __getpeername(int fd
, struct sockaddr
* __restrict address
,
33 socklen_t
* __restrict address_len
)
37 if (address_len
== NULL
) {
42 memset(&m
, 0, sizeof(m
));
43 m
.m_lc_vfs_sockaddr
.fd
= fd
;
44 m
.m_lc_vfs_sockaddr
.addr
= (vir_bytes
)address
;
45 m
.m_lc_vfs_sockaddr
.addr_len
= *address_len
;
47 if (_syscall(VFS_PROC_NR
, VFS_GETPEERNAME
, &m
) < 0)
50 *address_len
= m
.m_vfs_lc_socklen
.len
;
54 int getpeername(int sock
, struct sockaddr
*__restrict address
,
55 socklen_t
*__restrict address_len
)
58 nwio_tcpconf_t tcpconf
;
60 struct sockaddr_un uds_addr
;
62 r
= __getpeername(sock
, address
, address_len
);
63 if (r
!= -1 || (errno
!= ENOTSOCK
&& errno
!= ENOSYS
))
66 r
= ioctl(sock
, NWIOGTCPCONF
, &tcpconf
);
67 if (r
!= -1 || errno
!= ENOTTY
)
71 /* Bad file descriptor */
74 return _tcp_getpeername(sock
, address
, address_len
,
78 r
= ioctl(sock
, NWIOGUDPOPT
, &udpopt
);
79 if (r
!= -1 || errno
!= ENOTTY
)
83 /* Bad file descriptor */
86 return _udp_getpeername(sock
, address
, address_len
,
90 r
= ioctl(sock
, NWIOGUDSPADDR
, &uds_addr
);
91 if (r
!= -1 || errno
!= ENOTTY
)
95 /* Bad file descriptor */
98 return _uds_getpeername(sock
, address
, address_len
,
106 static int _tcp_getpeername(int sock
, struct sockaddr
*__restrict address
,
107 socklen_t
*__restrict address_len
, nwio_tcpconf_t
*tcpconfp
)
110 struct sockaddr_in sin
;
112 if (tcpconfp
->nwtc_remaddr
== 0 ||
113 tcpconfp
->nwtc_remport
== 0)
119 memset(&sin
, '\0', sizeof(sin
));
120 sin
.sin_family
= AF_INET
;
121 sin
.sin_addr
.s_addr
= tcpconfp
->nwtc_remaddr
;
122 sin
.sin_port
= tcpconfp
->nwtc_remport
;
123 sin
.sin_len
= sizeof(sin
);
126 if (len
> sizeof(sin
))
128 memcpy(address
, &sin
, len
);
134 static int _udp_getpeername(int sock
, struct sockaddr
*__restrict address
,
135 socklen_t
*__restrict address_len
, nwio_udpopt_t
*udpopt
)
138 struct sockaddr_in sin
;
140 if (udpopt
->nwuo_remaddr
== 0 ||
141 udpopt
->nwuo_remport
== 0)
147 memset(&sin
, '\0', sizeof(sin
));
148 sin
.sin_family
= AF_INET
;
149 sin
.sin_addr
.s_addr
= udpopt
->nwuo_remaddr
;
150 sin
.sin_port
= udpopt
->nwuo_remport
;
151 sin
.sin_len
= sizeof(sin
);
154 if (len
> sizeof(sin
))
156 memcpy(address
, &sin
, len
);
162 static int _uds_getpeername(int sock
, struct sockaddr
*__restrict address
,
163 socklen_t
*__restrict address_len
, struct sockaddr_un
*uds_addr
)
167 if (uds_addr
->sun_family
!= AF_UNIX
)
174 if (len
> sizeof(struct sockaddr_un
))
175 len
= sizeof(struct sockaddr_un
);
177 memcpy(address
, uds_addr
, len
);