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>
index | next in thread | raw e-mail
[-- Attachment #1 --]
Hi all.
When looking thru the code (and manpage) in libalias i could see that
proxy_rules support udp packets. This is nice.. The only problem is that in
the udpPacketIn/out functions proxy rules is not checked. I wrote a small
patch that implements this and I've done some basic testing..
Patch is attached to this mail.
I couldn't see any maintainer for libalias and decided to write to -net. I
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.
[-- Attachment #2 --]
--- 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);
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200211111244.53738.lists>
