This patch fix ping issues for linux-user guest. * The do_setsockopts function in linux-user does not support SOL_RAW socket which is used in ping net tool.
* The recvmsg in main_loop of ping could not fetch sockaddr_in struct. That is because do_sendrecvmsg in linux-user does not pass the msg->msg_name to the target. We fix the above issues. Signed-off-by: Jing Huang <jing.huang....@gmail.com> --- syscall.c | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletions(-) diff -git a/linux-user/syscall.c b/linux-user/syscall.c index 5346554..3343345 e43f56 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1349,7 +1349,13 @@target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len)); if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { - gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); + if(cmsg->cmsg_type == SO_TIMESTAMP) { + /*copy msg_name to target_msgh*/ + target_msgh->msg_namelen = msgh->msg_namelen; + memcpy(g2h((void *)(unsigned long)(target_ulong)target_msgh->msg_name), msgh->msg_name, msgh->msg_namelen); + } else { + gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); + } memcpy(target_data, data, len); } else { int *fd = (int *)data; @@ -1442,6 +1448,23 @@ goto unimplemented; } break; + case SOL_RAW: + switch (optname) { +#define ICMP_FILTER 1 + case ICMP_FILTER: + /*struct icmp_filter takes an u32 value*/ + optname = ICMP_FILTER; + if (optlen < sizeof(uint32_t)) + return -TARGET_EINVAL; + + if (get_user_u32(val, optval_addr)) + return -TARGET_EFAULT; + ret = get_errno(setsockopt(sockfd, level, optname, (char *)&val, sizeof(val))); + break; + default: + goto unimplemented; + } + break; case TARGET_SOL_SOCKET: switch (optname) { /* Options with 'int' argument. */