/// <summary> /// Verify the received message from client. /// </summary> /// <param name="remoteAddr">The remote address.</param> /// <param name="pccrrPacket">The pccrrPacket.</param> private void RetrievalTransport_Receive(IPEndPoint remoteAddr, PccrrPacket pccrrPacket) { PccrrGETBLKSRequestPacket pccrrGETBLKSRequestPacket = pccrrPacket as PccrrGETBLKSRequestPacket; if (pccrrGETBLKSRequestPacket != null) { MSG_GETBLKS msgGETBLKS = pccrrGETBLKSRequestPacket.MsgGetBLKS; MESSAGE_HEADER messageHEADER = pccrrGETBLKSRequestPacket.MessageHeader; this.sid = msgGETBLKS.SegmentID; REQUEST_MESSAGE requestMESSAGE = new REQUEST_MESSAGE(); requestMESSAGE.MESSAGEBODY = msgGETBLKS; requestMESSAGE.MESSAGEHEADER = messageHEADER; this.uiPayload = Marshal.SizeOf(messageHEADER) + Marshal.SizeOf(msgGETBLKS) + 24; PccrrBothRoleCaptureCode.CaptureBlockRangeRequirements(msgGETBLKS.ReqBlockRanges[0]); PccrrBothRoleCaptureCode.CaptureMessageHeaderRequirements(messageHEADER, this.uiPayload); this.VerifyGetBlocks(msgGETBLKS); this.VerifyRequestMessage(requestMESSAGE); PccrrBothRoleCaptureCode.CaptureSegmentIdRequirements(msgGETBLKS.SegmentID); PccrrBothRoleCaptureCode.CaptureHttpRequirements(); PccrrBothRoleCaptureCode.CaptureMessageRequirements(); this.ReceiveMsgGetBlk(msgGETBLKS.ReqBlockRanges[0].Index); } else { PccrrGETBLKLISTRequestPacket pccrrGETBLKLISTRequestPacket = pccrrPacket as PccrrGETBLKLISTRequestPacket; if (pccrrGETBLKLISTRequestPacket != null) { MSG_GETBLKLIST msgGETBLKLIST = pccrrGETBLKLISTRequestPacket.MsgGetBLKLIST; this.sid = msgGETBLKLIST.SegmentID; this.VerifyGetBlkList(msgGETBLKLIST); PccrrBothRoleCaptureCode.CaptureCommonDataTypesRequirements(msgGETBLKLIST); _BLOCKRANGE[] blockRanges = ClientHelper.ConvertFromStackBLOCKRANGEArray(msgGETBLKLIST.NeededBlockRanges); this.ReceiveMsgGetBlkList(blockRanges); } else { this.ReceiveMsgNegoReq(); } } }
/// <summary> /// Capture Common Data Types structure requirements. /// </summary> /// <param name="obj">The object.</param> public static void CaptureCommonDataTypesRequirements(object obj) { if (obj is MSG_GETBLKLIST) { MSG_GETBLKLIST getBlkList = (MSG_GETBLKLIST)obj; // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R22"); // Verify MS-PCCRR requirement: MS-PCCRR_R22 bool isVerifyR22 = getBlkList.NeededBlocksRangeCount.GetType() == typeof(uint); site.CaptureRequirementIfIsTrue( isVerifyR22, 22, @"[In Common Data Types]The protocol supports three field types: Integer (DWORD fields as defined in [MS-DTYP] section 2.2.9, transmitted in network byte order)."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R23"); // Verify MS-PCCRR requirement: MS-PCCRR_R23 bool isVerifyR23 = getBlkList.NeededBlockRanges.GetType() == typeof(BLOCK_RANGE[]); site.CaptureRequirementIfIsTrue( isVerifyR23, 23, @"[In Common Data Types][The protocol supports three field types]BLOCK_RANGE_ARRAY ( (Integer [2])[count], i.e. a count-sized array of BLOCK_RANGE fields)."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R24"); // Verify MS-PCCRR requirement: MS-PCCRR_R24 bool isVerifyR24 = getBlkList.SegmentID.GetType() == typeof(byte[]); site.CaptureRequirementIfIsTrue( isVerifyR24, 24, @"[In Common Data Types][The protocol supports three field types]BYTE array (BYTE[count], i.e. a count-sized array of bytes)."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R33"); // Verify MS-PCCRR requirement: MS-PCCRR_R33 // if server has any of the requested block ranges. then getBlkList.NeededBlockRanges > 0, // BlockRanges is an array of BLOCK_RANGE to store BLOCK_RANGE entries. // If the lenght is larger than 0, means it contains BLOCK_RANGE entries. bool isVerifyR33 = getBlkList.NeededBlockRanges.Length > 0; site.CaptureRequirementIfIsTrue( isVerifyR33, 33, @"[In BLOCK_RANGE_ARRAY]Variable-size array containing BLOCK_RANGE entries."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R34"); // Verify MS-PCCRR requirement: MS-PCCRR_R34 // If the type is BLOCK_RANGE[], means that it is declared as follows: typedef BLOCK_RANGE BLOCK_RANGE_ARRAY[]. bool isVerifyR34 = getBlkList.NeededBlockRanges.GetType() == typeof(BLOCK_RANGE[]); site.CaptureRequirementIfIsTrue( isVerifyR34, 34, @"[In BLOCK_RANGE_ARRAY]This type[BLOCK_RANGE_ARRAY] is declared as follows: typedef BLOCK_RANGE BLOCK_RANGE_ARRAY[];"); } else if (obj is MSG_BLKLIST) { MSG_BLKLIST blkList = (MSG_BLKLIST)obj; // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R22"); // Verify MS-PCCRR requirement: MS-PCCRR_R22 bool isVerifyR22 = blkList.BlockRangeCount.GetType() == typeof(uint); site.CaptureRequirementIfIsTrue( isVerifyR22, 22, @"[In Common Data Types]The protocol supports three field types:Integer (DWORD fields as defined in [MS-DTYP] section 2.2.9, transmitted in network byte order)."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R23"); // Verify MS-PCCRR requirement: MS-PCCRR_R23 bool isVerifyR23 = blkList.BlockRanges.GetType() == typeof(BLOCK_RANGE[]); site.CaptureRequirementIfIsTrue( isVerifyR23, 23, @"[In Common Data Types][The protocol supports three field types]BLOCK_RANGE_ARRAY ( (Integer [2])[count], i.e. a count-sized array of BLOCK_RANGE fields)."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R24"); // Verify MS-PCCRR requirement: MS-PCCRR_R24 bool isVerifyR24 = blkList.ZeroPad.GetType() == typeof(byte[]); site.CaptureRequirementIfIsTrue( isVerifyR24, 24, @"[In Common Data Types][The protocol supports three field types]BYTE array (BYTE[count], i.e. a count-sized array of bytes)."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R33"); // Verify MS-PCCRR requirement: MS-PCCRR_R33 // if server has any of the requested block ranges. then blkList.BlockRanges.Length > 0, // BlockRanges is an array of BLOCK_RANGE to store BLOCK_RANGE entries. // If the lenght is larger than 0, means it contains BLOCK_RANGE entries. bool isVerifyR33 = blkList.BlockRanges.Length >= 0; site.CaptureRequirementIfIsTrue( isVerifyR33, 33, @"[In BLOCK_RANGE_ARRAY]Variable-size array containing BLOCK_RANGE entries."); // // Add the debug information // site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R34"); // Verify MS-PCCRR requirement: MS-PCCRR_R34 // If the type is BLOCK_RANGE[], means that it is declared as follows: typedef BLOCK_RANGE BLOCK_RANGE_ARRAY[]. bool isVerifyR34 = blkList.BlockRanges.GetType() == typeof(BLOCK_RANGE[]); site.CaptureRequirementIfIsTrue( isVerifyR34, 34, @"[In BLOCK_RANGE_ARRAY]This type[BLOCK_RANGE_ARRAY] is declared as follows:typedef BLOCK_RANGE BLOCK_RANGE_ARRAY[];"); } }
/// <summary> /// MSG_GETBLKLIST structure capture. /// </summary> /// <param name="getBlkList">MSG_GETBLKLIST object.</param> private void VerifyGetBlkList(MSG_GETBLKLIST getBlkList) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R82"); // Verify MS-PCCRR requirement: MS-PCCRR_R82 // If GetBlkList.NeededBlockRanges is not null, means it contains a request for blocks of content. Site.CaptureRequirementIfIsNotNull( getBlkList.NeededBlockRanges, 82, @"[In MSG_GETBLKLIST]The MSG_GETBLKLIST (GetBlockList) message contains a request for a download block list."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R84"); // Verify MS-PCCRR requirement: MS-PCCRR_R84 Site.CaptureRequirementIfAreEqual <uint>( (uint)getBlkList.SegmentID.Length, getBlkList.SizeOfSegmentID, 84, @"[In MSG_GETBLKLIST]SizeOfSegmentID (4 bytes): Size, in bytes. of the subsequent SegmentID field."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R85"); // Verify MS-PCCRR requirement: MS-PCCRR_R85 bool isVerifyR85 = getBlkList.SizeOfSegmentID >= 0x00000000 && getBlkList.SizeOfSegmentID <= 0xFFFFFFFF; Site.CaptureRequirementIfIsTrue( isVerifyR85, 85, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)]The syntactic range of this field[SegmentID field] is from 0x00000000 to 0xFFFFFFFF."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R88"); // Verify MS-PCCRR requirement: MS-PCCRR_R88 Site.CaptureRequirementIfAreEqual <int>( 32, getBlkList.SegmentID.Length, 88, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)][Implementations ]MUST support content with 32-byte SegmentIDs.<4>"); if (null != getBlkList.ZeroPad) { bool isAllZero = true; // If the length is zero, the flag will remain in true // else, the bytes will be checked in foreach statements foreach (byte b in getBlkList.ZeroPad) { if (b != 0) { isAllZero = false; break; } } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R92"); // Verify MS-PCCRR requirement: MS-PCCRR_R92 bool isVerifyR92 = isAllZero; Site.CaptureRequirementIfIsTrue( isVerifyR92, 92, @"[In MSG_GETBLKLIST][ZeroPad (variable)]The value of each byte MUST be set to zero."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R93"); // Verify MS-PCCRR requirement: MS-PCCRR_R93 bool isVerifyR93 = getBlkList.ZeroPad.Length >= 0 && getBlkList.ZeroPad.Length <= 3; Site.CaptureRequirementIfIsTrue( isVerifyR93, 93, @"[In MSG_GETBLKLIST][ZeroPad (variable)]This field[ZeroPad ] is 0 to 3 bytes in length, as required."); } // Verify requirement MS-PCCRR_R87 and MS-PCCRR_R112 string isR87Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R87Implementated"); bool isR112Satisfied = getBlkList.SizeOfSegmentID >= 0x00000000 && getBlkList.SizeOfSegmentID <= 0xFFFFFFFF; if (isWindows) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R112"); // Verify MS-PCCRR requirement: MS-PCCRR_R112 Site.CaptureRequirementIfIsTrue( isR112Satisfied, 112, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)]Implementations support all allowed SegmentID lengths.[In windows]"); if (null == isR87Implementated) { Site.Properties.Add("PCCRR.SHOULDMAY.R87Implementated", Boolean.TrueString); isR87Implementated = Boolean.TrueString; } } if (null != isR87Implementated) { bool implement = Boolean.Parse(isR87Implementated); bool isSatisfied = isR112Satisfied; // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R87"); // Verify MS-PCCRR requirement: MS-PCCRR_R87 Site.CaptureRequirementIfAreEqual <bool>( implement, isSatisfied, 87, @"[In MSG_GETBLKLIST][SizeOfSegmentID (4 bytes)]Implementations SHOULD support all allowed SegmentID lengths"); } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R94"); // Verify MS-PCCRR requirement: MS-PCCRR_R94 Site.CaptureRequirementIfAreEqual <uint>( getBlkList.NeededBlocksRangeCount, (uint)getBlkList.NeededBlockRanges.Length, 94, @"[In MSG_GETBLKLIST]NeededBlocksRangeCount (4 bytes): Number of items in the subsequent block range array."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R95"); // Verify MS-PCCRR requirement: MS-PCCRR_R95 bool isVerifyR95 = getBlkList.NeededBlocksRangeCount >= 0x00000000 && getBlkList.NeededBlocksRangeCount <= 0xFFFFFFFF; Site.CaptureRequirementIfIsTrue( isVerifyR95, 95, @"[In MSG_GETBLKLIST][NeededBlocksRangeCount (4 bytes)]The syntactic range of this field is from 0x00000000 to 0xFFFFFFFF."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R96"); // Verify MS-PCCRR requirement: MS-PCCRR_R96 bool isVerifyR96 = getBlkList.NeededBlocksRangeCount >= 1 && getBlkList.NeededBlocksRangeCount <= 256; Site.CaptureRequirementIfIsTrue( isVerifyR96, 96, @"[In MSG_GETBLKLIST][NeededBlocksRangeCount (4 bytes)]The effective range of this field MUST be between 1 and 256 inclusive, because there cannot be more than 256 non-overlapping and non-contiguous ranges in a maximum segment size of 512 blocks."); // Capture directly, cause it won't get the packet if the client didn't specify a right server address Site.CaptureRequirement( 193, @"[In MSG_GETBLKLIST Initiation]To initiate a Retrieval Protocol query for the list of block ranges on a server, the higher-layer applications MUST specify a server address."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R194"); // Verify MS-PCCRR requirement: MS-PCCRR_R194 bool isVerifyR194 = true; Site.CaptureRequirementIfIsTrue( isVerifyR194, 194, @"[In MSG_GETBLKLIST Initiation]To initiate a Retrieval Protocol query for the list of block ranges on a server, the higher-layer applications MUST specify a segment ID."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R195"); // Verify MS-PCCRR requirement: MS-PCCRR_R195 bool isVerifyR195 = getBlkList.NeededBlocksRangeCount == (uint)getBlkList.NeededBlockRanges.Length && true; Site.CaptureRequirementIfIsTrue( isVerifyR195, 195, @"[In MSG_GETBLKLIST Initiation]To initiate a Retrieval Protocol query for the list of block ranges on a server, the higher-layer applications MUST specify a set of block ranges within the segment identified by the segment ID."); // Capture directly, because it won't send a GetBlocklist message to the server if the client // did not construct an instance of the Retrieval Protocol instantiation. Site.CaptureRequirement( 196, @"[In MSG_GETBLKLIST Initiation]The client instance of the Retrieval Protocol instantiation MUST construct a GetBlockList message ."); // Capture directly, because it won't send a GetBlocklist message to the server if the client // did not construct an instance of the Retrieval Protocol instantiation. Site.CaptureRequirement( 197, @"[In MSG_GETBLKLIST Initiation]The client instance of the Retrieval Protocol instantiation MUST send a GetBlockList message (MSG_GETBLKLIST (section 2.2.4.2)) to the server."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R171"); // Verify MS-PCCRR requirement: MS-PCCRR_R171 bool isVerifyR171 = getBlkList.NeededBlockRanges != null && getBlkList.SegmentID != null; Site.CaptureRequirementIfIsTrue( isVerifyR171, 171, @"[In Protocol Details]BlockList request/response: A client initiates a GetBlockList request (MSG_GETBLKLIST (section 2.2.4.2)) to a server in order to query the list of content blocks available on the server for a given segment ID, and a list of block ranges within the segment, by sending a MSG_GETBLKLIST request."); }