[4041] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Re: port remapping

daemon@ATHENA.MIT.EDU (Jan Vicherek)
Fri Aug 16 06:15:00 1996

Date: 	Thu, 15 Aug 1996 21:47:12 -0400 (EDT)
From: Jan Vicherek <honza@ied.com>
To: System Development <devel@vrml.k12.la.us>
cc: linux-net@vger.rutgers.edu
In-Reply-To: <199608141621.LAA03287@vpsd5.vrml.k12.la.us>

On Wed, 14 Aug 1996, System Development wrote:

> i am interested in remapping service ports on a linux gateway to 
> different ports on another machine.  For instance,
> 
> 198.180.155.8:81 -> 198.180.155.7:80
> 198.180.155.8:82 -> 198.180.155.6:80
> 
> any suggestions?

     sure.

 --- Gospel is the power of God for all who believe - (Rom. 1:16) ---
Jan Vicherek .............. Check out: http://www.ied.com/~honza/fslu/
Interactive Electronic Design Inc. . "To some, nothing is impossible."
http://www.ied.com/~honza ................... finger honza@www.ied.com

_________ bounce.c __________________________

/* Distribution: Public */
/* Copyright: Held by the respective contributors */
/* Posted to USENET September '93 by Mark mark@cairo.anu.edu.au */

/* This file was telserv.c, part of the Telnet Server package v. 1.0,
     written by "Hal-9000". Much of that package was developed by Richard
     Stephens and his thanks go to "Xanadude" for providing him with that
     section. Performance fix by Darren Reed. */

/* Reworked to add concurrency, password checking and destination selection
   on the fly. - Mark 31st Aug 93

   Now its a IRC bouncer

   Compiled and tested on:
       HPUX 9.01 9000/700 series        NeXTStep 3.1 NeXT 68040
	   OSx Pyramid 90x BSD universe     SunOS 5.2 sun4c
	   Ultrix 4.3 DEC RISC

   To compile, type "cc -O -s ircb.c -o ircb".
   Michael Morgan used "gcc -O -s bounce -o bounce"
*/


/*+  IRC Bouncer hacks  +*/

#define	ircserv	"irc.escape.com"
#define	ircport 6667
#define	ircbnc	10000

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>

#define    QLEN           5

char sbuf[4096], cbuf[4096];
extern int errno;
void reaper();
extern char *sys_errlist[];
int main();
void telcli();
int IRCBNC=0,IRCPORT=0;
char IRCSERV[100];

