Messages in this thread Patch in this message | | | Date | Sun, 18 Oct 1998 03:27:59 +0200 (CEST) | From | Sascha Schumann <> | Subject | Re: Dynamic IP hack |
| |
On Sat, 17 Oct 1998, Malware wrote:
> I wrote: > > with Linux 2.0.34 the dynamic IP hack was included into the kernel. I > > migrated this feature to the 2.1.xx kernels. I know of many people who > > And as usual I forgot to append it. But now I did. > > > Malware
+ int want_rewrite = sysctl_ip_dynaddr & 4 || (sysctl_ip_dynaddr & 3 && sk->state == TCP_SYN_SENT); ^^^^^^^^^^^^^^^^^^^^^ [...] + if ( (sysctl_ip_dynaddr & 3) ^^^ [...] + if ( (sysctl_ip_dynaddr & 3 ) ^^^^^ [...]
+The values for the ip_dynaddr sysctl are: + + 1: To enable: + 2: To enable verbosity: + 4: To enable RST-provoking: + 8: To enable asymetric routing work-around
The behaviour of the code isn't correct in this context. A (sysctl & 3) is only true, if the user has enabled verbosity and will always be false, if he doesn't want to see something (`quiet mode').
I've adapted the patch to match the documented behaviour.
Sascha --- linux/net/ipv4/tcp_ipv4.c.orig Sat Oct 17 17:32:15 1998 +++ linux/net/ipv4/tcp_ipv4.c Sat Oct 17 17:40:39 1998 @@ -44,6 +44,10 @@ * Andi Kleen: various fixes. * Vitaly E. Lavrov : Transparent proxy revived after year coma. * Andi Kleen : Fix new listen. + * Michael Mueller : Adapted RST-provoking patch for 2.0.xx + * by Erik Corry. + * Implemented work-around for asymetric + * routing and ip_dynaddr. * Andi Kleen : Fix accept error reporting. */ @@ -1707,7 +1711,9 @@ { struct rtable *rt = (struct rtable *)sk->dst_cache; __u32 new_saddr; - int want_rewrite = sysctl_ip_dynaddr && sk->state == TCP_SYN_SENT; + struct device *dev; + + int want_rewrite = sysctl_ip_dynaddr & 4 || (sysctl_ip_dynaddr & 1 && sk->state == TCP_SYN_SENT); if(rt == NULL) return 0; @@ -1766,12 +1772,32 @@ return 0; } + /* this should also not be happend! */ + if (!new_saddr) { + printk(KERN_WARNING "tcp_v4_rebuild_header(): new source addrs" + "would be zero\n"); + return 0; + } + if (new_saddr != sk->saddr) { - if (sysctl_ip_dynaddr > 1) { + if (sysctl_ip_dynaddr & 2) { printk(KERN_INFO "tcp_v4_rebuild_header(): shifting sk->saddr " "from %d.%d.%d.%d to %d.%d.%d.%d\n", NIPQUAD(sk->saddr), NIPQUAD(new_saddr)); + } + + /* Check if there is not another interface having the + * new address. This should fix a problem with + * asymetric routing. + */ + if ( sysctl_ip_dynaddr&8 && (dev=ip_dev_find(sk->saddr)) ) + { + if (sysctl_ip_dynaddr & 2) { + printk(KERN_INFO "tcp_v4_rebuild_header(): shifting " + "skipped since device %s has matching addr\n", dev->name); + } + return 0; } sk->saddr = new_saddr; --- linux/net/ipv4/ip_masq.c.orig Sat Oct 17 17:32:14 1998 +++ linux/net/ipv4/ip_masq.c Sat Oct 17 18:03:46 1998 @@ -32,6 +32,10 @@ * Steven Clarke : IP_MASQ_S_xx state design * Juan Jose Ciarlante : IP_MASQ_S state implementation * Juan Jose Ciarlante : xx_get() clears timer, _put() inserts it + * Michael Mueller : Adapted RST-provoking patch for 2.0.xx + * by Erik Corry + * Implemented work-around for asymetric + * routing and ip_dynaddr * Juan Jose Ciarlante : create /proc/net/ip_masq/ * Juan Jose Ciarlante : reworked checksums (save payload csum if possible) * Juan Jose Ciarlante : added missing ip_fw_masquerade checksum @@ -977,6 +981,7 @@ struct iphdr *iph = skb->nh.iph; union ip_masq_tphdr h; struct ip_masq *ms; + struct device *dev; int size; /* @@ -1051,24 +1056,37 @@ if (ms!=NULL) { /* - * If sysctl !=0 and no pkt has been received yet - * in this tunnel and routing iface address has changed... + * If sysctl & 1 and either no pkt has been received yet + * in this tunnel or sysctl & 4 and routing interface + * address has changed... * "You are welcome, diald". */ - if ( sysctl_ip_dynaddr && ms->flags & IP_MASQ_F_NO_REPLY && maddr != ms->maddr) { + if ( (sysctl_ip_dynaddr & 1) + && (ms->flags & IP_MASQ_F_NO_REPLY || sysctl_ip_dynaddr & 4 ) + && (maddr != ms->maddr) + ) { + if ( sysctl_ip_dynaddr&8 && (dev=ip_dev_find(maddr)) ) + { + if ( sysctl_ip_dynaddr & 2 ) + { + IP_MASQ_INFO( "ip_fw_masquerade(): skipped changing masq.addr since " + "device %s does match %d.%d.%d.%d\n", dev->name, NIPQUAD(maddr)); + } + } else { + if ( sysctl_ip_dynaddr & 2 ) + { + IP_MASQ_INFO( "ip_fw_masquerade(): change masq.addr from " + "%d.%d.%d.%d to %d.%d.%d.%d\n", NIPQUAD(ms->maddr),NIPQUAD(maddr)); + } + + write_lock(&__ip_masq_lock); + + ip_masq_unhash(ms); + ms->maddr = maddr; + ip_masq_hash(ms); - if (sysctl_ip_dynaddr > 1) { - IP_MASQ_INFO( "ip_fw_masquerade(): change masq.addr from %d.%d.%d.%d to %d.%d.%d.%d\n", - NIPQUAD(ms->maddr),NIPQUAD(maddr)); - } - - write_lock(&__ip_masq_lock); - - ip_masq_unhash(ms); - ms->maddr = maddr; - ip_masq_hash(ms); - - write_unlock(&__ip_masq_lock); + write_unlock(&__ip_masq_lock); + } } /* @@ -1224,7 +1242,9 @@ struct iphdr *ciph; /* The ip header contained within the ICMP */ __u16 *pptr; /* port numbers from TCP/UDP contained header */ struct ip_masq *ms; + struct device *dev; unsigned short len = ntohs(iph->tot_len) - (iph->ihl * 4); + IP_MASQ_DEBUG(2, "Incoming forward ICMP (%d,%d) %lX -> %lX\n", icmph->type, ntohs(icmp_id(icmph)), @@ -1260,24 +1280,37 @@ /* Rewrite source address */ /* - * If sysctl !=0 and no pkt has been received yet - * in this tunnel and routing iface address has changed... + * If sysctl & 1 and either no pkt has been received yet + * in this tunnel or sysctl & 4 and routing interface + * address has changed... * "You are welcome, diald". */ - if ( sysctl_ip_dynaddr && ms->flags & IP_MASQ_F_NO_REPLY && maddr != ms->maddr) { - - if (sysctl_ip_dynaddr > 1) { - IP_MASQ_INFO( "ip_fw_masq_icmp(): change masq.addr %d.%d.%d.%d to %d.%d.%d.%d", - NIPQUAD(ms->maddr), NIPQUAD(maddr)); - } + if ( (sysctl_ip_dynaddr & 1 ) + && (ms->flags & IP_MASQ_F_NO_REPLY || sysctl_ip_dynaddr & 4) + && maddr != ms->maddr + ) { + if ( sysctl_ip_dynaddr&8 && (dev=ip_dev_find(maddr)) ) + { + if ( sysctl_ip_dynaddr & 2 ) + { + IP_MASQ_INFO( "ip_fw_masq_icmp(): skipped changing masq.addr since " + "device %s does match %d.%d.%d.%d\n", dev->name, NIPQUAD(maddr)); + } + } else { + if ( sysctl_ip_dynaddr & 2 ) + { + IP_MASQ_INFO( "ip_fw_masq_icmp(): change masq.addr from " + "%d.%d.%d.%d to %d.%d.%d.%d\n", NIPQUAD(ms->maddr),NIPQUAD(maddr)); + } - write_lock(&__ip_masq_lock); + write_lock(&__ip_masq_lock); - ip_masq_unhash(ms); - ms->maddr = maddr; - ip_masq_hash(ms); + ip_masq_unhash(ms); + ms->maddr = maddr; + ip_masq_hash(ms); - write_unlock(&__ip_masq_lock); + write_unlock(&__ip_masq_lock); + } } iph->saddr = ms->maddr; --- linux/Documentation/networking/ip_dynaddr.txt.orig Sat May 9 23:25:38 1998 +++ linux/Documentation/networking/ip_dynaddr.txt Sat Oct 17 17:40:39 1998 @@ -1,10 +1,10 @@ -IP dynamic address hack-port v0.03 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +IP dynamic address hack-port v0.03-rst2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This stuff allows diald ONESHOT connections to get established by dynamically changing packet source address (and socket's if local procs). It is implemented for TCP diald-box connections(1) and IP_MASQuerading(2). -If enabled[*] and forwarding interface has changed: +If enabled[*] and forwarding interface address has changed: 1) Socket (and packet) source address is rewritten ON RETRANSMISSIONS while in SYN_SENT state (diald-box processes). 2) Out-bounded MASQueraded source address changes ON OUTPUT (when @@ -16,14 +16,51 @@ going up. So, the *same* (local AND masqueraded) connections requests that bring the link up will be able to get established. -[*] At boot, by default no address rewriting is attempted. - To enable: +If you enable the RST-provoking mode, then the source address will +be changed, even if the socket is established. This means we send +an incorrect packet out, which causes the remote host to kill our +socket. This is the desired behaviour, because such a socket is +doomed anyway, and the earlier it dies, the better. This prevents +the dial-on-demand connection from being kept up by a dead connection, +and tells the application that the connection was lost. + +With the RST-provoking mode enabled it happens packets with the address +of another interface as source are rewritten and get a new source address +this way. If you have asymetric routing and the other interfaces have +static addresses enabling the work-around might[**] help you. + +[*] At boot, by default no address rewriting is attempted. +[**] This code is currently totaly untested. + +The values for the ip_dynaddr sysctl are: + + 1: To enable: + 2: To enable verbosity: + 4: To enable RST-provoking: + 8: To enable asymetric routing work-around + +Flags can be combined by adding them. Common settings +would be: + + To switch off special handling of dynamic addresses (default) + # echo 0 > /proc/sys/net/ipv4/ip_dynaddr + To enable rewriting in quiet mode: # echo 1 > /proc/sys/net/ipv4/ip_dynaddr - To enable verbose mode: + To enable rewriting in verbose mode: + # echo 3 > /proc/sys/net/ipv4/ip_dynaddr + (for backwards compatibility you can also use) # echo 2 > /proc/sys/net/ipv4/ip_dynaddr - To disable (default) - # echo 0 > /proc/sys/net/ipv4/ip_dynaddr + To enable quiet RST-provoking mode: + # echo 5 > /proc/sys/net/ipv4/ip_dynaddr + To enable verbose RST-provoking mode: + # echo 7 > /proc/sys/net/ipv4/ip_dynaddr + To enable quiet RST-provoking mode with asymetric routing work-around: + # echo 13 > /proc/sys/net/ipv4/ip_dynaddr + To enable verbose RST-provoking mode with asymetric routing work-around: + # echo 15 > /proc/sys/net/ipv4/ip_dynaddr Enjoy! -- Juanjo <jjciarla@raiz.uncu.edu.ar> +(with RST-provoking mode by Erik Corry <erik@arbat.com> and asymetric routing + work-around by Michael Mueller <Michael.Mueller4@post.rwth-aachen.de>) | |