|
|
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.