⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipt_recent.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return 0;	/* seconds and hit_count only valid for CHECK/UPDATE */	if(info->check_set & IPT_RECENT_SET) { flag++; if(info->seconds || info->hit_count) return 0; }	if(info->check_set & IPT_RECENT_REMOVE) { flag++; if(info->seconds || info->hit_count) return 0; }	if(info->check_set & IPT_RECENT_CHECK) flag++;	if(info->check_set & IPT_RECENT_UPDATE) flag++;	/* One and only one of these should ever be set */	if(flag != 1) return 0;	/* Name must be set to something */	if(!info->name || !info->name[0]) return 0;	/* Things look good, create a list for this if it does not exist */	/* Lock the linked list while we play with it */	spin_lock_bh(&recent_lock);	/* Look for an entry with this name already created */	/* Finds the end of the list and the entry before the end if current name does not exist */	find_table = r_tables;	while( (last_table = find_table) && strncmp(info->name,find_table->name,IPT_RECENT_NAME_LEN) && (find_table = find_table->next) );	/* If a table already exists just increment the count on that table and return */	if(find_table) { #ifdef DEBUG		if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: table found (%s), incrementing count.\n",info->name);#endif		find_table->count++;		spin_unlock_bh(&recent_lock);		return 1;	}	spin_unlock_bh(&recent_lock);	/* Table with this name not found */	/* Allocate memory for new linked list item */#ifdef DEBUG	if(debug) {		printk(KERN_INFO RECENT_NAME ": checkentry: no table found (%s)\n",info->name);		printk(KERN_INFO RECENT_NAME ": checkentry: Allocationg %d for link-list entry.\n",sizeof(struct recent_ip_tables));	}#endif	curr_table = vmalloc(sizeof(struct recent_ip_tables));	if(curr_table == NULL) return 0;	spin_lock_init(&curr_table->list_lock);	curr_table->next = NULL;	curr_table->count = 1;	curr_table->time_pos = 0;	strncpy(curr_table->name,info->name,IPT_RECENT_NAME_LEN);	curr_table->name[IPT_RECENT_NAME_LEN-1] = '\0';	/* Allocate memory for this table and the list of packets in each entry. */#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for table (%s).\n",			sizeof(struct recent_ip_list)*ip_list_tot,			info->name);#endif	curr_table->table = vmalloc(sizeof(struct recent_ip_list)*ip_list_tot);	if(curr_table->table == NULL) { vfree(curr_table); return 0; }	memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot);#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n",			sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot);#endif	hold = vmalloc(sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot);#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n");#endif	if(hold == NULL) { 		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for pkt_list.\n");		vfree(curr_table->table); 		vfree(curr_table);		return 0;	}	for(c = 0; c < ip_list_tot; c++) {		curr_table->table[c].last_pkts = hold + c*ip_pkt_list_tot;	}	/* Allocate memory for the hash table */#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for hash_table.\n",			sizeof(int)*ip_list_hash_size);#endif	curr_table->hash_table = vmalloc(sizeof(int)*ip_list_hash_size);	if(!curr_table->hash_table) {		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for hash_table.\n");		vfree(hold);		vfree(curr_table->table); 		vfree(curr_table);		return 0;	}	for(c = 0; c < ip_list_hash_size; c++) {		curr_table->hash_table[c] = -1;	}	/* Allocate memory for the time info */#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for time_info.\n",			sizeof(struct time_info_list)*ip_list_tot);#endif	curr_table->time_info = vmalloc(sizeof(struct time_info_list)*ip_list_tot);	if(!curr_table->time_info) {		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for time_info.\n");		vfree(curr_table->hash_table);		vfree(hold);		vfree(curr_table->table); 		vfree(curr_table);		return 0;	}	for(c = 0; c < ip_list_tot; c++) {		curr_table->time_info[c].position = c;		curr_table->time_info[c].time = 0;	}	/* Put the new table in place */	spin_lock_bh(&recent_lock);	find_table = r_tables;	while( (last_table = find_table) && strncmp(info->name,find_table->name,IPT_RECENT_NAME_LEN) && (find_table = find_table->next) );	/* If a table already exists just increment the count on that table and return */	if(find_table) { 		find_table->count++;			spin_unlock_bh(&recent_lock);#ifdef DEBUG		if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: table found (%s), created by other process.\n",info->name);#endif		vfree(curr_table->time_info);		vfree(curr_table->hash_table);		vfree(hold);		vfree(curr_table->table);		vfree(curr_table);		return 1;	}	if(!last_table) r_tables = curr_table; else last_table->next = curr_table;	spin_unlock_bh(&recent_lock);#ifdef CONFIG_PROC_FS	/* Create our proc 'status' entry. */	curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent);	if (!curr_table->status_proc) {		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n");		/* Destroy the created table */		spin_lock_bh(&recent_lock);		last_table = NULL;		curr_table = r_tables;		if(!curr_table) {#ifdef DEBUG			if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, no tables.\n");#endif			spin_unlock_bh(&recent_lock);			return 0;		}		while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) );		if(!curr_table) {#ifdef DEBUG			if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, table already destroyed.\n");#endif			spin_unlock_bh(&recent_lock);			return 0;		}		if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next;		spin_unlock_bh(&recent_lock);		vfree(curr_table->time_info);		vfree(curr_table->hash_table);		vfree(hold);		vfree(curr_table->table);		vfree(curr_table);		return 0;	}		curr_table->status_proc->owner = THIS_MODULE;	curr_table->status_proc->data = curr_table;	wmb();	curr_table->status_proc->read_proc = ip_recent_get_info;	curr_table->status_proc->write_proc = ip_recent_ctrl;#endif /* CONFIG_PROC_FS */#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() left.\n");#endif	return 1;}/* This function is called in the event that a rule matching this module is * removed. * When this happens we need to check if there are no other rules matching * the table given.  If that is the case then we remove the table and clean * up its memory. */static voiddestroy(void *matchinfo, unsigned int matchsize){	const struct ipt_recent_info *info = matchinfo;	struct recent_ip_tables *curr_table, *last_table;#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": destroy() entered.\n");#endif	if(matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return;	/* Lock the linked list while we play with it */	spin_lock_bh(&recent_lock);	/* Look for an entry with this name already created */	/* Finds the end of the list and the entry before the end if current name does not exist */	last_table = NULL;	curr_table = r_tables;	if(!curr_table) { #ifdef DEBUG		if(debug) printk(KERN_INFO RECENT_NAME ": destroy() No tables found, leaving.\n");#endif		spin_unlock_bh(&recent_lock);		return;	}	while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) );	/* If a table does not exist then do nothing and return */	if(!curr_table) { #ifdef DEBUG		if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table not found, leaving.\n");#endif		spin_unlock_bh(&recent_lock);		return;	}	curr_table->count--;	/* If count is still non-zero then there are still rules referenceing it so we do nothing */	if(curr_table->count) { #ifdef DEBUG		if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table found, non-zero count, leaving.\n");#endif		spin_unlock_bh(&recent_lock);		return;	}#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table found, zero count, removing.\n");#endif	/* Count must be zero so we remove this table from the list */	if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next;	spin_unlock_bh(&recent_lock);	/* lock to make sure any late-runners still using this after we removed it from	 * the list finish up then remove everything */	spin_lock_bh(&curr_table->list_lock);	spin_unlock_bh(&curr_table->list_lock);#ifdef CONFIG_PROC_FS	if(curr_table->status_proc) remove_proc_entry(curr_table->name,proc_net_ipt_recent);#endif /* CONFIG_PROC_FS */	vfree(curr_table->table[0].last_pkts);	vfree(curr_table->table);	vfree(curr_table->hash_table);	vfree(curr_table->time_info);	vfree(curr_table);#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": destroy() left.\n");#endif	return;}/* This is the structure we pass to ipt_register to register our * module with iptables. */static struct ipt_match recent_match = {   .name = "recent",   .match = &match,   .checkentry = &checkentry,   .destroy = &destroy,   .me = THIS_MODULE};/* Kernel module initialization. */static int __init init(void){	int err, count;	printk(version);#ifdef CONFIG_PROC_FS	proc_net_ipt_recent = proc_mkdir("ipt_recent",proc_net);	if(!proc_net_ipt_recent) return -ENOMEM;#endif	if(ip_list_hash_size && ip_list_hash_size <= ip_list_tot) {	  printk(KERN_WARNING RECENT_NAME ": ip_list_hash_size too small, resetting to default.\n");	  ip_list_hash_size = 0;	}	if(!ip_list_hash_size) {		ip_list_hash_size = ip_list_tot*3;		count = 2*2;		while(ip_list_hash_size > count) count = count*2;		ip_list_hash_size = count;	}#ifdef DEBUG	if(debug) printk(KERN_INFO RECENT_NAME ": ip_list_hash_size: %d\n",ip_list_hash_size);#endif	err = ipt_register_match(&recent_match);	if (err)		remove_proc_entry("ipt_recent", proc_net);	return err;}/* Kernel module destruction. */static void __exit fini(void){	ipt_unregister_match(&recent_match);	remove_proc_entry("ipt_recent",proc_net);}/* Register our module with the kernel. */module_init(init);module_exit(fini);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -