#define EXT_DIAG_SOCKET 0x5684      /* hi-lo order */
#define COUNT 5
#define SEND 3
typedef struct
{
      char  objectName[48];
      WORDobjectType;
      long  objectID;
      BYTE  loginTime[7];
}connInfo;

typedef struct
{
      unsigned char majorVersion;
      unsigned char minorVersion;
      unsigned short SPXsocket;
      BYTE numComponents;
      BYTE IPXSPXcomponent;
      BYTE bridgeComponent;
      BYTE serverComp[13];
} identData;

unsigned short SPXDiagSocket;
unsigned  char networkAddress[10];
extern unsigned long mySem;

NodeIdent(unsigned char *reqNode)
{
      int                     ccode;
      unsigned short revision;
      identData               ident;
      IPX_HEADER              identSend;
      IPX_ECB                 identECB;
      unsigned longtransportTime;

      ccode = IpxGetVersion(&(ident.majorVersion),
                                                 &(ident.minorVersion),
                                                 &revision);
      if (ccode)
            return 0xFF;
      ident.SPXsocket  = SPXDiagSocket;
      ident.numComponents  = 3;
      ident.IPXSPXcomponent  = 0;
      ident.bridgeComponent  = 1;
      ident.serverComp[0]  = 6;
      ident.serverComp[1]  = '?';
      ident.serverComp[2]  = 4;
      memcpy(&(ident.serverComp[3]), networkAddress, 10);
      memcpy(identSend.destNet, reqNode, 12);
      identSend.packetLen  = (sizeof(IPX_HEADER)  + sizeof(identData));
      identECB.queueHead  = 0x00;
      identECB.socket  = EXT_DIAG_SOCKET;
      identECB.fragCount  = 2;
      identECB.fragList[0].fragAddress   = (IPX_ECB *)&identSend;
      identECB.fragList[0].fragSize  = (unsigned long)sizeof(IPX_HEADER);
      identECB.fragList[1].fragAddress  = (IPX_HEADER *)&ident;
      identECB.fragList[1].fragSize  = sizeof(identData);

      ccode  = IpxGetLocalTarget(reqNode,  &identECB,  &transportTime);
      if (ccode)
            return 0xFF;

      ccode  = IpxSend(EXT_DIAG_SOCKET, &identECB);
      if (ccode)
            return (ccode);
      ccode  = WaitOnLocalSemaphore(mySem);
      return ccode;
}

ServConfig(unsigned  char *reqNode)
{
      int ccode;
      FILE_SERV_INFO serverInfo;
      IPX_HEADER              infoSend;
      IPX_ECB                 infoECB;
      unsigned longtransportTime;
      
      ccode  = GetServerInformation(59,  (FILE_SERV_INFO  *)&serverInfo);
      if (ccode)
            return 0xFF;
      /* fill in the packet header and the ECB.
            The second frag is the serverInfo struct.*/
      memcpy(infoSend.destNet, reqNode, 12);
      infoSend.packetLen  = (sizeof(IPX_HEADER)  + 59);
      infoECB.queueHead  = 0x00;
      info ECB.socket  = EXT_DIAG_SOCKET;
      infoECB.fragCount  = 2;
      infoECB.fragList[0].fragAddress  = (IPX_ECB  *)&infoSend;
      infoECB.fragList[0].fragSize  = (unsigned long)sizeof(IPX_HEADER);
      infoECB.fragList[1].fragAddress  = (IPX_HEADER  *)&serverInfo;
      infoECB.fragList[1].fragSize  = (unsigned long)59;

      ccode  = IpxGetLocalTarget(reqNode,  &infoECB,  &transportTime);
      if (ccode)
            return 0xFF;

      ccode  = IpxSend(EXT_DIAG_SOCKET,  &infoECB);
      if (ccode)
            return (ccode);
      CCODE  = WaitOnLocalSemaphore(mySem);
      return ccode;
}


