e11a571f14
really embodies a huge number of changes. We are now able to talk quite fluently to a French NT Terminal Server - in normal usage only minor font issues remain (handling of TEXT2 order is not perfect). The next major hurdle is encryption, and it will be quite a big hurdle - there seems to be some quite nasty session key stuff. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@8 423420c4-83ab-492f-b58f-81f9feb106b5
175 lines
3.8 KiB
C
175 lines
3.8 KiB
C
/*
|
|
rdesktop: A Remote Desktop Protocol client.
|
|
Protocol services - ISO layer
|
|
Copyright (C) Matthew Chapman 1999-2000
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
|
|
/* Establish a connection up to the ISO layer */
|
|
HCONN iso_connect(char *server)
|
|
{
|
|
HCONN conn;
|
|
uint8 code;
|
|
|
|
if ((conn = tcp_connect(server)) == NULL)
|
|
return NULL;
|
|
|
|
iso_send_msg(conn, ISO_PDU_CR);
|
|
|
|
if (!iso_recv_msg(conn, &code) || (code != ISO_PDU_CC))
|
|
{
|
|
ERROR("ISO error, expected CC\n");
|
|
tcp_disconnect(conn);
|
|
return NULL;
|
|
}
|
|
|
|
return conn;
|
|
}
|
|
|
|
/* Disconnect from the ISO layer */
|
|
void iso_disconnect(HCONN conn)
|
|
{
|
|
iso_send_msg(conn, ISO_PDU_DR);
|
|
tcp_disconnect(conn);
|
|
}
|
|
|
|
/* Send self-contained ISO message identified by code */
|
|
BOOL iso_send_msg(HCONN conn, uint8 code)
|
|
{
|
|
TPKT tpkt;
|
|
TPDU tpdu;
|
|
|
|
iso_make_tpkt(&tpkt, 11);
|
|
iso_io_tpkt(&conn->out, &tpkt);
|
|
iso_make_tpdu(&tpdu, code);
|
|
iso_io_tpdu(&conn->out, &tpdu);
|
|
MARK_END(conn->out);
|
|
return tcp_send(conn);
|
|
}
|
|
|
|
/* Receive a message on the ISO layer, return code */
|
|
BOOL iso_recv_msg(HCONN conn, uint8 *code)
|
|
{
|
|
TPDU tpdu;
|
|
TPKT tpkt;
|
|
BOOL res;
|
|
|
|
res = tcp_recv(conn, 4);
|
|
res = res ? iso_io_tpkt(&conn->in, &tpkt) : False;
|
|
res = res ? tcp_recv(conn, tpkt.length - 4) : False;
|
|
res = res ? iso_io_tpdu(&conn->in, &tpdu) : False;
|
|
|
|
*code = tpdu.code;
|
|
return res;
|
|
}
|
|
|
|
/* Initialise ISO transport data packet */
|
|
void iso_init(struct connection *conn)
|
|
{
|
|
PUSH_LAYER(conn->out, iso_offset, 7);
|
|
}
|
|
|
|
/* Receive ISO transport data packet */
|
|
BOOL iso_recv(HCONN conn)
|
|
{
|
|
uint8 code;
|
|
|
|
if (!iso_recv_msg(conn, &code) || (code != ISO_PDU_DT))
|
|
{
|
|
ERROR("ISO error, expected DT\n");
|
|
return False;
|
|
}
|
|
|
|
return True;
|
|
}
|
|
|
|
/* Receive ISO transport data packet */
|
|
BOOL iso_send(HCONN conn)
|
|
{
|
|
TPKT tpkt;
|
|
TPDU tpdu;
|
|
|
|
POP_LAYER(conn->out, iso_offset);
|
|
iso_make_tpkt(&tpkt, conn->out.end);
|
|
iso_io_tpkt(&conn->out, &tpkt);
|
|
iso_make_tpdu(&tpdu, ISO_PDU_DT);
|
|
iso_io_tpdu(&conn->out, &tpdu);
|
|
return tcp_send(conn);
|
|
}
|
|
|
|
/* Initialise a TPKT structure */
|
|
void iso_make_tpkt(TPKT *tpkt, int length)
|
|
{
|
|
tpkt->version = 3;
|
|
tpkt->reserved = 0;
|
|
tpkt->length = length;
|
|
}
|
|
|
|
/* Marshall/demarshall a TPKT structure */
|
|
BOOL iso_io_tpkt(STREAM s, TPKT *tpkt)
|
|
{
|
|
if (!prs_io_uint8(s, &tpkt->version))
|
|
return False;
|
|
|
|
if (tpkt->version != 3)
|
|
{
|
|
ERROR("Wrong TPKT version %d\n", tpkt->version);
|
|
return False;
|
|
}
|
|
|
|
if (!prs_io_uint8 (s, &tpkt->reserved))
|
|
return False;
|
|
|
|
if (!msb_io_uint16(s, &tpkt->length))
|
|
return False;
|
|
|
|
return True;
|
|
}
|
|
|
|
/* Initialise a TPDU structure */
|
|
void iso_make_tpdu(TPDU *tpdu, uint8 code)
|
|
{
|
|
tpdu->hlen = (code == ISO_PDU_DT) ? 2 : 6;
|
|
tpdu->code = code;
|
|
tpdu->dst_ref = tpdu->src_ref = 0;
|
|
tpdu->class = 0;
|
|
tpdu->eot = 0x80;
|
|
}
|
|
|
|
/* Marshall/demarshall a TPDU structure */
|
|
BOOL iso_io_tpdu(STREAM s, TPDU *tpdu)
|
|
{
|
|
BOOL res = True;
|
|
|
|
res = res ? prs_io_uint8 (s, &tpdu->hlen) : False;
|
|
res = res ? prs_io_uint8 (s, &tpdu->code) : False;
|
|
|
|
if (tpdu->code == ISO_PDU_DT)
|
|
{
|
|
res = res ? prs_io_uint8(s, &tpdu->eot) : False;
|
|
}
|
|
else
|
|
{
|
|
res = res ? msb_io_uint16(s, &tpdu->dst_ref) : False;
|
|
res = res ? msb_io_uint16(s, &tpdu->src_ref) : False;
|
|
res = res ? prs_io_uint8 (s, &tpdu->class ) : False;
|
|
}
|
|
|
|
return res;
|
|
}
|