Created
November 21, 2014 10:12
-
-
Save kevinz/77325087b1a61da12240 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//’Hello World’ v2 netfilter hooks example | |
//For any packet, get the ip header and check the protocol field | |
//if the protocol number equal to UDP (17), log in var/log/messages | |
//default action of module to let all packets through | |
#include <linux/kernel.h> | |
#include <linux/module.h> | |
#include <linux/netfilter.h> | |
#include <linux/netfilter_ipv4.h> | |
#include <linux/skbuff.h> | |
#include <linux/udp.h> | |
#include <linux/ip.h> | |
#include <linux/tcp.h> | |
#include <net/tcp.h> | |
static struct nf_hook_ops nfho; //net filter hook option struct | |
static struct nf_hook_ops nfho_; //net filter hook option struct | |
static unsigned int shift_bits = 4; | |
static unsigned int ts_id= 1; | |
unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) | |
{ | |
struct iphdr *iph = ip_hdr(skb); | |
struct tcphdr *hdr; | |
unsigned int hdroff = iph->ihl*4; | |
int datalen = skb->len - hdroff; | |
int hdrsize = 8; /* TCP connection tracking guarantees this much */ | |
const unsigned char *ptr; | |
unsigned char buff[(15 * 4) - sizeof(struct tcphdr)]; | |
int length; | |
int recalc = 0; | |
//printk(KERN_DEBUG "+++index=%d %pI4 -> %pI4 :\n", out->ifindex,&iph->saddr, &iph->daddr); | |
if (iph->protocol != IPPROTO_TCP) { | |
return NF_ACCEPT; | |
} | |
if(out->ifindex!=4) | |
return NF_ACCEPT; | |
hdr = (struct tcphdr *)(skb->data + hdroff); | |
if (skb->len >= hdroff + sizeof(struct tcphdr)) | |
hdrsize = sizeof(struct tcphdr); | |
if (!skb_make_writable(skb, hdroff + hdrsize)) | |
return NF_ACCEPT; | |
length = (hdr->doff*4) - sizeof(struct tcphdr); | |
ptr = skb_header_pointer(skb, sizeof(struct tcphdr) + hdroff, | |
length, buff); | |
while (length > 0) { | |
int opcode=*ptr++; | |
int opsize; | |
switch (opcode) { | |
case TCPOPT_EOL: | |
return NF_ACCEPT; | |
case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ | |
length--; | |
continue; | |
case TCPOPT_TIMESTAMP: | |
{ | |
int i = 0; | |
char *base = ptr-1; | |
opsize=*ptr; | |
// printk(KERN_DEBUG "+++%pI4 -> %pI4 datalen=%d jiffies=%u ntohl(jiffies)=%u:", &iph->saddr, &iph->daddr, datalen, jiffies, ntohl(jiffies)); | |
unsigned int * tsp = (unsigned int *)(base+2); | |
unsigned int ts = ntohl(*tsp); | |
// unsigned int ts_echo = ntohl(*(unsigned int *)(base+6)); | |
ts = (ts << shift_bits) + ts_id; | |
printk(KERN_DEBUG "+++%pI4 -> %pI4,before ts=%u,after jiffies =%u ntohl(jiffies)=%u ts=%u===\n",&iph->saddr, &iph->daddr,ntohl(*tsp),jiffies,ntohl(jiffies),ts); | |
*tsp = htonl(ts); | |
recalc = 1; | |
} | |
default: | |
opsize=*ptr++; | |
length -= opsize; | |
ptr += opsize - 2; | |
} | |
} | |
if (recalc) { | |
// hdr->check = 0; | |
// hdr->check = tcp_v4_check(datalen,iph->saddr, iph->daddr, csum_partial(hdr,datalen, 0)); | |
// ip_send_check(iph); | |
// tcp_v4_send_check(skb->sk,skb); | |
// hdr->check = 0; | |
/* | |
hdr->check = tcp_v4_check(datalen, | |
iph->saddr, iph->daddr, | |
csum_partial(hdr, | |
datalen, 0)); | |
*/ | |
// skb->ip_summed = CHECKSUM_NONE; //stop offloading | |
skb->ip_summed == CHECKSUM_COMPLETE; | |
} | |
return NF_ACCEPT; | |
} | |
unsigned int hook_func_pre(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) | |
{ | |
struct iphdr *iph = (struct iphdr *)(skb->data); | |
struct tcphdr *hdr; | |
unsigned int hdroff = iph->ihl*4; | |
int datalen = skb->len - hdroff; | |
int hdrsize = 8; /* TCP connection tracking guarantees this much */ | |
const unsigned char *ptr; | |
unsigned char buff[(15 * 4) - sizeof(struct tcphdr)]; | |
int length; | |
int recalc = 0; | |
if (iph->protocol != IPPROTO_TCP) { | |
return NF_ACCEPT; | |
} | |
//printk(KERN_DEBUG "---index=%d %pI4 -> %pI4 :\n", in->ifindex,&iph->saddr, &iph->daddr); | |
if(in->ifindex!=4) | |
return NF_ACCEPT; | |
hdr = (struct tcphdr *)(skb->data + hdroff); | |
if (skb->len >= hdroff + sizeof(struct tcphdr)) | |
hdrsize = sizeof(struct tcphdr); | |
if (!skb_make_writable(skb, hdroff + hdrsize)) | |
return NF_ACCEPT; | |
length = (hdr->doff*4) - sizeof(struct tcphdr); | |
ptr = skb_header_pointer(skb, sizeof(struct tcphdr) + hdroff, | |
length, buff); | |
while (length > 0) { | |
int opcode=*ptr++; | |
int opsize; | |
switch (opcode) { | |
case TCPOPT_EOL: | |
return NF_ACCEPT; | |
case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ | |
length--; | |
continue; | |
case TCPOPT_TIMESTAMP: | |
{ | |
int i = 0; | |
char *base = ptr-1; | |
opsize=*ptr; | |
unsigned int ts = ntohl(*(unsigned int *)(base+2)); | |
unsigned int * tse= (unsigned int *)(base+6); | |
unsigned int ts_echo = ntohl(*tse); | |
if(ts_echo){ | |
ts_echo = ts_echo - ts_id; | |
unsigned int high = (jiffies & 0xf0000000); | |
ts_echo = (ts_echo >> shift_bits)|high; | |
printk(KERN_DEBUG "---%pI4 -> %pI4 before ts_echo=%u,after high =%u ts_echo=%u===\n",&iph->saddr, &iph->daddr,ntohl(*tse),high,ts_echo); | |
*tse = htonl(ts_echo); | |
recalc = 1; | |
} | |
} | |
default: | |
opsize=*ptr++; | |
length -= opsize; | |
ptr += opsize - 2; | |
} | |
} | |
if (recalc) { | |
/* | |
hdr->check = 0; | |
hdr->check = tcp_v4_check(datalen, | |
iph->saddr, iph->daddr, | |
csum_partial(hdr, | |
datalen, 0)); | |
*/ | |
skb->ip_summed == CHECKSUM_COMPLETE; | |
// iph->check=0; | |
// iph->check = ip_fast_csum((u8 *)iph, iph->ihl); | |
// ip_send_check(iph); | |
// tcp_v4_send_check(skb->sk,skb); | |
} | |
return NF_ACCEPT; | |
} | |
int init_hack() | |
{ | |
printk(KERN_DEBUG " hackts init.\n"); | |
nfho.hook = hook_func; | |
nfho.hooknum = NF_INET_POST_ROUTING; | |
nfho.pf = PF_INET; | |
nfho.priority = NF_IP_PRI_FIRST; | |
nfho_.hook = hook_func_pre; | |
nfho_.hooknum = NF_INET_PRE_ROUTING; | |
nfho_.pf = PF_INET; | |
nfho_.priority = NF_IP_PRI_FIRST; | |
nf_register_hook(&nfho); | |
nf_register_hook(&nfho_); | |
printk(KERN_DEBUG " hackts init finished.\n"); | |
return 0; | |
} | |
void cleanup_hack() | |
{ | |
nf_unregister_hook(&nfho); | |
nf_unregister_hook(&nfho_); | |
} | |
module_init( init_hack); | |
module_exit( cleanup_hack); | |
MODULE_LICENSE("GPL"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment