/* Function that compares a received TCP packet''''s destination port * with the port specified in the Port Deny Rule. If a processing * error occurs, NF_ACCEPT will be returned so that the packet is * not lost. */ static int check_tcp_packet(struct sk_buff *skb) { /* Seperately defined pointers to header structures are used * to access the TCP fields because it seems that the so-called * transport header from skb is the same as its network header TCP packets. * If you don''''t believe me then print the addresses of skb->nh.iph * and skb->h.th. * It would have been nicer if the network header only was IP and * the transport header was TCP but what can you do? */ struct tcphdr *thead;
/* We don''''t want any NULL pointers in the chain to the TCP header. */ if (!skb ) return NF_ACCEPT; if (!(skb->nh.iph)) return NF_ACCEPT;
/* Be sure this is a TCP packet first */ if (skb->nh.iph->protocol != IPPROTO_TCP) { return NF_ACCEPT; }
/* Now check the destination port */ if ((thead->dest) == deny_port) { /* Update statistics */ lwfw_statistics.total_dropped++; lwfw_statistics.tcp_dropped++;
return NF_DROP; }
return NF_ACCEPT; }
/* Function that compares a received IPv4 packet''''s source address * with the address specified in the IP Deny Rule. If a processing * error occurs, NF_ACCEPT will be returned so that the packet is * not lost. */ static int check_ip_packet(struct sk_buff *skb) { /* We don''''t want any NULL pointers in the chain to the IP header. */ if (!skb ) return NF_ACCEPT; if (!(skb->nh.iph)) return NF_ACCEPT;
if (skb->nh.iph->saddr == deny_ip) {/* Matches the address. Barf. */ lwfw_statistics.ip_dropped++; /* Update the statistics */ lwfw_statistics.total_dropped++;
return NF_DROP; }
return NF_ACCEPT; }
static int set_if_rule(char *name) { int ret = 0; char *if_dup; /* Duplicate interface */
/* Make sure the name is non-null */ NULL_CHECK(name);
/* Free any previously saved interface name */ if (deny_if) { kfree(deny_if); deny_if = NULL; }
deny_if = if_dup; lwfw_statistics.if_dropped = 0; /* Reset drop count for IF rule */ printk("LWFW: Set to deny from interface: %s\n", deny_if);
return ret; }
static int set_ip_rule(unsigned int ip) { deny_ip = ip; lwfw_statistics.ip_dropped = 0; /* Reset drop count for IP rule */
printk("LWFW: Set to deny from IP address: %d.%d.%d.%d\n", ip & 0x000000FF, (ip & 0x0000FF00) >> 8, (ip & 0x00FF0000) >> 16, (ip & 0xFF000000) >> 24);
return 0; }
static int set_port_rule(unsigned short port) { deny_port = port; lwfw_statistics.tcp_dropped = 0; /* Reset drop count for TCP rule */
printk("LWFW: Set to deny for TCP port: %d\n", ((port & 0xFF00) >> 8 | (port & 0x00FF) << 8));
return 0; }
/*********************************************/ /* * File operations functions for control device */ static int lwfw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0;
switch (cmd) { case LWFW_GET_VERS: return LWFW_VERS; case LWFW_ACTIVATE: { active = 1; printk("LWFW: Activated.\n"); if (!deny_if && !deny_ip && !deny_port) { printk("LWFW: No deny options set.\n"); } break; } case LWFW_DEACTIVATE: { active ^= active; printk("LWFW: Deactivated.\n"); break; } case LWFW_GET_STATS: { ret = copy_stats((struct lwfw_stats *)arg); break; } case LWFW_DENY_IF: { ret = set_if_rule((char *)arg); break; } case LWFW_DENY_IP: { ret = set_ip_rule((unsigned int)arg); break; } case LWFW_DENY_PORT: { ret = set_port_rule((unsigned short)arg); break; } default: ret = -EBADRQC; };
return ret; }
/* Called whenever open() is called on the device file */ static int lwfw_open(struct inode *inode, struct file *file) { if (lwfw_ctrl_in_use) { return -EBUSY; } else { MOD_INC_USE_COUNT; lwfw_ctrl_in_use++; return 0; } return 0; }
/* Called whenever close() is called on the device file */ static int lwfw_release(struct inode *inode, struct file *file) { lwfw_ctrl_in_use ^= lwfw_ctrl_in_use; MOD_DEC_USE_COUNT; return 0; }
/*********************************************/ /* * Module initialisation and cleanup follow... */ int init_module() { /* Register the control device, /dev/lwfw */ SET_MODULE_OWNER(&lwfw_fops);
/* Attempt to register the LWFW control device */ if ((major = register_chrdev(LWFW_MAJOR, LWFW_NAME, &lwfw_fops)) < 0) { printk("LWFW: Failed registering control device!\n"); printk("LWFW: Module installation aborted.\n"); return major; }
/* Make sure the usage marker for the control device is cleared */ lwfw_ctrl_in_use ^= lwfw_ctrl_in_use;
printk("\nLWFW: Control device successfully registered.\n");