ff_syscall_wrapper.c: add linux_cmsghdr and its support in recvmsg

add support for IP_RECVTTL and IP_RECVTOS
This commit is contained in:
Fidaullah Noonari 2022-04-22 11:22:44 +05:00
parent fb4e62428e
commit 584a11ee03
1 changed files with 63 additions and 0 deletions

View File

@ -88,6 +88,8 @@
#define LINUX_IP_TTL 2
#define LINUX_IP_HDRINCL 3
#define LINUX_IP_OPTIONS 4
#define LINUX_IP_RECVTTL 12
#define LINUX_IP_RECVTOS 13
#define LINUX_IP_MULTICAST_IF 32
#define LINUX_IP_MULTICAST_TTL 33
@ -198,6 +200,21 @@ struct linux_msghdr {
/* msghdr define end */
/* cmsghdr define start */
struct linux_cmsghdr
{
size_t cmsg_len; /* Length of data in cmsg_data plus length
of cmsghdr structure.
!! The type should be socklen_t but the
definition of the kernel is incompatible
with this. */
int cmsg_level; /* Originating protocol. */
int cmsg_type; /* Protocol specific type. */
};
/* cmsghdr define end */
extern int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
static long
@ -382,6 +399,10 @@ ip_opt_convert(int optname)
return IP_ADD_MEMBERSHIP;
case LINUX_IP_DROP_MEMBERSHIP:
return IP_DROP_MEMBERSHIP;
case LINUX_IP_RECVTTL:
return IP_RECVTTL;
case LINUX_IP_RECVTOS:
return IP_RECVTOS;
default:
return optname;
}
@ -423,6 +444,43 @@ tcp_opt_convert(int optname)
}
}
static int
ip_opt_convert2linux(int optname)
{
switch(optname) {
case IP_RECVTTL:
return LINUX_IP_TTL; // in linux kernel return IP_TTL not IP_RECVTTL
case IP_RECVTOS:
return LINUX_IP_TOS; // in linux kernel return IP_TOS not IP_RECVTOS
default:
return optname;
}
}
static void
freebsd2linux_cmsghdr(struct linux_msghdr *linux_msg)
{
struct cmsghdr *cmsg;
cmsg = CMSG_FIRSTHDR(linux_msg);
struct linux_cmsghdr *linux_cmsg = (struct linux_cmsghdr*)cmsg;
// for multiple cmsghdrs implement for loop
// for (; cmsg; cmsg = CMSG_NXTHDR(linux_msg, cmsg))
// {
switch (cmsg->cmsg_level)
{
case IPPROTO_IP:
linux_cmsg->cmsg_type = ip_opt_convert2linux(cmsg->cmsg_type);
break;
default:
break;
}
linux_cmsg->cmsg_level = cmsg->cmsg_level;
linux_cmsg->cmsg_len = cmsg->cmsg_len;
// }
}
static int
linux2freebsd_opt(int level, int optname)
{
@ -869,6 +927,11 @@ ff_recvmsg(int s, struct msghdr *msg, int flags)
linux_msg->msg_flags = msg->msg_flags;
msg->msg_flags = 0;
if(msg->msg_control)
{
freebsd2linux_cmsghdr(linux_msg);
}
return (rc);
kern_fail:
ff_os_errno(rc);