|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.