/[rdesktop]/sourceforge.net/trunk/rdesktop/iso.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/iso.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 9 by matty, Tue Jul 25 12:34:29 2000 UTC revision 347 by forsberg, Thu Mar 27 13:11:58 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - ISO layer     Protocol services - ISO layer
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2002
5        
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "includes.h"  #include "rdesktop.h"
22    
23  /* Establish a connection up to the ISO layer */  /* Send a self-contained ISO PDU */
24  HCONN iso_connect(char *server)  static void
25    iso_send_msg(uint8 code)
26  {  {
27          HCONN conn;          STREAM s;
         uint8 code;  
28    
29          if ((conn = tcp_connect(server)) == NULL)          s = tcp_init(11);
                 return NULL;  
30    
31          iso_send_msg(conn, ISO_PDU_CR);          out_uint8(s, 3);        /* version */
32            out_uint8(s, 0);        /* reserved */
33            out_uint16_be(s, 11);   /* length */
34    
35          if (!iso_recv_msg(conn, &code) || (code != ISO_PDU_CC))          out_uint8(s, 6);        /* hdrlen */
36          {          out_uint8(s, code);
37                  ERROR("ISO error, expected CC\n");          out_uint16(s, 0);       /* dst_ref */
38                  tcp_disconnect(conn);          out_uint16(s, 0);       /* src_ref */
39                  return NULL;          out_uint8(s, 0);        /* class */
         }  
40    
41          return conn;          s_mark_end(s);
42            tcp_send(s);
43  }  }
44    
45  /* Disconnect from the ISO layer */  static void
46  void iso_disconnect(HCONN conn)  iso_send_connection_request(char *username)
47  {  {
48          iso_send_msg(conn, ISO_PDU_DR);          STREAM s;
49          tcp_disconnect(conn);          int length = 30 + strlen(username);
 }  
50    
51  /* Send self-contained ISO message identified by code */          s = tcp_init(length);
52  BOOL iso_send_msg(HCONN conn, uint8 code)  
53  {          out_uint8(s, 3);        /* version */
54          TPKT tpkt;          out_uint8(s, 0);        /* reserved */
55          TPDU tpdu;          out_uint16_be(s, length);       /* length */
56    
57            out_uint8(s, length - 5);       /* hdrlen */
58            out_uint8(s, ISO_PDU_CR);
59            out_uint16(s, 0);       /* dst_ref */
60            out_uint16(s, 0);       /* src_ref */
61            out_uint8(s, 0);        /* class */
62    
63            out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
64            out_uint8p(s, username, strlen(username));
65    
66          iso_make_tpkt(&tpkt, 11);          out_uint8(s, 0x0d);     /* Unknown */
67          iso_io_tpkt(&conn->out, &tpkt);          out_uint8(s, 0x0a);     /* Unknown */
68          iso_make_tpdu(&tpdu, code);  
69          iso_io_tpdu(&conn->out, &tpdu);          s_mark_end(s);
70          MARK_END(conn->out);          tcp_send(s);
         return tcp_send(conn);  
71  }  }
72    
73  /* Receive a message on the ISO layer, return code */  /* Receive a message on the ISO layer, return code */
74  BOOL iso_recv_msg(HCONN conn, uint8 *code)  static STREAM
75    iso_recv_msg(uint8 * code)
76  {  {
77          TPDU tpdu;          STREAM s;
78          TPKT tpkt;          uint16 length;
79          BOOL res;          uint8 version;
80            BOOL shortform = False; // Shut the compiler up.
81          res = tcp_recv(conn, 4);  
82          res = res ? iso_io_tpkt(&conn->in, &tpkt) : False;        next_packet:
83          res = res ? tcp_recv(conn, tpkt.length - 4) : False;          s = tcp_recv(4);
84          res = res ? iso_io_tpdu(&conn->in, &tpdu) : False;          if (s == NULL)
85                    return NULL;
86    
87          *code = tpdu.code;          in_uint8(s, version);
88          return res;          switch (version & 3)
89  }          {
90                    case 0:
91                            in_uint8(s, length);
92                            if (length & 0x80)
93                            {
94                                    length &= ~0x80;
95                                    next_be(s, length);
96                                    shortform = False;
97                            }
98                            else
99                            {
100                                    shortform = True;
101                            }
102                            break;
103    
104                    case 3:
105                            in_uint8s(s, 1);        /* pad */
106                            in_uint16_be(s, length);
107                            break;
108    
109                    default:
110                            error("TPKT v%d\n", version);
111                            return NULL;
112            }
113    
114  /* Initialise ISO transport data packet */          s = tcp_recv(length - 4);
115  void iso_init(struct connection *conn)          if (s == NULL)
116  {                  return NULL;
         PUSH_LAYER(conn->out, iso_offset, 7);  
 }  
117    
118  /* Receive ISO transport data packet */          if ((version & 3) == 0)
119  BOOL iso_recv(HCONN conn)          {
120  {                  rdp5_process(s, version & 0x80, shortform);
121          uint8 code;                  goto next_packet;
122            }
123    
124          if (!iso_recv_msg(conn, &code) || (code != ISO_PDU_DT))          in_uint8s(s, 1);        /* hdrlen */
125            in_uint8(s, *code);
126    
127            if (*code == ISO_PDU_DT)
128          {          {
129                  ERROR("ISO error, expected DT\n");                  in_uint8s(s, 1);        /* eot */
130                  return False;                  return s;
131          }          }
132    
133          return True;          in_uint8s(s, 5);        /* dst_ref, src_ref, class */
134            return s;
135  }  }
136    
137  /* Receive ISO transport data packet */  /* Initialise ISO transport data packet */
138  BOOL iso_send(HCONN conn)  STREAM
139    iso_init(int length)
140  {  {
141          TPKT tpkt;          STREAM s;
         TPDU tpdu;  
142    
143          POP_LAYER(conn->out, iso_offset);          s = tcp_init(length + 7);
144          iso_make_tpkt(&tpkt, conn->out.end);          s_push_layer(s, iso_hdr, 7);
         iso_io_tpkt(&conn->out, &tpkt);  
         iso_make_tpdu(&tpdu, ISO_PDU_DT);  
         iso_io_tpdu(&conn->out, &tpdu);  
         return tcp_send(conn);  
 }  
145    
146  /* Initialise a TPKT structure */          return s;
 void iso_make_tpkt(TPKT *tpkt, int length)  
 {  
         tpkt->version = 3;  
         tpkt->reserved = 0;  
         tpkt->length = length;  
147  }  }
148    
149  /* Marshall/demarshall a TPKT structure */  /* Send an ISO data PDU */
150  BOOL iso_io_tpkt(STREAM s, TPKT *tpkt)  void
151    iso_send(STREAM s)
152  {  {
153          if (!prs_io_uint8(s, &tpkt->version))          uint16 length;
                 return False;  
154    
155          if (tpkt->version != 3)          s_pop_layer(s, iso_hdr);
156          {          length = s->end - s->p;
                 ERROR("Wrong TPKT version %d\n", tpkt->version);  
                 return False;  
         }  
157    
158          if (!prs_io_uint8 (s, &tpkt->reserved))          out_uint8(s, 3);        /* version */
159                  return False;          out_uint8(s, 0);        /* reserved */
160            out_uint16_be(s, length);
161    
162          if (!msb_io_uint16(s, &tpkt->length))          out_uint8(s, 2);        /* hdrlen */
163                  return False;          out_uint8(s, ISO_PDU_DT);       /* code */
164            out_uint8(s, 0x80);     /* eot */
165    
166          return True;          tcp_send(s);
167  }  }
168    
169  /* Initialise a TPDU structure */  /* Receive ISO transport data packet */
170  void iso_make_tpdu(TPDU *tpdu, uint8 code)  STREAM
171    iso_recv(void)
172  {  {
173          tpdu->hlen = (code == ISO_PDU_DT) ? 2 : 6;          STREAM s;
174          tpdu->code = code;          uint8 code;
175          tpdu->dst_ref = tpdu->src_ref = 0;  
176          tpdu->class = 0;          s = iso_recv_msg(&code);
177          tpdu->eot = 0x80;          if (s == NULL)
178                    return NULL;
179    
180            if (code != ISO_PDU_DT)
181            {
182                    error("expected DT, got 0x%x\n", code);
183                    return NULL;
184            }
185    
186            return s;
187  }  }
188    
189  /* Marshall/demarshall a TPDU structure */  /* Establish a connection up to the ISO layer */
190  BOOL iso_io_tpdu(STREAM s, TPDU *tpdu)  BOOL
191    iso_connect(char *server, char *username)
192  {  {
193          BOOL res = True;          uint8 code;
194    
195            if (!tcp_connect(server))
196                    return False;
197    
198          res = res ? prs_io_uint8 (s, &tpdu->hlen) : False;          iso_send_connection_request(username);
         res = res ? prs_io_uint8 (s, &tpdu->code) : False;  
199    
200          if (tpdu->code == ISO_PDU_DT)          if (iso_recv_msg(&code) == NULL)
201          {                  return False;
202                  res = res ? prs_io_uint8(s, &tpdu->eot) : False;  
203          }          if (code != ISO_PDU_CC)
         else  
204          {          {
205                  res = res ? msb_io_uint16(s, &tpdu->dst_ref) : False;                  error("expected CC, got 0x%x\n", code);
206                  res = res ? msb_io_uint16(s, &tpdu->src_ref) : False;                  tcp_disconnect();
207                  res = res ? prs_io_uint8 (s, &tpdu->class  ) : False;                  return False;
208          }          }
209    
210          return res;          return True;
211    }
212    
213    /* Disconnect from the ISO layer */
214    void
215    iso_disconnect(void)
216    {
217            iso_send_msg(ISO_PDU_DR);
218            tcp_disconnect();
219  }  }

Legend:
Removed from v.9  
changed lines
  Added in v.347

  ViewVC Help
Powered by ViewVC 1.1.26