From: Stacey Son <s...@freebsd.org> Definitions of the socket conversion functions.
Add bsd-user/bsd-socket.c, which contains the actual definitions of the socket conversion functions. Signed-off-by: Karim Taha <kariem.taha...@gmail.com> --- bsd-user/bsd-socket.c | 108 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 bsd-user/bsd-socket.c diff --git a/bsd-user/bsd-socket.c b/bsd-user/bsd-socket.c new file mode 100644 index 0000000000..8a5e44444d --- /dev/null +++ b/bsd-user/bsd-socket.c @@ -0,0 +1,108 @@ +/* + * BSD socket system call related helpers + * + * Copyright (c) 2013 Stacey D. Son + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include "qemu/osdep.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netinet/in.h> + +#include "qemu.h" +#include "qemu-bsd.h" + +/* + * socket conversion + */ +abi_long target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, + socklen_t len) +{ + const socklen_t unix_maxlen = sizeof(struct sockaddr_un); + sa_family_t sa_family; + struct target_sockaddr *target_saddr; + + target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); + if (target_saddr == 0) { + return -TARGET_EFAULT; + } + + sa_family = target_saddr->sa_family; + + /* + * Oops. The caller might send a incomplete sun_path; sun_path + * must be terminated by \0 (see the manual page), but unfortunately + * it is quite common to specify sockaddr_un length as + * "strlen(x->sun_path)" while it should be "strlen(...) + 1". We will + * fix that here if needed. + */ + if (target_saddr->sa_family == AF_UNIX) { + if (len < unix_maxlen && len > 0) { + char *cp = (char *)target_saddr; + + if (cp[len - 1] && !cp[len]) { + len++; + } + } + if (len > unix_maxlen) { + len = unix_maxlen; + } + } + + memcpy(addr, target_saddr, len); + addr->sa_family = sa_family; /* type uint8_t */ + addr->sa_len = target_saddr->sa_len; /* type uint8_t */ + unlock_user(target_saddr, target_addr, 0); + + return 0; +} + +abi_long host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr, + socklen_t len) +{ + struct target_sockaddr *target_saddr; + + target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0); + if (target_saddr == 0) { + return -TARGET_EFAULT; + } + memcpy(target_saddr, addr, len); + target_saddr->sa_family = addr->sa_family; /* type uint8_t */ + target_saddr->sa_len = addr->sa_len; /* type uint8_t */ + unlock_user(target_saddr, target_addr, len); + + return 0; +} + +abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, abi_ulong target_addr, + socklen_t len) +{ + struct target_ip_mreqn *target_smreqn; + + target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1); + if (target_smreqn == 0) { + return -TARGET_EFAULT; + } + mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr; + mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr; + if (len == sizeof(struct target_ip_mreqn)) { + mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex); + } + unlock_user(target_smreqn, target_addr, 0); + + return 0; +} -- 2.40.0