blob: 79042b485d97dce34d54d2b34f1549f26361325d [file] [log] [blame]
Jack Jansenedf58551994-12-14 13:36:34 +00001/*
2 * Glue routines for mactcp module.
3 * Jack Jansen, CWI, 1994.
4 *
5 * Adapted from mactcp socket library, which was in turn
6 * adapted from ncsa telnet code.
7 *
8 * Original authors: Tom Milligan, Charlie Reiman
9 */
10
11# include <Memory.h>
12# include <Files.h>
13# include <Errors.h>
14
15#include "tcpglue.h"
16#include <Devices.h>
17
Jack Jansenedf58551994-12-14 13:36:34 +000018static short driver = 0;
19
20#ifndef __powerc
21/*
22 * Hack fix for MacTCP 1.0.X bug
23 *
24 * This hack doesn't work on the PPC. But then, people with new machines
25 * shouldn't run ancient buggy software. -- Jack.
26 */
27
28pascal char *ReturnA5(void) = {0x2E8D};
29#endif /* !__powerc */
30
31OSErr xOpenDriver()
32{
33 if (driver == 0)
34 {
35 ParamBlockRec pb;
36 OSErr io;
37
38 pb.ioParam.ioCompletion = 0L;
39 pb.ioParam.ioNamePtr = "\p.IPP";
40 pb.ioParam.ioPermssn = fsCurPerm;
41 io = PBOpen(&pb,false);
42 if (io != noErr)
43 return(io);
44 driver = pb.ioParam.ioRefNum;
45 }
46 return noErr;
47}
48
49/*
50 * create a TCP stream
51 */
52OSErr xTCPCreate(buflen,notify,udp, pb)
53 int buflen;
Jack Jansen75b6f1c1995-01-18 13:50:42 +000054 TCPNotifyUPP notify;
Jack Jansenedf58551994-12-14 13:36:34 +000055 void *udp;
56 TCPiopb *pb;
57{
58 pb->ioCRefNum = driver;
59 pb->csCode = TCPCreate;
60 pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
61 pb->csParam.create.rcvBuffLen = buflen;
62 pb->csParam.create.notifyProc = notify;
63 pb->csParam.create.userDataPtr = udp;
64 return (xPBControlSync(pb));
65}
66
67
68/*
69 * start listening for a TCP connection
70 */
Jack Jansen75b6f1c1995-01-18 13:50:42 +000071OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion,
Jack Jansenedf58551994-12-14 13:36:34 +000072 void *udp)
73{
74 if (driver == 0)
75 return(invalidStreamPtr);
76
77 pb->ioCRefNum = driver;
78 pb->csCode = TCPPassiveOpen;
79 pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
80 pb->csParam.open.ulpTimeoutValue = 255 /* seconds */;
81 pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
82 pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
83 pb->csParam.open.remoteHost = 0;
84 pb->csParam.open.remotePort = 0;
85 pb->csParam.open.localHost = 0;
86 pb->csParam.open.localPort = port;
87 pb->csParam.open.dontFrag = 0;
88 pb->csParam.open.timeToLive = 0;
89 pb->csParam.open.security = 0;
90 pb->csParam.open.optionCnt = 0;
91 pb->csParam.open.userDataPtr = udp;
92 return (xPBControl(pb,completion));
93}
94
95/*
96 * connect to a remote TCP
97 */
98OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport,
Jack Jansen75b6f1c1995-01-18 13:50:42 +000099 TCPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000100{
101 if (driver == 0)
102 return(invalidStreamPtr);
103
104 pb->ioCRefNum = driver;
105 pb->csCode = TCPActiveOpen;
106 pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
107 pb->csParam.open.ulpTimeoutValue = 60 /* seconds */;
108 pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
109 pb->csParam.open.commandTimeoutValue = 0;
110 pb->csParam.open.remoteHost = rhost;
111 pb->csParam.open.remotePort = rport;
112 pb->csParam.open.localHost = 0;
113 pb->csParam.open.localPort = port;
114 pb->csParam.open.dontFrag = 0;
115 pb->csParam.open.timeToLive = 0;
116 pb->csParam.open.security = 0;
117 pb->csParam.open.optionCnt = 0;
118 return (xPBControl(pb,completion));
119}
120
121OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
122 TCPiopb *pb;
123 rdsEntry *rds;
124 int rdslen;
125 int timeout;
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000126 TCPIOCompletionUPP completion;
Jack Jansenedf58551994-12-14 13:36:34 +0000127{
128
129 if (driver == 0)
130 return(invalidStreamPtr);
131
132 pb->ioCRefNum = driver;
133 pb->csCode = TCPNoCopyRcv;
134 pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
135 pb->csParam.receive.rdsPtr = (Ptr)rds;
136 pb->csParam.receive.rdsLength = rdslen;
137 return (xPBControl(pb,completion));
138}
139
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000140OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000141 {
142 pb->ioCRefNum = driver;
143 pb->csCode = TCPRcvBfrReturn;
144 pb->csParam.receive.rdsPtr = (Ptr)rds;
145
146 return (xPBControl(pb,completion));
147 }
148
149/*
150 * send data
151 */
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000152OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000153{
154 if (driver == 0)
155 return invalidStreamPtr;
156
157 pb->ioCRefNum = driver;
158 pb->csCode = TCPSend;
159 pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
160 pb->csParam.send.ulpTimeoutValue = 60 /* seconds */;
161 pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
162 pb->csParam.send.pushFlag = push;
163 pb->csParam.send.urgentFlag = urgent;
164 pb->csParam.send.wdsPtr = (Ptr)wds;
165 return (xPBControl(pb,completion));
166}
167
168
169/*
170 * close a connection
171 */
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000172OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000173{
174 if (driver == 0)
175 return(invalidStreamPtr);
176
177 pb->ioCRefNum = driver;
178 pb->csCode = TCPClose;
179 pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
180 pb->csParam.close.ulpTimeoutValue = 60 /* seconds */;
181 pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
182 return (xPBControl(pb,completion));
183}
184
185/*
186 * abort a connection
187 */
188OSErr xTCPAbort(TCPiopb *pb)
189{
190 if (driver == 0)
191 return(invalidStreamPtr);
192
193 pb->ioCRefNum = driver;
194 pb->csCode = TCPAbort;
195 return (xPBControlSync(pb));
196}
197
198/*
199 * close down a TCP stream (aborting a connection, if necessary)
200 */
201OSErr xTCPRelease(pb)
202 TCPiopb *pb;
203{
204 OSErr io;
205
206 if (driver == 0)
207 return(invalidStreamPtr);
208
209 pb->ioCRefNum = driver;
210 pb->csCode = TCPRelease;
211 io = xPBControlSync(pb);
212 if (io == noErr)
213 DisposPtr(pb->csParam.create.rcvBuff); /* there is no release pb */
214 return(io);
215}
216
217#if 0
218
219int
220xTCPBytesUnread(sp)
221 SocketPtr sp;
222{
223 TCPiopb *pb;
224 OSErr io;
225
226 if (!(pb = sock_fetch_pb(sp)))
227 return -1; /* panic */
228
229 if (driver == 0)
230 return(-1);
231
232 pb->ioCRefNum = driver;
233 pb->csCode = TCPStatus;
234 io = xPBControlSync(pb);
235 if (io != noErr)
236 return(-1);
237 return(pb->csParam.status.amtUnreadData);
238}
239
240int
241xTCPBytesWriteable(sp)
242 SocketPtr sp;
243 {
244 TCPiopb *pb;
245 OSErr io;
246 long amount;
247
248 if (!(pb = sock_fetch_pb(sp)))
249 return -1; /* panic */
250
251 if (driver == 0)
252 return(-1);
253
254 pb->ioCRefNum = driver;
255 pb->csCode = TCPStatus;
256 io = xPBControlSync(pb);
257 if (io != noErr)
258 return(-1);
259 amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
260 if (amount < 0)
261 amount = 0;
262 return amount;
263 }
264
265int xTCPWriteBytesLeft(SocketPtr sp)
266 {
267 TCPiopb *pb;
268 OSErr io;
269
270 if (!(pb = sock_fetch_pb(sp)))
271 return -1; /* panic */
272
273 if (driver == 0)
274 return(-1);
275
276 pb->ioCRefNum = driver;
277 pb->csCode = TCPStatus;
278 io = xPBControlSync(pb);
279 if (io != noErr)
280 return(-1);
281 return (pb->csParam.status.amtUnackedData);
282 }
283#endif
284
285OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb)
286 {
287 OSErr io;
288
289 if (driver == 0)
290 return(-1);
291
292 pb->ioCRefNum = driver;
293 pb->csCode = TCPStatus;
294 io = xPBControlSync(pb);
295 if (io == noErr)
296 *spb = &pb->csParam.status;
297 return(io);
298 }
299
300
301/*
302 * create a UDP stream, hook it to a socket.
303 */
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000304OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp)
Jack Jansenedf58551994-12-14 13:36:34 +0000305 {
306 OSErr io;
307
308 pb->ioCRefNum = driver;
309 pb->csCode = UDPCreate;
310 pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
311 pb->csParam.create.rcvBuffLen = buflen;
312 pb->csParam.create.notifyProc = asr;
313 pb->csParam.create.userDataPtr = udp;
314 pb->csParam.create.localPort = *port;
315 if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
316 return io;
317
318 *port = pb->csParam.create.localPort;
319 return noErr;
320 }
321
322/*
323 * ask for incoming data
324 */
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000325OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000326 {
327
328 if (driver == 0)
329 return(invalidStreamPtr);
330
331 pb->ioCRefNum = driver;
332 pb->csCode = UDPRead;
333 pb->csParam.receive.timeOut = timeout;
334 pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000335 return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion ));
Jack Jansenedf58551994-12-14 13:36:34 +0000336 }
337
338OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
339 {
340
341 if (driver == 0)
342 return(invalidStreamPtr);
343
344 pb->ioCRefNum = driver;
345 pb->csCode = UDPBfrReturn;
346 pb->csParam.receive.rcvBuff = buff;
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000347 return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) );
Jack Jansenedf58551994-12-14 13:36:34 +0000348 }
349
350/*
351 * send data
352 */
353OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000354 UDPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000355 {
356
357 if (driver == 0)
358 return(invalidStreamPtr);
359
360 pb->ioCRefNum = driver;
361 pb->csCode = UDPWrite;
362 pb->csParam.send.remoteHost = host;
363 pb->csParam.send.remotePort = port;
364 pb->csParam.send.wdsPtr = (Ptr)wds;
365 pb->csParam.send.checkSum = true;
366 pb->csParam.send.sendLength = 0/* must be zero */;
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000367 return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion));
Jack Jansenedf58551994-12-14 13:36:34 +0000368 }
369
370/*
371 * close down a UDP stream (aborting a read, if necessary)
372 */
373OSErr xUDPRelease(UDPiopb *pb) {
374 OSErr io;
375
376 if (driver == 0)
377 return(invalidStreamPtr);
378
379 pb->ioCRefNum = driver;
380 pb->csCode = UDPRelease;
381 io = xPBControlSync( (TCPiopb *)pb );
382 if (io == noErr) {
383 DisposPtr(pb->csParam.create.rcvBuff);
384 }
385 return(io);
386 }
387
388ip_addr xIPAddr(void)
389{
390 struct GetAddrParamBlock pbr;
391 OSErr io;
392
393 pbr.ioCRefNum = driver;
394 pbr.csCode = ipctlGetAddr;
395 io = xPBControlSync( (TCPiopb *)&pbr );
396 if (io != noErr)
397 return(0);
398 return(pbr.ourAddress);
399}
400
401long xNetMask()
402{
403 struct GetAddrParamBlock pbr;
404 OSErr io;
405
406 pbr.ioCRefNum = driver;
407 pbr.csCode = ipctlGetAddr;
408 io = xPBControlSync( (TCPiopb *)&pbr);
409 if (io != noErr)
410 return(0);
411 return(pbr.ourNetMask);
412}
413
414unsigned short xMaxMTU()
415{
416 struct UDPiopb pbr;
417 OSErr io;
418
419 pbr.ioCRefNum = driver;
420 pbr.csCode = UDPMaxMTUSize;
421 pbr.csParam.mtu.remoteHost = xIPAddr();
422 io = xPBControlSync( (TCPiopb *)&pbr );
423 if (io != noErr)
424 return(0);
425 return(pbr.csParam.mtu.mtuSize);
426}
427
428OSErr xPBControlSync(TCPiopb *pb)
429{
430 (pb)->ioCompletion = 0L;
431 return PBControl((ParmBlkPtr)(pb),false);
432}
433
434#pragma segment SOCK_RESIDENT
435
436OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
437 TCPiopb *pb;
438 Ptr buf;
439 int buflen;
440 int timeout;
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000441 TCPIOCompletionUPP completion;
Jack Jansenedf58551994-12-14 13:36:34 +0000442{
443
444 if (driver == 0)
445 return(invalidStreamPtr);
446
447 pb->ioCRefNum = driver;
448 pb->csCode = TCPRcv;
449 pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
450 pb->csParam.receive.rcvBuff = buf;
451 pb->csParam.receive.rcvBuffLen = buflen;
452 return (xPBControl(pb,completion));
453}
454
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000455OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion)
Jack Jansenedf58551994-12-14 13:36:34 +0000456{
457#ifndef __MWERKS__
458 pb->ioNamePtr = ReturnA5();
459#endif
460
461 if (completion == 0L)
462 {
463 (pb)->ioCompletion = 0L;
464 return(PBControl((ParmBlkPtr)(pb),false)); /* sync */
465 }
Jack Jansen75b6f1c1995-01-18 13:50:42 +0000466 else if (completion == (TCPIOCompletionUPP)-1L)
Jack Jansenedf58551994-12-14 13:36:34 +0000467 {
468 (pb)->ioCompletion = 0L;
469 return(PBControl((ParmBlkPtr)(pb),true)); /* async */
470 }
471 else
472 {
Jack Jansenedf58551994-12-14 13:36:34 +0000473 (pb)->ioCompletion = completion;
Jack Jansenedf58551994-12-14 13:36:34 +0000474 return(PBControl((ParmBlkPtr)(pb),true)); /* async */
475 }
476}
477