Annotation of researchv10no/ipc/mgrs/gate/tcpgate.c, revision 1.1.1.1

1.1       root        1: #include <sys/types.h>
                      2: #include <sys/inet/tcp_user.h>
                      3: #include <sys/inio.h>
                      4: #include <sys/filio.h>
                      5: #include <stdio.h>
                      6: #include <ipc.h>
                      7: 
                      8: /*
                      9:  *  This program gates between a tcp network and connection server
                     10:  *  machines that don't run the darpa Internet suite.
                     11:  */
                     12: 
                     13: /* imports */
                     14: extern char *in_host();
                     15: extern in_addr in_address();
                     16: extern int ip_ld;
                     17: extern char *strchr();
                     18: extern int errno;
                     19: extern char *errstr;
                     20: 
                     21: /* global */
                     22: char *me;
                     23: 
                     24: usage()
                     25: {
                     26:        fprintf(stderr, "usage: %s tcp-address\n", me);
                     27:        exit(1);
                     28: }
                     29: 
                     30: /*
                     31:  *  Prime function - shuffle bytes twixt two fd's
                     32:  */
                     33: gate(caller, callee)
                     34:        int caller;
                     35:        int callee;
                     36: {
                     37:        fd_set fds, bfds;
                     38: 
                     39:        /* shuttle bytes back and forth */
                     40:        FD_ZERO(bfds);
                     41:        FD_SET(caller, bfds);
                     42:        FD_SET(callee, bfds);
                     43:        for(;;) {
                     44:                fds = bfds;
                     45:                switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) {
                     46:                case -1:
                     47:                        log("select failed %d\n", errno);
                     48:                        return;
                     49:                case 0:
                     50:                        continue;
                     51:                }
                     52:                if (FD_ISSET(caller, fds))
                     53:                        switch(pass(caller, callee)){
                     54:                        case -1:
                     55:                                log("caller io error %d\n", errno);
                     56:                                return;
                     57:                        case 0:
                     58:                                FD_CLR(caller, bfds);
                     59:                                break;
                     60:                        default:
                     61:                                break;
                     62:                        }
                     63:                if (FD_ISSET(callee, fds))
                     64:                        switch(pass(callee, caller)){
                     65:                        case -1:
                     66:                                log("callee io error %d\n", errno);
                     67:                        case 0:
                     68:                                return;
                     69:                        default:
                     70:                                break;
                     71:                        }
                     72:        }
                     73: }
                     74: 
                     75: pass(from, to)
                     76:        int from, to;
                     77: {
                     78:        char buf[4096];
                     79:        int n;
                     80: 
                     81:        if((n=read(from, buf, sizeof(buf)))<0)
                     82:                return -1;
                     83:        if (write(to, buf, n)!=n)
                     84:                return -1;
                     85:        return n;
                     86: }
                     87: 
                     88: /*
                     89:  *  Map an entry - for now use a simple mechanism
                     90:  *     a.b.c.att.com.,port x -> dk!c/b/a!tcp.x
                     91:  */
                     92: #define TAIL1 ".att.com"
                     93: #define TAIL2 ".att.com."
                     94: 
                     95: char *
                     96: tcptodk(inaddr, port)
                     97:        in_addr inaddr;
                     98:        int port;
                     99: {
                    100:        static char buf[256];
                    101:        char dkname[128];
                    102:        char *fields[16];
                    103:        char *host;
                    104:        int n;
                    105: 
                    106:        host = in_host(inaddr);
                    107:        n = strlen(host);
                    108:        if (n > sizeof(TAIL1)-1){
                    109:                if(strcmp(&host[n-sizeof(TAIL1)+1], TAIL1)==0)
                    110:                        host[n-sizeof(TAIL1)+1] = '\0';
                    111:                else if(strcmp(&host[n-sizeof(TAIL2)+1], TAIL2)==0)
                    112:                        host[n-sizeof(TAIL2)+1] = '\0';
                    113:        }
                    114:        setfields(".");
                    115:        n = getmfields(host, fields, 16);
                    116:        strcpy(dkname, fields[--n]);
                    117:        for(n--; n>=0; n--) {
                    118:                strcat(dkname, "/");
                    119:                strcat(dkname, fields[n]);
                    120:        }
                    121:        sprintf(buf, "dk!%s!tcp.%d", dkname, port);
                    122:        return buf;
                    123: }
                    124: 
                    125: /*
                    126:  *  create a pipe and push ip onto each side
                    127:  */
                    128: in_addr
                    129: ipconfig(netname)
                    130:        char *netname;
                    131: {
                    132:        in_addr addr, myaddr;
                    133:        int ippipe[2];
                    134: 
                    135:        addr = in_address(netname);
                    136:        if (addr == 0){
                    137:                fprintf(stderr, "%s: bad ip address %s\n", netname);
                    138:                exit(1);
                    139:        }
                    140:        myaddr = addr+255;
                    141: 
                    142:        /*
                    143:         *  push the ip ld on a pipe to config the network
                    144:         */
                    145:        pipe(ippipe);
                    146:        if(ioctl(ippipe[0], FIOPUSHLD, &ip_ld) < 0){
                    147:                perror(me);
                    148:                exit(1);
                    149:        }
                    150:        if(ioctl(ippipe[0], IPIOLOCAL, &myaddr) < 0){
                    151:                perror("IPIOLOCAL");
                    152:                exit(1);
                    153:        }
                    154:        ioctl(ippipe[0], IPIONET, &addr);
                    155:        if(ioctl(ippipe[1], FIOPUSHLD, &ip_ld) < 0){
                    156:                perror(me);
                    157:                exit(1);
                    158:        }
                    159:        if(ioctl(ippipe[1], IPIOLOCAL, &addr) < 0){
                    160:                perror("IPIOLOCAL");
                    161:                exit(1);
                    162:        }
                    163:        ioctl(ippipe[1], IPIONET, &myaddr);
                    164:        return(addr);
                    165: }
                    166: 
                    167: /*
                    168:  *  Listen to calls from tcp.  Transfer call via connection server.
                    169:  */
                    170: fromtcp(netname, addr)
                    171:        char *netname;
                    172:        in_addr addr;
                    173: {
                    174:        int fd;
                    175:        char *np;
                    176:        struct tcpuser tu;
                    177:        char name[128];
                    178:        int caller, callee;
                    179:        int pid;
                    180: 
                    181:        /*
                    182:         *  request all tcp calls to the given network
                    183:         */
                    184:        fd = tcp_sock();
                    185:        if (fd < 0){
                    186:                fprintf(stderr, "%s: no tcp devices\n", me);
                    187:                return;
                    188:        }
                    189:        tu.lport = TCPPORT_ANY;
                    190:        tu.laddr = addr;
                    191:        tu.fport = 0;
                    192:        tu.faddr = 0;
                    193:        tu.param = 0;
                    194:        if (tcp_listen(fd, &tu)<0) {
                    195:                fprintf(stderr, "%s: server already exists\n", me);
                    196:                exit(1);
                    197:        }
                    198: 
                    199:        /*
                    200:         *  keep grabbing calls till something nasty happens
                    201:         */
                    202:        for(;;){
                    203:                if ((caller = tcp_accept(fd, &tu))<0) {
                    204:                        log("bad accept %d\n", errno);
                    205:                        break;
                    206:                }
                    207:                if ((pid = fork()) < 0) {
                    208:                        log("fork failed %d\n", errno);
                    209:                        close(caller);  /* drop connection */
                    210:                }
                    211:                else if (pid) {
                    212:                        while (wait((int *)0) != pid)
                    213:                                ;
                    214:                        close(caller);
                    215:                } else {
                    216:                        close(fd);
                    217:                        switch (fork()) {       /* so main tcpgate not our parent */
                    218:                        case -1:
                    219:                                log("second fork failed %d\n", errno);
                    220:                        default:
                    221:                                exit(0);
                    222: 
                    223:                        case 0:                 /* child */
                    224:                                break;
                    225:                        }
                    226:                        np = tcptodk(tu.laddr, tu.lport);
                    227:                        log("call %s\n", np);
                    228:                        callee = ipcopen(np, "");
                    229:                        if (callee < 0)
                    230:                                log("failed: %s\n", errstr);
                    231:                        else
                    232:                                gate(caller, callee);
                    233:                        exit(0);
                    234:                }
                    235:        }
                    236:        close(fd);
                    237: }
                    238: 
                    239: main(ac, av)
                    240:        int ac;
                    241:        char *av[];
                    242: {
                    243:        in_addr addr;
                    244: 
                    245:        me = av[0];
                    246:        if(ac<2)
                    247:                usage();
                    248: 
                    249:        /* where the cs name space starts */
                    250:        chdir("/cs");
                    251: 
                    252:        addr = ipconfig(av[1]);
                    253:        for(;;){
                    254:                fromtcp(av[1], addr);
                    255:                sleep(10);
                    256:        }
                    257: }
                    258: 
                    259: log(s, a, b, c)
                    260: char *s;
                    261: {
                    262:        long now;
                    263: 
                    264:        time(&now);
                    265:        fprintf(stderr, "%.15s %d ", ctime(&now)+4, getpid());
                    266:        fprintf(stderr, s, a, b, c);
                    267: }

unix.superglobalmegacorp.com

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