ReturnConnectionTable(unsigned  char *reqNode, unsigned short connID)
{
      int ccode,i;
      SPX_ECB     connECB;
      SPX_HEADER  connSend;
      struct
      {
            int numConnections;
            connInfo    connTable[5];
      }retBuf;
      unsigned longtransportTime;
      
      for (i=1; i<=5; i++)
      {
            ccode  = GetConnectionInformation(i,

                  retBuf.connTable[i-1].objectName, 

                  &(retBuf.connTable[i-1].objectType), 

                  &(retBuf.connTable[i-1].objectID), 

                  &(retBuf.connTable[i-1].loginTime));
            }
            retBuf.numConnections  = 5;
      /* fill in the packet header and the ECB.
            The second frag is the connTable struct.*/
      memcpy(connSend.destNet,  reqNode, 12);
      connSend.packetLen  = (sizeof(IPX_HEADER)  + sizeof(retBuf));
      connECB.queueHead  = 0x00;
      connECB.semHandle  = mySem;
      connECB.socket  = EXT_DIAG_SOCKET;
      connECB.fragCount  = 2;
      connECB.fragList[0].fragAddress  = (IPX_ECB  *)&connSend;
      connECB.fragList[0].fragSize  = sizeof(IPX_HEADER);
      connECB.fragList[1].fragAddress  = (IPX_HEADER  *)&retBuf;
      connECB.fragList[1].fragSize  = sizeof(retBuf);

      ccode  = SpxSendSequencedPacket(connID,  &connECB);
      if (ccode)
            return (ccode);
      ccode  = WaitOnLocalSemaphore(mySem);
      return ccode;
}

KnownNetworks(unsigned  char *reqNode, unsigned short connID)
{
      int ccode,i;
      SPX_HEADER              netSend;
      SPX_ECB                 netECB;
      struct
      {
            int   ccode;
            int   intervalMarker;
            int   numNetworks;
            unsigned longnetTable[5];
      } retBuf;
      unsigned longtransportTime;
      long                    objectID;
      char                    objName[48], objHasProp, objFlag, objSec;
      WORD              objType;
      BYTE                    propValue[128], moreSegments, propertyFlags;
      
      for (i=1; i<=5; i++)
      {
            ccode  = ScanBinderyObject("*", (WORD) 4
                                                            &objectID, &objName,
                                                            &objType, &objHasProp,
                                                            &objFlag, &objSec);
            if (ccode)
                  return 0xFF;
            ccode  = ReadPropertyValue(objName, objType, "NET_ADDRESS", (int) 1,
                                                            propValue,
 &moreSegments, &propertyFlags);
            if (ccode)
                  return 0xFF;
            memcpy(retBuf.netTable[i-1], propValue, 4);
      }
      retBuf.ccode  = 0;
      retBuf.intervalMarker  = 0xFF;
      retBuf.numNetworks  = 5;
      /* fill in the packet header and the ECB.
            The second frag is the netTable struct.*/
      memcpy(netSend.destNet,  reqNode, 12);
      netSend.packetLen  = (sizeof(IPX_HEADER) + sizeof(retBuf));
      netECB.queueHead  = 0x00;
      netECB.semHandle  = mySem;
      netECB.socket  = EXT_DIAG_SOCKET;
      netECB.fragCount  = 2;
      netECB.fragList[0].fragAddress  = (IPX_ECB  *)&netSend;
      netECB.fragList[0].fragSize  = sizeof(IPX_HEADER);
      netECB.fragList[1].fragAddress  = (IPX_HEADER  *)&retBuf;
      netECB.fragList[1].fragSize  = sizeof(retBuf);

      ccode  = SpxSendSequencedPacket(connID,  &netECB);
      if (ccode)
            return (ccode);
      ccode  = WaitOnLocalSemaphore(mySem);
      return ccode;
}

