| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
- // software: you can redistribute it and/or modify it under the terms of
- // the GNU General Public License as published by the Free Software Foundation,
- // either version 3 of the License, or (at your option) any later version.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- /* $Header: /CounterStrike/IPXCONN.CPP 1 3/03/97 10:24a Joe_bostic $ */
- /***************************************************************************
- ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
- ***************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : IPXCONN.CPP *
- * *
- * Programmer : Bill Randolph *
- * *
- * Start Date : December 20, 1994 *
- * *
- * Last Update : April 9, 1995 [BRR] *
- * *
- *-------------------------------------------------------------------------*
- * Functions: *
- * IPXConnClass::IPXConnClass -- class constructor *
- * IPXConnClass::~IPXConnClass -- class destructor *
- * IPXConnClass::Init -- hardware-specific initialization routine *
- * IPXConnClass::Configure -- One-time initialization routine *
- * IPXConnClass::Start_Listening -- commands IPX to listen *
- * IPXConnClass::Stop_Listening -- commands IPX to stop listen *
- * IPXConnClass::Send -- sends a packet; invoked by SequencedConnection *
- * IPXConnClass::Open_Socket -- opens communications socket *
- * IPXConnClass::Close_Socket -- closes the socket *
- * IPXConnClass::Send_To -- sends the packet to the given address *
- * IPXConnClass::Broadcast -- broadcasts the given packet *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "function.h"
- #include <stdio.h>
- //#include <mem.h>
- #include <string.h>
- #include "ipxconn.h"
- #ifdef WINSOCK_IPX
- #include "WSProto.h"
- #else
- #include "ipx95.h"
- #ifdef WIN32
- #include "tcpip.h"
- #else //WIN32
- #include "fakesock.h"
- #endif //WIN32
- #endif //WINSOCK_IPX
- /*
- ********************************* Globals ***********************************
- */
- unsigned short IPXConnClass::Socket;
- int IPXConnClass::ConnectionNum;
- ECBType * IPXConnClass::ListenECB;
- IPXHeaderType * IPXConnClass::ListenHeader;
- char * IPXConnClass::ListenBuf;
- ECBType * IPXConnClass::SendECB;
- IPXHeaderType * IPXConnClass::SendHeader;
- char * IPXConnClass::SendBuf;
- long IPXConnClass::Handler;
- int IPXConnClass::Configured = 0;
- int IPXConnClass::SocketOpen = 0;
- int IPXConnClass::Listening = 0;
- int IPXConnClass::PacketLen;
- /***************************************************************************
- * IPXConnClass::IPXConnClass -- class constructor *
- * *
- * INPUT: *
- * numsend desired # of entries for the send queue *
- * numreceive desired # of entries for the receive queue *
- * maxlen max length of an application packet *
- * magicnum the packet "magic number" for this connection *
- * address address of destination (NULL = no address) *
- * id connection's unique numerical ID *
- * name connection's name *
- * extralen max size of app-specific extra bytes (optional) *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/20/1994 BR : Created. *
- *=========================================================================*/
- IPXConnClass::IPXConnClass (int numsend, int numreceive, int maxlen,
- unsigned short magicnum, IPXAddressClass *address, int id, char *name,
- int extralen) :
- ConnectionClass (numsend, numreceive, maxlen, magicnum,
- 2, // retry delta
- -1, // max retries
- 60, // timeout
- extralen) // (currently, this is only used by the Global Channel)
- {
- NetNumType net;
- NetNodeType node;
- /*------------------------------------------------------------------------
- Save the values passed in
- ------------------------------------------------------------------------*/
- if (address)
- Address = (*address);
- ID = id;
- strcpy (Name, name);
- #ifdef WINSOCK_IPX
- Address.Get_Address(net,node);
- memcpy(ImmediateAddress,node,6);
- Immed_Set = 0;
- #else
- if ( !Winsock.Get_Connected() ) {
- /*------------------------------------------------------------------------
- If our Address field is an actual address (ie NULL wasn't passed to the
- constructor), pre-compute the ImmediateAddress value for the SendECB.
- This allows pre-computing of the ImmediateAddress for all connections
- created after Configure() is called.
- ------------------------------------------------------------------------*/
- if (!Address.Is_Broadcast() && Configured==1) {
- Address.Get_Address(net,node);
- /*.....................................................................
- If the user is logged in & has a valid Novell Connection Number, get
- the bridge address the "official" way
- .....................................................................*/
- if (ConnectionNum != 0) {
- if (IPX_Get_Local_Target (net, node, Socket, ImmediateAddress)!=0) {
- memcpy(ImmediateAddress,node,6);
- }
- }
- /*.....................................................................
- Otherwise, use the destination node address as the ImmediateAddress,
- and just hope there's no network bridge in the path.
- .....................................................................*/
- else {
- memcpy(ImmediateAddress,node,6);
- }
- Immed_Set = 1;
- }
- else {
- memset (ImmediateAddress, 0, 6);
- Immed_Set = 0;
- }
- }
- #endif //WINSOCK_IPX
- } /* end of IPXConnClass */
- /***************************************************************************
- * IPXConnClass::Init -- hardware-specific initialization routine *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/20/1994 BR : Created. *
- *=========================================================================*/
- void IPXConnClass::Init (void)
- {
- /*------------------------------------------------------------------------
- Invoke the parent's Init routine
- ------------------------------------------------------------------------*/
- ConnectionClass::Init();
- } /* end of Init */
- /***************************************************************************
- * IPXConnClass::Configure -- One-time initialization routine *
- * *
- * This routine sets up static members that are shared by all IPX *
- * connections (ie those variables used by the Send/Listen/Broadcast *
- * routines). *
- * *
- * INPUT: *
- * socket socket ID for sending & receiving *
- * conn_num local IPX Connection Number (0 = not logged in) *
- * listen_ecb ptr to ECBType for listening *
- * send_ecb ptr to ECBType for sending *
- * listen_header ptr to IPXHeaderType for listening *
- * send_header ptr to IPXHeaderType for sending *
- * listen_buf ptr to buffer for listening *
- * send_buf ptr to buffer for sending *
- * handler_rm_ptr REAL-MODE pointer to event service routine *
- * (high word = segment, low word = offset) *
- * maxpacketlen max packet size to listen for *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * - All pointers must be protected-mode pointers, but must point to *
- * DOS real-mode memory (except the Handler segment/offset) *
- * *
- * HISTORY: *
- * 12/20/1994 BR : Created. *
- *=========================================================================*/
- void IPXConnClass::Configure (unsigned short socket, int conn_num,
- ECBType *listen_ecb, ECBType *send_ecb, IPXHeaderType *listen_header,
- IPXHeaderType *send_header, char *listen_buf, char *send_buf,
- long handler_rm_ptr, int maxpacketlen)
- {
- /*------------------------------------------------------------------------
- Save the values passed in
- ------------------------------------------------------------------------*/
- Socket = socket;
- ConnectionNum = conn_num;
- ListenECB = listen_ecb;
- SendECB = send_ecb;
- ListenHeader = listen_header;
- SendHeader = send_header;
- ListenBuf = listen_buf;
- SendBuf = send_buf;
- Handler = handler_rm_ptr;
- PacketLen = maxpacketlen;
- Configured = 1;
- } /* end of Configure */
- /***************************************************************************
- * IPXConnClass::Start_Listening -- commands IPX to listen *
- * *
- * This routine may be used to start listening in polled mode (if the *
- * ECB's Event_Service_Routine is NULL), or in interrupt mode; it's *
- * up to the caller to fill the ECB in. If in polled mode, Listening *
- * must be restarted every time a packet comes in. *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * - The ListenECB must have been properly filled in by the IPX Manager.*
- * - Configure must be called before calling this routine. *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- int IPXConnClass::Start_Listening(void)
- {
- #ifdef WIN32
- #ifdef WINSOCK_IPX
- /*
- ** Open the socket.
- */
- if (!Open_Socket(Socket))
- return(false);
- /*
- ** start listening on the socket.
- */
- if ( PacketTransport->Start_Listening () ) {
- Listening =1;
- return (true);
- } else {
- Close_Socket(Socket);
- return (false);
- }
- #else
- if (Winsock.Get_Connected ()) return (true);
- /*------------------------------------------------------------------------
- Open the Socket
- ------------------------------------------------------------------------*/
- if (!Open_Socket(Socket))
- return(false);
- if (IPX_Start_Listening95()) {
- Listening =1;
- return (true);
- } else {
- Close_Socket(Socket);
- return (false);
- }
- #endif //WINSOCK_IPX
- #else //WIN32
- void *hdr_ptr;
- unsigned long hdr_val;
- void *buf_ptr;
- unsigned long buf_val;
- int rc;
- /*------------------------------------------------------------------------
- Don't do a thing unless we've been configured, and we're not listening.
- ------------------------------------------------------------------------*/
- if (Configured==0 || Listening==1) {
- return(0);
- }
- /*------------------------------------------------------------------------
- Open the Socket
- ------------------------------------------------------------------------*/
- if (!Open_Socket(Socket)) {
- return(0);
- }
- /*------------------------------------------------------------------------
- Clear the ECB & header
- ------------------------------------------------------------------------*/
- memset(ListenECB, 0, sizeof(ECBType));
- memset(ListenHeader, 0, sizeof(IPXHeaderType));
- /*------------------------------------------------------------------------
- Convert protected-mode ptrs to real-mode ptrs
- ------------------------------------------------------------------------*/
- hdr_val = (unsigned long)ListenHeader;
- hdr_ptr = (void *)(((hdr_val & 0xffff0) << 12) | (hdr_val & 0x000f));
- buf_val = (unsigned long)ListenBuf;
- buf_ptr = (void *)(((buf_val & 0xffff0) << 12) | (buf_val & 0x000f));
- /*------------------------------------------------------------------------
- Fill in the ECB
- ------------------------------------------------------------------------*/
- ListenECB->SocketNumber = Socket;
- ListenECB->PacketCount = 2;
- ListenECB->Packet[0].Address = hdr_ptr;
- ListenECB->Packet[0].Length = sizeof(IPXHeaderType);
- ListenECB->Packet[1].Address = buf_ptr;
- ListenECB->Packet[1].Length = (unsigned short)PacketLen;
- ((long &)ListenECB->Event_Service_Routine) = Handler;
- /*------------------------------------------------------------------------
- Command IPX to listen
- ------------------------------------------------------------------------*/
- rc = IPX_Listen_For_Packet(ListenECB);
- if (rc!=0) {
- Close_Socket(Socket);
- return(0);
- }
- else {
- Listening = 1;
- return(1);
- }
- #endif //WIN32
- } /* end of Start_Listening */
- /***************************************************************************
- * IPXConnClass::Stop_Listening -- commands IPX to stop listen *
- * *
- * INPUT: *
- * none. *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * - This routine MUST NOT be called if IPX is not listening already! *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- int IPXConnClass::Stop_Listening(void)
- {
- #ifdef WINSOCK_IPX
- if ( PacketTransport ) PacketTransport->Stop_Listening();
- Listening = 0;
- // All done.
- return(1);
- #else
- /*------------------------------------------------------------------------
- Don't do anything unless we're already Listening.
- ------------------------------------------------------------------------*/
- if (Listening==0) {
- return(0);
- }
- #ifdef WIN32
- if (Winsock.Get_Connected()) {
- Listening = 0;
- return (true);
- } else {
- IPX_Shut_Down95();
- Close_Socket(Socket);
- }
- #else //WIN32
- /*------------------------------------------------------------------------
- Shut IPX down.
- ------------------------------------------------------------------------*/
- IPX_Cancel_Event(ListenECB);
- Close_Socket(Socket);
- #endif //WIN32
- Listening = 0;
- /*------------------------------------------------------------------------
- All done.
- ------------------------------------------------------------------------*/
- return(1);
- #endif //WINSOCK_IPX
- } /* end of Stop_Listening */
- /***************************************************************************
- * IPXConnClass::Send -- sends a packet; invoked by SequencedConnection *
- * *
- * INPUT: *
- * buf buffer to send *
- * buflen length of buffer to send *
- * extrabuf (not used by this class) *
- * extralen (not used by this class) *
- * *
- * OUTPUT: *
- * 1 = OK, 0 = error *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- int IPXConnClass::Send(char *buf, int buflen, void *, int)
- {
- /*------------------------------------------------------------------------
- Invoke our own Send_To routine, filling in our Address as the destination.
- ------------------------------------------------------------------------*/
- if (Immed_Set) {
- return(Send_To (buf, buflen, &Address, ImmediateAddress));
- }
- else {
- return(Send_To (buf, buflen, &Address, NULL));
- }
- } /* end of Send */
- /***************************************************************************
- * IPXConnClass::Open_Socket -- opens communications socket *
- * *
- * INPUT: *
- * socket desired socket ID number *
- * *
- * OUTPUT: *
- * 1 = OK, 0 = error *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- int IPXConnClass::Open_Socket(unsigned short socket)
- {
- int rc;
- #ifdef WINSOCK_IPX
- rc = PacketTransport->Open_Socket(socket);
- SocketOpen = rc;
- return ( rc );
- #else //WINSOCK_IPX
- if (Winsock.Get_Connected()) {
- SocketOpen = 1;
- return (true);
- }
- SocketOpen = 0;
- /*------------------------------------------------------------------------
- Try to open a listen socket. The socket may have been left open by
- a previously-crashed program, so ignore the state of the SocketOpen
- flag for this call; use IPX to determine if the socket was already open.
- ------------------------------------------------------------------------*/
- rc = IPX_Open_Socket(socket);
- if (rc) {
- /*.....................................................................
- If already open, close & reopen it
- .....................................................................*/
- if (rc==IPXERR_SOCKET_ERROR) {
- #ifdef WIN32
- WWDebugString ("Error -- Specified socket is already open");
- #endif //WIN32
- IPX_Close_Socket(socket);
- rc = IPX_Open_Socket(socket);
- }
- /*..................................................................
- Still can't open: return error
- ..................................................................*/
- if (rc) {
- return(0);
- }
- }
- SocketOpen = 1;
- return(1);
- #endif //WINSOCK_IPX
- } /* end of Open_Socket */
- /***************************************************************************
- * IPXConnClass::Close_Socket -- closes the socket *
- * *
- * INPUT: *
- * socket desired socket ID number *
- * *
- * OUTPUT: *
- * none. *
- * *
- * WARNINGS: *
- * Calling this routine when the sockets aren't open may crash! *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- void IPXConnClass::Close_Socket(unsigned short socket)
- {
- #ifdef WINSOCK_IPX
- socket = socket;
- PacketTransport->Close_Socket();
- SocketOpen = 0;
- #else //WINSOCK_IPX
- if (Winsock.Get_Connected()) {
- SocketOpen = 0;
- return;
- }
- /*------------------------------------------------------------------------
- Never, ever, ever, under any circumstances whatsoever, close a socket
- that isn't open. You'll regret it forever (or until at least until
- you're through rebooting, which, if you're on a Pentium is the same
- thing).
- ------------------------------------------------------------------------*/
- if (SocketOpen==1) {
- IPX_Close_Socket(socket);
- }
- SocketOpen = 0;
- #endif //WINSOCK_IPX
- } /* end of Close_Socket */
- /***************************************************************************
- * IPXConnClass::Send_To -- sends the packet to the given address *
- * *
- * The "ImmediateAddress" field of the SendECB must be filled in with the *
- * address of a bridge, or the node address of the destination if there *
- * is no bridge. The NETX call to find this address will always crash *
- * if NETX isn't loaded (ConnectionNum is 0), so this case is trapped & *
- * prevented. *
- * Also, if the address of this IPX connection is known when the *
- * constructor is called, and Configure has been called, Get_Local_Target *
- * is called to precompute the ImmediateAddress; this case is detected & *
- * if the value is already computed, it's just memcpy'd over. *
- * *
- * INPUT: *
- * buf buffer to send *
- * buflen length of buffer *
- * address Address to send to *
- * immed ImmediateAddress value, NULL if none *
- * *
- * OUTPUT: *
- * 1 = OK, 0 = error *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- int IPXConnClass::Send_To(char *buf, int buflen, IPXAddressClass *address,
- NetNodeType immed)
- {
- #ifdef WINSOCK_IPX
- immed = immed;
- assert ( immed == NULL );
- PacketTransport->WriteTo ( (void*)buf, buflen, (void*) address );
- return (true);
- #else //WINSOCK_IPX
- NetNumType net;
- NetNodeType node;
- int rc;
- #ifdef WIN32
- unsigned char send_address[6];
- if (Winsock.Get_Connected()) {
- Winsock.Write((void*)buf, buflen);
- return (true);
- }
- if (immed) {
- memcpy(send_address, immed, 6);
- #ifdef FIXIT_DESTNET
- // fixes DESTNET
- address->Get_Address(net,node);
- #else
- // breaks DESTNET
- memcpy(node, immed, 6);
- memset (net, 0, sizeof(net) );
- #endif
- } else {
- address->Get_Address(net,node);
- /*.....................................................................
- If the user is logged in & has a valid Novell Connection Number, get the
- bridge address the "official" way
- .....................................................................*/
- if (ConnectionNum != 0) {
- rc = IPX_Get_Local_Target (net, node, Socket, &send_address[0]);
- if (rc!=0) {
- return(false);
- }
- } else {
- /*.....................................................................
- Otherwise, use the destination node address as the ImmediateAddress, and
- just hope there's no network bridge in the path.
- .....................................................................*/
- memcpy(send_address,node,6);
- }
- }
- return (IPX_Send_Packet95(&send_address[0], (unsigned char*)buf, buflen, (unsigned char*)net, (unsigned char*)node));
- #else //WIN32
- void *hdr_ptr;
- void *buf_ptr;
- unsigned long hdr_val;
- unsigned long buf_val;
- /*------------------------------------------------------------------------
- Clear the ECB & header
- ------------------------------------------------------------------------*/
- memset(SendECB, 0, sizeof(ECBType));
- memset(SendHeader, 0, sizeof(IPXHeaderType));
- /*------------------------------------------------------------------------
- Copy the message into the SendBuf
- ------------------------------------------------------------------------*/
- memcpy (SendBuf,buf,buflen);
- /*------------------------------------------------------------------------
- Convert protected-mode ptrs to real-mode ptrs
- ------------------------------------------------------------------------*/
- hdr_val = (unsigned long)SendHeader;
- hdr_ptr = (void *)(((hdr_val & 0xffff0) << 12) | (hdr_val & 0x000f));
- buf_val = (unsigned long)SendBuf;
- buf_ptr = (void *)(((buf_val & 0xffff0) << 12) | (buf_val & 0x000f));
- /*------------------------------------------------------------------------
- Fill in ECB
- ------------------------------------------------------------------------*/
- SendECB->SocketNumber = Socket; // my output socket
- SendECB->PacketCount = 2; // 2 data areas
- SendECB->Packet[0].Address = hdr_ptr;
- SendECB->Packet[0].Length = sizeof(IPXHeaderType);
- SendECB->Packet[1].Address = buf_ptr;
- SendECB->Packet[1].Length = (unsigned short)buflen;
- /*------------------------------------------------------------------------
- Get the bridge address
- ------------------------------------------------------------------------*/
- if (immed) {
- memcpy(SendECB->ImmediateAddress, immed, 6);
- }
- else {
- address->Get_Address(net,node);
- /*.....................................................................
- If the user is logged in & has a valid Novell Connection Number, get
- the bridge address the "official" way
- .....................................................................*/
- if (ConnectionNum != 0) {
- rc = IPX_Get_Local_Target (net, node, Socket,
- SendECB->ImmediateAddress);
- if (rc!=0) {
- return(0);
- }
- }
- /*.....................................................................
- Otherwise, use the destination node address as the ImmediateAddress,
- and just hope there's no network bridge in the path.
- .....................................................................*/
- else {
- memcpy(SendECB->ImmediateAddress,node,6);
- }
- }
- /*------------------------------------------------------------------------
- Fill in outgoing header
- ------------------------------------------------------------------------*/
- SendHeader->PacketType = 4; // 4 = IPX packet
- address->Get_Address(SendHeader); // fill in header addresses
- SendHeader->DestNetworkSocket = Socket; // destination socket id
- /*------------------------------------------------------------------------
- Send the packet
- ------------------------------------------------------------------------*/
- IPX_Send_Packet(SendECB);
- /*------------------------------------------------------------------------
- Wait for send to complete
- ------------------------------------------------------------------------*/
- while (SendECB->InUse)
- Let_IPX_Breath();
- if (SendECB->CompletionCode!=0) {
- return(0);
- }
- else {
- return(1);
- }
- #endif //WIN32
- #endif //WINSOCK_IPX
- } /* end of Send_To */
- /***************************************************************************
- * IPXConnClass::Broadcast -- broadcasts the given packet *
- * *
- * INPUT: *
- * socket desired socket ID number *
- * *
- * OUTPUT: *
- * 1 = OK, 0 = error *
- * *
- * WARNINGS: *
- * none. *
- * *
- * HISTORY: *
- * 12/16/1994 BR : Created. *
- *=========================================================================*/
- int IPXConnClass::Broadcast(char *buf, int buflen)
- {
- #ifdef WINSOCK_IPX
- PacketTransport->Broadcast (buf, buflen);
- return (true);
- #else //WINSOCK_IPX
- #ifdef WIN32
- if (Winsock.Get_Connected()) {
- Winsock.Write((void*)buf, buflen);
- return(true);
- } else {
- return (IPX_Broadcast_Packet95((unsigned char*)buf, buflen));
- }
- #else //WIN32
- void *hdr_ptr;
- void *buf_ptr;
- unsigned long hdr_val;
- unsigned long buf_val;
- /*------------------------------------------------------------------------
- Clear the ECB & header
- ------------------------------------------------------------------------*/
- memset(SendECB, 0, sizeof(ECBType));
- memset(SendHeader, 0, sizeof(IPXHeaderType));
- /*------------------------------------------------------------------------
- Copy the message into the SendBuf
- ------------------------------------------------------------------------*/
- memcpy (SendBuf,buf,buflen);
- /*------------------------------------------------------------------------
- Convert protected-mode ptrs to real-mode ptrs
- ------------------------------------------------------------------------*/
- hdr_val = (unsigned long)SendHeader;
- hdr_ptr = (void *)(((hdr_val & 0xffff0) << 12) | (hdr_val & 0x000f));
- buf_val = (unsigned long)SendBuf;
- buf_ptr = (void *)(((buf_val & 0xffff0) << 12) | (buf_val & 0x000f));
- /*------------------------------------------------------------------------
- Fill in ECB
- ------------------------------------------------------------------------*/
- SendECB->SocketNumber = Socket; // my output socket
- SendECB->PacketCount = 2; // 2 data areas
- SendECB->Packet[0].Address = hdr_ptr;
- SendECB->Packet[0].Length = sizeof(IPXHeaderType);
- SendECB->Packet[1].Address = buf_ptr;
- SendECB->Packet[1].Length = (unsigned short)buflen;
- SendECB->ImmediateAddress[0] = 0xff;
- SendECB->ImmediateAddress[1] = 0xff;
- SendECB->ImmediateAddress[2] = 0xff;
- SendECB->ImmediateAddress[3] = 0xff;
- SendECB->ImmediateAddress[4] = 0xff;
- SendECB->ImmediateAddress[5] = 0xff;
- /*------------------------------------------------------------------------
- Fill in outgoing header
- ------------------------------------------------------------------------*/
- SendHeader->PacketType = 4; // 4 = IPX packet
- SendHeader->DestNetworkNumber[0] = 0xff; // 0xff = broadcast
- SendHeader->DestNetworkNumber[1] = 0xff;
- SendHeader->DestNetworkNumber[2] = 0xff;
- SendHeader->DestNetworkNumber[3] = 0xff;
- SendHeader->DestNetworkNode[0] = 0xff; // 0xff = broadcast
- SendHeader->DestNetworkNode[1] = 0xff;
- SendHeader->DestNetworkNode[2] = 0xff;
- SendHeader->DestNetworkNode[3] = 0xff;
- SendHeader->DestNetworkNode[4] = 0xff;
- SendHeader->DestNetworkNode[5] = 0xff;
- SendHeader->DestNetworkSocket = Socket; // destination socket #
- /*------------------------------------------------------------------------
- Send the packet
- ------------------------------------------------------------------------*/
- IPX_Send_Packet(SendECB);
- /*------------------------------------------------------------------------
- Wait for send to complete
- ------------------------------------------------------------------------*/
- while (SendECB->InUse) {
- Let_IPX_Breath();
- }
- if (SendECB->CompletionCode!=0) {
- return(0);
- }
- else {
- return(1);
- }
- #endif //WIN32
- #endif //WINSOCK_IPX
- } /* end of Broadcast */
- /************************** end of ipxconn.cpp *****************************/
|