Skip site navigation (1)Skip section navigation (2)
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>