IP_AutoForward for 2.1.xx

Harald Hoyer (HarryH@Royal.Net)
Fri, 04 Apr 1997 17:05:23 +0200


This is a multi-part message in MIME format.
------------6A2BBD2B1FA3823C728930580
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=us-ascii

HI,

With some small modifications I ported autoforwarding to 2.1.xx.
My goal was to run a Quake-Server behind a Masq-Firewall.
First I run a patched kernel with the pure autoforwarding code.
Then I saw, that ip_masq_quake was not used to parse the connection.
After that added a line in ip_masq_app.c that also binds an incoming
connection
to a masq-app. Everything seems to work fine now, but since I added
the quake-server to the major quake-server-scanning-list, my masq-table
began to grow.
This was because the udp-timeout is 5 mins.
For Port-Forwarding this is quite stupid, because we know which daddr
belongs to
our maddr, so I added a mflag. Now, if portforwarding is done, an extra
udp-timeout
of 30*HZ is set.

Future implementations of masq-app-modules should implie bidirectional
masquing (like my
ip_masq_quake does :)).

Also, it would be nice to unbind a masq-app from a connection, within a
masq-app.

Quake-Server forwarding looks like this:

modprobe ip_masq_quake
ipautofw -A -v -p udp 26000 xxx.xxx.xxx.xxx:26000

where xxx.xxx.xxx.xxx is the IP of the host running the quake-server.

Any problems, suggestions or flames?

-- 
Harald Hoyer mailto:HarryH@Royal.Net http://home.pages.de/~saturn
_______________________________________________________________________________
Computers are like air conditioner. Both stop working, if you open
windows.
------------6A2BBD2B1FA3823C728930580
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="ip_autofw-patch.diff"
Content-Type: text/plain; charset=us-ascii; name="ip_autofw-patch.diff"

