⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tunnel.c

📁 rtp tunnel 一个非常好的rtp tunnel程序
💻 C
字号:
/*  rtptunnel - A UDP to TCP tunneling program  Copyright (C) 1999  Roland Dreier    This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.    This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.    You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    $Id: tunnel.c 1.3 Sat, 04 Dec 1999 16:05:07 -0600 dreier $*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <ctype.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <popt.h>enum {  DEFAULT_RTP_PORT = 5004,  DEFAULT_TUNNEL_PORT = 5685};enum {  MAX_PORTS = 2,  MAX_PACKET_SIZE = 2000};int Tunnel_Port = DEFAULT_TUNNEL_PORT;int Recv_Rtp_Port = DEFAULT_RTP_PORT;int Send_Rtp_Port = DEFAULT_RTP_PORT;char *Tunnel_Hostname = NULL;char *Send_Rtp_String = NULL;char *Send_Hostname = NULL;struct poptOption optionsTable[] = {  { "tunnel-port", 't', POPT_ARG_INT, &Tunnel_Port, 0,    "Set TCP port for tunnel", "port" },  { "recv-rtp", 'r', POPT_ARG_INT, &Recv_Rtp_Port, 0,    "Set RTP port to listen on", "port" },  { "send-rtp", 's', POPT_ARG_STRING, &Send_Rtp_String, 0,    "Set RTP host and port to send to", "[hostname]:[port]" },  { "call", 'c', POPT_ARG_STRING, &Tunnel_Hostname, 0,    "Tunnel to remote computer", "hostname" },  POPT_AUTOHELP  { NULL, 0, 0, NULL, 0 }};int Tunnel_Sock;int Num_Ports;int Recv_Port[MAX_PORTS], Send_Port[MAX_PORTS];int Recv_Sock[MAX_PORTS], Send_Sock;static voidfind_host(char *host_name, struct in_addr *address){  struct hostent *host;  if (inet_aton(host_name, address)) {    return;  } else {    host = gethostbyname(host_name);  }    if (!host) {    herror("error looking up host");    exit(1);  }  memmove(address, (struct in_addr *) host->h_addr_list[0],          sizeof(struct in_addr));}static intcall_out(void){  int t;  int sock;  struct sockaddr_in address;  sock = socket(AF_INET, SOCK_STREAM, 0);  if (sock < 0) {    perror("socket");    exit(1);  }  t = 1;  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t));  address.sin_family = AF_INET;  address.sin_port = htons(Tunnel_Port);  memset(&address.sin_zero, 0, sizeof(address.sin_zero));  find_host(Tunnel_Hostname, &address.sin_addr);  if (connect(sock, (struct sockaddr *) &address, sizeof address)) {    perror("connect");    exit(1);  }  return(sock);}static intanswer_call(void){  int t;  int sock, conn;  int addrlen;  struct sockaddr_in address;  sock = socket(AF_INET, SOCK_STREAM, 0);  if (sock < 0) {    perror("socket");    exit(1);  }  t = 1;  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t));  address.sin_family = AF_INET;  address.sin_port = htons(Tunnel_Port);  address.sin_addr.s_addr = INADDR_ANY;  memset(&address.sin_zero, 0, sizeof address.sin_zero);    if (bind(sock, (struct sockaddr *) &address, sizeof address) < 0) {    perror("bind");    exit(1);  }  if (listen(sock, 2) < 0) {    perror("listen");    exit(1);  }  addrlen = sizeof address;  conn = accept(sock, &address, &addrlen);  if (conn < 0) {    perror("accept");    exit(1);  }  close(sock);  return(conn);}static voidopen_udp_sock(void){  int i;  struct sockaddr_in address;  Send_Sock = socket(AF_INET, SOCK_DGRAM, 0);  if (Send_Sock < 0) {    perror("socket");    exit(1);  }  for (i = 0; i < Num_Ports; i++) {    Recv_Sock[i] = socket(AF_INET, SOCK_DGRAM, 0);    if (Recv_Sock[i] < 0) {      perror("socket");      exit(1);    }    address.sin_family = AF_INET;    address.sin_addr.s_addr = INADDR_ANY;    memset(&address.sin_zero, 0, sizeof address.sin_zero);    address.sin_port = htons(Recv_Port[i]);    if (bind(Recv_Sock[i], (struct sockaddr *) &address,	     sizeof address) < 0) {      perror("bind");      exit(1);    }  }}static voidread_tcp(int sock, char *data, int len){  int off, r;  for (off = 0; off < len; off += r) {    r = read(sock, data + off, len - off);    if (r <= 0) {      perror("read");      exit(1);    }  }}static voidwrite_tcp(int sock, char *data, int len){  int off, r;  for (off = 0; off < len; off += r) {    r = write(sock, data + off, len - off);    if (r <= 0) {      perror("write");      exit(1);    }  }}static voidtunnel(void){  int i;  int fdmax;  fd_set fds;  char buf[MAX_PACKET_SIZE];  short t;  int len, port;  struct sockaddr_in address;  fdmax = Tunnel_Sock;  for (i = 0; i < Num_Ports; i++) {    if (Recv_Sock[i] > fdmax) {      fdmax = Recv_Sock[i];    }  }  address.sin_family = AF_INET;  if (Send_Hostname == NULL) {    address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);  } else {    find_host(Send_Hostname, &address.sin_addr);  }  memset(&address.sin_zero, 0, sizeof address.sin_zero);  while (1) {    FD_ZERO(&fds);    FD_SET(Tunnel_Sock, &fds);    for (i = 0; i < Num_Ports; i++) {      FD_SET(Recv_Sock[i], &fds);    }    if (select(fdmax + 1, &fds, NULL, NULL, NULL) < 0) {      perror("select");      exit(1);    }    if (FD_ISSET(Tunnel_Sock, &fds)) {      read_tcp(Tunnel_Sock, (char *) &t, sizeof (short));      len = ntohs(t);      read_tcp(Tunnel_Sock, (char *) &t, sizeof (short));      port = ntohs(t);      if (len > MAX_PACKET_SIZE) {	fprintf(stderr, "packet too large: size = %x\n", len);	exit(1);      }      if (port > Num_Ports) {	fprintf(stderr, "port number too high: port = %d\n", port);	exit(1);      }      read_tcp(Tunnel_Sock, buf, len);      address.sin_port = htons(Send_Port[port]);      if (sendto(Send_Sock, (void *) buf, len, 0,		 (struct sockaddr *) &address, sizeof address) < 0) {	perror("sendto");	exit(1);      }    }    for (i = 0; i < Num_Ports; i++) {      if (FD_ISSET(Recv_Sock[i], &fds)) {	len = recvfrom(Recv_Sock[i], buf, MAX_PACKET_SIZE, 0,		       NULL, 0);	if (len < 0) {	  perror("recvfrom");	  exit(1);	}	t = htons((short) len);	write_tcp(Tunnel_Sock, (char *) &t, sizeof (short));	t = htons((short) i);	write_tcp(Tunnel_Sock, (char *) &t, sizeof (short));	write_tcp(Tunnel_Sock, buf, len);      }    }  }}intmain(int argc, char *argv[]){  int i, j;  char rc;  poptContext optCon;  optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);  rc = poptGetNextOpt(optCon);  if (Send_Rtp_String != NULL) {    int port_start, colons, is_number;    port_start = 0;    colons = 0;    is_number = 1;    for (i = 0; i < strlen(Send_Rtp_String); i++) {      if (!isdigit(Send_Rtp_String[i])) {        is_number = 0;      }      if (Send_Rtp_String[i] == ':') {        if (colons == 0) {          port_start = i + 1;        }        ++colons;      }    }    if (colons > 1) {      fprintf(stderr, "%s: -s argument %s has too many colons.\n",              argv[0], Send_Rtp_String);      exit(1);    }    if (is_number || colons == 1) {      Send_Rtp_Port = strtol(Send_Rtp_String + port_start, NULL, 10);    }    if (!is_number) {      Send_Hostname = Send_Rtp_String;      if (colons == 1) {        Send_Hostname[port_start - 1] = '\0';      }    }  }  Num_Ports = 2;  Recv_Port[0] = Recv_Rtp_Port;  Recv_Port[1] = Recv_Rtp_Port + 1;  Send_Port[0] = Send_Rtp_Port;  Send_Port[1] = Send_Rtp_Port + 1;  for (i = 0; i < Num_Ports; i++) {    for (j = 0; j < Num_Ports; j++) {      if (Recv_Port[i] == Send_Port[j] && Send_Hostname == NULL) {	fprintf(stderr, "%s: Listening on and sending to UDP port %d.  Bad!\n",		argv[0], Recv_Port[i]);	exit(1);      }    }  }  if (Tunnel_Hostname != NULL) {    Tunnel_Sock = call_out();  } else {    Tunnel_Sock = answer_call();  }  open_udp_sock();  tunnel();  return 0;}/* * Local variables: *  compile-command: "make -k rtptunnel" * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -