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

Annotation of /jpeg/rdpproxy/trunk/pparser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 429 - (hide annotations)
Mon Jun 30 08:59:07 2003 UTC (20 years, 10 months ago) by forsberg
Original Path: sourceforge.net/branches/CHAPMAN_AND_FORSBERG/rdpproxy/pparser.py
File MIME type: text/x-python
File size: 105836 byte(s)
Initial import to SF.net

1 forsberg 429 #!/usr/bin/env python2
2    
3     import string
4     import getopt
5     import sys
6     import time
7     import re
8     import POW
9     import struct
10     import os
11    
12     from keymap import keymap
13    
14     keys = keymap("keymaps", 'sv')
15     currentchannel = 0
16    
17     rdp_channel_flags = [(0x80000000, "OPTION_INITIALIZED"),
18     (1073741824, "OPTION_ENCRYPT_RDP"),
19     (536870912, "OPTION_ENCRYPT_SC"),
20     (268435456, "OPTION_ENCRYPT_CS"),
21     (134217728, "OPTION_PRI_HIGH"),
22     (67108864, "OPTION_PRI_MED"),
23     (33554432, "OPTION_PRI_LOW"),
24     (8388608, "OPTION_COMPRESS_RDP"),
25     (4194304, "OPTION_COMPRESS"),
26     (2097152, "OPTION_SHOW_PROTOCOL")]
27    
28     rdp_channels = {}
29    
30     def LaTeX_escape(s):
31     s = s.replace("#", "\\#")
32     s = s.replace("_", "\\_")
33     return s
34    
35     class PacketPart:
36     BER_TAGS = {'BOOLEAN':1,
37     'INTEGER':2,
38     'OCTET_STRING':4,
39     'TAG_RESULT':10,
40     'DOMAIN_PARAMS':0x30,
41     'CONN_INITIAL':0x7f65,
42     'CONN_RESPONSE':0x7f66}
43    
44     classname = "PacketPart"
45    
46     def __init__(self, description, knvalue=None, indent=0, **kw):
47     self.description = description
48     self.owntbl = 1
49     self.knvalue = knvalue
50     self.indent = indent
51     self.datatype = "[unknown type]"
52     self.value = []
53     self.raw = 0
54     self.maxlength = 0
55    
56     if kw.has_key('maxlength'):
57     self.maxlength = kw['maxlength']
58     else:
59     self.maxlength = None
60    
61     def __len__(self):
62     ret = 0
63     for p in self.value:
64     ret+=len(p)
65     return ret
66    
67     def strvalue(self):
68     if 0 == len(self.value):
69     return "[no value]"
70     else:
71     ret = "\n"+" "*self.indent
72     ret+=string.join(map(lambda x: str(x),
73     self.value),
74     "\n"+" "*self.indent)
75     return ret
76    
77     def tblvalue(self, **kw):
78     s = "%s\t%s\t" % (self.datatype,
79     self.description)
80     if None != self.knvalue:
81     s+=str(self.knvalue)
82     s+="\t%s\t" % self.strvalue()
83     return s
84    
85     def latexvalue(self, **kw):
86     s = "%s & %s &" % (self.datatype, self.description)
87     if None != self.knvalue:
88     s+=str(self.knvalue)
89     s+="& %s \\\\ \n" % self.strvalue()
90     return s
91    
92     def __str__(self):
93     ret = " "*self.indent+self.datatype+" "+self.description+" "
94     if None != self.knvalue:
95     ret+="(expected: "+str(self.knvalue)+") "
96     if self.raw:
97     ret+=" RAW DATA (length 0x%.2x (%d))" % (self.rawlength,
98     self.rawlength)
99     return ret+self.strvalue()
100    
101     def hextostr(self, data, fill=1):
102     ret = ""
103     if fill and len(data) < 16:
104     ret+=(16-len(data))*" "
105     for c in data:
106     if c >= 0x20 and c < 0x7f:
107     ret+=chr(c)
108     else:
109     ret+="."
110     return ret
111    
112     def packtobytestring(self, data):
113     ret = ""
114     for byte in data:
115     ret+=struct.pack('B', byte)
116     return ret
117    
118     def parse(self, data):
119     """Parse the packet value into a human readable form.
120     In PacketPart (top-level class), we just eat the bytes and
121     present it as a hexdump, as a last resort"""
122    
123     returndata = []
124     if None != self.maxlength:
125     returndata = data[self.maxlength:]
126     data = data[:self.maxlength]
127    
128     self.raw = 1
129     self.rawlength = len(data)
130    
131     while 0 < len(data):
132     hl = HexLine("")
133     data = hl.parse(data)
134     self.value.append(hl)
135    
136     return returndata
137    
138     def postparse(self, data):
139     return data
140    
141     def preparse(self, data):
142     return data
143    
144     def ppparse(self, data):
145     return self.postparse(self.parse(self.preparse(data)))
146    
147     class CryptoSignature(PacketPart):
148     def __init__(self, description, **kw):
149     PacketPart.__init__(self, description, **kw)
150     self.owntbl = 0
151    
152     def latexvalue(self, **kw):
153     return "RAW & Crypto signature & & 8 bytes of data\\\\"
154    
155     class HexLine(PacketPart):
156    
157     classname = "HexLine"
158    
159     def __init__(self, description, **kw):
160     PacketPart.__init__(self, description, **kw)
161     self.datatype="RAW"
162     self.owntbl = 0
163    
164     def parse(self, data):
165     self.value = data[:16]
166     return data[16:]
167    
168     def strvalue(self):
169     datap = map(lambda x: "%.2x" % x, self.value)
170     return string.join(datap, ' ')+" "+self.hextostr(self.value)
171    
172     def tblvalue(self, **kw):
173     return "RAW\t%s\t\t%s\t%s" % (self.description, string.join(
174     map(lambda x: "%.2x" % x, self.value), " "),
175     self.hextostr(self.value, fill=0))
176    
177     def tblvalue(self, **kw):
178     return "RAW & %s& & %s & %s \\\n" % (self.description, string.join(
179     map(lambda x: "%.2x" % x, self.value), " "),
180     self.hextostr(self.value, fill=0))
181    
182    
183    
184    
185     def __len__(self):
186     return len(self.value)
187    
188    
189     class Integer8Part(PacketPart):
190    
191     classname = "Integer8Part"
192    
193     def __init__(self, description, **kw):
194     PacketPart.__init__(self, description, **kw)
195     self.datatype="Int8 (be)"
196     self.value = -1
197     self.owntbl = 0
198    
199     def __len__(self):
200     return 1
201    
202     def strvalue(self):
203     return "0x%.2x (%d)" % (self.value, self.value)
204    
205     def parse(self, data):
206     self.value = data[0]
207     return data[1:]
208    
209     class Integer16Part(Integer8Part):
210    
211     classname = "Integer16Part"
212    
213     def __init__(self, description, **kw):
214     Integer8Part.__init__(self, description, **kw)
215     self.datatype="Int16 (be)"
216    
217     def __len__(self):
218     return 2
219    
220     def strvalue(self):
221     return "0x%.4x (%d)" % (self.value, self.value)
222    
223     def parse(self, data):
224     try:
225     self.value = string.atoi(string.join(map(lambda x: "%.2x" % x,
226     data[0:2]), ''), 16)
227     except ValueError:
228     print "Exception while parsing %s:" % self.description
229     raise
230     return data[2:]
231    
232     class Integer16or8000Part(Integer16Part):
233    
234     classname = "Integer16or8000Part"
235    
236     def parse(self, data):
237     data = Integer16Part.parse(self, data)
238     self.value = self.value & ~0x8000
239     self.datatype = "Int16 (be) | 0x8000"
240     return data
241    
242     class Integer16lePart(Integer16Part):
243    
244     classname = "Integer16lePart"
245    
246     def __init__(self, description, **kw):
247     Integer8Part.__init__(self, description, **kw)
248     self.datatype="Int16 (le)"
249    
250     def parse(self, data):
251     mydata = data[0:2]
252     mydata.reverse()
253     Integer16Part.parse(self, mydata)
254     return data[2:]
255    
256     class Integer32Part(Integer8Part):
257    
258     classname = "Integer32Part"
259    
260     def __init__(self, description, **kw):
261     Integer8Part.__init__(self, description, **kw)
262     self.datatype="Int32 (be)"
263    
264     def __len__(self):
265     return 4
266    
267     def strvalue(self):
268     return "0x%.8x (%d)" % (self.value, self.value)
269    
270     def parse(self, data):
271     valstr = string.join(map(lambda x: "%.2x" % x, data[:4]), '')
272     try:
273     self.value = string.atoi(valstr, 16)
274     except ValueError:
275     self.value = string.atol(valstr, 16)
276     return data[4:]
277    
278     class Integer32lePart(Integer32Part):
279    
280     classname = "Integer32lePart"
281    
282     def __init__(self, description, **kw):
283     Integer32Part.__init__(self, description, **kw)
284     self.datatype="Int32 (le)"
285    
286     def parse(self, data):
287     mydata = data[0:4]
288     mydata.reverse()
289     Integer32Part.parse(self, mydata)
290     return data[4:]
291    
292     class Time32le(Integer32lePart):
293    
294     classname = "Time32le"
295    
296     def __init__(self, description, **kw):
297     Integer32lePart.__init__(self, description, **kw)
298     self.datatype="Time"
299    
300     def strvalue(self):
301     return Integer32Part.strvalue(self)+\
302     " (%s)" % time.asctime(time.gmtime(self.value))
303    
304    
305     class VariableInt(PacketPart):
306    
307     classname = "VariableInt"
308    
309     def __init__(self, description, **kw):
310     PacketPart.__init__(self, description, **kw)
311     self.owntbl = 0
312    
313     def parse(self, data):
314     self.value = data[0]
315     data = data[1:]
316     self.datatype = "VariableInt(1)"
317     self.lengthbytes = 0
318     if self.value & 0x80:
319     self.lengthbytes = self.value & ~0x80
320     self.datatype = "VariableInt(%d)" % self.lengthbytes
321     self.value = string.atoi(string.join(map(lambda x: "%.2x" % x,
322     data[0:self.lengthbytes]),
323     ''), 16)
324     data = data[self.lengthbytes:]
325    
326     return data
327    
328     def __len__(self):
329     return self.lengthbytes+1
330    
331     def strvalue(self):
332     return "0x%.4x (%d)" % (self.value, self.value)
333    
334     class MSVariableInt(VariableInt):
335    
336     classname = "MSVariableInt"
337    
338     def parse(self, data):
339     self.value = data[0]
340     data = data[1:]
341     self.datatype = "MSVariableInt(1)"
342     self.lengthbytes = 1
343    
344     if self.value & 0x80:
345     self.lengthbytes = 2
346     lb = data[0]
347     data = data[1:]
348     self.value = ((self.value & ~0x80) << 8) | lb
349     self.datatype = "MSVariableInt(2)"
350    
351    
352     return data
353    
354     class KnownLengthInt(PacketPart):
355    
356     classname = "KnownLengthInt"
357    
358     def __init__(self, description, length, **kw):
359     PacketPart.__init__(self, description, **kw)
360     self.length = length
361     self.datatype = "KLIInt(%d)" % (8*length)
362     self.owntbl = 0
363    
364     def strvalue(self):
365     return "0x%.2x (%d)" % (self.value, self.value)
366    
367     def parse(self, data):
368     self.value = string.atoi(string.join(map(lambda x: "%.2x" % x,
369     data[0:self.length]),
370     ''), 16)
371     return data[self.length:]
372    
373     def __len__(self):
374     return self.length
375    
376    
377     class MultiTableValue(PacketPart):
378    
379     classname = "MultiTableValue"
380    
381     def tblvalue(self, offset=0):
382     s = "%s\n" % self.value[0].tblvalue(offset=offset)
383     offset+=len(self.value[0])
384     for part in self.value[1:-1]:
385     s+="%d\t%s\n" % (offset, part.tblvalue(offset=offset))
386     offset+=len(part)
387     s+="%d\t%s" % (offset, self.value[-1:][0].tblvalue(offset=offset))
388     return s
389    
390     def latexvalue(self, offset=0):
391     s = "%s\n" % self.value[0].latexvalue(offset=offset)
392     offset+=len(self.value[0])
393     for part in self.value[1:-1]:
394     s+="%d & %s\n" % (offset, part.latexvalue(offset=offset))
395     offset+=len(part)
396     s+="%d & %s\\\\" % (offset,
397     self.value[-1:][0].latexvalue(offset=offset))
398     return s
399    
400    
401     class BERHeader(PacketPart):
402    
403     classname = "BERHeader"
404    
405     def __init__(self, description, tag, **kw):
406     PacketPart.__init__(self, description, **kw)
407     self.tag = tag
408     self.owntbl = 0
409     self.taglen = 1
410    
411     def parse(self, data):
412     if self.tag > 0xff:
413     self.taglen = 2
414     self.realtag = string.atoi(string.join(map(lambda x: "%.2x" % x,
415     data[0:2]), ''), 16)
416    
417     self.datatype = "BER tag %d" % (self.realtag)
418    
419     if self.realtag != self.tag:
420     raise "Unexpected BER tag, "\
421     "got %s expected %s" % (str(self.value),
422     str(self.tag))
423    
424     data = data[2:]
425    
426     else:
427     self.realtag = data[0]
428    
429     self.datatype = "BER tag %d" % (self.realtag)
430    
431     if self.realtag != self.tag:
432     raise "Unexpected BER tag, "\
433     "got %s expected %s" % (str(self.value), str(self.tag))
434    
435     data = data[1:]
436    
437     length = VariableInt("BER length", indent=self.indent+1)
438     self.value.append(length)
439     return length.parse(data)
440    
441     def __len__(self):
442     return self.taglen + len(self.value[0])
443    
444     def tblvalue(self, offset=0):
445     s = "%s\t%s\t%s\t%s\n" % (self.datatype, self.description,
446     self.tag, self.realtag)
447     return s+"%d\t%s" % (offset+self.taglen,
448     self.value[0].tblvalue(offset=offset+self.taglen))
449    
450     def latexvalue(self, offset=0):
451     s = "%s & %s & %s & %s \\\\" % (self.datatype, self.description,
452     self.tag, self.realtag)
453     return s+"%d & %s" % (offset+self.taglen,
454     self.value[0].latexvalue(offset=offset+self.taglen))
455    
456    
457    
458    
459     class BERValue(MultiTableValue):
460    
461     classname = "BERValue"
462    
463     def __init__(self, description, bertype, **kw):
464     PacketPart.__init__(self, description, **kw)
465     self.bertype = bertype
466     self.owntbl = 0
467    
468     def parse(self, data):
469     hdr = BERHeader(self.bertype, self.BER_TAGS[self.bertype],
470     indent=self.indent+1)
471     self.value.append(hdr)
472     data = hdr.parse(data)
473    
474     self.datatype = "BER %s(%d)" % (self.bertype,
475     8*hdr.value[0].value)
476    
477    
478     kliint = KnownLengthInt(self.description + " Value",
479     hdr.value[0].value,
480     indent=self.indent+1)
481     self.value.append(kliint)
482     return kliint.parse(data)
483    
484    
485     class DomainParametersPacket(PacketPart):
486    
487     classname = "DomainParametersPacket"
488    
489     def __init__(self, description, **kw):
490     PacketPart.__init__(self, description, **kw)
491     self.datatype = "Domain Parameters"
492    
493     def parse(self, data):
494     domparam_initial_header = BERHeader(self.description,
495     self.BER_TAGS['DOMAIN_PARAMS'],
496     indent=self.indent)
497     self.value.append(domparam_initial_header)
498    
499     self.value.append(BERValue("Channels", 'INTEGER',
500     indent=self.indent+1))
501     self.value.append(BERValue("Users", 'INTEGER',
502     indent=self.indent+1))
503     self.value.append(BERValue("Tokens", 'INTEGER',
504     indent=self.indent+1))
505     self.value.append(BERValue("Priorities", 'INTEGER',
506     indent=self.indent+1))
507     self.value.append(BERValue("Throughput", 'INTEGER',
508     indent=self.indent+1))
509     self.value.append(BERValue("Height", 'INTEGER', indent=self.indent+1))
510     self.value.append(BERValue("PDUsize", 'INTEGER', indent=self.indent+1))
511     self.value.append(BERValue("Protocol", 'INTEGER',
512     indent=self.indent+1))
513    
514     for dp in self.value:
515     data = dp.parse(data)
516    
517     return data
518    
519     class Latin1String(PacketPart):
520     classname = "Latin1String"
521    
522     def __init__(self, description, length, **kw):
523     PacketPart.__init__(self, description, **kw)
524     self.havenullchar=1
525     if kw.has_key("nonullchar"):
526     self.havenullchar=0
527     self.datatype = "Latin1 String(%d" % length
528     if self.havenullchar:
529     self.datatype+=" + nullchar)"
530     else:
531     self.datatype+=")"
532     self.length = length
533     self.owntbl = 0
534    
535    
536    
537     def __len__(self):
538     return self.length + self.havenullchar
539    
540     def strvalue(self):
541     return self.value
542    
543     def parse(self, data):
544     self.value = ""
545     mydata = data[0:self.length]
546     for char in mydata:
547     if char != 0:
548     self.value+=(chr(char))
549    
550     return data[self.length+self.havenullchar:]
551    
552     class UnicodeString(PacketPart):
553    
554     classname = "UnicodeString"
555    
556     def __init__(self, description, length, **kw):
557     PacketPart.__init__(self, description, **kw)
558     self.datatype = "Unicode string(%d)" % length
559     self.length = length
560     self.owntbl = 0
561    
562     def __len__(self):
563     return self.length
564    
565     def strvalue(self):
566     return self.value
567    
568     def parse(self, data):
569     self.value = ""
570     mydata = data[0:2*self.length]
571     while 0 < len(mydata):
572     thischr = mydata[0:2]
573     thischr.reverse()
574     val = string.atoi(string.join(map(lambda x: "%.2x" % x,
575     thischr), ''), 16)
576     if val in range(1, 256):
577     self.value+=unichr(val).encode('latin-1')
578     elif 0 == val:
579     self.value+="."
580     else:
581     self.value+="§"
582     mydata = mydata[2:]
583    
584     return data[2*self.length:]
585    
586     class ColorDepthInfo(Integer16lePart):
587    
588     classname = "ColorDepthInfo"
589    
590     depths = {0xca01:'8',
591     0xca02:'15',
592     0xca03:'16',
593     0xca04:'24'}
594    
595     def __init__(self, description, **kw):
596     Integer16lePart.__init__(self, description, **kw)
597     self.datatype = "ColorDepth (Int16 (le))"
598    
599     def strvalue(self):
600     return Integer16lePart.strvalue(self) + "(%s bits depth)" % self.depths.get(self.value, "Unknown")
601    
602    
603     class UserdataClientinfoPacket(PacketPart):
604    
605     classname = "UserdataClientinfoPacket"
606    
607     def __init__(self, description, **kw):
608     PacketPart.__init__(self, description, **kw)
609     self.datatype = "MCS userdata/clientinfo"
610    
611     def parse(self, data):
612     clinfotag = Integer16lePart("Client info tag", knvalue=0xc001,
613     indent=self.indent)
614     self.value.append(clinfotag)
615     data = clinfotag.parse(data)
616    
617     if clinfotag.value != 0xc001:
618     raise "Expected Client info (tagged by 0xc001), got %d" % clinfotag.value
619    
620     clinfolen = Integer16lePart("Client info length",
621     knvalue="136 in rdesktop, "\
622     "%d bytes remaining" % (len(data)-2),
623     indent=self.indent)
624     self.value.append(clinfolen)
625     data = clinfolen.parse(data)
626    
627     clinfodata = data[:clinfolen.value-4]
628    
629     self.value.append(Integer16lePart("RDP version",
630     knvalue="0x0001 for RDP4, "\
631     "0x0004 for RDP5",
632     indent=self.indent))
633     self.value.append(Integer16lePart("", knvalue=0x0008,
634     indent=self.indent))
635     self.value.append(Integer16lePart("Width",
636     indent=self.indent))
637     self.value.append(Integer16lePart("Height",
638     indent=self.indent))
639     self.value.append(Integer16lePart("", knvalue=0xca01,
640     indent=self.indent))
641     self.value.append(Integer16lePart("", knvalue=0xaa03,
642     indent=self.indent))
643     self.value.append(Integer32lePart("Keylayout",
644     indent=self.indent))
645     self.value.append(Integer32lePart("Client build",
646     indent=self.indent))
647     self.value.append(UnicodeString("Hostname", 16,
648     indent=self.indent))
649     self.value.append(Integer32lePart("", knvalue=0x00000004,
650     indent=self.indent))
651     self.value.append(Integer32lePart("", knvalue=0x00000000,
652     indent=self.indent))
653     self.value.append(Integer32lePart("", knvalue=0x0000000c,
654     indent=self.indent))
655    
656     valuelen = len(self.value)
657    
658     for dp in self.value[2:]:
659     clinfodata = dp.parse(clinfodata)
660    
661     reserved_data = PacketPart("Reserved data", indent=self.indent)
662     self.value.append(reserved_data)
663     reserved_data.parse(clinfodata[:64])
664     valuelen+=1
665    
666     clinfodata = clinfodata[64:]
667    
668     self.value.append(ColorDepthInfo("(client)", indent=self.indent))
669    
670     self.value.append(Integer16lePart("", knvalue=0x0000,
671     indent=self.indent))
672    
673     self.value.append(PacketPart("Remaining client data",
674     indent=self.indent))
675    
676     for dp in self.value[valuelen:]:
677     clinfodata = dp.parse(clinfodata)
678    
679     return data[clinfolen.value-4:]
680    
681     class CertificatePart(PacketPart):
682    
683     classname = "CertificatePart"
684    
685     def __init__(self, description, **kw):
686     PacketPart.__init__(self, description, **kw)
687     self.datatype = "Certificate"
688    
689     def parse(self, data):
690     returndata = []
691     if None != self.maxlength:
692     returndata = data[self.maxlength:]
693     data = data[:self.maxlength]
694    
695     strcert = self.packtobytestring(data)
696     x = POW.derRead(POW.X509_CERTIFICATE, strcert)
697     self.value = [x.pprint().replace("\\x00", "")]
698    
699     return returndata
700    
701     def latexvalue(self, **kw):
702     return "\\begin{verbatim}\n%s\n\\end{verbatim}" % self.value
703    
704     class MCSResponseCryptinfoPacket(PacketPart):
705    
706     classname = "MCSResponseCryptinfoPacket"
707    
708     def __init__(self, description, **kw):
709     PacketPart.__init__(self, description, **kw)
710     self.datatype = "MCS response userdata cryptinfo"
711    
712     def parse(self, data):
713     self.value.append(Integer32lePart("RC4 key size", indent=self.indent,
714     knvalue="1/40 bit, 2/128 bit"))
715     self.value.append(Integer32lePart("Encryption level",
716     indent=self.indent,
717     knvalue="0/None, 1/Low, 2/Med, 3/High"))
718     randsaltlen = Integer32lePart("Random salt len",
719     indent=self.indent,
720     knvalue=0x20)
721     self.value.append(randsaltlen)
722    
723     for dp in self.value:
724     data = dp.parse(data)
725    
726     valuelen = len(self.value)
727    
728     self.value.append(Integer32lePart("RSA info len",
729     indent=self.indent,
730     knvalue=len(data)-32-4))
731    
732     for dp in self.value[valuelen:]:
733     data = dp.parse(data)
734    
735     valuelen = len(self.value)
736    
737     self.value.append(PacketPart("Server salt", indent=self.indent, maxlength=randsaltlen.value))
738    
739     self.value.append(PacketPart("Cert header", indent=self.indent, maxlength=8))
740     cacertlen = Integer32lePart("CA Certificate length", indent=self.indent)
741     self.value.append(cacertlen)
742    
743     for dp in self.value[valuelen:]:
744     data = dp.parse(data)
745    
746     valuelen = len(self.value)
747    
748     self.value.append(CertificatePart("(CA)", indent=self.indent,
749     maxlength=cacertlen.value))
750     certlen = Integer32lePart("Certificate length", indent=self.indent)
751     self.value.append(certlen)
752    
753     for dp in self.value[valuelen:]:
754     data = dp.parse(data)
755    
756     valuelen = len(self.value)
757    
758     self.value.append(CertificatePart("", indent=self.indent, maxlength=certlen.value))
759     self.value.append(PacketPart("Remaining info", indent=self.indent))
760    
761     for dp in self.value[valuelen:]:
762     data = dp.parse(data)
763    
764     return data
765    
766     class SrvInfoPart(PacketPart):
767    
768     classname = "Srvinfopart"
769    
770     def __init__(self, description, **kw):
771     PacketPart.__init__(self, description, **kw)
772     self.datatype = "TAG_SRV_INFO"
773    
774     def parse(self, data):
775     self.value.append(Integer16lePart("RDP version",
776     indent=self.indent+1))
777     self.value.append(Integer16lePart("Unknown",
778     indent=self.indent+1,
779     knvalue=8))
780    
781     for dp in self.value:
782     data = dp.parse(data)
783    
784     return data
785    
786     class TaggedData(PacketPart):
787    
788     classname = "TaggedData"
789    
790     class HexLines(PacketPart):
791     classname = "HexLines"
792     def tblvalue(self, offset=0):
793     s = self.value[0].tblvalue()+"\n"
794     offset+=len(self.value[0])
795     for hexline in self.value[1:]:
796     s+="%d\t%s\n" % (offset, hexline.tblvalue())
797     offset+=len(hexline)
798     return s
799    
800     def latexvalue(self, offset=0):
801     s = self.value[0].latexvalue()+"\n"
802     offset+=len(self.value[0])
803     for hexline in self.value[1:]:
804     s+="%d & %s\\\\\n" % (offset, hexline.latexvalue())
805     offset+=len(hexline)
806     return s
807    
808     class CliChannelsPart(PacketPart):
809     classname = "CliChannelsPart"
810     class ChannelFlags(Integer32lePart):
811    
812     classname = "ChannelFlags"
813    
814     def __init__(self, description, **kw):
815     PacketPart.__init__(self, description, **kw)
816     self.datatype = "RDP Channel Flags"
817     self.owntbl = 0
818    
819     def strvalue(self):
820     ret = Integer32lePart.strvalue(self)+" "
821     for flag, desc in rdp_channel_flags:
822     if self.value & flag:
823     ret+="%s, " % desc
824    
825     return ret
826    
827     def __init__(self, description, **kw):
828     PacketPart.__init__(self, description, **kw)
829     self.datatype = "RDP Channel data"
830     self.owntbl = 1
831    
832     def parse(self, data):
833     numchannels = Integer32lePart("Number of channels", indent=self.indent+1)
834     self.value.append(numchannels)
835     data = numchannels.parse(data)
836    
837     for i in range(numchannels.value):
838     channelname = Latin1String("Channel #%d name" % i, 7, indent=self.indent+2)
839     channelflags = self.ChannelFlags("Channel #%d flags" % i, indent=self.indent+2)
840     self.value.append(channelname)
841     self.value.append(channelflags)
842     data = channelname.parse(data)
843     data = channelflags.parse(data)
844    
845     rdp_channels[i] = (channelname.value, channelflags.value)
846    
847     return data
848    
849    
850    
851    
852     tags = {0xc001:('TAG_CLI_INFO', HexLines),
853     0xc002:('TAG_CLI_CRYPT', HexLines),
854     0xc003:('TAG_CLI_CHANNELS', CliChannelsPart),
855     0x0c01:('TAG_SRV_INFO', SrvInfoPart),
856     0x0c02:('TAG_SRV_CRYPT', MCSResponseCryptinfoPacket),
857     0x0c03:('TAG_SRV_SRV3', HexLines)}
858    
859     def __init__(self, description, **kw):
860     PacketPart.__init__(self, description, **kw)
861     self.datatype = "Tagged data"
862     self.owntbl = 1
863    
864     def parse(self, data):
865    
866     while 0 < len(data):
867    
868     tag = Integer16lePart("Tag", indent=self.indent+2)
869     data = tag.parse(data)
870    
871     length = Integer16lePart("Length", indent=self.indent+2)
872     data = length.parse(data)
873    
874     (tagtype, packetclass) = self.tags.get(tag.value,
875     ("Unknown", self.HexLines))
876    
877     datapart = packetclass("Data", indent=self.indent+2)
878     packetdata = data[:length.value-4]
879     datapart.parse(packetdata)
880    
881     container = PacketPart("%s" % tagtype,
882     indent=self.indent+1)
883     container.datatype = "Tagged datapart"
884     container.value.append(tag)
885     container.value.append(length)
886     container.value.append(datapart)
887    
888     self.value.append(container)
889    
890     data = data[length.value-4:]
891    
892     return data # Should return empty list.
893    
894     def tblvalue(self, offset=0):
895     tag = self.value[0].value[0]
896     length = self.value[0].value[1]
897     dp = self.value[0].value[2]
898     (tagtype, packetclass) = self.tags.get(tag.value,
899     ("Unknown", PacketPart))
900    
901     s = "%s\tTag\t\t%s (%s)\n" % (tag.datatype,
902     tag.value, tagtype)
903     offset+=len(tag)
904     s+= "%d\t%s\n" % (offset, length.tblvalue(offset=offset))
905     offset+=len(length)
906     s+= "%d\t%s\n" % (offset, dp.tblvalue(offset=offset))
907     offset+=len(dp)
908     for cont in self.value[1:]:
909     tag = cont.value[0]
910     length = cont.value[1]
911     dp = cont.value[2]
912     (tagtype, packetclass) = self.tags.get(tag.value,
913     ("Unknown", PacketPart))
914    
915     s+= "%d\t%s\tTag\t\t%s (%s)\n" % (offset, tag.datatype,
916     tag.value, tagtype)
917     offset+=len(tag)
918     s+= "%d\t%s\n" % (offset, length.tblvalue(offset=offset))
919     offset+=len(length)
920     s+= "%d\t%s\n" % (offset, dp.tblvalue(offset=offset))
921     offset+=len(dp)
922    
923     return s
924    
925     def latexvalue(self, offset=0):
926     tag = self.value[0].value[0]
927     length = self.value[0].value[1]
928     dp = self.value[0].value[2]
929     (tagtype, packetclass) = self.tags.get(tag.value,
930     ("Unknown", PacketPart))
931    
932     s = "%s & Tag & & %s (%s)\\\\\n" % (tag.datatype,
933     tag.value, tagtype)
934     offset+=len(tag)
935     s+= "%d & %s \\\\\n" % (offset, length.latexvalue(offset=offset))
936     offset+=len(length)
937     s+= "%d & %s \\\\\n" % (offset, dp.latexvalue(offset=offset))
938     offset+=len(dp)
939     for cont in self.value[1:]:
940     tag = cont.value[0]
941     length = cont.value[1]
942     dp = cont.value[2]
943     (tagtype, packetclass) = self.tags.get(tag.value,
944     ("Unknown", PacketPart))
945    
946     s+= "%d & %s & Tag & & %s (%s)\\\\\n" % (offset, tag.datatype,
947     tag.value, tagtype)
948     offset+=len(tag)
949     s+= "%d & %s \\\\ " % (offset, length.latexvalue(offset=offset))
950     offset+=len(length)
951     s+= "%d & %s \\\\\n" % (offset, dp.latexvalue(offset=offset))
952     offset+=len(dp)
953    
954     return s
955    
956    
957    
958     class MCSResponseUserdataPacket(PacketPart):
959    
960     classname = "MCSResponseUserdataPacket"
961    
962     def __init__(self, description, **kw):
963     PacketPart.__init__(self, description, **kw)
964     self.datatype = "MCS response userdata"
965    
966     def parse(self, data):
967     userdata_length = BERHeader("Userdata length",
968     self.BER_TAGS['OCTET_STRING'],
969     indent=self.indent)
970     self.value.append(userdata_length)
971     data = userdata_length.parse(data)
972    
973     userdata = data[:userdata_length.value[0].value]
974    
975     t124 = PacketPart("T.124 data", indent=self.indent)
976     t124.parse(userdata[:21])
977     self.value.append(t124)
978    
979     userdata = userdata[21:]
980    
981     remlength = MSVariableInt("Remaining length "\
982     "(remaining bytes: %d)" % len(userdata),
983     indent=self.indent)
984     self.value.append(remlength)
985    
986     userdata = remlength.parse(userdata)
987    
988     tagged_data = TaggedData("Tagged data", indent=self.indent)
989     self.value.append(tagged_data)
990     userdata = tagged_data.parse(userdata)
991    
992     if 0 < len(userdata):
993     remaining_data = PacketPart("Remaining MCS response user data",
994     indent=self.indent)
995     self.value.append(remaining_data)
996     remaining_data.parse(userdata)
997    
998     return data[userdata_length.value[0].value:]
999    
1000     class McsInitialUserdataPacket(PacketPart):
1001    
1002     classname = "McsInitialUserdataPacket"
1003    
1004     def __init__(self, description, **kw):
1005     PacketPart.__init__(self, description, **kw)
1006     self.datatype = "MCS initial userdata"
1007    
1008     def parse(self, data):
1009     userdata_length = BERHeader("Userdata length",
1010     self.BER_TAGS['OCTET_STRING'],
1011     indent=self.indent)
1012     self.value.append(userdata_length)
1013     self.value.append(Integer16Part("", knvalue=0x05, indent=self.indent))
1014     self.value.append(Integer16Part("", knvalue=0x14, indent=self.indent))
1015     self.value.append(Integer8Part("", knvalue=0x7c, indent=self.indent))
1016     self.value.append(Integer16Part("", knvalue=0x01, indent=self.indent))
1017    
1018     for dp in self.value:
1019     data = dp.parse(data)
1020    
1021     vallen = len(self.value)
1022    
1023     remlen = Integer16or8000Part("Remaining length "\
1024     "(should be %d)" % (len(data)-2),
1025     indent=self.indent)
1026     self.value.append(remlen)
1027    
1028     self.value.append(Integer16Part("", knvalue=0x08, indent=self.indent))
1029     self.value.append(Integer16Part("", knvalue=0x0f, indent=self.indent))
1030     self.value.append(Integer8Part("", knvalue=0x00, indent=self.indent))
1031     self.value.append(Integer16Part("", knvalue=0xc001,
1032     indent=self.indent))
1033     self.value.append(Integer8Part("", knvalue=0x00, indent=self.indent))
1034     self.value.append(Integer32lePart("", knvalue="0x61637544 \"Duca\"",
1035     indent=self.indent))
1036    
1037     for dp in self.value[vallen:]:
1038     data = dp.parse(data)
1039    
1040     remlen = Integer16or8000Part("Remaining length "\
1041     "(should be %d)" % (len(data)-2),
1042     indent=self.indent)
1043     self.value.append(remlen)
1044     data = remlen.parse(data)
1045    
1046    
1047     clientinfo = UserdataClientinfoPacket("", indent=self.indent+1)
1048     self.value.append(clientinfo)
1049     data = clientinfo.parse(data)
1050    
1051     td = TaggedData("", indent=self.indent+1)
1052     self.value.append(td)
1053     data = td.parse(data)
1054    
1055     if len(data):
1056     remaining_userdata = PacketPart("Remaining user data",
1057     indent=self.indent)
1058     self.value.append(remaining_userdata)
1059     data = remaining_userdata.parse(data)
1060    
1061     return data[remlen.value:]
1062    
1063    
1064    
1065     class MCSConnInitialPacket(PacketPart):
1066    
1067     classname = "MCSConnInitialPacket"
1068    
1069     def __init__(self, description, **kw):
1070     PacketPart.__init__(self, description, **kw)
1071     self.datatype = "MCS Connect Initial"
1072    
1073     def parse(self, data):
1074     conn_initial_header = BERHeader("MCS Conn initial",
1075     self.BER_TAGS['CONN_INITIAL'],
1076     indent=self.indent)
1077     self.value.append(conn_initial_header)
1078     self.value.append(BERValue("Calling Domain", 'OCTET_STRING',
1079     indent=self.indent))
1080    
1081     self.value.append(BERValue("Called Domain", 'OCTET_STRING',
1082     indent=self.indent))
1083     self.value.append(BERValue("Upward flag", 'BOOLEAN',
1084     indent=self.indent))
1085    
1086     self.value.append(DomainParametersPacket("Target", indent=self.indent))
1087     self.value.append(DomainParametersPacket("Min", indent=self.indent))
1088     self.value.append(DomainParametersPacket("Max", indent=self.indent))
1089     self.value.append(McsInitialUserdataPacket("", indent=self.indent))
1090    
1091     for dp in self.value:
1092     data = dp.parse(data)
1093    
1094     # Code below should basically print nothing, when done deencoding
1095     # the whole packet.
1096    
1097     rempkt = PacketPart("Remaining MCS conn initial data",
1098     indent=self.indent)
1099     self.value.append(rempkt)
1100     remdata = rempkt.parse(data[:conn_initial_header.value[0].value])
1101     return remdata + data[conn_initial_header.value[0].value:]
1102    
1103    
1104     class MCSConnResponsePacket(PacketPart):
1105    
1106     classname = "MCSConnResponsePacket"
1107    
1108     def __init__(self, description, **kw):
1109     PacketPart.__init__(self, description, **kw)
1110     self.datatype = "MCS Connect Response"
1111    
1112     def parse(self, data):
1113     self.value.append(BERHeader("MCS Conn response",
1114     self.BER_TAGS['CONN_RESPONSE'],
1115     indent=self.indent))
1116     self.value.append(BERValue("Result", 'TAG_RESULT',
1117     indent=self.indent))
1118     self.value.append(BERValue("Connection id", 'INTEGER',
1119     indent=self.indent))
1120     self.value.append(DomainParametersPacket("Target", indent=self.indent))
1121     self.value.append(MCSResponseUserdataPacket("User data",
1122     indent=self.indent))
1123    
1124     for dp in self.value:
1125     data = dp.parse(data)
1126    
1127     return data
1128    
1129    
1130     class EDRQPart(PacketPart):
1131    
1132     classname = "EDRQPart"
1133    
1134     def __init__(self, description, **kw):
1135     PacketPart.__init__(self, description, **kw)
1136     self.datatype = "EDRQ data"
1137    
1138     def parse(self, data):
1139     self.value.append(Integer16lePart("SubHeight", indent=self.indent))
1140     self.value.append(Integer16lePart("SubInterval", indent=self.indent))
1141    
1142     for dp in self.value:
1143     data = dp.parse(data)
1144    
1145     return data
1146    
1147     class Enumerated(PacketPart):
1148    
1149     classname = "Enumerated"
1150    
1151     def __init__(self, description, dataparser=Integer8Part, **kw):
1152     PacketPart.__init__(self, description, **kw)
1153     self.dataparser = dataparser("")
1154    
1155    
1156     def parse(self, data):
1157     data = self.dataparser.parse(data)
1158     self.value = self.dataparser.value
1159     res = self.results.get(self.value, "Unknown")
1160     self.parser = PacketPart
1161     self.datatype = res
1162     if type(res) == type(()):
1163     self.datatype = res[0]
1164     self.parser = res[1]
1165    
1166     return data
1167    
1168     def strvalue(self):
1169     return self.dataparser.strvalue()+" %s" % self.datatype
1170    
1171     class MCSResultPart(Enumerated):
1172    
1173     classname = "MCSResultPart"
1174    
1175     results = {0:"RT-SUCCESSFUL",
1176     1:"RT-DOMAIN-MERGING",
1177     2:"RT-DOMAIN-NOT-HIEARCHICAL",
1178     3:"RT-NO-SUCH-CHANNEL",
1179     4:"RT-NO-SUCH-DOMAIN",
1180     5:"RT-NO-SUCH-USER",
1181     6:"RT-NOT-ADMITTED",
1182     7:"RT-OTHER-USER-ID",
1183     8:"RT-PARAMETERS-UNACCEPTABLE",
1184     9:"RT-TOKEN-NOT-AVAILABLE",
1185     10:"RT-TOKEN-NOT-POSSESSED",
1186     11:"RT-TOO-MANY-CHANNELS",
1187     12:"RT-TOO-MANY-TOKENS",
1188     13:"RT-TOO-MANY-USERS",
1189     14:"RT-UNSPECIFIED-FAILURE",
1190     15:"RT-USER-REJECTED"}
1191    
1192    
1193     def __init__(self, description, **kw):
1194     Enumerated.__init__(self, description, **kw)
1195     self.datatype = "AUCF data"
1196    
1197     class DataPriorityPart(Enumerated):
1198    
1199     classname = "DataPriorityPart"
1200    
1201     results = {0:"top",
1202     1:"high",
1203     2:"medium",
1204     3:"low"}
1205    
1206     def __init__(self, description, **kw):
1207     Enumerated.__init__(self, description, **kw)
1208     self.datatype = "Data Priority"
1209    
1210     class AUCFPart(PacketPart):
1211    
1212     classname = "AUCFPart"
1213    
1214     def __init__(self, description, **kw):
1215     PacketPart.__init__(self, description, **kw)
1216     self.datatype = "AUCF data"
1217    
1218     def parse(self, data):
1219     self.value.append(MCSResultPart("", indent=self.indent+1))
1220     self.value.append(Integer16Part("User id", indent=self.indent+1))
1221    
1222     for dp in self.value:
1223     data = dp.parse(data)
1224    
1225     return data
1226    
1227     class CJRQPart(PacketPart):
1228    
1229     classname = "CJRQPart"
1230    
1231     def __init__(self, description, **kw):
1232     PacketPart.__init__(self, description, **kw)
1233     self.datatype = "CJRQ data"
1234    
1235     def parse(self, data):
1236     self.value.append(Integer16Part("User id", indent=self.indent+1))
1237     self.channelid = Integer16Part("Channel id", indent=self.indent+1)
1238     self.value.append(self.channelid)
1239    
1240     for dp in self.value:
1241     data = dp.parse(data)
1242    
1243     global currentchannel
1244     currentchannel = self.channelid.value
1245    
1246     return data
1247    
1248     class CJCFPart(PacketPart):
1249    
1250     classname = "CJCFPart"
1251    
1252     def __init__(self, description, **kw):
1253     PacketPart.__init__(self, description, **kw)
1254     self.datatype = "CJCF data"
1255    
1256     def parse(self, data):
1257     self.value.append(MCSResultPart("", indent=self.indent+1))
1258     self.value.append(Integer16Part("Initiator (user id)",
1259     indent=self.indent+1))
1260     self.value.append(Integer16Part("Requested", indent=self.indent+1))
1261     self.channelid = Integer16Part("Channel id", indent=self.indent+1)
1262     self.value.append(self.channelid)
1263    
1264     for dp in self.value:
1265     data = dp.parse(data)
1266    
1267     global currentchannel
1268     currentchannel = self.channelid.value
1269    
1270     return data
1271    
1272     class LicensePart(PacketPart):
1273    
1274     classname = "LicensePart"
1275    
1276     def __init__(self, description, **kw):
1277     PacketPart.__init__(self, description, **kw)
1278     self.datatype = "License data"
1279    
1280     def parse(self, data):
1281     self.value.append(Integer16lePart("Tag", indent=self.indent))
1282     length = Integer8Part("Length", indent=self.indent)
1283     self.value.append(length)
1284    
1285     for dp in self.value:
1286     data = dp.parse(data)
1287    
1288     remaining_data = PacketPart("Remaining license data",
1289     indent=self.indent+1)
1290     self.value.append(remaining_data)
1291     remaining_data.parse(data[:length.value-3])
1292    
1293     return data[length.value-3:]
1294    
1295     class GeneralCapability(PacketPart):
1296    
1297     classname = "GeneralCapability"
1298    
1299     def __init__(self, description, **kw):
1300     PacketPart.__init__(self, description, **kw)
1301     self.datatype = "General Capability set"
1302    
1303     def parse(self, data):
1304     self.value.append(Integer16lePart("OS major type",
1305     indent=self.indent+1))
1306     self.value.append(Integer16lePart("OS minor type",
1307     indent=self.indent+1))
1308     self.value.append(Integer16Part("Protocol version",
1309     indent=self.indent+1))
1310     self.value.append(Integer16Part("Pad",
1311     indent=self.indent+1))
1312     self.value.append(Integer16Part("Compression types",
1313     indent=self.indent+1))
1314     self.value.append(Integer16Part("Pad",
1315     indent=self.indent+1))
1316     self.value.append(Integer16Part("Update capability",
1317     indent=self.indent+1))
1318     self.value.append(Integer16Part("Remote unshare capability",
1319     indent=self.indent+1))
1320     self.value.append(Integer16Part("Compression level",
1321     indent=self.indent+1))
1322     self.value.append(Integer16Part("Pad",
1323     indent=self.indent+1))
1324    
1325     for dp in self.value:
1326     data = dp.parse(data)
1327    
1328     return data
1329    
1330     class OrderCapability(PacketPart):
1331    
1332     classname = "OrderCapability"
1333    
1334     class OrderCaps(PacketPart):
1335    
1336     classname = "OrderCaps"
1337    
1338     def __init__(self, description, **kw):
1339     PacketPart.__init__(self, description, **kw)
1340     self.datatype = "Orders supported"
1341    
1342     def parse(self, data):
1343     self.value.append(Integer8Part("Dest blt",
1344     indent=self.indent+1,
1345     knvalue=1))
1346     self.value.append(Integer8Part("Pat blt",
1347     indent=self.indent+1,
1348     knvalue=1))
1349     self.value.append(Integer8Part("Screen blt",
1350     indent=self.indent+1,
1351     knvalue=1))
1352     self.value.append(Integer8Part("Req for memblt?",
1353     indent=self.indent+1,
1354     knvalue=1))
1355     self.value.append(Integer8Part("Unknown",
1356     indent=self.indent+1,
1357     knvalue=0))
1358     self.value.append(Integer8Part("Unknown",
1359     indent=self.indent+1,
1360     knvalue=0))
1361     self.value.append(Integer8Part("Unknown",
1362     indent=self.indent+1,
1363     knvalue=0))
1364     self.value.append(Integer8Part("Unknown",
1365     indent=self.indent+1,
1366     knvalue=0))
1367     self.value.append(Integer8Part("Line",
1368     indent=self.indent+1,
1369     knvalue=1))
1370     self.value.append(Integer8Part("Line",
1371     indent=self.indent+1,
1372     knvalue=1))
1373     self.value.append(Integer8Part("Rect",
1374     indent=self.indent+1,
1375     knvalue=1))
1376     self.value.append(Integer8Part("Unknown",
1377     indent=self.indent+1,
1378     knvalue=0))
1379     self.value.append(Integer8Part("Memblt",
1380     indent=self.indent+1,
1381     knvalue=1))
1382     self.value.append(Integer8Part("Triblt",
1383     indent=self.indent+1,
1384     knvalue=1))
1385     self.value.append(Integer8Part("Triblt",
1386     indent=self.indent+1,
1387     knvalue=1))
1388     self.value.append(Integer8Part("Unknown",
1389     indent=self.indent+1,
1390     knvalue=0))
1391     self.value.append(Integer8Part("Unknown",
1392     indent=self.indent+1,
1393     knvalue=0))
1394     self.value.append(Integer8Part("Unknown",
1395     indent=self.indent+1,
1396     knvalue=0))
1397     self.value.append(Integer8Part("Unknown",
1398     indent=self.indent+1,
1399     knvalue=0))
1400     self.value.append(Integer8Part("Unknown",
1401     indent=self.indent+1,
1402     knvalue=0))
1403     self.value.append(Integer8Part("Unknown",
1404     indent=self.indent+1,
1405     knvalue=0))
1406     self.value.append(Integer8Part("Unknown",
1407     indent=self.indent+1,
1408     knvalue=0))
1409     self.value.append(Integer8Part("Polyline",
1410     indent=self.indent+1,
1411     knvalue=1))
1412     self.value.append(Integer8Part("Text2",
1413     indent=self.indent+1,
1414     knvalue=1))
1415     self.value.append(PacketPart("Rem. order support data",
1416     indent=self.indent+1,
1417     maxlength=8))
1418    
1419     for dp in self.value:
1420     data = dp.parse(data)
1421    
1422     return data
1423    
1424     def __init__(self, description, **kw):
1425     PacketPart.__init__(self, description, **kw)
1426     self.datatype = "Order Capability set"
1427    
1428     def parse(self, data):
1429     self.value.append(PacketPart("Terminal desc, pad",
1430     indent=self.indent+1,
1431     maxlength=20))
1432     self.value.append(Integer16lePart("Cache X granularity",
1433     knvalue=1,
1434     indent=self.indent+1))
1435     self.value.append(Integer16lePart("Cache Y granularity",
1436     knvalue=20,
1437     indent=self.indent+1))
1438     self.value.append(Integer16lePart("Pad",
1439     knvalue=0,
1440     indent=self.indent+1))
1441     self.value.append(Integer16lePart("Max order level",
1442     knvalue=1,
1443     indent=self.indent+1))
1444     self.value.append(Integer16lePart("Number of fonts",
1445     knvalue=0x147,
1446     indent=self.indent+1))
1447     self.value.append(Integer16lePart("Capability flags",
1448     knvalue=0x2a,
1449     indent=self.indent+1))
1450     self.value.append(self.OrderCaps("Orders supported",
1451     indent=self.indent+1,
1452     maxlength=32))
1453     self.value.append(Integer16lePart("Text capability flags",
1454     knvalue=0x6a1,
1455     indent=self.indent+1))
1456     self.value.append(PacketPart("Pad",
1457     indent=self.indent+1,
1458     maxlength=6))
1459     self.value.append(Integer32lePart("Desktop cache size",
1460     knvalue=0x38400,
1461     indent=self.indent+1))
1462     self.value.append(Integer32lePart("Unknown",
1463     knvalue=0,
1464     indent=self.indent+1))
1465     self.value.append(Integer32lePart("Unknown",
1466     knvalue=0x4e4,
1467     indent=self.indent+1))
1468    
1469     for dp in self.value:
1470     data = dp.parse(data)
1471    
1472     return data
1473    
1474    
1475    
1476     class CapsetPart(PacketPart):
1477    
1478     classname = "CapsetPart"
1479    
1480     class CapabilityType(Integer16lePart):
1481    
1482     classname = "CapabilityType"
1483    
1484     types = {1:('GENERAL', GeneralCapability),
1485     2:('BITMAP', PacketPart),
1486     3:('ORDER', OrderCapability),
1487     4:('BMPCACHE', PacketPart),
1488     5:('CONTROL', PacketPart),
1489     7:('ACTIVATE', PacketPart),
1490     8:('POINTER', PacketPart),
1491     9:('SHARE', PacketPart),
1492     10:('COLCACHE', PacketPart),
1493     13:('UNKNOWN', PacketPart)}
1494    
1495     def strvalue(self):
1496     return Integer16lePart.strvalue(self)+" "+self.pkttype
1497    
1498     def parse(self, data):
1499     data = Integer16lePart.parse(self, data)
1500     (self.pkttype, self.parser) = self.types.get(self.value,
1501     ("Unknown",
1502     PacketPart))
1503     return data
1504    
1505     def __init__(self, description, **kw):
1506     PacketPart.__init__(self, description, **kw)
1507     self.datatype = "Capability set"
1508    
1509     def parse(self, data):
1510     pkttype = self.CapabilityType("Capability type", indent=self.indent+1)
1511     data = pkttype.parse(data)
1512     self.value.append(pkttype)
1513    
1514     pktlen = Integer16lePart("Capability length", indent=self.indent+1)
1515     data = pktlen.parse(data)
1516     self.value.append(pktlen)
1517    
1518     datapart = pkttype.parser("", indent=self.indent+1,
1519     maxlength=pktlen.value-4)
1520     data = datapart.parse(data)
1521     self.value.append(datapart)
1522    
1523     return data
1524    
1525    
1526     class DemandActivePart(PacketPart):
1527    
1528     classname = "DemandActivePart"
1529    
1530     def __init__(self, description, **kw):
1531     PacketPart.__init__(self, description, **kw)
1532     self.datatype = "Demand Active data"
1533    
1534     def parse(self, data):
1535     self.value.append(Integer32lePart("Share ID", indent=self.indent+1))
1536     sourcelen = Integer16lePart("Length of source",
1537     indent=self.indent+1)
1538     self.value.append(sourcelen)
1539     self.value.append(Integer16lePart("Capabilities length",
1540     indent=self.indent+1))
1541    
1542     for dp in self.value:
1543     data = dp.parse(data)
1544    
1545     valuelen = len(self.value)
1546    
1547     self.value.append(PacketPart("Source", indent=self.indent+1,
1548     maxlength=sourcelen.value))
1549    
1550     numcapabilities = Integer16lePart("Number of capabilities",
1551     indent=self.indent+1)
1552     self.value.append(numcapabilities)
1553     self.value.append(Integer16lePart("Pad",
1554     indent=self.indent+1))
1555     self.value.append(Integer16lePart("Pad",
1556     indent=self.indent+1))
1557     self.value.append(Integer16lePart("Pad",
1558     indent=self.indent+1))
1559    
1560     self.value.append(Integer16lePart("User ID", indent=self.indent+1))
1561    
1562     self.value.append(Integer16lePart("Pad",
1563     indent=self.indent+1))
1564    
1565     for dp in self.value[valuelen:]:
1566     data = dp.parse(data)
1567    
1568     for i in range(numcapabilities.value):
1569     capability = CapsetPart("", indent=self.indent+1)
1570     data = capability.parse(data)
1571     self.value.append(capability)
1572    
1573     remaining_data = PacketPart("Remaining capability data",
1574     indent=self.indent+1)
1575     self.value.append(remaining_data)
1576    
1577     data = remaining_data.parse(data)
1578    
1579     return data
1580    
1581     class ConfirmActivePart(PacketPart):
1582    
1583     classname = "ConfirmActivePart"
1584    
1585     def __init__(self, description, **kw):
1586     PacketPart.__init__(self, description, **kw)
1587     self.datatype = "Confirm Active data"
1588    
1589     def parse(self, data):
1590     self.value.append(Integer32lePart("Share ID", indent=self.indent+1))
1591     self.value.append(Integer16lePart("User ID", indent=self.indent+1))
1592     sourcelen = Integer16lePart("Length of source",
1593     indent=self.indent+1)
1594     self.value.append(sourcelen)
1595     self.value.append(Integer16lePart("Capabilities length",
1596     indent=self.indent+1))
1597    
1598     for dp in self.value:
1599     data = dp.parse(data)
1600    
1601     valuelen = len(self.value)
1602    
1603     self.value.append(PacketPart("Source", indent=self.indent+1,
1604     maxlength=sourcelen.value))
1605    
1606     numcapabilities = Integer16lePart("Number of capabilities",
1607     indent=self.indent+1)
1608     self.value.append(numcapabilities)
1609     self.value.append(Integer16lePart("Pad",
1610     indent=self.indent+1))
1611    
1612     for dp in self.value[valuelen:]:
1613     data = dp.parse(data)
1614    
1615     for i in range(numcapabilities.value):
1616     capability = CapsetPart("", indent=self.indent+1)
1617     data = capability.parse(data)
1618     self.value.append(capability)
1619    
1620     remaining_data = PacketPart("Remaining capability data",
1621     indent=self.indent+1)
1622     self.value.append(remaining_data)
1623    
1624     data = remaining_data.parse(data)
1625    
1626     return data
1627    
1628     class DataPDUSynchronize(PacketPart):
1629    
1630     classname = "DataPDUSynchronize"
1631    
1632     def __init__(self, description, **kw):
1633     PacketPart.__init__(self, description, **kw)
1634     self.datatype = "RDP Data PDU Synchronize"
1635    
1636     def parse(self, data):
1637     self.value.append(Integer16lePart("Type", indent=self.indent+1))
1638     self.value.append(Integer16lePart("Userid(?)", indent=self.indent+1))
1639    
1640     for dp in self.value:
1641     data = dp.parse(data)
1642    
1643     return data
1644    
1645     class DataPDUControl(PacketPart):
1646    
1647     classname = "DataPDUControl"
1648    
1649     class DataPDUControlType(Enumerated):
1650    
1651     classname = "DataPDUControlType"
1652    
1653     results = {1:'Request control',
1654     2:'Grant control',
1655     3:'Control detach',
1656     4:'Cooperate'}
1657    
1658     def __init__(self, description, **kw):
1659     Enumerated.__init__(self, description,
1660     dataparser=Integer16lePart, **kw)
1661     self.datatype = "RDP Control"
1662    
1663    
1664     def __init__(self, description, **kw):
1665     PacketPart.__init__(self, description, **kw)
1666     self.datatype = "RDP Data PDU Control"
1667    
1668     def parse(self, data):
1669     self.value.append(self.DataPDUControlType("Action",
1670     indent=self.indent+1))
1671     self.value.append(Integer16Part("Userid(?)", indent=self.indent+1))
1672     # FIXME - Integer32 (not le) in rdesktop
1673     self.value.append(Integer32lePart("Control id",
1674     indent=self.indent+1))
1675    
1676     for dp in self.value:
1677     data = dp.parse(data)
1678    
1679     return data
1680    
1681     class DataPDUFont(PacketPart):
1682    
1683     classname = "DataPDUFont"
1684    
1685     def __init__(self, description, **kw):
1686     PacketPart.__init__(self, description, **kw)
1687     self.datatype = "RDP Data PDU Font"
1688    
1689     def parse(self, data):
1690     self.value.append(Integer16Part("Number of fonts",
1691     indent=self.indent+1))
1692     self.value.append(Integer16lePart("Unknown",
1693     indent=self.indent+1,
1694     knvalue=0x3e))
1695     self.value.append(Integer16lePart("Unknown (Sequence?)",
1696     indent=self.indent+1))
1697     self.value.append(Integer16lePart("Entry size", indent=self.indent+1,
1698     knvalue=0x32))
1699    
1700     for dp in self.value:
1701     data = dp.parse(data)
1702    
1703     return data
1704    
1705     class DataPDUInput(PacketPart):
1706    
1707     classname = "DataPDUInput"
1708    
1709     class InputEvent(PacketPart):
1710    
1711     classname = "InputEvent"
1712    
1713     class MessageType(Enumerated):
1714    
1715     classname = "MessageType"
1716    
1717     results = {0:'Synchronize',
1718     1:'Codepoint',
1719     2:'Virtual key',
1720     4:'Scancode',
1721     0x8001:'Mouse'}
1722    
1723     def __init__(self, description, **kw):
1724     Enumerated.__init__(self, description,
1725     dataparser=Integer16lePart, **kw)
1726    
1727     class ScanCodePart(Integer16lePart):
1728     classname = "ScanCodePart"
1729    
1730     def strvalue(self):
1731     return Integer16lePart.strvalue(self) + " (%s)" % keys[self.value]
1732    
1733     def __init__(self, description, **kw):
1734     PacketPart.__init__(self, description, **kw)
1735     self.datatype = "Input event"
1736    
1737     def parse(self, data):
1738     self.value.append(Time32le("Event timestamp",
1739     indent=self.indent+1))
1740     mt = self.MessageType("Event type",
1741     indent=self.indent+1)
1742    
1743     self.value.append(mt)
1744    
1745     # Stoppa in parsning av keycode här pÃ¥ nÃ¥tt sätt. *bonk*
1746    
1747     # Fixme: We should have an enumerated here.
1748     self.value.append(Integer16lePart("Device flags",
1749     indent=self.indent+1))
1750     for dp in self.value:
1751     data = dp.parse(data)
1752     valuelen = len(self.value)
1753    
1754     if 4 == mt.value:
1755     self.value.append(self.ScanCodePart("Key number",
1756     indent=self.indent+1))
1757     else:
1758     self.value.append(Integer16lePart("Param #1",
1759     indent=self.indent+1))
1760     self.value.append(Integer16lePart("Param #2",
1761     indent=self.indent+1))
1762    
1763     for dp in self.value[valuelen:]:
1764     data = dp.parse(data)
1765    
1766     return data
1767    
1768    
1769     def __init__(self, description, **kw):
1770     PacketPart.__init__(self, description, **kw)
1771     self.datatype = "RDP Data PDU Input"
1772    
1773     def parse(self, data):
1774     numevents = Integer16lePart("Number of inputs", indent=self.indent+1)
1775     self.value.append(numevents)
1776     data = numevents.parse(data)
1777    
1778     self.value.append(Integer16Part("Pad", indent=self.indent+1,
1779     knvalue=0))
1780     for ordernum in range(numevents.value):
1781     self.value.append(self.InputEvent("%d" % (ordernum+1),
1782     indent=self.indent+1))
1783    
1784     for dp in self.value[1:]:
1785     data = dp.parse(data)
1786    
1787     return data
1788    
1789    
1790    
1791     class RDP_DATA_PDUType(Enumerated):
1792    
1793     classname = "RDP_DATA_PDUType"
1794    
1795     results = {2:'Update',
1796     20:('Control', DataPDUControl),
1797     27:'Pointer',
1798     28:('Input', DataPDUInput),
1799     31:('Synchronize', DataPDUSynchronize),
1800     34:'Bell',
1801     38:'Logon',
1802     39:('Font2', DataPDUFont)}
1803    
1804    
1805     def __init__(self, description, **kw):
1806     Enumerated.__init__(self, description, **kw)
1807     self.datatype = "Data PDUType"
1808    
1809    
1810     class RDP_PDU_DataPart(PacketPart):
1811    
1812     classname = "RDP_PDU_DataPart"
1813    
1814     def __init__(self, description, **kw):
1815     PacketPart.__init__(self, description, **kw)
1816     self.datatype = "RDP data PDU"
1817    
1818     def parse(self, data):
1819     self.value.append(Integer32lePart("Share id", indent=self.indent+1))
1820     self.value.append(Integer8Part("Pad", indent=self.indent+1,
1821     knvalue=0))
1822     self.value.append(Integer8Part("Stream id", indent=self.indent+1,
1823     knvalue=1))
1824     self.value.append(Integer16lePart("Remaining length",
1825     indent=self.indent+1,
1826     knvalue=len(data)-8))
1827     rdpt = RDP_DATA_PDUType("", indent=self.indent+1)
1828     self.value.append(rdpt)
1829     self.value.append(Integer8Part("Compress type", indent=self.indent+1))
1830     self.value.append(Integer16Part("Compressed length",
1831     indent=self.indent+1))
1832     for dp in self.value:
1833     data = dp.parse(data)
1834    
1835     remaining_data = rdpt.parser("", indent=self.indent+1)
1836     self.value.append(remaining_data)
1837    
1838     data = remaining_data.parse(data)
1839    
1840     return data
1841    
1842     class RDP_PDUtype(Integer16lePart):
1843    
1844     classname = "RDP_PDUtype"
1845    
1846     types = {1:('DEMAND_ACTIVE', DemandActivePart),
1847     3:('CONFIRM_ACTIVE', ConfirmActivePart),
1848     6:('DEACTIVATE', PacketPart),
1849     7:('DATA', RDP_PDU_DataPart)}
1850    
1851     def __init__(self, description, **kw):
1852     Integer16lePart.__init__(self, description, **kw)
1853     self.datatype = "RDP pdu type"
1854    
1855     def parse(self, data):
1856     data = Integer16lePart.parse(self, data)
1857     (self.typestr, self.parser) = self.types.get((self.value & 0xf),
1858     ("Unknown", PacketPart))
1859     return data
1860    
1861     def strvalue(self):
1862     return Integer16lePart.strvalue(self)+\
1863     " & 0xf = %d (%s)" % (self.value & 0xf, self.typestr)
1864    
1865     class SDIN_RDPData(PacketPart):
1866    
1867     classname = "SDIN_RDPData"
1868    
1869     def __init__(self, description, **kw):
1870     PacketPart.__init__(self, description, **kw)
1871     self.datatype = "RDP payload"
1872    
1873     def parse(self, data):
1874     length = Integer16lePart("Length", indent=self.indent+1)
1875     self.value.append(length)
1876     pdutype = RDP_PDUtype("Packet type",
1877     indent=self.indent+1)
1878     self.value.append(pdutype)
1879     self.value.append(Integer16lePart("User id",
1880     indent=self.indent+1))
1881    
1882     for dp in self.value:
1883     data = dp.parse(data)
1884    
1885     remaining_data = pdutype.parser("", indent=self.indent+1)
1886     self.value.append(remaining_data)
1887     data = remaining_data.parse(data)
1888    
1889     return data
1890    
1891    
1892     class RDPLogonPart(PacketPart):
1893    
1894     classname = "RDPLogonPart"
1895    
1896     class LogonFlags(Integer32lePart):
1897    
1898     classname = "LogonFlags"
1899    
1900     flags = [(0x33, "LOGON_NORMAL"),
1901     (0x8, "LOGON_AUTO"),
1902     (0x100, "BLOB_EXISTS"),
1903     (0x280, "COMPRESS")]
1904    
1905     def __init__(self, description, **kw):
1906     PacketPart.__init__(self, description, **kw)
1907     self.datatype = "RDP Logon Flags"
1908    
1909     def strvalue(self):
1910     ret = Integer32lePart.strvalue(self)+" "
1911     for flag, desc in self.flags:
1912     if self.value & flag:
1913     ret+="%s, " % desc
1914    
1915     return ret
1916    
1917    
1918    
1919     def __init__(self, description, **kw):
1920     PacketPart.__init__(self, description, **kw)
1921     self.datatype = "RDP Logon packet"
1922    
1923     def parse(self, data):
1924     self.value.append(Integer32Part("Unknown", indent=self.indent+1,
1925     knvalue=0))
1926     logonflags = self.LogonFlags("", indent=self.indent+1)
1927     self.value.append(logonflags)
1928     len_domain = Integer16lePart("Domain length", indent=self.indent+1)
1929     len_user = Integer16lePart("User length", indent=self.indent+1)
1930     self.value+=[len_domain, len_user]
1931    
1932     for dp in self.value:
1933     data = dp.parse(data)
1934     valuelen = len(self.value)
1935    
1936     if logonflags.value & 0x8:
1937     len_password = Integer16lePart("Password length",
1938     indent=self.indent+1)
1939     self.value.append(len_password)
1940    
1941     len_blob = Integer16lePart("BLOB length",
1942     indent=self.indent+1)
1943     len_blob.value = 0
1944     if logonflags.value & 0x100:
1945     self.value.append(len_blob)
1946     len_program = Integer16lePart("Program length",
1947     indent=self.indent+1)
1948     self.value.append(len_program)
1949    
1950     for dp in self.value[valuelen:]:
1951     data = dp.parse(data)
1952    
1953     valuelen = len(self.value)
1954    
1955     len_directory = Integer16lePart("Directory length", indent=self.indent+1)
1956     len_directory.value = 0
1957    
1958     # if 0 < len_program.value:
1959     self.value.append(len_directory)
1960     # else:
1961     # self.value.append(Integer16lePart("Instead of directory length", indent=self.indent+1))
1962    
1963     if 0 < len_domain.value:
1964     self.value.append(UnicodeString("Domain", len_domain.value/2+1,
1965     indent=self.indent+1))
1966     else:
1967     self.value.append(Integer16lePart("Instead of domain", indent=self.indent+1))
1968    
1969     if 0 < len_user.value:
1970     self.value.append(UnicodeString("User", len_user.value/2+1,
1971     indent=self.indent+1))
1972     if logonflags.value & 0x8:
1973     self.value.append(UnicodeString("Password", len_password.value/2+1,
1974     indent=self.indent+1))
1975     # self.value.append(Integer16lePart("Unknown1", indent=self.indent+1,
1976     # knvalue=0xd806))
1977    
1978    
1979     if logonflags.value & 0x100:
1980     self.value.append(PacketPart("BLOB",
1981     indent=self.indent+1,
1982     maxlength=len_blob.value))
1983     self.value.append(Integer16lePart("Unknown2", indent=self.indent+1,
1984     knvalue=0))
1985    
1986    
1987     for dp in self.value[valuelen:]:
1988     data = dp.parse(data)
1989    
1990     valuelen = len(self.value)
1991    
1992    
1993     if 0 < len_program.value:
1994     self.value.append(UnicodeString("Program", len_program.value/2+1,
1995     indent=self.indent+1))
1996     else:
1997     self.value.append(Integer16lePart("Instead of Program, #0", indent=self.indent+1))
1998     if 0 == len_directory.value:
1999     self.value.append(Integer16lePart("Instead of Directory", indent=self.indent+1))
2000    
2001     if 0 < len_directory.value:
2002     self.value.append(UnicodeString("Directory",
2003     len_directory.value/2+1,
2004     indent=self.indent+1))
2005    
2006     elif 0 < len_program.value:
2007     self.value.append(Integer16lePart("Instead of directory",
2008     indent=self.indent+1))
2009    
2010    
2011     self.value.append(Integer16lePart("Unknown", knvalue=2,
2012     indent=self.indent+1))
2013    
2014     iplen = Integer16lePart("Client ip length", indent=self.indent+1)
2015     self.value.append(iplen)
2016    
2017     for dp in self.value[valuelen:]:
2018     data = dp.parse(data)
2019     valuelen = len(self.value)
2020    
2021    
2022    
2023     self.value.append(UnicodeString("Client ip", iplen.value/2, indent=self.indent+1))
2024    
2025     for dp in self.value[valuelen:]:
2026     data = dp.parse(data)
2027     valuelen = len(self.value)
2028    
2029    
2030     if 0 < len(data): # This data seems to be here only when running RDP 5.2 (maybe in .1)
2031    
2032     dllstrlen = Integer16lePart("DLL String length",
2033     indent=self.indent+1)
2034     self.value.append(dllstrlen)
2035     data = dllstrlen.parse(data)
2036     valuelen+=1
2037    
2038     self.value.append(UnicodeString("DLL/executable used", dllstrlen.value/2, indent=self.indent+1))
2039    
2040     self.value.append(Integer16lePart("Unknown3", knvalue=0xffc4, indent=self.indent+1))
2041     self.value.append(Integer16lePart("Unknown3½", knvalue=0xffff,
2042     indent=self.indent+1))
2043    
2044     self.value.append(UnicodeString("Time zone #0", 32,
2045     indent=self.indent+1))
2046    
2047     self.value.append(PacketPart("Unknown", indent=self.indent+1,
2048     maxlength=20))
2049    
2050     self.value.append(UnicodeString("Time zone #1", 32, indent=self.indent+1))
2051    
2052     self.value.append(PacketPart("Remaining RDP Logon data",
2053     indent=self.indent+1))
2054    
2055     for dp in self.value[valuelen:]:
2056     data = dp.parse(data)
2057    
2058     return data
2059    
2060     class ClipboardData(PacketPart):
2061    
2062     classname = "ClipboardData"
2063    
2064     class FormatDescription(PacketPart):
2065     classname = "FormatDescription"
2066    
2067     def __init__(self, description, **kw):
2068     PacketPart.__init__(self, description, **kw)
2069     self.datatype = "Clipboard format description"
2070    
2071     def parse(self, data):
2072     self.value.append(Integer32lePart("Numeric code",
2073     indent=self.indent+1))
2074     self.value.append(UnicodeString("Text representation", 16,
2075     indent=self.indent+1))
2076    
2077     for dp in self.value:
2078     data = dp.parse(data)
2079    
2080     return data
2081    
2082     class ChannelDataFlags(Integer32lePart):
2083    
2084     classname = "ChannelDataFlags"
2085    
2086     flags = [(1, "FLAG_FIRST"),
2087     (2, "FLAG_LAST"),
2088     (0, "FLAG_MIDDLE"),]
2089    
2090     def __init__(self, description, **kw):
2091     PacketPart.__init__(self, description, **kw)
2092     self.datatype = "Channel data flags"
2093     self.owntbl = 0
2094    
2095     def strvalue(self):
2096     ret = Integer32lePart.strvalue(self)+" "
2097     for flag, desc in self.flags:
2098     if self.value & flag:
2099     ret+="%s, " % desc
2100    
2101     return ret
2102    
2103     def __init__(self, description, **kw):
2104     PacketPart.__init__(self, description, **kw)
2105     self.datatype = "Clipboard data"
2106    
2107     def parse(self, data):
2108     CHANNEL_FLAG_FIRST = 1
2109     CHANNEL_FLAG_LAST = 2
2110     cdlength = Integer32lePart("Clpbrd data length",
2111     indent=self.indent+1)
2112     flags = self.ChannelDataFlags("Flags",
2113     indent=self.indent+1)
2114    
2115     self.value = [cdlength, flags]
2116    
2117     for dp in self.value:
2118     data = dp.parse(data)
2119    
2120     valuelen = len(self.value)
2121    
2122     if flags.value == 2: # Last packet:
2123     self.value.append(PacketPart("Clipboard data, last packet of several", indent=self.indent+1))
2124     elif flags.value & 0x0f == 0x3: # Single write op.
2125     ptype0 = Integer16lePart("Ptype0", indent=self.indent+1)
2126     ptype1 = Integer16lePart("Ptype1", indent=self.indent+1)
2127     self.value.append(ptype0)
2128     self.value.append(ptype1)
2129    
2130     for dp in self.value[valuelen:]:
2131     data = dp.parse(data)
2132    
2133     valuelen = len(self.value)
2134    
2135     if 2 == ptype0.value: # Format announce
2136     remlen = Integer32lePart("Remaining length", indent=self.indent+1)
2137     self.value.append(remlen)
2138     valuelen+=1
2139     data = remlen.parse(data)
2140    
2141     for i in range(remlen.value/36):
2142     self.value.append(self.FormatDescription("#%d" % i,
2143     indent=self.indent+1))
2144     self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1))
2145    
2146     elif 1 == ptype0.value or 3 == ptype0.value: # First pkt from server / answer to format announce
2147     remlen = Integer32lePart("Remaining length", indent=self.indent+1)
2148     self.value.append(remlen)
2149     valuelen+=1
2150     data = remlen.parse(data)
2151    
2152     self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1))
2153    
2154     elif 4 == ptype0.value: # Request data
2155     remlen = Integer32lePart("Remaining length", indent=self.indent+1)
2156     self.value.append(remlen)
2157     valuelen+=1
2158     data = remlen.parse(data)
2159    
2160     self.value.append(Integer32lePart("Requested format code", indent=self.indent+1))
2161     self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1))
2162    
2163     elif 5 == ptype0.value: # Send data
2164     remlen = Integer32lePart("Remaining length", indent=self.indent+1)
2165     self.value.append(remlen)
2166     valuelen+=1
2167     data = remlen.parse(data)
2168    
2169     if remlen.value > 1600:
2170     datalen = 1592
2171     else:
2172     datalen = remlen.value
2173    
2174     self.value.append(PacketPart("Clipboard data", indent=self.indent+1,
2175     maxlength=datalen))
2176     if remlen.value < 1600:
2177     self.value.append(Integer32lePart("Unknown (Pad?)", indent=self.indent+1))
2178    
2179    
2180     elif (not (flags.value & CHANNEL_FLAG_FIRST) and not (flags.value & CHANNEL_FLAG_LAST)) or (flags.value & CHANNEL_FLAG_LAST):
2181     self.value.append(PacketPart("Clipboard data", indent=self.indent+1))
2182    
2183     for dp in self.value[valuelen:]:
2184     data = dp.parse(data)
2185    
2186     return data
2187    
2188    
2189     class SDINPart(PacketPart):
2190    
2191     classname = "SDINPart"
2192    
2193     def __init__(self, description, **kw):
2194     PacketPart.__init__(self, description, **kw)
2195     self.datatype = "SDIN data"
2196    
2197     def parse(self, data):
2198     self.value.append(Integer16Part("Initiator (user id)",
2199     indent=self.indent+1))
2200     self.channelid = Integer16Part("Channel id", indent=self.indent+1)
2201     self.value.append(self.channelid)
2202     self.value.append(Integer8Part("Flags", indent=self.indent+1))
2203     remaining_length = MSVariableInt("Data length", indent=self.indent+1)
2204     self.value.append(remaining_length)
2205     flags = Integer32lePart("Flags(?)", indent=self.indent+1)
2206     self.value.append(flags)
2207    
2208     for dp in self.value:
2209     data = dp.parse(data)
2210    
2211     global currentchannel
2212     currentchannel = self.channelid.value
2213    
2214     valuelen = len(self.value)
2215    
2216     if flags.value & 0x0008: # Encrypted == have signature
2217     self.value.append(CryptoSignature("Crypto signature",
2218     indent=self.indent+1, maxlength=8))
2219    
2220     if flags.value & 0x0080: # License packet.
2221     self.value.append(LicensePart("", indent=self.indent+1))
2222     elif 1003 < self.channelid.value:
2223     self.value.append(ClipboardData("", indent=self.indent+1))
2224     else:
2225     self.value.append(SDIN_RDPData("", indent=self.indent+1))
2226    
2227     try:
2228     for dp in self.value[valuelen:]:
2229     data = dp.parse(data)
2230     except ValueError:
2231     if flags.value & 0x260000:
2232     mysterious = PacketPart("Mysterious data",
2233     indent=self.indent+1)
2234     self.value.append(mysterious)
2235     data = mysterious.parse(data)
2236    
2237     if 0 < len(data):
2238     rem_data = PacketPart("Remaining SDIN data",
2239     indent=self.indent+1)
2240     data = rem_data.parse(data)
2241     self.value.append(rem_data)
2242    
2243    
2244     return data
2245    
2246     class SDRQPart(PacketPart):
2247    
2248     classname = "SDRQPart"
2249    
2250     def __init__(self, description, **kw):
2251     PacketPart.__init__(self, description, **kw)
2252     self.datatype = "SDRQ data"
2253    
2254     def parse(self, data):
2255     self.value.append(Integer16Part("Initiator (user id)",
2256     indent=self.indent+1))
2257     self.channelid = Integer16Part("Channel id", indent=self.indent+1)
2258     self.value.append(self.channelid)
2259     self.value.append(Integer8Part("Flags", indent=self.indent+1))
2260     remaining_length = MSVariableInt("Data length", indent=self.indent+1)
2261     self.value.append(remaining_length)
2262     flags = Integer32lePart("Flags(?)", indent=self.indent+1)
2263     self.value.append(flags)
2264    
2265     for dp in self.value:
2266     data = dp.parse(data)
2267    
2268     global currentchannel
2269     currentchannel = self.channelid.value
2270    
2271     valuelen = len(self.value)
2272    
2273     if flags.value & 0x0008:
2274     cryptsig = CryptoSignature("Crypto signature", indent=self.indent+1)
2275     cryptsig.parse(data[:8])
2276     data = data[8:]
2277     self.value.append(cryptsig)
2278    
2279     valuelen = len(self.value)
2280    
2281     if flags.value & 0x0040: # RDP Logon info
2282     self.value.append(RDPLogonPart("", indent=self.indent+1))
2283    
2284     elif flags.value & 0x0080: # License neg.
2285     self.value.append(LicensePart("", indent=self.indent+1))
2286     elif 1003 < self.channelid.value:
2287     self.value.append(ClipboardData("", indent=self.indent+1))
2288     else:
2289     self.value.append(SDIN_RDPData("", indent=self.indent+1))
2290    
2291     elif flags.value & 0x0001: # Client random
2292     saltlen = Integer32lePart("Client salt len",
2293     indent=self.indent+1)
2294     self.value.append(saltlen)
2295     for dp in self.value[valuelen:]:
2296     data = dp.parse(data)
2297     valuelen = len(self.value)
2298    
2299     self.value.append(PacketPart("Client salt", indent=self.indent+1,
2300     maxlength=saltlen.value))
2301    
2302     else:
2303    
2304     self.value.append(PacketPart("Remaining SDRQ data",
2305     indent=self.indent+1))
2306    
2307     for dp in self.value[valuelen:]:
2308     data = dp.parse(data)
2309    
2310     return data
2311    
2312    
2313     class MCSPacket(PacketPart):
2314    
2315     classname = "MCSPacket"
2316    
2317     class MCStype8(Integer8Part):
2318    
2319     classname = "MCStype8"
2320    
2321     types = {1:('EDRQ', EDRQPart),
2322     8:('DPUM', PacketPart),
2323     10:('AURQ', PacketPart),
2324     11:('AUCF', AUCFPart),
2325     14:('CJRQ', CJRQPart),
2326     15:('CJCF', CJCFPart),
2327     25:('SDRQ', SDRQPart),
2328     26:('SDIN', SDINPart)}
2329     def strvalue(self):
2330     return "0x%.2x (%d) %s" % (self.value, self.value,
2331     self.typestr)
2332    
2333     def parse(self, data):
2334     data = Integer8Part.parse(self, data)
2335     self.value = self.value >> 2
2336     (self.typestr, self.parser) = self.types.get(self.value,
2337     ("Unknown",
2338     PacketPart))
2339     return data
2340    
2341     class MCStype16(Integer16Part):
2342    
2343     classname = "MCStype16"
2344    
2345     types = {0x7f65:'Connect Initial',
2346     0x7f66:'Connect Response'}
2347     def strvalue(self):
2348     return "0x%.4x (%d) %s" % (self.value, self.value,
2349     self.types.get(self.value, "Unknown"))
2350    
2351    
2352     def __init__(self, description, **kw):
2353     PacketPart.__init__(self, description, **kw)
2354     self.datatype = "MCS packet"
2355    
2356     def parse(self, data):
2357     origdata = data
2358     mcstype = self.MCStype8("MCS type", indent=self.indent+1)
2359     ndata = mcstype.parse(data)
2360     if 0x1f == mcstype.value:
2361     mcstype = self.MCStype16("MCS type", indent=self.indent+1)
2362     data = mcstype.parse(data)
2363     else:
2364     data = ndata
2365    
2366     if 0x7f65 == mcstype.value:
2367     rempkt = MCSConnInitialPacket("",
2368     indent=self.indent+1)
2369     elif 0x7f66 == mcstype.value:
2370     rempkt = MCSConnResponsePacket("",
2371     indent=self.indent+1)
2372     else:
2373     self.value.append(mcstype)
2374     rempkt = mcstype.parser("", indent=self.indent+1)
2375     self.value.append(rempkt)
2376     return rempkt.parse(data)
2377    
2378    
2379     self.value.append(rempkt)
2380    
2381     # Special case - we print the type twice. Probably not good..
2382     data = rempkt.parse(origdata)
2383    
2384     return data
2385    
2386    
2387     class ISOPacket(PacketPart):
2388    
2389     classname = "TPDU"
2390    
2391     class ISOPacketType(Integer8Part):
2392    
2393     classname = "TPDU"
2394    
2395     types = {0xe0:'Connection request',
2396     0xd0:'Connection confirm',
2397     0x80:'Disconnect request',
2398     0xf0:'Data',
2399     0x70:'Error'}
2400    
2401     def strvalue(self):
2402     return "0x%.2x (%d) %s" % (self.value, self.value,
2403     self.types.get(self.value, "Unknown"))
2404     def __init__(self, description, **kw):
2405     PacketPart.__init__(self, description, **kw)
2406     self.datatype = "TPDU"
2407    
2408     def parse(self, data):
2409     headerlen = Integer8Part("TPDU hdr length", indent=self.indent+1)
2410     self.value.append(headerlen)
2411    
2412     isotype = self.ISOPacketType("TPDU packet type", indent=self.indent+1)
2413     self.value.append(isotype)
2414    
2415     data = headerlen.parse(data)
2416     data = isotype.parse(data)
2417    
2418     if 2 == headerlen.value:
2419     eot = Integer8Part("TPDU eot", knvalue = 0x80, indent=self.indent+1)
2420     self.value.append(eot)
2421     data = eot.parse(data)
2422     mcs = MCSPacket("", indent=self.indent+1)
2423     self.value.append(mcs)
2424     data = mcs.parse(data)
2425    
2426     else:
2427     dst_ref = Integer16Part("Dst ref", indent=self.indent+1)
2428     self.value.append(dst_ref)
2429    
2430     src_ref = Integer16Part("Src ref", indent=self.indent+1)
2431     self.value.append(src_ref)
2432    
2433     cls = Integer8Part("Class", indent=self.indent+1)
2434     self.value.append(cls)
2435    
2436     data = dst_ref.parse(data)
2437     data = src_ref.parse(data)
2438     data = cls.parse(data)
2439    
2440     return data
2441    
2442    
2443     class TPKT(PacketPart):
2444    
2445     classname = "TPKT"
2446    
2447     def __init__(self, description, **kw):
2448     PacketPart.__init__(self, description, **kw)
2449     self.datatype = "TPKT"
2450    
2451     def parse(self, data):
2452    
2453     self.value.append(Integer8Part("TPKT version", indent=self.indent+1,
2454     knvalue = 3))
2455     self.value.append(Integer8Part("TPKT reserved", indent=self.indent+1,
2456     knvalue = 0))
2457     self.value.append(Integer16Part("TPKT length", indent=self.indent+1))
2458     self.value.append(ISOPacket("", indent=self.indent+1))
2459    
2460     for dp in self.value:
2461     data = dp.parse(data)
2462    
2463     if (0 < len(data)):
2464     mstshash = Latin1String("mstshash", len(data)-2, nonullchar=1,
2465     indent=self.indent+1)
2466     self.value.append(mstshash)
2467     data = mstshash.parse(data)
2468    
2469     if (0 < len(data)):
2470     remaining = Integer16lePart("Unknown", indent=self.indent+1)
2471     data = remaining.parse(data)
2472     self.value.append(remaining)
2473    
2474    
2475    
2476    
2477    
2478     return data
2479    
2480    
2481     class OrdersPart(PacketPart):
2482    
2483     classname = "OrdersPart"
2484    
2485     def __init__(self, description, **kw):
2486     PacketPart.__init__(self, description, **kw)
2487     self.datatype = "Orders"
2488    
2489     def parse(self, data):
2490     if None != self.maxlength:
2491     returndata = data[self.maxlength:]
2492     data = data[:self.maxlength]
2493    
2494     self.value.append(Integer16lePart("Order count",
2495     indent=self.indent+1))
2496     self.value.append(PacketPart("Order data",
2497     indent=self.indent+1))
2498    
2499     for dp in self.value:
2500     data = dp.parse(data)
2501    
2502     return returndata
2503    
2504    
2505    
2506     class BitmapUpdatePart(PacketPart):
2507    
2508     classname = "BitmapUpdatePart"
2509    
2510     class UpdateSubPart(PacketPart):
2511    
2512     classname = "UpdateSubPart"
2513    
2514     def __init__(self, description, **kw):
2515     PacketPart.__init__(self, description, **kw)
2516     self.datatype = "Bitmap update subpart"
2517    
2518     def parse(self, data):
2519     pad = Integer16lePart("Pad?", indent=self.indent+1)
2520     left = Integer16lePart("Left", indent=self.indent+1)
2521     top = Integer16lePart("Top", indent=self.indent+1)
2522     right = Integer16lePart("Right", indent=self.indent+1)
2523     bottom = Integer16lePart("Bottom", indent=self.indent+1)
2524     width = Integer16lePart("Width", indent=self.indent+1)
2525     height = Integer16lePart("Height", indent=self.indent+1)
2526     bpp = Integer16lePart("bpp", indent=self.indent+1)
2527     compress = Integer16lePart("Compress", indent=self.indent+1)
2528     bufsize = Integer16lePart("Bufsize", indent=self.indent+1)
2529    
2530     self.value = [pad, left, top, right, bottom, width,
2531     height, bpp, compress, bufsize]
2532    
2533     for dp in self.value:
2534     data = dp.parse(data)
2535    
2536     bmpdata = None
2537     Bpp = (bpp.value+7) / 8
2538    
2539     if not compress.value:
2540     bmpdata = PacketPart("BMP data (not compressed)", indent=self.indent+1,
2541     maxlength=width.value*height.value*Bpp)
2542     data = bmpdata.parse(data)
2543     self.value.append(bmpdata)
2544     return data
2545    
2546     valuelen = len(self.value)
2547    
2548     if compress.value & 0x400:
2549     size = bufsize
2550     else:
2551     self.value.append(Integer16Part("Pad", indent=self.indent+1))
2552     size = Integer16lePart("Size", indent=self.indent+1)
2553     self.value.append(size)
2554     self.value.append(Integer16lePart("Line size", indent=self.indent+1))
2555     self.value.append(Integer16lePart("Final size", indent=self.indent+1))
2556     for dp in self.value[valuelen:]:
2557     data = dp.parse(data)
2558    
2559     bmpdata = PacketPart("BMP data (compressed)", indent=self.indent+1,
2560     maxlength=size.value)
2561     data = bmpdata.parse(data)
2562     self.value.append(bmpdata)
2563     return data
2564    
2565     def __init__(self, description, **kw):
2566     PacketPart.__init__(self, description, **kw)
2567     self.datatype = "Bitmap update"
2568    
2569     def parse(self, data):
2570     if None != self.maxlength:
2571     returndata = data[self.maxlength:]
2572     data = data[:self.maxlength]
2573    
2574     num_updates = Integer16lePart("# of updates", indent=self.indent+1)
2575     data = num_updates.parse(data)
2576     self.value.append(num_updates)
2577    
2578     for i in range(num_updates.value):
2579     self.value.append(self.UpdateSubPart("%d" % i, indent=self.indent+1))
2580    
2581     for dp in self.value[1:]:
2582     data = dp.parse(data)
2583    
2584     if 0 < len(data):
2585     remaining_data = PacketPart("Remaining Bitmap update data", indent=self.indent+1)
2586     remaining_data.parse(data)
2587     self.value.append(remaining_data)
2588    
2589     return returndata
2590    
2591     class RDP5Packet(PacketPart):
2592    
2593     classname = "RDP5Packet"
2594    
2595     class RDP5StartByte(Integer8Part):
2596    
2597     classname = "RDP5StartByte"
2598    
2599     def strvalue(self):
2600     ret = Integer8Part.strvalue(self)
2601     if self.value & 0x80:
2602     ret+=", encrypted"
2603     ret+=", %d inputs" % ((self.value & 124) >> 2)
2604     return ret
2605    
2606     class RDP5PacketType(Enumerated):
2607    
2608     classname = "RDP5PacketType"
2609    
2610     def __init__(self, description, **kw):
2611     Enumerated.__init__(self, description, **kw)
2612     self.datatype = "RDP5 packetpart"
2613    
2614     results = {0x00:('Orders', OrdersPart),
2615     0x01:('Bitmap update', BitmapUpdatePart),
2616     0x02:'Palette',
2617     0x03:'Palette with offset 3(?)',
2618     0x05:'NullSystemPointer(?)',
2619     0x06:'DefaultSystemPointer(?)',
2620     0x07:'MonoPointer(?)',
2621     0x08:'Position(?)',
2622     0x09:'ColourPointer(?)',
2623     0x0a:'CachedPointer(?)',
2624     0x0b:'Mouse pointer (b/w)'}
2625    
2626     def __init__(self, description, **kw):
2627     PacketPart.__init__(self, description, **kw)
2628     self.datatype = "RDP5 packet"
2629    
2630     def encrypted(self):
2631     return self.startbyte.value & 0x80
2632    
2633     def parse(self, data):
2634     self.startbyte = self.RDP5StartByte("RDP5 start byte",
2635     indent=self.indent+1)
2636     self.value.append(self.startbyte)
2637    
2638     remaining_length = MSVariableInt("Packet length",
2639     indent=self.indent+1,
2640     knvalue=len(data))
2641     self.value.append(remaining_length)
2642    
2643     valuelen = len(self.value)
2644    
2645     for dp in self.value:
2646     data = dp.parse(data)
2647    
2648     if self.encrypted():
2649     cryptsig = PacketPart("Cryptsig", indent=self.indent+1)
2650     self.value.append(cryptsig)
2651     cryptsig.parse(data[:8])
2652     data = data[8:]
2653     valuelen+=1
2654    
2655     while 0 < len(data):
2656     pt = self.RDP5PacketType("",
2657     indent=self.indent+2)
2658     self.value.append(pt)
2659     data = pt.parse(data)
2660     partlen = Integer16lePart("Partlen(?)",
2661     indent=self.indent+2)
2662     self.value.append(partlen)
2663     data = partlen.parse(data)
2664    
2665     partdata = pt.parser("Part data", indent=self.indent+3,
2666     maxlength=partlen.value)
2667     data = partdata.parse(data)
2668     self.value.append(partdata)
2669    
2670     remaining_data = PacketPart("Remaining data",
2671     indent=self.indent+1)
2672     self.value.append(remaining_data)
2673     return remaining_data.parse(data)
2674    
2675     class LaTeXindex:
2676     def __init__(self):
2677     self.figs = []
2678    
2679     def append(self, filename, description):
2680     self.figs.append((filename, description))
2681    
2682     def __str__(self):
2683     ret = """
2684     \\documentclass{report}
2685     \\usepackage[english]{babel}
2686     \\usepackage[latin1]{inputenc}
2687     \\usepackage{graphicx}
2688     \\begin{document}
2689    
2690     """
2691     for (filename, description) in self.figs:
2692     ret+= """
2693     \\begin{figure}[h]
2694     \\includegraphics{%s.eps}
2695     \\caption{%s}
2696     \\label{fig:%s}
2697     \\end{figure}
2698    
2699     """ % (filename, description, filename)
2700    
2701     ret+= """
2702     \\end{document}
2703    
2704    
2705     """
2706     return ret
2707    
2708    
2709    
2710    
2711    
2712     clsrefs = {}
2713    
2714    
2715     def create_tbl(ofile, p, origin, totpacketno, packetno,
2716     location, classnames, infilename):
2717     if "Server" == origin:
2718     origin = "S"
2719     else:
2720     origin = "C"
2721    
2722     class PlaceHolder(PacketPart):
2723     def strvalue(self):
2724     return self.value
2725    
2726     def rec(part, res, packetno):
2727     if type([]) == type(part.value):
2728     newvalue = []
2729     partno = 0
2730     for subpart in part.value:
2731     if isinstance(subpart, PacketPart) and subpart.owntbl:
2732     subpart.packetno = "%s%d" % (packetno, partno)
2733     res.append(subpart)
2734     rec(subpart, res, "%s%d-" % (packetno, partno))
2735    
2736     placeholder = PlaceHolder(subpart.description)
2737     placeholder.datatype = subpart.datatype
2738     placeholder.value = "See %s%s%d" % (origin, packetno, partno)
2739     newvalue.append(placeholder)
2740    
2741     partno+=1
2742     else:
2743     newvalue.append(subpart)
2744     part.value = newvalue
2745    
2746    
2747     if 0 == totpacketno:
2748     return
2749    
2750     res = [p]
2751     p.packetno = packetno
2752     rec(p, res, "%d-" % packetno)
2753    
2754     outfile = None
2755    
2756     for ppart in res:
2757     if location:
2758     if outfile:
2759     outfile.close()
2760     if classnames:
2761     num = 0
2762     if clsrefs.has_key(ppart.classname):
2763     num = clsrefs[ppart.classname]
2764     clsrefs[ppart.classname]+=1
2765     else:
2766     clsrefs[ppart.classname]=1
2767     path = os.path.join(location, "%s-%d-%s%d-%s-%d.tbl" % (infilename.replace(".", "-"), totpacketno, origin, packetno, ppart.classname, num))
2768     else:
2769     path = os.path.join(location, "%s%s.tbl" % (origin, ppart.packetno))
2770     outfile = open(path, 'w')
2771     else:
2772     outfile = ofile
2773     print >> outfile, """
2774     .TS
2775     box;
2776     lB| cB s s s s
2777     r l l l l l
2778     r l l l l l.
2779     %s%s (%s)\t%s %s\t
2780     _
2781     Offset\tDatatype\tDescription\tExpected value\tValue\t
2782     _""" % (origin, ppart.packetno, ppart.classname, ppart.datatype, ppart.description)
2783    
2784     s = ""
2785     offset = 0
2786     if type([]) == type(ppart.value):
2787     for subpart in ppart.value:
2788     if type("") == type(subpart):
2789     print >> outfile, "(str)\t\t\t%s\t" % (subpart)
2790     else:
2791     print >> outfile, "%d\t%s" % (offset,
2792     subpart.tblvalue(offset=offset))
2793     offset+=len(subpart)
2794    
2795     else:
2796     s = "off\t%s\t%s\t" % (ppart.datatype,
2797     ppart.description)
2798     if None != ppart.knvalue:
2799     s+=str(ppart.knvalue)
2800     s+="\t%s\t" % ppart.value
2801     print >> outfile, s
2802     print >> outfile, ".TE\n"
2803    
2804    
2805     def create_latex(ofile, p, origin, totpacketno, packetno,
2806     location, classnames, infilename):
2807     if "Server" == origin:
2808     origin = "S"
2809     else:
2810     origin = "C"
2811    
2812     class PlaceHolder(PacketPart):
2813     def strvalue(self):
2814     return self.value
2815    
2816     def rec(part, res, packetno):
2817     if type([]) == type(part.value):
2818     newvalue = []
2819     partno = 0
2820     for subpart in part.value:
2821     if isinstance(subpart, PacketPart) and subpart.owntbl:
2822     subpart.packetno = "%s%d" % (packetno, partno)
2823     res.append(subpart)
2824     rec(subpart, res, "%s%d-" % (packetno, partno))
2825    
2826     placeholder = PlaceHolder(subpart.description)
2827     placeholder.datatype = subpart.datatype
2828     placeholder.value = "\pktref{%s%s%d}" % (origin,
2829     packetno,
2830     partno)
2831     newvalue.append(placeholder)
2832    
2833     partno+=1
2834     else:
2835     newvalue.append(subpart)
2836     part.value = newvalue
2837    
2838    
2839     if 0 == totpacketno:
2840     return
2841    
2842     res = [p]
2843     p.packetno = packetno
2844     rec(p, res, "%d-" % packetno)
2845    
2846     outfile = None
2847    
2848     summaryfile = open(os.path.join(location, "%s-%d-summary.tex" % (infilename.replace(".", "-"), totpacketno)), 'w')
2849    
2850     print >> summaryfile, """
2851     \\begin{tabular}{l}"""
2852    
2853     fname = ""
2854    
2855     i = 0
2856     for ppart in res:
2857     if location:
2858     if outfile:
2859     outfile.close()
2860     if classnames:
2861     num = 0
2862     if clsrefs.has_key(ppart.classname):
2863     num = clsrefs[ppart.classname]
2864     clsrefs[ppart.classname]+=1
2865     else:
2866     clsrefs[ppart.classname]=1
2867     fname = "%s-%d-%s%d-%s-%d.tex" % (infilename.replace(".", "-"), totpacketno, origin, packetno, ppart.classname, num)
2868     else:
2869     fname = "%s%s.tex" % (origin, ppart.packetno)
2870     outfile = open(os.path.join(location, fname), 'w')
2871     else:
2872     outfile = ofile
2873     print >> outfile, LaTeX_escape("\pkttab{%s%s}{%s %s}{\n" % (origin, ppart.packetno, ppart.datatype, ppart.description))
2874    
2875    
2876     s = ""
2877     offset = 0
2878     if type([]) == type(ppart.value):
2879     for subpart in ppart.value:
2880     if type("") == type(subpart):
2881     print >> outfile, LaTeX_escape("(str)&&&&%s\\\\" % (subpart))
2882     else:
2883     print >> outfile, LaTeX_escape("%d & %s" % (offset,
2884     subpart.latexvalue(offset=offset)))
2885     offset+=len(subpart)
2886    
2887     else:
2888     s = "off & %s & %s & " % (ppart.datatype,
2889     ppart.description)
2890     if None != ppart.knvalue:
2891     s+=str(ppart.knvalue)
2892     s+="& %s \\\\" % ppart.value
2893     print >> outfile, LaTeX_escape(s)
2894     print >> outfile, "}\n"
2895     if id(ppart) != id(res[-1:][0]):
2896     print >> summaryfile, "\input{%s}\\\\[\\betweenpktheight]" % os.path.join("figures", "pktfigs", fname)
2897     else:
2898     print >> summaryfile, "\input{%s}\\\\" % os.path.join("figures", "pktfigs", fname)
2899    
2900     print >> summaryfile, """\n\\end{tabular}"""
2901    
2902    
2903    
2904    
2905    
2906    
2907     def parse_rdpproxy(infile, outfile, outputformat, location,
2908     classnames, infilename, wantedchannels, quiet):
2909     pktre = re.compile("#([0-9]*?), #([0-9]*?) from (Server|Client), type (TPKT|RDP5), l: ([0-9]*), ")
2910     databeginre = re.compile("^0000 [0-9]{2} ")
2911     line = infile.readline()
2912     while line:
2913     mo = pktre.search(line)
2914     if None != mo:
2915     headerline = line
2916     totpacketno = int(mo.group(1))
2917     partpacketno = int(mo.group(2))
2918     part = mo.group(3)
2919     pkttype = mo.group(4)
2920     pktlength = int(mo.group(5))
2921     line = infile.readline()
2922     while None == databeginre.search(line): # Unknown data, print.
2923     line = infile.readline()
2924     # We are now expecting pktlength bytes of data
2925     data = line[5:53]
2926     lines = pktlength / 16
2927     if pktlength % 16:
2928     lines+=1
2929     lines-=1
2930     for i in range(lines):
2931     thisdata = infile.readline()[5:53]
2932     data+= thisdata
2933     data = map(lambda x: string.atoi(x, 16), data.strip().split(' '))
2934     remaining = []
2935     if "TPKT" == pkttype:
2936     p = TPKT("from %s" % part)
2937     remaining = p.parse(data)
2938     elif "RDP5" == pkttype:
2939     p = RDP5Packet("from %s" % part)
2940     remaining = p.parse(data)
2941     global currentchannel
2942     if 0 < len(wantedchannels) and currentchannel not in wantedchannels:
2943     line = infile.readline()
2944     continue
2945     currentchannel = 0
2946     if "TBL" == outputformat:
2947     create_tbl(outfile, p, part, totpacketno, partpacketno, location, classnames, infilename)
2948     elif "LATEX" == outputformat:
2949     create_latex(outfile, p, part, totpacketno, partpacketno, location, classnames, infilename)
2950     else:
2951     if not quiet:
2952     outfile.write(headerline)
2953     print >> outfile, p
2954     if 0 < len(remaining):
2955     rempkt = PacketPart("Remaining data")
2956     rempkt.parse(remaining)
2957     print >> outfile, rempkt
2958    
2959     else: # Unknown data line, just print it out.
2960     if not quiet and "TXT" == outputformat:
2961     outfile.write("Unknown data: %s" % line)
2962    
2963     outfile.flush()
2964     line = infile.readline()
2965    
2966    
2967    
2968     def print_usage(progname):
2969     print "%s <infile> <outfile>" % progname
2970     print "<infile> and <outfile> may be '-' to use stdin/stdout"
2971     print
2972     print "OPTIONS is zero or more of the following:"
2973     print "-f <outputformat> specifies that another format than text is wanted."
2974     print " Possible formats are TXT (default), TBL and LATEX"
2975     print "-l Specifies where the files produced by the TBL and LATEX formats should be written."
2976     print " When this flag is used, outfile can be left out"
2977     print "-n Use the names of the classes when printing out TBL and LATEX"
2978     print "-c <channels> Print only output from specific channels."
2979     print "-q Be quiet."
2980     print "--help Print this not very helpful message :-)"
2981     print
2982    
2983     if '__main__' == __name__:
2984     now = time.time()
2985     optlist, args = getopt.getopt(sys.argv[1:], 'f:l:ni:c:q')
2986    
2987     outputformat = "TXT"
2988     location = None
2989     classnames = None
2990     ltxindex_out = None
2991     channels = []
2992     quiet = 0
2993     for arg, opt in optlist:
2994     if '-f' == arg:
2995     outputformat = opt
2996     if '-l' == arg:
2997     location = opt
2998     if '-n' == arg:
2999     classnames = 1
3000     if '-c' == arg:
3001     channels = map(int, opt.split(','))
3002     if '-q' == arg:
3003     quiet = 1
3004     if '--help' == arg:
3005     print_usage(sys.argv[0])
3006     sys.exit(0)
3007    
3008     if len(args) < 2 and not location:
3009     print_usage(sys.argv[0])
3010     sys.exit(0)
3011    
3012     infile = sys.stdin
3013     outfile = sys.stdout
3014    
3015     infilename = "stdin"
3016    
3017     if '-' != args[0]:
3018     infilename = os.path.basename(args[0])
3019     infile = open(args[0], 'r')
3020     if not location and '-' != args[1]:
3021     outfile = open(args[1], 'w')
3022    
3023     parse_rdpproxy(infile, outfile, outputformat, location,
3024     classnames, infilename, channels, quiet)
3025    
3026     print "Total processing time: %.2f seconds" % (time.time() - now)
3027    
3028     if sys.stdin != outfile:
3029     infile.close()
3030     if sys.stdout != outfile:
3031     outfile.close()
3032    
3033    
3034     # sys.argv = ["ARGL!", '/home/forsberg/xjobb/sniff/w2ktsk.1.out', '/home/forsberg/xjobb/rdpproxy/p.out']

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26