1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 let compatibleclient = ref 10
36 let get_emule_version () =
37 (!compatibleclient lsl 24) lor
38 (int_of_string
(Autoconf.major_version
) lsl 17) lor
39 (int_of_string
(Autoconf.minor_version
) lsl 10) lor
40 (int_of_string
(Autoconf.sub_version
) lsl 7)
42 let mldonkey_emule_proto =
44 emule_version
= get_emule_version ();
46 emule_osinfosupport
= 1;
49 (* emule_miscoptions1 *)
50 received_miscoptions1
= false;
54 emule_compression
= 1;
55 emule_secident
= 3; (* Emule uses v1 if advertising both, v2 if only advertising 2 *)
56 emule_sourceexchange
= 2; (* 2 : +client_md4 3 : +IdHybrid (emule Kademlia?)*)
57 emule_extendedrequest
= 1; (* 1: +file_status 2: +ncomplete_sources*)
60 emule_noviewshared
= 0;
61 emule_multipacket
= 0;
62 emule_supportpreview
= 0;
64 (* emule_miscoptions2 *)
65 received_miscoptions2
= false;
66 emule_require_crypt
= 0;
67 emule_request_crypt
= 0;
68 emule_support_crypt
= 0;
69 emule_extmultipacket
= 0;
71 emule_kad_version
= 0;
74 let emule_miscoptions1 m
=
76 (m
.emule_aich
lsl 29) lor
77 (m
.emule_unicode
lsl 28) lor
78 (m
.emule_udpver
lsl 24) lor
79 (m
.emule_compression
lsl 20) lor
80 (m
.emule_secident
lsl 16) lor
81 (m
.emule_sourceexchange
lsl 12) lor
82 (m
.emule_extendedrequest
lsl 8) lor
83 (m
.emule_comments
lsl 4) lor
84 (m
.emule_peercache
lsl 3) lor
85 (m
.emule_noviewshared
lsl 2) lor
86 (m
.emule_multipacket
lsl 1) lor
87 (m
.emule_supportpreview
lsl 0)
91 let update_emule_proto_from_miscoptions1 m
o =
92 let o = Int64.to_int
o in
93 m
.emule_aich
<- (o lsr 29) land 0x7;
94 m
.emule_unicode
<- (o lsr 28) land 0xf;
95 m
.emule_udpver
<- (o lsr 24) land 0xf;
96 m
.emule_compression
<- (o lsr 20) land 0xf;
97 m
.emule_secident
<- (o lsr 16) land 0xf;
98 m
.emule_sourceexchange
<- (o lsr 12) land 0xf;
99 m
.emule_extendedrequest
<- (o lsr 8) land 0xf;
100 m
.emule_comments
<- (o lsr 4) land 0xf;
101 m
.emule_peercache
<- (o lsr 3) land 0x1;
102 m
.emule_noviewshared
<- (o lsr 2) land 0x1;
103 m
.emule_multipacket
<- (o lsr 1) land 0x1;
104 m
.emule_supportpreview
<- (o lsr 0) land 0x1
106 let print_emule_proto_miscoptions1 m
=
107 let buf = Buffer.create
50 in
108 if m
.emule_aich
<> 0 then Printf.bprintf
buf " aich %d\n" m
.emule_aich
;
109 if m
.emule_unicode
<> 0 then Printf.bprintf
buf " unicode %d\n" m
.emule_unicode
;
110 if m
.emule_udpver
<> 0 then Printf.bprintf
buf " udpver %d\n" m
.emule_udpver
;
111 if m
.emule_compression
<> 0 then Printf.bprintf
buf " compression %d\n" m
.emule_compression
;
112 if m
.emule_secident
<> 0 then Printf.bprintf
buf " secident %d\n" m
.emule_secident
;
113 if m
.emule_sourceexchange
<> 0 then Printf.bprintf
buf " sourceexchange %d\n" m
.emule_sourceexchange
;
114 if m
.emule_extendedrequest
<> 0 then Printf.bprintf
buf " extendedrequest %d\n" m
.emule_extendedrequest
;
115 if m
.emule_comments
<> 0 then Printf.bprintf
buf " comments %d\n" m
.emule_comments
;
116 if m
.emule_peercache
<> 0 then Printf.bprintf
buf " peercache %d\n" m
.emule_peercache
;
117 if m
.emule_noviewshared
<> 0 then Printf.bprintf
buf " noviewshared %d\n" m
.emule_noviewshared
;
118 if m
.emule_multipacket
<> 0 then Printf.bprintf
buf " multipacket %d\n" m
.emule_multipacket
;
119 if m
.emule_supportpreview
<> 0 then Printf.bprintf
buf " supportpreview %d\n" m
.emule_supportpreview
;
122 let emule_miscoptions2 m
=
124 (m
.emule_largefiles
lsl 4)
128 let update_emule_proto_from_miscoptions2 m
o =
129 let o = Int64.to_int
o in
130 m
.emule_require_crypt
<- (o lsr 9) land 0x1;
131 m
.emule_request_crypt
<- (o lsr 8) land 0x1;
132 m
.emule_support_crypt
<- (o lsr 7) land 0x1;
133 m
.emule_extmultipacket
<- (o lsr 5) land 0x1;
134 m
.emule_largefiles
<- (o lsr 4) land 0x1;
135 m
.emule_kad_version
<- (o lsr 0) land 0xf
137 let print_emule_proto_miscoptions2 m
=
138 let buf = Buffer.create
50 in
139 if m
.emule_require_crypt
<> 0 then Printf.bprintf
buf " require_crypt %d\n" m
.emule_require_crypt
;
140 if m
.emule_request_crypt
<> 0 then Printf.bprintf
buf " request_crypt %d\n" m
.emule_request_crypt
;
141 if m
.emule_support_crypt
<> 0 then Printf.bprintf
buf " support_crypt %d\n" m
.emule_support_crypt
;
142 if m
.emule_extmultipacket
<> 0 then Printf.bprintf
buf " extmultipacket %d\n" m
.emule_extmultipacket
;
143 if m
.emule_largefiles
<> 0 then Printf.bprintf
buf " largefiles %d\n" m
.emule_largefiles
;
144 if m
.emule_kad_version
<> 0 then Printf.bprintf
buf " kad_version %d\n" m
.emule_kad_version
;
147 let emule_compatoptions m
=
148 (m
.emule_osinfosupport
lsl 0)
150 let update_emule_proto_from_compatoptions m
o =
151 m
.emule_osinfosupport
<- (o lsr 0) land 0x1
153 let extendedrequest e
=
154 min e
.emule_extendedrequest
mldonkey_emule_proto.emule_extendedrequest
156 let sourceexchange e
=
157 min e
.emule_sourceexchange
mldonkey_emule_proto.emule_sourceexchange
160 BAD MESSAGE FROM CONNECTING CLIENT
162 ascii: [(1)(16)(231)(129)(131)(26) O(247)(154)(145)(251)(253)(167) G }(207) j(146)(140) { l(139) F(18)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)]
166 (231)(129)(131)(26)(79)(247)(154)(145)(251)(253)(167)(71)(125)(207)(106)(146)
173 let rec lbprint_tags buf tags
=
175 [] -> Printf.bprintf
buf ""
177 Printf.bprintf
buf " (%s)=(%s)" (escaped_string_of_field tag
)
178 (string_of_tag_value tag
.tag_value
);
179 lbprint_tags buf tags
181 module Connect
= struct
188 server_info
: (Ip.t
* int) option;
192 let names_of_tag = client_common_tags
195 List.map
(fun (v
, name
) -> (v
, Field_KNOWN name
)) names_of_tag
197 let parse reply len s
=
198 let hash_len, pos
= if not reply
then get_uint8 s
1, 2 else -1, 1 in
199 let md4 = get_md4 s pos
in
200 let ip = get_ip s
(pos
+16) in
201 let port = get_port s
(pos
+20) in
202 let tags, pos
= get_tags s
(pos
+22) names_of_tag in
203 let server_info = Some
(get_ip s pos
, get_port s
(pos
+4)) in
204 let left_bytes = String.sub s
(pos
+6) (String.length s
- pos
- 6) in
211 server_info = server_info;
212 left_bytes = left_bytes;
217 let b1 = Buffer.create
50 in
218 let b2 = Buffer.create
5 in
219 lbprint_tags b1 t
.tags;
220 String.iter
(fun c
-> Printf.bprintf
b2 "(%d)" (int_of_char c
)) t
.left_bytes;
221 lprintf_nl
"Connect [hl: %d] [md4: %s] [ip: %s:%d] [server: %s] [left: %s] [tags:%s]"
223 (Md4.to_string t
.md4)
224 (Ip.to_string t
.ip) t
.port
225 (match t
.server_info with
227 | Some
(ip, port) -> Printf.sprintf
"%s:%d" (Ip.to_string
ip) port)
228 (if String.length t
.left_bytes <> 0 then (Buffer.contents
b2) else "None")
232 let write reply
buf t
=
239 buf_tags
buf t
.tags names_of_tag;
241 match t
.server_info with
256 let (s
, p
) = get_string s
1 in
260 lprintf_nl
"SAY %s" t
266 module OneMd4
= functor(M
: sig val m
: string end) -> (struct
273 lprintf_nl
"OneMd4: %s OF %s" M.m
(Md4.to_string t
)
280 module JoinQueue
= struct
281 type t
= Md4.t
option
289 lprintf_nl
"JOIN QUEUE %s"
290 (match t
with None
-> "" | Some
md4 ->
291 Printf.sprintf
"OF %s" (Md4.to_string
md4))
293 let write emule
buf t
=
294 if extendedrequest emule
> 0 then
303 val parse : int -> string -> t
304 val print : t -> unit
305 val write : Buffer.t -> t -> unit
311 (* In Emule, this message contains much more information, and will probably
312 remove the need for QueryChunks. *)
314 let get_bitmap s pos
=
315 let nchunks = get_int16 s pos
in
317 if nchunks = 0 then (Bitv.create
0 false), pos
+2 else
319 let chunks = (Bitv.create
nchunks false) in
320 for i
= 0 to (nchunks-1) / 8 do
321 let m = get_uint8 s
(pos + i
) in
325 Bitv.set
chunks n ((m land (1 lsl j
)) <> 0);
328 let pos = pos + (nchunks-1)/8 + 1 in
333 let print_bitmap chunks =
334 lprintf
"\n%s\n" (Bitv.to_string
chunks)
336 let write_bitmap buf chunks =
337 let nchunks = Bitv.length
chunks in
338 buf_int16
buf nchunks;
340 for i
= 0 to (nchunks-1) / 8 do
345 if (Bitv.get
chunks n) then
346 m := !m lor (1 lsl j
);
351 module QueryFile
= struct
354 emule_extension
: (Bitv.t
* int) option;
357 let parse emule len s
=
358 (* lprintf "Query File: emule version %d len %d"
359 (extendedrequest emule) len;
361 let md4 = get_md4 s
1 in
362 let emule_extension =
364 if len
< 18 || extendedrequest emule
= 0 then None
else
365 let chunks, pos = get_bitmap s
17 in
366 let ncompletesources =
367 if extendedrequest emule
> 1 && len
> pos+1 then get_int16 s
pos
369 Some
(chunks, ncompletesources)
373 emule_extension = emule_extension }
376 lprintf_nl
"QUERY FILE OF %s" (Md4.to_string t
.md4);
377 match t
.emule_extension with
379 | Some
(bitmap
, ncompletesources) ->
382 if ncompletesources >= 0 then
383 lprintf_nl
"Complete sources: %d" ncompletesources
385 let write emule
buf t
=
387 match t
.emule_extension with
389 | Some
(chunks, ncompletesources) ->
390 if extendedrequest emule
> 0 then begin
391 write_bitmap buf chunks;
392 if extendedrequest emule
> 1 && ncompletesources >= 0 then
393 buf_int16
buf ncompletesources
397 module QueryChunks
= OneMd4
(struct let m = "QUERY CHUNKS" end)
400 module QueryChunkMd4
= OneMd4
(struct let m = "QUERY CHUNKS MD4" end)
401 module EndOfDownload
= OneMd4
(struct let m = "END OF DOWNLOAD MD4" end)
402 module NoSuchFile
= OneMd4
(struct let m = "NO SUCH FILE" end)
404 module QueryChunksReply
= struct (* Request 80 *)
412 let md4 = get_md4 s
1 in
413 let chunks, pos = get_bitmap s
17 in
420 lprintf_nl
"CHUNKS for %s" (Md4.to_string t
.md4);
421 lprintf_nl
"%s\n" (Bitv.to_string t
.chunks)
425 write_bitmap buf t
.chunks;
426 if Bitv.length t
.chunks = 0 then buf_int8
buf 0
429 dec: [(96)(215)(1)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)]
431 OP_QUEUERANKING: int16
434 module QueryChunkMd4Reply
= struct (* Request 80 *)
442 let md4 = get_md4 s
1 in
443 let nchunks = get_int16 s
17 in
444 (* lprintf "nchunks : %d" nchunks; lprint_newline (); *)
445 let chunks = Array.create
nchunks md4 in
446 for i
= 0 to nchunks - 1 do
447 chunks.(i
) <- get_md4 s
(19 + i
* 16)
455 lprintf_nl
"CHUNKSMd4 for %s" (Md4.to_string t
.md4);
458 lprintf
" %s" (Md4.to_string b
))
464 let nchunks = Array.length t
.chunks in
465 buf_int16
buf nchunks;
466 for i
= 0 to nchunks - 1 do
467 buf_md4
buf t
.chunks.(i
)
471 module QueryFileReply
= struct
478 let name, _
= get_string s
17 in
484 lprintf_nl
"QUERY FILE REPLY OF %s : \"%s\"" (Md4.to_string t
.md4) t
.name
488 buf_string
buf t
.name
502 let parse usesixtyfour len s
=
505 usesixtyfour
= usesixtyfour
;
506 start_pos
= if usesixtyfour
then get_int64 s
17 else get_uint64_32 s
17;
507 end_pos
= if usesixtyfour
then get_int64 s
25 else get_uint64_32 s
21;
509 bloc_begin
= if usesixtyfour
then 33 else 25;
510 bloc_len
= if usesixtyfour
then len
- 33 else len
- 25;
514 lprintf_nl
"BLOC OF %s len %Ld [%Ld - %Ld] " (Md4.to_string t
.md4)
515 (t
.end_pos
-- t
.start_pos
)
521 if t
.usesixtyfour
then buf_int64
buf t
.start_pos
else buf_int64_32
buf t
.start_pos
;
522 if t
.usesixtyfour
then buf_int64
buf t
.end_pos
else buf_int64_32
buf t
.end_pos
;
523 Buffer.add_substring
buf t
.bloc_str t
.bloc_begin t
.bloc_len
526 module QueryBloc
= struct
530 start_pos1
: int64
; (* 180 ko *)
538 let parse usesixtyfour len s
=
541 usesixtyfour
= usesixtyfour
;
542 start_pos1
= if usesixtyfour
then get_int64 s
17 else get_uint64_32 s
17;
543 end_pos1
= if usesixtyfour
then get_int64 s
41 else get_uint64_32 s
29;
544 start_pos2
= if usesixtyfour
then get_int64 s
25 else get_uint64_32 s
21;
545 end_pos2
= if usesixtyfour
then get_int64 s
49 else get_uint64_32 s
33;
546 start_pos3
= if usesixtyfour
then get_int64 s
33 else get_uint64_32 s
25;
547 end_pos3
= if usesixtyfour
then get_int64 s
57 else get_uint64_32 s
37;
551 lprintf_nl
"QUERY BLOCS OF %s [%s - %s] [%s - %s] [%s - %s]"
552 (Md4.to_string t
.md4)
553 (Int64.to_string t
.start_pos1
) (Int64.to_string t
.end_pos1
)
554 (Int64.to_string t
.start_pos2
) (Int64.to_string t
.end_pos2
)
555 (Int64.to_string t
.start_pos3
) (Int64.to_string t
.end_pos3
)
559 if t
.usesixtyfour
then buf_int64
buf t
.start_pos1
else buf_int64_32
buf t
.start_pos1
;
560 if t
.usesixtyfour
then buf_int64
buf t
.start_pos2
else buf_int64_32
buf t
.start_pos2
;
561 if t
.usesixtyfour
then buf_int64
buf t
.start_pos3
else buf_int64_32
buf t
.start_pos3
;
562 if t
.usesixtyfour
then buf_int64
buf t
.end_pos1
else buf_int64_32
buf t
.end_pos1
;
563 if t
.usesixtyfour
then buf_int64
buf t
.end_pos2
else buf_int64_32
buf t
.end_pos2
;
564 if t
.usesixtyfour
then buf_int64
buf t
.end_pos3
else buf_int64_32
buf t
.end_pos3
568 module NoArg
= functor(M
: sig val m : string end) -> (struct
576 let write (buf: Buffer.t
) (t
: t
) = unit
581 val parse : int -> string -> t
582 val print : t -> unit
583 val write : Buffer.t -> t -> unit
588 module AvailableSlot
= NoArg
(struct let m = "AvailableSlot" end)
589 module ReleaseSlot
= NoArg
(struct let m = "ReleaseSlot" end)
590 module OutOfParts
= NoArg
(struct let m = "OutOfParts" end)
591 module ViewFiles
= NoArg
(struct let m = "VIEW FILES" end)
592 module ViewDirs
= NoArg
(struct let m = "VIEW DIRS" end)
594 module ViewFilesReply
= struct
603 type t = tagged_file list
605 let names_of_tag = file_common_tags
607 let rec get_files s
pos n =
608 if n = 0 then [], pos else
609 let md4 = get_md4 s
pos in
610 let ip = get_ip s
(pos + 16) in
611 let port = get_port s
(pos + 20) in
612 let tags, pos = get_tags s
(pos+22) names_of_tag in
619 let files, pos = get_files s
pos (n-1) in
623 let n = get_int s
1 in
624 let files, pos = get_files s
5 n in
628 lprintf_nl
"VIEW FILES REPLY:";
631 lprintf_nl
" MD4: %s" (Md4.to_string
t.f_md4
);
632 lprintf_nl
" ip: %s" (Ip.to_string
t.f_ip
);
633 lprintf_nl
" port: %d" t.f_port
;
636 lprint_newline
();) t
638 let rec write_files buf files =
642 buf_md4
buf file.f_md4
;
643 buf_ip
buf file.f_ip
;
644 buf_port
buf file.f_port
;
645 buf_tags
buf file.f_tags
names_of_tag;
646 write_files buf files
649 buf_int
buf (List.length
t);
652 let rec write_files_max buf files nfiles max_len
=
653 let prev_len = Buffer.length
buf in
655 [] -> nfiles
, prev_len
657 buf_md4
buf file.f_md4
;
658 buf_ip
buf file.f_ip
;
659 buf_port
buf file.f_port
;
660 buf_tags
buf file.f_tags
names_of_tag;
661 if Buffer.length
buf < max_len
then
662 write_files_max buf files (nfiles
+1) max_len
667 module ViewDirsReply
= struct
671 let rec get_dirs s
pos n =
672 if n = 0 then [], pos else
673 let dir, pos = get_string16 s
pos in
674 let dirs, pos = get_dirs s
pos (n-1) in
678 let dirs, pos = get_dirs s
2 (get_int16 s
0) in
682 lprintf_nl
"VIEW DIRS REPLY:";
683 List.iter
(fun dir ->
684 lprintf_nl
"DIR: %s" dir;) t
687 buf_int
buf (List.length
t);
688 List.iter
(fun dir ->
689 buf_string
buf dir;) t
693 module ViewFilesDir
= struct
698 lprintf_nl
"VIEW FILES DIR: %s" t
701 let dir, pos = get_string s
1 in
709 module ViewFilesDirReply
= struct
711 type t = string * tagged_file list
713 let names_of_tag = file_common_tags
716 let dir, pos = get_string s
1 in
717 let n = get_int s
(pos+1) in
718 let files, pos = ViewFilesReply.get_files s
(pos+5) n in
722 lprintf_nl
"VIEW FILES DIR REPLY:";
723 let dir, files = t in begin
724 lprintf_nl
"DIR: %s" dir;
725 List.iter
(fun file ->
727 lprintf_nl
" MD4: %s" (Md4.to_string
file.f_md4
);
728 lprintf_nl
" ip: %s" (Ip.to_string
file.f_ip
);
729 lprintf_nl
" port: %d" file.f_port
;
731 print_tags
file.f_tags
;
732 lprint_newline
();) files
736 let dir, files = t in begin
738 buf_int
buf (List.length
files);
739 ViewFilesReply.write_files buf files
744 module OtherLocations
= struct
750 for i
= 0 to len
/ 4 - 1 do
751 list := (get_ip s
(i
*4+1)) :: !list;
756 lprintf_nl
"OTHER LOCATIONS:\n";
758 lprintf_nl
" ip: %s" (Ip.to_string
ip);) t
761 List.iter
(buf_ip
buf) t
764 module NewUserID
= struct
769 get_ip s
1, get_ip s
5
771 let print (ip1
,ip2
) =
772 lprintf_nl
"NEW USER ID: %s -> %s" (Ip.to_string ip1
)
775 let write buf (ip1
,ip2
) =
781 module Sources
= struct
785 sources
: (Ip.t * int * Ip.t) list;
789 let len = get_int16 s
1 in
790 let md4 = get_md4 s
3 in
792 (* let pos = 19 in *)
793 for i
= 0 to len - 1 do
794 list := (get_ip s
(19 + 10 * i
), get_port s
(23 + 10 * i
),
795 get_ip s
(25 + 10 * i
)) :: !list;
802 lprintf_nl
"SOURCES for %s:" (Md4.to_string
t.md4);
803 List.iter
(fun (ip1
, port, ip2
) ->
804 lprintf_nl
" %s:%d:%s" (Ip.to_string ip1
) port(Ip.to_string ip2
)) t.sources
807 buf_int16
buf (List.length
t.sources
);
809 List.iter
(fun (ip1
, port, ip2
) ->
812 buf_ip
buf ip2
) t.sources
815 module EmuleClientInfo
= struct
818 version
: int; (* CURRENT_VERSION_SHORT = !!emule_protocol_version *)
819 protversion
: int; (* EMULE_PROTOCOL_VERSION = 0x1 *)
820 mutable tags : tag
list;
823 let names_of_tag = client_common_tags
826 List.map
(fun (v
, name) -> (v
, Field_KNOWN
name)) names_of_tag
829 let version = get_uint8 s
1 in
830 let protversion = get_uint8 s
2 in
831 let tags,_
= get_tags s
3 names_of_tag in
834 protversion = protversion;
839 let b1 = Buffer.create
50 in
840 lbprint_tags b1 t.tags;
841 lprintf_nl
"%s: [version: %d] [protversion: %d] [tags:%s]" m t.version t.protversion (Buffer.contents
b1)
844 buf_int8
buf t.version;
845 buf_int8
buf t.protversion;
846 buf_tags
buf t.tags names_of_tag;
850 module EmuleQueueRanking
= struct
854 let parse len s
= get_int16 s
1
856 lprintf_nl
"EmuleQueueRanking: %d" t
858 let string_null10 = String.make
10 (char_of_int
0)
862 Buffer.add_string
buf string_null10
866 module QueueRank
= struct
870 let parse len s
= get_int s
1
872 lprintf_nl
"QueueRank: %d" t
879 module EmuleRequestSources
= struct
887 lprintf_nl
"EmuleRequestSources: %s" (Md4.to_string
t)
895 let buf_estring buf s
=
896 let len = String.length s
in
898 Buffer.add_string
buf s
900 module EmuleSignatureReq
= struct
908 lprintf_nl
"EmuleSignatureReq [type %d] [sig(%d): %s]" t.ip_type
(String.length
t.signature
) (String.escaped
t.signature
)
911 let mlen = get_uint8 s
1 in
912 let slen = String.length s
in
913 let signature = String.sub s
2 mlen in
914 let ip_type = if mlen = (slen-2) then 0 else get_uint8 s
(2 + mlen) in
916 signature = signature;
921 buf_estring buf t.signature;
922 if (t.ip_type <> 0) then
923 buf_int8
buf t.ip_type;
928 module EmulePublicKeyReq
= struct
933 lprintf_nl
"EmulePublicKeyReq [key(%d): %s]" (String.length
t) (String.escaped
t)
936 let len = get_uint8 s
1 in
944 module EmuleSecIdentStateReq
= struct
952 lprintf_nl
"EmuleSecIdentStateReq [state: %d] [challenge: %Ld]" t.state
t.challenge
955 let state = get_uint8 s
1 in
956 let challenge = get_uint64_32 s
2 in
959 challenge = challenge;
963 buf_int8
buf t.state;
964 buf_int64_32
buf t.challenge
968 module EmuleRequestSourcesReply
= struct
973 mutable src_server_ip
: Ip.t;
974 mutable src_server_port
: int;
975 mutable src_md4
: Md4.t;
976 mutable src_cc
: int option;
981 sources
: source array
;
987 src_server_ip
= Ip.null
;
994 let md4 = get_md4 s
1 in
995 let ncount = get_int16 s
17 in
998 if ncount = 0 then [||] else
999 let slen = (len - 19) / ncount in
1000 (* lprintf "PER SOURCES LEN: %d\n" slen; *)
1001 let sources = Array.create
ncount dummy_source in
1002 let rec iter pos i
=
1005 let ip = get_ip s
pos in
1009 src_port
= get_int16 s
(pos+4);
1010 src_cc
= Geoip.get_country_code_option
ip
1013 if slen > 6 then begin
1014 ss.src_server_ip
<- get_ip s
(pos+6);
1015 ss.src_server_port
<- get_int16 s
(pos+10);
1016 if slen > 12 && (sourceexchange e
> 1) then begin
1017 ss.src_md4
<- get_md4 s
(pos+12);
1036 let ncount = Array.length
t.sources in
1037 lprintf_nl
"EMULE SOURCES REPLY: %d sources for %s"
1038 ncount (Md4.to_string
t.md4);
1039 for i
= 0 to ncount - 1 do
1040 let s = t.sources.(i
) in
1042 (if Ip.valid
s.src_ip
then
1043 Printf.sprintf
"%s:%d" (Ip.to_string
s.src_ip
) s.src_port
1045 Printf.sprintf
"%s:%d (Indirect)" (Ip.to_string
s.src_server_ip
) s.src_server_port
)
1046 (if s.src_md4
!= Md4.null
then
1047 Printf.sprintf
"MD4: %s" (Md4.to_string
s.src_md4
)
1053 let ncount = Array.length
t.sources in
1054 buf_int16
buf ncount;
1056 for i
= 0 to ncount - 1 do
1057 let s = t.sources.(i
) in
1058 buf_ip
buf s.src_ip
;
1059 buf_port
buf s.src_port
;
1060 if sourceexchange e
> 0 then begin
1061 buf_ip
buf s.src_server_ip
;
1062 buf_port
buf s.src_server_port
;
1063 if sourceexchange e
> 1 then
1064 buf_md4
buf s.src_md4
1069 module EmuleFileDesc
= struct
1077 let rating = get_uint8
s 1 in
1078 let (comment
, _
) = get_string32
s 2 in
1085 lprintf_nl
"EmuleFileDesc [%d][%s]" t.rating t.comment
1088 buf_int8
buf t.rating;
1089 buf_string
buf t.comment
1092 module EmuleCompressedPart
= struct
1096 usesixtyfour
: bool;
1102 let parse usesixtyfour
len s =
1105 usesixtyfour
= usesixtyfour
;
1106 statpos
= if usesixtyfour
then get_int64
s 17 else get_uint64_32
s 17;
1107 newsize
= if usesixtyfour
then get_uint64_32
s 25 else get_uint64_32
s 21;
1108 bloc
= if usesixtyfour
then String.sub
s 29 (len-29) else String.sub
s 25 (len-25)
1112 lprintf_nl
"EmuleCompressedPart for %s %Ld %Ld len %d"
1113 (Md4.to_string
t.md4) t.statpos
t.newsize
(String.length
t.bloc
)
1117 if t.usesixtyfour
then buf_int64
buf t.statpos
else buf_int64_32
buf t.statpos
;
1118 buf_int64_32
buf t.newsize
;
1119 Buffer.add_string
buf t.bloc
1122 module EmulePortTestReq
= struct
1127 lprintf_nl
"Emule porttest request %s" (String.escaped
s)
1137 | ConnectReq
of Connect.t
1138 | ConnectReplyReq
of Connect.t
1139 | QueryFileReq
of QueryFile.t
1140 | QueryFileReplyReq
of QueryFileReply.t
1142 | QueryBlocReq
of QueryBloc.t
1143 | JoinQueueReq
of JoinQueue.t (* sent before queryBloc *)
1144 | AvailableSlotReq
of AvailableSlot.t
1145 | ReleaseSlotReq
of ReleaseSlot.t
1146 | OutOfPartsReq
of OutOfParts.t
1147 | QueryChunksReq
of QueryChunks.t
1148 | QueryChunksReplyReq
of QueryChunksReply.t
1149 | QueryChunkMd4Req
of QueryChunkMd4.t
1150 | QueryChunkMd4ReplyReq
of QueryChunkMd4Reply.t
1151 | ViewFilesReq
of ViewFiles.t
1152 | ViewFilesReplyReq
of ViewFilesReply.t
1153 | ViewDirsReq
of ViewDirs.t
1154 | ViewDirsReplyReq
of ViewDirsReply.t
1155 | ViewFilesDirReq
of ViewFilesDir.t
1156 | ViewFilesDirReplyReq
of ViewFilesDirReply.t
1157 | QueueReq
of OtherLocations.t
1158 | UnknownReq
of int * string
1159 | OtherLocationsReq
of OtherLocations.t
1161 | SourcesReq
of Sources.t
1162 | EndOfDownloadReq
of EndOfDownload.t
1163 | NewUserIDReq
of NewUserID.t
1164 | NoSuchFileReq
of NoSuchFile.t
1165 | QueueRankReq
of QueueRank.t
1167 | EmuleClientInfoReq
of EmuleClientInfo.t
1168 | EmuleClientInfoReplyReq
of EmuleClientInfo.t
1169 | EmuleQueueRankingReq
of EmuleQueueRanking.t
1170 | EmuleRequestSourcesReq
of EmuleRequestSources.t
1171 | EmuleRequestSourcesReplyReq
of EmuleRequestSourcesReply.t
1172 | EmuleFileDescReq
of EmuleFileDesc.t
1173 | EmulePublicKeyReq
of EmulePublicKeyReq.t
1174 | EmuleSignatureReq
of EmuleSignatureReq.t
1175 | EmuleSecIdentStateReq
of EmuleSecIdentStateReq.t
1176 | EmuleMultiPacketReq
of Md4.t * t list
1177 | EmuleMultiPacketAnswerReq
of Md4.t * t list
1178 | EmuleCompressedPart
of EmuleCompressedPart.t
1179 | EmulePortTestReq
of EmulePortTestReq.t
1184 | ConnectReq
t -> Connect.print t
1185 | ConnectReplyReq
t -> Connect.print t
1186 | QueryFileReq
t -> QueryFile.print t
1187 | QueryFileReplyReq
t -> QueryFileReply.print t
1188 | BlocReq
t -> Bloc.print t
1189 | QueryBlocReq
t -> QueryBloc.print t
1190 | JoinQueueReq
t -> JoinQueue.print t
1191 | AvailableSlotReq
t -> AvailableSlot.print t
1192 | ReleaseSlotReq
t -> ReleaseSlot.print t
1193 | OutOfPartsReq
t -> OutOfParts.print t
1194 | QueryChunksReq
t -> QueryChunks.print t
1195 | QueryChunksReplyReq
t -> QueryChunksReply.print t
1196 | QueryChunkMd4Req
t -> QueryChunkMd4.print t
1197 | QueryChunkMd4ReplyReq
t -> QueryChunkMd4Reply.print t
1198 | ViewFilesReplyReq
t -> ViewFilesReply.print t
1199 | ViewFilesReq
t -> ViewFiles.print t
1200 | ViewDirsReq
t -> ViewDirs.print t
1201 | ViewDirsReplyReq
t -> ViewDirsReply.print t
1202 | ViewFilesDirReq
t -> ViewFilesDir.print t
1203 | ViewFilesDirReplyReq
t -> ViewFilesDirReply.print t
1204 | QueueReq
t -> OtherLocations.print t
1205 | OtherLocationsReq
t -> OtherLocations.print t
1206 | SayReq
t -> Say.print t
1207 | SourcesReq
t -> Sources.print t
1208 | EndOfDownloadReq
t -> EndOfDownload.print t
1209 | NewUserIDReq
t -> NewUserID.print t
1210 | NoSuchFileReq
t -> NoSuchFile.print t
1214 | EmuleClientInfoReq
t ->
1215 EmuleClientInfo.print "EmuleClientInfo" t
1216 | EmuleClientInfoReplyReq
t ->
1217 EmuleClientInfo.print "EmuleClientInfoReply" t
1218 | EmuleQueueRankingReq
t ->
1219 EmuleQueueRanking.print t
1220 | EmuleRequestSourcesReq
t ->
1221 EmuleRequestSources.print t
1222 | EmuleRequestSourcesReplyReq
t ->
1223 EmuleRequestSourcesReply.print t
1225 | EmuleFileDescReq
t ->
1226 EmuleFileDesc.print t
1228 | EmuleMultiPacketReq
(md4, list) ->
1229 lprintf_nl
"EmuleMultiPacket for %s:" (Md4.to_string
md4);
1235 | EmuleMultiPacketAnswerReq
(md4, list) ->
1236 lprintf_nl
"EmuleMultiPacketAnswer for %s:" (Md4.to_string
md4);
1241 | EmuleSecIdentStateReq
t ->
1242 EmuleSecIdentStateReq.print t
1243 | EmuleSignatureReq
t ->
1244 EmuleSignatureReq.print t
1245 | EmulePublicKeyReq
t ->
1246 EmulePublicKeyReq.print t
1247 | EmuleCompressedPart
t ->
1248 EmuleCompressedPart.print t
1249 | EmulePortTestReq
t ->
1250 EmulePortTestReq.print t
1251 | UnknownReq
(opcode
, s) ->
1252 let len = String.length
s in
1253 lprintf_nl
"UnknownReq: magic (%d), opcode (%d) len (%d)" opcode
1257 for i
= 0 to len - 1 do
1259 let n = int_of_char
c in
1260 if n > 31 && n < 127 then
1267 for i
= 0 to len - 1 do
1269 let n = int_of_char
c in
1275 let rec parse_emule_packet emule opcode
len s =
1277 lprintf "Emule magic: %d opcode %d:" magic opcode; lprint_newline ();
1278 dump s; lprint_newline ();
1280 let t = match opcode
with
1281 | 1 -> EmuleClientInfoReq
(EmuleClientInfo.parse len s)
1282 | 2 -> EmuleClientInfoReplyReq
(EmuleClientInfo.parse len s)
1284 | 0x60 (* 96 *) -> EmuleQueueRankingReq
(EmuleQueueRanking.parse len s)
1286 | 0x61 (* 97 *) -> EmuleFileDescReq
(EmuleFileDesc.parse len s)
1288 | 0x81 (* 129 *) -> EmuleRequestSourcesReq
(EmuleRequestSources.parse len s)
1290 EmuleRequestSourcesReplyReq
(
1291 EmuleRequestSourcesReply.parse emule
len s)
1294 (* OP_COMPRESSEDPART *)
1295 EmuleCompressedPart
(EmuleCompressedPart.parse false len s)
1298 EmulePublicKeyReq
(EmulePublicKeyReq.parse len s)
1301 EmuleSignatureReq
(EmuleSignatureReq.parse len s)
1304 EmuleSecIdentStateReq
(EmuleSecIdentStateReq.parse len s)
1306 (* | 0x90 (* 144 *) -> RequestPreview *)
1307 (* | 0x91 (* 145 *) -> PreviewAnswer *)
1309 let md4 = get_md4
s 1 in
1311 (* lprintf "MULTI EMULE VERSION %d"
1312 (extendedrequest emule); print_newline (); *)
1313 (* let pos = 17 in *)
1316 let opcode = get_uint8
s pos in
1319 let bitmap, pos = get_bitmap s (pos+1) in
1320 let ncompletesources, pos =
1321 if extendedrequest emule
> 1 then
1322 get_int16
s pos, pos+2
1326 QueryFile.md4 = md4;
1327 QueryFile.emule_extension = Some
(bitmap, ncompletesources);
1330 (QueryChunksReq
md4) :: iter (pos+1)
1332 (EmuleRequestSourcesReq
md4) :: iter (pos+1)
1334 lprintf_nl
"Unknown short emule packet %d" opcode;
1339 EmuleMultiPacketReq
(md4, iter 17)
1342 if String.length
s < 16 then begin
1343 if !verbose_unknown_messages
then lprintf_nl
"EmuleMultiPacketAnswer: incomplete request";
1346 let md4 = get_md4
s 1 in
1348 (* lprintf "MULTI EMULE VERSION %d"
1349 (extendedrequest emule); print_newline (); *)
1350 let rec iter s pos len =
1352 let opcode = get_uint8
s pos in
1355 let module Q
= QueryFileReply
in
1356 let name, pos = get_string
s (pos+1) in
1361 (QueryFileReplyReq
q) :: (iter s pos len)
1363 let module Q
= QueryChunksReply
in
1364 let chunks, pos = get_bitmap s (pos+1) in
1369 (QueryChunksReplyReq
q) :: (iter s pos len)
1371 lprintf_nl
"Unknown packet in emule multipacket 0x93: %d" opcode;
1376 EmuleMultiPacketAnswerReq
(md4, iter s 17 len)
1378 | 0xa1 (* 161 *) -> (* OP_COMPRESSEDPART_I64 *)
1379 EmuleCompressedPart
(EmuleCompressedPart.parse true len s)
1380 | 0xa2 -> BlocReq
(Bloc.parse true len s) (* OP_SENDINGPART_I64 *)
1381 | 0xa3 -> QueryBlocReq
(QueryBloc.parse true len s) (*OP_REQUESTPARTS_I64 *)
1386 if !CommonOptions.verbose_unknown_messages
then
1387 lprintf_nl
"EDK: unknown eMule message %d" code
;
1391 lprintf "EMULE MESSAGE: "; lprint_newline ();
1393 lprint_newline (); *)
1396 and parse emule_version magic
s =
1398 let len = String.length
s in
1399 if len = 0 then raise Not_found
;
1400 let opcode = int_of_char
(s.[0]) in
1401 (*lprintf "opcode: %d" opcode; lprint_newline (); *)
1406 | 1 -> ConnectReq
(Connect.parse false len s)
1407 | 70 -> BlocReq
(Bloc.parse false len s)
1408 | 71 -> QueryBlocReq
(QueryBloc.parse false len s)
1409 | 72 -> NoSuchFileReq
(NoSuchFile.parse len s)
1410 | 73 -> EndOfDownloadReq
(EndOfDownload.parse len s)
1411 | 74 -> ViewFilesReq
(ViewFiles.parse len s)
1412 | 75 -> ViewFilesReplyReq
(ViewFilesReply.parse len s)
1413 | 76 -> ConnectReplyReq
(Connect.parse true len s)
1414 | 77 -> NewUserIDReq
(NewUserID.parse len s)
1415 | 78 -> SayReq
(Say.parse len s)
1416 | 79 -> QueryChunksReq
(QueryChunks.parse len s)
1417 | 80 -> QueryChunksReplyReq
(QueryChunksReply.parse len s)
1418 | 81 -> QueryChunkMd4Req
(QueryChunkMd4.parse len s)
1419 | 82 -> QueryChunkMd4ReplyReq
(QueryChunkMd4Reply.parse len s)
1420 (* JoinQueue: the sender wants to join the upload queue *)
1421 | 84 -> JoinQueueReq
(JoinQueue.parse len s)
1422 (* AvailableSlot: there is an available slot in upload queue *)
1423 | 85 -> AvailableSlotReq
(AvailableSlot.parse len s)
1424 (* ReleaseSlot: the upload is finished *)
1425 | 86 -> ReleaseSlotReq
(ReleaseSlot.parse len s)
1426 (* OutOfParts: the upload slot is not available *)
1427 | 87 -> OutOfPartsReq
(OutOfParts.parse len s)
1428 | 88 -> QueryFileReq
(QueryFile.parse emule_version
len s)
1429 | 89 -> QueryFileReplyReq
(QueryFileReply.parse len s)
1430 | 92 -> QueueRankReq
(QueueRank.parse len s)
1431 | 93 -> ViewDirsReq
(ViewDirs.parse len s)
1432 | 94 -> ViewFilesDirReq
(ViewFilesDir.parse len s)
1434 | 95 -> ViewDirsReplyReq (ViewDirsReply.parse len s)
1435 | 96 -> ViewFilesDirReplyReq (ViewFilesDirReply.parse len s)
1437 | 250 -> SourcesReq
(Sources.parse len s)
1439 | _
-> raise Not_found
1442 | 0xc5 -> (* 197: emule extended protocol *)
1443 parse_emule_packet emule_version
opcode len s
1445 (* Compressed packet, probably sent by cDonkey ? *)
1449 let s = Zlib.uncompress_string2
(String.sub
s 1 (len-1)) in
1450 let s = Printf.sprintf
"%c%s" (char_of_int
opcode) s in
1452 parse_emule_packet emule_version
opcode (String.length
s) s
1455 if !CommonOptions.verbose_unknown_messages
then begin
1456 lprintf_nl
"Unknown message From client: %s (magic %d)"
1457 (Printexc2.to_string e
) magic
;
1458 let tmp_file = Filename2.temp_file
"comp" "pak" in
1459 File.from_string
tmp_file s;
1460 lprintf_nl
"Saved unknown packet %s" tmp_file;
1464 UnknownReq
(magic
,s)
1468 if !CommonOptions.verbose_unknown_messages
then
1469 lprintf_nl
"Strange magic: %d" magic
;
1473 if !CommonOptions.verbose_unknown_messages
then begin
1474 lprintf_nl
"Unknown message From client: %s (magic %d)"
1475 (Printexc2.to_string e
) magic
;
1476 let tmp_file = Filename2.temp_file
"comp" "pak" in
1477 File.from_string
tmp_file s;
1478 lprintf_nl
"Saved unknown packet %s" tmp_file;
1483 UnknownReq
(magic
,s)
1485 let write emule
buf t =
1486 let magic = match t with
1487 EmuleMultiPacketAnswerReq _
1488 | EmuleMultiPacketReq _
1489 | EmuleSecIdentStateReq _
1490 | EmuleSignatureReq _
1491 | EmulePublicKeyReq _
1492 | EmuleRequestSourcesReplyReq _
1493 | EmuleRequestSourcesReq _
1494 | EmuleClientInfoReplyReq _
1495 | EmuleClientInfoReq _
1496 | EmuleFileDescReq _
1497 | EmuleQueueRankingReq _
1498 | EmuleCompressedPart _
1500 | QueryBlocReq
t when t.QueryBloc.usesixtyfour
-> 0xC5
1501 | BlocReq
t when t.Bloc.usesixtyfour
-> 0xC5
1509 Connect.write false buf t
1510 | ConnectReplyReq
t ->
1512 Connect.write true buf t
1515 QueryFile.write emule
buf t
1516 | QueryFileReplyReq
t ->
1518 QueryFileReply.write buf t
1521 OtherLocations.write buf t
1523 buf_int8
buf (if t.QueryBloc.usesixtyfour
then 0xa3 else 71);
1524 QueryBloc.write buf t
1526 buf_int8
buf (if t.Bloc.usesixtyfour
then 0xa2 else 70);
1530 JoinQueue.write emule
buf t
1531 | QueryChunksReq
t ->
1533 QueryChunks.write buf t
1534 | QueryChunksReplyReq
t ->
1536 QueryChunksReply.write buf t
1537 | QueryChunkMd4Req
t ->
1539 QueryChunkMd4.write buf t
1540 | QueryChunkMd4ReplyReq
t ->
1542 QueryChunkMd4Reply.write buf t
1543 | AvailableSlotReq
t ->
1545 AvailableSlot.write buf t
1546 | ReleaseSlotReq
t ->
1548 ReleaseSlot.write buf t
1549 | OutOfPartsReq
t ->
1551 OutOfParts.write buf t
1554 ViewFiles.write buf t
1555 | ViewFilesReplyReq
t ->
1557 ViewFilesReply.write buf t
1560 ViewDirs.write buf t
1561 | ViewDirsReplyReq
t ->
1563 ViewDirsReply.write buf t
1564 | ViewFilesDirReq
t ->
1566 ViewFilesDir.write buf t
1567 | ViewFilesDirReplyReq
t ->
1569 ViewFilesDirReply.write buf t
1570 | OtherLocationsReq
t ->
1572 OtherLocations.write buf t
1581 NewUserID.write buf t
1582 | EndOfDownloadReq
t ->
1584 EndOfDownload.write buf t
1585 | NoSuchFileReq
t ->
1587 NoSuchFile.write buf t
1590 QueueRank.write buf t
1592 | EmuleClientInfoReq
t ->
1594 EmuleClientInfo.write buf t
1595 | EmuleClientInfoReplyReq
t ->
1597 EmuleClientInfo.write buf t
1598 | EmuleQueueRankingReq
t ->
1600 EmuleQueueRanking.write buf t
1601 | EmuleRequestSourcesReq
t ->
1603 EmuleRequestSources.write buf t
1604 | EmuleRequestSourcesReplyReq
t ->
1606 EmuleRequestSourcesReply.write emule
buf t
1607 | EmuleFileDescReq
t ->
1609 EmuleFileDesc.write buf t
1610 | EmuleCompressedPart
t ->
1611 buf_int8
buf (if t.EmuleCompressedPart.usesixtyfour
then 0xa1 else 0x40);
1612 EmuleCompressedPart.write buf t
1613 | EmuleMultiPacketReq
(md4, list) ->
1620 (match t.QueryFile.emule_extension with
1622 | Some
(bitmap, ncompletesources) ->
1623 write_bitmap buf bitmap;
1624 if ncompletesources >= 0 && extendedrequest emule
> 1 then
1625 buf_int16
buf ncompletesources)
1626 | QueryChunksReq _
->
1628 | EmuleRequestSourcesReq _
->
1631 lprintf_nl
"WARNING: Don't know how to write short packet:";
1636 | EmuleMultiPacketAnswerReq
(md4, list) ->
1641 QueryFileReplyReq
t ->
1643 buf_string
buf t.QueryFileReply.name
1644 | QueryChunksReplyReq
t ->
1646 write_bitmap buf t.QueryChunksReply.chunks
1648 lprintf_nl
"WARNING: Don't know how to write short packet:";
1653 | EmuleSecIdentStateReq
t ->
1655 EmuleSecIdentStateReq.write buf t
1657 | EmuleSignatureReq
t ->
1659 EmuleSignatureReq.write buf t
1661 | EmulePublicKeyReq
t ->
1663 EmulePublicKeyReq.write buf t
1665 | EmulePortTestReq
t ->
1667 EmulePortTestReq.write buf;
1669 | UnknownReq
(opcode, s) ->
1670 Buffer.add_string
buf s
1676 ------------------------------------------------------
1677 1044008574.297 192.168.0.3:37522 -> 80.26.114.12:13842 of len 6
1678 ? Become Friend ? ping ?
1683 ------------------------------------------------------
1684 1044008576.274 80.26.114.12:13842 -> 192.168.0.3:37522 of len 6
1687 (227)(1)(0)(0)(0)(99)]
1689 ------------------------------------------------------
1690 1044008687.977 192.168.0.3:37522 -> 80.26.114.12:13842 of len 6
1696 ------------------------------------------------------
1697 1044008690.832 80.26.114.12:13842 -> 192.168.0.3:37522 of len 43
1698 Browse Main Dir Reply
1701 (2)(0)(0)(0) --------> 2 directories:
1702 (12)(0) C : \ D o w n l o a d s
1703 (17)(0) ! I n c o m p l e t e F i l e s
1706 ------------------------------------------------------
1707 1044008766.137 192.168.0.3:37522 -> 80.26.114.12:13842 of len 20
1712 (12)(0) C : \ D o w n l o a d s
1714 ------------------------------------------------------
1715 1044008769.045 80.26.114.12:13842 -> 192.168.0.3:37522 of len 300
1716 (227) p(8)(0)(0) `(12)(0) C : \ D o w n l o a d s(21)(0)(0)(0)(152) 2(229)(158)(218)(141)(217)(138) n(181) 6 ( ) h V(179)(0)(0)(0)(0)(0)(0)(3)(0)(0)(0)(2)(1)(0)(1)(11)(0) d e s k t o p . i n i(3)(1)(0)(2)(180)(0)(0)(0)(3)(1)(0)(19)(0)(0)(0)(0) y(16)(15) 9 O Z(219) i e(200)(10) |(29)(27) F(128)(0)(0)(0)(0)(0)(0)(5)(0)(0)(0)(2)(1)(0)(1)(15)(0) u t b o n u s p a c k . z i p(3)(1)(0)(2) J(16)(221)(0)(2)(1)(0)(3)(3)(0) P r o(2)(1)(0)(4)(3)(0) z i p(3)(1)(0)(19)(0)(0)(0)(0)(178)(145)(161)(146) P(199)(228)(249) K a :(9)(237)(246)(233) v(0)(0)(0)(0)(0)(0)(5)(0)(0)(0)(2)(1)(0)(1)(11)(0) c t f m a p s . z i p(3)(1)(0)(2)(236)(239)(23)(0)(2)(1)(0)(3)(3)(0) P r o(2)(1)(0)(4)(3)(0) z i p(3)(1)(0)(19)(0)(0)(0)(0) a n(251)(225) ^ g(205)(133)(25)(12) # ' J A(221) `(0)(0)(0)(0)(0)(0)(5)(0)(0)(0)(2)(1)(0)(1)(23)(0) u t i n o x x p a c k - n o - u m o d . z i p(3)(1)(0)(2)]
1720 (12)(0) C : \ D o w n l o a d s
1721 (21)(0)(0)(0) 21 files
1723 (152)(50)(229)(158)(218)(141)(217)(138)(110)(181)(54)(40)(41)(104)(86)(179)
1729 (11)(0) d e s k t o p . i n i
1737 (121)(16)(15)(57)(79)(90)(219)(105)(101)(200)(10)(124)(29)(27)(70)(128)
1743 (15)(0) u t b o n u s p a c k . z i p
1760 (* 92: Queue Rank *)