int main(argc, argv)
int argc;
char *argv[];
{
    char string_user[20];
    int srv_fd, rem_fd, rem_len, opt = 1;
    struct sockaddr_in rem_addr, srv_addr;
#if !defined(SVR4) && !defined(POSIX) && !defined(linux) && !defined(__386BSD__) && !defined(hpux)
    union wait status;
#else
    int    status;
#endif /* !defined(SVR4) */

    printf ("\n\rIRC IP/Port Bouncer * Modified by Bourbon");
    printf ("\n\rOriginal code by Mark mark@cairo.anu.edu.au\n\r");
    printf ("Weak command line code added by Michael Morgan ");
    printf ("mlmorgan@rice.edu\n\r");

    if (argc>1 && !strcmp(argv[1],"-s"))
    {
       printf ("\n\rEnter IRC Server Port [%i]: ",ircport);
       gets(string_user);
       if (string_user[0]==0)
          IRCPORT=ircport;
       else
          IRCPORT=atoi(string_user);
 
       printf ("\n\rEnter Bouncer Port [%i]: ",ircbnc);
       gets(string_user);
       if (string_user[0]==0)
          IRCBNC=ircbnc;
       else
          IRCBNC=atoi(string_user);
       
       printf ("\n\rEnter IRC Server IP or address [%s]: ",ircserv);
       gets(IRCSERV);
       if (IRCSERV[0]==0) strcpy (IRCSERV,ircserv);
    }
/* Michael Morgan's attempt at a simple command line interface */
    else if (argc==5 && !strcmp(argv[1],"-c"))
    {
       IRCBNC=atoi(argv[2]);
       strcpy (IRCSERV,argv[3]);
       IRCPORT=atoi(argv[4]);
    }
/* End of my try */
    else
    {
       IRCPORT=ircport;
       IRCBNC=ircbnc;
       strcpy(IRCSERV,ircserv);
    }

    if (argc>1 && !strcmp(argv[1],"-h"))
    {
       printf ("\n\rUsage: %s [-h] [-s] [-c ",argv[0]);
       printf ("<bounce port> <remote machine> <remote port>]");
       printf ("\n\r-s      Set ports&IP interactively");
       printf ("\n\r-c      Set ports&IP on command line");
       printf ("\n\r-h      Display this help\n\r");
       printf ("\n\rCurrent Defaults: 127.0.0.1:%i -> %s:%i\n\n\r",ircbnc,ircserv,ircport);		
       exit(0);
    }

    printf ("\n\rRedirecting port %i of this machine to port %i of %s\n\n\r"
          ,IRCBNC,IRCPORT,IRCSERV);
    bzero((char *) &rem_addr, sizeof(rem_addr));
    bzero((char *) &srv_addr, sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    srv_addr.sin_port = htons(IRCBNC);  /*+ IRC Bouncer hack  +*/
    srv_fd = socket(PF_INET, SOCK_STREAM, 0);
    if (bind(srv_fd, (struct sockaddr *) &srv_addr, sizeof(srv_addr)) == -1) {
        perror("bind");
        exit(-1);
    }
    listen(srv_fd, QLEN);
    close(0); close(1); close(2);
#ifdef TIOCNOTTY
    if ((rem_fd = open("/dev/tty", O_RDWR)) >= 0) {
        ioctl(rem_fd, TIOCNOTTY, (char *)0);
        close(rem_fd);
    }
#endif
    if (fork()) exit(0);
    while (1) {
    rem_len = sizeof(rem_addr);
        rem_fd=accept(srv_fd, (struct sockaddr *) &rem_addr, &rem_len);
        if (rem_fd < 0) {
            if (errno == EINTR) continue;
            exit(-1);
        }
        switch(fork()) {
        case 0:                             /* child process */
            close(srv_fd);                  /* close original socket */
            telcli(rem_fd);                 /* process the request */
            close(rem_fd);
            exit(0);
            break;
        default: 
            close(rem_fd);                  /* parent process */
            if (fork()) exit(0);            /* let init worry about children */
            break;
        case -1:
            fprintf(stderr, "\n\rfork: %s\n\r", sys_errlist[errno]);
            break;
        }
    }
}

void telcli(source)
int source;
{
    int dest;
    int found;
    struct sockaddr_in sa;
    struct hostent *hp;
    struct servent *sp;
    char gethost[100];
    char getport[100];
    char string[100];

        hp = gethostbyname(IRCSERV);
        if (hp) {
            found++;
#if !defined(h_addr)        /* In 4.3, this is a #define */
#if defined(hpux) || defined(NeXT) || defined(ultrix) || defined(POSIX)
            memcpy((caddr_t)&sa.sin_addr, hp->h_addr_list[0], hp->h_length);
#else
            bcopy(hp->h_addr_list[0], &sa.sin_addr, hp->h_length);
#endif
#else /* defined(h_addr) */
#if defined(hpux) || defined(NeXT) || defined(ultrix) || defined(POSIX)
            memcpy((caddr_t)&sa.sin_addr, hp->h_addr, hp->h_length);
#else
            bcopy(hp->h_addr, &sa.sin_addr, hp->h_length);
#endif
#endif /* defined(h_addr) */
        } else {
            if (inet_addr(gethost) == -1) {
                found = 0;
                sprintf(string, "Didnt find address for %s\r\n", gethost);
                write(source, string, strlen(string));
            } else {
                found++;
                sa.sin_addr.s_addr = inet_addr(gethost);
            }
        }
    sa.sin_family = AF_INET;
    sa.sin_port = htons((unsigned) IRCPORT);
    if (sa.sin_port == 0) {
        sp = getservbyname(getport, "tcp");
        if (sp)
            sa.sin_port = sp->s_port;
        else {
            sprintf(string, "%s: bad port number\r\n", getport);
            write(source, string, strlen(string));
            return;
        }
    }
    if ((dest = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("telcli: socket");
        exit(1);
    }
    connect(dest, (struct sockaddr *) &sa, sizeof(sa));
#ifdef FNDELAY
    fcntl(source,F_SETFL,fcntl(source,F_GETFL,0)|FNDELAY);
    fcntl(dest,F_SETFL,fcntl(dest,F_GETFL,0)|FNDELAY);
#else
    fcntl(source,F_SETFL,O_NDELAY);
    fcntl(dest,F_SETFL,O_NDELAY);
#endif
    communicate(dest,source);
    close(dest);
    exit(0);
}

communicate(sfd,cfd)    {
    char *chead, *ctail, *shead, *stail;
    int num, nfd, spos, cpos;
    extern int errno;
    fd_set rd, wr;

    chead = ctail = cbuf;
    cpos = 0;
    shead = stail = sbuf;
    spos = 0;
    while (1) {
        FD_ZERO(&rd);
        FD_ZERO(&wr);
        if (spos < sizeof(sbuf)-1) FD_SET(sfd, &rd);
        if (ctail > chead) FD_SET(sfd, &wr);
        if (cpos < sizeof(cbuf)-1) FD_SET(cfd, &rd);
        if (stail > shead) FD_SET(cfd, &wr);
        nfd = select(256, &rd, &wr, 0, 0);
        if (nfd <= 0) continue;
        if (FD_ISSET(sfd, &rd)) {
            num=read(sfd,stail,sizeof(sbuf)-spos);
            if ((num==-1) && (errno != EWOULDBLOCK)) return;
            if (num==0) return;
            if (num>0) {
                spos += num;
                stail += num;
                if (!--nfd) continue;
            }
        }
        if (FD_ISSET(cfd, &rd)) {
            num=read(cfd,ctail,sizeof(cbuf)-cpos);
            if ((num==-1) && (errno != EWOULDBLOCK)) return;
            if (num==0) return;
            if (num>0) {
                cpos += num;
                ctail += num;
                if (!--nfd) continue;
            }
        }
        if (FD_ISSET(sfd, &wr)) {
            num=write(sfd,chead,ctail-chead);
            if ((num==-1) && (errno != EWOULDBLOCK)) return;
            if (num>0) {
                chead += num;
                if (chead == ctail) {
                    chead = ctail = cbuf;
                    cpos = 0;
                }
                if (!--nfd) continue;
            }
        }
        if (FD_ISSET(cfd, &wr)) {
            num=write(cfd,shead,stail-shead);
            if ((num==-1) && (errno != EWOULDBLOCK)) return;
            if (num>0) {
                shead += num;
                if (shead == stail) {
                    shead = stail = sbuf;
                    spos = 0;
                }
                if (!--nfd) continue;
            }
        }
    }
}



home help back first fref pref prev next nref lref last post