1--- ../kernel/linux-2.4.20-pre4/net/ipv4/netfilter/ip_tables.c 2002-08-29 01:56:13.000000000 +0200 2+++ linux-2.4.20-pre4/net/ipv4/netfilter/ip_tables.c 2002-08-29 20:30:37.000000000 +0200 3@@ -1699,14 +1699,15 @@ 4 = { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL }; 5 6 #ifdef CONFIG_PROC_FS 7-static inline int print_name(const struct ipt_table *t, 8+static inline int print_name(const char *i, 9 off_t start_offset, char *buffer, int length, 10 off_t *pos, unsigned int *count) 11 { 12 if ((*count)++ >= start_offset) { 13 unsigned int namelen; 14 15- namelen = sprintf(buffer + *pos, "%s\n", t->name); 16+ namelen = sprintf(buffer + *pos, "%s\n", 17+ i + sizeof(struct list_head)); 18 if (*pos + namelen > length) { 19 /* Stop iterating */ 20 return 1; 21@@ -1724,7 +1725,7 @@ 22 if (down_interruptible(&ipt_mutex) != 0) 23 return 0; 24 25- LIST_FIND(&ipt_tables, print_name, struct ipt_table *, 26+ LIST_FIND(&ipt_tables, print_name, void *, 27 offset, buffer, length, &pos, &count); 28 29 up(&ipt_mutex); 30@@ -1733,6 +1734,46 @@ 31 *start=(char *)((unsigned long)count-offset); 32 return pos; 33 } 34+ 35+static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) 36+{ 37+ off_t pos = 0; 38+ unsigned int count = 0; 39+ 40+ if (down_interruptible(&ipt_mutex) != 0) 41+ return 0; 42+ 43+ LIST_FIND(&ipt_target, print_name, void *, 44+ offset, buffer, length, &pos, &count); 45+ 46+ up(&ipt_mutex); 47+ 48+ *start = (char *)((unsigned long)count - offset); 49+ return pos; 50+} 51+ 52+static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) 53+{ 54+ off_t pos = 0; 55+ unsigned int count = 0; 56+ 57+ if (down_interruptible(&ipt_mutex) != 0) 58+ return 0; 59+ 60+ LIST_FIND(&ipt_match, print_name, void *, 61+ offset, buffer, length, &pos, &count); 62+ 63+ up(&ipt_mutex); 64+ 65+ *start = (char *)((unsigned long)count - offset); 66+ return pos; 67+} 68+ 69+static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = 70+{ { "ip_tables_names", ipt_get_tables }, 71+ { "ip_tables_targets", ipt_get_targets }, 72+ { "ip_tables_matches", ipt_get_matches }, 73+ { NULL, NULL} }; 74 #endif /*CONFIG_PROC_FS*/ 75 76 static int __init init(void) 77@@ -1758,13 +1799,19 @@ 78 #ifdef CONFIG_PROC_FS 79 { 80 struct proc_dir_entry *proc; 81+ int i; 82 83- proc = proc_net_create("ip_tables_names", 0, ipt_get_tables); 84- if (!proc) { 85- nf_unregister_sockopt(&ipt_sockopts); 86- return -ENOMEM; 87+ for (i = 0; ipt_proc_entry[i].name; i++) { 88+ proc = proc_net_create(ipt_proc_entry[i].name, 0, 89+ ipt_proc_entry[i].get_info); 90+ if (!proc) { 91+ while (--i >= 0) 92+ proc_net_remove(ipt_proc_entry[i].name); 93+ nf_unregister_sockopt(&ipt_sockopts); 94+ return -ENOMEM; 95+ } 96+ proc->owner = THIS_MODULE; 97 } 98- proc->owner = THIS_MODULE; 99 } 100 #endif 101 102@@ -1776,7 +1823,11 @@ 103 { 104 nf_unregister_sockopt(&ipt_sockopts); 105 #ifdef CONFIG_PROC_FS 106- proc_net_remove("ip_tables_names"); 107+ { 108+ int i; 109+ for (i = 0; ipt_proc_entry[i].name; i++) 110+ proc_net_remove(ipt_proc_entry[i].name); 111+ } 112 #endif 113 } 114 115