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.
 
 
 
 
 
 

1627 lines
33 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
intial.c
Abstract:
Notes:
(REWRITE)
Initialization for the Pacer AppleTalk stack and/or router.
This routine takes an array of structures as its main argument. These
describe the network configuration of each physical port that the stack
or router should be able to communicate on. This may now be done
piece-meal, not starting all ports at once. If Iam an AppleTalkStack,
that is, not just an AppleTalkRouter, the first call to Initialize() must
specify a defaultPort and this port cannot subsequently be shutdown.
A maxmimum of MaximumNumberOrPorts (from "ports.h") ports are currently
supported.
11/12/90: We now allow non-seed router ports. This can pose an
interesting problem in the case where "Iam an AppleTalkStack" AND
"Iam an AppleTalkRouter" for the "default port". The default port
is where all "user node/sockets" are allocated. Also, remember
that no user sockets are ever allocated on the router's node; a
routing port, that is the default port, that has user services running
on it, will always have at least two nodes, one for the router and
at least one for user stuff. Imagine, if you will, a case where
the default port is a non-seed routing port and "user services" (e.g.
a file server) start before the router can be started, due to lack of
a seed router. Further imagine that the user services start in the wrong
network range (maybe the startup range). Now, imagine that a seed
router finally comes up, and somebody starts the router. The router's
node on the port will want ot be in the correct network range so it
can start routing. We, however, don't want to "move" any user nodes
because that would break any active connections. What we do is: tag
any user nodes that are now in the wrong range as "orphaned". These
nodes will be released when the last user socket closes on them. All
further user socket open requests will be handled on new nodes that are
allocated in the correct range. Got that?
The only price we pay for this way cool scheme is that on LocalTalk
(where only a single node is allowed) we cannot allow the port to
BOTH route and be the default port. LocalTalk ports can, however, be
routing ports OR be stack-only default ports. Anyhow, why would
anybody want a LocalTalk port to be a default port?
Author:
Garth Conboy (Pacer Software)
Nikhil Kamkolkar (NikhilK)
Revision History:
--*/
#define GLOBALS
#include "atalk.h"
LOCAL
NbpCompletionHandler
InitRegisterComplete;
LOCAL
BOOLEAN
CopyInitializationInfo(
PPORT_INFO PortInfo,
PPORT_DESCRIPTOR PortDescriptor);
LOCAL
VOID
RegisterInitName(
int Port);
LOCAL
BOOLEAN
CopyInitializationInfo(
PPORT_INFO PortInfo,
PPORT_DESCRIPTOR PortDescriptor);
LOCAL
VOID
_cdecl
InitRegisterComplete(
APPLETALK_ERROR ErrorCode,
ULONG UserData,
int Reason,
long OnWhosBehalf,
int NbpId,
...);
LOCAL
BOOLEAN
CheckHalfPortInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckRemoteAccessInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckPortNameInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckRoutingFlagsInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckPramInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckSeedingInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckNetworkRangeInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckZoneNameInfo(
UINT Port,
PPORT_INFO PortInfo);
LOCAL
BOOLEAN
CheckZoneListInfo(
UINT Port,
PPORT_INFO PortInfo);
static BOOLEAN ourRegisterCompleteFlag;
static APPLETALK_ERROR ourRegisterErrorCode;
BOOLEAN
PreInitialize(
int MaximumNumberOfPortsExpected
)
{
int i;
InitCriticalSectionLocks();
//
// Allocate the port descriptors if they are not already
// allocated
//
if (!PortDescriptors) {
PortDescriptors = Calloc(
sizeof(PORT_DESCRIPTOR)*MaximumNumberOfPortsExpected,
sizeof(CHAR));
if (PortDescriptors == NULL) {
LOG_ERROR(
EVENT_ATALK_MEMORY_RESOURCES,
(__INITIAL__ | __LINE__),
MaximumNumberExpected,
NULL,
0,
0,
NULL);
return(FALSE);
}
} else {
LOG_ERROR(
EVENT_ATALK_PREINITIALIZE,
(__INITIAL__ | __LINE__),
PortDescriptors,
NULL,
0,
0,
NULL);
return(FALSE);
}
NumberOfPortsAllocated = MaximumNumberExpected;
NumberOfPortsInUse = 0;
for (i=0; i < NumberOfPortsAllocated; i++) {
PortDescriptors[i].Type = PD_TYPE;
PortDescriptors[i].Size = PD_SIZE;
}
AppletalkRunning = TRUE;
// Reference for creation, this goes away in unload
AtalkReferenceStack(__INITIAL__ | __LINE__);
InitializeTimers();
#if ArapIncluded
// We now have Arap support... initialize the Des package.
if (desinit(0) != 0) {
UnloadAppleTalk();
return(FALSE);
}
#endif
return(TRUE);
}
BOOLEAN
Initialize(
int MaximumNumberExpected,
int NumberOfPorts,
PORT_INFO PortInfo[]
)
{
int index, indexToo, targetPort, defaultPort;
BOOLEAN foundDefaultPort = FALSE, foundDefaultPortInPortInfo = FALSE;
BOOLEAN foundDefaultZone, foundDesiredZone;
PZONE_LIST zoneList;
PortHandlers portHandlers;
BOOLEAN extendedNetworkPort;
BOOLEAN halfPort, remoteAccess;
BOOLEAN anyRemoteAccessPorts = FALSE;
//
// Loop through all currently active ports to see if one is already the
// default port.
//
for (index = 0; index < NumberOfPortsAllocated; index += 1) {
if (GET_PORTDESCRIPTOR(index)->Flags & PD_ACTIVE) {
if (GET_PORTDESCRIPTOR(index)->DefaultPort) {
foundDefaultPort = TRUE;
ASSERT(DefaultPort == index);
} else if (GET_PORTDESCRIPTOR(index)->PortType is APPLETALK_REMOTEACCESS)
anyRemoteAccessPorts = TRUE;
}
}
//
// Do a little error checking... conditional compilation based on whether
// we're being built as a router or not.
//
if ((NumberOfPorts+NumberOfPortsInUse) > NumberOfPortsAllocated ) {
LOG_ERROR(
EVENT_ATALK_TOOMANYPORTS,
(__INITIAL__ | __LINE__),
NumberOfPortsAllocated,
NULL,
0,
0,
NULL);
return(FALSE);
}
//
// Go through this for loop one to make sure all the portInfo
// have valid port types - we will not initialize any if any
// one of them has an invalid type. Also check default port number.
//
for (index = 0; index < NumberOfPorts; index += 1) {
// Valid port types?
switch(PortInfo[index].PortType) {
case LOCALTALK_NETWORK:
case ETHERNET_NETWORK:
case TOKENRING_NETWORK:
case FDDI_NETWORK:
case NONAPPLETALK_HALFPORT:
break;
#if ArapIncluded
case APPLETALK_REMOTEACCESS:
anyRemoteAccessPort = TRUE;
break;
#endif
default:
LOG_ERRORONPORT(
index,
EVENT_ATALK_INVALID_PORTTYPE,
(__INITIAL__ | __LINE__),
PortInfo[index].PortType,
NULL,
0,
0,
NULL);
return(FALSE);
}
//
// Desired port must either be valid or -1 (meaning we should choose
// one).
//
if (((PortInfo[index].DesiredPort != DynamicPort) &&
(PortInfo[index].DesiredPort < 0)) ||
(PortInfo[index].DesiredPort >= NumberOfPortsAllocated)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_INVALID_PORTNUMBER,
(__INITIAL__ | __LINE__),
PortInfo[index].DesiredPort,
NULL,
0,
0,
NULL);
return(FALSE);
}
if (PortInfo[index].DefaultPort) {
if (!foundDefaultPortInPortInfo) {
foundDefaultPortInPortInfo = TRUE;
// Default port had better be on a real network!
ASSERT(
(PortInfo[index].PortType != NONAPPLETALK_HALFPORT) &&
(PortInfo[index].PortType != APPLETALK_REMOTEACCESS));
} else {
// Multiple default ports not allowed
LOG_ERRORONPORT(
index,
EVENT_ATALK_MULTIPLE_DEFAULTPORT,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
//
// Find an actual port to use: the explicitly requested port must be
// available, if such a request was made; else we'll settle for any port.
//
targetPort = DynamicPort;
if (PortInfo[index].DesiredPort != DynamicPort) {
if (!GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort])->Flags & PD_ACTIVE)
targetPort = PortInfo[index].DesiredPort;
} else {
for (indexToo = 0; indexToo < NumberOfPortsAllocated; indexToo += 1) {
if (!GET_PORTDESCRIPTOR(indexToo)->Flags & PD_ACTIVE) {
targetPort = indexToo;
PortInfo[index].DesiredPort = indexToo; // Tell our caller
break;
}
}
}
// Run away if we haven't found a port.
if (targetPort is DynamicPort) {
LOG_ERROR(
EVENT_ATALK_NO_PORTNUMBER,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
//
// If we're a stack, not just a router, we need a default port. Remote
// access needs a default port too!
//
if ((Iam an AppleTalkStack) || anyRemoteAccessPorts) {
if (!foundDefaultPort && !foundDefaultPortInPortInfo) {
LOG_ERROR(
EVENT_ATALK_NO_DEFAULTPORT,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
//
// Now go through the ports indicated and start them off
//
for (index = 0; index < NumberOfPorts; index += 1) {
extendedNetworkPort = (PortInfo[index].PortType != LOCALTALK_NETWORK);
// Check HalfPort specific stuff.
halfPort = (PortInfo[index].PortType == NONAPPLETALK_HALFPORT);
if (halfPort) {
if (!CheckHalfPortInfo(index, &PortInfo[index]))
return(FALSE);
}
#if ArapIncluded
// Check remote access stuff.
remoteAccess = (PortInfo[index].PortType == APPLETALK_REMOTEACCESS );
if (remoteAccess) {
anyRemoteAccessPorts = TRUE;
if (!CheckRemoteAccessInfo(index, &PortInfo[index]))
return(FALSE);
}
#endif
if (!CheckPortNameInfo(index, &PortInfo[index]) {
return(FALSE);
}
if (!CheckRoutingFlagsInfo(index, &PortInfo[index]) {
return(FALSE);
}
if (!CheckNetworkRangeInfo(index, &PortInfo[index]) {
return(FALSE);
}
if (!CheckPramInfo(index, &PortInfo[index]) {
return(FALSE);
}
if (!CheckZoneNameInfo(index, &PortInfo[index]) {
return(FALSE);
}
//
// Check zone stuff based on our router/stack-ness. If we're a seed
// router ALL seeding information must be present.
//
if (!CheckSeedingInfo(index, &PortInfo[index]) {
return(FALSE);
}
if (!CheckZoneListInfo(index, &PortInfo[index]) {
return(FALSE);
}
// Copy initialization info into the port descriptor.
if (!CopyInitializationInfo(
&PortInfo[index],
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort))) {
return(FALSE);
}
// Okay, tag our new port.
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->Flags & PD_ACTIVE = TRUE;
// Reference for creation
if (AtalkVerifyPortDescriptor(
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort),
(__INITIAL__ | __LINE__)) == NULL) {
INTERNAL_ERROR(__LINE__ | __INITIAL__, 0, NULL, 0);
}
// Reference the stack for this port which is activated
// This will go away when the port is shutdown
if (!AtalkVerifyStack(__INITIAL__ | __LINE__)) {
INTERNAL_ERROR(__LINE__ | __INITIAL__, 0, NULL, 0);
}
#if Iam an AppleTalkRouter
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->UniqueId = UniqueNumber();
#endif
// Do any controller initialization that may be needed.
portHandlers = &PortSpecificInfo[PortInfo[index].PortType];
if (!(*portHandlers->InitializeController)(
PortInfo[index].DesiredPort,
PortInfo[index].ControllerInfo)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_INIT_CONTROLLER,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
AtalkDereferencePortDescriptor(
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort),
(__INITIAL__ | __LINE__));
return(FALSE);
}
// Okay, try to find the hardware address of this port.
if (portHandlers->FindMyAddress) {
if (!(*portHandlers->FindMyAddress)(
PortInfo[index].DesiredPort,
PortInfo[index].ControllerInfo,
GET_PORTDESCRIPTOR(TargetPort)->MyAddress)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_INIT_FINDADDRESS,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
AtalkDereferencePortDescriptor(
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort),
(__INITIAL__ | __LINE__));
return(FALSE);
}
}
// Set up initial values for this-cable-range.
if (GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->ExtendedNetwork &&
!halfPort &&
!remoteAccess) {
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->\
ThisCableRange.FirstNetworkNumber = FIRST_VALIDNETWORKNUMBER;
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->\
ThisCableRange.LastNetworkNumber = LAST_STARTUPNETWORKNUMBER;
} else {
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->\
ThisCableRange.FirstNetworkNumber =
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->\
ThisCableRange.LastNetworkNumber =
}
//
// If we're built as a router, start up the router on the port.
// Otherwise, put our RTMP ears on (get a node on each port).
//
#if Iam an AppleTalkRouter
if (PortInfo[index].StartRouter)
StartRouterOnPort(PortInfo[index].DesiredPort);
#endif
if (!GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort])->RouterRunning &&
PortInfo[index].PortType != APPLETALK_REMOTEACCESS) {
if (GetNodeOnPort(
PortInfo[index].DesiredPort,
TRUE,
TRUE,
FALSE,
NULL) != ATnoError) {
LOG_ERRORONPORT(
PortInfo[index].DesiredPort,
EVENT_ATALK_INIT_COULDNOTGETNODE,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
}
}
// Register our name on the port
if (PortInfo[index].PortType != NONAPPLETALK_HALFPORT &&
PortInfo[index].PortType != APPLETALK_REMOTEACCESS &&
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort])->activeNodes != NULL) {
RegisterInitName(PortInfo[index].DesiredPort);
}
}
#if ArapIncluded
//
// For each new remote access port we need to allocate a proxy node on the
// default port.
//
defaultPort = FindDefaultPort();
if (defaultPort < 0) {
return(FALSE);
}
for (index = 0; index < NumberOfPorts; index += 1)
if (PortInfo[index].PortType is APPLETALK_REMOTEACCESS) {
if (GetNodeOnPort(defaultPort, TRUE, TRUE, FALSE, empty) != ATnoError) {
LOG_ERRORONPORT(
PortInfo[index].DesiredPort,
EVENT_ATALK_NO_DEFAULTPORT,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
continue;
}
// New node is now first on list... set it up as a proxy node.
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes->ProxyNode = TRUE;
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes->ProxyPort =
PortInfo[index].DesiredPort;
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->RemoteAccessInfo\
->ProxyNode =
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes;
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPort)->RemoteAccessInfo\
->ProxyPort =
defaultPort;
// Close the static sockets on the proxy node, they're not needed.
CloseSocketOnNodeIfOpen(
defaultPort,
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes->ExtendedNode,
NAMESINFORMATION_SOCKET);
CloseSocketOnNodeIfOpen(
defaultPort,
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes->ExtendedNode,
ECHOER_SOCKET);
CloseSocketOnNodeIfOpen(
defaultPort,
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes->ExtendedNode,
RTMP_SOCKET);
CloseSocketOnNodeIfOpen(
defaultPort,
GET_PORTDESCRIPTOR(defaultPort)->ActiveNodes->ExtendedNode,
ZONESINFORMATION_SOCKET);
//
// Okay, we can now accept an incoming connection on this remote
// access port.
//
GET_PORTDESCRIPTOR(PortInfo[index].DesiredPor)->RemoteAccessInfo->State =
ArapWaiting;
}
#endif
// All set!
return(TRUE);
} // Initialize
VOID
RegisterInitName(
int Port
)
{
CHAR currentName[MaximumEntityFieldLength + 1];
APPLETALK_ADDRESS address;
LONG socket;
//
// Build the Appletalk address of the NAMESINFORMATION_SOCKET on our
// first node -- that's the one we'll name.
//
ASSERT(GET_PORTDESCRIPTOR(Port)->ActiveNodes != NULL);
address.NetworkNumber =
GET_PORTDESCRIPTOR(Port)->ActiveNodes->ExtendedNode.NetworkNumber;
address.NodeNumber =
GET_PORTDESCRIPTOR(Port)->ActiveNodes->ExtendedNode.NodeNumber;
address.SocketNumber = NAMESINFORMATION_SOCKET;
if ((socket = MapAddressToSocket(Port, address)) < 0) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INIT_NISNOTOPEN,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return;
}
// Pick our port name.
if (GET_PORTDESCRIPTOR(Port)->PortName[0] != 0) {
strcpy(currentName, GET_PORTDESCRIPTOR(Port)->PortName);
} else {
if (GET_PORTDESCRIPTOR(Port)->RoutingPort)
strcpy(currentName, InitPortNameDefaultRouter);
else
strcpy(currentName, InitPortNameDefaultNonRouter);
}
// Start off the register, completion will log the status of the
// register
if (NbpAction(
ForRegister,
socket,
currentName,
InitPortNameType,
NULL,
GetNextNbpIdForNode(socket),
0,
0,
InitRegisterComplete,
(long unsigned)Port) != ATnoError) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INIT_NAMEREGISTERFAILED,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
}
return;
} // RegisterInitName
BOOLEAN
CopyInitializationInfo(
PPORT_INFO PortInfo,
PPORT_DESCRIPTOR PortDescriptor
)
{
//
// Copy all of the information from the initialization record (PortInfo)
// to the actual portDescriptor.
//
PortDescriptor->PortType = PortInfo->PortType;
PortDescriptor->ProtocolInfo = PortInfo->ProtocolInfo;
if (PortInfo->AarpProbes <= 0)
PortDescriptor->AarpProbes = NUMBER_OFAARPPROBES;
else
PortDescriptor->AarpProbes = PortInfo->AarpProbes;
PortDescriptor->ExtendedNetwork =
(PortDescriptor->PortType != LOCALTALK_NETWORK);
PortDescriptor->InitialNetworkRange =
PortInfo->NetworkRange;
PortDescriptor->RoutersPRamStartupNode =
PortInfo->RoutersPRamStartupNode;
PortDescriptor->UsersPRamStartupNode =
PortInfo->UsersPRamStartupNode;
if (PortInfo->ZoneList != NULL)
if ((PortDescriptor->InitialZoneList =
CopyZoneList(PortInfo->ZoneList)) == NULL)
return(FALSE);
if (PortInfo->PortName != NULL)
strcpy(PortDescriptor->PortName, PortInfo->PortName);
else
PortDescriptor->PortName[0] = 0;
if (PortInfo->DefaultZone != NULL)
strcpy(PortDescriptor->InitialDefaultZone, PortInfo->DefaultZone);
if (PortInfo->DesiredZone != NULL)
strcpy(PortDescriptor->InitialDesiredZone, PortInfo->DesiredZone);
PortDescriptor->DefaultPort = PortInfo->DefaultPort;
PortDescriptor->RoutingPort = PortInfo->RoutingPort;
#if Iam an AppleTalkRouter
PortDescriptor->SeedRouter = PortInfo->SeedRouter;
#endif
PortDescriptor->RouterRunning = FALSE;
PortDescriptor->SendDdpChecksums =
PortInfo->SendDdpChecksums;
if (PortInfo->PortType is APPLETALK_REMOTEACCESS)
PortDescriptor->RemoteAccessInfo->configuration =
PortInfo->RemoteAccessConfigurationInfo;
if (PortInfo->ControllerInfoSize != 0) {
// Make a copy of the cotroller info.
if ((PortDescriptor->ControllerInfo =
(PCHAR)Malloc(PortInfo->ControllerInfoSize)) == NULL) {
LOG_ERROR(
EVENT_ATALK_MEMORY_RESOURCES,
(__INITIAL__ | __LINE__),
PortInfo->ControllerInfoSize,
NULL,
0,
0,
NULL);
return(FALSE);
}
MoveMem(
PortDescriptor->ControllerInfo,
PortInfo->ControllerInfo,
PortInfo->ControllerInfoSize);
}
else
PortDescriptor->ControllerInfo = NULL;
// All set.
return(TRUE);
} // CopyInitializationInfo
VOID
_cdecl
InitRegisterComplete(
APPLETALK_ERROR ErrorCode,
ULONG UserData,
int Reason,
long OnWhosBehalf,
int NbpId,
...
)
{
UNREFERENCED_PARAMETER(Reason);
UNREFERENCED_PARAMETER(OnWhosBehalf);
UNREFERENCED_PARAMETER(NbpId);
// Log the results of the register
if (ErrorCode == ATnbpNameInUse) {
LOG_ERRORONPORT(
UserData,
EVENT_ATALK_INIT_NAMEINUSE,
(__INITIAL__ | __LINE__),
MaximumNumberExpected,
NULL,
0,
0,
NULL);
} else if (ErrorCode != ATnbpNameInUse) {
LOG_ERRORONPORT(
UserData,
EVENT_ATALK_INIT_NAMEREGISTERFAILED,
(__INITIAL__ | __LINE__),
ErrorCode,
NULL,
0,
0,
NULL);
}
return;
} // InitRegisterComplete
BOOLEAN
CheckHalfPortInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// Do we like the HalfPort type?
if ((PortInfo->ProtocolInfo < FIRST_VALIDHALFPORTTYPE) ||
(PortInfo->ProtocolInfo > LAST_VALIDHALFPORTTYPE)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INVALID_HALFPORTTYPE
(__INITIAL__ | __LINE__),
PortInfo->ProtocolInfo,
NULL,
0,
0,
NULL);
return(FALSE);
}
// HalfPorts gotta route.
if (not PortInfo[index].RoutingPort) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INVALID_HALFPORTTYPE
(__INITIAL__ | __LINE__),
PortInfo->ProtocolInfo,
NULL,
0,
0,
NULL);
return(FALSE);
}
// We don't really have networks, so we can't seed.
if ((PortInfo->SeedRouter) ||
(PortInfo->NetworkRange.FirstNetworkNumber !=
UNKNOWN_NETWORKNUMBER) ||
(PortInfo->ZoneList != NULL) ||
(PortInfo->DefaultZone != NULL) ||
(PortInfo->DesiredZone != NULL)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_SEEDING_NOTALLOWED
(__INITIAL__ | __LINE__),
PortInfo->SeedRouter,
NULL,
0,
0,
NULL);
return(FALSE);
}
// No network, so can't be the default port!
if (PortInfo->DefaultPort) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_DEFAULTPORT_NOTALLOWED
(__INITIAL__ | __LINE__),
PortInfo->DefaultPort,
NULL,
0,
0,
NULL);
return(FALSE);
}
// No network, no PRAM!
if ((PortInfo->RoutersPRamStartupNode.NetworkNumber !=
UNKNOWN_NETWORKNUMBER) ||
(PortInfo->UsersPRamStartupNode.networkNumber !=
UNKNOWN_NETWORKNUMBER) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_PRAM_NOTALLOWED
(__INITIAL__ | __LINE__),
PortInfo->RoutersPRamStartupNode.NetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
return(TRUE);
}
BOOLEAN
CheckRemoteAccessInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// Do we like the RemoteAccess type?
if ((PortInfo[index].ProtocolInfo < FIRST_VALIDREMOTEACCESSTYPE) ||
(PortInfo[index].ProtocolInfo > LAST_VALIDREMOTEACCESSTYPE)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_INVALID_ARAPPORTTYPE
(__INITIAL__ | __LINE__),
PortInfo[index].PortType,
NULL,
0,
0,
NULL);
return(FALSE);
}
// Remote access ports can't route.
if ((PortInfo[index].RoutingPort) ||
(PortInfo[index].StartRouter)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_ROUTING_ARAPPORT
(__INITIAL__ | __LINE__),
PortInfo[index].RoutingPort,
NULL,
0,
0,
NULL);
return(FALSE);
}
// We don't really have networks, so we can't seed.
if ((PortInfo->SeedRouter) ||
(PortInfo->NetworkRange.FirstNetworkNumber !=
UNKNOWN_NETWORKNUMBER) ||
(PortInfo->ZoneList != NULL) ||
(PortInfo->DefaultZone != NULL) ||
(PortInfo->DesiredZone != NULL)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_SEEDING_NOTALLOWED
(__INITIAL__ | __LINE__),
PortInfo->SeedRouter,
NULL,
0,
0,
NULL);
return(FALSE);
}
// No network, so can't be the default port!
if (PortInfo->DefaultPort) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_DEFAULTPORT_NOTALLOWED
(__INITIAL__ | __LINE__),
PortInfo->DefaultPort,
NULL,
0,
0,
NULL);
return(FALSE);
}
// No network, no PRAM!
if ((PortInfo->sPRamStartupNode.NetworkNumber !=
UNKNOWN_NETWORKNUMBER) ||
(PortInfo->RamStartupNode.networkNumber !=
UNKNOWN_NETWORKNUMBER) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_PRAM_NOTALLOWED
(__INITIAL__ | __LINE__),
PortInfo->sPRamStartupNode.NetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
// Check remote access configuration info.
ASSERT(
(!remoteAccess && (PortInfo->RemoteAccessConfigurationInfo == NULL))
||
(remoteAccess && (PortInfo->RemoteAccessConfigurationInfo != NULL)))
if (remoteAccess &&
PortInfo->RemoteAccessConfigurationInfo == NULL) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_NO_REMOTECONFIGINFO
(__INITIAL__ | __LINE__),
PortInfo->RoutersPRamStartupNode.NetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
if ((remoteAccess &&
(PortInfo->RemoteAccessConfigurationInfo->ServerName != NULL)) {
if (strlen(PortInfo->RemoteAccessConfigurationInfo->
ServerName) > ArapSvrStartSvrNameSize) {
PortInfo->RemoteAccessConfigurationInfo->ServerName = NULL;
}
}
return(TRUE);
}
BOOLEAN
CheckPortNameInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// Check port name.
if (PortInfo->PortName != NULL) {
if (strlen(PortInfo->PortName) > MAXIMUM_PORTNAMELENGTH) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INVALID_PORTNAME
(__INITIAL__ | __LINE__),
strlen(PortInfo->PortName,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
}
BOOLEAN
CheckRoutingFlagsInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// Check for valid routing flags.
#if Iam an AppleTalkRouter
if ((!PortInfo->RoutingPort) &&
(PortInfo->StartRouter)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_NONROUTINGPORT_START
(__INITIAL__ | __LINE__),
PortInfo->RoutingPort,
NULL,
0,
0,
NULL);
return(FALSE);
}
#else
if (PortInfo->RoutingPort ||
PortInfo->StartRouter) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_NONROUTER_START
(__INITIAL__ | __LINE__),
PortInfo->RoutingPort,
NULL,
0,
0,
NULL);
return(FALSE);
}
#endif
return(TRUE);
}
BOOLEAN
CheckNetworkRangeInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// Make sure we have a valid network range or none
if (PortInfo->NetworkRange.FirstNetworkNumber !=
UNKNOWN_NETWORKNUMBER) {
if (extendedNetworkPort) {
if (not CheckNetworkRange(PortInfo->NetworkRange)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INVALID_NETWORKRANGE
(__INITIAL__ | __LINE__),
PortInfo->NetworkRange.LastNetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
} else if ((PortInfo->NetworkRange.LastNetworkNumber !=
UNKNOWN_NETWORKNUMBER) &&
(PortInfo->NetworkRange.LastNetworkNumber !=
PortInfo->NetworkRange.FirstNetworkNumber)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_NONEXTENDED_NETWORKRANGE
(__INITIAL__ | __LINE__),
PortInfo->NetworkRange.LastNetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
// Check for range overlap with any other new seeds.
for (indexToo = 0; indexToo < NumberOfPorts; indexToo += 1) {
if (indexToo != index) {
if (PortInfo->NetworkRange.FirstNetworkNumber !=
UNKNOWN_NETWORKNUMBER) {
if (RangesOverlap(
&PortInfo->o].NetworkRange,
&PortInfo->NetworkRange)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INITIAL_RANGEOVERLAP
(__INITIAL__ | __LINE__),
PortInfo->NetworkRange.LastNetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
}
}
//
// We also need to check for range overlap with any other
// currently active ports.
//
for (indexToo = 0; indexToo < NumberOfPortsAllocated; indexToo += 1) {
if ((GET_PORTDESCRIPTOR(indexToo)->Flags & PD_ACTIVE) &&
(GET_PORTDESCRIPTOR(indexToo)->SeenRouterRecently) {
if (RangesOverlap(
&GET_PORTDESCRIPTOR(indexToo)->thisCableRange,
&PortInfo->NetworkRange)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_INITIAL_RANGEOVERLAP
(__INITIAL__ | __LINE__),
PortInfo[Port].NetworkRange.LastNetworkNumber,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
}
}
return(TRUE);
}
BOOLEAN
CheckPramInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// If we have PRAM values, they must be in this range.
if ((PortInfo->RoutersPRamStartupNode.NetworkNumber
!= UNKNOWN_NETWORKNUMBER) &&
(!IsWithinNetworkRange(
PortInfo->RoutersPRamStartupNode.NetworkNumber,
&PortInfo->NetworkRange)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_PRAM_VALUESNOTINRANGE,
(__INITIAL__ | __LINE__),
PortInfo->RoutersPRamStartupNode.NetworkNumber,
NULL,
0,
0,
NULL);
PortInfo->RoutersPRamStartupNode.NetworkNumber =
UNKNOWN_NETWORKNUMBER;
PortInfo->RoutersPRamStartupNode.NodeNumber =
UNKNOWN_NODENUMBER;
}
if ((PortInfo->UsersPRamStartupNode.NetworkNumber
!= UNKNOWN_NETWORKNUMBER) &&
(!IsWithinNetworkRange(
PortInfo->UsersPRamStartupNode.NetworkNumber,
&PortInfo->NetworkRange)) {
LOG_ERRORONPORT(
Port,
EVENT_ATALK_PRAM_VALUESNOTINRANGE,
(__INITIAL__ | __LINE__),
PortInfo->UsersPRamStartupNode.NetworkNumber,
NULL,
0,
0,
NULL);
PortInfo->UsersPRamStartupNode.networkNumber =
UNKNOWN_NETWORKNUMBER;
PortInfo->UsersPRamStartupNode.nodeNumber =
UNKNOWN_NODENUMBER;
}
return(TRUE);
}
BOOLEAN
CheckSeedingInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
ASSERT(PortInfo->SeedRouter || (PortInfo->ZoneList == NULL));
if (PortInfo->SeedRouter) {
if (PortInfo->NetworkRange.FirstNetworkNumber ==
UNKNOWN_NETWORKNUMBER) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_SEEDROUTER_NONETRANGE,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
if (extendedNetworkPort) {
if ((PortInfo->ZoneList == NULL) ||
(PortInfo->DefaultZone == NULL)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_SEEDROUTER_NOZONELIST,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
if (ElementsOnList(PortInfo->ZoneList) >
MAXIMUM_ZONESPERNETWORK) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_SEEDROUTER_TOOMANYZONES,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
} else {
if ((PortInfo->ZoneList == NULL) ||
(PortInfo->DefaultZone != NULL)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_NONEXTENDED_ZONEINFOINVALID,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
// Only one zone list on non-extended ports
if (ElementsOnList(PortInfo->ZoneList) != 1) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_NONEXTENDED_EXTRAZONESINLIST,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
}
}
return(TRUE);
}
BOOLEAN
CheckZoneNameInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
// Check default/desired zone field.
if ((!extendedNetworkPort) &&
((PortInfo[index].DesiredZone != NULL) ||
(PortInfo[index].DefaultZone != NULL))) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_NONEXTENDED_ZONENAME
(__INITIAL__ | __LINE__),
PortInfo[index].DesiredZone,
NULL,
0,
0,
NULL);
return(FALSE);
}
if (((PortInfo[index].DesiredZone != NULL) &&
(PortInfo[index].DesiredZone[0] == 0) ||
(strlen(PortInfo[index].DesiredZone) > MAXIMUM_ZONELENGTH))
||
((PortInfo[index].DefaultZone != NULL) &&
(PortInfo[index].DefaultZone[0] == 0) ||
(strlen(PortInfo[index].DefaultZone) > MAXIMUM_ZONELENGTH))) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_INVALID_ZONE,
(__INITIAL__ | __LINE__),
strlen(PortInfo[index].DesiredZone),
NULL,
0,
0,
NULL);
return(FALSE);
}
return(TRUE);
}
BOOLEAN
CheckZoneListInfo(
UINT Port,
PPORT_INFO PortInfo
)
{
//
// Validate zone list and make sure the default zone is on the list
// (if present).
//
for (zoneList = PortInfo->ZoneList,
foundDefaultZone = FALSE,
foundDesiredZone = FALSE;
zoneList != empty;
zoneList = zoneList->next) {
if ((zoneList->zone[0] == 0) ||
(strlen(zoneList->zone) > MAXIMUM_ZONELENGTH)) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_INVALID_ZONEINLIST,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
if (PortInfo->DefaultZone != NULL) {
if (CompareCaseInsensitive(
PortInfo->DefaultZone,
zoneList->Zone))
foundDefaultZone = TRUE;
}
if (PortInfo->DesiredZone != empty) {
if (CompareCaseInsensitive(
PortInfo->DesiredZone,
zoneList->Zone))
foundDesiredZone = TRUE;
}
}
if ((PortInfo->ZoneList != NULL) &&
(((PortInfo->DefaultZone != NULL) &&
(!foundDefaultZone)) ||
((PortInfo->DesiredZone != NULL) &&
(!foundDesiredZone)))) {
LOG_ERRORONPORT(
index,
EVENT_ATALK_ZONE_NOTINLIST,
(__INITIAL__ | __LINE__),
0,
NULL,
0,
0,
NULL);
return(FALSE);
}
return(TRUE);
}