lkml.org 
[lkml]   [1998]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: 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>)
\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.080 / U:0.068 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site