Date: Wed, 23 Aug 2000 18:26:52 +0300 From: Ruslan Ermilov <ru@FreeBSD.org> To: net@FreeBSD.org Cc: Charles Mott <cmott@scientech.com>, Erik Salander <erik@whistle.com>, Brian Somers <brian@FreeBSD.org>, Eivind Eklund <eivind@FreeBSD.org> Subject: libalias(3) ICMP bugs Message-ID: <20000823182652.A65441@sunbay.com>
next in thread | raw e-mail | index | archive | help
--3MwIy2ne0vdjdPXF Content-Type: text/plain; charset=us-ascii Hi! The following patch addresses some issues with aliasing/dealiasing ICMP packets. Unfortunately, I have no enough time now to describe all the possible symptoms, but if you have some spare weekend time, I would really appreciate it if you could test the following: 1) Suppose you have ed0 interface on your NAT box. 2) Bind two public IP addresses to it, say x.x.x.1 and x.x.x.2. 3) Run `natd -a x.x.x.1 -v'. 4) Run `tcpdump -n ed0 icmp'. 5) From another host x.x.x.3 on the same (ed0) network issue a `ping -n -c1 x.x.x.2' then `traceroute -q1 -n x.x.x.2' 6) Remove x.x.x.2 as an alias address from ed0 interface, on the host x.x.x.3 add the static route to x.x.x.2 via x.x.x.1. Then run `traceroute -q1 -n -m1 x.x.x.2'. Watch the tcpdump(8) and natd(8) output on the host x.x.x.1 and ping(8) and traceroute(8) output on host x.x.x.3, then compare them with and without this patch. Your comments are highly appreciated! Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --3MwIy2ne0vdjdPXF Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p Index: alias.c =================================================================== RCS file: /home/ncvs/src/lib/libalias/alias.c,v retrieving revision 1.21 diff -u -p -r1.21 alias.c --- alias.c 2000/07/26 23:15:46 1.21 +++ alias.c 2000/08/23 15:11:27 @@ -180,8 +180,8 @@ TcpMonitorOut(struct ip *pip, struct ali /* Protocol Specific Packet Aliasing Routines - IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2(), IcmpAliasIn3() - IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2(), IcmpAliasOut3() + IcmpAliasIn(), IcmpAliasIn1(), IcmpAliasIn2() + IcmpAliasOut(), IcmpAliasOut1(), IcmpAliasOut2() ProtoAliasIn(), ProtoAliasOut() UdpAliasIn(), UdpAliasOut() TcpAliasIn(), TcpAliasOut() @@ -222,12 +222,10 @@ the gateway machine or other machines on /* Local prototypes */ static int IcmpAliasIn1(struct ip *); static int IcmpAliasIn2(struct ip *); -static int IcmpAliasIn3(struct ip *); static int IcmpAliasIn (struct ip *); static int IcmpAliasOut1(struct ip *); static int IcmpAliasOut2(struct ip *); -static int IcmpAliasOut3(struct ip *); static int IcmpAliasOut (struct ip *); static int ProtoAliasIn(struct ip *); @@ -396,21 +394,6 @@ fragment contained in ICMP data section return(PKT_ALIAS_IGNORED); } -static int -IcmpAliasIn3(struct ip *pip) -{ - struct in_addr original_address; - - original_address = FindOriginalAddress(pip->ip_dst); - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); - pip->ip_dst = original_address; - - return PKT_ALIAS_OK; -} - static int IcmpAliasIn(struct ip *pip) @@ -442,7 +425,7 @@ IcmpAliasIn(struct ip *pip) break; case ICMP_ECHO: case ICMP_TSTAMP: - iresult = IcmpAliasIn3(pip); + iresult = IcmpAliasIn1(pip); break; } return(iresult); @@ -537,7 +520,7 @@ IcmpAliasOut2(struct ip *pip) { u_short *sptr; int accumulate; - struct in_addr alias_address; + struct in_addr alias_address, icmp_alias_address; u_short alias_port; alias_address = GetAliasAddress(link); @@ -555,11 +538,15 @@ IcmpAliasOut2(struct ip *pip) ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) /* Alias address in IP header */ + if (pip->ip_src.s_addr == ip->ip_dst.s_addr) + icmp_alias_address = alias_address; + else + icmp_alias_address = FindAliasAddress(pip->ip_src); DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, + (u_short *) &icmp_alias_address, (u_short *) &pip->ip_src, 2); - pip->ip_src = alias_address; + pip->ip_src = icmp_alias_address; /* Alias address and port number of original IP packet fragment contained in ICMP data section */ @@ -570,7 +557,7 @@ fragment contained in ICMP data section { u_short *sptr; int accumulate; - struct in_addr alias_address; + struct in_addr alias_address, icmp_alias_address; u_short alias_id; alias_address = GetAliasAddress(link); @@ -588,11 +575,15 @@ fragment contained in ICMP data section ADJUST_CHECKSUM(accumulate, ic->icmp_cksum) /* Alias address in IP header */ + if (pip->ip_src.s_addr == ip->ip_dst.s_addr) + icmp_alias_address = alias_address; + else + icmp_alias_address = FindAliasAddress(pip->ip_src); DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, + (u_short *) &icmp_alias_address, (u_short *) &pip->ip_src, 2); - pip->ip_src = alias_address; + pip->ip_src = icmp_alias_address; /* Alias address of original IP packet and sequence number of embedded ICMP datagram */ @@ -606,27 +597,6 @@ fragment contained in ICMP data section static int -IcmpAliasOut3(struct ip *pip) -{ -/* - Handle outgoing echo and timestamp replies. The - only thing which is done in this case is to alias - the source IP address of the packet. -*/ - struct in_addr alias_addr; - - alias_addr = FindAliasAddress(pip->ip_src); - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_addr, - (u_short *) &pip->ip_src, - 2); - pip->ip_src = alias_addr; - - return PKT_ALIAS_OK; -} - - -static int IcmpAliasOut(struct ip *pip) { int iresult; @@ -656,7 +626,7 @@ IcmpAliasOut(struct ip *pip) break; case ICMP_ECHOREPLY: case ICMP_TSTAMPREPLY: - iresult = IcmpAliasOut3(pip); + iresult = IcmpAliasOut1(pip); } return(iresult); } Index: alias_db.c =================================================================== RCS file: /home/ncvs/src/lib/libalias/alias_db.c,v retrieving revision 1.37 diff -u -p -r1.37 alias_db.c --- alias_db.c 2000/08/14 15:24:47 1.37 +++ alias_db.c 2000/08/23 15:11:28 @@ -1401,9 +1401,22 @@ FindIcmpIn(struct in_addr dst_addr, struct in_addr alias_addr, u_short id_alias) { - return FindLinkIn(dst_addr, alias_addr, + struct alias_link *link; + + link = FindLinkIn(dst_addr, alias_addr, NO_DEST_PORT, id_alias, LINK_ICMP, 0); + if (link == NULL && !(packetAliasMode & PKT_ALIAS_DENY_INCOMING)) + { + struct in_addr target_addr; + + target_addr = FindOriginalAddress(alias_addr); + link = AddLink(target_addr, dst_addr, alias_addr, + id_alias, NO_DEST_PORT, id_alias, + LINK_ICMP); + } + + return (link); } --3MwIy2ne0vdjdPXF-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000823182652.A65441>