KnownServers(unsigned  char *reqNode, unsigned short connID)
{
      int ccode,i;
      struct
      {
            int   ccode;
            int   intervalMarker;
            int   numNetworks;
            char                    servTable[5][48];
      } retBuf;
      IPX_HEADER              servSend;
      IPX_ECB                 servECB;
      unsigned longtransportTime;
      long                    objectID;
      char                    objName[48], objHasProp, objFlag, objSec;
      WORD              objType;
      
      for (i=1; i<=5; i++)
      {
            ccode  = ScanBinderyObject("*", (WORD) 4,
                                                            &objectID,
 retBuf.servTable[i-1],
                                                            &objType,
 &objHasProp,
                                                            &objFlag, &objSec);
            if (ccode)
                  return 0xFF;
      }
      retBuf.ccode  = 0;
      retBuf.intervalMarker  = 0xFF;
      retBuf.numNetworks  = 5;
      /* fill in the packet header and the ECB.
            The second frag is the servTable. */
      memcpy(servSend.destNet, reqNode, 12);
      servSend.packetLen  = (sizeof(IPX_HEADER)  + sizeof(retBuf));
      servECB.queueHead  = 0x00;
      servECB.semHandle  = mySem;
      servECB.socket  = EXT_DIAG_SOCKET;
      servECB.fragCount  = 2;
      servECB.fragList[0].fragAddress  = (IPX_ECB  *)&servSend;
      servECB.fragList[0].fragSize  = sizeof(IPX_HEADER);
      servECB.fragList[1].fragAddress  = (IPX_ECB  *)&retBuf;
      servECB.fragList[1].fragSize  = sizeof(retBuf);

      ccode  = SpxSendSequencedPacket(connID,  &servECB);
      if (ccode)
            return (ccode);
      ccode  = WaitOnLocalSemaphore(mySem);
      return ccode;
      
}

PointTest(unsigned  char request, InternetAddress *dest,
                  WORD numPackets, BYTE *immediateAddress,
                  WORD packetSize, unsigned short socket)
{
      int                     ccode, i, count;
      IPX_HEADER              pointTest;
      IPX_ECB                 pointECB;
      BYTE                    data[512];

      memcpy(pointTest.destNet,  dest, 12);
      pointTest.packetLen   = packetSize;
      pointECB.queueHead   = 0x00
      memcpy(pointECB.socket,  socket, 2);
      memcpy(pointECB.immediateAddress,  immediateAddress,  6);
      pointECB.fragCount   = 2;
      pointECB.fragList[0].fragAddress   = (IPX_ECB  *)&pointTest;
      pointECB.fragList[0].fragSize   = sizeof(IPX_HEADER);
      pointECB.fragList[1].fragAddress   = (IPX_ECB  *)data;
      pointECB.fragList[1].fragSize   = sizeof(data);

      switch(request)
      {
            case SEND;
                  for (i=1; i<=numPackets;  i++)
                  {
                        ccode  = IpxSend(0x00, &pointECB);
                        if (ccode)
                              return ccode;
                        ccode  = WaitOnLocalSemaphore(mySem);
                        if (ccode)
                              return ccode;
                  }
                  break;
            case COUNT;
                  while (count < numPackets)
                  {
                        ccode  = IpxReceive(0x00,  &pointECB);
                        if (ccode)
                              return ccode;
                        ccode  = WaitOnLocalSemaphore(mySem);
                        if (ccode)
                              return ccode;
                  }
                  break;
            default :
                  return 0xFF;
      }
}

/* module from workstation program */
#define EXT_DIAG_SOCKET  0x5684   /*hi-lo 0x8456 */
#define DIAG_SOCKET  0x5604

/* This module shows sending only the first broadcast with no exclusions */
/* The listens for the responses could be posted here or in another module */

void GetIdent(void)
{
      IPXHeader   identSend;
      ECB         identECB;
      struct
      {
            BYTE numExclusions;
            BYTE exclAddress[80][6];
      } data;

      memset(identSend.destination.network,  0, 4);
      memset(identSend.destination.node,  0xFF, 6);
      identSend.destination.socket[0]   = 0x04;
      identSend.destination.socket[0]   = 0x56;
      identSend.packetType   = 0x04;
      identSend.length   = (sizeof(IPXHeader)   + sizeof(data));
      identECB.ESRAddress   = 0x00;
      memset(identECB.immediateAddress,  0xFF, 6);
      identECB.socketNumber   = DIAG_SOCKET;
      identECB.fragmentCount   = 2;
      identECB.fragmentDescriptor[0].address   = (char far  *)&identSend;
      identECB.fragmentDescriptor[0].size   = sizeof(IPXHeader);
      identECB.fragmentDescriptor[1].address   = (char far  *)&data;
      identECB.fragmentDescriptor[1].size   = sizeof(data);

      IPXSendPacket(&identECB);
      while (identECB.inUseFlag);

      identSend.destination.socket[0]   = 0x84;
      identSend.destination.socket[0]   = 0x56;
      identECB.socketNumber   = EXT_DIAG_SOCKET;

      IPXSendPacket(&identECB);
      while (identECB.inUseFlag);
      return;
}
