diff -r -N -c libalias.org/Makefile libalias/Makefile
*** libalias.org/Makefile	Fri Jan 14 16:57:13 2000
--- libalias/Makefile	Sun May 21 00:42:36 2000
***************
*** 5,11 ****
  SHLIB_MINOR=	0
  CFLAGS+=	-Wall -I${.CURDIR}
  SRCS=		alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
! 		alias_nbt.c alias_proxy.c alias_util.c
  INCS=		alias.h
  MAN3=		libalias.3 
  
--- 5,11 ----
  SHLIB_MINOR=	0
  CFLAGS+=	-Wall -I${.CURDIR}
  SRCS=		alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
! 		alias_nbt.c alias_proxy.c alias_util.c alias_real.c
  INCS=		alias.h
  MAN3=		libalias.3 
  
diff -r -N -c libalias.org/alias.c libalias/alias.c
*** libalias.org/alias.c	Sat Sep 11 00:27:34 1999
--- libalias/alias.c	Sun May 28 23:50:25 2000
***************
*** 109,114 ****
--- 109,116 ----
  #define IRC_CONTROL_PORT_NUMBER_1 6667
  #define IRC_CONTROL_PORT_NUMBER_2 6668
  #define CUSEEME_PORT_NUMBER 7648
+ #define REAL_CONTROL_PORT_NUMBER_1 554
+ #define REAL_CONTROL_PORT_NUMBER_2 7070
  
  
  
***************
*** 982,987 ****
--- 984,992 ----
          if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1
           || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)
              AliasHandleIrcOut(pip, link, maxpacketsize);
+ 	if (ntohs(tc->th_dport) == REAL_CONTROL_PORT_NUMBER_1
+ 	 || ntohs(tc->th_dport) == REAL_CONTROL_PORT_NUMBER_2)
+ 	    AliasHandleRealOut(pip, link, maxpacketsize);
  
  /* Adjust TCP checksum since source port is being aliased */
  /* and source address is being altered                    */
diff -r -N -c libalias.org/alias_local.h libalias/alias_local.h
*** libalias.org/alias_local.h	Mon Aug 30 08:17:04 1999
--- libalias/alias_local.h	Sun Jun  4 13:59:32 2000
***************
*** 160,165 ****
--- 160,167 ----
  int ProxyCheck(struct ip *, struct in_addr *, u_short *);
  void ProxyModify(struct alias_link *, struct ip *, int, int);
  
