--- sourceforge.net/branches/RDESKTOP/rdesktop/iso.c 2000/05/10 07:36:34 3 +++ sourceforge.net/trunk/rdesktop/iso.c 2002/09/24 07:59:14 192 @@ -1,7 +1,7 @@ /* rdesktop: A Remote Desktop Protocol client. Protocol services - ISO layer - Copyright (C) Matthew Chapman 1999-2000 + Copyright (C) Matthew Chapman 1999-2001 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 @@ -18,157 +18,149 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "includes.h" +#include "rdesktop.h" -/* Establish a connection up to the ISO layer */ -HCONN iso_connect(char *server) +/* Send a self-contained ISO PDU */ +static void +iso_send_msg(uint8 code) { - HCONN conn; - uint8 code; + STREAM s; - if ((conn = tcp_connect(server)) == NULL) - return NULL; + s = tcp_init(11); + + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* reserved */ + out_uint16_be(s, 11); /* length */ + + out_uint8(s, 6); /* hdrlen */ + out_uint8(s, code); + out_uint16(s, 0); /* dst_ref */ + out_uint16(s, 0); /* src_ref */ + out_uint8(s, 0); /* class */ + + s_mark_end(s); + tcp_send(s); +} - iso_send_msg(conn, ISO_PDU_CR); +/* Receive a message on the ISO layer, return code */ +static STREAM +iso_recv_msg(uint8 * code) +{ + STREAM s; + uint16 length; + uint8 version; + + s = tcp_recv(4); + if (s == NULL) + return NULL; - if (!iso_recv_msg(conn, &code) || (code != ISO_PDU_CC)) + in_uint8(s, version); + if (version != 3) { - fprintf(stderr, "ISO error, expected CC\n"); - tcp_disconnect(conn); + error("TPKT v%d\n", version); return NULL; } - return conn; -} + in_uint8s(s, 1); /* pad */ + in_uint16_be(s, length); -/* Disconnect from the ISO layer */ -void iso_disconnect(HCONN conn) -{ - iso_send_msg(conn, ISO_PDU_DR); - tcp_disconnect(conn); -} + s = tcp_recv(length - 4); + if (s == NULL) + return NULL; -/* Send self-contained ISO message identified by code */ -BOOL iso_send_msg(HCONN conn, uint8 code) -{ - TPKT tpkt; - TPDU tpdu; + in_uint8s(s, 1); /* hdrlen */ + in_uint8(s, *code); - 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); + if (*code == ISO_PDU_DT) + { + in_uint8s(s, 1); /* eot */ + return s; + } + + in_uint8s(s, 5); /* dst_ref, src_ref, class */ + return s; } -/* Receive a message on the ISO layer, return code */ -BOOL iso_recv_msg(HCONN conn, uint8 *code) +/* Initialise ISO transport data packet */ +STREAM +iso_init(int length) { - 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; + STREAM s; + + s = tcp_init(length + 7); + s_push_layer(s, iso_hdr, 7); - *code = tpdu.code; - return res; + return s; } -/* Initialise ISO transport data packet */ -void iso_init(struct connection *conn) +/* Send an ISO data PDU */ +void +iso_send(STREAM s) { - PUSH_LAYER(conn->out, iso_offset, 7); + uint16 length; + + s_pop_layer(s, iso_hdr); + length = s->end - s->p; + + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* reserved */ + out_uint16_be(s, length); + + out_uint8(s, 2); /* hdrlen */ + out_uint8(s, ISO_PDU_DT); /* code */ + out_uint8(s, 0x80); /* eot */ + + tcp_send(s); } /* Receive ISO transport data packet */ -BOOL iso_recv(HCONN conn) +STREAM +iso_recv(void) { + STREAM s; uint8 code; - if (!iso_recv_msg(conn, &code) || (code != ISO_PDU_DT)) + s = iso_recv_msg(&code); + if (s == NULL) + return NULL; + + if (code != ISO_PDU_DT) { - fprintf(stderr, "ISO error, expected DT\n"); - return False; + error("expected DT, got 0x%x\n", code); + return NULL; } - return True; + return s; } -/* Receive ISO transport data packet */ -BOOL iso_send(HCONN conn) +/* Establish a connection up to the ISO layer */ +BOOL +iso_connect(char *server) { - TPKT tpkt; - TPDU tpdu; + uint8 code; - 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); -} + if (!tcp_connect(server)) + return False; -/* Initialise a TPKT structure */ -void iso_make_tpkt(TPKT *tpkt, int length) -{ - tpkt->version = 3; - tpkt->reserved = 0; - tpkt->length = length; -} + iso_send_msg(ISO_PDU_CR); -/* Marshall/demarshall a TPKT structure */ -BOOL iso_io_tpkt(STREAM s, TPKT *tpkt) -{ - if (!prs_io_uint8(s, &tpkt->version)) + if (iso_recv_msg(&code) == NULL) return False; - if (tpkt->version != 3) + if (code != ISO_PDU_CC) { - fprintf(stderr, "Wrong TPKT version %d\n", tpkt->version); + error("expected CC, got 0x%x\n", code); + tcp_disconnect(); 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) +/* Disconnect from the ISO layer */ +void +iso_disconnect(void) { - 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; + iso_send_msg(ISO_PDU_DR); + tcp_disconnect(); }