int parseUserInformation(byte[] buffer, int bufPos, int maxBufPos, ref bool userInfoValid) { iecs.logger.LogDebug(String.Format("ACSE: parseUserInformation {0} {1}", bufPos, maxBufPos)); bool hasindirectReference = false; bool isDataValid = false; while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); switch (tag) { case 0x02: /* indirect-reference */ nextReference = IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); bufPos += len; hasindirectReference = true; break; case 0xa0: /* encoding */ isDataValid = true; userDataBufferSize = len; userDataBufferIndex = bufPos; bufPos += len; break; default: /* ignore unknown tag */ bufPos += len; break; } } if (!hasindirectReference) { iecs.logger.LogDebug("ACSE: User data has no indirect reference!"); } if (!isDataValid) { iecs.logger.LogDebug("ACSE: No valid user data"); } if (hasindirectReference && isDataValid) { userInfoValid = true; } else { userInfoValid = false; } return(bufPos); }
int parsePresentationContextDefinitionList(byte[] buffer, int totalLength, int bufPos) { int endPos = bufPos + totalLength; while (bufPos < endPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, endPos); switch (tag) { case 0x30: iecs.logger.LogDebug("PRES: parse pcd entry"); bufPos = parsePCDLEntry(buffer, len, bufPos); if (bufPos < 0) { return(-1); } break; default: iecs.logger.LogDebug("PRES: unknown tag in presentation-context-definition-list"); bufPos += len; break; } } return(bufPos); }
/// <summary> /// Parses Iso presentation accept message /// </summary> /// <param name="buffer">Data buffer</param> /// <param name="offset">Index of the first message byte</param> /// <param name="length">Length of the buffer from offset to end</param> /// <returns>Index to the user data (payload) in the absolute numbering (from the buffer index 0)</returns> public int parseAcceptMessage(byte[] buffer, int offset, int length) { int maxBufPos = offset + length; int bufPos = offset; byte cpTag = buffer[bufPos++]; if (cpTag != 0x31) { iecs.logger.LogDebug("PRES: not a CPA message\n"); return(0); } int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length\n"); return(0); } switch (tag) { case 0xa0: /* mode-selector */ bufPos += len; /* ignore content since only normal mode is allowed */ break; case 0xa2: /* normal-mode-parameters */ bufPos = parseNormalModeParameters(buffer, len, bufPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: error parsing normal-mode-parameters"); return(0); } break; default: iecs.logger.LogDebug(String.Format("PRES: CPA unknown tag {0}", tag)); bufPos += len; break; } } return(bufPos); }
int parseNormalModeParameters(byte[] buffer, int totalLength, int bufPos) { int endPos = bufPos + totalLength; while (bufPos < endPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, endPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length"); return(-1); } switch (tag) { case 0x81: /* calling-presentation-selector */ iecs.logger.LogDebug("PRES: calling-pres-sel"); bufPos += len; break; case 0x82: /* calling-presentation-selector */ iecs.logger.LogDebug("PRES: calling-pres-sel"); bufPos += len; break; case 0xa4: /* presentation-context-definition list */ iecs.logger.LogDebug("PRES: pcd list"); bufPos = parsePresentationContextDefinitionList(buffer, len, bufPos); break; case 0x61: /* user data */ iecs.logger.LogDebug("PRES: user-data"); bufPos = parseFullyEncodedData(buffer, len, bufPos); if (bufPos < 0) { return(-1); } break; default: iecs.logger.LogDebug("PRES: unknown tag in normal-mode"); bufPos += len; break; } } return(bufPos); }
public AcseIndication parseMessage(byte[] buffer, int offset, int length) { AcseIndication indication; int messageSize = offset + length; int bufPos = offset; byte messageType = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, messageSize); if (bufPos < 0) { iecs.logger.LogDebug("ACSE: AcseConnection_parseMessage: invalid ACSE message!"); return(AcseIndication.ACSE_ERROR); } switch (messageType) { case 0x60: indication = parseAarqPdu(buffer, bufPos, messageSize); break; case 0x61: indication = parseAarePdu(buffer, bufPos, messageSize); break; case 0x62: /* A_RELEASE.request RLRQ-apdu */ indication = AcseIndication.ACSE_RELEASE_REQUEST; break; case 0x63: /* A_RELEASE.response RLRE-apdu */ indication = AcseIndication.ACSE_RELEASE_RESPONSE; break; case 0x64: /* A_ABORT */ indication = AcseIndication.ACSE_ABORT; break; default: iecs.logger.LogDebug("ACSE: Unknown ACSE message\n"); indication = AcseIndication.ACSE_ERROR; break; } return(indication); }
/// <summary> /// Parses Iso presentation user data message /// </summary> /// <param name="buffer">Data buffer</param> /// <param name="offset">Index of the first message byte</param> /// <param name="length">Length of the buffer from offset to end</param> /// <returns>Index to the user data (payload) in the absolute numbering (from the buffer index 0)</returns> public int parseUserData(byte[] buffer, int offset, int length) { int bufPos = offset; if (length < 9) { return(0); } if (buffer[bufPos++] != 0x61) { return(0); } int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, length); if (buffer[bufPos++] != 0x30) { return(0); } bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, length); if (buffer[bufPos++] != 0x02) { return(0); } if (buffer[bufPos++] != 0x01) { return(0); } nextContextId = buffer[bufPos++]; if (buffer[bufPos++] != 0xa0) { return(0); } int userDataLength = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref userDataLength, bufPos, length); return(bufPos); }
AcseIndication parseAarqPdu(byte[] buffer, int bufPos, int maxBufPos) { iecs.logger.LogDebug("ACSE: parse AARQ PDU\n"); int authValuePos = 0; int authValueLen = 0; int authMechanismPos = 0; int authMechLen = 0; bool userInfoValid = false; while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); if (bufPos < 0) { iecs.logger.LogDebug("ACSE: parseAarqPdu: user info invalid!\n"); return(AcseIndication.ACSE_ASSOCIATE_FAILED); } switch (tag) { case 0xa1: /* application context name */ bufPos += len; break; case 0xa2: /* called AP title */ bufPos += len; break; case 0xa3: /* called AE qualifier */ bufPos += len; break; case 0xa6: /* calling AP title */ bufPos += len; break; case 0xa7: /* calling AE qualifier */ bufPos += len; break; case 0x8a: /* sender ACSE requirements */ bufPos += len; break; case 0x8b: /* (authentication) mechanism name */ authMechLen = len; authMechanismPos = bufPos; bufPos += len; break; case 0xac: /* authentication value */ bufPos++; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); authValueLen = len; authValuePos = bufPos; bufPos += len; break; case 0xbe: /* user information */ if (buffer[bufPos] != 0x28) { iecs.logger.LogDebug("ACSE: invalid user info\n"); bufPos += len; } else { bufPos++; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); bufPos = parseUserInformation(buffer, bufPos, bufPos + len, ref userInfoValid); } break; default: /* ignore unknown tag */ iecs.logger.LogDebug(String.Format("ACSE: parseAarqPdu: unknown tag 0x{0:X2}", tag)); bufPos += len; break; } } if (checkAuthentication(buffer, authMechanismPos, authMechLen, authValuePos, authValueLen) == false) { iecs.logger.LogDebug("ACSE: parseAarqPdu: check authentication failed!"); return(AcseIndication.ACSE_ASSOCIATE_FAILED); } if (userInfoValid == false) { iecs.logger.LogDebug("ACSE: parseAarqPdu: user info invalid!"); return(AcseIndication.ACSE_ASSOCIATE_FAILED); } return(AcseIndication.ACSE_ASSOCIATE); }
AcseIndication parseAarePdu(byte[] buffer, int bufPos, int maxBufPos) { iecs.logger.LogDebug("ACSE: parse AARE PDU"); bool userInfoValid = false; uint result = 99; while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); switch (tag) { case 0xa1: /* application context name */ bufPos += len; break; case 0xa2: /* result */ bufPos++; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); result = IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); bufPos += len; break; case 0xa3: /* result source diagnostic */ bufPos += len; break; case 0xbe: /* user information */ if (buffer[bufPos] != 0x28) { iecs.logger.LogDebug("ACSE: invalid user info"); bufPos += len; } else { bufPos++; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); bufPos = parseUserInformation(buffer, bufPos, bufPos + len, ref userInfoValid); } break; default: /* ignore unknown tag */ iecs.logger.LogDebug(String.Format("ACSE: parseAarePdu: unknown tag 0x{0:X2}", tag)); bufPos += len; break; } } if (!userInfoValid) { return(AcseIndication.ACSE_ERROR); } if (result != 0) { return(AcseIndication.ACSE_ASSOCIATE_FAILED); } return(AcseIndication.ACSE_ASSOCIATE); }
/// <summary> /// Parses Iso presentation connect message /// </summary> /// <param name="buffer">Data buffer</param> /// <param name="offset">Index of the first message byte</param> /// <param name="length">Length of the buffer from offset to end</param> /// <returns>Index to the user data (payload) in the absolute numbering (from the buffer index 0)</returns> public int parseConnect(byte[] buffer, int offset, int length) { int maxBufPos = offset + length; int bufPos = offset; byte cpTag = buffer[bufPos++]; if (cpTag != 0x31) { iecs.logger.LogDebug("PRES: not a CP type"); return(0); } int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); iecs.logger.LogDebug(String.Format("PRES: CPType with len {0}", len)); while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length\n"); return(0); } switch (tag) { case 0xa0: /* mode-selection */ { if (buffer[bufPos++] != 0x80) { iecs.logger.LogDebug("PRES: mode-value of wrong type!"); return(0); } bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); uint modeSelector = IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); iecs.logger.LogDebug(String.Format("PRES: modesel {0}", modeSelector)); bufPos += len; } break; case 0xa2: /* normal-mode-parameters */ bufPos = parseNormalModeParameters(buffer, len, bufPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: error parsing normal-mode-parameters"); return(0); } break; default: /* unsupported element */ iecs.logger.LogDebug(String.Format("PRES: tag 0x{0:X2} not recognized\n", tag)); bufPos += len; break; } } return(bufPos); }
int parsePCDLEntry(byte[] buffer, int totalLength, int bufPos) { int endPos = bufPos + totalLength; int contextId = -1; bool isAcse = false; bool isMms = false; while (bufPos < endPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, endPos); switch (tag) { case 0x02: /* presentation-context-identifier */ contextId = (int)IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); bufPos += len; break; case 0x06: /* abstract-syntax-name */ iecs.logger.LogDebug(String.Format("PRES: abstract-syntax-name with len {0}", len)); if (len == 5) { isMms = true; for (int i = 0; i < 5; i++) { if (buffer[bufPos + i] != asn_id_mms[i]) { isMms = false; } } //if (memcmp(buffer + bufPos, asn_id_mms, 5) == 0) // isMms = true; } else if (len == 4) { isAcse = true; for (int i = 0; i < 4; i++) { if (buffer[bufPos + i] != asn_id_as_acse[i]) { isAcse = false; } } //if (memcmp(buffer + bufPos, asn_id_as_acse, 4) == 0) // isAcse = true; } bufPos += len; break; case 0x30: /* transfer-syntax-name */ iecs.logger.LogDebug("PRES: ignore transfer-syntax-name"); bufPos += len; break; default: iecs.logger.LogDebug("PRES: unknown tag in presentation-context-definition-list-entry"); bufPos += len; break; } } if (contextId < 0) { iecs.logger.LogDebug("PRES: ContextId not defined!"); return(-1); } if ((isAcse == false) && (isMms == false)) { iecs.logger.LogDebug("PRES: not an ACSE nor MMS context definition"); return(-1); } if (isMms) { mmsContextId = (byte)contextId; iecs.logger.LogDebug(String.Format("PRES: MMS context id is {0}", contextId)); } else { acseContextId = (byte)contextId; iecs.logger.LogDebug(String.Format("PRES: ACSE context id is {0}", contextId)); } return(bufPos); }
int parseFullyEncodedData(byte[] buffer, int len, int bufPos) { int presentationSelector = -1; bool userDataPresent = false; int endPos = bufPos + len; if (buffer[bufPos++] != 0x30) { iecs.logger.LogDebug("PRES: user-data parse error"); return(-1); } bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, endPos); endPos = bufPos + len; if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length"); return(-1); } while (bufPos < endPos) { byte tag = buffer[bufPos++]; int length = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref length, bufPos, endPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length"); return(-1); } switch (tag) { case 0x02: /* presentation-context-identifier */ iecs.logger.LogDebug("PRES: presentation-context-identifier"); { presentationSelector = (int)IsoUtil.BerDecoder_decodeUint32(buffer, length, bufPos); nextContextId = (byte)presentationSelector; bufPos += length; } break; case 0xa0: iecs.logger.LogDebug("PRES: fully-encoded-data"); userDataPresent = true; nextPayload_bufferIndex = bufPos; nextPayload_size = length; bufPos += length; break; default: iecs.logger.LogDebug(String.Format("PRES: fed: unknown tag 0x{0:X2}", tag)); bufPos += length; break; } } if (!userDataPresent) { iecs.logger.LogDebug("PRES: user-data not present\n"); return(-1); } return(bufPos); }