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
32 let compatibleclient = ref 10
34 let get_emule_version () =
35 (!compatibleclient lsl 24) lor
36 (int_of_string
(Autoconf.major_version
) lsl 17) lor
37 (int_of_string
(Autoconf.minor_version
) lsl 10) lor
38 (int_of_string
(Autoconf.sub_version
) lsl 7)
40 let mldonkey_emule_proto =
42 emule_version
= get_emule_version ();
44 emule_osinfosupport
= 1;
47 (* emule_miscoptions1 *)
48 received_miscoptions1
= false;
52 emule_compression
= 1;
53 emule_secident
= 3; (* Emule uses v1 if advertising both, v2 if only advertising 2 *)
54 emule_sourceexchange
= 2; (* 2 : +client_md4 3 : +IdHybrid (emule Kademlia?)*)
55 emule_extendedrequest
= 1; (* 1: +file_status 2: +ncomplete_sources*)
58 emule_noviewshared
= 0;
59 emule_multipacket
= 0;
60 emule_supportpreview
= 0;
62 (* emule_miscoptions2 *)
63 received_miscoptions2
= false;
64 emule_require_crypt
= 0;
65 emule_request_crypt
= 0;
66 emule_support_crypt
= 0;
67 emule_extmultipacket
= 0;
69 emule_kad_version
= 0;
70 emule_support_captcha
= 1;
73 let emule_miscoptions1 m
=
75 (m
.emule_aich
lsl 29) lor
76 (m
.emule_unicode
lsl 28) lor
77 (m
.emule_udpver
lsl 24) lor
78 (m
.emule_compression
lsl 20) lor
79 (m
.emule_secident
lsl 16) lor
80 (m
.emule_sourceexchange
lsl 12) lor
81 (m
.emule_extendedrequest
lsl 8) lor
82 (m
.emule_comments
lsl 4) lor
83 (m
.emule_peercache
lsl 3) lor
84 (m
.emule_noviewshared
lsl 2) lor
85 (m
.emule_multipacket
lsl 1) lor
86 (m
.emule_supportpreview
lsl 0)
90 let update_emule_proto_from_miscoptions1 m
o =
91 let o = Int64.to_int
o in
92 m
.emule_aich
<- (o lsr 29) land 0x7;
93 m
.emule_unicode
<- (o lsr 28) land 0xf;
94 m
.emule_udpver
<- (o lsr 24) land 0xf;
95 m
.emule_compression
<- (o lsr 20) land 0xf;
96 m
.emule_secident
<- (o lsr 16) land 0xf;
97 m
.emule_sourceexchange
<- (o lsr 12) land 0xf;
98 m
.emule_extendedrequest
<- (o lsr 8) land 0xf;
99 m
.emule_comments
<- (o lsr 4) land 0xf;
100 m
.emule_peercache
<- (o lsr 3) land 0x1;
101 m
.emule_noviewshared
<- (o lsr 2) land 0x1;
102 m
.emule_multipacket
<- (o lsr 1) land 0x1;
103 m
.emule_supportpreview
<- (o lsr 0) land 0x1
105 let print_emule_proto_miscoptions1 m
=
106 let buf = Buffer.create
50 in
107 if m
.emule_aich
<> 0 then Printf.bprintf
buf " aich %d\n" m
.emule_aich
;
108 if m
.emule_unicode
<> 0 then Printf.bprintf
buf " unicode %d\n" m
.emule_unicode
;
109 if m
.emule_udpver
<> 0 then Printf.bprintf
buf " udpver %d\n" m
.emule_udpver
;
110 if m
.emule_compression
<> 0 then Printf.bprintf
buf " compression %d\n" m
.emule_compression
;
111 if m
.emule_secident
<> 0 then Printf.bprintf
buf " secident %d\n" m
.emule_secident
;
112 if m
.emule_sourceexchange
<> 0 then Printf.bprintf
buf " sourceexchange %d\n" m
.emule_sourceexchange
;
113 if m
.emule_extendedrequest
<> 0 then Printf.bprintf
buf " extendedrequest %d\n" m
.emule_extendedrequest
;
114 if m
.emule_comments
<> 0 then Printf.bprintf
buf " comments %d\n" m
.emule_comments
;
115 if m
.emule_peercache
<> 0 then Printf.bprintf
buf " peercache %d\n" m
.emule_peercache
;
116 if m
.emule_noviewshared
<> 0 then Printf.bprintf
buf " noviewshared %d\n" m
.emule_noviewshared
;
117 if m
.emule_multipacket
<> 0 then Printf.bprintf
buf " multipacket %d\n" m
.emule_multipacket
;
118 if m
.emule_supportpreview
<> 0 then Printf.bprintf
buf " supportpreview %d\n" m
.emule_supportpreview
;
121 let emule_miscoptions2 m
=
123 (m
.emule_support_captcha
lsl 11) lor
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_support_captcha
<- (o lsr 11) land 0x1;
131 m
.emule_require_crypt
<- (o lsr 9) land 0x1;
132 m
.emule_request_crypt
<- (o lsr 8) land 0x1;
133 m
.emule_support_crypt
<- (o lsr 7) land 0x1;
134 m
.emule_extmultipacket
<- (o lsr 5) land 0x1;
135 m
.emule_largefiles
<- (o lsr 4) land 0x1;
136 m
.emule_kad_version
<- (o lsr 0) land 0xf
138 let print_emule_proto_miscoptions2 m
=
139 let buf = Buffer.create
50 in
140 if m
.emule_require_crypt
<> 0 then Printf.bprintf
buf " require_crypt %d\n" m
.emule_require_crypt
;
141 if m
.emule_request_crypt
<> 0 then Printf.bprintf
buf " request_crypt %d\n" m
.emule_request_crypt
;
142 if m
.emule_support_crypt
<> 0 then Printf.bprintf
buf " support_crypt %d\n" m
.emule_support_crypt
;
143 if m
.emule_extmultipacket
<> 0 then Printf.bprintf
buf " extmultipacket %d\n" m
.emule_extmultipacket
;
144 if m
.emule_largefiles
<> 0 then Printf.bprintf
buf " largefiles %d\n" m
.emule_largefiles
;
145 if m
.emule_kad_version
<> 0 then Printf.bprintf
buf " kad_version %d\n" m
.emule_kad_version
;
146 if m
.emule_support_captcha
<> 0 then Printf.bprintf
buf " support_captcha %d\n" m
.emule_support_captcha
;
149 let emule_compatoptions m
=
150 (m
.emule_osinfosupport
lsl 0)
152 let update_emule_proto_from_compatoptions m
o =
153 m
.emule_osinfosupport
<- (o lsr 0) land 0x1
155 let extendedrequest e
=
156 min e
.emule_extendedrequest
mldonkey_emule_proto.emule_extendedrequest
158 let sourceexchange e
=
159 min e
.emule_sourceexchange
mldonkey_emule_proto.emule_sourceexchange
162 BAD MESSAGE FROM CONNECTING CLIENT
164 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)]
168 (231)(129)(131)(26)(79)(247)(154)(145)(251)(253)(167)(71)(125)(207)(106)(146)
175 let rec lbprint_tags buf tags
=
177 [] -> Printf.bprintf
buf ""
179 Printf.bprintf
buf " (%s)=(%s)" (escaped_string_of_field tag
)
180 (string_of_tag_value tag
.tag_value
);
181 lbprint_tags buf tags
183 module Connect
= struct
190 server_info
: (Ip.t
* int) option;
194 let names_of_tag = client_common_tags
197 List.map
(fun (v
, name
) -> (v
, Field_KNOWN name
)) names_of_tag
199 let parse reply len s
=
200 let hash_len, pos
= if not reply
then get_uint8 s
1, 2 else -1, 1 in
201 let md4 = get_md4 s pos
in
202 let ip = get_ip s
(pos
+16) in
203 let port = get_port s
(pos
+20) in
204 let tags, pos
= get_tags s
(pos
+22) names_of_tag in
205 let server_info = Some
(get_ip s pos
, get_port s
(pos
+4)) in
206 let left_bytes = String.sub s
(pos
+6) (String.length s
- pos
- 6) in
213 server_info = server_info;
214 left_bytes = left_bytes;
219 let b1 = Buffer.create
50 in
220 let b2 = Buffer.create
5 in
221 lbprint_tags b1 t
.tags;
222 String.iter
(fun c
-> Printf.bprintf
b2 "(%d)" (int_of_char c
)) t
.left_bytes;
223 lprintf_nl
"Connect [hl: %d] [md4: %s] [ip: %s:%d] [server: %s] [left: %s] [tags:%s]"
225 (Md4.to_string t
.md4)
226 (Ip.to_string t
.ip) t
.port
227 (match t
.server_info with
229 | Some
(ip, port) -> Printf.sprintf
"%s:%d" (Ip.to_string
ip) port)
230 (if String.length t
.left_bytes <> 0 then (Buffer.contents
b2) else "None")
234 let write reply
buf t
=
241 buf_tags
buf t
.tags names_of_tag;
243 match t
.server_info with
258 let (s
, p
) = get_string s
1 in
262 lprintf_nl
"SAY %s" t
268 module OneMd4
= functor(M
: sig val m
: string end) -> (struct
275 lprintf_nl
"OneMd4: %s OF %s" M.m
(Md4.to_string t
)
282 module JoinQueue
= struct
283 type t
= Md4.t
option
291 lprintf_nl
"JOIN QUEUE %s"
292 (match t
with None
-> "" | Some
md4 ->
293 Printf.sprintf
"OF %s" (Md4.to_string
md4))
295 let write emule
buf t
=
296 if extendedrequest emule
> 0 then
305 val parse : int -> string -> t
306 val print : t -> unit
307 val write : Buffer.t -> t -> unit
313 (* In Emule, this message contains much more information, and will probably
314 remove the need for QueryChunks. *)
316 let get_bitmap s pos
=
317 let nchunks = get_int16 s pos
in
319 if nchunks = 0 then (Bitv.create
0 false), pos
+2 else
321 let chunks = (Bitv.create
nchunks false) in
322 for i
= 0 to (nchunks-1) / 8 do
323 let m = get_uint8 s
(pos + i
) in
327 Bitv.set
chunks n ((m land (1 lsl j
)) <> 0);
330 let pos = pos + (nchunks-1)/8 + 1 in
335 let print_bitmap chunks =
336 lprintf
"\n%s\n" (Bitv.to_string
chunks)
338 let write_bitmap buf chunks =
339 let nchunks = Bitv.length
chunks in
340 buf_int16
buf nchunks;
342 for i
= 0 to (nchunks-1) / 8 do
347 if (Bitv.get
chunks n) then
348 m := !m lor (1 lsl j
);
353 module QueryFile
= struct
356 emule_extension
: (Bitv.t
* int) option;
359 let parse emule len s
=
360 (* lprintf "Query File: emule version %d len %d"
361 (extendedrequest emule) len;
363 let md4 = get_md4 s
1 in
364 let emule_extension =
366 if len
< 18 || extendedrequest emule
= 0 then None
else
367 let chunks, pos = get_bitmap s
17 in
368 let ncompletesources =
369 if extendedrequest emule
> 1 && len
> pos+1 then get_int16 s
pos
371 Some
(chunks, ncompletesources)
375 emule_extension = emule_extension }
378 lprintf_nl
"QUERY FILE OF %s" (Md4.to_string t
.md4);
379 match t
.emule_extension with
381 | Some
(bitmap
, ncompletesources) ->
384 if ncompletesources >= 0 then
385 lprintf_nl
"Complete sources: %d" ncompletesources
387 let write emule
buf t
=
389 match t
.emule_extension with
391 | Some
(chunks, ncompletesources) ->
392 if extendedrequest emule
> 0 then begin
393 write_bitmap buf chunks;
394 if extendedrequest emule
> 1 && ncompletesources >= 0 then
395 buf_int16
buf ncompletesources
399 module QueryChunks
= OneMd4
(struct let m = "QUERY CHUNKS" end)
402 module QueryChunkMd4
= OneMd4
(struct let m = "QUERY CHUNKS MD4" end)
403 module EndOfDownload
= OneMd4
(struct let m = "END OF DOWNLOAD MD4" end)
404 module NoSuchFile
= OneMd4
(struct let m = "NO SUCH FILE" end)
406 module QueryChunksReply
= struct (* Request 80 *)
414 let md4 = get_md4 s
1 in
415 let chunks, pos = get_bitmap s
17 in
422 lprintf_nl
"CHUNKS for %s" (Md4.to_string t
.md4);
423 lprintf_nl
"%s\n" (Bitv.to_string t
.chunks)
427 write_bitmap buf t
.chunks;
428 if Bitv.length t
.chunks = 0 then buf_int8
buf 0
431 dec: [(96)(215)(1)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)]
433 OP_QUEUERANKING: int16
436 module QueryChunkMd4Reply
= struct (* Request 80 *)
444 let md4 = get_md4 s
1 in
445 let nchunks = get_int16 s
17 in
446 (* lprintf "nchunks : %d" nchunks; lprint_newline (); *)
447 let chunks = Array.make
nchunks md4 in
448 for i
= 0 to nchunks - 1 do
449 chunks.(i
) <- get_md4 s
(19 + i
* 16)
457 lprintf_nl
"CHUNKSMd4 for %s" (Md4.to_string t
.md4);
460 lprintf
" %s" (Md4.to_string b
))
466 let nchunks = Array.length t
.chunks in
467 buf_int16
buf nchunks;
468 for i
= 0 to nchunks - 1 do
469 buf_md4
buf t
.chunks.(i
)
473 module QueryFileReply
= struct
480 let name, _
= get_string s
17 in
486 lprintf_nl
"QUERY FILE REPLY OF %s : \"%s\"" (Md4.to_string t
.md4) t
.name
490 buf_string
buf t
.name
504 let parse usesixtyfour len s
=
507 usesixtyfour
= usesixtyfour
;
508 start_pos
= if usesixtyfour
then get_int64 s
17 else get_uint64_32 s
17;
509 end_pos
= if usesixtyfour
then get_int64 s
25 else get_uint64_32 s
21;
511 bloc_begin
= if usesixtyfour
then 33 else 25;
512 bloc_len
= if usesixtyfour
then len
- 33 else len
- 25;
516 lprintf_nl
"BLOC OF %s len %Ld [%Ld - %Ld] " (Md4.to_string t
.md4)
517 (t
.end_pos
-- t
.start_pos
)
523 if t
.usesixtyfour
then buf_int64
buf t
.start_pos
else buf_int64_32
buf t
.start_pos
;
524 if t
.usesixtyfour
then buf_int64
buf t
.end_pos
else buf_int64_32
buf t
.end_pos
;
525 Buffer.add_substring
buf t
.bloc_str t
.bloc_begin t
.bloc_len
528 module QueryBloc
= struct
532 start_pos1
: int64
; (* 180 ko *)
540 let parse usesixtyfour len s
=
543 usesixtyfour
= usesixtyfour
;
544 start_pos1
= if usesixtyfour
then get_int64 s
17 else get_uint64_32 s
17;
545 end_pos1
= if usesixtyfour
then get_int64 s
41 else get_uint64_32 s
29;
546 start_pos2
= if usesixtyfour
then get_int64 s
25 else get_uint64_32 s
21;
547 end_pos2
= if usesixtyfour
then get_int64 s
49 else get_uint64_32 s
33;
548 start_pos3
= if usesixtyfour
then get_int64 s
33 else get_uint64_32 s
25;
549 end_pos3
= if usesixtyfour
then get_int64 s
57 else get_uint64_32 s
37;
553 lprintf_nl
"QUERY BLOCS OF %s [%s - %s] [%s - %s] [%s - %s]"
554 (Md4.to_string t
.md4)
555 (Int64.to_string t
.start_pos1
) (Int64.to_string t
.end_pos1
)
556 (Int64.to_string t
.start_pos2
) (Int64.to_string t
.end_pos2
)
557 (Int64.to_string t
.start_pos3
) (Int64.to_string t
.end_pos3
)
561 if t
.usesixtyfour
then buf_int64
buf t
.start_pos1
else buf_int64_32
buf t
.start_pos1
;
562 if t
.usesixtyfour
then buf_int64
buf t
.start_pos2
else buf_int64_32
buf t
.start_pos2
;
563 if t
.usesixtyfour
then buf_int64
buf t
.start_pos3
else buf_int64_32
buf t
.start_pos3
;
564 if t
.usesixtyfour
then buf_int64
buf t
.end_pos1
else buf_int64_32
buf t
.end_pos1
;
565 if t
.usesixtyfour
then buf_int64
buf t
.end_pos2
else buf_int64_32
buf t
.end_pos2
;
566 if t
.usesixtyfour
then buf_int64
buf t
.end_pos3
else buf_int64_32
buf t
.end_pos3
570 module NoArg
= functor(M
: sig val m : string end) -> (struct
578 let write (buf: Buffer.t
) (t
: t
) = unit
583 val parse : int -> string -> t
584 val print : t -> unit
585 val write : Buffer.t -> t -> unit
590 module AvailableSlot
= NoArg
(struct let m = "AvailableSlot" end)
591 module ReleaseSlot
= NoArg
(struct let m = "ReleaseSlot" end)
592 module OutOfParts
= NoArg
(struct let m = "OutOfParts" end)
593 module ViewFiles
= NoArg
(struct let m = "VIEW FILES" end)
594 module ViewDirs
= NoArg
(struct let m = "VIEW DIRS" end)
596 module ViewFilesReply
= struct
605 type t = tagged_file list
607 let names_of_tag = file_common_tags
609 let rec get_files s
pos n =
610 if n = 0 then [], pos else
611 let md4 = get_md4 s
pos in
612 let ip = get_ip s
(pos + 16) in
613 let port = get_port s
(pos + 20) in
614 let tags, pos = get_tags s
(pos+22) names_of_tag in
621 let files, pos = get_files s
pos (n-1) in
625 let n = get_int s
1 in
626 let files, pos = get_files s
5 n in
630 lprintf_nl
"VIEW FILES REPLY:";
633 lprintf_nl
" MD4: %s" (Md4.to_string
t.f_md4
);
634 lprintf_nl
" ip: %s" (Ip.to_string
t.f_ip
);
635 lprintf_nl
" port: %d" t.f_port
;
638 lprint_newline
();) t
640 let rec write_files buf files =
644 buf_md4
buf file.f_md4
;
645 buf_ip
buf file.f_ip
;
646 buf_port
buf file.f_port
;
647 buf_tags
buf file.f_tags
names_of_tag;
648 write_files buf files
651 buf_int
buf (List.length
t);
654 let rec write_files_max buf files nfiles max_len
=
655 let prev_len = Buffer.length
buf in
657 [] -> nfiles
, prev_len
659 buf_md4
buf file.f_md4
;
660 buf_ip
buf file.f_ip
;
661 buf_port
buf file.f_port
;
662 buf_tags
buf file.f_tags
names_of_tag;
663 if Buffer.length
buf < max_len
then
664 write_files_max buf files (nfiles
+1) max_len
669 module ViewDirsReply
= struct
673 let rec get_dirs s
pos n =
674 if n = 0 then [], pos else
675 let dir, pos = get_string16 s
pos in
676 let dirs, pos = get_dirs s
pos (n-1) in
680 let dirs, pos = get_dirs s
2 (get_int16 s
0) in
684 lprintf_nl
"VIEW DIRS REPLY:";
685 List.iter
(fun dir ->
686 lprintf_nl
"DIR: %s" dir;) t
689 buf_int
buf (List.length
t);
690 List.iter
(fun dir ->
691 buf_string
buf dir;) t
695 module ViewFilesDir
= struct
700 lprintf_nl
"VIEW FILES DIR: %s" t
703 let dir, pos = get_string s
1 in
711 module ViewFilesDirReply
= struct
713 type t = string * tagged_file list
715 let names_of_tag = file_common_tags
718 let dir, pos = get_string s
1 in
719 let n = get_int s
(pos+1) in
720 let files, pos = ViewFilesReply.get_files s
(pos+5) n in
724 lprintf_nl
"VIEW FILES DIR REPLY:";
725 let dir, files = t in begin
726 lprintf_nl
"DIR: %s" dir;
727 List.iter
(fun file ->
729 lprintf_nl
" MD4: %s" (Md4.to_string
file.f_md4
);
730 lprintf_nl
" ip: %s" (Ip.to_string
file.f_ip
);
731 lprintf_nl
" port: %d" file.f_port
;
733 print_tags
file.f_tags
;
734 lprint_newline
();) files
738 let dir, files = t in begin
740 buf_int
buf (List.length
files);
741 ViewFilesReply.write_files buf files
746 module OtherLocations
= struct
752 for i
= 0 to len
/ 4 - 1 do
753 list := (get_ip s
(i
*4+1)) :: !list;
758 lprintf_nl
"OTHER LOCATIONS:\n";
760 lprintf_nl
" ip: %s" (Ip.to_string
ip);) t
763 List.iter
(buf_ip
buf) t
766 module NewUserID
= struct
771 get_ip s
1, get_ip s
5
773 let print (ip1
,ip2
) =
774 lprintf_nl
"NEW USER ID: %s -> %s" (Ip.to_string ip1
)
777 let write buf (ip1
,ip2
) =
783 module Sources
= struct
787 sources
: (Ip.t * int * Ip.t) list;
791 let len = get_int16 s
1 in
792 let md4 = get_md4 s
3 in
794 (* let pos = 19 in *)
795 for i
= 0 to len - 1 do
796 list := (get_ip s
(19 + 10 * i
), get_port s
(23 + 10 * i
),
797 get_ip s
(25 + 10 * i
)) :: !list;
804 lprintf_nl
"SOURCES for %s:" (Md4.to_string
t.md4);
805 List.iter
(fun (ip1
, port, ip2
) ->
806 lprintf_nl
" %s:%d:%s" (Ip.to_string ip1
) port(Ip.to_string ip2
)) t.sources
809 buf_int16
buf (List.length
t.sources
);
811 List.iter
(fun (ip1
, port, ip2
) ->
814 buf_ip
buf ip2
) t.sources
817 module EmuleClientInfo
= struct
820 version
: int; (* CURRENT_VERSION_SHORT = !!emule_protocol_version *)
821 protversion
: int; (* EMULE_PROTOCOL_VERSION = 0x1 *)
822 mutable tags : tag
list;
825 let names_of_tag = client_common_tags
828 List.map
(fun (v
, name) -> (v
, Field_KNOWN
name)) names_of_tag
831 let version = get_uint8 s
1 in
832 let protversion = get_uint8 s
2 in
833 let tags,_
= get_tags s
3 names_of_tag in
836 protversion = protversion;
841 let b1 = Buffer.create
50 in
842 lbprint_tags b1 t.tags;
843 lprintf_nl
"%s: [version: %d] [protversion: %d] [tags:%s]" m t.version t.protversion (Buffer.contents
b1)
846 buf_int8
buf t.version;
847 buf_int8
buf t.protversion;
848 buf_tags
buf t.tags names_of_tag;
852 module EmuleQueueRanking
= struct
856 let parse len s
= get_int16 s
1
858 lprintf_nl
"EmuleQueueRanking: %d" t
860 let string_null10 = String.make
10 (char_of_int
0)
864 Buffer.add_string
buf string_null10
868 module QueueRank
= struct
872 let parse len s
= get_int s
1
874 lprintf_nl
"QueueRank: %d" t
881 module EmuleRequestSources
= struct
889 lprintf_nl
"EmuleRequestSources: %s" (Md4.to_string
t)
897 let buf_estring buf s
=
898 let len = String.length s
in
900 Buffer.add_string
buf s
902 module EmuleSignatureReq
= struct
910 lprintf_nl
"EmuleSignatureReq [type %d] [sig(%d): %s]" t.ip_type
(String.length
t.signature
) (String.escaped
t.signature
)
913 let mlen = get_uint8 s
1 in
914 let slen = String.length s
in
915 let signature = String.sub s
2 mlen in
916 let ip_type = if mlen = (slen-2) then 0 else get_uint8 s
(2 + mlen) in
918 signature = signature;
923 buf_estring buf t.signature;
924 if (t.ip_type <> 0) then
925 buf_int8
buf t.ip_type;
930 module EmulePublicKeyReq
= struct
935 lprintf_nl
"EmulePublicKeyReq [key(%d): %s]" (String.length
t) (String.escaped
t)
938 let len = get_uint8 s
1 in
947 module EmuleCaptchaReq
= struct
952 lprintf_nl
"EmuleCaptchaReq [CAPTCHA BMP length=%d bytedata=%s]" (String.length
t) (String.escaped
t)
955 String.sub s
2 (len - 2)
963 module EmuleCaptchaRes
= struct
968 lprintf_nl
"EmuleCaptchaRes RESPONSE=%d" t
979 module EmuleSecIdentStateReq
= struct
987 lprintf_nl
"EmuleSecIdentStateReq [state: %d] [challenge: %Ld]" t.state
t.challenge
990 let state = get_uint8 s
1 in
991 let challenge = get_uint64_32 s
2 in
994 challenge = challenge;
998 buf_int8
buf t.state;
999 buf_int64_32
buf t.challenge
1003 module EmuleRequestSourcesReply
= struct
1008 mutable src_server_ip
: Ip.t;
1009 mutable src_server_port
: int;
1010 mutable src_md4
: Md4.t;
1011 mutable src_cc
: int option;
1016 sources
: source array
;
1019 let dummy_source = {
1022 src_server_ip
= Ip.null
;
1023 src_server_port
= 0;
1029 let md4 = get_md4 s
1 in
1030 let ncount = get_int16 s
17 in
1033 if ncount = 0 then [||] else
1034 let slen = (len - 19) / ncount in
1035 (* lprintf "PER SOURCES LEN: %d\n" slen; *)
1036 let sources = Array.make
ncount dummy_source in
1037 let rec iter pos i
=
1040 let ip = get_ip s
pos in
1044 src_port
= get_int16 s
(pos+4);
1045 src_cc
= Geoip.get_country_code_option
ip
1048 if slen > 6 then begin
1049 ss.src_server_ip
<- get_ip s
(pos+6);
1050 ss.src_server_port
<- get_int16 s
(pos+10);
1051 if slen > 12 && (sourceexchange e
> 1) then begin
1052 ss.src_md4
<- get_md4 s
(pos+12);
1071 let ncount = Array.length
t.sources in
1072 lprintf_nl
"EMULE SOURCES REPLY: %d sources for %s"
1073 ncount (Md4.to_string
t.md4);
1074 for i
= 0 to ncount - 1 do
1075 let s = t.sources.(i
) in
1077 (if Ip.valid
s.src_ip
then
1078 Printf.sprintf
"%s:%d" (Ip.to_string
s.src_ip
) s.src_port
1080 Printf.sprintf
"%s:%d (Indirect)" (Ip.to_string
s.src_server_ip
) s.src_server_port
)
1081 (if s.src_md4
!= Md4.null
then
1082 Printf.sprintf
"MD4: %s" (Md4.to_string
s.src_md4
)
1088 let ncount = Array.length
t.sources in
1089 buf_int16
buf ncount;
1091 for i
= 0 to ncount - 1 do
1092 let s = t.sources.(i
) in
1093 buf_ip
buf s.src_ip
;
1094 buf_port
buf s.src_port
;
1095 if sourceexchange e
> 0 then begin
1096 buf_ip
buf s.src_server_ip
;
1097 buf_port
buf s.src_server_port
;
1098 if sourceexchange e
> 1 then
1099 buf_md4
buf s.src_md4
1104 module EmuleFileDesc
= struct
1112 let rating = get_uint8
s 1 in
1113 let (comment
, _
) = get_string32
s 2 in
1120 lprintf_nl
"EmuleFileDesc [%d][%s]" t.rating t.comment
1123 buf_int8
buf t.rating;
1124 buf_string
buf t.comment
1127 module EmuleCompressedPart
= struct
1131 usesixtyfour
: bool;
1137 let parse usesixtyfour
len s =
1140 usesixtyfour
= usesixtyfour
;
1141 statpos
= if usesixtyfour
then get_int64
s 17 else get_uint64_32
s 17;
1142 newsize
= if usesixtyfour
then get_uint64_32
s 25 else get_uint64_32
s 21;
1143 bloc
= if usesixtyfour
then String.sub
s 29 (len-29) else String.sub
s 25 (len-25)
1147 lprintf_nl
"EmuleCompressedPart for %s %Ld %Ld len %d"
1148 (Md4.to_string
t.md4) t.statpos
t.newsize
(String.length
t.bloc
)
1152 if t.usesixtyfour
then buf_int64
buf t.statpos
else buf_int64_32
buf t.statpos
;
1153 buf_int64_32
buf t.newsize
;
1154 Buffer.add_string
buf t.bloc
1157 module EmulePortTestReq
= struct
1162 lprintf_nl
"Emule porttest request %s" (String.escaped
s)
1172 | ConnectReq
of Connect.t
1173 | ConnectReplyReq
of Connect.t
1174 | QueryFileReq
of QueryFile.t
1175 | QueryFileReplyReq
of QueryFileReply.t
1177 | QueryBlocReq
of QueryBloc.t
1178 | JoinQueueReq
of JoinQueue.t (* sent before queryBloc *)
1179 | AvailableSlotReq
of AvailableSlot.t
1180 | ReleaseSlotReq
of ReleaseSlot.t
1181 | OutOfPartsReq
of OutOfParts.t
1182 | QueryChunksReq
of QueryChunks.t
1183 | QueryChunksReplyReq
of QueryChunksReply.t
1184 | QueryChunkMd4Req
of QueryChunkMd4.t
1185 | QueryChunkMd4ReplyReq
of QueryChunkMd4Reply.t
1186 | ViewFilesReq
of ViewFiles.t
1187 | ViewFilesReplyReq
of ViewFilesReply.t
1188 | ViewDirsReq
of ViewDirs.t
1189 | ViewDirsReplyReq
of ViewDirsReply.t
1190 | ViewFilesDirReq
of ViewFilesDir.t
1191 | ViewFilesDirReplyReq
of ViewFilesDirReply.t
1192 | QueueReq
of OtherLocations.t
1193 | UnknownReq
of int * string
1194 | OtherLocationsReq
of OtherLocations.t
1196 | SourcesReq
of Sources.t
1197 | EndOfDownloadReq
of EndOfDownload.t
1198 | NewUserIDReq
of NewUserID.t
1199 | NoSuchFileReq
of NoSuchFile.t
1200 | QueueRankReq
of QueueRank.t
1202 | EmuleClientInfoReq
of EmuleClientInfo.t
1203 | EmuleClientInfoReplyReq
of EmuleClientInfo.t
1204 | EmuleQueueRankingReq
of EmuleQueueRanking.t
1205 | EmuleRequestSourcesReq
of EmuleRequestSources.t
1206 | EmuleRequestSourcesReplyReq
of EmuleRequestSourcesReply.t
1207 | EmuleFileDescReq
of EmuleFileDesc.t
1208 | EmulePublicKeyReq
of EmulePublicKeyReq.t
1209 | EmuleSignatureReq
of EmuleSignatureReq.t
1210 | EmuleSecIdentStateReq
of EmuleSecIdentStateReq.t
1211 | EmuleMultiPacketReq
of Md4.t * t list
1212 | EmuleMultiPacketAnswerReq
of Md4.t * t list
1213 | EmuleCompressedPart
of EmuleCompressedPart.t
1214 | EmulePortTestReq
of EmulePortTestReq.t
1215 | EmuleCaptchaReq
of EmuleCaptchaReq.t
1216 | EmuleCaptchaRes
of EmuleCaptchaRes.t
1221 | ConnectReq
t -> Connect.print t
1222 | ConnectReplyReq
t -> Connect.print t
1223 | QueryFileReq
t -> QueryFile.print t
1224 | QueryFileReplyReq
t -> QueryFileReply.print t
1225 | BlocReq
t -> Bloc.print t
1226 | QueryBlocReq
t -> QueryBloc.print t
1227 | JoinQueueReq
t -> JoinQueue.print t
1228 | AvailableSlotReq
t -> AvailableSlot.print t
1229 | ReleaseSlotReq
t -> ReleaseSlot.print t
1230 | OutOfPartsReq
t -> OutOfParts.print t
1231 | QueryChunksReq
t -> QueryChunks.print t
1232 | QueryChunksReplyReq
t -> QueryChunksReply.print t
1233 | QueryChunkMd4Req
t -> QueryChunkMd4.print t
1234 | QueryChunkMd4ReplyReq
t -> QueryChunkMd4Reply.print t
1235 | ViewFilesReplyReq
t -> ViewFilesReply.print t
1236 | ViewFilesReq
t -> ViewFiles.print t
1237 | ViewDirsReq
t -> ViewDirs.print t
1238 | ViewDirsReplyReq
t -> ViewDirsReply.print t
1239 | ViewFilesDirReq
t -> ViewFilesDir.print t
1240 | ViewFilesDirReplyReq
t -> ViewFilesDirReply.print t
1241 | QueueReq
t -> OtherLocations.print t
1242 | OtherLocationsReq
t -> OtherLocations.print t
1243 | SayReq
t -> Say.print t
1244 | SourcesReq
t -> Sources.print t
1245 | EndOfDownloadReq
t -> EndOfDownload.print t
1246 | NewUserIDReq
t -> NewUserID.print t
1247 | NoSuchFileReq
t -> NoSuchFile.print t
1251 | EmuleClientInfoReq
t ->
1252 EmuleClientInfo.print "EmuleClientInfo" t
1253 | EmuleClientInfoReplyReq
t ->
1254 EmuleClientInfo.print "EmuleClientInfoReply" t
1255 | EmuleQueueRankingReq
t ->
1256 EmuleQueueRanking.print t
1257 | EmuleRequestSourcesReq
t ->
1258 EmuleRequestSources.print t
1259 | EmuleRequestSourcesReplyReq
t ->
1260 EmuleRequestSourcesReply.print t
1262 | EmuleFileDescReq
t ->
1263 EmuleFileDesc.print t
1265 | EmuleMultiPacketReq
(md4, list) ->
1266 lprintf_nl
"EmuleMultiPacket for %s:" (Md4.to_string
md4);
1272 | EmuleMultiPacketAnswerReq
(md4, list) ->
1273 lprintf_nl
"EmuleMultiPacketAnswer for %s:" (Md4.to_string
md4);
1278 | EmuleSecIdentStateReq
t ->
1279 EmuleSecIdentStateReq.print t
1280 | EmuleSignatureReq
t ->
1281 EmuleSignatureReq.print t
1282 | EmulePublicKeyReq
t ->
1283 EmulePublicKeyReq.print t
1284 | EmuleCompressedPart
t ->
1285 EmuleCompressedPart.print t
1286 | EmulePortTestReq
t ->
1287 EmulePortTestReq.print t
1288 | EmuleCaptchaReq
t ->
1289 EmuleCaptchaReq.print t
1290 | EmuleCaptchaRes
t ->
1291 EmuleCaptchaRes.print t
1292 | UnknownReq
(opcode
, s) ->
1293 let len = String.length
s in
1294 lprintf_nl
"UnknownReq: magic (%d), opcode (%d) len (%d)" opcode
1298 for i
= 0 to len - 1 do
1300 let n = int_of_char
c in
1301 if n > 31 && n < 127 then
1308 for i
= 0 to len - 1 do
1310 let n = int_of_char
c in
1316 let rec parse_emule_packet emule opcode
len s =
1318 lprintf "Emule magic: %d opcode %d:" magic opcode; lprint_newline ();
1319 dump s; lprint_newline ();
1321 let t = match opcode
with
1322 | 1 -> EmuleClientInfoReq
(EmuleClientInfo.parse len s)
1323 | 2 -> EmuleClientInfoReplyReq
(EmuleClientInfo.parse len s)
1325 | 0x60 (* 96 *) -> EmuleQueueRankingReq
(EmuleQueueRanking.parse len s)
1327 | 0x61 (* 97 *) -> EmuleFileDescReq
(EmuleFileDesc.parse len s)
1329 | 0x81 (* 129 *) -> EmuleRequestSourcesReq
(EmuleRequestSources.parse len s)
1331 EmuleRequestSourcesReplyReq
(
1332 EmuleRequestSourcesReply.parse emule
len s)
1335 (* OP_COMPRESSEDPART *)
1336 EmuleCompressedPart
(EmuleCompressedPart.parse false len s)
1339 EmulePublicKeyReq
(EmulePublicKeyReq.parse len s)
1342 EmuleSignatureReq
(EmuleSignatureReq.parse len s)
1345 EmuleSecIdentStateReq
(EmuleSecIdentStateReq.parse len s)
1347 (* | 0x90 (* 144 *) -> RequestPreview *)
1348 (* | 0x91 (* 145 *) -> PreviewAnswer *)
1350 let md4 = get_md4
s 1 in
1352 (* lprintf "MULTI EMULE VERSION %d"
1353 (extendedrequest emule); print_newline (); *)
1354 (* let pos = 17 in *)
1357 let opcode = get_uint8
s pos in
1360 let bitmap, pos = get_bitmap s (pos+1) in
1361 let ncompletesources, pos =
1362 if extendedrequest emule
> 1 then
1363 get_int16
s pos, pos+2
1367 QueryFile.md4 = md4;
1368 QueryFile.emule_extension = Some
(bitmap, ncompletesources);
1371 (QueryChunksReq
md4) :: iter (pos+1)
1373 (EmuleRequestSourcesReq
md4) :: iter (pos+1)
1375 lprintf_nl
"Unknown short emule packet %d" opcode;
1380 EmuleMultiPacketReq
(md4, iter 17)
1383 if String.length
s < 16 then begin
1384 if !verbose_unknown_messages
then lprintf_nl
"EmuleMultiPacketAnswer: incomplete request";
1387 let md4 = get_md4
s 1 in
1389 (* lprintf "MULTI EMULE VERSION %d"
1390 (extendedrequest emule); print_newline (); *)
1391 let rec iter s pos len =
1393 let opcode = get_uint8
s pos in
1396 let module Q
= QueryFileReply
in
1397 let name, pos = get_string
s (pos+1) in
1402 (QueryFileReplyReq
q) :: (iter s pos len)
1404 let module Q
= QueryChunksReply
in
1405 let chunks, pos = get_bitmap s (pos+1) in
1410 (QueryChunksReplyReq
q) :: (iter s pos len)
1412 lprintf_nl
"Unknown packet in emule multipacket 0x93: %d" opcode;
1417 EmuleMultiPacketAnswerReq
(md4, iter s 17 len)
1419 | 0xa1 (* 161 *) -> (* OP_COMPRESSEDPART_I64 *)
1420 EmuleCompressedPart
(EmuleCompressedPart.parse true len s)
1421 | 0xa2 -> BlocReq
(Bloc.parse true len s) (* OP_SENDINGPART_I64 *)
1422 | 0xa3 -> QueryBlocReq
(QueryBloc.parse true len s) (*OP_REQUESTPARTS_I64 *)
1423 | 0xa5 (* 165 *) -> EmuleCaptchaReq
(EmuleCaptchaReq.parse len s) (* OP_CHATCAPTCHAREQ *)
1424 | 0xa6 (* 166 *) -> EmuleCaptchaRes
(EmuleCaptchaRes.parse s) (* OP_CHATCAPTCHARES *)
1425 | 0xfe (* 254 *) -> EmulePortTestReq
s
1428 if !CommonOptions.verbose_unknown_messages
then
1429 lprintf_nl
"EDK: unknown eMule message %d" code
;
1433 lprintf "EMULE MESSAGE: "; lprint_newline ();
1435 lprint_newline (); *)
1438 and parse emule_version magic
s =
1440 let len = String.length
s in
1441 if len = 0 then raise Not_found
;
1442 let opcode = int_of_char
(s.[0]) in
1443 (*lprintf "opcode: %d" opcode; lprint_newline (); *)
1448 | 1 -> ConnectReq
(Connect.parse false len s)
1449 | 70 -> BlocReq
(Bloc.parse false len s)
1450 | 71 -> QueryBlocReq
(QueryBloc.parse false len s)
1451 | 72 -> NoSuchFileReq
(NoSuchFile.parse len s)
1452 | 73 -> EndOfDownloadReq
(EndOfDownload.parse len s)
1453 | 74 -> ViewFilesReq
(ViewFiles.parse len s)
1454 | 75 -> ViewFilesReplyReq
(ViewFilesReply.parse len s)
1455 | 76 -> ConnectReplyReq
(Connect.parse true len s)
1456 | 77 -> NewUserIDReq
(NewUserID.parse len s)
1457 | 78 -> SayReq
(Say.parse len s)
1458 | 79 -> QueryChunksReq
(QueryChunks.parse len s)
1459 | 80 -> QueryChunksReplyReq
(QueryChunksReply.parse len s)
1460 | 81 -> QueryChunkMd4Req
(QueryChunkMd4.parse len s)
1461 | 82 -> QueryChunkMd4ReplyReq
(QueryChunkMd4Reply.parse len s)
1462 (* JoinQueue: the sender wants to join the upload queue *)
1463 | 84 -> JoinQueueReq
(JoinQueue.parse len s)
1464 (* AvailableSlot: there is an available slot in upload queue *)
1465 | 85 -> AvailableSlotReq
(AvailableSlot.parse len s)
1466 (* ReleaseSlot: the upload is finished *)
1467 | 86 -> ReleaseSlotReq
(ReleaseSlot.parse len s)
1468 (* OutOfParts: the upload slot is not available *)
1469 | 87 -> OutOfPartsReq
(OutOfParts.parse len s)
1470 | 88 -> QueryFileReq
(QueryFile.parse emule_version
len s)
1471 | 89 -> QueryFileReplyReq
(QueryFileReply.parse len s)
1472 | 92 -> QueueRankReq
(QueueRank.parse len s)
1473 | 93 -> ViewDirsReq
(ViewDirs.parse len s)
1474 | 94 -> ViewFilesDirReq
(ViewFilesDir.parse len s)
1476 | 95 -> ViewDirsReplyReq (ViewDirsReply.parse len s)
1477 | 96 -> ViewFilesDirReplyReq (ViewFilesDirReply.parse len s)
1479 | 250 -> SourcesReq
(Sources.parse len s)
1481 | _
-> raise Not_found
1484 | 0xc5 -> (* 197: emule extended protocol *)
1485 parse_emule_packet emule_version
opcode len s
1487 (* Compressed packet, probably sent by cDonkey ? *)
1491 let s = Zlib2.uncompress_string2
(String.sub
s 1 (len-1)) in
1492 let s = Printf.sprintf
"%c%s" (char_of_int
opcode) s in
1494 parse_emule_packet emule_version
opcode (String.length
s) s
1497 if !CommonOptions.verbose_unknown_messages
then begin
1498 lprintf_nl
"Unknown message From client: %s (magic %d)"
1499 (Printexc2.to_string e
) magic
;
1500 let tmp_file = Filename2.temp_file
"comp" "pak" in
1501 File.from_string
tmp_file s;
1502 lprintf_nl
"Saved unknown packet %s" tmp_file;
1506 UnknownReq
(magic
,s)
1510 if !CommonOptions.verbose_unknown_messages
then
1511 lprintf_nl
"Strange magic: %d" magic
;
1515 if !CommonOptions.verbose_unknown_messages
then begin
1516 lprintf_nl
"Unknown message From client: %s (magic %d)"
1517 (Printexc2.to_string e
) magic
;
1518 let tmp_file = Filename2.temp_file
"comp" "pak" in
1519 File.from_string
tmp_file s;
1520 lprintf_nl
"Saved unknown packet %s" tmp_file;
1525 UnknownReq
(magic
,s)
1527 let write emule
buf t =
1528 let magic = match t with
1529 EmuleMultiPacketAnswerReq _
1530 | EmuleMultiPacketReq _
1531 | EmuleSecIdentStateReq _
1532 | EmuleSignatureReq _
1533 | EmulePublicKeyReq _
1534 | EmuleRequestSourcesReplyReq _
1535 | EmuleRequestSourcesReq _
1536 | EmuleClientInfoReplyReq _
1537 | EmuleClientInfoReq _
1538 | EmuleFileDescReq _
1539 | EmuleQueueRankingReq _
1542 | EmuleCompressedPart _
1544 | QueryBlocReq
t when t.QueryBloc.usesixtyfour
-> 0xC5
1545 | BlocReq
t when t.Bloc.usesixtyfour
-> 0xC5
1553 Connect.write false buf t
1554 | ConnectReplyReq
t ->
1556 Connect.write true buf t
1559 QueryFile.write emule
buf t
1560 | QueryFileReplyReq
t ->
1562 QueryFileReply.write buf t
1565 OtherLocations.write buf t
1567 buf_int8
buf (if t.QueryBloc.usesixtyfour
then 0xa3 else 71);
1568 QueryBloc.write buf t
1570 buf_int8
buf (if t.Bloc.usesixtyfour
then 0xa2 else 70);
1574 JoinQueue.write emule
buf t
1575 | QueryChunksReq
t ->
1577 QueryChunks.write buf t
1578 | QueryChunksReplyReq
t ->
1580 QueryChunksReply.write buf t
1581 | QueryChunkMd4Req
t ->
1583 QueryChunkMd4.write buf t
1584 | QueryChunkMd4ReplyReq
t ->
1586 QueryChunkMd4Reply.write buf t
1587 | AvailableSlotReq
t ->
1589 AvailableSlot.write buf t
1590 | ReleaseSlotReq
t ->
1592 ReleaseSlot.write buf t
1593 | OutOfPartsReq
t ->
1595 OutOfParts.write buf t
1598 ViewFiles.write buf t
1599 | ViewFilesReplyReq
t ->
1601 ViewFilesReply.write buf t
1604 ViewDirs.write buf t
1605 | ViewDirsReplyReq
t ->
1607 ViewDirsReply.write buf t
1608 | ViewFilesDirReq
t ->
1610 ViewFilesDir.write buf t
1611 | ViewFilesDirReplyReq
t ->
1613 ViewFilesDirReply.write buf t
1614 | OtherLocationsReq
t ->
1616 OtherLocations.write buf t
1625 NewUserID.write buf t
1626 | EndOfDownloadReq
t ->
1628 EndOfDownload.write buf t
1629 | NoSuchFileReq
t ->
1631 NoSuchFile.write buf t
1634 QueueRank.write buf t
1636 | EmuleClientInfoReq
t ->
1638 EmuleClientInfo.write buf t
1639 | EmuleClientInfoReplyReq
t ->
1641 EmuleClientInfo.write buf t
1642 | EmuleQueueRankingReq
t ->
1644 EmuleQueueRanking.write buf t
1645 | EmuleRequestSourcesReq
t ->
1647 EmuleRequestSources.write buf t
1648 | EmuleRequestSourcesReplyReq
t ->
1650 EmuleRequestSourcesReply.write emule
buf t
1651 | EmuleFileDescReq
t ->
1653 EmuleFileDesc.write buf t
1654 | EmuleCompressedPart
t ->
1655 buf_int8
buf (if t.EmuleCompressedPart.usesixtyfour
then 0xa1 else 0x40);
1656 EmuleCompressedPart.write buf t
1657 | EmuleMultiPacketReq
(md4, list) ->
1664 (match t.QueryFile.emule_extension with
1666 | Some
(bitmap, ncompletesources) ->
1667 write_bitmap buf bitmap;
1668 if ncompletesources >= 0 && extendedrequest emule
> 1 then
1669 buf_int16
buf ncompletesources)
1670 | QueryChunksReq _
->
1672 | EmuleRequestSourcesReq _
->
1675 lprintf_nl
"WARNING: Don't know how to write short packet:";
1680 | EmuleMultiPacketAnswerReq
(md4, list) ->
1685 QueryFileReplyReq
t ->
1687 buf_string
buf t.QueryFileReply.name
1688 | QueryChunksReplyReq
t ->
1690 write_bitmap buf t.QueryChunksReply.chunks
1692 lprintf_nl
"WARNING: Don't know how to write short packet:";
1697 | EmuleSecIdentStateReq
t ->
1699 EmuleSecIdentStateReq.write buf t
1701 | EmuleSignatureReq
t ->
1703 EmuleSignatureReq.write buf t
1705 | EmulePublicKeyReq
t ->
1707 EmulePublicKeyReq.write buf t
1709 | EmulePortTestReq
t ->
1711 EmulePortTestReq.write buf
1713 | EmuleCaptchaReq
t ->
1715 EmuleCaptchaReq.write buf t
1717 | EmuleCaptchaRes
t ->
1719 EmuleCaptchaRes.write buf t
1721 | UnknownReq
(opcode, s) ->
1722 Buffer.add_string
buf s
1728 ------------------------------------------------------
1729 1044008574.297 192.168.0.3:37522 -> 80.26.114.12:13842 of len 6
1730 ? Become Friend ? ping ?
1735 ------------------------------------------------------
1736 1044008576.274 80.26.114.12:13842 -> 192.168.0.3:37522 of len 6
1739 (227)(1)(0)(0)(0)(99)]
1741 ------------------------------------------------------
1742 1044008687.977 192.168.0.3:37522 -> 80.26.114.12:13842 of len 6
1748 ------------------------------------------------------
1749 1044008690.832 80.26.114.12:13842 -> 192.168.0.3:37522 of len 43
1750 Browse Main Dir Reply
1753 (2)(0)(0)(0) --------> 2 directories:
1754 (12)(0) C : \ D o w n l o a d s
1755 (17)(0) ! I n c o m p l e t e F i l e s
1758 ------------------------------------------------------
1759 1044008766.137 192.168.0.3:37522 -> 80.26.114.12:13842 of len 20
1764 (12)(0) C : \ D o w n l o a d s
1766 ------------------------------------------------------
1767 1044008769.045 80.26.114.12:13842 -> 192.168.0.3:37522 of len 300
1768 (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)]
1772 (12)(0) C : \ D o w n l o a d s
1773 (21)(0)(0)(0) 21 files
1775 (152)(50)(229)(158)(218)(141)(217)(138)(110)(181)(54)(40)(41)(104)(86)(179)
1781 (11)(0) d e s k t o p . i n i
1789 (121)(16)(15)(57)(79)(90)(219)(105)(101)(200)(10)(124)(29)(27)(70)(128)
1795 (15)(0) u t b o n u s p a c k . z i p
1812 (* 92: Queue Rank *)