void rdp_write_header(rdpRdp* rdp, STREAM* s, UINT16 length, UINT16 channel_id) { int body_length; enum DomainMCSPDU MCSPDU; MCSPDU = (rdp->settings->ServerMode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest; if ((rdp->sec_flags & SEC_ENCRYPT) && (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)) { int pad; body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16; pad = 8 - (body_length % 8); if (pad != 8) length += pad; } mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0); per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */ per_write_integer16(s, channel_id, 0); /* channelId */ stream_write_BYTE(s, 0x70); /* dataPriority + segmentation */ /* * We always encode length in two bytes, eventhough we could use * only one byte if length <= 0x7F. It is just easier that way, * because we can leave room for fixed-length header, store all * the data first and then store the header. */ length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000; stream_write_UINT16_be(s, length); /* userData (OCTET_STRING) */ }
int ber_write_length(wStream* s, int length) { if (length > 0x7F) { stream_write_BYTE(s, 0x82); stream_write_UINT16_be(s, length); return 3; } else { stream_write_BYTE(s, length); return 1; } }
int ber_write_integer(wStream* s, UINT32 value) { ber_write_universal_tag(s, BER_TAG_INTEGER, FALSE); if (value <= 0xFF) { ber_write_length(s, 1); stream_write_BYTE(s, value); return 2; } else if (value < 0xFF80) { ber_write_length(s, 2); stream_write_UINT16_be(s, value); return 3; } else if (value < 0xFF8000) { ber_write_length(s, 3); stream_write_BYTE(s, (value >> 16)); stream_write_UINT16_be(s, (value & 0xFFFF)); return 4; }
int der_write_length(wStream* s, int length) { if (length > 0x7F && length <= 0xFF) { stream_write_BYTE(s, 0x81); stream_write_BYTE(s, length); return 2; } else if (length > 0xFF) { stream_write_BYTE(s, 0x82); stream_write_UINT16_be(s, length); return 3; } else { stream_write_BYTE(s, length); return 1; } }
void tpkt_write_header(wStream* s, UINT16 length) { stream_write_BYTE(s, 3); /* version */ stream_write_BYTE(s, 0); /* reserved */ stream_write_UINT16_be(s, length); /* length */ }