Date: Mon, 11 Nov 2002 12:44:53 +0100 From: lists@petri.cc To: freebsd-net@freebsd.org Subject: Bug/Missing implementation of udp proxying in libalias. Message-ID: <200211111244.53738.lists@petri.cc>
next in thread | raw e-mail | index | archive | help
--------------Boundary-00=_TYTE2F5GVBK3WZSJLYUT Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi all. When looking thru the code (and manpage) in libalias i could see that=20 proxy_rules support udp packets. This is nice.. The only problem is that = in=20 the udpPacketIn/out functions proxy rules is not checked. I wrote a small= =20 patch that implements this and I've done some basic testing..=20 Patch is attached to this mail. I couldn't see any maintainer for libalias and decided to write to -net. = I=20 hope this is the right list :) Comments ? --- Nicolai Petri catpipe Systems ApS Copenhagen / Denmark Ps. A volunteering commiter would be nice if the patch looks sane. --------------Boundary-00=_TYTE2F5GVBK3WZSJLYUT Content-Type: text/x-diff; charset="us-ascii"; name="alias_udp_patch.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="alias_udp_patch.diff" --- alias.c.orig Fri Nov 8 14:45:08 2002 +++ alias.c Mon Nov 11 11:38:46 2002 @@ -257,7 +257,7 @@ static int ProtoAliasIn(struct ip *); static int ProtoAliasOut(struct ip *); -static int UdpAliasOut(struct ip *); +static int UdpAliasOut(struct ip *, int); static int UdpAliasIn (struct ip *); static int TcpAliasOut(struct ip *, int); @@ -744,28 +744,28 @@ struct udphdr *ud; struct alias_link *link; -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) - return PKT_ALIAS_OK; - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); link = FindUdpTcpIn(pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport, - IPPROTO_UDP, 1); + IPPROTO_UDP, !(packetAliasMode & PKT_ALIAS_PROXY_ONLY)); if (link != NULL) { struct in_addr alias_address; struct in_addr original_address; + struct in_addr proxy_address; u_short alias_port; + u_short proxy_port; int accumulate; u_short *sptr; - int r = 0; + int r = 0; alias_address = GetAliasAddress(link); original_address = GetOriginalAddress(link); + proxy_address = GetProxyAddress(link); alias_port = ud->uh_dport; ud->uh_dport = GetOriginalPort(link); + proxy_port = GetProxyPort(link); /* Special processing for IP encoding protocols */ if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER) @@ -791,14 +791,48 @@ sptr = (u_short *) &original_address; accumulate -= *sptr++; accumulate -= *sptr; + +/* If this is a proxy packet, modify checksum because of source change.*/ + if (proxy_port != 0) + { + accumulate += ud->uh_sport; + accumulate -= proxy_port; + } + + if (proxy_address.s_addr != 0) + { + sptr = (u_short *) &pip->ip_src; + accumulate += *sptr++; + accumulate += *sptr; + sptr = (u_short *) &proxy_address; + accumulate -= *sptr++; + accumulate -= *sptr; + } + ADJUST_CHECKSUM(accumulate, ud->uh_sum); + } +/* XXX: Could the two if's below be concatenated to one ? */ +/* Restore source port and/or address in case of proxying*/ + + if (proxy_port != 0) + ud->uh_sport = proxy_port; + + if (proxy_address.s_addr != 0) + { + DifferentialChecksum(&pip->ip_sum, + (u_short *) &proxy_address, + (u_short *) &pip->ip_src, + 2); + pip->ip_src = proxy_address; + } + /* Restore original IP address */ DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); + (u_short *) &original_address, + (u_short *) &pip->ip_dst, + 2); pip->ip_dst = original_address; /* @@ -813,16 +847,57 @@ } static int -UdpAliasOut(struct ip *pip) +UdpAliasOut(struct ip *pip, int maxpacketsize) { struct udphdr *ud; struct alias_link *link; + int proxy_type; + u_short dest_port; + u_short proxy_server_port; + struct in_addr dest_address; + struct in_addr proxy_server_address; -/* Return if proxy-only mode is enabled */ - if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) +/* Return if proxy-only mode is enabled and not proxyrule found.*/ + ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); + + proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port); + + if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY)) return PKT_ALIAS_OK; - ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); +/* If this is a transparent proxy, save original destination, + then alter the destination and adjust checksums */ + dest_port = ud->uh_dport; + dest_address = pip->ip_dst; + + if (proxy_type != 0) + { + int accumulate; + u_short *sptr; + + accumulate = ud->uh_dport; + ud->uh_dport = proxy_server_port; + accumulate -= ud->uh_dport; + + sptr = (u_short *) &(pip->ip_dst); + accumulate += *sptr++; + accumulate += *sptr; + sptr = (u_short *) &proxy_server_address; + accumulate -= *sptr++; + accumulate -= *sptr; + + ADJUST_CHECKSUM(accumulate, ud->uh_sum); + + sptr = (u_short *) &(pip->ip_dst); + accumulate = *sptr++; + accumulate += *sptr; + pip->ip_dst = proxy_server_address; + sptr = (u_short *) &(pip->ip_dst); + accumulate -= *sptr++; + accumulate -= *sptr; + + ADJUST_CHECKSUM(accumulate, pip->ip_sum); + } link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport, @@ -832,6 +907,17 @@ u_short alias_port; struct in_addr alias_address; +/* Save original destination address, if this is a proxy packet. + Also modify packet to include destination encoding. This may + change the size of IP header. */ + if (proxy_type != 0) + { + SetProxyPort(link, dest_port); + SetProxyAddress(link, dest_address); + ProxyModify(link, pip, maxpacketsize, proxy_type); + ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); + } + alias_address = GetAliasAddress(link); alias_port = GetAliasPort(link); @@ -1092,7 +1178,7 @@ else if (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1 || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_1 || ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2 - || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) + || ntohs(tc->th_sport) == RTSP_CONTROL_PORT_NUMBER_2) AliasHandleRtspOut(pip, link, maxpacketsize); else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) @@ -1434,7 +1520,7 @@ iresult = IcmpAliasOut(pip); break; case IPPROTO_UDP: - iresult = UdpAliasOut(pip); + iresult = UdpAliasOut(pip, maxpacketsize); break; case IPPROTO_TCP: iresult = TcpAliasOut(pip, maxpacketsize); --------------Boundary-00=_TYTE2F5GVBK3WZSJLYUT-- 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?200211111244.53738.lists>