#include "module.h" extern int AT_ROUTING; extern uint32_t at_state; extern uint32_t at_mycid; extern struct gateway_list_head *glh; extern struct gateway_list_head *rlh; struct nf_hook_ops input_filter; struct nf_hook_ops output_filter; int inet_aton(const char *cp, __u32 *addr) { unsigned int val; int base, n; char c; u_int parts[4]; u_int *pp = parts; for (;;) { //Collect number up to ``.''. Values are specified as for C: // 0x=hex, 0=octal, other=decimal. val = 0; base = 10; if (*cp == '0') { if (*++cp == 'x' || *cp == 'X') base = 16, cp++; else base = 8; } while ((c = *cp) != '\0') { if (isascii(c) && isdigit(c)) { val = (val * base) + (c - '0'); cp++; continue; } if (base == 16 && isascii(c) && isxdigit(c)) { val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); cp++; continue; } break; } if (*cp == '.') { // Internet format: a.b.c.d a.b.c (with c treated as // 16-bits) a.b (with b treated as 24 bits) if (pp >= parts + 3 || val > 0xff) return (0); *pp++ = val, cp++; } else break; } // Check for trailing characters. if (*cp && (!isascii(*cp) || !isspace(*cp))) return (0); // Concoct the address according to the number of parts specified. n = pp - parts + 1; switch (n) { case 1: // a -- 32 bits break; case 2: //a.b -- 8.24 bits if (val > 0xffffff) return (0); val |= parts[0] << 24; break; case 3: //a.b.c -- 8.8.16 bits if (val > 0xffff) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: // a.b.c.d -- 8.8.8.8 bits if (val > 0xff) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } if (addr) *addr= htonl(val); return (1); } int populate_proc_packet_stats(char *page, char **start, off_t offset, int count, int *eof, void *data) { *eof = 1; sprintf(page, "%d\n", at_state); return strlen(page); } unsigned int output_handler( unsigned int hooknum,struct sk_buff **skb,const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct gateway_list_node gln; gln.gw = (((*skb)->nh).iph)->daddr; printk("<1>o/p handler, trying, %u.%u.%u.%u \n", NIPQUAD(gln.gw)); if(!check_entry_exists(&rlh, &gln)) { #ifdef AT_MESSAGES printk("<1>o/p handler, Entry doesn't exist, %u.%u.%u.%u \n", NIPQUAD(gln.gw)); #endif /*AT_MESSAGES*/ return NF_QUEUE;/* packets that can't be routed must be dropped */ } return NF_ACCEPT; /*well if they can be, they can go*/ } unsigned int input_handler(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct gateway_list_node gln; gln.gw = (((*skb)->nh).iph)->daddr; if(!check_entry_exists(&rlh, &gln)) { #ifdef AT_MESSAGES printk("<1>i/p handler, Entry doesn't exist, %u.%u.%u.%u \n", NIPQUAD(gln.gw)); printk("<1>i/p handler, source doesn't exist, %u.%u.%u.%u \n", NIPQUAD( (((*skb)->nh).iph)->saddr)); #endif /*AT_MESSAGES*/ return NF_DROP;/* packets that can't be routed must be dropped */ } return NF_ACCEPT; /*well if they can be, they can go*/ } /* initialize module */ int init_module(void) { /* * Set Alpha-T routing started * Allows the system call add_gateway to start funtioning */ AT_ROUTING = 1; at_state = -1; /* must initialize this variable */ at_mycid = 0; /*initialize gateway list*/ init_list(&glh); init_list(&rlh); /*create proc entries, so we can see what's happening*/ proc_mkdir("at_routing", NULL); create_proc_read_entry("at_routing/at_gateways", 0, NULL, populate_proc_gateways, NULL ); create_proc_read_entry("at_routing/at_routable", 0, NULL, populate_proc_routable, NULL ); create_proc_read_entry("at_routing/at_state", 0, NULL, populate_proc_state, NULL ); create_proc_read_entry("at_routing/at_cid", 0, NULL, populate_proc_cid, NULL ); /* input hook */ input_filter.list.next = NULL; input_filter.list.prev = NULL; input_filter.hook = input_handler; input_filter.pf = PF_INET; // IPv4 input_filter.hooknum = NF_IP_PRE_ROUTING; /* output hook */ output_filter.list.next = NULL; output_filter.list.prev = NULL; output_filter.hook = output_handler; output_filter.pf = PF_INET; // IPv4 output_filter.hooknum = NF_IP_LOCAL_OUT; /* register hooks to handle packets */ nf_register_hook(&input_filter); nf_register_hook(&output_filter); return 0; } void cleanup_module(void) { /*Remove Alpha-T routing*/ AT_ROUTING = 0; /*remove proc entries*/ remove_proc_entry("at_routing/at_gateways", NULL); remove_proc_entry("at_routing/at_routable", NULL); remove_proc_entry("at_routing/at_state", NULL); remove_proc_entry("at_routing/at_cid", NULL); remove_proc_entry("at_routing", NULL); /*remove gateway list*/ destroy_list(&glh); destroy_list(&rlh); nf_unregister_hook(&output_filter); nf_unregister_hook(&input_filter); return; }