197 lines
5.4 KiB
C
197 lines
5.4 KiB
C
/**
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
* Request To Send (RTS) PDUs
|
|
*
|
|
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "rts.h"
|
|
|
|
void rts_pdu_header_write(STREAM* s, RTS_PDU_HEADER* header)
|
|
{
|
|
stream_write_uint8(s, header->rpc_vers); /* rpc_vers (1 byte) */
|
|
stream_write_uint8(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */
|
|
stream_write_uint8(s, header->ptype); /* PTYPE (1 byte) */
|
|
stream_write_uint8(s, header->pfc_flags); /* pfc_flags (1 byte) */
|
|
stream_write_uint8(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */
|
|
stream_write_uint8(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */
|
|
stream_write_uint8(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */
|
|
stream_write_uint8(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */
|
|
stream_write_uint16(s, header->frag_length); /* frag_length (2 bytes) */
|
|
stream_write_uint16(s, header->auth_length); /* auth_length (2 bytes) */
|
|
stream_write_uint32(s, header->call_id); /* call_id (4 bytes) */
|
|
stream_write_uint16(s, header->flags); /* flags (2 bytes) */
|
|
stream_write_uint16(s, header->numberOfCommands); /* numberOfCommands (2 bytes) */
|
|
}
|
|
|
|
void rts_receive_window_size_command_write(STREAM* s, uint32 receiveWindowSize)
|
|
{
|
|
stream_write_uint32(s, RTS_CMD_RECEIVE_WINDOW_SIZE); /* CommandType (4 bytes) */
|
|
stream_write_uint32(s, receiveWindowSize); /* ReceiveWindowSize (4 bytes) */
|
|
}
|
|
|
|
void rts_cookie_command_write(STREAM* s, uint8* cookie)
|
|
{
|
|
stream_write_uint32(s, RTS_CMD_COOKIE); /* CommandType (4 bytes) */
|
|
stream_write(s, cookie, 16); /* Cookie (16 bytes) */
|
|
}
|
|
|
|
void rts_channel_lifetime_command_write(STREAM* s, uint32 channelLifetime)
|
|
{
|
|
stream_write_uint32(s, RTS_CMD_CHANNEL_LIFETIME); /* CommandType (4 bytes) */
|
|
stream_write_uint32(s, channelLifetime); /* ChannelLifetime (4 bytes) */
|
|
}
|
|
|
|
void rts_client_keepalive_command_write(STREAM* s, uint32 clientKeepalive)
|
|
{
|
|
stream_write_uint32(s, RTS_CMD_CLIENT_KEEPALIVE); /* CommandType (4 bytes) */
|
|
stream_write_uint32(s, clientKeepalive); /* ClientKeepalive (4 bytes) */
|
|
}
|
|
|
|
void rts_version_command_write(STREAM* s)
|
|
{
|
|
stream_write_uint32(s, RTS_CMD_VERSION); /* CommandType (4 bytes) */
|
|
stream_write_uint32(s, 1); /* Version (4 bytes) */
|
|
}
|
|
|
|
void rts_padding_command_read(STREAM* s)
|
|
{
|
|
uint32 ConformanceCount;
|
|
|
|
stream_read_uint32(s, ConformanceCount); /* ConformanceCount (4 bytes) */
|
|
stream_seek(s, ConformanceCount); /* Padding (variable) */
|
|
}
|
|
|
|
void rts_association_group_id_command_write(STREAM* s, uint8* associationGroupId)
|
|
{
|
|
stream_write_uint32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */
|
|
stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */
|
|
}
|
|
|
|
void rts_client_address_command_read(STREAM* s)
|
|
{
|
|
uint32 AddressType;
|
|
|
|
stream_read_uint32(s, AddressType); /* ConformanceCount (4 bytes) */
|
|
|
|
if (AddressType == 0)
|
|
{
|
|
stream_seek(s, 4); /* ClientAddress (4 bytes) */
|
|
}
|
|
else
|
|
{
|
|
stream_seek(s, 16); /* ClientAddress (16 bytes) */
|
|
}
|
|
|
|
stream_seek(s, 12); /* padding (12 bytes) */
|
|
}
|
|
|
|
int rts_pdu_recv(rdpRpc* rpc, STREAM* s)
|
|
{
|
|
int i;
|
|
uint16 flags;
|
|
uint32 CommandType;
|
|
uint16 numberOfCommands;
|
|
|
|
stream_seek_uint8(s); /* rpc_vers (1 byte) */
|
|
stream_seek_uint8(s); /* rpc_vers_minor (1 byte) */
|
|
stream_seek_uint8(s); /* PTYPE (1 byte) */
|
|
stream_seek_uint8(s); /* pfc_flags (1 byte) */
|
|
stream_seek_uint32(s); /* packet_drep (4 bytes) */
|
|
stream_seek_uint16(s); /* frag_length (2 bytes) */
|
|
stream_seek_uint16(s); /* auth_length (2 bytes) */
|
|
stream_seek_uint32(s); /* call_id (4 bytes) */
|
|
stream_read_uint16(s, flags); /* flags (2 bytes) */
|
|
stream_read_uint16(s, numberOfCommands); /* numberOfCommands (2 bytes) */
|
|
|
|
if (flags & RTS_FLAG_PING)
|
|
{
|
|
rpc_in_send_keep_alive(rpc);
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < numberOfCommands; i++)
|
|
{
|
|
stream_read_uint32(s, CommandType); /* CommandType (4 bytes) */
|
|
|
|
switch (CommandType)
|
|
{
|
|
case RTS_CMD_RECEIVE_WINDOW_SIZE:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
case RTS_CMD_FLOW_CONTROL_ACK:
|
|
stream_seek(s, 24);
|
|
break;
|
|
|
|
case RTS_CMD_CONNECTION_TIMEOUT:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
case RTS_CMD_COOKIE:
|
|
stream_seek(s, 16);
|
|
break;
|
|
|
|
case RTS_CMD_CHANNEL_LIFETIME:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
case RTS_CMD_CLIENT_KEEPALIVE:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
case RTS_CMD_VERSION:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
case RTS_CMD_EMPTY:
|
|
break;
|
|
|
|
case RTS_CMD_PADDING:
|
|
rts_padding_command_read(s);
|
|
break;
|
|
|
|
case RTS_CMD_NEGATIVE_ANCE:
|
|
break;
|
|
|
|
case RTS_CMD_ANCE:
|
|
break;
|
|
|
|
case RTS_CMD_CLIENT_ADDRESS:
|
|
rts_client_address_command_read(s);
|
|
break;
|
|
|
|
case RTS_CMD_ASSOCIATION_GROUP_ID:
|
|
stream_seek(s, 16);
|
|
break;
|
|
|
|
case RTS_CMD_DESTINATION:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY:
|
|
stream_seek(s, 4);
|
|
break;
|
|
|
|
default:
|
|
printf(" Error: Unknown RTS Command Type: 0x%x\n", CommandType);
|
|
return -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|