+ /* Real routines */
+ void AliasHandleRealOut(struct ip *, struct alias_link *, int);
  
  enum alias_tcp_state {
      ALIAS_TCP_STATE_NOT_CONNECTED,
diff -r -N -c libalias.org/alias_real.c libalias/alias_real.c
*** libalias.org/alias_real.c	Thu Jan  1 09:00:00 1970
--- libalias/alias_real.c	Sun Jun  4 14:01:32 2000
***************
*** 0 ****
--- 1,279 ----
+ /*-
+  * Copyright (c) 2000  Junichi SATOH <junichi@astec.co.jp>
+  *                                   <junichi@junichi.org>
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  *
+  * $FreeBSD: $
+  */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <netinet/in_systm.h>
+ #include <netinet/in.h>
+ #include <netinet/ip.h>
+ #include <netinet/tcp.h>
+ #include <netinet/udp.h>
+ 
+ #include "alias_local.h"
+ 
+ #define ISDIGIT(a) (((a) >= '0') && ((a) <= '9'))
+ 
+ int search_string(char *data, int dlen, char *search_str)
+ {
+     int i, j, k;
+     int search_str_len;
+ 
+     search_str_len = strlen(search_str);
+     for (i = 0; i < dlen - search_str_len; i++) {
+ 	for (j = i, k = 0; j < dlen - search_str_len; j++, k++) {
+ 	    if (data[j] != search_str[k] &&
+ 		data[j] != search_str[k] - ('a' - 'A')) {
+ 		break;
+ 	    }
+ 	    if (k == search_str_len - 1) {
+ 		return j + 1;
+ 	    }
+ 	}
+     }
+     return -1;
+ }
+ 
+ int alias_rtsp_out(struct ip *pip,
+ 		   struct alias_link *link,
+ 		   char *data)
+ {
+     int hlen, tlen, dlen;
+     struct tcphdr *tc;
+ 
+     int i, pos, state, port_dlen, new_dlen, delta;
+     char *transport_str = "transport:";
+     char *client_port_str = "client_port";
+     u_short p[2], alias_port, new_len, sport, eport;
+     char newdata[2048], *port_data, *port_newdata, stemp[80];
+     struct alias_link *rtsp_link;
+ 
+     /* Calculate data length of TCP packet */
+     tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+     hlen = (pip->ip_hl + tc->th_off) << 2;
+     tlen = ntohs(pip->ip_len);
+     dlen = tlen - hlen;
+ 
+     /* Find keyword, "Transport: " */
+     pos = search_string(data, dlen, transport_str);
+     if (pos < 0) {
+ 	return -1;
+     }
+     port_data = data + pos;
+     port_dlen = dlen - pos;
+ 
+     memcpy(newdata, data, pos);
+     port_newdata = newdata + pos;
+ 
+     while (port_dlen > strlen(client_port_str)) {
+ 	/* Find keyword, "client_port" */
+ 	pos = search_string(port_data, port_dlen, client_port_str);
+ 	if (pos < 0) {
+ 	    break;
+ 	}
+ 
+ 	memcpy (port_newdata, port_data, pos + 1);
+ 	port_newdata += (pos + 1);
+ 
+ 	p[0] = p[1] = 0;
+ 	sport = eport = 0;
+ 	state = 0;
+ 	for (i = pos; i < port_dlen; i++) {
+ 	    switch(state) {
+ 	    case 0:
+ 		if (port_data[i] == '=') {
+ 		    state++;
+ 		}
+ 		break;
+ 	    case 1:
+ 		if (ISDIGIT(port_data[i])) {
+ 		    p[0] = p[0] * 10 + port_data[i] - '0';
+ 		} else {
+ 		    if (port_data[i] == ';') {
+ 			state = 3;
+ 		    }
+ 		    if (port_data[i] == '-') {
+ 			state++;
+ 		    }
+ 		}
+ 		break;
+ 	    case 2:
+ 		if (ISDIGIT(port_data[i])) {
+ 		    p[1] = p[1] * 10 + port_data[i] - '0';
+ 		} else {
+ 		    state++;
+ 		}
+ 		break;
+ 	    case 3:
+ 		sport = htons(p[0]);
+ 		eport = htons(p[1]);
+ 		rtsp_link = FindUdpTcpOut(pip->ip_src, GetDestAddress(link),
+ 					  sport, 0, IPPROTO_UDP);
+ 		if (rtsp_link != NULL) {
+ #ifndef NO_FW_PUNCH
+ 		    /* Puhch hole in firewall */
+ 		    PunchFWHole(rtsp_link);
+ #endif
+ 		    alias_port = GetAliasPort(rtsp_link);
+ 		    
+ 		    /* Copy into IP packet */
+ 		    sprintf(stemp, "%d", ntohs(alias_port));
+ 		    memcpy(port_newdata, stemp, strlen(stemp));
+ 		    port_newdata += strlen(stemp);
+ 		}
+ 		if (eport != 0) {
+ 		    *port_newdata = '-';
+ 		    port_newdata++;
+ 		    rtsp_link = FindUdpTcpOut(pip->ip_src,
+ 					      GetDestAddress(link),
+ 					      eport, 0, IPPROTO_UDP);
+ 		    if (rtsp_link != NULL) {
+ #ifndef NO_FW_PUNCH
+ 			/* Puhch hole in firewall */
+ 			PunchFWHole(rtsp_link);
+ #endif
+ 			alias_port = GetAliasPort(rtsp_link);
+ 		    
+ 			/* Copy into IP packet */
+ 			sprintf(stemp, "%d", ntohs(alias_port));
+ 			memcpy(port_newdata, stemp, strlen(stemp));
+ 			port_newdata += strlen(stemp);
+ 		    }
+ 		}
+ 		*port_newdata = ';';
+ 		port_newdata++;
+ 		state++;
+ 		break;
+ 	    }
+ 	    if (state > 3) {
+ 		break;
+ 	    }
+ 	}
+ 	port_data += i;
+ 	port_dlen -= i;
+     }
+ 
+     memcpy (port_newdata, port_data, port_dlen);
+     port_newdata += port_dlen;
+     *port_newdata = '\0';
+ 
+     /* Create new packet */
+     new_dlen = port_newdata - newdata;
+     memcpy (data, newdata, new_dlen);
+ 
+     SetAckModified(link);
+     delta = GetDeltaSeqOut(pip, link);
+     AddSeq(pip, link, delta + new_dlen - dlen);
+ 
+     new_len = htons(hlen + new_dlen);
+     DifferentialChecksum(&pip->ip_sum,
+ 			 &new_len,
+ 			 &pip->ip_len,
+ 			 1);
+     pip->ip_len = new_len;
+ 
+     tc->th_sum = 0;
+     tc->th_sum = TcpChecksum(pip);
+ 
+     return 0;
+ }
+ 
+ int alias_pna_out(struct ip *pip,
+ 		  struct alias_link *link,
+ 		  char *data,
+ 		  int dlen)
+ {
+     struct alias_link *pna_links;
+     u_short msg_id, msg_len;
+     char *work;
+     u_short alias_port, port;
+     struct tcphdr *tc;
+ 
+     work = data;
+     work += 5;
+     while (work + 4 < data + dlen) {
+ 	memcpy(&msg_id, work, 2);
+ 	work += 2;
+ 	memcpy(&msg_len, work, 2);
+ 	work += 2;
+ 	if (ntohs(msg_id) == 0) {
+ 	    /* end of options */
+ 	    return 0;
+ 	}
+ 	if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) {
+ 	    memcpy((char*)&port, (char*)work, 2);
+ 	    pna_links = FindUdpTcpOut(pip->ip_src, GetDestAddress(link),
+ 				      port, 0, IPPROTO_UDP);
+ 	    if (pna_links != NULL) {
+ #ifndef NO_FW_PUNCH
+ 		/* Puhch hole in firewall */
+ 		PunchFWHole(pna_links);
+ #endif
+ 		tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
+ 		alias_port = GetAliasPort(pna_links);
+ 		memcpy((char*)work, (char*)&alias_port, 2);
+ 
+ 		/* Compute TCP checksum for revised packet */
+ 		tc->th_sum = 0;
+ 		tc->th_sum = TcpChecksum(pip);
+ 	    }
+ 	}
+ 	work += ntohs(msg_len);
+     }
+     
+     return 0;
+ }
+ 
+ void
+ AliasHandleRealOut(struct ip *pip, struct alias_link *link, int maxpacketsize)
+ {
+     int hlen, tlen, dlen;
+     struct tcphdr *tc;
+     char *data, *setup = "SETUP", *pna = "PNA";
+ 
+     tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
+     hlen = (pip->ip_hl + tc->th_off) << 2;
+     tlen = ntohs(pip->ip_len);
+     dlen = tlen - hlen;
+ 
+     data = (char*)pip;
+     data += hlen;
+ 
+     if (dlen >= strlen(setup)) {
+ 	if (memcmp(data, setup, strlen(setup)) == 0) {
+ 	    alias_rtsp_out(pip, link, data);
+ 	    return;
+ 	}
+     }
+     if (dlen >= strlen(pna)) {
+ 	if (memcmp(data, pna, strlen(pna)) == 0) {
+ 	    alias_pna_out(pip, link, data, dlen);
+ 	}
+     }
+ }
