2
rdesktop: A Remote Desktop Protocol client.
3
Stream parsing primitives
4
Copyright (C) Matthew Chapman 1999-2008
6
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
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
#if !(defined(L_ENDIAN) || defined(B_ENDIAN))
25
#warning no endian defined
31
unsigned char *p; /* current position */
32
unsigned char *end; /* end of stream */
33
unsigned char *data; /* pointer to stream-related mem.h-managed data */
34
unsigned int size; /* size of allocated data */
36
/* Saved positions for various layeres */
37
unsigned char *iso_hdr;
38
unsigned char *mcs_hdr;
39
unsigned char *sec_hdr;
40
unsigned char *rdp_hdr;
41
unsigned char *channel_hdr;
43
typedef struct stream *STREAM;
45
/* Save current pos for one encapsulation layer and skip forward */
46
#define s_push_layer(s,h,n) do { (s)->h = (s)->p; (s)->p += n; } while (0)
47
/* Restore pos for an encapsulation layer */
48
#define s_pop_layer(s,h) (s)->p = (s)->h
49
/* Mark that end of stream has been reached */
50
#define s_mark_end(s) (s)->end = (s)->p
52
/* True if end not reached
53
* FIXME: should be used more! */
54
#define s_check(s) ((s)->p <= (s)->end)
55
/* True if n more in stream
56
* FIXME: should be used! */
57
#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
58
/* True if exactly at end */
59
#define s_check_end(s) ((s)->p == (s)->end)
61
#if defined(L_ENDIAN) && !defined(NEED_ALIGN)
62
/* Direct LE parsing */
63
/* Read uint16 from stream and assign to v */
64
#define in_uint16_le(s,v) do { v = *(uint16 *)((s)->p); (s)->p += 2; } while (0)
65
/* Read uint32 from stream and assign to v */
66
#define in_uint32_le(s,v) do { v = *(uint32 *)((s)->p); (s)->p += 4; } while (0)
67
/* Write uint16 in v to stream */
68
#define out_uint16_le(s,v) do { *(uint16 *)((s)->p) = v; (s)->p += 2; } while (0)
69
/* Write uint32 in v to stream */
70
#define out_uint32_le(s,v) do { *(uint32 *)((s)->p) = v; (s)->p += 4; } while (0)
73
/* Byte-oriented LE parsing */
74
#define in_uint16_le(s,v) do { v = *((s)->p++); v += *((s)->p++) << 8; } while (0)
75
#define in_uint32_le(s,v) do { in_uint16_le(s,v); \
76
v += *((s)->p++) << 16; v += *((s)->p++) << 24; } while (0)
77
#define out_uint16_le(s,v) do { *((s)->p++) = (v) & 0xff; *((s)->p++) = ((v) >> 8) & 0xff; } while (0)
78
#define out_uint32_le(s,v) do { out_uint16_le(s, (v) & 0xffff); out_uint16_le(s, ((v) >> 16) & 0xffff); } while (0)
81
#if defined(B_ENDIAN) && !defined(NEED_ALIGN)
82
/* Direct BE parsing */
83
#define in_uint16_be(s,v) do { v = *(uint16 *)((s)->p); (s)->p += 2; } while (0)
84
#define in_uint32_be(s,v) do { v = *(uint32 *)((s)->p); (s)->p += 4; } while (0)
85
#define out_uint16_be(s,v) do { *(uint16 *)((s)->p) = v; (s)->p += 2; } while (0)
86
#define out_uint32_be(s,v) do { *(uint32 *)((s)->p) = v; (s)->p += 4; } while (0)
89
/* Byte-oriented BE parsing */
90
#define in_uint16_be(s,v) do { v = *((s)->p++); next_be(s,v); } while (0)
91
#define in_uint32_be(s,v) do { in_uint16_be(s,v); next_be(s,v); next_be(s,v); } while (0)
92
#define out_uint16_be(s,v) do { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; } while (0)
93
#define out_uint32_be(s,v) do { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); } while (0)
96
/* Read uint8 from stream and assign to v */
97
#define in_uint8(s,v) v = *((s)->p++)
98
/* Let v point to data at current pos and skip n */
99
#define in_uint8p(s,v,n) do { v = (s)->p; (s)->p += n; } while (0)
100
/* Copy n bytes from current pos to *v and skip n */
101
#define in_uint8a(s,v,n) do { memcpy(v,(s)->p,n); (s)->p += n; } while (0)
103
#define in_uint8s(s,n) (s)->p += n
104
/* Write uint8 in v to stream */
105
#define out_uint8(s,v) *((s)->p++) = v
106
/* Copy n bytes from *v to stream */
107
#define out_uint8p(s,v,n) do { memcpy((s)->p,v,n); (s)->p += n; } while (0)
108
/* Copy n bytes from *v to stream */
109
#define out_uint8a(s,v,n) out_uint8p(s,v,n)
110
/* Output n bytes zero to stream */
111
#define out_uint8s(s,n) do { memset((s)->p,0,n); (s)->p += n; } while (0)
113
/* Shift old v value and read new LSByte */
114
#define next_be(s,v) v = ((v) << 8) + *((s)->p++)
116
#endif /* __STREAM_H */