summaryrefslogtreecommitdiffstats
path: root/lib/libalias/alias_smedia.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalias/alias_smedia.c')
-rw-r--r--lib/libalias/alias_smedia.c445
1 files changed, 0 insertions, 445 deletions
diff --git a/lib/libalias/alias_smedia.c b/lib/libalias/alias_smedia.c
deleted file mode 100644
index 888937c..0000000
--- a/lib/libalias/alias_smedia.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * alias_smedia.c
- *
- * Copyright (c) 2000 Whistle Communications, Inc.
- * All rights reserved.
- *
- * Subject to the following obligations and disclaimer of warranty, use and
- * redistribution of this software, in source or object code forms, with or
- * without modifications are expressly permitted by Whistle Communications;
- * provided, however, that:
- * 1. Any and all reproductions of the source or object code must include the
- * copyright notice above and the following disclaimer of warranties; and
- * 2. No rights are granted, in any manner or form, to use Whistle
- * Communications, Inc. trademarks, including the mark "WHISTLE
- * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
- * such appears in the above copyright notice or in the software.
- *
- * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
- * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
- * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
- * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
- * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
- * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
- * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
- * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * 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.
- *
- * Authors: Erik Salander <erik@whistle.com>
- * Junichi SATOH <junichi@astec.co.jp>
- * <junichi@junichi.org>
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- Alias_smedia.c is meant to contain the aliasing code for streaming media
- protocols. It performs special processing for RSTP sessions under TCP.
- Specifically, when a SETUP request is sent by a client, or a 200 reply
- is sent by a server, it is intercepted and modified. The address is
- changed to the gateway machine and an aliasing port is used.
-
- More specifically, the "client_port" configuration parameter is
- parsed for SETUP requests. The "server_port" configuration parameter is
- parsed for 200 replies eminating from a server. This is intended to handle
- the unicast case.
-
- RTSP also allows a redirection of a stream to another client by using the
- "destination" configuration parameter. The destination config parm would
- indicate a different IP address. This function is NOT supported by the
- RTSP translation code below.
-
- The RTSP multicast functions without any address translation intervention.
-
- For this routine to work, the SETUP/200 must fit entirely
- into a single TCP packet. This is typically the case, but exceptions
- can easily be envisioned under the actual specifications.
-
- Probably the most troubling aspect of the approach taken here is
- that the new SETUP/200 will typically be a different length, and
- this causes a certain amount of bookkeeping to keep track of the
- changes of sequence and acknowledgment numbers, since the client
- machine is totally unaware of the modification to the TCP stream.
-
- Initial version: May, 2000 (eds)
-*/
-
-#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 RTSP_CONTROL_PORT_NUMBER_1 554
-#define RTSP_CONTROL_PORT_NUMBER_2 7070
-#define RTSP_PORT_GROUP 2
-
-#define ISDIGIT(a) (((a) >= '0') && ((a) <= '9'))
-
-static int
-search_string(char *data, int dlen, const 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);
-}
-
-static int
-alias_rtsp_out(struct libalias *la, struct ip *pip,
- struct alias_link *lnk,
- char *data,
- const char *port_str)
-{
- int hlen, tlen, dlen;
- struct tcphdr *tc;
- int i, j, pos, state, port_dlen, new_dlen, delta;
- u_short p[2], new_len;
- u_short sport, eport, base_port;
- u_short salias = 0, ealias = 0, base_alias = 0;
- const char *transport_str = "transport:";
- char newdata[2048], *port_data, *port_newdata, stemp[80];
- int links_created = 0, pkt_updated = 0;
- struct alias_link *rtsp_lnk = NULL;
- struct in_addr null_addr;
-
- /* Calculate data length of TCP packet */
- tc = (struct tcphdr *)ip_next(pip);
- 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 > (int)strlen(port_str)) {
- /* Find keyword, appropriate port string */
- pos = search_string(port_data, port_dlen, 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:
- base_port = p[0];
- sport = htons(p[0]);
- eport = htons(p[1]);
-
- if (!links_created) {
-
- links_created = 1;
- /*
- * Find an even numbered port
- * number base that satisfies the
- * contiguous number of ports we
- * need
- */
- null_addr.s_addr = 0;
- if (0 == (salias = FindNewPortGroup(la, null_addr,
- FindAliasAddress(la, pip->ip_src),
- sport, 0,
- RTSP_PORT_GROUP,
- IPPROTO_UDP, 1))) {
-#ifdef DEBUG
- fprintf(stderr,
- "PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n");
-#endif
- } else {
-
- base_alias = ntohs(salias);
- for (j = 0; j < RTSP_PORT_GROUP; j++) {
- /*
- * Establish link
- * to port found in
- * RTSP packet
- */
- rtsp_lnk = FindRtspOut(la, GetOriginalAddress(lnk), null_addr,
- htons(base_port + j), htons(base_alias + j),
- IPPROTO_UDP);
- if (rtsp_lnk != NULL) {
-#ifndef NO_FW_PUNCH
- /*
- * Punch
- * hole in
- * firewall
- */
- PunchFWHole(rtsp_lnk);
-#endif
- } else {
-#ifdef DEBUG
- fprintf(stderr,
- "PacketAlias/RTSP: Cannot allocate RTSP data ports\n");
-#endif
- break;
- }
- }
- }
- ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
- }
- if (salias && rtsp_lnk) {
-
- pkt_updated = 1;
-
- /* Copy into IP packet */
- sprintf(stemp, "%d", ntohs(salias));
- memcpy(port_newdata, stemp, strlen(stemp));
- port_newdata += strlen(stemp);
-
- if (eport != 0) {
- *port_newdata = '-';
- port_newdata++;
-
- /* Copy into IP packet */
- sprintf(stemp, "%d", ntohs(ealias));
- 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;
- }
-
- if (!pkt_updated)
- return (-1);
-
- 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(lnk);
- delta = GetDeltaSeqOut(pip, lnk);
- AddSeq(pip, lnk, 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);
-}
-
-/* Support the protocol used by early versions of RealPlayer */
-
-static int
-alias_pna_out(struct libalias *la, struct ip *pip,
- struct alias_link *lnk,
- 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(&port, work, 2);
- pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(lnk),
- port, 0, IPPROTO_UDP, 1);
- if (pna_links != NULL) {
-#ifndef NO_FW_PUNCH
- /* Punch hole in firewall */
- PunchFWHole(pna_links);
-#endif
- tc = (struct tcphdr *)ip_next(pip);
- alias_port = GetAliasPort(pna_links);
- memcpy(work, &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
-AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, int maxpacketsize)
-{
- int hlen, tlen, dlen;
- struct tcphdr *tc;
- char *data;
- const char *setup = "SETUP", *pna = "PNA", *str200 = "200";
- const char *okstr = "OK", *client_port_str = "client_port";
- const char *server_port_str = "server_port";
- int i, parseOk;
-
- (void)maxpacketsize;
-
- tc = (struct tcphdr *)ip_next(pip);
- hlen = (pip->ip_hl + tc->th_off) << 2;
- tlen = ntohs(pip->ip_len);
- dlen = tlen - hlen;
-
- data = (char *)pip;
- data += hlen;
-
- /* When aliasing a client, check for the SETUP request */
- if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) ||
- (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) {
-
- if (dlen >= (int)strlen(setup)) {
- if (memcmp(data, setup, strlen(setup)) == 0) {
- alias_rtsp_out(la, pip, lnk, data, client_port_str);
- return;
- }
- }
- if (dlen >= (int)strlen(pna)) {
- if (memcmp(data, pna, strlen(pna)) == 0) {
- alias_pna_out(la, pip, lnk, data, dlen);
- }
- }
- } else {
-
- /*
- * When aliasing a server, check for the 200 reply
- * Accomodate varying number of blanks between 200 & OK
- */
-
- if (dlen >= (int)strlen(str200)) {
-
- for (parseOk = 0, i = 0;
- i <= dlen - (int)strlen(str200);
- i++) {
- if (memcmp(&data[i], str200, strlen(str200)) == 0) {
- parseOk = 1;
- break;
- }
- }
- if (parseOk) {
-
- i += strlen(str200); /* skip string found */
- while (data[i] == ' ') /* skip blank(s) */
- i++;
-
- if ((dlen - i) >= (int)strlen(okstr)) {
-
- if (memcmp(&data[i], okstr, strlen(okstr)) == 0)
- alias_rtsp_out(la, pip, lnk, data, server_port_str);
-
- }
- }
- }
- }
-}
OpenPOWER on IntegriCloud