mirror of https://github.com/lianthony/NT4.0
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
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);
|
|
}
|
|
|
|
|
|
|