mirror of https://gitee.com/openkylin/qemu.git
linux-user: Added IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP flags to setsockopt
linux-user: Added IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP flags to setsockopt Signed-off-by: Lionel Landwerlin <lionel.landwerlin@openwide.fr> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
This commit is contained in:
parent
6f932f9172
commit
b975b83bec
|
@ -943,6 +943,24 @@ static abi_long do_select(int n,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline 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)
|
||||||
|
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 = tswapl(target_smreqn->imr_ifindex);
|
||||||
|
unlock_user(target_smreqn, target_addr, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
|
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
|
||||||
abi_ulong target_addr,
|
abi_ulong target_addr,
|
||||||
socklen_t len)
|
socklen_t len)
|
||||||
|
@ -1118,6 +1136,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||||
{
|
{
|
||||||
abi_long ret;
|
abi_long ret;
|
||||||
int val;
|
int val;
|
||||||
|
struct ip_mreqn *ip_mreq;
|
||||||
|
|
||||||
switch(level) {
|
switch(level) {
|
||||||
case SOL_TCP:
|
case SOL_TCP:
|
||||||
|
@ -1156,6 +1175,17 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||||
}
|
}
|
||||||
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
|
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
|
||||||
break;
|
break;
|
||||||
|
case IP_ADD_MEMBERSHIP:
|
||||||
|
case IP_DROP_MEMBERSHIP:
|
||||||
|
if (optlen < sizeof (struct target_ip_mreq) ||
|
||||||
|
optlen > sizeof (struct target_ip_mreqn))
|
||||||
|
return -TARGET_EINVAL;
|
||||||
|
|
||||||
|
ip_mreq = (struct ip_mreqn *) alloca(optlen);
|
||||||
|
target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
|
||||||
|
ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto unimplemented;
|
goto unimplemented;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,21 @@ struct target_sockaddr {
|
||||||
uint8_t sa_data[14];
|
uint8_t sa_data[14];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct target_in_addr {
|
||||||
|
uint32_t s_addr; /* big endian */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct target_ip_mreq {
|
||||||
|
struct target_in_addr imr_multiaddr;
|
||||||
|
struct target_in_addr imr_address;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct target_ip_mreqn {
|
||||||
|
struct target_in_addr imr_multiaddr;
|
||||||
|
struct target_in_addr imr_address;
|
||||||
|
abi_long imr_ifindex;
|
||||||
|
};
|
||||||
|
|
||||||
struct target_timeval {
|
struct target_timeval {
|
||||||
abi_long tv_sec;
|
abi_long tv_sec;
|
||||||
abi_long tv_usec;
|
abi_long tv_usec;
|
||||||
|
|
Loading…
Reference in New Issue