From 584a11ee038edf198532d3fdab1bf78398efcdb8 Mon Sep 17 00:00:00 2001 From: Fidaullah Noonari Date: Fri, 22 Apr 2022 11:22:44 +0500 Subject: [PATCH] ff_syscall_wrapper.c: add linux_cmsghdr and its support in recvmsg add support for IP_RECVTTL and IP_RECVTOS --- lib/ff_syscall_wrapper.c | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/lib/ff_syscall_wrapper.c b/lib/ff_syscall_wrapper.c index 7cf4698e7..0d07d7b8c 100644 --- a/lib/ff_syscall_wrapper.c +++ b/lib/ff_syscall_wrapper.c @@ -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);