axlibc/
net.rs

1use arceos_posix_api::{
2    sys_accept, sys_bind, sys_connect, sys_freeaddrinfo, sys_getaddrinfo, sys_getpeername,
3    sys_getsockname, sys_listen, sys_recv, sys_recvfrom, sys_send, sys_sendto, sys_shutdown,
4    sys_socket,
5};
6use core::ffi::{c_char, c_int, c_void};
7
8use crate::{ctypes, utils::e};
9
10/// Create an socket for communication.
11///
12/// Return the socket file descriptor.
13#[unsafe(no_mangle)]
14pub unsafe extern "C" fn socket(domain: c_int, socktype: c_int, protocol: c_int) -> c_int {
15    e(sys_socket(domain, socktype, protocol))
16}
17
18/// Bind a address to a socket.
19///
20/// Return 0 if success.
21#[unsafe(no_mangle)]
22pub unsafe extern "C" fn bind(
23    socket_fd: c_int,
24    socket_addr: *const ctypes::sockaddr,
25    addrlen: ctypes::socklen_t,
26) -> c_int {
27    e(sys_bind(socket_fd, socket_addr, addrlen))
28}
29
30/// Connects the socket to the address specified.
31///
32/// Return 0 if success.
33#[unsafe(no_mangle)]
34pub unsafe extern "C" fn connect(
35    socket_fd: c_int,
36    socket_addr: *const ctypes::sockaddr,
37    addrlen: ctypes::socklen_t,
38) -> c_int {
39    e(sys_connect(socket_fd, socket_addr, addrlen))
40}
41
42/// Send a message on a socket to the address specified.
43///
44/// Return the number of bytes sent if success.
45#[unsafe(no_mangle)]
46pub unsafe extern "C" fn sendto(
47    socket_fd: c_int,
48    buf_ptr: *const c_void,
49    len: ctypes::size_t,
50    flag: c_int, // currently not used
51    socket_addr: *const ctypes::sockaddr,
52    addrlen: ctypes::socklen_t,
53) -> ctypes::ssize_t {
54    if socket_addr.is_null() && addrlen == 0 {
55        return e(sys_send(socket_fd, buf_ptr, len, flag) as _) as _;
56    }
57    e(sys_sendto(socket_fd, buf_ptr, len, flag, socket_addr, addrlen) as _) as _
58}
59
60/// Send a message on a socket to the address connected.
61///
62/// Return the number of bytes sent if success.
63#[unsafe(no_mangle)]
64pub unsafe extern "C" fn send(
65    socket_fd: c_int,
66    buf_ptr: *const c_void,
67    len: ctypes::size_t,
68    flag: c_int, // currently not used
69) -> ctypes::ssize_t {
70    e(sys_send(socket_fd, buf_ptr, len, flag) as _) as _
71}
72
73/// Receive a message on a socket and get its source address.
74///
75/// Return the number of bytes received if success.
76#[unsafe(no_mangle)]
77pub unsafe extern "C" fn recvfrom(
78    socket_fd: c_int,
79    buf_ptr: *mut c_void,
80    len: ctypes::size_t,
81    flag: c_int, // currently not used
82    socket_addr: *mut ctypes::sockaddr,
83    addrlen: *mut ctypes::socklen_t,
84) -> ctypes::ssize_t {
85    if socket_addr.is_null() {
86        return e(sys_recv(socket_fd, buf_ptr, len, flag) as _) as _;
87    }
88    e(sys_recvfrom(socket_fd, buf_ptr, len, flag, socket_addr, addrlen) as _) as _
89}
90
91/// Receive a message on a socket.
92///
93/// Return the number of bytes received if success.
94#[unsafe(no_mangle)]
95pub unsafe extern "C" fn recv(
96    socket_fd: c_int,
97    buf_ptr: *mut c_void,
98    len: ctypes::size_t,
99    flag: c_int, // currently not used
100) -> ctypes::ssize_t {
101    e(sys_recv(socket_fd, buf_ptr, len, flag) as _) as _
102}
103
104/// Listen for connections on a socket
105///
106/// Return 0 if success.
107#[unsafe(no_mangle)]
108pub unsafe extern "C" fn listen(
109    socket_fd: c_int,
110    backlog: c_int, // currently not used
111) -> c_int {
112    e(sys_listen(socket_fd, backlog))
113}
114
115/// Accept for connections on a socket
116///
117/// Return file descriptor for the accepted socket if success.
118#[unsafe(no_mangle)]
119pub unsafe extern "C" fn accept(
120    socket_fd: c_int,
121    socket_addr: *mut ctypes::sockaddr,
122    socket_len: *mut ctypes::socklen_t,
123) -> c_int {
124    e(sys_accept(socket_fd, socket_addr, socket_len))
125}
126
127/// Shut down a full-duplex connection.
128///
129/// Return 0 if success.
130#[unsafe(no_mangle)]
131pub unsafe extern "C" fn shutdown(
132    socket_fd: c_int,
133    flag: c_int, // currently not used
134) -> c_int {
135    e(sys_shutdown(socket_fd, flag))
136}
137
138/// Query addresses for a domain name.
139///
140/// Return address number if success.
141#[unsafe(no_mangle)]
142pub unsafe extern "C" fn getaddrinfo(
143    nodename: *const c_char,
144    servname: *const c_char,
145    hints: *const ctypes::addrinfo,
146    res: *mut *mut ctypes::addrinfo,
147) -> c_int {
148    let ret = e(sys_getaddrinfo(nodename, servname, hints, res));
149    match ret {
150        r if r < 0 => ctypes::EAI_FAIL,
151        0 => ctypes::EAI_NONAME,
152        _ => 0,
153    }
154}
155
156/// Free queried `addrinfo` struct
157#[unsafe(no_mangle)]
158pub unsafe extern "C" fn freeaddrinfo(res: *mut ctypes::addrinfo) {
159    sys_freeaddrinfo(res);
160}
161
162/// Get current address to which the socket sockfd is bound.
163#[unsafe(no_mangle)]
164pub unsafe extern "C" fn getsockname(
165    sock_fd: c_int,
166    addr: *mut ctypes::sockaddr,
167    addrlen: *mut ctypes::socklen_t,
168) -> c_int {
169    e(sys_getsockname(sock_fd, addr, addrlen))
170}
171
172/// Get peer address to which the socket sockfd is connected.
173#[unsafe(no_mangle)]
174pub unsafe extern "C" fn getpeername(
175    sock_fd: c_int,
176    addr: *mut ctypes::sockaddr,
177    addrlen: *mut ctypes::socklen_t,
178) -> c_int {
179    e(sys_getpeername(sock_fd, addr, addrlen))
180}