Source code of Windows XP (NT5)
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.

528 lines
15 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ports.h
  5. Abstract:
  6. This module contains the structures for ports.
  7. Author:
  8. Jameel Hyder (jameelh@microsoft.com)
  9. Nikhil Kamkolkar (nikhilk@microsoft.com)
  10. Revision History:
  11. 19 Jun 1992 Initial Version
  12. Notes: Tab stop: 4
  13. --*/
  14. #ifndef _PORTS_
  15. #define _PORTS_
  16. #define PORT_AMT_HASH_SIZE 64
  17. #define PORT_BRC_HASH_SIZE 16
  18. #define MAX_ENTITY_LENGTH 32
  19. #define MAX_HW_ADDR_LEN 6
  20. #define MAX_ROUTING_BYTES 18
  21. #define MAX_ROUTING_SPACE 0x1F // This much space is allocated
  22. // for routing info
  23. typedef VOID (*REQ_COMPLETION)(
  24. NDIS_STATUS Status,
  25. PVOID Ctx
  26. );
  27. // Prototypes for handlers
  28. typedef ATALK_ERROR (*ADDMULTICASTADDR)(
  29. struct _PORT_DESCRIPTOR *pPortDesc,
  30. PBYTE Addr,
  31. BOOLEAN ExecuteSync,
  32. REQ_COMPLETION AddCompletion,
  33. PVOID AddContext);
  34. typedef ATALK_ERROR (*REMOVEMULTICASTADDR)(
  35. struct _PORT_DESCRIPTOR *pPortDesc,
  36. PBYTE Addr,
  37. BOOLEAN ExecuteSync,
  38. REQ_COMPLETION RemoveCompletion,
  39. PVOID RemoveContext);
  40. // Address mapping table
  41. // Each port that the stack or router is communicating on must have an
  42. // address mapping table [except non-extended ports]. The mapping table
  43. // holds the association between Appletalk node addresses (network/node),
  44. // and the actual hardware (ethernet/tokenring) addresses. Hash on the
  45. // network/node value.
  46. #define AMT_SIGNATURE (*(ULONG *)"AMT ")
  47. #if DBG
  48. #define VALID_AMT(pAmt) (((pAmt) != NULL) && \
  49. ((pAmt)->amt_Signature == AMT_SIGNATURE))
  50. #else
  51. #define VALID_AMT(pAmt) ((pAmt) != NULL)
  52. #endif
  53. typedef struct _AMT_NODE
  54. {
  55. #if DBG
  56. DWORD amt_Signature;
  57. #endif
  58. struct _AMT_NODE * amt_Next;
  59. ATALK_NODEADDR amt_Target;
  60. BYTE amt_HardwareAddr[MAX_HW_ADDR_LEN];
  61. BYTE amt_Age;
  62. BYTE amt_RouteInfoLen;
  63. // BYTE amt_RouteInfo[MAX_ROUTING_SPACE];
  64. } AMT, *PAMT;
  65. #define AMT_AGE_TIME 600 // In 100ms units
  66. #define AMT_MAX_AGE 3
  67. // Best Router Entry Table
  68. // Maintained only for extended networks. This must age more quickly than the
  69. // "SeenARouter" timer (50 seconds). To avoid allocations/frees for this structure,
  70. // we use statically allocated data in the port descriptor.
  71. typedef struct _BRE
  72. {
  73. struct _BRE * bre_Next;
  74. USHORT bre_Network;
  75. BYTE bre_Age;
  76. BYTE bre_RouterAddr[MAX_HW_ADDR_LEN];
  77. BYTE bre_RouteInfoLen;
  78. // BYTE bre_RouteInfo[MAX_ROUTING_SPACE];
  79. } BRE, *PBRE;
  80. #define BRC_AGE_TIME 40 // In 100ms units
  81. #define BRC_MAX_AGE 3
  82. //
  83. // Types of ports currently supported by stack. This is kept different
  84. // from the NDIS medium types for two reasons. One is we use these as
  85. // an index into the port handler array, and the second is if we decide
  86. // to implement half-ports etc., which ndis might not be able to deal with.
  87. // WARNING: THIS IS INTEGRATED WITH THE PORT HANDLER ARRAY IN GLOBALS.
  88. typedef enum
  89. {
  90. ELAP_PORT = 0,
  91. FDDI_PORT,
  92. TLAP_PORT,
  93. ALAP_PORT,
  94. ARAP_PORT,
  95. LAST_PORT,
  96. LAST_PORTTYPE = LAST_PORT
  97. } ATALK_PORT_TYPE;
  98. //
  99. // PORT DESCRIPTORS
  100. // Descriptor for each active port:
  101. //
  102. #define PD_ACTIVE 0x00000001 // State after packets recv enabled
  103. #define PD_BOUND 0x00000002 // State it goes in before ACTIVE
  104. #define PD_EXT_NET 0x00000004 // For now, non-localtalk
  105. #define PD_DEF_PORT 0x00000008 // Is this the default port
  106. #define PD_SEND_CHECKSUMS 0x00000010 // Send ddp checksums?
  107. #define PD_SEED_ROUTER 0x00000020 // seeding on this port?
  108. #define PD_ROUTER_STARTING 0x00000040 // Temporary state when router is starting
  109. #define PD_ROUTER_RUNNING 0x00000080 // Is the router running?
  110. #define PD_SEEN_ROUTER_RECENTLY 0x00000100 // Seen router recently?
  111. #define PD_VALID_DESIRED_ZONE 0x00000200 // Desired Zone is valid
  112. #define PD_VALID_DEFAULT_ZONE 0x00000400 // Default zone is valid
  113. #define PD_FINDING_DEFAULT_ZONE 0x00000800 // searching for default zone?
  114. #define PD_FINDING_DESIRED_ZONE 0x00001000 // searching for desired zone?
  115. #define PD_FINDING_NODE 0x00002000 // In the process of acquiring a
  116. // new node on this port
  117. #define PD_NODE_IN_USE 0x00004000 // Tentative node is already in
  118. // use.
  119. #define PD_ROUTER_NODE 0x00008000 // Router node is allocated
  120. #define PD_USER_NODE_1 0x00010000 // First user node is allocated
  121. #define PD_USER_NODE_2 0x00020000 // Second user node is allocated
  122. #define PD_RAS_PORT 0x00040000 // this port for RAS clients
  123. #define PD_PNP_RECONFIGURE 0x00080000 // this port is currently being reconfigured
  124. #define PD_CONFIGURED_ONCE 0x00100000 // this port has been configured once
  125. #define PD_CLOSING 0x80000000 // State when unbinding/shutting down
  126. #define PD_SIGNATURE (*(ULONG *)"PDES")
  127. #if DBG
  128. #define VALID_PORT(pPortDesc) (((pPortDesc) != NULL) && \
  129. ((pPortDesc)->pd_Signature == PD_SIGNATURE))
  130. #else
  131. #define VALID_PORT(pPortDesc) ((pPortDesc) != NULL)
  132. #endif
  133. typedef struct _PORT_DESCRIPTOR
  134. {
  135. #if DBG
  136. ULONG pd_Signature;
  137. #endif
  138. // Link to next - for now to help debugging
  139. struct _PORT_DESCRIPTOR *pd_Next;
  140. // Number of references to this port
  141. ULONG pd_RefCount;
  142. // State of the port
  143. ULONG pd_Flags;
  144. // if this is a Ras port, all ARAP connetions hang on this list
  145. LIST_ENTRY pd_ArapConnHead;
  146. // if this is a Ras port, all PPP connetions hang on this list
  147. LIST_ENTRY pd_PPPConnHead;
  148. // if this is a Ras port, how many lines do we have on this port?
  149. ULONG pd_RasLines;
  150. // Overide the default number of aarp probes when looking for a
  151. // node on this port
  152. SHORT pd_AarpProbes;
  153. // Node # of the localtalk node
  154. USHORT pd_LtNetwork;
  155. // Nodes that are being managed on this port. We have a maximum
  156. // of 2 nodes (3 if the router is started).
  157. struct _ATALK_NODE * pd_Nodes;
  158. struct _ATALK_NODE * pd_RouterNode;
  159. // Following are used only during node acquisition process.
  160. // PD_FINDINGNODE is set. Keep this separate from the ndis
  161. // request event. Both could happen at the same time.
  162. ATALK_NODEADDR pd_TentativeNodeAddr;
  163. KEVENT pd_NodeAcquireEvent;
  164. // Port type as defined above
  165. ATALK_PORT_TYPE pd_PortType;
  166. // NdisMedium type for this port
  167. NDIS_MEDIUM pd_NdisPortType;
  168. // Used during OpenAdapter to block
  169. KEVENT pd_RequestEvent;
  170. NDIS_STATUS pd_RequestStatus;
  171. // Binding handle to the mac associated with this port
  172. // Options associated with the mac.
  173. // MAC Options - these are things that we can and cannot do with
  174. // specific macs. Is the value of OID_GEN_MAC_OPTIONS.
  175. NDIS_HANDLE pd_NdisBindingHandle;
  176. ULONG pd_MacOptions;
  177. // This is the spin lock used to protect all requests that need exclusion
  178. // over requests per port.
  179. ATALK_SPIN_LOCK pd_Lock;
  180. // All the packets received on this port are linked in here. When the
  181. // receive complete indication is called, all of them are passed to DDP.
  182. LIST_ENTRY pd_ReceiveQueue;
  183. // ASCII port name to be registered on the router node for this port
  184. // This will be an NBP object name and hence is limited to 32 characters.
  185. CHAR pd_PortName[MAX_ENTITY_LENGTH + 1];
  186. // AdapterName is of the form \Device\<adaptername>. It is used
  187. // to bind to the NDIS macs, and then during ZIP requests by setup
  188. // to get the zonelist for a particular adapter. AdapterKey
  189. // contains the adapterName only- this is useful both for getting
  190. // per-port parameters and during errorlogging to specify the adapter
  191. // name without the '\Device\' prefix.
  192. UNICODE_STRING pd_AdapterKey;
  193. UNICODE_STRING pd_AdapterName;
  194. UNICODE_STRING pd_FriendlyAdapterName;
  195. ATALK_NODEADDR pd_RoutersPramNode;
  196. ATALK_NODEADDR pd_UsersPramNode1;
  197. ATALK_NODEADDR pd_UsersPramNode2;
  198. HANDLE pd_AdapterInfoHandle; // Valid during initialization only
  199. // Initial values from the registry
  200. ATALK_NETWORKRANGE pd_InitialNetworkRange;
  201. struct _ZONE_LIST * pd_InitialZoneList;
  202. struct _ZONE * pd_InitialDefaultZone;
  203. struct _ZONE * pd_InitialDesiredZone;
  204. // True cable range of connected network. Initial/aged values for
  205. // extended ports: 1:FFFE; Initial value for non-extended ports:
  206. // 0:0 (does not age).
  207. ATALK_NETWORKRANGE pd_NetworkRange;
  208. // If we are routing, this is the default zone for the network
  209. // on this port, and the zone list for the same.
  210. struct _ZONE_LIST * pd_ZoneList;
  211. struct _ZONE * pd_DefaultZone;
  212. struct _ZONE * pd_DesiredZone;
  213. // When did we hear from a router?
  214. LONG pd_LastRouterTime;
  215. // Address of last router seen. If we are a routing port, this will
  216. // always be the node that "our" router is operating on!
  217. ATALK_NODEADDR pd_ARouter;
  218. KEVENT pd_SeenRouterEvent;
  219. // Zone in which all nodes on this port reside and the multicast
  220. // address for it.
  221. CHAR pd_ZoneMulticastAddr[MAX_HW_ADDR_LEN];
  222. union
  223. {
  224. struct
  225. {
  226. //
  227. // FOR ETHERNET PORTS:
  228. //
  229. // We add multicast addresses during ZIP packet reception at non-init
  230. // time. We need to do a GET followed by a SET with the new address
  231. // list. But there could be two zip packets coming in and doing the
  232. // same thing effectively overwriting the effects of the first one to
  233. // set the multicast list. So we need to maintain our own copy of the
  234. // multicast list.
  235. //
  236. // Size of the list
  237. ULONG pd_MulticastListSize;
  238. PCHAR pd_MulticastList;
  239. };
  240. struct
  241. {
  242. //
  243. // FOR TOKENRING PORTS:
  244. //
  245. // Just like for ethernet, we need to store the value for
  246. // the current functional address. We only modify the last
  247. // four bytes of this address, as the first two always remain
  248. // constant. So we use a ULONG for it.
  249. //
  250. UCHAR pd_FunctionalAddr[4]; // TLAP_ADDR_LEN - TLAP_MCAST_HDR_LEN
  251. };
  252. };
  253. // Hardware address for the port
  254. union
  255. {
  256. UCHAR pd_PortAddr[MAX_HW_ADDR_LEN];
  257. USHORT pd_AlapNode;
  258. };
  259. // Mapping table for best route to "off cable" addresses.
  260. TIMERLIST pd_BrcTimer;
  261. PBRE pd_Brc[PORT_BRC_HASH_SIZE];
  262. // Logical/physical address mappings for the nodes on the network that
  263. // this port is connected to.
  264. ULONG pd_AmtCount; // # of entries in the Amt
  265. TIMERLIST pd_AmtTimer;
  266. PAMT pd_Amt[PORT_AMT_HASH_SIZE];
  267. union
  268. {
  269. TIMERLIST pd_RtmpSendTimer; // If router is configured
  270. TIMERLIST pd_RtmpAgingTimer; // else
  271. };
  272. // Per port statistics
  273. ATALK_PORT_STATS pd_PortStats;
  274. // Port handler stuff
  275. ADDMULTICASTADDR pd_AddMulticastAddr;
  276. REMOVEMULTICASTADDR pd_RemoveMulticastAddr;
  277. BYTE pd_BroadcastAddr[MAX_HW_ADDR_LEN];
  278. USHORT pd_BroadcastAddrLen;
  279. USHORT pd_AarpHardwareType;
  280. USHORT pd_AarpProtocolType;
  281. PKEVENT pd_ShutDownEvent;
  282. } PORT_DESCRIPTOR, *PPORT_DESCRIPTOR;
  283. #define INDICATE_ATP 0x01
  284. #define INDICATE_ADSP 0x02
  285. #define ATALK_CACHE_SKTMAX 8
  286. #define ATALK_CACHE_ADSPSKT ((BYTE)0x01)
  287. #define ATALK_CACHE_ATPSKT ((BYTE)0x02)
  288. #define ATALK_CACHE_INUSE ((BYTE)0x10)
  289. #define ATALK_CACHE_NOTINUSE ((BYTE)0)
  290. typedef struct _ATALK_SKT_CACHE
  291. {
  292. USHORT ac_Network;
  293. BYTE ac_Node;
  294. struct ATALK_CACHED_SKT
  295. {
  296. BYTE Type;
  297. BYTE Socket;
  298. union
  299. {
  300. // For ATP
  301. struct _ATP_ADDROBJ * pAtpAddr;
  302. } u;
  303. } ac_Cache[ATALK_CACHE_SKTMAX];
  304. } ATALK_SKT_CACHE, *PATALK_SKT_CACHE;
  305. extern ATALK_SKT_CACHE AtalkSktCache;
  306. extern ATALK_SPIN_LOCK AtalkSktCacheLock;
  307. // externS
  308. extern PPORT_DESCRIPTOR AtalkPortList; // Head of the port list
  309. extern PPORT_DESCRIPTOR AtalkDefaultPort; // Ptr to the def port
  310. extern KEVENT AtalkDefaultPortEvent; // Signalled when default port is available
  311. extern UNICODE_STRING AtalkDefaultPortName; // Name of the default port
  312. extern ATALK_SPIN_LOCK AtalkPortLock; // Lock for AtalkPortList
  313. extern ATALK_NODEADDR AtalkUserNode1; // Node address of user node
  314. extern ATALK_NODEADDR AtalkUserNode2; // Node address of user node
  315. extern SHORT AtalkNumberOfPorts; // Determine dynamically
  316. extern SHORT AtalkNumberOfActivePorts;// Number of ports active
  317. extern BOOLEAN AtalkRouter; // Are we a router?
  318. extern BOOLEAN AtalkFilterOurNames; // If TRUE, Nbplookup fails on names on this machine
  319. extern KEVENT AtalkUnloadEvent; // Event for unloading
  320. extern NDIS_HANDLE AtalkNdisPacketPoolHandle;
  321. extern NDIS_HANDLE AtalkNdisBufferPoolHandle;
  322. extern LONG AtalkHandleCount;
  323. extern UNICODE_STRING AtalkRegPath;
  324. extern HANDLE TdiRegistrationHandle;
  325. extern BOOLEAN AtalkNoDefPortPrinted;
  326. // Exported prototypes
  327. extern
  328. VOID FASTCALL
  329. AtalkPortDeref(
  330. IN OUT PPORT_DESCRIPTOR pPortDesc,
  331. IN BOOLEAN AtDpc);
  332. extern
  333. BOOLEAN
  334. AtalkReferenceDefaultPort(
  335. IN VOID
  336. );
  337. extern
  338. ATALK_ERROR
  339. AtalkPortShutdown(
  340. IN OUT PPORT_DESCRIPTOR pPortDesc);
  341. VOID FASTCALL
  342. AtalkPortSetResetFlag(
  343. IN PPORT_DESCRIPTOR pPortDesc,
  344. IN BOOLEAN fRemoveBit,
  345. IN DWORD dwBit);
  346. // Macros
  347. #define AtalkPortReferenceByPtr(Port, pErr) \
  348. { \
  349. DBGPRINT(DBG_COMP_REFCOUNTS, DBG_LEVEL_INFO, \
  350. ("Ref at %s %d\n", __FILE__, __LINE__)); \
  351. AtalkPortRefByPtr((Port), (pErr)); \
  352. }
  353. #define AtalkPortReferenceByPtrDpc(Port, pErr) \
  354. { \
  355. DBGPRINT(DBG_COMP_REFCOUNTS, DBG_LEVEL_INFO, \
  356. ("Ref (Dpc) at %s %d\n", \
  357. __FILE__, __LINE__)); \
  358. AtalkPortRefByPtrDpc((Port), (pErr)); \
  359. }
  360. #define AtalkPortReferenceByPtrNonInterlock(Port, pErr) \
  361. { \
  362. DBGPRINT(DBG_COMP_REFCOUNTS, DBG_LEVEL_INFO, \
  363. ("Ref at %s %d\n", __FILE__, __LINE__)); \
  364. AtalkPortRefByPtrNonInterlock((Port), (pErr)); \
  365. }
  366. #define AtalkPortReferenceByDdpAddr(DdpAddr, Port, pErr) \
  367. { \
  368. DBGPRINT(DBG_COMP_REFCOUNTS, DBG_LEVEL_INFO, \
  369. ("Ref at %s %d\n", __FILE__, __LINE__)); \
  370. AtalkPortRefByDdpAddr((DdpAddr), (Port), (pErr)); \
  371. }
  372. #define AtalkPortDereference(Port) \
  373. { \
  374. DBGPRINT(DBG_COMP_REFCOUNTS, DBG_LEVEL_INFO, \
  375. ("Deref at %s %d\n", __FILE__, __LINE__)); \
  376. AtalkPortDeref(Port, FALSE); \
  377. }
  378. #define AtalkPortDereferenceDpc(Port) \
  379. { \
  380. DBGPRINT(DBG_COMP_REFCOUNTS, DBG_LEVEL_INFO, \
  381. ("Deref at %s %d\n", __FILE__, __LINE__)); \
  382. AtalkPortDeref(Port, TRUE); \
  383. }
  384. #define EXT_NET(_pPortDesc) ((_pPortDesc)->pd_Flags & PD_EXT_NET)
  385. #define DEF_PORT(_pPortDesc) ((_pPortDesc)->pd_Flags & PD_DEF_PORT)
  386. #define PORT_BOUND(_pPortDesc) ((_pPortDesc)->pd_Flags & PD_BOUND)
  387. #define PORT_CLOSING(_pPortDesc) ((_pPortDesc)->pd_Flags & PD_CLOSING)
  388. #define AtalkPortRefByPtr(pPortDesc, pErr) \
  389. { \
  390. KIRQL OldIrql; \
  391. \
  392. ACQUIRE_SPIN_LOCK(&((pPortDesc)->pd_Lock),&OldIrql);\
  393. AtalkPortRefByPtrNonInterlock((pPortDesc), (pErr)); \
  394. RELEASE_SPIN_LOCK(&((pPortDesc)->pd_Lock),OldIrql); \
  395. }
  396. #define AtalkPortRefByPtrDpc(pPortDesc, pErr) \
  397. { \
  398. ACQUIRE_SPIN_LOCK_DPC(&((pPortDesc)->pd_Lock)); \
  399. AtalkPortRefByPtrNonInterlock((pPortDesc), (pErr)); \
  400. RELEASE_SPIN_LOCK_DPC(&((pPortDesc)->pd_Lock)); \
  401. }
  402. #define AtalkPortRefByPtrNonInterlock(pPortDesc, pErr) \
  403. { \
  404. if (((pPortDesc)->pd_Flags & PD_CLOSING) == 0) \
  405. { \
  406. ASSERT((pPortDesc)->pd_RefCount > 0); \
  407. (pPortDesc)->pd_RefCount++; \
  408. *(pErr) = ATALK_NO_ERROR; \
  409. } \
  410. else \
  411. { \
  412. *(pErr) = ATALK_PORT_CLOSING; \
  413. } \
  414. }
  415. #define AtalkPortRefByDdpAddr(pDdpAddr, ppPortDesc, pErr) \
  416. { \
  417. ASSERT(VALID_ATALK_NODE((pDdpAddr)->ddpao_Node)); \
  418. \
  419. *(ppPortDesc) = (pDdpAddr)->ddpao_Node->an_Port; \
  420. AtalkPortRefByPtr(*(ppPortDesc), (pErr)); \
  421. }
  422. VOID
  423. atalkPortFreeZones(
  424. IN PPORT_DESCRIPTOR pPortDesc
  425. );
  426. #endif // _PORTS_