Annotation of researchv10no/ipc/mgrs/gate/tcpgate.c, revision 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.