Skip to content

Instantly share code, notes, and snippets.

@shiponcs
Last active May 3, 2023 13:02
Show Gist options
  • Save shiponcs/96e9ca16afb0ff7a1f49eeb1542ef0f6 to your computer and use it in GitHub Desktop.
Save shiponcs/96e9ca16afb0ff7a1f49eeb1542ef0f6 to your computer and use it in GitHub Desktop.
/*
here case1 is always true before case2 (i.e. 1st call of help -> case1 is true, 2nd call of help -> case2 true).
So, in the 2nd call, case2 is true where we're using exp, ctinfoPrev, saddr_m what have been initialized before in case1.
Note: these structures are allocated in module init function which is called when the module is loaded
*/
union nf_inet_addr *saddr_m;
struct sk_buff* skbPrev;
enum ip_conntrack_info ctinfoPrev;
struct nf_conntrack_expect *exp;
static int help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
switch (msgType) {
case case1:
ctinfoPrev = ctinfo;
memcpy((void *)skbPrev, (const void *)skb, sizeof(skb));
skbPrev->next = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL);
skbPrev->prev = (struct sk_buff*) kmalloc(sizeof(struct sk_buff), GFP_KERNEL);
skbPrev->sk = (struct sock*) kmalloc(sizeof(struct sock), GFP_KERNEL);
memcpy((void *)(skbPrev->next), (const void *)skb->next, sizeof(skb->next));
memcpy((void *)(skbPrev->prev), (const void *)skb->prev, sizeof(skb->prev));
memcpy((void *)(skbPrev->sk), (const void *)skb->sk, sizeof(skb->sk));
unsigned int type = (dptr[0] << 8) | dptr[1]; // little endian
unsigned int length = (dptr[2] << 8) | dptr[3];
printk(KERN_INFO "type: %hu length: %hu", type, length);
unsigned int ip;
memcpy(&ip, dptr, 4);
ip = ntohl(ip) ^ MAGIC_COOKIE_VALUE_HOST;
exp = nf_ct_expect_alloc(ct);
if (exp == NULL) {
printk( KERN_INFO "cannot alloc expectation");
return NF_DROP;
}
tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
nf_ct_l3num(ct),
saddr_m, &tuple->dst.u3,
IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);
pr_debug("expect: ");
nf_ct_dump_tuple(&exp->tuple);
break;
case case2:
printk(KERN_INFO "createpermission response\n");
nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
ret = nf_nat_tftp(skbPrev, ctinfoPrev, exp);
else if (nf_ct_expect_related(exp, 0) != 0) {
printk( KERN_INFO "cannot add expectation");
nf_ct_helper_log(skb, ct, "cannot add expectation");
ret = NF_DROP;
}
nf_ct_expect_put(exp);
break;
}
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment