Permalink
Browse files

Kernel 3.X support (#3)

* adding recieve support for 3.X

* adding versioning for sock_recvmsg

* Adding hook wrapper to adapt to mainline differences

* making ksocket_recieve more portable with kernel_recvmsg

* typo
  • Loading branch information...
landhb committed Oct 8, 2018
1 parent ab44eb5 commit 5a4a9620ccdde89fb6c6e86db61cc75d1d565f7d
Showing with 87 additions and 24 deletions.
  1. +53 −4 kernel/xt_hook.c
  2. +34 −20 kernel/xt_listen.c
@@ -92,7 +92,7 @@ static unsigned int conn_state_check(int type, __be32 src, struct in6_addr * src
return NF_ACCEPT;
}

static unsigned int pkt_hook_v6(void * priv, struct sk_buff * skb, const struct nf_hook_state * state) {
static unsigned int pkt_hook_v6(struct sk_buff * skb) {

struct tcphdr * tcp_header;
struct udphdr * udp_header;
@@ -126,7 +126,7 @@ static unsigned int pkt_hook_v6(void * priv, struct sk_buff * skb, const struct
}


static unsigned int pkt_hook_v4(void * priv, struct sk_buff * skb, const struct nf_hook_state * state) {
static unsigned int pkt_hook_v4(struct sk_buff * skb) {

struct tcphdr * tcp_header;
struct udphdr * udp_header;
@@ -160,20 +160,69 @@ static unsigned int pkt_hook_v4(void * priv, struct sk_buff * skb, const struct
}


// Version specific callbacks
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
static unsigned int hook_wrapper_v4(void * priv, struct sk_buff * skb, const struct nf_hook_state * state) {
return pkt_hook_v4(skb);
}
static unsigned int hook_wrapper_v6(void * priv, struct sk_buff * skb, const struct nf_hook_state * state) {
return pkt_hook_v6(skb);
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
static unsigned int hook_wrapper_v4(const struct nf_hook_ops *ops,struct sk_buff *skb, const struct nf_hook_state *state) {
return pkt_hook_v4(skb);
}
static unsigned int hook_wrapper_v6(const struct nf_hook_ops *ops,struct sk_buff *skb, const struct nf_hook_state *state) {
return pkt_hook_v6(skb);
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)
static unsigned int hook_wrapper_v4(const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
return pkt_hook_v4(skb);
}
static unsigned int hook_wrapper_v6(const struct nf_hook_ops *ops,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
return pkt_hook_v6(skb);
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
static unsigned int hook_wrapper_v4(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
return pkt_hook_v4(skb);
}
static unsigned int hook_wrapper_v6(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
return pkt_hook_v6(skb);
}
#else
#error "Unsuported kernel version. Only Linux 3.X and greater."
#endif


static struct nf_hook_ops pkt_hook_ops __read_mostly = {
.pf = NFPROTO_IPV4,
.priority = NF_IP_PRI_FIRST,
.hooknum = NF_INET_LOCAL_IN,
.hook = &pkt_hook_v4,
.hook = &hook_wrapper_v4,
};


static struct nf_hook_ops pkt_hook_ops_v6 __read_mostly = {
.pf = NFPROTO_IPV6,
.priority = NF_IP_PRI_FIRST,
.hooknum = NF_INET_LOCAL_IN,
.hook = &pkt_hook_v6,
.hook = &hook_wrapper_v6,
};


@@ -12,6 +12,7 @@
#include <linux/wait.h> // DECLARE_WAITQUEUE
#include <linux/filter.h>
#include <linux/uio.h> // iov_iter
#include <linux/version.h>
#include "drawbridge.h"
#include "key.h"

@@ -85,29 +86,33 @@ void inet6_ntoa(char * str_ip, struct in6_addr * src_6)
static int ksocket_receive(struct socket* sock, struct sockaddr_in* addr, unsigned char* buf, int len)
{
struct msghdr msg;
mm_segment_t oldfs;
int size = 0;
struct iovec iov;
struct kvec iov;

if (sock->sk == NULL) return 0;
if (sock->sk == NULL) {
return 0;
}

iov.iov_base=buf;
iov.iov_len=len;


msg.msg_flags = MSG_DONTWAIT;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0)
msg.msg_iocb = NULL;
iov_iter_init(&msg.msg_iter, WRITE, (struct iovec *)&iov, 1, len);
#else
msg.msg_iov = &iov;
msg.msg_iovlen = len;
#endif

iov_iter_init(&msg.msg_iter, WRITE, &iov, 1, len);

oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_recvmsg(sock,&msg,msg.msg_flags);
set_fs(oldfs);
// https://github.com/torvalds/linux/commit/2da62906b1e298695e1bb725927041cd59942c98
// switching to kernel_recvmsg because it's more consistent across versions
// https://elixir.bootlin.com/linux/v4.6/source/net/socket.c#L741
size = kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);

return size;
}
@@ -119,6 +124,17 @@ static inline void hexdump(unsigned char *buf,unsigned int len) {
printk("\n");
}

static void free_signature(pkey_signature * sig) {
if(sig->s) {
kfree(sig->s);
}
if(sig->digest) {
kfree(sig->digest);
}
kfree(sig);
}


// Pointer arithmatic to parse out the signature and digest
static pkey_signature * get_signature(void * pkt, u32 offset) {

@@ -130,6 +146,7 @@ static pkey_signature * get_signature(void * pkt, u32 offset) {

// Sanity check the sig size
if(sig->s_size > MAX_SIG_SIZE || sig->s_size < 0) {
kfree(sig);
return NULL;
}

@@ -144,6 +161,8 @@ static pkey_signature * get_signature(void * pkt, u32 offset) {

// Sanity check the digest size
if(sig->digest_size > MAX_DIGEST_SIZE || sig->digest_size < 0) {
kfree(sig->s);
kfree(sig);
return NULL;
}

@@ -156,15 +175,6 @@ static pkey_signature * get_signature(void * pkt, u32 offset) {

}

static void free_signature(pkey_signature * sig) {
if(sig->s) {
kfree(sig->s);
}
if(sig->digest) {
kfree(sig->digest);
}
kfree(sig);
}

// Callback function for the reaper: removes expired connections
void reap_expired_connections(unsigned long timeout) {
@@ -214,7 +224,6 @@ int listen(void * data) {
// Socket info
struct socket * sock;
struct sockaddr_in source;

struct timespec tm;

// Buffers
@@ -362,6 +371,11 @@ int listen(void * data) {
offset += sizeof(struct udphdr) + sizeof(struct packet);
}
}
else {
// unsupported protocol
continue;
}


// Process packet
res = (struct packet *)(pkt + offset - sizeof(struct packet));

0 comments on commit 5a4a962

Please sign in to comment.