Annotation of quakeworld/qwfwd/qwfwd.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Copyright (C) 1996-1997 Id Software, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
                     12: 
                     13: See the GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
                     18: 
                     19: */
                     20: 
                     21: 
                     22: /*
                     23:  * udpred - a inetd launched udp port redirector
                     24:  *
                     25:  * Version:    @(#)udpred.c 0.01   01/15/97
                     26:  *
                     27:  * Author:     Chris Faherty <[email protected]>
                     28:  *
                     29:  * syntax:
                     30:  *
                     31:  * udpred toip toport
                     32:  *
                     33:  * sample inetd.conf entry:
                     34:  *
                     35:  * 7000        dgram   udp     wait    root    /usr/sbin/tcpd  /usr/sbin/udpred 192.168.100.16 7000
                     36:  *
                     37:  *
                     38:  *     This program is free software; you can redistribute it and/or
                     39:  *     modify it under the terms of the GNU General Public License
                     40:  *     as published by the Free Software Foundation; either version
                     41:  *     2 of the License, or (at your option) any later version.
                     42:  *
                     43:  */
                     44: #include <stdio.h>
                     45: #include <errno.h>
                     46: #include <fcntl.h>
                     47: #include <signal.h>
                     48: #include <stdlib.h>
                     49: #include <sys/types.h>
                     50: #include <time.h>
                     51: 
                     52: #ifdef _WIN32
                     53: #include <winsock.h>
                     54: #else
                     55: #include <sys/time.h>
                     56: #include <sys/socket.h>
                     57: #include <sys/wait.h>
                     58: #include <netdb.h>
                     59: #include <netinet/in.h>
                     60: #include <unistd.h>
                     61: #include <syslog.h>
                     62: 
                     63: #endif
                     64: 
                     65: int host_port; // port we are listening on
                     66: 
                     67: typedef struct peer {
                     68:        time_t last;
                     69:        struct sockaddr_in sin;
                     70:        struct sockaddr_in dest;
                     71:        int s; // connected socket to remote
                     72:        struct peer *next;
                     73: } peer_t;
                     74: 
                     75: peer_t *peers;
                     76: 
                     77: /*
                     78: ====================
                     79: NET_Init
                     80: ====================
                     81: */
                     82: void NET_Init (void)
                     83: {
                     84: #ifdef _WIN32
                     85:        static WSADATA          winsockdata;
                     86: //    WORD    wVersionRequested;
                     87:     int             r;
                     88: 
                     89: //    wVersionRequested = MAKEWORD(1, 1);
                     90: 
                     91:     r = WSAStartup (MAKEWORD(2, 1), &winsockdata);
                     92: 
                     93:     if (r) {
                     94:                fprintf(stderr, "Winsock initialization failed.");
                     95:                exit(1);
                     96:        }
                     97: 
                     98:     printf("Winsock Initialized\n");
                     99: #endif
                    100: }
                    101: 
                    102: 
                    103: 
                    104: int connectsock(char *host, char *service, char *protocol)
                    105: {
                    106:        struct hostent *phe;
                    107:        struct servent *pse;
                    108:        struct protoent *ppe;
                    109:        struct sockaddr_in sin;
                    110:        int s, type;
                    111: 
                    112:        memset(&sin, 0, sizeof(sin));
                    113:        sin.sin_family = AF_INET;
                    114: 
                    115: /* Map service name to port number */
                    116:        if(pse = getservbyname(service, protocol))
                    117:                sin.sin_port = pse->s_port;
                    118:        else if((sin.sin_port = htons((u_short)atoi(service))) == 0)
                    119:        {
                    120:                fprintf(stderr, "udpred: can't get \"%s\" service entry\n", service);
                    121:                exit(2);
                    122:        }
                    123: 
                    124: /* Map host name to IP address, allowing for dotted decimal */
                    125:        if(phe = gethostbyname(host))
                    126:                memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length);
                    127:        else if((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
                    128:        {
                    129:                fprintf(stderr, "udpred: can't get \"%s\" host entry\n", host);
                    130:                exit(2);
                    131:        }
                    132: 
                    133: /* Map protocol name to protocol number */
                    134:        if((ppe = getprotobyname(protocol)) == 0)
                    135:        {
                    136:                fprintf(stderr, "udpred: can't get \"%s\" protocol entry\n", protocol);
                    137:                exit(2);
                    138:        }
                    139: 
                    140: /* Use protocol to choose a socket type */
                    141:        if(strcmp(protocol, "udp") == 0)
                    142:                type = SOCK_DGRAM;
                    143:        else
                    144:                type = SOCK_STREAM;
                    145: 
                    146: /* Allocate a socket */
                    147:        s = socket(PF_INET, type, ppe->p_proto);
                    148:        if(s < 0)
                    149:        {
                    150:                fprintf(stderr, "udpred: can't create socket: %s\n", sys_errlist[errno]);
                    151:                exit(2);
                    152:        }
                    153: 
                    154: /* Connect the socket */
                    155:        if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
                    156:        {
                    157:                fprintf(stderr, "udpred: can't connect to %s.%s: %s\n", host, service, sys_errlist[errno]);
                    158:                exit(2);
                    159:        }
                    160:        return s;
                    161: }
                    162: 
                    163: int main(int argc, char *argv[])
                    164: {
                    165:        fd_set rfds;
                    166:        struct timeval tv;
                    167:        int retval;
                    168:        int i1;
                    169:        char buffer[4095];
                    170:        struct sockaddr_in fsin;
                    171:        int alen;
                    172:        peer_t *p;
                    173:        int s;
                    174:        struct sockaddr_in      address;
                    175: 
                    176:        if (argc < 3) {
                    177:                printf("Usage:  %s <port> <remote server> <remote server port>\n", argv[0]);
                    178:                return 1;
                    179:        }
                    180: 
                    181:        NET_Init();
                    182: 
                    183:        if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
                    184:                perror("socket");
                    185:                return 1;
                    186:        }
                    187: 
                    188:        address.sin_family = AF_INET;
                    189:        address.sin_addr.s_addr = INADDR_ANY;
                    190:        address.sin_port = htons((unsigned short)atoi(argv[1]));
                    191:        if (bind (s, (void *)&address, sizeof(address)) == -1)
                    192:                perror("bind");
                    193: 
                    194:        while(1)
                    195:        {
                    196:                FD_ZERO(&rfds);
                    197:                FD_SET(s, &rfds);
                    198:                i1 = s;
                    199:                for (p = peers; p; p = p->next) {
                    200:                        FD_SET(p->s, &rfds);
                    201:                        if (p->s >= i1)
                    202:                                i1 = p->s + 1;
                    203:                }
                    204:                /* Wait up to two minutes. */
                    205:                tv.tv_sec = 2;
                    206:                tv.tv_usec = 0;
                    207:                retval = select(i1, &rfds, (fd_set *)0, (fd_set *)0, &tv);
                    208:                if(retval > 0)
                    209:                {
                    210:                        if(FD_ISSET(s, &rfds))
                    211:                        {
                    212:                                alen = sizeof(fsin);
                    213:                                i1 = recvfrom(s, buffer, 4096, 0, (struct sockaddr *) &fsin, &alen);
                    214:                                if(i1 > 0) {
                    215:                                        for (p = peers; p; p = p->next)
                    216:                                                if (memcmp(&p->sin.sin_addr, &fsin.sin_addr, sizeof(p->sin.sin_addr)) == 0 &&
                    217:                                                        memcmp(&p->sin.sin_port, &fsin.sin_port, sizeof(p->sin.sin_port)) == 0) 
                    218:                                                {
                    219:                                                        send(p->s, buffer, i1, 0);
                    220:                                                        time(&p->last);
                    221:                                                        break;
                    222:                                                }
                    223:                                        if (p == NULL) { // new peer
                    224:                                                printf("peer %s:%d added", inet_ntoa(fsin.sin_addr), (int)ntohs(fsin.sin_port));
                    225:                                                p = malloc(sizeof *p);
                    226:                                                p->sin = fsin;
                    227:                                                p->s = connectsock(argv[2], argv[3], "udp");
                    228:                                                p->next = peers;
                    229:                                                peers = p;
                    230:                                                send(p->s, buffer, i1, 0);
                    231:                                                time(&p->last);
                    232:                                        }
                    233:                                }
                    234:                        }
                    235:                        for (p = peers; p; p = p->next)
                    236:                                if(FD_ISSET(p->s, &rfds))
                    237:                                {
                    238:                                        i1 = recv(p->s, buffer, 4096, 0);
                    239:                                        if(i1 > 0) {
                    240:                                                time(&p->last);
                    241:                                                sendto(s, buffer, i1, 0, (struct sockaddr *) &p->sin, 
                    242:                                                        sizeof(p->sin)); 
                    243:                                        }
                    244:                                }
                    245:                } else {
                    246:                        peer_t *pp;
                    247: 
                    248:                        pp = NULL;
                    249:                        p = peers; 
                    250:                        while (p) {
                    251:                                if (time(NULL) - p->last > 300) {
                    252:                                        if (!pp && !p->next) {
                    253:                                                printf("peer %s:%d removed (timeout)", inet_ntoa(p->sin.sin_addr), (int)ntohs(p->sin.sin_port));
                    254:                                                free(p);
                    255:                                                p = pp = NULL;
                    256:                                                continue;
                    257:                                        }
                    258:                                        pp->next = p->next;
                    259:                                        printf ("peer %s:%d removed (timeout)", inet_ntoa(p->sin.sin_addr), (int)ntohs(p->sin.sin_port));
                    260:                                        free(p);
                    261:                                        p = pp->next;
                    262:                                } else {
                    263:                                        pp = p;
                    264:                                        p = p->next;
                    265:                                }
                    266:                        }
                    267:                }
                    268:        }
                    269: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.