162 lines
3 KiB
C
162 lines
3 KiB
C
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
periodbc.c
|
|
|
|
Abstract:
|
|
|
|
Contains the work item handler periodic bcast
|
|
|
|
Author:
|
|
|
|
Stefan Solomon 07/20/1995
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
/*++
|
|
|
|
Function: IfPeriodicBcast
|
|
|
|
Descr: called to initiate or continue (complete) a bcast
|
|
if EnumHandle is NULL it is a start, else a continuation
|
|
|
|
Remark: called with the interface lock held
|
|
|
|
--*/
|
|
|
|
VOID
|
|
IfPeriodicBcast(PWORK_ITEM wip)
|
|
{
|
|
UCHAR ripsocket[2];
|
|
USHORT pktlen;
|
|
ULONG delay;
|
|
PICB icbp;
|
|
|
|
icbp = wip->icbp;
|
|
|
|
#define EnumHandle wip->WorkItemSpecific.WIS_EnumRoutes.RtmEnumerationHandle
|
|
|
|
if(icbp->IfStats.RipIfOperState != OPER_STATE_UP) {
|
|
|
|
if(EnumHandle) {
|
|
|
|
CloseEnumHandle(EnumHandle);
|
|
}
|
|
|
|
FreeWorkItem(wip);
|
|
|
|
return;
|
|
}
|
|
|
|
PUTUSHORT2SHORT(ripsocket, IPX_RIP_SOCKET);
|
|
|
|
// check if this is the start or the continuation of a periodic bcast
|
|
if(EnumHandle == NULL) {
|
|
|
|
// *** This is the start of a new broadcast ***
|
|
|
|
// create an RTM enumeration handle
|
|
if((EnumHandle = CreateBestRoutesEnumHandle()) == NULL) {
|
|
|
|
SS_ASSERT(FALSE);
|
|
FreeWorkItem(wip);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// *** This is the continuation of a started broadcast ***
|
|
|
|
// check if this was the last packet in the response
|
|
GETSHORT2USHORT(&pktlen, wip->Packet + IPXH_LENGTH);
|
|
|
|
if(pktlen < FULL_PACKET) {
|
|
|
|
// we are done
|
|
goto ResetPeriodicBcast;
|
|
}
|
|
|
|
// check the time stamp to determine if an interpacket gap is needed
|
|
delay = (wip->TimeStamp + 55) - GetTickCount();
|
|
if(delay < MAXULONG/2) {
|
|
|
|
// have to wait this delay
|
|
IfRefStartWiTimer(wip, delay);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// make the gen response packet
|
|
pktlen = MakeRipGenResponsePacket(wip,
|
|
bcastnode,
|
|
ripsocket);
|
|
if(pktlen == EMPTY_PACKET) {
|
|
|
|
// we are done
|
|
goto ResetPeriodicBcast;
|
|
}
|
|
|
|
// send the bcast and increment the ref counter
|
|
if(IfRefSendSubmit(wip) != NO_ERROR) {
|
|
|
|
// can't send on this interface now -> requeue in timer and retry
|
|
goto ResetPeriodicBcast;
|
|
}
|
|
|
|
return;
|
|
|
|
ResetPeriodicBcast:
|
|
|
|
// no more routes to advertise for this general response
|
|
CloseEnumHandle(EnumHandle);
|
|
EnumHandle = NULL;
|
|
|
|
// enqueue for the bcast time in the timer queue
|
|
IfRefStartWiTimer(wip, PERIODIC_UPDATE_INTERVAL_MILISECS(icbp));
|
|
}
|
|
|
|
/*++
|
|
|
|
Function: IfPeriodicSendGenRequest
|
|
|
|
Descr: called to send periodically a gen request on a wan line for
|
|
a remote or local workstation dial. This is mainly to remain
|
|
compatible with NT 3.51 rip router which requires a gen request
|
|
in order to send its internal node (if client) or routing table
|
|
if server.
|
|
|
|
Remark: called with the interface lock held
|
|
|
|
--*/
|
|
|
|
VOID
|
|
IfPeriodicGenRequest(PWORK_ITEM wip)
|
|
{
|
|
PICB icbp;
|
|
|
|
icbp = wip->icbp;
|
|
|
|
if(icbp->IfStats.RipIfOperState != OPER_STATE_UP) {
|
|
|
|
FreeWorkItem(wip);
|
|
|
|
return;
|
|
}
|
|
|
|
SendRipGenRequest(icbp);
|
|
|
|
// enqueue the periodic send bcast in the timer queue
|
|
IfRefStartWiTimer(wip, 60000);
|
|
}
|