windows-nt/Source/XPSP1/NT/net/wins/server/rpl/rplmsgf.c

1414 lines
36 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/****
TODO
Change name of this module to one that indicates the module to be
platform dependent
****/
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
rplmsgf.c
Abstract:
This module contains functions to format and unformat messages
sent between the replicators on different WINS servers
Functions:
RplMsgfFrmAddVersMapReq--format send ip address - max version #
records request
RplMsgfFrmAddVersMapRsp--format response to send ip address - max
version # request sent earlier
RplMsgfFrmSndEntriesReq--format send data records request
RplMsgfFrmSndEntriesRsp--format response to "send data records"
request
RplMsgfUfmAddVersMapRsp--unformat "send address - max version #"
response
RplMsgfUfmSndEntriesReq--unformat "send data records" request
RplMsgfUfmSndEntriesRsp--unformat "send data records" response
....
Portability:
This module is non-portable across different address families (different
transports) since it relies on the address being an IP address.
Author:
Pradeep Bahl (PradeepB) Jan-1993
Revision History:
Modification date Person Description of modification
----------------- ------- ----------------------------
--*/
/*
* Includes
*/
#include "wins.h"
#ifdef DBGSVC
#include "nms.h"
#endif
#include "comm.h"
#include "nmsdb.h"
#include "rpl.h"
#include "rplmsgf.h"
#include "winsevt.h"
#include "winsmsc.h"
/*
* Local Macro Declarations
*/
/*
ENTRY_DELIM -- Delimiter between data records (name-address mapping records)
in the message. The end of the message is marked by two of
these.
Since a data record starts with the length of the name
(which will never by FFFFFFFF), this delimiter serves us
fine.
*/
#define ENTRY_DELIM 0xFFFFFFFF //-1
/*
* Local Typedef Declarations
*/
/*
* Global Variable Definitions
*/
/*
* Local Variable Definitions
*/
/*
* Local Function Prototype Declarations
*/
/* prototypes for functions local to this module go here */
FUTURES("Change to a macro")
PERF("Change to a macro")
VOID
RplMsgfFrmAddVersMapReq(
IN LPBYTE pBuff,
OUT LPDWORD pMsgLen
)
/*++
Routine Description:
This function formats the message to request a remote WINS server's
replicator to send the IP address - Max Version # mappings
Arguments:
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
GetVersNo() in rplpull.c
Side Effects:
Comments:
None
--*/
{
RPLMSGF_SET_OPC_M(pBuff, RPLMSGF_E_ADDVERSNO_MAP_REQ);
*pMsgLen = 4;
return;
}
VOID
RplMsgfFrmAddVersMapRsp(
#if SUPPORT612WINS > 0
IN BOOL fPnrIsBeta1Wins,
#endif
IN RPLMSGF_MSG_OPCODE_E Opcode_e,
IN LPBYTE pBuff,
IN DWORD BuffLen,
IN PRPL_ADD_VERS_NO_T pOwnerAddVersNoMap,
IN DWORD MaxNoOfOwners,
IN DWORD InitiatorWinsIpAdd,
OUT LPDWORD pMsgLen
)
/*++
Routine Description:
This function formats the following two messages
1)Response to the "send me IP address - version # map " request"
2)Push Notification message.
Both messages are identical except for the opcode
Arguments:
Opcode_e - Opcode indicating the message to send
pBuff - Buffer to populate
BuffLen - Buffer length
pOwnerAddVersNoMap - Array of address to version numbers mappings.
The version number is the max version number
for the owner RQ server
MaxNoOfOwners - Max. No Of Owners in this WINS's db
InitiatorWinsIpAdd - Address of WINS that initiated the push.
pMsgLen - Actual length of buffer filled in
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
Push Handler (Push Thread)
Side Effects:
Comments:
None
--*/
{
LPLONG pTmpL = (LPLONG)pBuff;
LPBYTE pTmpB = pBuff;
DWORD i; //counter for looping over all records
VERS_NO_T StartVersNo;
WINS_UID_T Uid;
//
// Backward compatibility with pre-3.51 beta copies of WINS.
//
StartVersNo.QuadPart = 0;
Uid = 1;
RPLMSGF_SET_OPC_M(pTmpB, Opcode_e);
pTmpL = (LPLONG)pTmpB;
/*
* Store number of records in the buffer
*/
COMM_HOST_TO_NET_L_M( MaxNoOfOwners, *pTmpL );
pTmpL += 1;
//
// To guard us (PUSH thread) against simultaneous updates to the
// NmsDbOwnAddTbl array (by the PULL thread). This array is
// accessed by RPL_FIND_ADD_BY_OWNER_ID_M macro
//
/*
* Now, let us store all the records
*/
for (i = 0; i < MaxNoOfOwners; i++)
{
/*
* We will send the V part of the address since the other
* end knows the T and L (more like XDR encoding where T is
* not sent)
*/
NONPORT("Do not rely on the address being a long here")
/*
* As an optmization here, we make use of the fact that
* the address is an IP address and is therefore a long.
* When we start working with more than one address family or
* when the size of the IP address changes, we should change
* the code here. For now, there is no harm in optimizing
* it
*/
COMM_HOST_TO_NET_L_M(
(pOwnerAddVersNoMap + i)->OwnerWinsAdd.Add.IPAdd, *pTmpL
);
pTmpL++; //advance to next 4 bytes
/*
* Store the version number
*/
WINS_PUT_VERS_NO_IN_STREAM_M(
&((pOwnerAddVersNoMap + i)->VersNo),
pTmpL
);
pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //adv. the
//pointer
#if SUPPORT612WINS > 0
if (fPnrIsBeta1Wins == FALSE)
{
#endif
/*
* Store the Start version number
*/
WINS_PUT_VERS_NO_IN_STREAM_M( &StartVersNo, pTmpL );
pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //adv. the
//pointer
COMM_HOST_TO_NET_L_M( Uid, *pTmpL );
pTmpL++;
#if SUPPORT612WINS > 0
}
#endif
}
COMM_HOST_TO_NET_L_M( InitiatorWinsIpAdd, *pTmpL );
pTmpL++;
//
// Let us tell our client the exact length of the response message
//
*pMsgLen = (ULONG) ( (LPBYTE)pTmpL - (LPBYTE)pBuff );
return;
} // RplMsgfFormatAddVersMapRsp()
VOID
RplMsgfFrmSndEntriesReq(
#if SUPPORT612WINS > 0
IN BOOL fPnrIsBeta1Wins,
#endif
IN LPBYTE pBuff,
IN PCOMM_ADD_T pWinsAdd,
IN VERS_NO_T MaxVersNo,
IN VERS_NO_T MinVersNo,
IN DWORD RplType, //for now
OUT LPDWORD pMsgLen
)
/*++
Routine Description:
This function is called to format a "send data entries" request for
getting records belonging to a particular WINS server.
Arguments:
pBuff - Buffer that will store the request message
pWinsAdd - Address of the RQ server whose data records are being
sought
MaxVersNo - Max. Version Number in the range of records sought
MinVersNo - Min. Version Number in the range of records sought.
pMsgLen - Length of request message
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
PullEntries() in rplpull.c
Side Effects:
Comments:
I might update this function to format a request for getting
data records of more than one WINS server.
For the sake of simplicity, I have chosen not to do so currently.
--*/
{
LPBYTE pTmpB = pBuff;
LPLONG pTmpL;
RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_SNDENTRIES_REQ);
pTmpL = (LPLONG)pTmpB;
/*
* We will send the V part of the address since the other
* end knows the T and L (more like XDR encoding where T is
* not sent)
*/
NONPORT("Do not rely on the address being a long here")
/*
* As an optmization here, we make use of the fact that
* the address is an IP address and is therefore a long.
* When we start working with more than one address family or
* when the size of the IP address changes, we should change
* the code here. For now, there is no harm in optimizing
* it
*/
COMM_HOST_TO_NET_L_M(pWinsAdd->Add.IPAdd, *pTmpL);
pTmpL++; //advance to next 4 bytes
/*
* Store the max version number
*/
WINS_PUT_VERS_NO_IN_STREAM_M(&MaxVersNo, pTmpL);
pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //advance the
//pointer
/*
* Store the min version number
*/
WINS_PUT_VERS_NO_IN_STREAM_M(&MinVersNo, pTmpL);
pTmpL = (LPLONG)((LPBYTE)(pTmpL) + WINS_VERS_NO_SIZE); //advance the
//pointer
#if SUPPORT612WINS > 0
if (fPnrIsBeta1Wins == FALSE)
{
#endif
COMM_HOST_TO_NET_L_M(RplType, *pTmpL);
pTmpL++;
#if SUPPORT612WINS > 0
}
#endif
//
// Let us tell the caller the exact length of the request message
//
*pMsgLen = (ULONG) ((LPBYTE)pTmpL - pBuff );
return;
}
VOID
RplMsgfFrmSndEntriesRsp (
#if SUPPORT612WINS > 0
IN BOOL fPnrIsBeta1Wins,
#endif
IN LPBYTE pBuff,
IN DWORD NoOfRecs,
IN LPBYTE pName,
IN DWORD NameLen,
IN BOOL fGrp,
IN DWORD NoOfAdds,
IN PCOMM_ADD_T pNodeAdd,
IN DWORD Flag,
IN VERS_NO_T VersNo,
IN BOOL fFirstTime,
OUT LPBYTE *ppNewPos
)
/*++
Routine Description:
This function is used to format a "send entries" response. The
function is called once for each data entry record that needs to be
sent.
The first time, it is called (fFirstTime = TRUE), it puts the
opcode and the first directory entry in the buffer. On subsequent
calls the data entries passed are tacked on at the end of the
buffer
Arguments:
ppBuff - ptr to address of location to start storing the info from.
NoOfRecs - No of records that are being sent.
pName - Name of unique entry or group
NameLen - Length of name
fGrp - Indicates whether the name is a unique name or a group name
NoOfAdds - No of addresses (useful if entry is a group entry)
pNodeAdd - Ptr to address of node (if unique entry) or to list of
addresses if (entry group)
Flag - The flag word of the entry
VersNo - The version number of the entry
fFirstTime - Indicates whether this is the first call in a sequence of
calls to this function for formatting a send data entries
response
ppNewPos - contains the starting position for the next record
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
Side Effects:
Comments:
NOTE NOTE NOTE
The set of calls to this function result in a message
containing records pertaining to one owner. This is the owner
whose records were requested by the PULL partner
--*/
{
LPLONG pTmpL = (LPLONG)pBuff;
LPBYTE pTmpB = pBuff;
DWORD i; /*counter for looping over all records*/
if (fFirstTime)
{
//
// In the first invocation, we need to offset the
// pointer by the header size used by COMM code for
// its header
//
// Due to the above, this formatting function is slightly
// inconsistent with the other formatting functions that
// don't do any offsetting. Subsequent invocations do
// not require any offseting.
//
RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_SNDENTRIES_RSP);
pTmpL++; //advance to next 4 bytes
COMM_HOST_TO_NET_L_M(NoOfRecs, *pTmpL);
pTmpL++; //advance to next 4 bytes
pTmpB = (LPBYTE)pTmpL;
}
/*
* Store the length of the name
*/
COMM_HOST_TO_NET_L_M(NameLen, *pTmpL);
pTmpB += sizeof(LONG);
/*
*Store the name.
*/
WINSMSC_COPY_MEMORY_M(pTmpB, pName, NameLen);
/*
* Adjust the pointer
*/
pTmpB += NameLen;
/*
* let us align the next field at a long boundary
*/
pTmpB += sizeof(LONG) - ((ULONG_PTR) pTmpB % sizeof(LONG));
/*
* Store the Flags field
*/
#if SUPPORT612WINS > 0
if (fPnrIsBeta1Wins == FALSE)
{
#endif
pTmpL = (LPLONG)pTmpB;
COMM_HOST_TO_NET_L_M(Flag, *pTmpL);
pTmpB += sizeof(LONG);
#if SUPPORT612WINS > 0
}
else
{
*pTmpB++ = (BYTE)Flag;
}
#endif
/*
* Store the group flag
*/
*pTmpB++ = (UCHAR)fGrp;
//align it on a long boundary
pTmpB += sizeof(LONG) - ((ULONG_PTR)pTmpB % sizeof(LONG));
pTmpL = (LPLONG)pTmpB;
/*
* Store the Version Number
*/
WINS_PUT_VERS_NO_IN_STREAM_M(&VersNo, pTmpL);
pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
if (NMSDB_ENTRY_TYPE_M(Flag) == NMSDB_UNIQUE_ENTRY)
{
/*
* We will send the V part of the address since the other
* and knows the T and L (more like XDR encoding where T is
* not sent)
*/
NONPORT("Do not rely on the address being a long here")
/*
* As an optmization here, we make use of the fact that
* the address is an IP address and is therefore a long.
* When we start working with more than one address family or
* when the size of the IP address changes, we should change
* the code here. For now, there is no harm in optimizing
* it
*/
COMM_HOST_TO_NET_L_M(pNodeAdd->Add.IPAdd, *pTmpL);
pTmpL++;
}
else //it is a group or a multihomed entry
{
if (NMSDB_ENTRY_TYPE_M(Flag) != NMSDB_NORM_GRP_ENTRY)
{
//
// we were passed a ptr to the address of the
// first member in a ptr instead of a pptr.
//
PCOMM_ADD_T *ppNodeAdd = (PCOMM_ADD_T *)pNodeAdd;
//
// let us threfore initialize pNodeAdd to the address
// of the first member
//
pNodeAdd = *ppNodeAdd;
/*
* It is a special group or a multihomed entry.
* store the number of addresses first
*/
pTmpB = (LPBYTE)pTmpL;
FUTURES("If we start storing > 255 members in a group, then change the")
FUTURES("following (i.e. use COMM_HOST_TO_NET_L_M)")
*pTmpB++ = (BYTE)NoOfAdds;
pTmpB += sizeof(LONG) - 1;
DBGPRINT2(DET, "RplMsgfFrmSndEntriesRsp: NoOfAdds=(%d) in %s\n", NoOfAdds, NMSDB_ENTRY_TYPE_M(Flag) == NMSDB_SPEC_GRP_ENTRY ?
"SPECIAL GROUP" : "MULTIHOMED");
pTmpL = (LPLONG)pTmpB;
/*
* Store all the addresses
* Note: The No of addresses is an even number
* because we
* are passing two addresses for each member in the
* list (that is what this function gets). The first
* address of the pair is the address of the member;
* the second address of the pair is the address
* of the WINS server that registered or refreshed the
* member)
*/
for (i = 0; i < NoOfAdds ; i++)
{
COMM_HOST_TO_NET_L_M(
pNodeAdd->Add.IPAdd,
*pTmpL
);
pNodeAdd++; //increment to point to
//address of member
pTmpL++;
COMM_HOST_TO_NET_L_M(
pNodeAdd->Add.IPAdd,
*pTmpL
);
pNodeAdd++; //increment to point to
//address of owner
pTmpL++;
}
}
else // it is a normal group
{
COMM_HOST_TO_NET_L_M(pNodeAdd->Add.IPAdd, *pTmpL);
pTmpL++;
}
}
/*
* Store the end delimiter (2 row delimiters in sequence).
*/
*pTmpL++ = ENTRY_DELIM;
*pTmpL = ENTRY_DELIM;
/*
* Init ppBuff to point to last delimiter, so that next entry if
* there starts from that location. If there is no other entry,
* then two delimiters will be there to mark the end of the message
*/
*ppNewPos = (LPBYTE)pTmpL;
return;
}
VOID
RplMsgfUfmAddVersMapRsp(
#if SUPPORT612WINS > 0
IN BOOL fIsPnrBeta1Wins,
#endif
IN LPBYTE pBuff,
OUT LPDWORD pNoOfMaps,
OUT LPDWORD pInitiatorWinsIpAdd,
IN OUT PRPL_ADD_VERS_NO_T *ppAddVers
)
/*++
Routine Description:
This function unformats the request to the
"give me address - version #" message
Arguments:
pBuff - Buffer that contains the response message
pNoOfMaps - No of Address - Version # entries
pAddVers - array of structures storing add-version # mappings
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
GetVersNo() in rplpull.c
Side Effects:
Comments:
pBuff should be pointing to the location just past the opcode
(i.e. 4 bytes from the start of the opcode in the message received
--*/
{
DWORD i = 0;
PRPL_ADD_VERS_NO_T pAddVers;
VERS_NO_T StartVersNo;
WINS_UID_T Uid;
//
// Get the No of Mappings
//
COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff), *pNoOfMaps);
ASSERT(*pNoOfMaps > 0);
pBuff += sizeof(LONG);
if (*pNoOfMaps > 0)
{
WinsMscAlloc(*pNoOfMaps * sizeof(RPL_ADD_VERS_NO_T), ppAddVers);
pAddVers = *ppAddVers;
//
// get all the mappings
//
for(i=0; i < *pNoOfMaps ; i++, pAddVers++)
{
COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff),
pAddVers->OwnerWinsAdd.Add.IPAdd);
pAddVers->OwnerWinsAdd.AddTyp_e = COMM_ADD_E_TCPUDPIP;
pAddVers->OwnerWinsAdd.AddLen = sizeof(COMM_IP_ADD_T);
pBuff += sizeof(LONG);
WINS_GET_VERS_NO_FR_STREAM_M(pBuff, &pAddVers->VersNo);
pBuff += WINS_VERS_NO_SIZE;
#if SUPPORT612WINS > 0
if (fIsPnrBeta1Wins == FALSE)
{
#endif
WINS_GET_VERS_NO_FR_STREAM_M(pBuff, &StartVersNo);
pBuff += WINS_VERS_NO_SIZE;
COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff), Uid);
pBuff += sizeof(LONG);
#if SUPPORT612WINS > 0
}
#endif
}
#if SUPPORT612WINS > 0
if (fIsPnrBeta1Wins == FALSE)
{
#endif
if (pInitiatorWinsIpAdd != NULL)
{
COMM_NET_TO_HOST_L_M(*((LPLONG)pBuff), *pInitiatorWinsIpAdd);
}
#if SUPPORT612WINS > 0
}
#endif
} // if (NoOfMaps > 0)
return;
}
VOID
RplMsgfUfmSndEntriesReq(
#if SUPPORT612WINS > 0
IN BOOL fPnrIsBeta1Wins,
#endif
IN LPBYTE pBuff,
OUT PCOMM_ADD_T pWinsAdd,
OUT PVERS_NO_T pMaxVersNo,
OUT PVERS_NO_T pMinVersNo,
OUT LPDWORD pRplType
)
/*++
Routine Description:
This function unformats the "send entries request"
Arguments:
pBuff - buffer that holds the request
pWinsAdd - memory that will hold the address of the
WINS whose records are being requested
pMaxVersNo - Max. Vers. No requested
pMinVersNo - Min. Vers. No requested
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
HandleAddVersMapReq in rplpush.c
Side Effects:
Comments:
pBuff should be pointing to the location just past the opcode
(i.e. 4 bytes from the start of the opcode in the message received)
--*/
{
LPLONG pTmpL = (LPLONG)pBuff;
NONPORT("Port when we start supporting different address families")
pWinsAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
COMM_NET_TO_HOST_L_M(*pTmpL, pWinsAdd->Add.IPAdd);
pTmpL++;
WINS_GET_VERS_NO_FR_STREAM_M(pTmpL, pMaxVersNo);
pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
WINS_GET_VERS_NO_FR_STREAM_M(pTmpL, pMinVersNo);
#if SUPPORT612WINS > 0
if (fPnrIsBeta1Wins == FALSE)
{
#endif
if (pRplType != NULL)
{
pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
//COMM_NET_TO_HOST_L_M(*pTmpL, *pRplType);
*pRplType = WINSCNF_RPL_DEFAULT_TYPE;
}
#if SUPPORT612WINS > 0
}
else
{
*pRplType = WINSCNF_RPL_DEFAULT_TYPE;
}
#endif
return;
}
//__inline
VOID
RplMsgfUfmSndEntriesRsp(
#if SUPPORT612WINS > 0
IN BOOL fPnrIsBeta1Wins,
#endif
IN OUT LPBYTE *ppBuff,
OUT LPDWORD pNoOfRecs,
OUT IN LPBYTE pName,
OUT LPDWORD pNameLen,
OUT LPBOOL pfGrp,
OUT LPDWORD pNoOfAdds,
OUT PCOMM_ADD_T pNodeAdd,
OUT LPDWORD pFlag,
OUT PVERS_NO_T pVersNo,
IN BOOL fFirstTime
)
/*++
Routine Description:
This function unformats the "send entries response"
When it is called the first time (fFirstTime = TRUE), it
returns the value for the NoOfRecs OUTARG and the first
record. The value of ppBuff is adjusted to point to just past
the row delimiter.
When called the second or subsequent times, the function returns with
the next entry in the list, until all entries have been exhausted.
The function finds out that it is at the end of the list when
it encounters at ENTRY_DELIM in the first 'sizeof(LONG)' bytes in
the buffer.
When a group entry is returned, pNodeAdd is made to point to the
start location in *ppBuff where the list of members are stored.
The caller will have to use the COMM_NET_TO_HOST_L_M macro to
convert each address to its host form.
The above requires the caller to know the transport that is used
(by the fact that it is extracting the IP address). For the sake
of overall optimization, this is considered ok (If we didn't do this,
this function would have to allocate a buffer to store all the
addresses for a group and return that)
Arguments:
pNodeAdd -- This should point to an array of COMM_ADD_T structures.
Since we have a maximum of 25 group members,
the caller can use an auto array.
Externals Used:
None
Return Value:
NONE
Error Handling:
Called by:
Side Effects:
Comments:
ppBuff should be pointing to the location just past the opcode
(i.e. 4 bytes from the start of the opcode in the message received)
when the function is called the first time. For subsequent calls,
it would be at a row delimiter (ENTRY_DELIM)
--*/
{
LPLONG pTmpL = (LPLONG)*ppBuff;
LPBYTE pTmpB;
if (fFirstTime)
{
COMM_NET_TO_HOST_L_M(*pTmpL, *pNoOfRecs);
if (*pNoOfRecs == 0)
{
return;
}
pTmpL++;
}
else
{
//
// If we are pointing to a delimiter, then we have
// reached the end of the list of data records.
//
if (*pTmpL == ENTRY_DELIM)
{
DBGPRINT0(ERR, "RplMsgfUnfSndEntriesRsp:Weird. The function should not have been called\n");
/*
we have reached the end of the array, return
success.
Note: the caller should not have called us,
since we gave him the No of Recs value before (
the first time he called)
*/
WINSEVT_LOG_M(
WINS_FAILURE,
WINS_EVT_SFT_ERR,
);
return;
}
}
pTmpB = (LPBYTE)pTmpL;
/*
* Store the length of the name.
*/
COMM_NET_TO_HOST_L_M(*pTmpL, *pNameLen);
if(*pNameLen > 255) {
*pNoOfRecs = 0;
return;
}
pTmpB += sizeof(LONG);
/*
* Store the name.
*/
WINSMSC_COPY_MEMORY_M(pName, pTmpB, *pNameLen);
/*
* Adjust the pointer
*/
pTmpB += *pNameLen;
/*
* The next field is at a long boundary. So, let us adjust pTmpB
*/
pTmpB += sizeof(LONG) - ((ULONG_PTR)pTmpB % sizeof(LONG));
/*
* Store the Flags field
*/
#if SUPPORT612WINS > 0
if (fPnrIsBeta1Wins == FALSE)
{
#endif
pTmpL = (LPLONG)pTmpB;
COMM_NET_TO_HOST_L_M(*pTmpL, *pFlag);
pTmpB += sizeof(LONG);
#if SUPPORT612WINS > 0
}
else
{
*pFlag = (DWORD)*pTmpB++;
}
#endif
/*
* Store the group field
*/
*pfGrp = *pTmpB++;
//align it at a long boundary
pTmpB += sizeof(LONG) - ((ULONG_PTR)pTmpB % sizeof(LONG));
pTmpL = (LPLONG)pTmpB;
/*
* Store the Version Number
*/
WINS_GET_VERS_NO_FR_STREAM_M(pTmpL, pVersNo);
pTmpL = (LPLONG)((LPBYTE)pTmpL + WINS_VERS_NO_SIZE);
if (NMSDB_ENTRY_TYPE_M(*pFlag) == NMSDB_UNIQUE_ENTRY)
{
NONPORT("Do not rely on the address being a long here")
/*
As an optmization here, we make use of the fact that
the address is an IP address and is therefore a long.
When we start working with more than one address family or
when the size of the IP address changes, we should change
the code here. For now, there is no harm in optimizing
code here
*/
pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
pTmpL++;
}
else //it is either a group entry or a multihomed entry
{
DWORD i;
if(NMSDB_ENTRY_TYPE_M(*pFlag) != NMSDB_NORM_GRP_ENTRY)
{
/*
* store the number of addresses first
*/
pTmpB = (LPBYTE)pTmpL;
FUTURES("If we start storing > 255 members in a group, then change the")
FUTURES("following (i.e. use COMM_HOST_TO_NET_L_M)")
*pNoOfAdds = *pTmpB++;
pTmpB += sizeof(LONG) - 1;
DBGPRINT2(FLOW, "RplMsgfUfrmSndEntriesRsp: NoOfAdds=(%d) in %s record \n", *pNoOfAdds, NMSDB_ENTRY_TYPE_M(*pFlag) == NMSDB_SPEC_GRP_ENTRY ? "SPECIAL GROUP": "MULTIHOMED");
pTmpL = (LPLONG)pTmpB;
/*
Init the pointer to the list of addresses
Note: The No of addresses is an even number because we
are passing two addresses for each member in the
list (that is what this function returns). The first
address of the pair is the address of the member;
the second address of the pair is the address
of the WINS server that registered or refreshed the
member)
*/
for (i = 0; i < *pNoOfAdds ; i++)
{
NONPORT("this will have to be changed when we move to other address families")
//
// Get address of owner
//
pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
pNodeAdd++;
pTmpL++;
//
// Get address of member
//
pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
pNodeAdd++;
pTmpL++;
}
}
else //it is a normal group
{
pNodeAdd->AddTyp_e = COMM_ADD_E_TCPUDPIP;
COMM_NET_TO_HOST_L_M(*pTmpL, pNodeAdd->Add.IPAdd);
pNodeAdd->AddLen = sizeof(COMM_IP_ADD_T);
pTmpL++;
}
}
/*
* Make the ptr point to the location after the ENTRY_DELIM
*/
pTmpL++ ;
/*
* Init ppBuff to point to last delimiter, so that next entry if
* there starts from that location. If there is no other entry,
* then two delimiters will be there to mark the end of the message
*/
*ppBuff = (LPBYTE)pTmpL;
return;
}
VOID
RplMsgfUfmPullPnrReq(
LPBYTE pMsg,
DWORD MsgLen,
PRPLMSGF_MSG_OPCODE_E pPullReqType_e
)
/*++
Routine Description:
This function unformats a message received from a WINS
that is a pull partner
Arguments:
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
Push Thread
Side Effects:
Comments:
Change this function to a macro
--*/
{
UNREFERENCED_PARAMETER(MsgLen);
//
// First three bytes should be 0s.
//
PERF("since we never use up more than 1 byte for the opcode, we can get")
PERF("rid of the first 3 assignements down below and retrieve the opcode")
PERF("directly from the 4th byte. Make corresponding change in the formatting")
PERF("functions too")
*pPullReqType_e |= *pMsg++ << 24;
*pPullReqType_e |= *pMsg++ << 16;
*pPullReqType_e |= *pMsg++ << 8;
*pPullReqType_e = *pMsg ;
return;
}
VOID
RplMsgfFrmUpdVersNoReq(
IN LPBYTE pBuff,
IN LPBYTE pName,
IN DWORD NameLen,
OUT LPDWORD pMsgLen
)
/*++
Routine Description:
This function is called to format an "update version number" request
Arguments:
pBuff - Buffer that will hold the formatted request
pName - Name in the name-address mapping db that needs to have
its version no. updated
NameLen - Length of the name
pMsgLen - Length of the formatted message
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
InfRemWins() in nmschl.c
Side Effects:
Comments:
None
--*/
{
LPBYTE pTmpB = pBuff;
LPLONG pTmpL = (LPLONG)pBuff;
RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_UPDVERSNO_REQ);
pTmpL = (LPLONG)pTmpB;
/*
* Store the length of the name.
*/
COMM_HOST_TO_NET_L_M(NameLen, *pTmpL);
pTmpB += sizeof(LONG);
/*
* Store the name.
*/
WINSMSC_COPY_MEMORY_M(pTmpB, pName, NameLen);
/*
* Adjust the pointer
*/
pTmpB += NameLen;
//
// Find size of req buffer
//
*pMsgLen = (ULONG) (pTmpB - pBuff);
return;
}
VOID
RplMsgfUfmUpdVersNoReq(
IN LPBYTE pBuff,
OUT LPBYTE pName,
OUT LPDWORD pNameLen
)
/*++
Routine Description:
This function is called to unformat the "update version no" request
sent by a remote WINS
Arguments:
pBuff - Buffer holding the formatted request
pName - Name whose version no. is to be updated
pNameLen - Length of name
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
HandleUpdVersNoReq in rplpush.c
Side Effects:
Comments:
None
--*/
{
LPBYTE pTmpB = pBuff;
LPLONG pTmpL = (LPLONG)pBuff;
/*
* Store the length of the name.
*/
COMM_NET_TO_HOST_L_M(*pTmpL, *pNameLen);
pTmpB += sizeof(LONG);
/*
* Store the name.
*/
WINSMSC_COPY_MEMORY_M(pName, pTmpB, *pNameLen);
/*
* Adjust the pointer
*/
pTmpB += *pNameLen;
return;
}
VOID
RplMsgfFrmUpdVersNoRsp(
IN LPBYTE pRspBuff,
IN BYTE Rcode,
OUT LPDWORD pRspBuffLen
)
/*++
Routine Description:
This function is called to send the response to the "update version
# request"
Arguments:
pRspBuff - Buffer to hold the formatted response
Rcode - result of the operation
pRspBuffLen - Length of response
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
HandleUpdVersNoReq() in rplpush.c
Side Effects:
Comments:
None
--*/
{
LPBYTE pTmpB = pRspBuff;
RPLMSGF_SET_OPC_M(pTmpB, RPLMSGF_E_UPDVERSNO_RSP);
*pTmpB++ = Rcode;
*pRspBuffLen = (ULONG) (pTmpB - pRspBuff);
return;
}
FUTURES("change to a macro")
PERF("change to a macro")
VOID
RplMsgfUfmUpdVersNoRsp(
IN LPBYTE pRspBuff,
OUT LPBYTE pRcode
)
/*++
Routine Description:
This function is called to unformat the response to the
"update version number" request.
Arguments:
pRspBuff - Buffer holding the formatted response
pRcode - result of the update
Externals Used:
None
Return Value:
None
Error Handling:
Called by:
InfRemWins() in nmschl.c
Side Effects:
Comments:
Change to a macro
--*/
{
*pRcode = *pRspBuff;
return;
}