diff --recursive -u -B -b linux/Documentation/Configure.help linux-2.1.31/Documentation/Configure.help --- linux/Documentation/Configure.help Fri Apr 4 15:46:55 1997 +++ linux-2.1.31/Documentation/Configure.help Fri Apr 4 14:39:18 1997 @@ -1023,6 +1023,16 @@ inserted in and removed from the running kernel whenever you want; read Documentation/modules.txt for details. +IP: ipautofw masquerade support (EXPERIMENTAL) +CONFIG_IP_MASQUERADE_IPAUTOFW + ipautofw is a program by Richard Lynch allowing additional + support for masquerading protocols which do not (as yet) + have additional protocol helpers. + Information and source for ipautofw is available from + ftp://ftp.netis.com/pub/members/rlynch/ + This is EXPERIMENTAL code, which means that it need not be completely + stable. If you want this, say Y. + IP: always defragment CONFIG_IP_ALWAYS_DEFRAG This option means that all incoming fragments (= parts of IP packets diff --recursive -u -B -b linux/include/linux/ip_fw.h linux-2.1.31/include/linux/ip_fw.h --- linux/include/linux/ip_fw.h Sun Feb 2 15:45:57 1997 +++ linux-2.1.31/include/linux/ip_fw.h Fri Apr 4 15:35:49 1997 @@ -57,6 +57,7 @@ #include <linux/ip.h> #include <linux/tcp.h> #include <linux/udp.h> +#include <linux/config.h> struct ip_fw { @@ -127,6 +128,9 @@ #define IP_FW_OUT 2 #define IP_FW_ACCT 3 #define IP_FW_CHAINS 4 /* total number of ip_fw chains */ +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +#define IP_FW_AUTOFW 5 +#endif #define IP_FW_INSERT (IP_FW_BASE_CTL) #define IP_FW_APPEND (IP_FW_BASE_CTL+1) @@ -167,6 +171,12 @@ #define IP_ACCT_FLUSH (IP_FW_FLUSH | (IP_FW_ACCT << IP_FW_SHIFT)) #define IP_ACCT_ZERO (IP_FW_ZERO | (IP_FW_ACCT << IP_FW_SHIFT)) +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +#define IP_AUTOFW_ADD (IP_FW_APPEND | (IP_FW_AUTOFW << IP_FW_SHIFT)) +#define IP_AUTOFW_DEL (IP_FW_DELETE | (IP_FW_AUTOFW << IP_FW_SHIFT)) +#define IP_AUTOFW_FLUSH (IP_FW_FLUSH | (IP_FW_AUTOFW << IP_FW_SHIFT)) +#endif + struct ip_fwpkt { struct iphdr fwp_iph; /* IP header */ @@ -207,6 +217,9 @@ extern int ip_fw_fwd_policy; extern int ip_fw_ctl(int, void *, int); #endif +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +extern int ip_autofw_ctl(int, void *, int); +#endif #ifdef CONFIG_IP_ACCT extern struct ip_fw *ip_acct_chain; extern int ip_acct_ctl(int, void *, int); @@ -216,4 +229,33 @@ extern void ip_fw_init(void); #endif /* KERNEL */ +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +#define IP_FWD_RANGE 1 +#define IP_FWD_PORT 2 +#define IP_FWD_DIRECT 3 + +#define IP_AUTOFW_ACTIVE 1 +#define IP_AUTOFW_USETIME 2 +#define IP_AUTOFW_SECURE 4 + +struct ip_autofw { + struct ip_autofw * next; + __u16 type; + __u16 low; + __u16 hidden; + __u16 high; + __u16 visible; + __u16 protocol; + __u32 lastcontact; + __u32 where; + __u16 ctlproto; + __u16 ctlport; + __u16 flags; + struct timer_list timer; +}; +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + #endif /* _IP_FW_H */ + + + diff --recursive -u -B -b linux/include/linux/proc_fs.h linux-2.1.31/include/linux/proc_fs.h --- linux/include/linux/proc_fs.h Fri Apr 4 15:46:30 1997 +++ linux-2.1.31/include/linux/proc_fs.h Fri Apr 4 15:24:38 1997 @@ -98,6 +98,7 @@ PROC_NET_IPACCT, PROC_NET_IPMSQHST, PROC_NET_WIRELESS, + PROC_NET_IPAUTOFW, PROC_NET_IPX_INTERFACE, PROC_NET_IPX_ROUTE, PROC_NET_IPX, diff --recursive -u -B -b linux/include/net/ip_masq.h linux-2.1.31/include/net/ip_masq.h --- linux/include/net/ip_masq.h Sun Feb 2 15:45:57 1997 +++ linux-2.1.31/include/net/ip_masq.h Fri Apr 4 15:35:49 1997 @@ -20,6 +20,9 @@ #define MASQUERADE_EXPIRE_TCP 15*60*HZ #define MASQUERADE_EXPIRE_TCP_FIN 2*60*HZ #define MASQUERADE_EXPIRE_UDP 5*60*HZ +#define MASQUERADE_EXPIRE_AFWUDP 30*HZ + +#define IP_AUTOFW_EXPIRE 15*HZ #define IP_MASQ_F_OUT_SEQ 0x01 /* must do output seq adjust */ #define IP_MASQ_F_IN_SEQ 0x02 /* must do input seq adjust */ @@ -32,6 +35,7 @@ #define IP_MASQ_F_SAW_FIN (IP_MASQ_F_SAW_FIN_IN | \ IP_MASQ_F_SAW_FIN_OUT) /* tcp fin pkts seen */ +#define IP_MASQ_F_AFW_PORT 0x100 #ifdef __KERNEL__ @@ -69,6 +73,9 @@ int tcp_timeout; int tcp_fin_timeout; int udp_timeout; +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + int afw_udp_timeout; +#endif }; extern struct ip_fw_masq *ip_masq_expire; @@ -98,6 +105,9 @@ extern struct ip_masq *ip_masq_new(struct device *dev, int proto, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned flags); extern void ip_masq_set_expire(struct ip_masq *ms, unsigned long tout); +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +extern void ip_autofw_expire(unsigned long data); +#endif /* * @@ -166,6 +176,10 @@ * a segment of skb. */ extern struct sk_buff * ip_masq_skb_replace(struct sk_buff *skb, int pri, char *o_buf, int o_len, char *n_buf, int n_len); + +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +extern struct ip_autofw * ip_autofw_hosts; +#endif #endif /* __KERNEL__ */ diff --recursive -u -B -b linux/net/ipv4/Config.in linux-2.1.31/net/ipv4/Config.in --- linux/net/ipv4/Config.in Fri Apr 4 15:44:56 1997 +++ linux-2.1.31/net/ipv4/Config.in Fri Apr 4 14:39:13 1997 @@ -12,6 +12,9 @@ bool 'IP: masquerading' CONFIG_IP_MASQUERADE if [ "$CONFIG_IP_MASQUERADE" != "n" ]; then comment 'Protocol-specific masquerading support will be built as modules.' + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'IP: ipautofw masq support (EXPERIMENTAL)' CONFIG_IP_MASQUERADE_IPAUTOFW + fi fi bool 'IP: transparent proxy support' CONFIG_IP_TRANSPARENT_PROXY bool 'IP: always defragment' CONFIG_IP_ALWAYS_DEFRAG diff --recursive -u -B -b linux/net/ipv4/ip_fw.c linux-2.1.31/net/ipv4/ip_fw.c --- linux/net/ipv4/ip_fw.c Fri Apr 4 15:46:35 1997 +++ linux-2.1.31/net/ipv4/ip_fw.c Fri Apr 4 14:39:10 1997 @@ -905,6 +905,87 @@ } #endif +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + +int ip_autofw_add(struct ip_autofw * af) +{ + struct ip_autofw * newaf; + init_timer(&af->timer); + newaf = kmalloc( sizeof(struct ip_autofw), GFP_ATOMIC ); + memcpy(newaf, af, sizeof(struct ip_autofw)); + newaf->timer.data = (unsigned long) newaf; + newaf->timer.function = ip_autofw_expire; + newaf->timer.expires = 0; + newaf->lastcontact=0; + newaf->next=ip_autofw_hosts; + ip_autofw_hosts=newaf; + return(0); +} + +int ip_autofw_del(struct ip_autofw * af) +{ + struct ip_autofw * prev, * curr; + prev=NULL; + curr=ip_autofw_hosts; + while (curr) + { + if (af->type == curr->type && + af->low == curr->low && + af->high == curr->high && + af->hidden == curr->hidden && + af->visible == curr->visible && + af->protocol == curr->protocol && + af->where == curr->where && + af->ctlproto == curr->ctlproto && + af->ctlport == curr->ctlport) + { + if (prev) + { + prev->next=curr->next; + kfree_s(curr,sizeof(struct ip_autofw)); + return(0); + } + else + { + kfree_s(ip_autofw_hosts,sizeof(struct ip_autofw)); + ip_autofw_hosts=curr->next; + return(0); + } + } + prev=curr; + curr=curr->next; + } + return(EINVAL); +} + +int ip_autofw_flush(void) +{ + struct ip_autofw * af; + while (ip_autofw_hosts) + { + af=ip_autofw_hosts; + ip_autofw_hosts=ip_autofw_hosts->next; + kfree_s(af,sizeof(struct ip_autofw)); + } + return(0); +} + +int ip_autofw_ctl(int stage, void *m, int len) +{ + if (stage == IP_AUTOFW_ADD) + return (ip_autofw_add((struct ip_autofw *) m)); + + if (stage == IP_AUTOFW_DEL) + return (ip_autofw_del((struct ip_autofw *) m)); + + if (stage == IP_AUTOFW_FLUSH) + return (ip_autofw_flush()); + + return(EINVAL); +} + +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + #ifdef CONFIG_IP_FIREWALL int ip_fw_ctl(int stage, void *m, int len) { diff --recursive -u -B -b linux/net/ipv4/ip_masq.c linux-2.1.31/net/ipv4/ip_masq.c --- linux/net/ipv4/ip_masq.c Fri Apr 4 15:47:13 1997 +++ linux-2.1.31/net/ipv4/ip_masq.c Fri Apr 4 15:08:32 1997 @@ -15,6 +15,8 @@ * Nigel Metheringham : Added ICMP handling for demasquerade * Nigel Metheringham : Checksum checking of masqueraded data * Nigel Metheringham : Better handling of timeouts of TCP conns + * Richard Lynch : Added IP Autoforward + * Harald Hoyer : Added extra autofoward UDP-Timer and some fixes * * */ @@ -37,6 +38,7 @@ #include <net/udp.h> #include <net/checksum.h> #include <net/ip_masq.h> +#include <linux/ip_fw.h> #define IP_MASQ_TAB_SIZE 256 /* must be power of 2 */ @@ -94,11 +96,112 @@ static struct ip_fw_masq ip_masq_dummy = { MASQUERADE_EXPIRE_TCP, MASQUERADE_EXPIRE_TCP_FIN, - MASQUERADE_EXPIRE_UDP + MASQUERADE_EXPIRE_UDP, +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + MASQUERADE_EXPIRE_AFWUDP +#endif }; struct ip_fw_masq *ip_masq_expire = &ip_masq_dummy; +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +/* + * Auto-forwarding table + */ + +struct ip_autofw * ip_autofw_hosts = NULL; + +/* + * Check if a masq entry should be created for a packet + */ + +struct ip_autofw * ip_autofw_check_range (__u32 where, __u16 port, __u16 protocol, int reqact) +{ + struct ip_autofw *af; + af=ip_autofw_hosts; + port=ntohs(port); + while (af) + { + if (af->type==IP_FWD_RANGE && + port>=af->low && + port<=af->high && + protocol==af->protocol && + /* it's ok to create masq entries after the timeout if we're in insecure mode */ + (af->flags & IP_AUTOFW_ACTIVE || !reqact || !(af->flags & IP_AUTOFW_SECURE)) && + (!(af->flags & IP_AUTOFW_SECURE) || af->lastcontact==where || !reqact)) + return(af); + af=af->next; + } + return(NULL); +} + +struct ip_autofw * ip_autofw_check_port (__u16 port, __u16 protocol) +{ + struct ip_autofw *af; + af=ip_autofw_hosts; + port=ntohs(port); + while (af) + { + if (af->type==IP_FWD_PORT && port==af->visible && protocol==af->protocol) + return(af); + af=af->next; + } + return(NULL); +} + +struct ip_autofw * ip_autofw_check_direct (__u16 port, __u16 protocol) +{ + struct ip_autofw *af; + af=ip_autofw_hosts; + port=ntohs(port); + while (af) + { + if (af->type==IP_FWD_DIRECT && af->low<=port && af->high>=port) + return(af); + af=af->next; + } + return(NULL); +} + +void ip_autofw_update_out (__u32 who, __u32 where, __u16 outport, __u16 protocol) +{ + struct ip_autofw *af; + af=ip_autofw_hosts; + outport=ntohs(outport); + + while (af) + { + if (af->type==IP_FWD_RANGE && af->ctlport==outport && af->ctlproto==protocol) + { + if (af->flags & IP_AUTOFW_USETIME) + { + if (af->timer.expires) + del_timer(&af->timer); + af->timer.expires=jiffies+IP_AUTOFW_EXPIRE; + add_timer(&af->timer); + } + af->flags|=IP_AUTOFW_ACTIVE; + af->lastcontact=where; + af->where=who; + } + af=af->next; + } +} + +void ip_autofw_update_in (__u32 where, __u16 port, __u16 protocol) +{ +/* struct ip_autofw *af; + af=ip_autofw_check_range(where, port,protocol); + if (af) + { + del_timer(&af->timer); + af->timer.expires=jiffies+IP_AUTOFW_EXPIRE; + add_timer(&af->timer); + }*/ +} + +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + /* * Returns hash value */ @@ -332,13 +435,26 @@ restore_flags(flags); } +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +void ip_autofw_expire(unsigned long data) +{ + struct ip_autofw * af; + af=(struct ip_autofw *) data; + af->flags&=0xFFFF ^ IP_AUTOFW_ACTIVE; + af->timer.expires=0; + af->lastcontact=0; + if (af->flags & IP_AUTOFW_SECURE) + af->where=0; +} +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + /* * Create a new masquerade list entry, also allocate an * unused mport, keeping the portnumber between the * given boundaries MASQ_BEGIN and MASQ_END. */ -struct ip_masq * ip_masq_new(struct device *dev, int proto, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags) +struct ip_masq * ip_masq_new_enh(struct device *dev, int proto, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags, __u16 matchport) { struct ip_masq *ms, *mst; int ports_tried, *free_ports_p; @@ -372,7 +488,7 @@ ms->flags = mflags; ms->app_data = NULL; - if (proto == IPPROTO_UDP) + if (proto == IPPROTO_UDP && !matchport) ms->flags |= IP_MASQ_F_NO_DADDR; /* get masq address from rif */ @@ -386,7 +502,11 @@ * Try the next available port number */ + if (!matchport || ports_tried) ms->mport = htons(masq_port++); + else + ms->mport = matchport; + if (masq_port==PORT_MASQ_END) masq_port = PORT_MASQ_BEGIN; restore_flags(flags); @@ -396,7 +516,7 @@ */ mst = ip_masq_getbym(proto, ms->maddr, ms->mport); - if (mst == NULL) { + if (mst == NULL || matchport) { save_flags(flags); cli(); @@ -422,6 +542,11 @@ return NULL; } +struct ip_masq * ip_masq_new(struct device *dev, int proto, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags) +{ + return (ip_masq_new_enh(dev, proto, saddr, sport, daddr, dport, mflags, 0) ); +} + /* * Set masq expiration (deletion) and adds timer, * if timeout==0 cancel expiration. @@ -486,12 +611,34 @@ * Nope, not found, create a new entry for it */ +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + + /* update any ipautofw entries .. */ + + ip_autofw_update_out(iph->saddr, iph->daddr, portptr[1], iph->protocol); + +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + if (ms==NULL) { - ms = ip_masq_new(dev, iph->protocol, +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + /* if the source port is supposed to match the masq port, then + make it so */ + if (ip_autofw_check_direct(portptr[1],iph->protocol)) + ms = ip_masq_new_enh(dev, iph->protocol, iph->saddr, portptr[0], iph->daddr, portptr[1], + IP_MASQ_F_AFW_PORT, + portptr[0]); + else +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + ms = ip_masq_new_enh(dev, iph->protocol, + iph->saddr, portptr[0], + iph->daddr, portptr[1], + 0, 0); + + if (ms == NULL) return -1; } @@ -528,6 +675,11 @@ if (iph->protocol==IPPROTO_UDP) { +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + if(ms->flags & IP_MASQ_F_AFW_PORT) + timeout = ip_masq_expire->afw_udp_timeout; + else +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ timeout = ip_masq_expire->udp_timeout; recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,size); } @@ -570,12 +722,12 @@ ip_masq_set_expire(ms, timeout); ip_send_check(iph); - #ifdef DEBUG_CONFIG_IP_MASQUERADE +#ifdef DEBUG_CONFIG_IP_MASQUERADE printk("O-routed from %lX:%X over %s\n",ntohl(ms->maddr),ntohs(ms->mport),dev->name); - #endif +#endif return 0; - } +} /* @@ -768,7 +920,7 @@ } - /* +/* * Check if it's an masqueraded port, look it up, * and send it on its way... * @@ -785,6 +937,9 @@ struct ip_masq *ms; unsigned short len; unsigned long timeout; +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + struct ip_autofw *af; +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ switch (iph->protocol) { case IPPROTO_ICMP: @@ -793,8 +948,14 @@ case IPPROTO_UDP: /* Make sure packet is in the masq range */ portptr = (__u16 *)&(((char *)iph)[iph->ihl*4]); - if (ntohs(portptr[1]) < PORT_MASQ_BEGIN || + if ( (ntohs(portptr[1]) < PORT_MASQ_BEGIN || ntohs(portptr[1]) > PORT_MASQ_END) +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + && !ip_autofw_check_range(iph->saddr, portptr[1], iph->protocol, 0) + && !ip_autofw_check_direct(portptr[1], iph->protocol) + && !ip_autofw_check_port(portptr[1], iph->protocol) +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + ) return 0; /* Check that the checksum is OK */ len = ntohs(iph->tot_len) - (iph->ihl * 4); @@ -835,8 +996,38 @@ ms = ip_masq_in_get(iph); +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + + if (ms == NULL && (af=ip_autofw_check_range(iph->saddr, portptr[1], iph->protocol, 0))) + { +#ifdef DEBUG_CONFIG_IP_MASQUERADE + printk("ip_autofw_check_range\n"); +#endif + ms = ip_masq_new_enh(dev, iph->protocol, + af->where, portptr[1], + iph->saddr, portptr[0], + 0, + portptr[1]); + } + if ( ms == NULL && (af=ip_autofw_check_port(portptr[1], iph->protocol)) ) + { +#ifdef DEBUG_CONFIG_IP_MASQUERADE + printk("ip_autofw_check_port\n"); +#endif + ms = ip_masq_new_enh(dev, iph->protocol, + af->where, htons(af->hidden), + iph->saddr, portptr[0], + IP_MASQ_F_AFW_PORT, + htons(af->visible)); + } +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + if (ms != NULL) { +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + ip_autofw_update_in(iph->saddr, portptr[1], iph->protocol); +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + /* Stop the timer ticking.... */ ip_masq_set_expire(ms,0); @@ -847,7 +1038,7 @@ if ( ms->flags & IP_MASQ_F_NO_DPORT && ms->protocol == IPPROTO_TCP ) { ms->flags &= ~IP_MASQ_F_NO_DPORT; ms->dport = portptr[0]; -#if DEBUG_CONFIG_IP_MASQUERADE +#ifdef DEBUG_CONFIG_IP_MASQUERADE printk("ip_fw_demasquerade(): filled dport=%d\n", ntohs(ms->dport)); #endif @@ -855,7 +1046,7 @@ if (ms->flags & IP_MASQ_F_NO_DADDR && ms->protocol == IPPROTO_TCP) { ms->flags &= ~IP_MASQ_F_NO_DADDR; ms->daddr = iph->saddr; -#if DEBUG_CONFIG_IP_MASQUERADE +#ifdef DEBUG_CONFIG_IP_MASQUERADE printk("ip_fw_demasquerade(): filled daddr=%X\n", ntohs(ms->daddr)); #endif @@ -888,6 +1079,11 @@ if (iph->protocol==IPPROTO_UDP) { recalc_check((struct udphdr *)portptr,iph->saddr,iph->daddr,len); +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + if(ms->flags & IP_MASQ_F_AFW_PORT) + timeout = ip_masq_expire->afw_udp_timeout; + else +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ timeout = ip_masq_expire->udp_timeout; } else @@ -937,8 +1133,52 @@ } /* - * /proc/net entry + * /proc/net entries */ +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + +static int ip_autofw_procinfo(char *buffer, char **start, off_t offset, + int length, int unused) +{ + off_t pos=0, begin=0; + struct ip_autofw * af; + int len=0; + + len=sprintf(buffer,"Type Prot Low High Vis Hid Where Last CPto CPrt Timer\n"); + + for(af = ip_autofw_hosts; af ; af = af->next) + { + len+=sprintf(buffer+len,"%4X %4X %04X-%04X/%04X %04X %08lX %08lX %04X %04X %6lu %4X\n", + af->type, + af->protocol, + af->low, + af->high, + af->visible, + af->hidden, + ntohl(af->where), + ntohl(af->lastcontact), + af->ctlproto, + af->ctlport, + (af->timer.expires<jiffies ? 0 : af->timer.expires-jiffies), + af->flags + ); + + pos=begin+len; + if(pos<offset) + { + len=0; + begin=pos; + } + if(pos>offset+length) + break; + } + *start=buffer+(offset-begin); + len-=(offset-begin); + if(len>length) + len=length; + return len; +} +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ static int ip_msqhst_procinfo(char *buffer, char **start, off_t offset, int length, int unused) @@ -1005,6 +1245,17 @@ 0, &proc_net_inode_operations, ip_msqhst_procinfo }; + +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW +static struct proc_dir_entry proc_net_ipafwhst = { + PROC_NET_IPAUTOFW, 9, "ip_autofw", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + ip_autofw_procinfo +}; +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ + + #endif /* @@ -1014,6 +1265,9 @@ { #ifdef CONFIG_PROC_FS proc_net_register(&proc_net_ipmsqhst); +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + proc_net_register(&proc_net_ipafwhst); +#endif /* CONFIG_IP_MASQUERADE_IPAUTOFW */ #endif ip_masq_app_init(); diff --recursive -u -B -b linux/net/ipv4/ip_masq_app.c linux-2.1.31/net/ipv4/ip_masq_app.c --- linux/net/ipv4/ip_masq_app.c Fri Apr 4 15:47:13 1997 +++ linux-2.1.31/net/ipv4/ip_masq_app.c Fri Apr 4 14:00:56 1997 @@ -182,7 +182,9 @@ struct ip_masq_app * ip_masq_bind_app(struct ip_masq *ms) { struct ip_masq_app * mapp; - mapp = ip_masq_app_get(ms->protocol, ms->dport); + if(!(mapp = ip_masq_app_get(ms->protocol, ms->dport))) + mapp = ip_masq_app_get(ms->protocol, ms->sport); + if (mapp != NULL) { /* * don't allow binding if already bound diff --recursive -u -B -b linux/net/ipv4/ip_sockglue.c linux-2.1.31/net/ipv4/ip_sockglue.c --- linux/net/ipv4/ip_sockglue.c Fri Apr 4 15:45:39 1997 +++ linux-2.1.31/net/ipv4/ip_sockglue.c Fri Apr 4 14:53:58 1997 @@ -545,6 +545,21 @@ return -err; /* -0 is 0 after all */ #endif +#ifdef CONFIG_IP_MASQUERADE_IPAUTOFW + case IP_AUTOFW_ADD: + case IP_AUTOFW_DEL: + case IP_AUTOFW_FLUSH: + if(!suser()) + return -EPERM; + if(optlen>sizeof(tmp_fw) || optlen<1) + return -EINVAL; + err = copy_from_user(&tmp_fw, optval,optlen); + if(err) + return -EFAULT; + err=ip_autofw_ctl(optname, &tmp_fw,optlen); + return -err; /* -0 is 0 after all */ + +#endif #ifdef CONFIG_IP_ACCT case IP_ACCT_INSERT: case IP_ACCT_APPEND:

------------6A2BBD2B1FA3823C728930580--