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