Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
8.8 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
rtmpstub.c
Abstract:
Handle the RTMP protocol for a non-routing node.
Author:
Garth Conboy (Pacer Software)
Nikhil Kamkolkar (NikhilK)
Revision History:
GC - (03/23/92): Try a little harder to figure out our port's zone name
when a router comes up on a cable, after startup or after
all routers have aged out.
--*/
#define IncludeRtmpStubErrors 1
#include "atalk.h"
ExternForVisibleFunction TimerHandler RtmpAgingTimerExpired;
static Boolean firstCall = True;
void far ShutdownRtmpStub(void)
{
firstCall = True;
} // ShutdownRtmpStub
long far RtmpPacketIn(AppleTalkErrorCode errorCode,
long unsigned userData,
int port,
AppleTalkAddress source,
long destinationSocket,
int protocolType,
char far *datagram,
int datagramLength,
AppleTalkAddress actualDestination)
{
ExtendedAppleTalkNodeNumber sendersNode, ourNode;
AppleTalkNetworkRange cableRange;
AppleTalkAddress ourAddress;
// "Use" unused formals.
userData, source, actualDestination;
// Do we care?
if (errorCode is ATsocketClosed)
return((long)True);
else if (errorCode isnt ATnoError) {
ErrorLog("RtmpPacketIn", ISevError, __LINE__, port,
IErrRtmpStubBadIncomingError, IMsgRtmpStubBadIncomingError,
Insert0());
return((long)True);
}
if (protocolType isnt DdpProtocolRtmpResponseOrData)
return((long)True);
if (firstCall) {
StartTimer(RtmpAgingTimerExpired, RtmpAgingTimerSeconds, 0, empty);
firstCall = False;
}
//
// Non-routing half port? Shouldn't really ever happen, except at startup,
// and we don't care then.
//
if (GET_PORTDESCRIPTOR(port)->PortType is NonAppleTalkHalfPort)
return((long)True);
// Is the packet long enough to have any interestng data?
if (GET_PORTDESCRIPTOR(port)->ExtendedNetwork and
datagramLength < RtmpRangeEndOffset + 2) {
ErrorLog("RtmpPacketIn", ISevWarning, __LINE__, port,
IErrRtmpStubTooShortExt, IMsgRtmpStubTooShortExt,
Insert0());
return((long)True);
}
else if (not GET_PORTDESCRIPTOR(port)->ExtendedNetwork and
datagramLength < RtmpSendersIdOffset) {
ErrorLog("RtmpPacketIn", ISevWarning, __LINE__, port,
IErrRtmpStubTooShort, IMsgRtmpStubTooShort,
Insert0());
return((long)True);
}
// Okay, pull out what we're interested in.
sendersNode.networkNumber =
(short unsigned)(datagram[RtmpSendersNetworkOffset] << 8);
sendersNode.networkNumber +=
(unsigned char)datagram[RtmpSendersNetworkOffset + 1];
if (datagram[RtmpSendersIdLengthOffset] isnt 8) {
ErrorLog("RtmpPacketIn", ISevWarning, __LINE__, port,
IErrRtmpStubBadIdLength, IMsgRtmpStubBadIdLength,
Insert0());
return((long)True);
}
sendersNode.nodeNumber = datagram[RtmpSendersIdOffset];
if (GET_PORTDESCRIPTOR(port)->ExtendedNetwork) {
cableRange.firstNetworkNumber =
(short unsigned)(datagram[RtmpRangeStartOffset] << 8);
cableRange.firstNetworkNumber +=
(unsigned char )datagram[RtmpRangeStartOffset + 1];
cableRange.lastNetworkNumber =
(short unsigned)(datagram[RtmpRangeEndOffset] << 8);
cableRange.lastNetworkNumber +=
(unsigned char )datagram[RtmpRangeEndOffset + 1];
if (not CheckNetworkRange(cableRange))
return((long)True);
}
//
// On a non-extended network, we don't have to do any checking, just copy
// the information into A-ROUTER and THIS-NET.
//
if (not GET_PORTDESCRIPTOR(port)->ExtendedNetwork) {
GET_PORTDESCRIPTOR(port)->SeenRouterRecently = True;
GET_PORTDESCRIPTOR(port)->LastRouterTime = CurrentRelativeTime();
GET_PORTDESCRIPTOR(port)->ARouter = sendersNode;
if (GET_PORTDESCRIPTOR(port)->ThisCableRange.FirstNetworkNumber is
UnknownNetworkNumber)
GET_PORTDESCRIPTOR(port)->ActiveNodes->ExtendedNode.NetworkNumber =
GET_PORTDESCRIPTOR(port)->ThisCableRange.FirstNetworkNumber =
sendersNode.networkNumber;
else if (GET_PORTDESCRIPTOR(port)->ThisCableRange.FirstNetworkNumber isnt
sendersNode.networkNumber)
ErrorLog("RtmpPacketIn", ISevWarning, __LINE__, port,
IErrRtmpStubNetNumChanged, IMsgRtmpStubNetNumChanged,
Insert0());
return((long)True);
}
//
// On extended networks, we may want to reject the information: If we
// already know about a router, the cable ranges must exacly match; If we
// don't know about a router, our node's network number must be within
// the cable range specified by the first tuple. The latter test will
// discard the information if our node is in the startup range (which is
// the right thing to do).
//
if (GET_PORTDESCRIPTOR(port)->SeenRouterRecently)
if (cableRange.firstNetworkNumber isnt
GET_PORTDESCRIPTOR(port)->ThisCableRange.FirstNetworkNumber or
cableRange.lastNetworkNumber isnt
GET_PORTDESCRIPTOR(port)->ThisCableRange.LastNetworkNumber)
return((long)True);
else
// Okay ;
//
// Okay, we've seen a valid Rtmp data, this should allow us to find the
// zone name for the port. We do this outside of the "not seenRouterRecently"
// case because the first time a router send out an Rtmp data it may not
// know everything yet, or GetNetworkInfoForNode() (which calls WaitFor) may
// really do a hard wait and we may need to try it a second time (due to not
// repsonding to Aarp LocateNode's the first time through... the second time
// our addresses should be cached by the remote router and he won't need
// to do a LocateNode again).
//
if (not GET_PORTDESCRIPTOR(port)->ThisZoneValid) {
if (MapSocketToAddress(destinationSocket, &ourAddress) isnt ATnoError)
{
ErrorLog("RtmpPacketIn", ISevError, __LINE__, port,
IErrRtmpStubCouldntMapAddr, IMsgRtmpStubCouldntMapAddr,
Insert0());
return((long)True);
}
if (not IsWithinNetworkRange(ourAddress.networkNumber, &cableRange))
return((long)True);
// Oh boy, a new router, see if it will tell us our zone name.
ourNode.networkNumber = ourAddress.networkNumber;
ourNode.nodeNumber = ourAddress.nodeNumber;
GetNetworkInfoForNode(port, ourNode, False, False);
}
//
// Well, it looks like we win. Copy the information. Don't do it
// if we're a router [maybe a proxy node on arouting port] -- we don't
// want "aRouter" to shift away from "us."
//
if (not GET_PORTDESCRIPTOR(port)->RouterRunning) {
GET_PORTDESCRIPTOR(port)->SeenRouterRecently = True;
GET_PORTDESCRIPTOR(port)->LastRouterTime = CurrentRelativeTime();
GET_PORTDESCRIPTOR(port)->ARouter = sendersNode;
GET_PORTDESCRIPTOR(port)->ThisCableRange = cableRange;
}
// All set!
return((long)True);
} // RtmpPacketIn
ExternForVisibleFunction void far
RtmpAgingTimerExpired(long unsigned timerId,
int additionalDataSize,
char far *additionalData)
{
int port;
long unsigned now = CurrentRelativeTime();
// "Use" unused formals.
timerId, additionalData, additionalDataSize;
// Walk through our active ports; have any routers aged out?
for (port = 0; port < MaximumNumberOfPorts; port += 1)
if (GET_PORTDESCRIPTOR(port)->Flags & PD_ACTIVE and
not GET_PORTDESCRIPTOR(port)->RouterRunning and
GET_PORTDESCRIPTOR(port)->SeenRouterRecently and
(GET_PORTDESCRIPTOR(port)->LastRouterTime +
RtmpAgingTimerSeconds) < now) {
//
// Age out A-ROUTER; on extended networks age out THIS-CABLE-RANGE
// and THIS-ZONE too.
//
GET_PORTDESCRIPTOR(port)->SeenRouterRecently = False;
if (GET_PORTDESCRIPTOR(port)->ExtendedNetwork) {
PortHandlers portHandlers;
portHandlers = &portSpecificInfo[GET_PORTDESCRIPTOR(port)->PortType];
GET_PORTDESCRIPTOR(port)->ThisZoneValid = False;
GET_PORTDESCRIPTOR(port)->ThisCableRange.FirstNetworkNumber =
FirstValidNetworkNumber;
GET_PORTDESCRIPTOR(port)->ThisCableRange.LastNetworkNumber =
LastStartupNetworkNumber;
//
// If we have a zone-multicast address that is not broadcast,
// age it out too.
//
if (not FixedCompareCaseSensitive(GET_PORTDESCRIPTOR(port)->
zoneMulticastAddress,
portHandlers->
hardwareAddressLength,
portHandlers->broadcastAddress,
portHandlers->
hardwareAddressLength))
(*portHandlers->removeMulticastAddress)(port, 1,
GET_PORTDESCRIPTOR(port)->
zoneMulticastAddress);
FillMem(GET_PORTDESCRIPTOR(port)->ZoneMulticastAddress,
0, portHandlers->hardwareAddressLength);
}
}
// Restart the timer and flee.
StartTimer(RtmpAgingTimerExpired, RtmpAgingTimerSeconds, 0, empty);
HandleDeferredTimerChecks();
return;
} // RtmpAgingTimerExpired