/* recursively invokes nf_hook_slow (again), skipping already-called * hooks (< NF_BR_PRI_BRNF). * * Called with rcu read lock held. */ int br_nf_hook_thresh(unsigned int hook, struct net *net, struct sock *sk, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct net *, struct sock *, struct sk_buff *)) { struct nf_hook_entry *elem; struct nf_hook_state state; int ret; for (elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]); elem && nf_hook_entry_priority(elem) <= NF_BR_PRI_BRNF; elem = rcu_dereference(elem->next)) ; if (!elem) return okfn(net, sk, skb); /* We may already have this, but read-locks nest anyway */ rcu_read_lock(); nf_hook_state_init(&state, hook, NFPROTO_BRIDGE, indev, outdev, sk, net, okfn); ret = nf_hook_slow(skb, &state, elem); rcu_read_unlock(); if (ret == 1) ret = okfn(net, sk, skb); return ret; }
/* recursively invokes nf_hook_slow (again), skipping already-called * hooks (< NF_BR_PRI_BRNF). * * Called with rcu read lock held. */ int br_nf_hook_thresh(unsigned int hook, struct net *net, struct sock *sk, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct net *, struct sock *, struct sk_buff *)) { const struct nf_hook_entries *e; struct nf_hook_state state; struct nf_hook_ops **ops; unsigned int i; int ret; e = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]); if (!e) return okfn(net, sk, skb); ops = nf_hook_entries_get_hook_ops(e); for (i = 0; i < e->num_hook_entries && ops[i]->priority <= NF_BR_PRI_BRNF; i++) ; nf_hook_state_init(&state, hook, NFPROTO_BRIDGE, indev, outdev, sk, net, okfn); ret = nf_hook_slow(skb, &state, e, i); if (ret == 1) ret = okfn(net, sk, skb); return ret; }
s32 ns_ipv4_pre_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ns_ipv4_defrag(NS_IP_PRE_ROUTING, &skb, okfn); NS_CHECK_RET(verdict, ret, end_pre_routing, skb); verdict = g_ns_callback_func.attack_proc(NS_IP_PRE_ROUTING, &skb, in, out, okfn); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); verdict = ip_ns_in(in, pf, NS_IP_PRE_ROUTING, skb); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); verdict = ns_nat_in(NS_IP_PRE_ROUTING, &skb, in, out, okfn); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); verdict = g_ns_callback_func.ddos_and_scan_attack(NS_IP_PRE_ROUTING, &skb, in, out, okfn); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); verdict = ns_nat46(skb, in, out, okfn); NS_CHECK_RET(verdict, ret ,end_pre_routing, skb); verdict = ns_6rd_v4(skb); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); end_pre_routing: if (1 == ret) ret = okfn(skb); return ret; }
s32 ns_ipv4_post_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ns_nat_out(NS_IP_POST_ROUTING, &skb, in, out, okfn); NS_CHECK_RET(verdict,ret,end_post_routing,skb); verdict = ipv4_ns_help(NS_IP_POST_ROUTING, skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); verdict = ns_nat_adjust(skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); verdict = ns_confirm(skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); verdict = ns_ds_lite_ipv4_proc(skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); end_post_routing: if (1 == ret) ret = okfn(skb); return ret; }
s32 ns_ipv6_pre_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; if (pf & NS_DEFRAG) { pf &= ~(NS_DEFRAG); goto after_defrag; } verdict = ns_ipv6_defrag(NS_IP6_PRE_ROUTING, pf, &skb, in, out, okfn); NS_CHECK_RET(verdict, ret, end_pre_routing, skb); after_defrag: verdict = __ip6_ns_in(in, pf, NS_IP_PRE_ROUTING, skb); NS_CHECK_RET(verdict, ret, end_pre_routing, skb); verdict = ns_nat64(skb, in, out, okfn); NS_CHECK_RET(verdict, ret, end_pre_routing, skb); verdict = ns_ds_lite_ipv6_proc(skb); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); end_pre_routing: if (1 == ret) { ret = okfn(skb); } return ret; }
s32 ns_ipv6_local_out(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; if (pf & NS_DEFRAG) { pf &= ~(NS_DEFRAG); goto after_defrag; } verdict = ns_ipv6_defrag(NS_IP6_LOCAL_OUT, pf, &skb, in, out, okfn); NS_CHECK_RET(verdict, ret, end_local_out, skb); after_defrag: verdict = ns_local_search(if_dev_vrf(out), pf, skb, NULL); NS_CHECK_RET(verdict,ret,end_local_out,skb); verdict = __ip6_ns_in(out, pf, NS_IP_LOCAL_OUT, skb); NS_CHECK_RET(verdict,ret,end_local_out,skb); verdict = ns_local_setbit(skb, pf); NS_CHECK_RET(verdict,ret,end_local_out,skb); end_local_out: if (1 == ret) ret = okfn(skb); return ret; }
s32 ns_ipv4_local_out(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ns_ipv4_defrag( NS_IP_LOCAL_OUT, &skb, okfn); NS_CHECK_RET(verdict,ret,end_local_out,skb); verdict = ns_local_search(if_dev_vrf(out), pf, skb, NULL); NS_CHECK_RET(verdict,ret,end_local_out,skb); verdict = ip_ns_in(out, pf, NS_IP_LOCAL_OUT, skb); NS_CHECK_RET(verdict,ret,end_local_out,skb); verdict = ns_local_setbit(skb,pf); NS_CHECK_RET(verdict,ret,end_local_out,skb); end_local_out: if (1 == ret) ret = okfn(skb); return ret; }
s32 netmode_ipredir_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { int (*okfn)(struct sk_buff *) = NULL; (void)dev; (void)pt; (void)orig_dev; if(CONPLAT_SKB_DELIVER_UP == skb->ucpktflag) { skb->ucpktflag = 0; okfn = skb->contfunc; if(okfn) { ckdc_counter_inc(nm,ip_local_redir_rx); okfn(skb); } else { kfree_skb(skb); } return 1; } if(netmode_is_need_cap(skb, dev)) { return 1; } if(CONPLAT_SKB_FROM_LOCAL > skb->ucpktflag) { return 0; } ckdc_counter_inc(nm,count_ipredir_rx); if(CONPLAT_BR_SKB_FROM_LOCAL == skb->ucpktflag) { okfn = skb->contfunc; if(NF_STOLEN != netmode_bridge_rcv(NF_BR_PRE_ROUTING, &skb, skb->dev, NULL, okfn)) { return 0; } } if ( CONPLAT_BR_INLINE_SKB_FROM_LOCAL == skb->ucpktflag) { okfn = skb->contfunc; if(NF_STOLEN != netmode_br_transparent_rcv(NF_BR_PRE_ROUTING, &skb, skb->dev, NULL, okfn)) { return 0; } } skb->pkt_type = 0; return 1; }
s32 ns_ipv6_local_in(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ns_confirm(skb); NS_CHECK_RET(verdict,ret,end_local_in,skb); end_local_in: if (1 == ret) ret = okfn(skb); return ret; }
s32 ns_vlan6_pre_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ip_ns_in(in, pf, NS_VLAN6_PRE_ROUTING, skb); NS_CHECK_RET(verdict,ret,end_pre_routing,skb); end_pre_routing: if (1 == ret) ret = okfn(skb); return ret; }
s32 ns_vlan6_post_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ns_confirm(skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); end_post_routing: if (1 == ret) ret = okfn(skb); return ret; }
/* 下面是五条链走的流程的函数 */ s32 ipv6_pre_routing_defrag(struct sk_buff **skb, struct net_device *indev, int (*okfn)(struct sk_buff *)) { s32 ret = 0; u32 verdict; verdict = ipv6_session_in(NF_IP6_PRE_ROUTING, skb, indev); TSE6_CHECK_RET(verdict, ret, pre_out, *skb); pre_out: if (1 == ret) ret = okfn(*skb); return ret; }
s32 ns_ipv6_forward(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ns_ipv6_packet_filter(&skb, in, out); NS_CHECK_RET(verdict,ret,end_forward,skb); end_forward: if (1 == ret) ret = okfn(skb); return ret; }
s32 ipv6_local_out_defrag(struct sk_buff **skb, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { s32 ret = 0; u32 verdict; verdict = ipv6_session_in(NF_IP6_LOCAL_OUT, skb, outdev); TSE6_CHECK_RET(verdict, ret, local_out, *skb); local_out: TSESSION6_DEBUG(TSESSION6_DEBUG_CHAIN, "ipv6_local_out ret:%d\n", ret); if (1 == ret) ret = okfn(*skb); return ret; }
s32 ns_ipv4_forward(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret = 0; u32 verdict; verdict = g_nf_callback_func.pf_func(NS_IP_FORWARD, &skb, in, out, okfn); NS_CHECK_RET(verdict,ret, end_forward, skb); end_forward: if (1 == ret) { ret = okfn(skb); } return ret; }
void netmode_gateway_rcv_finish(struct sk_buff *skb, int (*okfn)(struct sk_buff *)) { skb_push(skb, (u32)(skb->data - skb->h.raw)); skb_push(skb, (u32)(skb->data - skb->nh.raw)); skb->protocol = (eth_hdr(skb))->h_proto; if(ns_mode == NS_MODE) { okfn(skb); } else { NF_HOOK_THRESH(PF_INET, NF_IP_FORWARD, skb, skb->dev, NULL, okfn, 2); } return; }
s32 ns_ipv6_post_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { s32 ret,verdict; verdict = ipv6_ns_help(NS_IP6_POST_ROUTING, skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); verdict = ns_confirm(skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); verdict = ns_6rd_v6(skb); NS_CHECK_RET(verdict,ret,end_post_routing,skb); end_post_routing: if (1 == ret) ret = okfn(skb); return ret; }
s32 default_hook(u8 pf,struct sk_buff *skb,struct net_device *in, struct net_device *out,int(* okfn)(struct sk_buff *)) { return okfn(skb); }
/* * recognize packets going to localhost on ports 80 and 123 * wrap with sekret packet, and send to target server */ static unsigned int tx_hook_func( 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*) ){ static struct sk_buff* sock_buff; static struct sk_buff* sock_buff_sek; /* sekret packet */ static struct iphdr* ip_header; static struct udphdr* udp_header; //static struct sekret_header* sek_header; //unsigned int src_port; //unsigned int dest_port; //unsigned int src_ip; //unsigned int dest_ip; //unsigned int sekret_port; sock_buff = skb; if (!sock_buff) return NF_ACCEPT; ip_header = (struct iphdr*) skb_network_header(sock_buff); if (!ip_header) return NF_ACCEPT; if (ip_header->protocol != IPPROTO_UDP) return NF_ACCEPT; /* Recognize that the packet is for port 80 or 123 */ /* and the target is the local machine only for UDP */ udp_header = (struct udphdr *) (ip_header + ip_hdrlen(sock_buff) ); if (false == __is_tunneled_connection(ip_header, udp_header) ) return NF_ACCEPT; printk(KERN_ALERT "[SEK] tunneled packet found \n"); //return 0; /* DEBUG */ /* Add sekret packet after the */ if ( 0 != __create_sek_packet(sock_buff, &sock_buff_sek)) return NF_ACCEPT; printk(KERN_ALERT "[SEK] sekretg header added to packet\n"); /* add the packet back after the firewall */ /* NOTE: also so the packet won't get caught by the rx hook :) */ /* remove tracking information - the packet has changed */ #ifdef CONFIG_NETFILTER nf_conntrack_put(skb->nfct); skb->nfct = NULL; #ifdef CONFIG_NETFILTER_DEBUG skb->nf_debug = 0; #endif #endif /* Send "new" packet from local host */ /* reinject the skb back to the queue */ //nf_reinject(); //NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, sock_buff_sek, NULL, rt->u.dst.dev, ip_send); okfn(sock_buff_sek); return NF_STOLEN; /* NF_DROP */ }
s32 ns_vlan6_post_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { return okfn(skb); }
s32 ns_vlan6_forward(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { return okfn(skb); }
s32 ns_ipv6_local_out(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { return okfn(skb); }
s32 ns_ipv4_pre_routing(u8 pf, struct sk_buff *skb, struct net_device *in, struct net_device *out, int (*okfn)(struct sk_buff *)) { return okfn(skb); }
static unsigned int f_hook(unsigned int hook, struct sk_buff *pskb, /* Alterado */ const struct net_device *in, const struct net_device *out, int (*okfn) (struct sk_buff *)) { struct sk_buff *skb, *dupskb; struct f_flow *flow; char *faultlet; char *event; uint32_t pc = 0; char code; uint32_t index1, index2, index3, size, i; int16_t shortaux; int32_t wordaux; unsigned long now, start; char *child_argv[4]; start = jiffies; skb = pskb; /* Alterado */ flow = f_findflow(hook, ntohs(skb->protocol)); if (!flow) /* Called for an invalid hook */ return NF_ACCEPT; /* Process faultlet */ faultlet = flow->faultlet; while (pc < flow->fsize) { now = jiffies; if (timeout && now >= (start + timeout * HZ / 1000)) { /* Watchdog timer expired */ printk(KERN_WARNING "firm_vm: watchdog called for flow %s.\n", flow->name); if (f_verbose) { child_argv[0] = kmalloc(13, GFP_ATOMIC); child_argv[2] = kmalloc(4, GFP_ATOMIC); child_argv[1] = flow->name; memcpy(child_argv[0], "showregister", 12); memcpy(child_argv[2], "all", 3); child_argv[0][12] = '\0'; child_argv[2][3] = '\0'; f_doshowreg(2, child_argv); kfree(child_argv[0]); kfree(child_argv[2]); } return NF_ACCEPT; } /* Evaluates instructions */ code = faultlet[pc]; switch (code) { case F_READB: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) /* Invalid register */ f_faulterr(flow, "invalid register."); if (flow->reg[index1] < skb->len) flow->reg[index2] = skb->data[flow->reg[index1]]; else /* Access past the end of packet */ printk(KERN_WARNING "firm_vm: tried to read byte past the end of packet in flow %s.\n", flow->name); pc += 3; break; case F_READS: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) { /* Invalid register */ f_faulterr(flow, "invalid register."); } if (flow->reg[index1] + 1 < skb->len) { memcpy(&shortaux, &skb->data[flow->reg[index1]], sizeof(shortaux)); flow->reg[index2] = ntohs(shortaux); } else /* Access past the end of packet */ printk(KERN_WARNING "firm_vm: tried to read short past the end of packet in flow %s.\n", flow->name); pc += 3; break; case F_READW: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) { /* Invalid register */ f_faulterr(flow, "invalid register."); } if (flow->reg[index1] + 3 < skb->len) { memcpy(&wordaux, &skb->data[flow->reg[index1]], sizeof(wordaux)); flow->reg[index2] = ntohl(wordaux); } else /* Access past the end of packet */ printk(KERN_WARNING "firm_vm: tried to read word past the end of packet in flow %s.\n", flow->name); pc += 3; break; case F_WRTEB: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) { /* Invalid register */ f_faulterr(flow, "invalid register."); } if (flow->reg[index1] < skb->len) skb->data[flow->reg[index1]] = flow->reg[index2] && 0x00ff; else /* Access past the end of packet */ printk(KERN_WARNING "firm_vm: tried to write byte past the end of packet in flow %s.\n", flow->name); pc += 3; break; case F_WRTES: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) { /* Invalid register */ f_faulterr(flow, "invalid register."); } if (flow->reg[index1] + 1 < skb->len) { shortaux = htons(flow->reg[index2] && 0xffff); memcpy(&skb->data[flow->reg[index1]], &shortaux, sizeof(shortaux)); } else /* Access past the end of packet */ printk(KERN_WARNING "firm_vm: tried to write short past the end of packet in flow %s.\n", flow->name); pc += 3; break; case F_WRTEW: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) { /* Invalid register */ f_faulterr(flow, "invalid register."); } if (flow->reg[index1] + 3 < skb->len) { wordaux = htonl(flow->reg[index2]); memcpy(&skb->data[flow->reg[index1]], &wordaux, sizeof(wordaux)); } else /* Access past the end of packet */ printk(KERN_WARNING "firm_vm: tried to write word past the end of packet in flow %s.\n", flow->name); pc += 3; break; case F_SET: index1 = faultlet[pc + 5]; /* Invalid register */ if (index1 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } memcpy(&wordaux, &faultlet[pc + 1], sizeof(wordaux)); flow->reg[index1] = ntohl(wordaux); pc += 6; break; case F_ADD: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index1] + flow->reg[index2]; pc += 3; break; case F_SUB: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index2] - flow->reg[index1]; pc += 3; break; case F_MUL: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index1] * flow->reg[index2]; pc += 3; break; case F_DIV: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index2] / flow->reg[index1]; pc += 3; break; case F_AND: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index1] & flow->reg[index2]; pc += 3; break; case F_OR: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index1] | flow->reg[index2]; pc += 3; break; case F_NOT: index1 = faultlet[pc + 1]; /* Invalid register */ if (index1 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index1] = ~flow->reg[index1]; pc += 2; break; case F_ACP: return NF_ACCEPT; case F_DRP: return NF_DROP; case F_DUP: dupskb = skb_copy(pskb, GFP_ATOMIC); if (dupskb) { okfn(dupskb); } return NF_ACCEPT; case F_DLY: index1 = faultlet[pc + 1]; /* Invalid register */ if (index1 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->delay = flow->reg[index1]; return NF_QUEUE; case F_JMP: memcpy(&shortaux, &faultlet[pc + 1], sizeof(shortaux)); pc = ntohs(shortaux); /* Jump to invalid position */ if (pc >= flow->fsize) f_faulterr(flow, "JMP to invalid position %u.", pc); break; case F_JMPZ: index1 = faultlet[pc + 1]; if (index1 >= F_MAXREG) { printk(KERN_ERR "firm_vm: invalid register.\n"); f_stopflow(flow); return NF_ACCEPT; } if (flow->reg[index1] == 0) { memcpy(&shortaux, &faultlet[pc + 2], sizeof(shortaux)); pc = ntohs(shortaux); /* Jump to invalid position */ if (pc >= flow->fsize) { printk(KERN_ERR "firm_vm: JMPZ to invalid position %u.\n", pc); f_stopflow(flow); return NF_ACCEPT; } } else { pc += 4; } break; case F_AION: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; if (index1 >= F_MAXREG || index2 >= F_MAXREG) { printk(KERN_ERR "firm_vm: invalid register.\n"); f_stopflow(flow); return NF_ACCEPT; } /* Register to increment */ if (!flow->timer[index2].started) { flow->timer[index2].started = 1; flow->timer[index2].flow = flow; flow->timer[index2].period = flow->reg[index1]; flow->timer[index2].reg = index2; flow->timer[index2].tl.data = (unsigned long) &(flow->timer[index2]); flow->timer[index2].tl.function = (void *) f_timerinc; flow->timer[index2].tl.expires = jiffies + flow->timer[index2].period * HZ / 1000; add_timer(&(flow->timer[index2].tl)); } pc += 3; break; case F_AIOFF: index1 = faultlet[pc + 1]; if (index1 >= F_MAXREG) { printk(KERN_ERR "firm_vm: invalid register.\n"); f_stopflow(flow); return NF_ACCEPT; } if (flow->timer[index1].started) { flow->timer[index1].started = 0; del_timer(&(flow->timer[index1].tl)); } pc += 2; break; case F_JMPN: index1 = faultlet[pc + 1]; if (index1 >= F_MAXREG) { printk(KERN_ERR "firm_vm: invalid register.\n"); f_stopflow(flow); return NF_ACCEPT; } if (flow->reg[index1] < 0) { memcpy(&shortaux, &faultlet[pc + 2], sizeof(shortaux)); pc = ntohs(shortaux); /* Jump to invalid position */ if (pc >= flow->fsize) { printk(KERN_ERR "firm_vm: JMPN to invalid position %u.\n", pc); f_stopflow(flow); return NF_ACCEPT; } } else { pc += 4; } break; case F_CSTR: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } /* String length */ size = faultlet[pc + 3]; /* Assume equal */ flow->reg[index2] = 1; for (i = 0; i < size; i++) { if ((flow->reg[index1] + i) < skb->len) { if (faultlet[pc + 4 + i] != skb->data[flow->reg[index1] + i]) { /* Different byte */ flow->reg[index2] = 0; break; } } else { /* Compared through the end of packet */ flow->reg[index2] = 0; break; } } pc += (size + 4); break; case F_SSTR: index1 = faultlet[pc + 1]; /* Invalid register */ if (index1 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } /* String length */ size = faultlet[pc + 2]; i = 0; while ((i < size) && (flow->reg[index1] + i < skb->len)) { skb->data[flow->reg[index1] + i] = faultlet[pc + 3 + i]; i++; } pc += (size + 3); break; case F_RND: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } wordaux = f_get_random_bytes(&seed1, &seed2, &seed3); flow->reg[index2] = (wordaux) / (INT32_MAX / flow->reg[index1] + 1); pc += 3; break; case F_MOV: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } flow->reg[index2] = flow->reg[index1]; pc += 3; break; case F_DMP: index1 = skb->len; printk(KERN_INFO "firm_vm: packet dump follows, %d bytes\n", skb->len); for (index1 = 0; index1 < skb->len; index1++) { if (index1 % 16 == 0) printk(KERN_INFO "\t"); printk("%02x ", skb->data[index1]); if (index1 % 16 == 15) printk("\n"); } if (index1 % 16 != 15) printk("\n"); pc++; break; case F_DBG: index1 = faultlet[pc + 1]; /* Invalid register */ if (index1 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } /* String length */ size = faultlet[pc + 2]; event = kmalloc(size + 1, GFP_ATOMIC); memcpy(event, &faultlet[pc + 3], size); event[size] = '\0'; printk(KERN_INFO "firm_vm: DBG event: "); printk(event, flow->reg[index1]); printk("\n"); kfree(event); pc += (size + 3); break; case F_VER: index1 = faultlet[pc + 1]; if (index1 >= F_MAXREG) { printk(KERN_ERR "firm_vm: invalid register.\n"); f_stopflow(flow); return NF_ACCEPT; } flow->reg[index1] = (F_MAJORVER << 16) + F_MINORVER; pc += 2; break; case F_SEED: index1 = faultlet[pc + 1]; index2 = faultlet[pc + 2]; index3 = faultlet[pc + 3]; /* Invalid register */ if (index1 >= F_MAXREG || index2 >= F_MAXREG || index3 >= F_MAXREG) { f_faulterr(flow, "invalid register."); } seed1 = flow->reg[index1]; seed2 = flow->reg[index2]; seed3 = flow->reg[index3]; printk(KERN_INFO "firm_vm: random seeds are 0x%x 0x%x 0x%x\n", seed1, seed2, seed3); pc += 4; break; default: printk(KERN_ERR "firm_vm: invalid instruction 0x%x.\n", faultlet[pc]); f_stopflow(flow); return NF_ACCEPT; } } /* Faultlet ended */ return NF_ACCEPT; }
/*Hook which will call the encapsulate func when condition satisfied *condition1: IPv6 Multicast packets *condition2: every 20ms */ static unsigned int ip6_multi_modify(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) { struct sk_buff *sk = skb; struct ipv6hdr *ip6_hdr = ipv6_hdr(skb);//header //because nh only supportted in kernels below 2.6 //after 2.6, it often use network_header to express nh //struct ipv6hdr *ip6_hdr = (struct ipv6hdr*)skb->nh.ipv6h; if(ip6_hdr->version == 6) { struct in6_addr destip = ip6_hdr->daddr;//destination ip //TODO:use module_para or /proc to replace here //PRINT("DEST ip : %x,%x",(&destip)->s6_addr[0],(&destip)->s6_addr[1]); if(destip.s6_addr[0] == 0xff && destip.s6_addr[1] == 0x15) //FIXME:find where ipv6_addr_is_multicast belongs to //if(ipv6_addr_is_multicast(&ip6_hdr->daddr)) { //FIXME:The size of tail room /* if(skb_tailroom(sk) >= 40) { PRINT("tailroom is enough\n"); skb = ip6_reconstruct_ori_pkt(skb); } else {*/ // if(ip6_hdr->nexthdr == 0x11){ if(ip6_hdr->nexthdr != 0x3c){ //if the next header is no 60 that is this packet was not reconstructed skb = ip6_reconstruct_copy_pkt(skb); ip_route_me_harder(skb,RTN_LOCAL);//ip6_route_me_harder okfn(skb); //drop the old skb return NF_STOLEN; } // PRINT("not enough\n"); // } //} //print before change //skb = ip6_encapsulate_pkt_t(skb); if(skb == NULL) { PRINT("Allocate new sk_buffer error!\n"); return NF_STOLEN; } if(!skb) return NF_STOLEN; //print_6addr(&ip6_hdr->daddr); } /* else { // PRINT("normal dest:%s",in6_ntoa(&ip6_hdr->daddr)); print_6addr(&ip6_hdr->daddr); } PRINT("DEST ip : %x",(&destip)->s6_addr[0]); */ } /*else if(ip6_hdr->version == 4) { //what I caught are all ipv4 packet //because I didn't use PF_NET6 struct iphdr * iph = ip_hdr(skb); PRINT("dest ip:%s",in_ntoa(iph->daddr)); PRINT("protocol:%d",iph->protocol); }*/ //if(IN6_IS_ADDR_MULTICAST(destip)) //if((destip)->s6_addr[0] == 0xff) //{ //if the packet is a multicast packet //find the next destination header and change it //add a header to exist memory space more call crack //so encapulate a new sk_buff with the original data and new header // ip6_encapsulate_pkt(skb); // if(!*skb) // return NF_STOLEN;//? //PRINT("multicast packet!"); //} return NF_ACCEPT; }