static unsigned int kaodv_hook(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 = SKB_NETWORK_HDR_IPH(skb); struct expl_entry e; struct in_addr ifaddr, bcaddr; int res = 0; memset(&ifaddr, 0, sizeof(struct in_addr)); memset(&bcaddr, 0, sizeof(struct in_addr)); /* We are only interested in IP packets */ if (iph == NULL) return NF_ACCEPT; /* We want AODV control messages to go through directly to the * AODV socket.... */ if (iph && iph->protocol == IPPROTO_UDP) { struct udphdr *udph; udph = (struct udphdr *)((char *)iph + (iph->ihl << 2)); if (ntohs(udph->dest) == AODV_PORT || ntohs(udph->source) == AODV_PORT) { #ifdef CONFIG_QUAL_THRESHOLD #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) qual = (int)(skb)->__unused; #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) qual = (skb)->iwq.qual; #endif if (qual_th && hooknum == NF_INET_PRE_ROUTING) { if (qual && qual < qual_th) { pkts_dropped++; return NF_DROP; } } #endif /* CONFIG_QUAL_THRESHOLD */ if (hooknum == NF_INET_PRE_ROUTING && in) kaodv_update_route_timeouts(hooknum, in, iph); return NF_ACCEPT; } } if (hooknum == NF_INET_PRE_ROUTING) res = if_info_from_ifindex(&ifaddr, &bcaddr, in->ifindex); else res = if_info_from_ifindex(&ifaddr, &bcaddr, out->ifindex); if (res < 0) return NF_ACCEPT; /* Ignore broadcast and multicast packets */ if (iph->daddr == INADDR_BROADCAST || IN_MULTICAST(ntohl(iph->daddr)) || iph->daddr == bcaddr.s_addr) return NF_ACCEPT; /* Check which hook the packet is on... */ switch (hooknum) { case NF_INET_PRE_ROUTING: kaodv_update_route_timeouts(hooknum, in, iph); /* If we are a gateway maybe we need to decapsulate? */ if (is_gateway && iph->protocol == IPPROTO_MIPE && iph->daddr == ifaddr.s_addr) { ip_pkt_decapsulate(skb); iph = SKB_NETWORK_HDR_IPH(skb); return NF_ACCEPT; } /* Ignore packets generated locally or that are for this * node. */ if (iph->saddr == ifaddr.s_addr || iph->daddr == ifaddr.s_addr) { return NF_ACCEPT; } /* Check for unsolicited data packets */ else if (!kaodv_expl_get(iph->daddr, &e)) { kaodv_netlink_send_rerr_msg(PKT_INBOUND, iph->saddr, iph->daddr, in->ifindex); return NF_DROP; } /* Check if we should repair the route */ else if (e.flags & KAODV_RT_REPAIR) { kaodv_netlink_send_rt_msg(KAODVM_REPAIR, iph->saddr, iph->daddr); kaodv_queue_enqueue_packet(skb, okfn); return NF_STOLEN; } break; case NF_INET_LOCAL_OUT: if (!kaodv_expl_get(iph->daddr, &e) || (e.flags & KAODV_RT_REPAIR)) { if (!kaodv_queue_find(iph->daddr)) kaodv_netlink_send_rt_msg(KAODVM_ROUTE_REQ, 0, iph->daddr); kaodv_queue_enqueue_packet(skb, okfn); return NF_STOLEN; } else if (e.flags & KAODV_RT_GW_ENCAP) { /* Make sure that also the virtual Internet * dest entry is refreshed */ kaodv_update_route_timeouts(hooknum, out, iph); skb = ip_pkt_encapsulate(skb, e.nhop); if (!skb) return NF_STOLEN; ip_route_me_harder(skb, RTN_LOCAL); } break; case NF_INET_POST_ROUTING: kaodv_update_route_timeouts(hooknum, out, iph); } return NF_ACCEPT; }
static unsigned int kaodv_hook(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 = SKB_NETWORK_HDR_IPH(skb); struct expl_entry e; struct in_addr ifaddr, bcaddr; int res = 0; memset(&ifaddr, 0, sizeof(struct in_addr)); memset(&bcaddr, 0, sizeof(struct in_addr)); /* We are only interested in IP packets */ if (iph == NULL) return NF_ACCEPT; /* Hook FORWARD only takecare of gateway packets */ if(hooknum == NF_INET_FORWARD) { //we are only handle forwarded packets in gateway mode if(!is_gateway) return NF_ACCEPT; //we don't process packets from binded interface if(!in || if_info_from_ifindex(NULL, NULL, in->ifindex) == 0) return NF_ACCEPT; } /* We want AODV control messages to go through directly to the * AODV socket.... */ if (iph && iph->protocol == IPPROTO_UDP) { struct udphdr *udph; udph = (struct udphdr *)((char *)iph + (iph->ihl << 2)); if (ntohs(udph->dest) == AODV_PORT || ntohs(udph->source) == AODV_PORT) { #ifdef CONFIG_QUAL_THRESHOLD qual = (skb)->iwq.qual; if (qual_th && hooknum == NF_INET_PRE_ROUTING) { if (qual && qual < qual_th) { pkts_dropped++; return NF_DROP; } } #endif /* CONFIG_QUAL_THRESHOLD */ if (hooknum == NF_INET_PRE_ROUTING && in) kaodv_update_route_timeouts(hooknum, in, iph); return NF_ACCEPT; } } if (hooknum == NF_INET_PRE_ROUTING) { res = if_info_from_ifindex(&ifaddr, &bcaddr, in->ifindex); printk(KERN_DEBUG "kaodv: in->ifindex %d, res %d.\n", in->ifindex, res); } else { res = if_info_from_ifindex(&ifaddr, &bcaddr, out->ifindex); printk(KERN_DEBUG "kaodv: out->ifindex %d, res %d.\n", out->ifindex, res); } if (res < 0) { printk(KERN_DEBUG "kaodv: No information!\n"); return NF_ACCEPT; } /* Ignore broadcast and multicast packets */ if (iph->daddr == INADDR_BROADCAST || IN_MULTICAST(ntohl(iph->daddr)) || iph->daddr == bcaddr.s_addr) { printk(KERN_DEBUG "kaodv: Broadcast packet!\n"); return NF_ACCEPT; } /* Check which hook the packet is on... */ printk(KERN_DEBUG "kaodv: Check which hook the packet is on...\n"); switch (hooknum) { case NF_INET_PRE_ROUTING: printk(KERN_DEBUG "kaodv: NF_INET_PRE_ROUTING\n"); kaodv_update_route_timeouts(hooknum, in, iph); /* If we are a gateway maybe we need to decapsulate? */ if (is_gateway && iph->protocol == IPPROTO_MIPE && iph->daddr == ifaddr.s_addr) { ip_pkt_decapsulate(skb); printk(KERN_DEBUG "kaodv: successfully returned from ip_pkt_decapsulate!\n"); iph = SKB_NETWORK_HDR_IPH(skb); return NF_ACCEPT; } /* Ignore packets generated locally or that are for this * node. */ if (iph->saddr == ifaddr.s_addr || iph->daddr == ifaddr.s_addr) { return NF_ACCEPT; } /* Check for unsolicited data packets */ else if (!kaodv_expl_get(iph->daddr, &e)) { kaodv_netlink_send_rerr_msg(PKT_INBOUND, iph->saddr, iph->daddr, in->ifindex); return NF_DROP; } /* Check if we should repair the route */ else if (e.flags & KAODV_RT_REPAIR) { kaodv_netlink_send_rt_msg(KAODVM_REPAIR, iph->saddr, iph->daddr); kaodv_queue_enqueue_packet(skb, okfn); return NF_STOLEN; } break; case NF_INET_FORWARD: case NF_INET_LOCAL_OUT: printk(KERN_DEBUG "kaodv: NF_INET_LOCAL_OUT\n"); if (!kaodv_expl_get(iph->daddr, &e) || (e.flags & KAODV_RT_REPAIR)) { if (!kaodv_queue_find(iph->daddr)) kaodv_netlink_send_rt_msg(KAODVM_ROUTE_REQ, 0, iph->daddr); kaodv_queue_enqueue_packet(skb, okfn); return NF_STOLEN; } else if (e.flags & KAODV_RT_GW_ENCAP) { /* Make sure that also the virtual Internet * dest entry is refreshed */ kaodv_update_route_timeouts(hooknum, out, iph); skb = ip_pkt_encapsulate(skb, e.nhop); if (!skb) return NF_STOLEN; printk(KERN_DEBUG "kaodv: successfully returned from ip_pkt_encapsulate!\n"); ip_route_me_harder(skb, RTN_LOCAL); } break; case NF_INET_POST_ROUTING: printk(KERN_DEBUG "kaodv: NF_INET_POST_ROUTING\n"); kaodv_update_route_timeouts(hooknum, out, iph); break; } printk(KERN_DEBUG "kaodv: Succesfully returned from NF_HOOK!\n"); return NF_ACCEPT; }