1/* 2 * iptables module to match on related connections 3 * (c) 2001 Martin Josefsson <gandalf@wlug.westbo.se> 4 * 5 * Released under the terms of GNU GPLv2. 6 * 7 * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>: 8 * - Port to newnat infrastructure 9 */ 10#include <linux/module.h> 11#include <linux/skbuff.h> 12#include <linux/netfilter_ipv4/ip_conntrack.h> 13#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 14#include <linux/netfilter_ipv4/ip_tables.h> 15#include <linux/netfilter_ipv4/ipt_helper.h> 16 17MODULE_LICENSE("GPL"); 18 19#define DEBUGP(format, args...) 20 21static int 22match(const struct sk_buff *skb, 23 const struct net_device *in, 24 const struct net_device *out, 25 const void *matchinfo, 26 int offset, 27 const void *hdr, 28 u_int16_t datalen, 29 int *hotdrop) 30{ 31 const struct ipt_helper_info *info = matchinfo; 32 struct ip_conntrack_expect *exp; 33 struct ip_conntrack *ct; 34 enum ip_conntrack_info ctinfo; 35 36 ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); 37 if (!ct) { 38 DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); 39 return 0; 40 } 41 42 //2008.05 Angela { 43 /*If command is --helper XXX, check the struct helper */ 44 if((info->cmd & IPT_HELPER_HELPER) == IPT_HELPER_HELPER) 45 { 46 if(ct->helper) { 47 if(!strncmp(ct->helper->name, info->name, strlen(info->name))) 48 return 1; 49 } 50 } 51 /* check expectant connect */ 52 //2008.05 Angela } 53 if (!ct->master) { 54 DEBUGP("ipt_helper: conntrack %p has no master\n", ct); 55 return 0; 56 } 57 58 exp = ct->master; 59 if (!exp->expectant) { 60 DEBUGP("ipt_helper: expectation %p without expectant !?!\n", 61 exp); 62 return 0; 63 } 64 65 if (!exp->expectant->helper) { 66 DEBUGP("ipt_helper: master ct %p has no helper\n", 67 exp->expectant); 68 return 0; 69 } 70 71 DEBUGP("master's name = %s , info->name = %s\n", 72 exp->expectant->helper->name, info->name); 73 74 return !strncmp(exp->expectant->helper->name, info->name, 75 strlen(exp->expectant->helper->name)) ^ info->invert; 76} 77 78static int check(const char *tablename, 79 const struct ipt_ip *ip, 80 void *matchinfo, 81 unsigned int matchsize, 82 unsigned int hook_mask) 83{ 84 struct ipt_helper_info *info = matchinfo; 85 86 info->name[29] = '\0'; 87 88 /* verify size */ 89 if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) 90 return 0; 91 92 /* verify that we actually should match anything */ 93 if ( strlen(info->name) == 0 ) 94 return 0; 95 96 return 1; 97} 98 99static struct ipt_match helper_match 100= { { NULL, NULL }, "helper", &match, &check, NULL, THIS_MODULE }; 101 102static int __init init(void) 103{ 104 /* NULL if ip_conntrack not a module */ 105 if (ip_conntrack_module) 106 __MOD_INC_USE_COUNT(ip_conntrack_module); 107 return ipt_register_match(&helper_match); 108} 109 110static void __exit fini(void) 111{ 112 ipt_unregister_match(&helper_match); 113 if (ip_conntrack_module) 114 __MOD_DEC_USE_COUNT(ip_conntrack_module); 115} 116 117module_init(init); 118module_exit(fini); 119 120