Skip to content

Implement SIOCGETSGCNT_IN6 ioctl #3615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/kernel_abi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <linux/if_bonding.h>
#include <linux/ipc.h>
#include <linux/mqueue.h>
#include <linux/mroute.h>
#include <linux/mroute6.h>
#include <linux/msg.h>
#include <linux/net.h>
#include <linux/netfilter/x_tables.h>
Expand Down
42 changes: 42 additions & 0 deletions src/kernel_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,12 +525,36 @@ struct BaseArch : public wordsize,
ptr<void> sival_ptr;
};

struct in_addr {
uint32_t s_addr;
};
RR_VERIFY_TYPE(in_addr);

struct in6_addr {
union {
/* don't call these s6_addrX - those are macros */
uint8_t addr8[16];
uint16_t addr16[8];
uint32_t addr32[4];
};
};
RR_VERIFY_TYPE(in_addr);

struct sockaddr {
unsigned_short sa_family;
char sa_data[14];
};
RR_VERIFY_TYPE(sockaddr);

struct sockaddr_in6 {
unsigned_short sin6_family;
unsigned_short sin6_port;
uint32_t sin6_flowinfo;
in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
RR_VERIFY_TYPE(sockaddr_in6);

struct sockaddr_storage {
char sa_data[128];
};
Expand Down Expand Up @@ -1049,6 +1073,24 @@ struct BaseArch : public wordsize,
};
RR_VERIFY_TYPE(iwreq);

struct sioc_sg_req {
in_addr src;
in_addr grp;
unsigned long pktcnt;
unsigned long bytecnt;
unsigned long wrong_if;
};
RR_VERIFY_TYPE(sioc_sg_req);

struct sioc_sg_req6 {
sockaddr_in6 src;
sockaddr_in6 grp;
unsigned long pktcnt;
unsigned long bytecnt;
unsigned long wrong_if;
};
RR_VERIFY_TYPE(sioc_sg_req6);

struct _flock {
signed_short l_type;
signed_short l_whence;
Expand Down
18 changes: 18 additions & 0 deletions src/record_syscall.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <linux/ipc.h>
#include <linux/joystick.h>
#include <linux/kd.h>
#include <linux/mroute.h>
#include <linux/mroute6.h>
#include <linux/msdos_fs.h>
#include <linux/msg.h>
#include <linux/net.h>
Expand Down Expand Up @@ -1718,6 +1720,22 @@ static Switchable prepare_ioctl(RecordTask* t,
syscall_state.after_syscall_action(record_page_below_stack_ptr);
return PREVENT_SWITCH;

#if 0
/* TODO: the IPv4 and IPv6 variants of this ioctl have the same value.
* (SIOCPROTOPRIVATE+1) - and there are other uses of this in other
* protocols. So this probably needs a dispatch by fd socket type :(
*/
case SIOCGETSGCNT:
syscall_state.reg_parameter<typename Arch::sioc_sg_req>(3);
syscall_state.after_syscall_action(record_page_below_stack_ptr);
return PREVENT_SWITCH;
#endif

case SIOCGETSGCNT_IN6:
syscall_state.reg_parameter<typename Arch::sioc_sg_req6>(3);
syscall_state.after_syscall_action(record_page_below_stack_ptr);
return PREVENT_SWITCH;

// https://github.com/torvalds/linux/blob/254ec036db1123b10e23e1412c191a3cf70dce71/net/bridge/br_ioctl.c#L316-L369
case SIOCGIFBR: {
auto params = syscall_state.reg_parameter<unsigned long>(3, IN);
Expand Down