20#include <freerdp/config.h>
23#include <winpr/print.h>
25#include <freerdp/log.h>
29#define TAG FREERDP_TAG("core")
66static BOOL tpdu_write_header(
wStream* s, UINT16 length, BYTE code);
75BOOL tpdu_read_header(
wStream* s, BYTE* code, BYTE* li, UINT16 tpktlength)
77 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
80 Stream_Read_UINT8(s, *li);
81 Stream_Read_UINT8(s, *code);
83 if (*li + 4 > tpktlength)
85 WLog_ERR(TAG,
"tpdu length %" PRIu8
" > tpkt header length %" PRIu16, *li, tpktlength);
89 if (*code == X224_TPDU_DATA)
99 if (!Stream_SafeSeek(s, 5))
101 WLog_WARN(TAG,
"tpdu invalid data, got %" PRIuz
", require at least 5 more",
102 Stream_GetRemainingLength(s));
117BOOL tpdu_write_header(
wStream* s, UINT16 length, BYTE code)
119 if (length > UINT8_MAX)
121 WLog_WARN(TAG,
"tpdu invalid length, got %" PRIu16
", maximum supported is %d", length,
125 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 3))
128 WINPR_ASSERT(length <= UINT8_MAX);
129 Stream_Write_UINT8(s, (UINT8)length);
130 Stream_Write_UINT8(s, code);
132 if (code == X224_TPDU_DATA)
134 Stream_Write_UINT8(s, 0x80);
138 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 5))
140 Stream_Write_UINT16(s, 0);
141 Stream_Write_UINT16(s, 0);
142 Stream_Write_UINT8(s, 0);
153BOOL tpdu_read_connection_request(
wStream* s, BYTE* li, UINT16 tpktlength)
157 if (!tpdu_read_header(s, &code, li, tpktlength))
160 if (code != X224_TPDU_CONNECTION_REQUEST)
162 WLog_ERR(TAG,
"Error: expected X224_TPDU_CONNECTION_REQUEST");
175BOOL tpdu_write_connection_request(
wStream* s, UINT16 length)
177 return tpdu_write_header(s, length, X224_TPDU_CONNECTION_REQUEST);
186BOOL tpdu_read_connection_confirm(
wStream* s, BYTE* li, UINT16 tpktlength)
190 size_t bytes_read = 0;
193 position = Stream_GetPosition(s);
195 if (!tpdu_read_header(s, &code, li, tpktlength))
198 if (code != X224_TPDU_CONNECTION_CONFIRM)
200 WLog_ERR(TAG,
"Error: expected X224_TPDU_CONNECTION_CONFIRM");
210 bytes_read = (Stream_GetPosition(s) - position) - 1;
212 return Stream_CheckAndLogRequiredLength(TAG, s, (
size_t)(*li - bytes_read));
221BOOL tpdu_write_connection_confirm(
wStream* s, UINT16 length)
223 return tpdu_write_header(s, length, X224_TPDU_CONNECTION_CONFIRM);
232BOOL tpdu_write_disconnect_request(
wStream* s, UINT16 length)
234 return tpdu_write_header(s, length, X224_TPDU_DISCONNECT_REQUEST);
242BOOL tpdu_write_data(
wStream* s)
244 return tpdu_write_header(s, 2, X224_TPDU_DATA);
252BOOL tpdu_read_data(
wStream* s, UINT16* LI, UINT16 tpktlength)
257 if (!tpdu_read_header(s, &code, &li, tpktlength))
260 if (code != X224_TPDU_DATA)
262 const BYTE dCode = X224_TPDU_DATA;
263 WLog_ERR(TAG,
"tpdu got code 0x%02" PRIx8
" expected X224_TPDU_DATA [0x%02" PRIx8
"]", code,
273const char* tpdu_type_to_string(
int type)
277 case X224_TPDU_CONNECTION_REQUEST:
278 return "X224_TPDU_CONNECTION_REQUEST";
279 case X224_TPDU_CONNECTION_CONFIRM:
280 return "X224_TPDU_CONNECTION_CONFIRM";
281 case X224_TPDU_DISCONNECT_REQUEST:
282 return "X224_TPDU_DISCONNECT_REQUEST";
284 return "X224_TPDU_DATA";
285 case X224_TPDU_ERROR:
286 return "X224_TPDU_ERROR";
288 return "X224_TPDU_UNKNOWN";