Skip to content
Open
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
28 changes: 22 additions & 6 deletions forge_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ int inet_forge_listen(struct socket *sock, int backlog)
return err;
}


int __init forge_init(void)
{
int rc = -EINVAL;
Expand All @@ -104,6 +103,7 @@ int __init forge_init(void)
forge_prot.getsockopt = forge_getsockopt;
forge_prot.setsockopt = forge_setsockopt;


/* proto_register will only alloc twsk_prot and rsk_prot if they are
null no sense in allocing more space - we can just use TCP's, since
we are effecitvely just a TCP socket
Expand Down Expand Up @@ -190,8 +190,13 @@ int forge_getsockopt(struct sock *sk, int level, int optname,
}
EXPORT_SYMBOL(forge_getsockopt);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 1)
int forge_setsockopt(struct sock *sk, int level, int optname,
sockptr_t optval, unsigned int optlen)
#else
int forge_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen)
#endif
{
if (optname == TCP_STATE) {
struct tcp_state st;
Expand All @@ -201,8 +206,12 @@ int forge_setsockopt(struct sock *sk, int level, int optname,
if (!capable(CAP_NET_RAW))
return -EACCES;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 1)
if (copy_from_sockptr(&st, optval, sizeof(st)))
#else
if (copy_from_user(&st, (struct tcp_state __user *)optval,
sizeof(st)))
sizeof(st)))
#endif
return -EFAULT;

/* from syn_recv: */
Expand All @@ -224,7 +233,7 @@ int forge_setsockopt(struct sock *sk, int level, int optname,
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
inet_sk(sk)->opt = NULL; /* TODO: support Ip options */
#else
inet_sk(sk)->inet_opt = NULL;
inet_sk(sk)->inet_opt = NULL;
#endif

inet_sk(sk)->mc_ttl = 1; /* TODO: add multicast support */
Expand Down Expand Up @@ -265,7 +274,7 @@ int forge_setsockopt(struct sock *sk, int level, int optname,


#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
tcp_prequeue_init(tp);
tcp_prequeue_init(tp);
tp->srtt = 0;
tp->mdev = TCP_TIMEOUT_INIT;
#else
Expand Down Expand Up @@ -322,7 +331,11 @@ int forge_setsockopt(struct sock *sk, int level, int optname,

if (tp->rx_opt.tstamp_ok) {
tp->rx_opt.ts_recent = st.ts_recent;
tp->rx_opt.ts_recent_stamp = get_seconds();
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 1)
tp->rx_opt.ts_recent_stamp = ktime_get_seconds();
#else
tp->rx_opt.ts_recent_stamp = get_seconds();
#endif
/* We want get_seconds() + ts_offset == st->ts_val.
*/
//tp->rx_opt.ts_offset = st->ts_val - tcp_time_stamp;
Expand Down Expand Up @@ -382,7 +395,9 @@ int forge_setsockopt(struct sock *sk, int level, int optname,
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
__inet_hash_nolisten(sk, NULL);
#else
inet_ehash_nolisten(sk, NULL);
// bool inet_ehash_nolisten(struct sock *sk,
// struct sock *osk, bool *found_dup_sk)
inet_ehash_nolisten(sk, NULL, NULL);
#endif

/* uc_ttl is at least as old as 2.6.17, maybe older.
Expand Down Expand Up @@ -412,6 +427,7 @@ int forge_setsockopt(struct sock *sk, int level, int optname,

return 0;
}

return tcp_setsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(forge_setsockopt);
Expand Down
5 changes: 5 additions & 0 deletions forge_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ struct tcp_state {


#ifdef __KERNEL__
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 1)
int forge_setsockopt(struct sock *sk, int level, int optname,
sockptr_t optval, unsigned int optlen);
#else
int forge_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, unsigned int optlen);
#endif
int forge_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
int forge_getsockopt_socket(struct socket *sock, int level, int optname,
Expand Down