#include "rdp.h" /* TPDUs over stream protocols like TCP are prepended with TPKT to delimit message boundaries -- T.123 clause 8; RFC 1006. */ int readtpdu(int fd, void *abuf, uint n) { int m, mgc, len; uchar *buf; buf = abuf; /* read TPKT header */ m = readn(fd, buf, TPKTFIXLEN); if(m != TPKTFIXLEN) return -1; mgc = GBIT8(buf); /* 0x03 octet; followed one is reserved */ if(mgc != 0x03) return -1; len = GBE16(buf+BIT8SZ+BIT8SZ); if(len <= TPKTFIXLEN || len > n){ werrstr("bad length in TPKT header: %d", len); return -1; } len -= TPKTFIXLEN; m = readn(fd, buf+TPKTFIXLEN, len); if(m < len) return 0; return m +TPKTFIXLEN; }; /* fixme: the following two are incosistent in what they do return */ int mktpcr(uchar* buf, int nbuf, int ndata) /* connect request */ { int size; uchar *p; p = buf; size = TPKTFIXLEN + 2*BIT8SZ + 2*BIT16SZ + 1*BIT8SZ + ndata; if(size > nbuf){ werrstr("buffer too small"); return -1; } /* format TPKT header */ PBIT8(p, 0x03); /* 0x03 octet */; p += BIT8SZ; PBIT8(p, 0); /* reserved */ p += BIT8SZ; PBE16(p, size); p += BIT16SZ; PBIT8(p, size - TPKTFIXLEN - BIT8SZ); /* length indicator */ p += BIT8SZ; PBIT8(p, TPDUCR); /* TPDU code */ p += BIT8SZ; PBE16(p, 0); /* DST-REF */ p += BIT16SZ; PBE16(p, 0); /* SRC-REF */ p += BIT16SZ; PBIT8(p, 0); /* CLASS OPTION: class 0 */ p += BIT8SZ; USED(p); return size; } int mktpdata(uchar* buf, int nbuf, int ndata) /* data transfer */ { int size; uchar *p; p = buf; size = TPDATAFIXLEN + ndata; if(size > nbuf){ werrstr("buffer too small"); return -1; } /* format TPKT header */ PBIT8(p, 0x03); /* 0x03 octet */; p += BIT8SZ; PBIT8(p, 0); /* reserved */ p += BIT8SZ; PBE16(p, size); p += BIT16SZ; PBIT8(p, 2*BIT8SZ); /* length indicator */ p += BIT8SZ; PBIT8(p, TPDUDT); /* TPDU code */ p += BIT8SZ; PBIT8(p, 0x80); /* TPDU send sequence number (0 in Class 0) + EOT mark (1<<7) */ return TPDATAFIXLEN; }