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.

558 lines
17 KiB

  1. #ifndef _PACKET_H_
  2. #define _PACKET_H_
  3. #ifndef _PPPOE_VERSION
  4. #define _PPPOE_VERSION 1
  5. #endif
  6. typedef struct _ADAPTER* PADAPTER;
  7. typedef struct _BINDING* PBINDING;
  8. //
  9. // Network-to-Host and vice versa conversion macros
  10. //
  11. #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
  12. #define htons(x) _byteswap_ushort((USHORT)(x))
  13. #define htonl(x) _byteswap_ulong((ULONG)(x))
  14. #else
  15. #define htons( a ) ((((a) & 0xFF00) >> 8) |\
  16. (((a) & 0x00FF) << 8))
  17. #define htonl( a ) ((((a) & 0xFF000000) >> 24) | \
  18. (((a) & 0x00FF0000) >> 8) | \
  19. (((a) & 0x0000FF00) << 8) | \
  20. (((a) & 0x000000FF) << 24))
  21. #endif
  22. #define ntohs( a ) htons(a)
  23. #define ntohl( a ) htonl(a)
  24. //
  25. // Constants related to packet lengths
  26. //
  27. #define PPPOE_PACKET_BUFFER_SIZE 1514
  28. #define ETHERNET_HEADER_LENGTH 14
  29. #define PPPOE_PACKET_HEADER_LENGTH 20 // Per RFC2156
  30. #define PPPOE_TAG_HEADER_LENGTH 4 // Per RFC2156
  31. #define PPP_MAX_HEADER_LENGTH 14 // maximum possible header length for ppp
  32. #define PPPOE_AC_COOKIE_TAG_LENGTH 6
  33. //
  34. // Offsets for the header members
  35. //
  36. #define PPPOE_PACKET_DEST_ADDR_OFFSET 0 // Per RFC2156
  37. #define PPPOE_PACKET_SRC_ADDR_OFFSET 6 // Per RFC2156
  38. #define PPPOE_PACKET_ETHER_TYPE_OFFSET 12 // Per RFC2156
  39. #define PPPOE_PACKET_VERSION_OFFSET 14 // Per RFC2156
  40. #define PPPOE_PACKET_TYPE_OFFSET 14 // Per RFC2156
  41. #define PPPOE_PACKET_CODE_OFFSET 15 // Per RFC2156
  42. #define PPPOE_PACKET_SESSION_ID_OFFSET 16 // Per RFC2156
  43. #define PPPOE_PACKET_LENGTH_OFFSET 18 // Per RFC2156
  44. //
  45. // Macros to set information in the header of the packet
  46. //
  47. #define PacketSetDestAddr( pP, addr ) \
  48. NdisMoveMemory( ( pP->pHeader + PPPOE_PACKET_DEST_ADDR_OFFSET ), addr, 6 )
  49. #define PacketSetSrcAddr( pP, addr ) \
  50. NdisMoveMemory( ( pP->pHeader + PPPOE_PACKET_SRC_ADDR_OFFSET ), addr, 6 )
  51. #define PacketSetEtherType( pP, type ) \
  52. * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_ETHER_TYPE_OFFSET ) = htons( (USHORT) type )
  53. #define PacketSetVersion( pP, ver ) \
  54. * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_VERSION_OFFSET ) |= ( ( ( (UCHAR) ver ) << 4 ) & PACKET_VERSION_MASK )
  55. #define PacketSetType( pP, type ) \
  56. * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_TYPE_OFFSET ) |= ( ( (UCHAR) type ) & PACKET_TYPE_MASK )
  57. #define PacketSetCode( pP, code ) \
  58. * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_CODE_OFFSET ) = ( (UCHAR) code )
  59. #define PacketSetSessionId( pP, ses_id ) \
  60. * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_SESSION_ID_OFFSET ) = htons( (USHORT) ses_id )
  61. #define PacketSetLength( pP, len) \
  62. * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_LENGTH_OFFSET ) = htons( (USHORT) len )
  63. #define PacketSetSendCompletionStatus( pP, s ) \
  64. ( pP->SendCompletionStatus = s )
  65. //
  66. // Macros to get information from the header of the packet
  67. //
  68. #define PacketGetDestAddr( pP ) \
  69. ( pP->pHeader + PPPOE_PACKET_DEST_ADDR_OFFSET )
  70. #define PacketGetSrcAddr( pP ) \
  71. ( pP->pHeader + PPPOE_PACKET_SRC_ADDR_OFFSET )
  72. #define PacketGetEtherType( pP ) \
  73. ntohs( * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_ETHER_TYPE_OFFSET ) )
  74. #define PacketGetVersion( pP ) \
  75. ( ( ( * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_VERSION_OFFSET ) ) & PACKET_VERSION_MASK ) >> 4 )
  76. #define PacketGetType( pP ) \
  77. ( ( * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_TYPE_OFFSET ) ) & PACKET_TYPE_MASK )
  78. #define PacketGetCode( pP ) \
  79. ( * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_CODE_OFFSET ) )
  80. #define PacketGetSessionId( pP ) \
  81. ntohs( * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_SESSION_ID_OFFSET ) )
  82. #define PacketGetLength( pP ) \
  83. ntohs( * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_LENGTH_OFFSET ) )
  84. #define PacketGetSendCompletionStatus( pP ) \
  85. ( pP->SendCompletionStatus )
  86. //
  87. // Macro that returns the Ndis Packet for a PPPoE packet
  88. //
  89. #define PacketGetNdisPacket( pP ) \
  90. ( pP->pNdisPacket )
  91. //
  92. // This structure is just a map, and it is not actually used in the code
  93. //
  94. typedef struct
  95. _PPPOE_HEADER
  96. {
  97. CHAR DestAddr[6];
  98. CHAR SrcAddr[6];
  99. #define PACKET_BROADCAST_ADDRESS EthernetBroadcastAddress
  100. USHORT usEtherType;
  101. #define PACKET_ETHERTYPE_DISCOVERY 0x8863
  102. #define PACKET_ETHERTYPE_PAYLOAD 0x8864
  103. union
  104. {
  105. //
  106. // Version field is 4 bits and MUST be set to 0x1 for this version
  107. //
  108. CHAR usVersion;
  109. #define PACKET_VERSION_MASK 0xf0
  110. #define PACKET_VERSION (USHORT)0x1
  111. //
  112. // Type field is 4 bits and MUST be set to 0x1 for this version
  113. //
  114. CHAR usType;
  115. #define PACKET_TYPE_MASK 0x0f
  116. #define PACKET_TYPE (USHORT)0x1
  117. } uVerType;
  118. //
  119. // Code field is 8 bits and is defined as follows for Version 1
  120. // Values selected from enumerated type PACKET_CODES (see below)
  121. //
  122. CHAR usCode;
  123. //
  124. // Session Id field is 16 bits and define a unique session combined with
  125. // the source and destination addresses
  126. //
  127. USHORT usSessionId;
  128. #define PACKET_NULL_SESSION 0x0000
  129. //
  130. // Length field is 16 bits and indicates the length of the payload field only.
  131. // The length field excludes the PPPoE header block.
  132. //
  133. USHORT usLength;
  134. //
  135. // Subtract Header size from Max PADI and MAX payload lengths per RFC2156
  136. //
  137. #define PACKET_PADI_MAX_LENGTH 1478 // (1514 - 20 - 16)
  138. #define PACKET_GEN_MAX_LENGTH 1494 // (1514 - 20)
  139. #define PACKET_PPP_PAYLOAD_MAX_LENGTH 1480 // (1514 - 20)
  140. }
  141. PPPOE_HEADER;
  142. //
  143. // PACKET CODES defined by RFC2156
  144. //
  145. typedef enum
  146. _PACKET_CODES
  147. {
  148. PACKET_CODE_PADI = 0x09,
  149. PACKET_CODE_PADO = 0x07,
  150. PACKET_CODE_PADR = 0x19,
  151. PACKET_CODE_PADS = 0x65,
  152. PACKET_CODE_PADT = 0xa7,
  153. PACKET_CODE_PAYLOAD = 0x00
  154. }
  155. PACKET_CODES;
  156. //
  157. // TAGS defined by RFC2156
  158. //
  159. typedef enum
  160. _PACKET_TAGS
  161. {
  162. tagEndOfList = 0x0000,
  163. tagServiceName = 0x0101,
  164. tagACName = 0x0102,
  165. tagHostUnique = 0x0103,
  166. tagACCookie = 0x0104,
  167. tagVendorSpecific = 0x0105,
  168. tagRelaySessionId = 0x0110,
  169. tagServiceNameError = 0x0201,
  170. tagACSystemError = 0x0202,
  171. tagGenericError = 0x0204
  172. }
  173. PACKET_TAGS;
  174. //
  175. // This is the packet context.
  176. //
  177. // CAUTION: Packets are not protected by their own locks, however they must be accessed carefully
  178. // by using their owner's locks.
  179. //
  180. typedef struct
  181. _PPPOE_PACKET
  182. {
  183. //
  184. // Points to the previous and next packet contexts when in a doubly linked list
  185. //
  186. LIST_ENTRY linkPackets;
  187. //
  188. // Keeps references on the packet
  189. // References added and removed for the following operations:
  190. //
  191. // (a) A reference is added when a packet is created and removed when it is freed.
  192. //
  193. // (b) A reference must be added before sending the packet and must be removed when
  194. // send operation is completed.
  195. //
  196. LONG lRef;
  197. //
  198. // Quick look-up for tags.
  199. //
  200. // The value pointers mark the beginning of the tag value in the pPacket->pPayload section.
  201. // The length values show the lengths of the values (not including the tag header)
  202. //
  203. USHORT tagServiceNameLength;
  204. CHAR* tagServiceNameValue;
  205. USHORT tagACNameLength;
  206. CHAR* tagACNameValue;
  207. USHORT tagHostUniqueLength;
  208. CHAR* tagHostUniqueValue;
  209. USHORT tagACCookieLength;
  210. CHAR* tagACCookieValue;
  211. USHORT tagRelaySessionIdLength;
  212. CHAR* tagRelaySessionIdValue;
  213. PACKET_TAGS tagErrorType;
  214. USHORT tagErrorTagLength;
  215. CHAR* tagErrorTagValue;
  216. //
  217. // Points to the buffer that holds the header portion of a PPPoE packet in wire format.
  218. // This points to the buffer portion of pNdisBuffer (see below)
  219. //
  220. CHAR* pHeader;
  221. //
  222. // Points to the payload portion of a PPPoE packet in wire format.
  223. // This is calculated and is set as : pPacket->pHeader + PPPOE_PACKET_HEADER_LENGTH
  224. //
  225. CHAR* pPayload;
  226. //
  227. // Bit flags that identifies the nature of the buffer and packet
  228. //
  229. // (a) PCBF_BufferAllocatedFromNdisBufferPool: Indicates that pNdisBuffer points to a buffer allocated
  230. // from gl_hNdisBufferpool, and it must be freed to that pool.
  231. //
  232. // (b) PCBF_BufferAllocatedFromOurBufferPool: Indicates that pNdisBuffer points to a buffer allocated
  233. // from gl_poolBuffers, and it must be freed to that pool.
  234. //
  235. // (c) PCBF_PacketAllocatedFromOurPacketPool: Indicates that pNdisPacket points to a packet allocated
  236. // from gl_poolPackets, and it must be freed to that pool.
  237. //
  238. // (d) PCBF_BufferChainedToPacket: Indicates that the buffer pointed to by pNdisBuffer is chained to
  239. // the packet pointed to by pNdisPacket, and must be unchained before
  240. // returning them back to their pools.
  241. //
  242. // (e) PCBF_CallNdisReturnPackets: Indicates that the packet was created using PacketCreateFromReceived()
  243. // and we should call NdisReturnPackets() when we are done with it to
  244. // return it back to NDIS.
  245. //
  246. //
  247. // (f) PCBF_ErrorTagReceived: This flag is valid only for received packets.
  248. // It indicates that when the packet was processed and a PPPoE packet was created
  249. // some error tags were noticed in the packet.
  250. //
  251. ULONG ulFlags;
  252. #define PCBF_BufferAllocatedFromNdisBufferPool 0x00000001
  253. #define PCBF_BufferAllocatedFromOurBufferPool 0x00000002
  254. #define PCBF_PacketAllocatedFromOurPacketPool 0x00000004
  255. #define PCBF_BufferChainedToPacket 0x00000008
  256. #define PCBF_CallNdisReturnPackets 0x00000010
  257. #define PCBF_CallNdisMWanSendComplete 0x00000020
  258. #define PCBF_ErrorTagReceived 0x00000040
  259. #define PCBF_PacketIndicatedIncomplete 0x00000080
  260. //
  261. // Pointer to the NdisBuffer
  262. //
  263. NDIS_BUFFER* pNdisBuffer;
  264. //
  265. // Points directly to the NDIS_PACKET
  266. //
  267. NDIS_PACKET* pNdisPacket;
  268. //
  269. // pPacket->pNdisPacket->ProtocolReserved[0 * sizeof(PVOID)] = (PVOID) pPPPoEPacket;
  270. // pPacket->pNdisPacket->ProtocolReserved[1 * sizeof(PVOID)] = (PVOID) pNdiswanPacket;
  271. // pPacket->pNdisPacket->ProtocolReserved[2 * sizeof(PVOID)] = (PVOID) miniportAdapter;
  272. //
  273. //
  274. // Points to the PACKETHEAD struct in ppool.h. It contains the pointer to NDIS_PACKET
  275. //
  276. PACKETHEAD* pPacketHead;
  277. //
  278. // This is needed to dereference the binding when PCBF_CallNdisReturnPackets flag is set.
  279. //
  280. PBINDING pBinding;
  281. //
  282. // Send completion status for the packet
  283. //
  284. NDIS_STATUS SendCompletionStatus;
  285. }
  286. PPPOE_PACKET;
  287. VOID PacketPoolInit();
  288. VOID PacketPoolUninit();
  289. VOID PacketPoolAlloc();
  290. VOID PacketPoolFree();
  291. PPPOE_PACKET* PacketAlloc();
  292. VOID PacketFree(
  293. IN PPPOE_PACKET* pPacket
  294. );
  295. VOID ReferencePacket(
  296. IN PPPOE_PACKET* pPacket
  297. );
  298. VOID DereferencePacket(
  299. IN PPPOE_PACKET* pPacket
  300. );
  301. PPPOE_PACKET*
  302. PacketCreateSimple();
  303. PPPOE_PACKET*
  304. PacketCreateForReceived(
  305. PBINDING pBinding,
  306. PNDIS_PACKET pNdisPacket,
  307. PNDIS_BUFFER pNdisBuffer,
  308. PUCHAR pContents
  309. );
  310. PPPOE_PACKET*
  311. PacketNdis2Pppoe(
  312. IN PBINDING pBinding,
  313. IN PNDIS_PACKET pNdisPacket,
  314. OUT PINT pRefCount
  315. );
  316. BOOLEAN
  317. PacketFastIsPPPoE(
  318. IN CHAR* HeaderBuffer,
  319. IN UINT HeaderBufferSize
  320. );
  321. VOID
  322. RetrieveTag(
  323. IN OUT PPPOE_PACKET* pPacket,
  324. IN PACKET_TAGS tagType,
  325. OUT USHORT* pTagLength,
  326. OUT CHAR** pTagValue,
  327. IN USHORT prevTagLength,
  328. IN CHAR* prevTagValue,
  329. IN BOOLEAN fSetTagInPacket
  330. );
  331. NDIS_STATUS PacketInsertTag(
  332. IN PPPOE_PACKET* pPacket,
  333. IN PACKET_TAGS tagType,
  334. IN USHORT tagLength,
  335. IN CHAR* tagValue,
  336. OUT CHAR** pNewTagValue
  337. );
  338. NDIS_STATUS PacketInitializePADIToSend(
  339. OUT PPPOE_PACKET** ppPacket,
  340. IN USHORT tagServiceNameLength,
  341. IN CHAR* tagServiceNameValue,
  342. IN USHORT tagHostUniqueLength,
  343. IN CHAR* tagHostUniqueValue
  344. );
  345. NDIS_STATUS
  346. PacketInitializePADOToSend(
  347. IN PPPOE_PACKET* pPADI,
  348. OUT PPPOE_PACKET** ppPacket,
  349. IN CHAR* pSrcAddr,
  350. IN USHORT tagServiceNameLength,
  351. IN CHAR* tagServiceNameValue,
  352. IN USHORT tagACNameLength,
  353. IN CHAR* tagACNameValue,
  354. IN BOOLEAN fInsertACCookieTag
  355. );
  356. NDIS_STATUS PacketInitializePADRToSend(
  357. IN PPPOE_PACKET* pPADO,
  358. OUT PPPOE_PACKET** ppPacket,
  359. IN USHORT tagServiceNameLength,
  360. IN CHAR* tagServiceNameValue,
  361. IN USHORT tagHostUniqueLength,
  362. IN CHAR* tagHostUniqueValue
  363. );
  364. NDIS_STATUS PacketInitializePADSToSend(
  365. IN PPPOE_PACKET* pPADR,
  366. OUT PPPOE_PACKET** ppPacket,
  367. IN USHORT usSessionId
  368. );
  369. NDIS_STATUS PacketInitializePADTToSend(
  370. OUT PPPOE_PACKET** ppPacket,
  371. IN CHAR* pSrcAddr,
  372. IN CHAR* pDestAddr,
  373. IN USHORT usSessionId
  374. );
  375. NDIS_STATUS PacketInitializePAYLOADToSend(
  376. OUT PPPOE_PACKET** ppPacket,
  377. IN CHAR* pSrcAddr,
  378. IN CHAR* pDestAddr,
  379. IN USHORT usSessionId,
  380. IN NDIS_WAN_PACKET* pWanPacket,
  381. IN PADAPTER MiniportAdapter
  382. );
  383. NDIS_STATUS PacketInitializeFromReceived(
  384. IN PPPOE_PACKET* pPacket
  385. );
  386. BOOLEAN PacketAnyErrorTagsReceived(
  387. IN PPPOE_PACKET* pPacket
  388. );
  389. VOID PacketRetrievePayload(
  390. IN PPPOE_PACKET* pPacket,
  391. OUT CHAR** ppPayload,
  392. OUT USHORT* pusLength
  393. );
  394. VOID PacketRetrieveServiceNameTag(
  395. IN PPPOE_PACKET* pPacket,
  396. OUT USHORT* pTagLength,
  397. OUT CHAR** pTagValue,
  398. IN USHORT prevTagLength,
  399. IN CHAR* prevTagValue
  400. );
  401. VOID PacketRetrieveHostUniqueTag(
  402. IN PPPOE_PACKET* pPacket,
  403. OUT USHORT* pTagLength,
  404. OUT CHAR** pTagValue
  405. );
  406. VOID PacketRetrieveACNameTag(
  407. IN PPPOE_PACKET* pPacket,
  408. OUT USHORT* pTagLength,
  409. OUT CHAR** pTagValue
  410. );
  411. VOID PacketRetrieveACCookieTag(
  412. IN PPPOE_PACKET* pPacket,
  413. OUT USHORT* pTagLength,
  414. OUT CHAR** pTagValue
  415. );
  416. VOID PacketRetrieveErrorTag(
  417. IN PPPOE_PACKET* pPacket,
  418. OUT PACKET_TAGS* pTagType,
  419. OUT USHORT* pTagLength,
  420. OUT CHAR** pTagValue
  421. );
  422. PPPOE_PACKET* PacketGetRelatedPppoePacket(
  423. IN NDIS_PACKET* pNdisPacket
  424. );
  425. NDIS_WAN_PACKET* PacketGetRelatedNdiswanPacket(
  426. IN PPPOE_PACKET* pPacket
  427. );
  428. PADAPTER PacketGetMiniportAdapter(
  429. IN PPPOE_PACKET* pPacket
  430. );
  431. PPPOE_PACKET* PacketMakeClone(
  432. IN PPPOE_PACKET* pPacket
  433. );
  434. VOID
  435. PacketGenerateACCookieTag(
  436. IN PPPOE_PACKET* pPacket,
  437. IN CHAR tagACCookieValue[ PPPOE_AC_COOKIE_TAG_LENGTH ]
  438. );
  439. BOOLEAN
  440. PacketValidateACCookieTagInPADR(
  441. IN PPPOE_PACKET* pPacket
  442. );
  443. //////////////////////////////////////////////////////////
  444. //
  445. // Error codes and messages
  446. //
  447. //////////////////////////////////////////////////////////
  448. #define PPPOE_ERROR_BASE 0
  449. #define PPPOE_NO_ERROR PPPOE_ERROR_BASE
  450. #define PPPOE_ERROR_SERVICE_NOT_SUPPORTED PPPOE_ERROR_BASE + 1
  451. #define PPPOE_ERROR_SERVICE_NOT_SUPPORTED_MSG "Service not supported"
  452. #define PPPOE_ERROR_SERVICE_NOT_SUPPORTED_MSG_SIZE ( sizeof( PPPOE_ERROR_SERVICE_NOT_SUPPORTED_MSG ) / sizeof( CHAR ) )
  453. #define PPPOE_ERROR_INVALID_AC_COOKIE_TAG PPPOE_ERROR_BASE + 2
  454. #define PPPOE_ERROR_INVALID_AC_COOKIE_TAG_MSG "AC-Cookie tag is invalid"
  455. #define PPPOE_ERROR_INVALID_AC_COOKIE_TAG_MSG_SIZE ( sizeof( PPPOE_ERROR_INVALID_AC_COOKIE_TAG_MSG ) / sizeof( CHAR ) )
  456. #define PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED PPPOE_ERROR_BASE + 3
  457. #define PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED_MSG "Can not accept any more connections from this machine"
  458. #define PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED_MSG_SIZE ( sizeof( PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED_MSG ) / sizeof( CHAR ) )
  459. #endif