summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Mac/Unsupported/mactcp/macdnrmodule.c17
-rw-r--r--Mac/Unsupported/mactcp/mactcpmodule.c104
-rw-r--r--Mac/Unsupported/mactcp/tcpglue.c45
-rw-r--r--Mac/Unsupported/mactcp/tcpglue.h43
4 files changed, 146 insertions, 63 deletions
diff --git a/Mac/Unsupported/mactcp/macdnrmodule.c b/Mac/Unsupported/mactcp/macdnrmodule.c
index 75dd89a..ca6ea1e 100644
--- a/Mac/Unsupported/mactcp/macdnrmodule.c
+++ b/Mac/Unsupported/mactcp/macdnrmodule.c
@@ -190,8 +190,10 @@ dnrr_getattr(self, name)
if ( rv ) return rv;
err_clear();
if ( self->waiting )
- if ( !dnrwait(self) )
+ if ( !dnrwait(self) ) {
+ err_setstr(ErrorObject, "Resolver busy");
return NULL;
+ }
tp = self->type;
return getmember((char *)&self->hinfo, dnrr_mlists[tp], name);
}
@@ -293,7 +295,7 @@ dnr_StrToAddr(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
- } else {
+ } else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -321,7 +323,7 @@ dnr_AddrToName(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
- } else {
+ } else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -369,7 +371,7 @@ dnr_HInfo(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
- } else {
+ } else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -401,17 +403,12 @@ dnr_MXInfo(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
- } else {
+ } else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
}
return (object *)rv;
-
- if (!newgetargs(args, ""))
- return NULL;
- INCREF(None);
- return None;
}
/* List of methods defined in the module */
diff --git a/Mac/Unsupported/mactcp/mactcpmodule.c b/Mac/Unsupported/mactcp/mactcpmodule.c
index 0ba05ec..f2c1290 100644
--- a/Mac/Unsupported/mactcp/mactcpmodule.c
+++ b/Mac/Unsupported/mactcp/mactcpmodule.c
@@ -30,8 +30,21 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <Desk.h>
+/* State of a tcp stream, in the connectionState field */
+#define STATE_CLOSED 0
+#define STATE_LISTEN 2
+#define STATE_ESTAB 8
+#define STATE_CWAIT 18
+
static object *ErrorObject;
+TCPIOCompletionUPP upp_tcp_done;
+TCPNotifyUPP upp_tcp_asr;
+#if 0
+UDPIOCompletionUPP upp_udp_done;
+#endif
+UDPNotifyUPP upp_udp_asr;
+
/* ----------------------------------------------------- */
/* Declarations for objects of type MacTCP connection status */
@@ -64,6 +77,8 @@ staticforward typeobject Tcpgstype;
typedef struct {
OB_HEAD
TCPiopb iop;
+ long localhost; /* Our IP address */
+ short localport; /* Our port number */
object *asr; /* Optional async notification routine */
int asr_ec; /* error code parameter to asr */
int asr_reason; /* detail for some errors */
@@ -242,6 +257,34 @@ static typeobject Tcpgstype = {
/* -------------------------------------------------------- */
static int
+tcps_checkstate(self, state, state2)
+ tcpsobject *self;
+ int state, state2;
+{
+ OSErr err;
+ TCPStatusPB *pb;
+ char buf[80];
+
+ if ( self->async_busy ) {
+ err_setstr(ErrorObject, "Operation not allowed, PassiveOpen in progress");
+ return -1;
+ }
+ if ( state < 0 && state2 < 0 )
+ return 0;
+ err = xTCPStatus(&self->iop, &pb);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return -1;
+ }
+ if ( state == pb->connectionState ||
+ state2 == pb->connectionState )
+ return 0;
+ sprintf(buf, "Operation not allowed, connection state=%d", pb->connectionState);
+ err_setstr(ErrorObject, buf);
+ return -1;
+}
+
+static int
tcps_asr_safe(arg)
void *arg;
{
@@ -276,14 +319,14 @@ tcps_asr(str, ec, self, reason, icmp)
}
static void
-tcps_opendone(pb)
+tcps_done(pb)
TCPiopb *pb;
{
tcpsobject *self = (tcpsobject *)pb->csParam.open.userDataPtr;
if ( pb != &self->iop || !self->async_busy ) {
/* Oops... problems */
- printf("tcps_opendone: unexpected call\n");
+ printf("tcps_done: unexpected call\n");
return;
}
self->async_busy = 0;
@@ -339,15 +382,19 @@ tcps_PassiveOpen(self, args)
if (!newgetargs(args, "h", &port))
return NULL;
+ if ( tcps_checkstate(self, -1, -1) < 0 )
+ return NULL;
self->async_busy = 1;
self->async_err = 0;
- err = xTCPPassiveOpen(&self->iop, port, (TCPIOCompletionProc)tcps_opendone,
+ err = xTCPPassiveOpen(&self->iop, port, upp_tcp_done,
(void *)self);
if ( err ) {
self->async_busy = 0;
PyErr_Mac(ErrorObject, err);
return NULL;
}
+ self->localhost = self->iop.csParam.open.localHost;
+ self->localport = self->iop.csParam.open.localPort;
INCREF(None);
return None;
}
@@ -363,11 +410,15 @@ tcps_ActiveOpen(self, args)
if (!newgetargs(args, "hlh", &lport, &rhost, &rport))
return NULL;
- err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionProc)0);
+ if ( tcps_checkstate(self, -1, -1) < 0 )
+ return NULL;
+ err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
}
+ self->localhost = self->iop.csParam.open.localHost;
+ self->localport = self->iop.csParam.open.localPort;
INCREF(None);
return None;
}
@@ -385,11 +436,13 @@ tcps_Send(self, args)
if (!newgetargs(args, "s#|ii", &buf, &bufsize, &push, &urgent))
return NULL;
+ if ( tcps_checkstate(self, STATE_ESTAB, STATE_CWAIT) < 0 )
+ return NULL;
wds.length = bufsize;
wds.ptr = buf;
wds.terminus = 0;
err = xTCPSend(&self->iop, (wdsEntry *)&wds, (Boolean)push, (Boolean)urgent,
- (TCPIOCompletionProc)0);
+ (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -412,8 +465,10 @@ tcps_Rcv(self, args)
if (!newgetargs(args, "i", &timeout))
return NULL;
+ if ( tcps_checkstate(self, -1, -1) < 0 )
+ return NULL;
memset((char *)&rds, 0, sizeof(rds));
- err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionProc)0);
+ err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -421,7 +476,7 @@ tcps_Rcv(self, args)
urgent = self->iop.csParam.receive.urgentFlag;
mark = self->iop.csParam.receive.markFlag;
rv = newsizedstringobject((char *)rds[0].ptr, rds[0].length);
- err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionProc)0);
+ err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionUPP)0);
if ( err ) {
/* Should not happen */printf("mactcp module: BufReturn failed?\n");
PyErr_Mac(ErrorObject, err);
@@ -440,7 +495,7 @@ tcps_Close(self, args)
if (!newgetargs(args, ""))
return NULL;
- err = xTCPClose(&self->iop, (TCPIOCompletionProc)0);
+ err = xTCPClose(&self->iop, (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -477,6 +532,8 @@ tcps_Status(self, args)
if (!newgetargs(args, ""))
return NULL;
+ if ( tcps_checkstate(self, -1, -1) < 0 )
+ return NULL;
err = xTCPStatus(&self->iop, &pb);
if ( err ) {
PyErr_Mac(ErrorObject, err);
@@ -485,6 +542,21 @@ tcps_Status(self, args)
return (object *)newtcpcsobject(pb);
}
+static object *
+tcps_GetSockName(self, args)
+ tcpsobject *self;
+ object *args;
+{
+ /* This routine is needed so we can get at the local port even when
+ ** a PassiveOpen is in progress (when we can't do a Status call).
+ ** This is needed for socket listen(); getsockname(); accept() emulation
+ ** as used by ftp and the like.
+ */
+ if (!newgetargs(args, ""))
+ return NULL;
+ return mkvalue("(lh)", self->localhost, self->localport);
+}
+
static struct methodlist tcps_methods[] = {
{"isdone", (method)tcps_isdone, 1},
{"wait", (method)tcps_wait, 1},
@@ -495,6 +567,7 @@ static struct methodlist tcps_methods[] = {
{"Close", (method)tcps_Close, 1},
{"Abort", (method)tcps_Abort, 1},
{"Status", (method)tcps_Status, 1},
+ {"GetSockName", (method)tcps_GetSockName, 1},
{NULL, NULL} /* sentinel */
};
@@ -535,7 +608,7 @@ newtcpsobject(bufsize)
if (self == NULL)
return NULL;
memset((char *)&self->iop, 0, sizeof(self->iop));
- err= xTCPCreate(bufsize, (TCPNotifyProc)tcps_asr, (void *)self, &self->iop);
+ err= xTCPCreate(bufsize, upp_tcp_asr, (void *)self, &self->iop);
if ( err ) {
DEL(self);
PyErr_Mac(ErrorObject, err);
@@ -626,7 +699,7 @@ udps_Read(self, args)
if (!newgetargs(args, "i", &timeout))
return NULL;
- err = xUDPRead(&self->iop, timeout, (UDPIOCompletionProc)0);
+ err = xUDPRead(&self->iop, timeout, (UDPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -659,7 +732,7 @@ udps_Write(self, args)
wds.length = bufsize;
wds.ptr = buf;
wds.terminus = 0;
- err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionProc)0);
+ err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@@ -715,7 +788,7 @@ newudpsobject(bufsize, port)
return NULL;
memset((char *)&self->iop, 0, sizeof(self->iop));
self->port = port;
- err= xUDPCreate(&self->iop, bufsize, &self->port, (UDPNotifyProc)udps_asr,
+ err= xUDPCreate(&self->iop, bufsize, &self->port, upp_udp_asr,
(void *)self);
if ( err ) {
DEL(self);
@@ -899,6 +972,13 @@ initmactcp()
d = getmoduledict(m);
ErrorObject = newstringobject("mactcp.error");
dictinsert(d, "error", ErrorObject);
+
+ upp_tcp_done = NewTCPIOCompletionProc(tcps_done);
+ upp_tcp_asr = NewTCPNotifyProc(tcps_asr);
+#if 0
+ upp_udp_done = NewUDPIOCompletionProc(udps_done);
+#endif
+ upp_udp_asr = NewUDPNotifyProc(udps_asr);
/* XXXX Add constants here */
diff --git a/Mac/Unsupported/mactcp/tcpglue.c b/Mac/Unsupported/mactcp/tcpglue.c
index 1c8ecb0..79042b4 100644
--- a/Mac/Unsupported/mactcp/tcpglue.c
+++ b/Mac/Unsupported/mactcp/tcpglue.c
@@ -15,11 +15,6 @@
#include "tcpglue.h"
#include <Devices.h>
-#ifndef __MWERKS__
-#define TCPIOCompletionUPP TCPIOCompletionProc
-#define NewTCPIOCompletionProc(x) (x)
-#endif /* __MWERKS__ */
-
static short driver = 0;
#ifndef __powerc
@@ -56,7 +51,7 @@ OSErr xOpenDriver()
*/
OSErr xTCPCreate(buflen,notify,udp, pb)
int buflen;
- TCPNotifyProc notify;
+ TCPNotifyUPP notify;
void *udp;
TCPiopb *pb;
{
@@ -73,7 +68,7 @@ OSErr xTCPCreate(buflen,notify,udp, pb)
/*
* start listening for a TCP connection
*/
-OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion,
+OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion,
void *udp)
{
if (driver == 0)
@@ -101,7 +96,7 @@ OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion,
* connect to a remote TCP
*/
OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport,
- TCPIOCompletionProc completion)
+ TCPIOCompletionUPP completion)
{
if (driver == 0)
return(invalidStreamPtr);
@@ -128,7 +123,7 @@ OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
rdsEntry *rds;
int rdslen;
int timeout;
- TCPIOCompletionProc completion;
+ TCPIOCompletionUPP completion;
{
if (driver == 0)
@@ -142,7 +137,7 @@ OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
return (xPBControl(pb,completion));
}
-OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
+OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion)
{
pb->ioCRefNum = driver;
pb->csCode = TCPRcvBfrReturn;
@@ -154,7 +149,7 @@ OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
/*
* send data
*/
-OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion)
+OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion)
{
if (driver == 0)
return invalidStreamPtr;
@@ -174,7 +169,7 @@ OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCo
/*
* close a connection
*/
-OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion)
+OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion)
{
if (driver == 0)
return(invalidStreamPtr);
@@ -306,7 +301,7 @@ OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb)
/*
* create a UDP stream, hook it to a socket.
*/
-OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp)
+OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp)
{
OSErr io;
@@ -327,7 +322,7 @@ OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *
/*
* ask for incoming data
*/
-OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion)
+OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionUPP completion)
{
if (driver == 0)
@@ -337,7 +332,7 @@ OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion)
pb->csCode = UDPRead;
pb->csParam.receive.timeOut = timeout;
pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
- return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionProc)completion ));
+ return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion ));
}
OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
@@ -349,14 +344,14 @@ OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
pb->ioCRefNum = driver;
pb->csCode = UDPBfrReturn;
pb->csParam.receive.rcvBuff = buff;
- return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionProc)-1 ) );
+ return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) );
}
/*
* send data
*/
OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
- UDPIOCompletionProc completion)
+ UDPIOCompletionUPP completion)
{
if (driver == 0)
@@ -369,7 +364,7 @@ OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
pb->csParam.send.wdsPtr = (Ptr)wds;
pb->csParam.send.checkSum = true;
pb->csParam.send.sendLength = 0/* must be zero */;
- return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionProc)completion));
+ return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion));
}
/*
@@ -443,7 +438,7 @@ OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
Ptr buf;
int buflen;
int timeout;
- TCPIOCompletionProc completion;
+ TCPIOCompletionUPP completion;
{
if (driver == 0)
@@ -457,7 +452,7 @@ OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
return (xPBControl(pb,completion));
}
-OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion)
+OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion)
{
#ifndef __MWERKS__
pb->ioNamePtr = ReturnA5();
@@ -468,22 +463,14 @@ OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion)
(pb)->ioCompletion = 0L;
return(PBControl((ParmBlkPtr)(pb),false)); /* sync */
}
- else if (completion == (TCPIOCompletionProc)-1L)
+ else if (completion == (TCPIOCompletionUPP)-1L)
{
(pb)->ioCompletion = 0L;
return(PBControl((ParmBlkPtr)(pb),true)); /* async */
}
else
{
-#if 0
- /* If I understand the PowerPC calling correctly this is the right
- ** code, but the MetroWerks headers seem to disagree. We'll see... -- Jack
- */
- TCPIOCompletionUPP comp_upp = NewTCPIOCompletionProc(completion);
- (pb)->ioCompletion = comp_upp;
-#else
(pb)->ioCompletion = completion;
-#endif
return(PBControl((ParmBlkPtr)(pb),true)); /* async */
}
}
diff --git a/Mac/Unsupported/mactcp/tcpglue.h b/Mac/Unsupported/mactcp/tcpglue.h
index 4db91f0..ef9e133 100644
--- a/Mac/Unsupported/mactcp/tcpglue.h
+++ b/Mac/Unsupported/mactcp/tcpglue.h
@@ -14,6 +14,21 @@
#include <UDPPB.h>
#include <AddressXlation.h>
+#ifndef __MWERKS__
+#define TCPIOCompletionUPP TCPIOCompletionProc
+#define TCPNotifyUPP TCPNotifyProc
+#define UDPIOCompletionUPP UDPIOCompletionProc
+#define UDPNotifyUPP UDPNotifyProc
+#define NewTCPIOCompletionProc(x) (x)
+#define NewTCPNotifyProc(x) (x)
+#define NewUDPIOCompletionProc(x) (x)
+#define NewUDPNotifyProc(x) (x)
+#endif /* __MWERKS__ */
+
+#if defined(powerc) || defined (__powerc)
+#pragma options align=mac68k
+#endif
+
typedef struct miniwds
{
unsigned short length;
@@ -21,26 +36,30 @@ typedef struct miniwds
unsigned short terminus; /* must be zero'd for use */
} miniwds;
+#if defined(powerc) || defined(__powerc)
+#pragma options align=reset
+#endif
+
OSErr xOpenDriver(void);
-OSErr xPBControl(TCPiopb *pb, TCPIOCompletionProc completion);
+OSErr xPBControl(TCPiopb *pb, TCPIOCompletionUPP completion);
OSErr xPBControlSync(TCPiopb *pb);
-OSErr xTCPCreate(int buflen, TCPNotifyProc notify, void *udp, TCPiopb *pb);
-OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion, void *udp);
-OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionProc completion);
-OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionProc completion);
-OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionProc);
-OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion);
-OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion);
-OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion);
+OSErr xTCPCreate(int buflen, TCPNotifyUPP notify, void *udp, TCPiopb *pb);
+OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion, void *udp);
+OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionUPP completion);
+OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionUPP completion);
+OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionUPP);
+OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion);
+OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion);
+OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion);
OSErr xTCPAbort(TCPiopb *pb);
OSErr xTCPRelease(TCPiopb *pb);
-OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp);
-OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionProc completion);
+OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp);
+OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionUPP completion);
OSErr xUDPBfrReturn(UDPiopb *pb, char *buff);
OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
- UDPIOCompletionProc completion);
+ UDPIOCompletionUPP completion);
OSErr xUDPRelease(UDPiopb *pb);
ip_addr xIPAddr(void);