fix some "deprecated" warnings
[mldonkey.git] / src / networks / donkey / donkeyProtoClient.ml
blob099d6e4f5b623adf855aa8ac639574dac00ad53c
1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
2 (*
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
20 open Options
21 open Int64ops
22 open AnyEndian
23 open Printf2
24 open Md4
25 open CommonTypes
26 open LittleEndian
27 open CommonGlobals
28 open CommonOptions
30 open DonkeyOptions
31 open DonkeyTypes
32 open DonkeyMftp
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 ();
45 emule_release = "";
46 emule_osinfosupport = 1;
47 emule_features = 3;
49 (* emule_miscoptions1 *)
50 received_miscoptions1 = false;
51 emule_aich = 0;
52 emule_unicode = 0;
53 emule_udpver = 0;
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*)
58 emule_comments = 1;
59 emule_peercache = 0;
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;
70 emule_largefiles = 1;
71 emule_kad_version = 0;
72 emule_support_captcha = 1;
75 let emule_miscoptions1 m =
76 let o =
77 (m.emule_aich lsl 29) lor
78 (m.emule_unicode lsl 28) lor
79 (m.emule_udpver lsl 24) lor
80 (m.emule_compression lsl 20) lor
81 (m.emule_secident lsl 16) lor
82 (m.emule_sourceexchange lsl 12) lor
83 (m.emule_extendedrequest lsl 8) lor
84 (m.emule_comments lsl 4) lor
85 (m.emule_peercache lsl 3) lor
86 (m.emule_noviewshared lsl 2) lor
87 (m.emule_multipacket lsl 1) lor
88 (m.emule_supportpreview lsl 0)
90 Int64.of_int o
92 let update_emule_proto_from_miscoptions1 m o =
93 let o = Int64.to_int o in
94 m.emule_aich <- (o lsr 29) land 0x7;
95 m.emule_unicode <- (o lsr 28) land 0xf;
96 m.emule_udpver <- (o lsr 24) land 0xf;
97 m.emule_compression <- (o lsr 20) land 0xf;
98 m.emule_secident <- (o lsr 16) land 0xf;
99 m.emule_sourceexchange <- (o lsr 12) land 0xf;
100 m.emule_extendedrequest <- (o lsr 8) land 0xf;
101 m.emule_comments <- (o lsr 4) land 0xf;
102 m.emule_peercache <- (o lsr 3) land 0x1;
103 m.emule_noviewshared <- (o lsr 2) land 0x1;
104 m.emule_multipacket <- (o lsr 1) land 0x1;
105 m.emule_supportpreview <- (o lsr 0) land 0x1
107 let print_emule_proto_miscoptions1 m =
108 let buf = Buffer.create 50 in
109 if m.emule_aich <> 0 then Printf.bprintf buf " aich %d\n" m.emule_aich;
110 if m.emule_unicode <> 0 then Printf.bprintf buf " unicode %d\n" m.emule_unicode;
111 if m.emule_udpver <> 0 then Printf.bprintf buf " udpver %d\n" m.emule_udpver;
112 if m.emule_compression <> 0 then Printf.bprintf buf " compression %d\n" m.emule_compression;
113 if m.emule_secident <> 0 then Printf.bprintf buf " secident %d\n" m.emule_secident;
114 if m.emule_sourceexchange <> 0 then Printf.bprintf buf " sourceexchange %d\n" m.emule_sourceexchange;
115 if m.emule_extendedrequest <> 0 then Printf.bprintf buf " extendedrequest %d\n" m.emule_extendedrequest;
116 if m.emule_comments <> 0 then Printf.bprintf buf " comments %d\n" m.emule_comments;
117 if m.emule_peercache <> 0 then Printf.bprintf buf " peercache %d\n" m.emule_peercache;
118 if m.emule_noviewshared <> 0 then Printf.bprintf buf " noviewshared %d\n" m.emule_noviewshared;
119 if m.emule_multipacket <> 0 then Printf.bprintf buf " multipacket %d\n" m.emule_multipacket;
120 if m.emule_supportpreview <> 0 then Printf.bprintf buf " supportpreview %d\n" m.emule_supportpreview;
121 Buffer.contents buf
123 let emule_miscoptions2 m =
124 let o =
125 (m.emule_support_captcha lsl 11) lor
126 (m.emule_largefiles lsl 4)
128 Int64.of_int o
130 let update_emule_proto_from_miscoptions2 m o =
131 let o = Int64.to_int o in
132 m.emule_support_captcha <- (o lsr 11) land 0x1;
133 m.emule_require_crypt <- (o lsr 9) land 0x1;
134 m.emule_request_crypt <- (o lsr 8) land 0x1;
135 m.emule_support_crypt <- (o lsr 7) land 0x1;
136 m.emule_extmultipacket <- (o lsr 5) land 0x1;
137 m.emule_largefiles <- (o lsr 4) land 0x1;
138 m.emule_kad_version <- (o lsr 0) land 0xf
140 let print_emule_proto_miscoptions2 m =
141 let buf = Buffer.create 50 in
142 if m.emule_require_crypt <> 0 then Printf.bprintf buf " require_crypt %d\n" m.emule_require_crypt;
143 if m.emule_request_crypt <> 0 then Printf.bprintf buf " request_crypt %d\n" m.emule_request_crypt;
144 if m.emule_support_crypt <> 0 then Printf.bprintf buf " support_crypt %d\n" m.emule_support_crypt;
145 if m.emule_extmultipacket <> 0 then Printf.bprintf buf " extmultipacket %d\n" m.emule_extmultipacket;
146 if m.emule_largefiles <> 0 then Printf.bprintf buf " largefiles %d\n" m.emule_largefiles;
147 if m.emule_kad_version <> 0 then Printf.bprintf buf " kad_version %d\n" m.emule_kad_version;
148 if m.emule_support_captcha <> 0 then Printf.bprintf buf " support_captcha %d\n" m.emule_support_captcha;
149 Buffer.contents buf
151 let emule_compatoptions m =
152 (m.emule_osinfosupport lsl 0)
154 let update_emule_proto_from_compatoptions m o =
155 m.emule_osinfosupport <- (o lsr 0) land 0x1
157 let extendedrequest e =
158 min e.emule_extendedrequest mldonkey_emule_proto.emule_extendedrequest
160 let sourceexchange e =
161 min e.emule_sourceexchange mldonkey_emule_proto.emule_sourceexchange
164 BAD MESSAGE FROM CONNECTING CLIENT
165 UnknownReq:
166 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)]
167 dec: [
169 (16)
170 (231)(129)(131)(26)(79)(247)(154)(145)(251)(253)(167)(71)(125)(207)(106)(146)
171 (140)(123)(108)(139)
172 (70)(18)
173 (0)(0)(0)(0)
174 (0)(0)(0)(0)(0)(0)
177 let rec lbprint_tags buf tags =
178 match tags with
179 [] -> Printf.bprintf buf ""
180 | tag :: tags ->
181 Printf.bprintf buf " (%s)=(%s)" (escaped_string_of_field tag)
182 (string_of_tag_value tag.tag_value);
183 lbprint_tags buf tags
185 module Connect = struct
186 type t = {
187 hash_len : int;
188 md4 : Md4.t;
189 ip: Ip.t;
190 port: int;
191 tags : tag list;
192 server_info : (Ip.t * int) option;
193 left_bytes : string;
196 let names_of_tag = client_common_tags
198 let names_of_tag =
199 List.map (fun (v, name) -> (v, Field_KNOWN name)) names_of_tag
201 let parse reply len s =
202 let hash_len, pos = if not reply then get_uint8 s 1, 2 else -1, 1 in
203 let md4 = get_md4 s pos in
204 let ip = get_ip s (pos+16) in
205 let port = get_port s (pos+20) in
206 let tags, pos = get_tags s (pos+22) names_of_tag in
207 let server_info = Some (get_ip s pos, get_port s (pos+4)) in
208 let left_bytes = String.sub s (pos+6) (String.length s - pos - 6) in
210 hash_len = hash_len;
211 md4 = md4;
212 ip = ip;
213 port = port;
214 tags = tags;
215 server_info = server_info;
216 left_bytes = left_bytes;
220 let print t =
221 let b1 = Buffer.create 50 in
222 let b2 = Buffer.create 5 in
223 lbprint_tags b1 t.tags;
224 String.iter (fun c -> Printf.bprintf b2 "(%d)" (int_of_char c)) t.left_bytes;
225 lprintf_nl "Connect [hl: %d] [md4: %s] [ip: %s:%d] [server: %s] [left: %s] [tags:%s]"
226 t.hash_len
227 (Md4.to_string t.md4)
228 (Ip.to_string t.ip) t.port
229 (match t.server_info with
230 None -> "None"
231 | Some (ip, port) -> Printf.sprintf "%s:%d" (Ip.to_string ip) port)
232 (if String.length t.left_bytes <> 0 then (Buffer.contents b2) else "None")
233 (Buffer.contents b1)
236 let write reply buf t =
237 if not reply then
238 buf_int8 buf 16;
240 buf_md4 buf t.md4;
241 buf_ip buf t.ip;
242 buf_port buf t.port;
243 buf_tags buf t.tags names_of_tag;
244 begin
245 match t.server_info with
246 None ->
247 buf_ip buf Ip.null;
248 buf_port buf 0
249 | Some (ip, port) ->
250 buf_ip buf ip;
251 buf_port buf port;
256 module Say = struct
257 type t = string
259 let parse len s =
260 let (s, p) = get_string s 1 in
263 let print t =
264 lprintf_nl "SAY %s" t
266 let write buf t =
267 buf_string buf t
270 module OneMd4 = functor(M: sig val m : string end) -> (struct
271 type t = Md4.t
273 let parse len s =
274 get_md4 s 1
276 let print t =
277 lprintf_nl "OneMd4: %s OF %s" M.m (Md4.to_string t)
279 let write buf t =
280 buf_md4 buf t
282 end)
284 module JoinQueue = struct
285 type t = Md4.t option
287 let parse len s =
288 if len >= 17 then
289 Some (get_md4 s 1)
290 else None
292 let print t =
293 lprintf_nl "JOIN QUEUE %s"
294 (match t with None -> "" | Some md4 ->
295 Printf.sprintf "OF %s" (Md4.to_string md4))
297 let write emule buf t =
298 if extendedrequest emule > 0 then
299 match t with
300 None -> ()
301 | Some md4 ->
302 buf_md4 buf md4
305 : sig
306 type t
307 val parse : int -> string -> t
308 val print : t -> unit
309 val write : Buffer.t -> t -> unit
310 val t :t
315 (* In Emule, this message contains much more information, and will probably
316 remove the need for QueryChunks. *)
318 let get_bitmap s pos =
319 let nchunks = get_int16 s pos in
320 let chunks, pos =
321 if nchunks = 0 then (Bitv.create 0 false), pos+2 else
322 let pos = pos + 2 in
323 let chunks = (Bitv.create nchunks false) in
324 for i = 0 to (nchunks-1) / 8 do
325 let m = get_uint8 s (pos + i) in
326 for j = 0 to 7 do
327 let n = i * 8 + j in
328 if n < nchunks then
329 Bitv.set chunks n ((m land (1 lsl j)) <> 0);
330 done;
331 done;
332 let pos = pos + (nchunks-1)/8 + 1 in
333 chunks, pos
335 chunks, pos
337 let print_bitmap chunks =
338 lprintf "\n%s\n" (Bitv.to_string chunks)
340 let write_bitmap buf chunks =
341 let nchunks = Bitv.length chunks in
342 buf_int16 buf nchunks;
343 if nchunks > 0 then
344 for i = 0 to (nchunks-1) / 8 do
345 let m = ref 0 in
346 for j = 0 to 7 do
347 let n = i * 8 + j in
348 if n < nchunks then
349 if (Bitv.get chunks n) then
350 m := !m lor (1 lsl j);
351 done;
352 buf_int8 buf !m
353 done
355 module QueryFile = struct
356 type t = {
357 md4 : Md4.t;
358 emule_extension : (Bitv.t * int) option;
361 let parse emule len s =
362 (* lprintf "Query File: emule version %d len %d"
363 (extendedrequest emule) len;
364 print_newline (); *)
365 let md4 = get_md4 s 1 in
366 let emule_extension =
368 if len < 18 || extendedrequest emule = 0 then None else
369 let chunks, pos = get_bitmap s 17 in
370 let ncompletesources =
371 if extendedrequest emule > 1 && len > pos+1 then get_int16 s pos
372 else -1 in
373 Some (chunks, ncompletesources)
374 with _ -> None
376 { md4 = md4;
377 emule_extension = emule_extension }
379 let print t =
380 lprintf_nl "QUERY FILE OF %s" (Md4.to_string t.md4);
381 match t.emule_extension with
382 None -> ()
383 | Some (bitmap, ncompletesources) ->
384 print_bitmap bitmap;
385 lprint_newline ();
386 if ncompletesources >= 0 then
387 lprintf_nl "Complete sources: %d" ncompletesources
389 let write emule buf t =
390 buf_md4 buf t.md4;
391 match t.emule_extension with
392 None -> ()
393 | Some (chunks, ncompletesources) ->
394 if extendedrequest emule > 0 then begin
395 write_bitmap buf chunks;
396 if extendedrequest emule > 1 && ncompletesources >= 0 then
397 buf_int16 buf ncompletesources
401 module QueryChunks = OneMd4(struct let m = "QUERY CHUNKS" end)
402 (* Request 79 *)
404 module QueryChunkMd4 = OneMd4(struct let m = "QUERY CHUNKS MD4" end)
405 module EndOfDownload = OneMd4(struct let m = "END OF DOWNLOAD MD4" end)
406 module NoSuchFile = OneMd4(struct let m = "NO SUCH FILE" end)
408 module QueryChunksReply = struct (* Request 80 *)
410 type t = {
411 md4 : Md4.t;
412 chunks: Bitv.t;
415 let parse len s =
416 let md4 = get_md4 s 1 in
417 let chunks, pos = get_bitmap s 17 in
419 md4 = md4;
420 chunks = chunks;
423 let print t =
424 lprintf_nl "CHUNKS for %s" (Md4.to_string t.md4);
425 lprintf_nl "%s\n" (Bitv.to_string t.chunks)
427 let write buf t =
428 buf_md4 buf t.md4;
429 write_bitmap buf t.chunks;
430 if Bitv.length t.chunks = 0 then buf_int8 buf 0
433 dec: [(96)(215)(1)(0)(0)(0)(0)(0)(0)(0)(0)(0)(0)]
435 OP_QUEUERANKING: int16
438 module QueryChunkMd4Reply = struct (* Request 80 *)
440 type t = {
441 md4 : Md4.t;
442 chunks: Md4.t array;
445 let parse len s =
446 let md4 = get_md4 s 1 in
447 let nchunks = get_int16 s 17 in
448 (* lprintf "nchunks : %d" nchunks; lprint_newline (); *)
449 let chunks = Array.make nchunks md4 in
450 for i = 0 to nchunks - 1 do
451 chunks.(i) <- get_md4 s (19 + i * 16)
452 done;
454 md4 = md4;
455 chunks = chunks;
458 let print t =
459 lprintf_nl "CHUNKSMd4 for %s" (Md4.to_string t.md4);
460 lprint_string " ";
461 Array.iter (fun b ->
462 lprintf " %s" (Md4.to_string b))
463 t.chunks;
464 lprint_newline ()
466 let write buf t =
467 buf_md4 buf t.md4;
468 let nchunks = Array.length t.chunks in
469 buf_int16 buf nchunks;
470 for i = 0 to nchunks - 1 do
471 buf_md4 buf t.chunks.(i)
472 done
475 module QueryFileReply = struct
476 type t = {
477 md4 : Md4.t;
478 name : string;
481 let parse len s =
482 let name, _ = get_string s 17 in
483 { md4 = get_md4 s 1;
484 name = name;
487 let print t =
488 lprintf_nl "QUERY FILE REPLY OF %s : \"%s\"" (Md4.to_string t.md4) t.name
490 let write buf t =
491 buf_md4 buf t.md4;
492 buf_string buf t.name
495 module Bloc = struct
496 type t = {
497 md4 : Md4.t;
498 usesixtyfour : bool;
499 start_pos : int64;
500 end_pos: int64;
501 bloc_str: string;
502 bloc_begin : int;
503 bloc_len : int;
506 let parse usesixtyfour len s =
508 md4 = get_md4 s 1;
509 usesixtyfour = usesixtyfour;
510 start_pos = if usesixtyfour then get_int64 s 17 else get_uint64_32 s 17;
511 end_pos = if usesixtyfour then get_int64 s 25 else get_uint64_32 s 21;
512 bloc_str = s;
513 bloc_begin = if usesixtyfour then 33 else 25;
514 bloc_len = if usesixtyfour then len - 33 else len - 25;
517 let print t =
518 lprintf_nl "BLOC OF %s len %Ld [%Ld - %Ld] " (Md4.to_string t.md4)
519 (t.end_pos -- t.start_pos)
520 t.start_pos
521 t.end_pos
523 let write buf t =
524 buf_md4 buf t.md4;
525 if t.usesixtyfour then buf_int64 buf t.start_pos else buf_int64_32 buf t.start_pos;
526 if t.usesixtyfour then buf_int64 buf t.end_pos else buf_int64_32 buf t.end_pos;
527 Buffer.add_substring buf t.bloc_str t.bloc_begin t.bloc_len
530 module QueryBloc = struct
531 type t = {
532 md4 : Md4.t;
533 usesixtyfour : bool;
534 start_pos1 : int64; (* 180 ko *)
535 end_pos1: int64;
536 start_pos2 : int64;
537 end_pos2: int64;
538 start_pos3 : int64;
539 end_pos3: int64;
542 let parse usesixtyfour len s =
544 md4 = get_md4 s 1;
545 usesixtyfour = usesixtyfour;
546 start_pos1 = if usesixtyfour then get_int64 s 17 else get_uint64_32 s 17;
547 end_pos1 = if usesixtyfour then get_int64 s 41 else get_uint64_32 s 29;
548 start_pos2 = if usesixtyfour then get_int64 s 25 else get_uint64_32 s 21;
549 end_pos2 = if usesixtyfour then get_int64 s 49 else get_uint64_32 s 33;
550 start_pos3 = if usesixtyfour then get_int64 s 33 else get_uint64_32 s 25;
551 end_pos3 = if usesixtyfour then get_int64 s 57 else get_uint64_32 s 37;
554 let print t =
555 lprintf_nl "QUERY BLOCS OF %s [%s - %s] [%s - %s] [%s - %s]"
556 (Md4.to_string t.md4)
557 (Int64.to_string t.start_pos1) (Int64.to_string t.end_pos1)
558 (Int64.to_string t.start_pos2) (Int64.to_string t.end_pos2)
559 (Int64.to_string t.start_pos3) (Int64.to_string t.end_pos3)
561 let write buf t =
562 buf_md4 buf t.md4;
563 if t.usesixtyfour then buf_int64 buf t.start_pos1 else buf_int64_32 buf t.start_pos1;
564 if t.usesixtyfour then buf_int64 buf t.start_pos2 else buf_int64_32 buf t.start_pos2;
565 if t.usesixtyfour then buf_int64 buf t.start_pos3 else buf_int64_32 buf t.start_pos3;
566 if t.usesixtyfour then buf_int64 buf t.end_pos1 else buf_int64_32 buf t.end_pos1;
567 if t.usesixtyfour then buf_int64 buf t.end_pos2 else buf_int64_32 buf t.end_pos2;
568 if t.usesixtyfour then buf_int64 buf t.end_pos3 else buf_int64_32 buf t.end_pos3
571 let unit = ()
572 module NoArg = functor(M: sig val m : string end) -> (struct
573 type t = unit
575 let parse len s = ()
577 let print t =
578 lprintf_nl "%s:" M.m
580 let write (buf: Buffer.t) (t: t) = unit
582 let t = (() : t)
583 end : sig
584 type t
585 val parse : int -> string -> t
586 val print : t -> unit
587 val write : Buffer.t -> t -> unit
588 val t :t
592 module AvailableSlot = NoArg(struct let m = "AvailableSlot" end)
593 module ReleaseSlot = NoArg(struct let m = "ReleaseSlot" end)
594 module OutOfParts = NoArg(struct let m = "OutOfParts" end)
595 module ViewFiles = NoArg(struct let m = "VIEW FILES" end)
596 module ViewDirs = NoArg(struct let m = "VIEW DIRS" end)
598 module ViewFilesReply = struct
600 type file = {
601 md4: Md4.t;
602 ip: Ip.t;
603 port: int;
604 tags: tag list;
607 type t = tagged_file list
609 let names_of_tag = file_common_tags
611 let rec get_files s pos n =
612 if n = 0 then [], pos else
613 let md4 = get_md4 s pos in
614 let ip = get_ip s (pos + 16) in
615 let port = get_port s (pos + 20) in
616 let tags, pos = get_tags s (pos+22) names_of_tag in
617 let file = {
618 f_md4 = md4;
619 f_ip = ip;
620 f_port = port;
621 f_tags = tags;
622 } in
623 let files, pos = get_files s pos (n-1) in
624 file :: files, pos
626 let parse len s =
627 let n = get_int s 1 in
628 let files, pos = get_files s 5 n in
629 files
631 let print t =
632 lprintf_nl "VIEW FILES REPLY:";
633 List.iter (fun t ->
634 lprintf_nl "FILE:";
635 lprintf_nl " MD4: %s" (Md4.to_string t.f_md4);
636 lprintf_nl " ip: %s" (Ip.to_string t.f_ip);
637 lprintf_nl " port: %d" t.f_port;
638 lprintf " tags: ";
639 print_tags t.f_tags;
640 lprint_newline ();) t
642 let rec write_files buf files =
643 match files with
644 [] -> ()
645 | file :: files ->
646 buf_md4 buf file.f_md4;
647 buf_ip buf file.f_ip;
648 buf_port buf file.f_port;
649 buf_tags buf file.f_tags names_of_tag;
650 write_files buf files
652 let write buf t =
653 buf_int buf (List.length t);
654 write_files buf t
656 let rec write_files_max buf files nfiles max_len =
657 let prev_len = Buffer.length buf in
658 match files with
659 [] -> nfiles, prev_len
660 | file :: files ->
661 buf_md4 buf file.f_md4;
662 buf_ip buf file.f_ip;
663 buf_port buf file.f_port;
664 buf_tags buf file.f_tags names_of_tag;
665 if Buffer.length buf < max_len then
666 write_files_max buf files (nfiles+1) max_len
667 else
668 nfiles, prev_len
671 module ViewDirsReply = struct
673 type t = string list
675 let rec get_dirs s pos n =
676 if n = 0 then [], pos else
677 let dir, pos = get_string16 s pos in
678 let dirs, pos = get_dirs s pos (n-1) in
679 dir :: dirs, pos
681 let parse len s =
682 let dirs, pos = get_dirs s 2 (get_int16 s 0) in
683 dirs
685 let print t =
686 lprintf_nl "VIEW DIRS REPLY:";
687 List.iter (fun dir ->
688 lprintf_nl "DIR: %s" dir;) t
690 let write buf t =
691 buf_int buf (List.length t);
692 List.iter (fun dir ->
693 buf_string buf dir;) t
697 module ViewFilesDir = struct
699 type t = string
701 let print t =
702 lprintf_nl "VIEW FILES DIR: %s" t
704 let parse len s =
705 let dir, pos = get_string s 1 in
708 let write buf t =
709 buf_string buf t
713 module ViewFilesDirReply = struct
715 type t = string * tagged_file list
717 let names_of_tag = file_common_tags
719 let parse len s =
720 let dir, pos = get_string s 1 in
721 let n = get_int s (pos+1) in
722 let files, pos = ViewFilesReply.get_files s (pos+5) n in
723 dir, files
725 let print t =
726 lprintf_nl "VIEW FILES DIR REPLY:";
727 let dir, files = t in begin
728 lprintf_nl "DIR: %s" dir;
729 List.iter (fun file ->
730 lprintf_nl "FILE:";
731 lprintf_nl " MD4: %s" (Md4.to_string file.f_md4);
732 lprintf_nl " ip: %s" (Ip.to_string file.f_ip);
733 lprintf_nl " port: %d" file.f_port;
734 lprintf " tags: ";
735 print_tags file.f_tags;
736 lprint_newline ();) files
739 let write buf t =
740 let dir, files = t in begin
741 buf_string buf dir;
742 buf_int buf (List.length files);
743 ViewFilesReply.write_files buf files
748 module OtherLocations = struct
750 type t = Ip.t list
752 let parse len s =
753 let list = ref [] in
754 for i = 0 to len / 4 - 1 do
755 list := (get_ip s (i*4+1)) :: !list;
756 done;
757 !list
759 let print t =
760 lprintf_nl "OTHER LOCATIONS:\n";
761 List.iter (fun ip ->
762 lprintf_nl " ip: %s" (Ip.to_string ip);) t
764 let write buf t =
765 List.iter (buf_ip buf) t
768 module NewUserID = struct
770 type t = Ip.t * Ip.t
772 let parse len s =
773 get_ip s 1, get_ip s 5
775 let print (ip1,ip2) =
776 lprintf_nl "NEW USER ID: %s -> %s" (Ip.to_string ip1)
777 (Ip.to_string ip2)
779 let write buf (ip1,ip2) =
780 buf_ip buf ip1;
781 buf_ip buf ip2
785 module Sources = struct
787 type t = {
788 md4: Md4.t;
789 sources : (Ip.t * int * Ip.t) list;
792 let parse len s =
793 let len = get_int16 s 1 in
794 let md4 = get_md4 s 3 in
795 let list = ref [] in
796 (* let pos = 19 in *)
797 for i = 0 to len - 1 do
798 list := (get_ip s (19 + 10 * i), get_port s (23 + 10 * i),
799 get_ip s (25 + 10 * i)) :: !list;
800 done;
801 { md4 = md4;
802 sources = !list;
805 let print t =
806 lprintf_nl "SOURCES for %s:" (Md4.to_string t.md4);
807 List.iter (fun (ip1, port, ip2) ->
808 lprintf_nl " %s:%d:%s" (Ip.to_string ip1) port(Ip.to_string ip2)) t.sources
810 let write buf t =
811 buf_int16 buf (List.length t.sources);
812 buf_md4 buf t.md4;
813 List.iter (fun (ip1, port, ip2) ->
814 buf_ip buf ip1;
815 buf_port buf port;
816 buf_ip buf ip2) t.sources
819 module EmuleClientInfo = struct
821 type t = {
822 version : int; (* CURRENT_VERSION_SHORT = !!emule_protocol_version *)
823 protversion : int; (* EMULE_PROTOCOL_VERSION = 0x1 *)
824 mutable tags : tag list;
827 let names_of_tag = client_common_tags
829 let names_of_tag =
830 List.map (fun (v, name) -> (v, Field_KNOWN name)) names_of_tag
832 let parse len s =
833 let version = get_uint8 s 1 in
834 let protversion = get_uint8 s 2 in
835 let tags,_ = get_tags s 3 names_of_tag in
837 version = version;
838 protversion = protversion;
839 tags = tags;
842 let print m t =
843 let b1 = Buffer.create 50 in
844 lbprint_tags b1 t.tags;
845 lprintf_nl "%s: [version: %d] [protversion: %d] [tags:%s]" m t.version t.protversion (Buffer.contents b1)
847 let write buf t =
848 buf_int8 buf t.version;
849 buf_int8 buf t.protversion;
850 buf_tags buf t.tags names_of_tag;
854 module EmuleQueueRanking = struct
856 type t = int
858 let parse len s = get_int16 s 1
859 let print t =
860 lprintf_nl "EmuleQueueRanking: %d" t
862 let string_null10 = String.make 10 (char_of_int 0)
864 let write buf t =
865 buf_int16 buf t;
866 Buffer.add_string buf string_null10
870 module QueueRank = struct
872 type t = int
874 let parse len s = get_int s 1
875 let print t =
876 lprintf_nl "QueueRank: %d" t
878 let write buf t =
879 buf_int buf t
883 module EmuleRequestSources = struct
885 type t = Md4.t
887 let parse len s =
888 get_md4 s 1
890 let print t =
891 lprintf_nl "EmuleRequestSources: %s" (Md4.to_string t)
893 let write buf t =
894 buf_md4 buf t
899 let buf_estring buf s =
900 let len = String.length s in
901 buf_int8 buf len;
902 Buffer.add_string buf s
904 module EmuleSignatureReq = struct
906 type t = {
907 signature : string;
908 ip_type : int;
911 let print t =
912 lprintf_nl "EmuleSignatureReq [type %d] [sig(%d): %s]" t.ip_type (String.length t.signature) (String.escaped t.signature)
914 let parse len s =
915 let mlen = get_uint8 s 1 in
916 let slen = String.length s in
917 let signature = String.sub s 2 mlen in
918 let ip_type = if mlen = (slen-2) then 0 else get_uint8 s (2 + mlen) in
920 signature = signature;
921 ip_type = ip_type;
924 let write buf t =
925 buf_estring buf t.signature;
926 if (t.ip_type <> 0) then
927 buf_int8 buf t.ip_type;
932 module EmulePublicKeyReq = struct
934 type t = string
936 let print t =
937 lprintf_nl "EmulePublicKeyReq [key(%d): %s]" (String.length t) (String.escaped t)
939 let parse len s =
940 let len = get_uint8 s 1 in
941 String.sub s 2 len
943 let write buf t =
944 buf_estring buf t
949 module EmuleCaptchaReq = struct
951 type t = string
953 let print t =
954 lprintf_nl "EmuleCaptchaReq [CAPTCHA BMP length=%d bytedata=%s]" (String.length t) (String.escaped t)
956 let parse len s =
957 String.sub s 2 (len - 2)
959 let write buf t =
960 buf_estring buf t
965 module EmuleCaptchaRes = struct
967 type t = int
969 let print t =
970 lprintf_nl "EmuleCaptchaRes RESPONSE=%d" t
972 let parse s =
973 get_uint8 s 1
975 let write buf t =
976 buf_int8 buf t
981 module EmuleSecIdentStateReq = struct
983 type t = {
984 state : int;
985 challenge : int64;
988 let print t =
989 lprintf_nl "EmuleSecIdentStateReq [state: %d] [challenge: %Ld]" t.state t.challenge
991 let parse len s =
992 let state = get_uint8 s 1 in
993 let challenge = get_uint64_32 s 2 in
995 state = state;
996 challenge = challenge;
999 let write buf t =
1000 buf_int8 buf t.state;
1001 buf_int64_32 buf t.challenge
1005 module EmuleRequestSourcesReply = struct
1007 type source = {
1008 src_ip : Ip.t;
1009 src_port : int;
1010 mutable src_server_ip : Ip.t;
1011 mutable src_server_port : int;
1012 mutable src_md4 : Md4.t;
1013 mutable src_cc : int option;
1016 type t = {
1017 md4 : Md4.t;
1018 sources : source array;
1021 let dummy_source = {
1022 src_ip = Ip.null;
1023 src_port = 0;
1024 src_server_ip = Ip.null;
1025 src_server_port = 0;
1026 src_md4 = Md4.null;
1027 src_cc = None;
1030 let parse e len s =
1031 let md4 = get_md4 s 1 in
1032 let ncount = get_int16 s 17 in
1034 let sources =
1035 if ncount = 0 then [||] else
1036 let slen = (len - 19) / ncount in
1037 (* lprintf "PER SOURCES LEN: %d\n" slen; *)
1038 let sources = Array.make ncount dummy_source in
1039 let rec iter pos i =
1040 if i < ncount then
1041 let ss =
1042 let ip = get_ip s pos in
1044 dummy_source with
1045 src_ip = ip;
1046 src_port = get_int16 s (pos+4);
1047 src_cc = Geoip.get_country_code_option ip
1048 } in
1049 let pos =
1050 if slen > 6 then begin
1051 ss.src_server_ip <- get_ip s (pos+6);
1052 ss.src_server_port <- get_int16 s (pos+10);
1053 if slen > 12 && (sourceexchange e > 1) then begin
1054 ss.src_md4 <- get_md4 s (pos+12);
1055 pos + 28
1056 end else
1057 pos + 12
1059 else pos + 6
1061 sources.(i) <- ss;
1062 iter pos (i+1)
1064 iter 19 0;
1065 sources
1068 md4 = md4;
1069 sources = sources;
1072 let print t =
1073 let ncount = Array.length t.sources in
1074 lprintf_nl "EMULE SOURCES REPLY: %d sources for %s"
1075 ncount (Md4.to_string t.md4);
1076 for i = 0 to ncount - 1 do
1077 let s = t.sources.(i) in
1078 lprintf_nl "%s %s"
1079 (if Ip.valid s.src_ip then
1080 Printf.sprintf "%s:%d" (Ip.to_string s.src_ip) s.src_port
1081 else
1082 Printf.sprintf "%s:%d (Indirect)" (Ip.to_string s.src_server_ip) s.src_server_port)
1083 (if s.src_md4 != Md4.null then
1084 Printf.sprintf "MD4: %s" (Md4.to_string s.src_md4)
1085 else "")
1086 done
1088 let write e buf t =
1089 buf_md4 buf t.md4;
1090 let ncount = Array.length t.sources in
1091 buf_int16 buf ncount;
1093 for i = 0 to ncount - 1 do
1094 let s = t.sources.(i) in
1095 buf_ip buf s.src_ip;
1096 buf_port buf s.src_port;
1097 if sourceexchange e > 0 then begin
1098 buf_ip buf s.src_server_ip;
1099 buf_port buf s.src_server_port;
1100 if sourceexchange e > 1 then
1101 buf_md4 buf s.src_md4
1103 done
1106 module EmuleFileDesc = struct
1108 type t = {
1109 rating : int;
1110 comment : string;
1113 let parse len s =
1114 let rating = get_uint8 s 1 in
1115 let (comment, _) = get_string32 s 2 in
1117 rating = rating;
1118 comment = comment;
1121 let print t =
1122 lprintf_nl "EmuleFileDesc [%d][%s]" t.rating t.comment
1124 let write buf t =
1125 buf_int8 buf t.rating;
1126 buf_string buf t.comment
1129 module EmuleCompressedPart = struct
1131 type t = {
1132 md4 : Md4.t;
1133 usesixtyfour : bool;
1134 statpos : int64;
1135 newsize : int64;
1136 bloc : string;
1139 let parse usesixtyfour len s =
1141 md4 = get_md4 s 1;
1142 usesixtyfour = usesixtyfour;
1143 statpos = if usesixtyfour then get_int64 s 17 else get_uint64_32 s 17;
1144 newsize = if usesixtyfour then get_uint64_32 s 25 else get_uint64_32 s 21;
1145 bloc = if usesixtyfour then String.sub s 29 (len-29) else String.sub s 25 (len-25)
1148 let print t =
1149 lprintf_nl "EmuleCompressedPart for %s %Ld %Ld len %d"
1150 (Md4.to_string t.md4) t.statpos t.newsize (String.length t.bloc)
1152 let write buf t =
1153 buf_md4 buf t.md4;
1154 if t.usesixtyfour then buf_int64 buf t.statpos else buf_int64_32 buf t.statpos;
1155 buf_int64_32 buf t.newsize;
1156 Buffer.add_string buf t.bloc
1159 module EmulePortTestReq = struct
1161 type t = string
1163 let print s =
1164 lprintf_nl "Emule porttest request %s" (String.escaped s)
1166 let parse s = s
1168 let write buf =
1169 buf_int8 buf 0x12
1173 type t =
1174 | ConnectReq of Connect.t
1175 | ConnectReplyReq of Connect.t
1176 | QueryFileReq of QueryFile.t
1177 | QueryFileReplyReq of QueryFileReply.t
1178 | BlocReq of Bloc.t
1179 | QueryBlocReq of QueryBloc.t
1180 | JoinQueueReq of JoinQueue.t (* sent before queryBloc *)
1181 | AvailableSlotReq of AvailableSlot.t
1182 | ReleaseSlotReq of ReleaseSlot.t
1183 | OutOfPartsReq of OutOfParts.t
1184 | QueryChunksReq of QueryChunks.t
1185 | QueryChunksReplyReq of QueryChunksReply.t
1186 | QueryChunkMd4Req of QueryChunkMd4.t
1187 | QueryChunkMd4ReplyReq of QueryChunkMd4Reply.t
1188 | ViewFilesReq of ViewFiles.t
1189 | ViewFilesReplyReq of ViewFilesReply.t
1190 | ViewDirsReq of ViewDirs.t
1191 | ViewDirsReplyReq of ViewDirsReply.t
1192 | ViewFilesDirReq of ViewFilesDir.t
1193 | ViewFilesDirReplyReq of ViewFilesDirReply.t
1194 | QueueReq of OtherLocations.t
1195 | UnknownReq of int * string
1196 | OtherLocationsReq of OtherLocations.t
1197 | SayReq of Say.t
1198 | SourcesReq of Sources.t
1199 | EndOfDownloadReq of EndOfDownload.t
1200 | NewUserIDReq of NewUserID.t
1201 | NoSuchFileReq of NoSuchFile.t
1202 | QueueRankReq of QueueRank.t
1204 | EmuleClientInfoReq of EmuleClientInfo.t
1205 | EmuleClientInfoReplyReq of EmuleClientInfo.t
1206 | EmuleQueueRankingReq of EmuleQueueRanking.t
1207 | EmuleRequestSourcesReq of EmuleRequestSources.t
1208 | EmuleRequestSourcesReplyReq of EmuleRequestSourcesReply.t
1209 | EmuleFileDescReq of EmuleFileDesc.t
1210 | EmulePublicKeyReq of EmulePublicKeyReq.t
1211 | EmuleSignatureReq of EmuleSignatureReq.t
1212 | EmuleSecIdentStateReq of EmuleSecIdentStateReq.t
1213 | EmuleMultiPacketReq of Md4.t * t list
1214 | EmuleMultiPacketAnswerReq of Md4.t * t list
1215 | EmuleCompressedPart of EmuleCompressedPart.t
1216 | EmulePortTestReq of EmulePortTestReq.t
1217 | EmuleCaptchaReq of EmuleCaptchaReq.t
1218 | EmuleCaptchaRes of EmuleCaptchaRes.t
1220 let rec print t =
1221 begin
1222 match t with
1223 | ConnectReq t -> Connect.print t
1224 | ConnectReplyReq t -> Connect.print t
1225 | QueryFileReq t -> QueryFile.print t
1226 | QueryFileReplyReq t -> QueryFileReply.print t
1227 | BlocReq t -> Bloc.print t
1228 | QueryBlocReq t -> QueryBloc.print t
1229 | JoinQueueReq t -> JoinQueue.print t
1230 | AvailableSlotReq t -> AvailableSlot.print t
1231 | ReleaseSlotReq t -> ReleaseSlot.print t
1232 | OutOfPartsReq t -> OutOfParts.print t
1233 | QueryChunksReq t -> QueryChunks.print t
1234 | QueryChunksReplyReq t -> QueryChunksReply.print t
1235 | QueryChunkMd4Req t -> QueryChunkMd4.print t
1236 | QueryChunkMd4ReplyReq t -> QueryChunkMd4Reply.print t
1237 | ViewFilesReplyReq t -> ViewFilesReply.print t
1238 | ViewFilesReq t -> ViewFiles.print t
1239 | ViewDirsReq t -> ViewDirs.print t
1240 | ViewDirsReplyReq t -> ViewDirsReply.print t
1241 | ViewFilesDirReq t -> ViewFilesDir.print t
1242 | ViewFilesDirReplyReq t -> ViewFilesDirReply.print t
1243 | QueueReq t -> OtherLocations.print t
1244 | OtherLocationsReq t -> OtherLocations.print t
1245 | SayReq t -> Say.print t
1246 | SourcesReq t -> Sources.print t
1247 | EndOfDownloadReq t -> EndOfDownload.print t
1248 | NewUserIDReq t -> NewUserID.print t
1249 | NoSuchFileReq t -> NoSuchFile.print t
1250 | QueueRankReq t ->
1251 QueueRank.print t
1253 | EmuleClientInfoReq t ->
1254 EmuleClientInfo.print "EmuleClientInfo" t
1255 | EmuleClientInfoReplyReq t ->
1256 EmuleClientInfo.print "EmuleClientInfoReply" t
1257 | EmuleQueueRankingReq t ->
1258 EmuleQueueRanking.print t
1259 | EmuleRequestSourcesReq t ->
1260 EmuleRequestSources.print t
1261 | EmuleRequestSourcesReplyReq t ->
1262 EmuleRequestSourcesReply.print t
1264 | EmuleFileDescReq t ->
1265 EmuleFileDesc.print t
1267 | EmuleMultiPacketReq (md4, list) ->
1268 lprintf_nl "EmuleMultiPacket for %s:" (Md4.to_string md4);
1269 List.iter (fun t ->
1270 lprintf " ";
1271 print t
1272 ) list
1274 | EmuleMultiPacketAnswerReq (md4, list) ->
1275 lprintf_nl "EmuleMultiPacketAnswer for %s:" (Md4.to_string md4);
1276 List.iter (fun t ->
1277 lprintf " ";
1278 print t
1279 ) list
1280 | EmuleSecIdentStateReq t ->
1281 EmuleSecIdentStateReq.print t
1282 | EmuleSignatureReq t ->
1283 EmuleSignatureReq.print t
1284 | EmulePublicKeyReq t ->
1285 EmulePublicKeyReq.print t
1286 | EmuleCompressedPart t ->
1287 EmuleCompressedPart.print t
1288 | EmulePortTestReq t ->
1289 EmulePortTestReq.print t
1290 | EmuleCaptchaReq t ->
1291 EmuleCaptchaReq.print t
1292 | EmuleCaptchaRes t ->
1293 EmuleCaptchaRes.print t
1294 | UnknownReq (opcode, s) ->
1295 let len = String.length s in
1296 lprintf_nl "UnknownReq: magic (%d), opcode (%d) len (%d)" opcode
1297 (int_of_char s.[0])
1298 (String.length s);
1299 lprintf "ascii: [";
1300 for i = 0 to len - 1 do
1301 let c = s.[i] in
1302 let n = int_of_char c in
1303 if n > 31 && n < 127 then
1304 lprintf " %c" c
1305 else
1306 lprintf "(%d)" n
1307 done;
1308 lprintf "]\n";
1309 lprintf "dec: [";
1310 for i = 0 to len - 1 do
1311 let c = s.[i] in
1312 let n = int_of_char c in
1313 lprintf "(%d)" n
1314 done;
1315 lprintf "]\n"
1318 let rec parse_emule_packet emule opcode len s =
1320 lprintf "Emule magic: %d opcode %d:" magic opcode; lprint_newline ();
1321 dump s; lprint_newline ();
1323 let t = match opcode with
1324 | 1 -> EmuleClientInfoReq (EmuleClientInfo.parse len s)
1325 | 2 -> EmuleClientInfoReplyReq (EmuleClientInfo.parse len s)
1327 | 0x60 (* 96 *) -> EmuleQueueRankingReq (EmuleQueueRanking.parse len s)
1329 | 0x61 (* 97 *) -> EmuleFileDescReq (EmuleFileDesc.parse len s)
1331 | 0x81 (* 129 *) -> EmuleRequestSourcesReq (EmuleRequestSources.parse len s)
1332 | 0x82 (* 130 *) ->
1333 EmuleRequestSourcesReplyReq (
1334 EmuleRequestSourcesReply.parse emule len s)
1336 | 0x40 (* 64 *) ->
1337 (* OP_COMPRESSEDPART *)
1338 EmuleCompressedPart (EmuleCompressedPart.parse false len s)
1340 | 0x85 (* 133 *) ->
1341 EmulePublicKeyReq(EmulePublicKeyReq.parse len s)
1343 | 0x86 (* 134 *) ->
1344 EmuleSignatureReq(EmuleSignatureReq.parse len s)
1346 | 0x87 (* 135 *) ->
1347 EmuleSecIdentStateReq (EmuleSecIdentStateReq.parse len s)
1349 (* | 0x90 (* 144 *) -> RequestPreview *)
1350 (* | 0x91 (* 145 *) -> PreviewAnswer *)
1351 | 0x92 (* 146 *) ->
1352 let md4 = get_md4 s 1 in
1354 (* lprintf "MULTI EMULE VERSION %d"
1355 (extendedrequest emule); print_newline (); *)
1356 (* let pos = 17 in *)
1357 let rec iter pos =
1358 if pos < len then
1359 let opcode = get_uint8 s pos in
1360 match opcode with
1361 0x58 (* 88 *) ->
1362 let bitmap, pos = get_bitmap s (pos+1) in
1363 let ncompletesources, pos =
1364 if extendedrequest emule > 1 then
1365 get_int16 s pos, pos+2
1366 else -1, pos
1368 (QueryFileReq {
1369 QueryFile.md4 = md4;
1370 QueryFile.emule_extension = Some (bitmap, ncompletesources);
1371 }) :: (iter pos)
1372 | 0x4F (* 79 *) ->
1373 (QueryChunksReq md4) :: iter (pos+1)
1374 | 0x81 (* 129 *) ->
1375 (EmuleRequestSourcesReq md4) :: iter (pos+1)
1376 | _ ->
1377 lprintf_nl "Unknown short emule packet %d" opcode;
1378 raise Not_found
1379 else
1382 EmuleMultiPacketReq (md4, iter 17)
1384 | 0x93 (* 147 *) ->
1385 if String.length s < 16 then begin
1386 if !verbose_unknown_messages then lprintf_nl "EmuleMultiPacketAnswer: incomplete request";
1387 raise Not_found
1388 end;
1389 let md4 = get_md4 s 1 in
1391 (* lprintf "MULTI EMULE VERSION %d"
1392 (extendedrequest emule); print_newline (); *)
1393 let rec iter s pos len =
1394 if pos < len then
1395 let opcode = get_uint8 s pos in
1396 match opcode with
1397 | 89 ->
1398 let module Q = QueryFileReply in
1399 let name, pos = get_string s (pos+1) in
1400 let q = {
1401 Q.md4 = md4;
1402 Q.name = name;
1403 } in
1404 (QueryFileReplyReq q) :: (iter s pos len)
1405 | 80 ->
1406 let module Q = QueryChunksReply in
1407 let chunks, pos = get_bitmap s (pos+1) in
1408 let q = {
1409 Q.md4 = md4;
1410 Q.chunks = chunks;
1411 } in
1412 (QueryChunksReplyReq q) :: (iter s pos len)
1413 | _ ->
1414 lprintf_nl "Unknown packet in emule multipacket 0x93: %d" opcode;
1415 raise Not_found
1416 else
1419 EmuleMultiPacketAnswerReq (md4, iter s 17 len)
1421 | 0xa1 (* 161 *) -> (* OP_COMPRESSEDPART_I64 *)
1422 EmuleCompressedPart (EmuleCompressedPart.parse true len s)
1423 | 0xa2 -> BlocReq (Bloc.parse true len s) (* OP_SENDINGPART_I64 *)
1424 | 0xa3 -> QueryBlocReq (QueryBloc.parse true len s) (*OP_REQUESTPARTS_I64 *)
1425 | 0xa5 (* 165 *) -> EmuleCaptchaReq (EmuleCaptchaReq.parse len s) (* OP_CHATCAPTCHAREQ *)
1426 | 0xa6 (* 166 *) -> EmuleCaptchaRes (EmuleCaptchaRes.parse s) (* OP_CHATCAPTCHARES *)
1427 | 0xfe (* 254 *) -> EmulePortTestReq s
1429 | code ->
1430 if !CommonOptions.verbose_unknown_messages then
1431 lprintf_nl "EDK: unknown eMule message %d" code;
1432 raise Not_found
1435 lprintf "EMULE MESSAGE: "; lprint_newline ();
1436 print t;
1437 lprint_newline (); *)
1440 and parse emule_version magic s =
1442 let len = String.length s in
1443 if len = 0 then raise Not_found;
1444 let opcode = int_of_char (s.[0]) in
1445 (*lprintf "opcode: %d" opcode; lprint_newline (); *)
1446 match magic with
1447 227 ->
1448 begin
1449 match opcode with
1450 | 1 -> ConnectReq (Connect.parse false len s)
1451 | 70 -> BlocReq (Bloc.parse false len s)
1452 | 71 -> QueryBlocReq (QueryBloc.parse false len s)
1453 | 72 -> NoSuchFileReq (NoSuchFile.parse len s)
1454 | 73 -> EndOfDownloadReq (EndOfDownload.parse len s)
1455 | 74 -> ViewFilesReq (ViewFiles.parse len s)
1456 | 75 -> ViewFilesReplyReq (ViewFilesReply.parse len s)
1457 | 76 -> ConnectReplyReq (Connect.parse true len s)
1458 | 77 -> NewUserIDReq (NewUserID.parse len s)
1459 | 78 -> SayReq (Say.parse len s)
1460 | 79 -> QueryChunksReq (QueryChunks.parse len s)
1461 | 80 -> QueryChunksReplyReq (QueryChunksReply.parse len s)
1462 | 81 -> QueryChunkMd4Req (QueryChunkMd4.parse len s)
1463 | 82 -> QueryChunkMd4ReplyReq (QueryChunkMd4Reply.parse len s)
1464 (* JoinQueue: the sender wants to join the upload queue *)
1465 | 84 -> JoinQueueReq (JoinQueue.parse len s)
1466 (* AvailableSlot: there is an available slot in upload queue *)
1467 | 85 -> AvailableSlotReq (AvailableSlot.parse len s)
1468 (* ReleaseSlot: the upload is finished *)
1469 | 86 -> ReleaseSlotReq (ReleaseSlot.parse len s)
1470 (* OutOfParts: the upload slot is not available *)
1471 | 87 -> OutOfPartsReq (OutOfParts.parse len s)
1472 | 88 -> QueryFileReq (QueryFile.parse emule_version len s)
1473 | 89 -> QueryFileReplyReq (QueryFileReply.parse len s)
1474 | 92 -> QueueRankReq (QueueRank.parse len s)
1475 | 93 -> ViewDirsReq (ViewDirs.parse len s)
1476 | 94 -> ViewFilesDirReq (ViewFilesDir.parse len s)
1478 | 95 -> ViewDirsReplyReq (ViewDirsReply.parse len s)
1479 | 96 -> ViewFilesDirReplyReq (ViewFilesDirReply.parse len s)
1481 | 250 -> SourcesReq (Sources.parse len s)
1483 | _ -> raise Not_found
1486 | 0xc5 -> (* 197: emule extended protocol *)
1487 parse_emule_packet emule_version opcode len s
1489 (* Compressed packet, probably sent by cDonkey ? *)
1491 | 0xD4 -> (* 212 *)
1493 let s = Zlib.uncompress_string2 (String.sub s 1 (len-1)) in
1494 let s = Printf.sprintf "%c%s" (char_of_int opcode) s in
1495 begin try
1496 parse_emule_packet emule_version opcode (String.length s) s
1497 with
1498 | e ->
1499 if !CommonOptions.verbose_unknown_messages then begin
1500 lprintf_nl "Unknown message From client: %s (magic %d)"
1501 (Printexc2.to_string e) magic;
1502 let tmp_file = Filename2.temp_file "comp" "pak" in
1503 File.from_string tmp_file s;
1504 lprintf_nl "Saved unknown packet %s" tmp_file;
1505 dump s;
1506 lprint_newline ();
1507 end;
1508 UnknownReq (magic,s)
1511 | _ ->
1512 if !CommonOptions.verbose_unknown_messages then
1513 lprintf_nl "Strange magic: %d" magic;
1514 raise Not_found
1515 with
1516 | e ->
1517 if !CommonOptions.verbose_unknown_messages then begin
1518 lprintf_nl "Unknown message From client: %s (magic %d)"
1519 (Printexc2.to_string e) magic;
1520 let tmp_file = Filename2.temp_file "comp" "pak" in
1521 File.from_string tmp_file s;
1522 lprintf_nl "Saved unknown packet %s" tmp_file;
1524 dump s;
1525 lprint_newline ();
1526 end;
1527 UnknownReq (magic,s)
1529 let write emule buf t =
1530 let magic = match t with
1531 EmuleMultiPacketAnswerReq _
1532 | EmuleMultiPacketReq _
1533 | EmuleSecIdentStateReq _
1534 | EmuleSignatureReq _
1535 | EmulePublicKeyReq _
1536 | EmuleRequestSourcesReplyReq _
1537 | EmuleRequestSourcesReq _
1538 | EmuleClientInfoReplyReq _
1539 | EmuleClientInfoReq _
1540 | EmuleFileDescReq _
1541 | EmuleQueueRankingReq _
1542 | EmuleCaptchaReq _
1543 | EmuleCaptchaRes _
1544 | EmuleCompressedPart _
1545 -> 0xC5
1546 | QueryBlocReq t when t.QueryBloc.usesixtyfour -> 0xC5
1547 | BlocReq t when t.Bloc.usesixtyfour -> 0xC5
1549 -> 227
1551 begin
1552 match t with
1553 | ConnectReq t ->
1554 buf_int8 buf 1;
1555 Connect.write false buf t
1556 | ConnectReplyReq t ->
1557 buf_int8 buf 76;
1558 Connect.write true buf t
1559 | QueryFileReq t ->
1560 buf_int8 buf 88;
1561 QueryFile.write emule buf t
1562 | QueryFileReplyReq t ->
1563 buf_int8 buf 89;
1564 QueryFileReply.write buf t
1565 | QueueReq t ->
1566 buf_int8 buf 77;
1567 OtherLocations.write buf t
1568 | QueryBlocReq t ->
1569 buf_int8 buf (if t.QueryBloc.usesixtyfour then 0xa3 else 71);
1570 QueryBloc.write buf t
1571 | BlocReq t ->
1572 buf_int8 buf (if t.Bloc.usesixtyfour then 0xa2 else 70);
1573 Bloc.write buf t
1574 | JoinQueueReq t ->
1575 buf_int8 buf 84;
1576 JoinQueue.write emule buf t
1577 | QueryChunksReq t ->
1578 buf_int8 buf 79;
1579 QueryChunks.write buf t
1580 | QueryChunksReplyReq t ->
1581 buf_int8 buf 80;
1582 QueryChunksReply.write buf t
1583 | QueryChunkMd4Req t ->
1584 buf_int8 buf 81;
1585 QueryChunkMd4.write buf t
1586 | QueryChunkMd4ReplyReq t ->
1587 buf_int8 buf 82;
1588 QueryChunkMd4Reply.write buf t
1589 | AvailableSlotReq t ->
1590 buf_int8 buf 85;
1591 AvailableSlot.write buf t
1592 | ReleaseSlotReq t ->
1593 buf_int8 buf 86;
1594 ReleaseSlot.write buf t
1595 | OutOfPartsReq t ->
1596 buf_int8 buf 87;
1597 OutOfParts.write buf t
1598 | ViewFilesReq t ->
1599 buf_int8 buf 74;
1600 ViewFiles.write buf t
1601 | ViewFilesReplyReq t ->
1602 buf_int8 buf 75;
1603 ViewFilesReply.write buf t
1604 | ViewDirsReq t ->
1605 buf_int8 buf 93;
1606 ViewDirs.write buf t
1607 | ViewDirsReplyReq t ->
1608 buf_int8 buf 95;
1609 ViewDirsReply.write buf t
1610 | ViewFilesDirReq t ->
1611 buf_int8 buf 94;
1612 ViewFilesDir.write buf t
1613 | ViewFilesDirReplyReq t ->
1614 buf_int8 buf 96;
1615 ViewFilesDirReply.write buf t
1616 | OtherLocationsReq t ->
1617 buf_int8 buf 72;
1618 OtherLocations.write buf t
1619 | SayReq t ->
1620 buf_int8 buf 78;
1621 Say.write buf t
1622 | SourcesReq t ->
1623 buf_int8 buf 250;
1624 Sources.write buf t
1625 | NewUserIDReq t ->
1626 buf_int8 buf 77;
1627 NewUserID.write buf t
1628 | EndOfDownloadReq t ->
1629 buf_int8 buf 73;
1630 EndOfDownload.write buf t
1631 | NoSuchFileReq t ->
1632 buf_int8 buf 72;
1633 NoSuchFile.write buf t
1634 | QueueRankReq t ->
1635 buf_int8 buf 92;
1636 QueueRank.write buf t
1638 | EmuleClientInfoReq t ->
1639 buf_int8 buf 1;
1640 EmuleClientInfo.write buf t
1641 | EmuleClientInfoReplyReq t ->
1642 buf_int8 buf 2;
1643 EmuleClientInfo.write buf t
1644 | EmuleQueueRankingReq t ->
1645 buf_int8 buf 0x60;
1646 EmuleQueueRanking.write buf t
1647 | EmuleRequestSourcesReq t ->
1648 buf_int8 buf 0x81;
1649 EmuleRequestSources.write buf t
1650 | EmuleRequestSourcesReplyReq t ->
1651 buf_int8 buf 0x82;
1652 EmuleRequestSourcesReply.write emule buf t
1653 | EmuleFileDescReq t ->
1654 buf_int8 buf 0x61;
1655 EmuleFileDesc.write buf t
1656 | EmuleCompressedPart t ->
1657 buf_int8 buf (if t.EmuleCompressedPart.usesixtyfour then 0xa1 else 0x40);
1658 EmuleCompressedPart.write buf t
1659 | EmuleMultiPacketReq (md4, list) ->
1660 buf_int8 buf 0x92;
1661 buf_md4 buf md4;
1662 List.iter (fun t ->
1663 match t with
1664 QueryFileReq t ->
1665 buf_int8 buf 0x58;
1666 (match t.QueryFile.emule_extension with
1667 None -> ()
1668 | Some (bitmap, ncompletesources) ->
1669 write_bitmap buf bitmap;
1670 if ncompletesources >= 0 && extendedrequest emule > 1 then
1671 buf_int16 buf ncompletesources)
1672 | QueryChunksReq _ ->
1673 buf_int8 buf 0x4F
1674 | EmuleRequestSourcesReq _ ->
1675 buf_int8 buf 0x81
1676 | _ ->
1677 lprintf_nl "WARNING: Don't know how to write short packet:";
1678 print t;
1679 print_newline ();
1680 ) list
1682 | EmuleMultiPacketAnswerReq (md4, list) ->
1683 buf_int8 buf 0x93;
1684 buf_md4 buf md4;
1685 List.iter (fun t ->
1686 match t with
1687 QueryFileReplyReq t ->
1688 buf_int8 buf 89;
1689 buf_string buf t.QueryFileReply.name
1690 | QueryChunksReplyReq t ->
1691 buf_int8 buf 80;
1692 write_bitmap buf t.QueryChunksReply.chunks
1693 | _ ->
1694 lprintf_nl "WARNING: Don't know how to write short packet:";
1695 print t;
1696 print_newline ();
1697 ) list
1699 | EmuleSecIdentStateReq t ->
1700 buf_int8 buf 0x87;
1701 EmuleSecIdentStateReq.write buf t
1703 | EmuleSignatureReq t ->
1704 buf_int8 buf 0x86;
1705 EmuleSignatureReq.write buf t
1707 | EmulePublicKeyReq t ->
1708 buf_int8 buf 0x85;
1709 EmulePublicKeyReq.write buf t
1711 | EmulePortTestReq t ->
1712 buf_int8 buf 0xfe;
1713 EmulePortTestReq.write buf
1715 | EmuleCaptchaReq t ->
1716 buf_int8 buf 0xa5;
1717 EmuleCaptchaReq.write buf t
1719 | EmuleCaptchaRes t ->
1720 buf_int8 buf 0xa6;
1721 EmuleCaptchaRes.write buf t
1723 | UnknownReq (opcode, s) ->
1724 Buffer.add_string buf s
1726 end;
1727 magic
1730 ------------------------------------------------------
1731 1044008574.297 192.168.0.3:37522 -> 80.26.114.12:13842 of len 6
1732 ? Become Friend ? ping ?
1734 (227)(1)(0)(0)(0)
1735 (98)
1737 ------------------------------------------------------
1738 1044008576.274 80.26.114.12:13842 -> 192.168.0.3:37522 of len 6
1739 ? OK ? pong ?
1741 (227)(1)(0)(0)(0)(99)]
1743 ------------------------------------------------------
1744 1044008687.977 192.168.0.3:37522 -> 80.26.114.12:13842 of len 6
1745 Browse Main Dir
1747 (227)(1)(0)(0)(0)
1748 (93)
1750 ------------------------------------------------------
1751 1044008690.832 80.26.114.12:13842 -> 192.168.0.3:37522 of len 43
1752 Browse Main Dir Reply
1753 (227)(38)(0)(0)(0)
1754 (95)
1755 (2)(0)(0)(0) --------> 2 directories:
1756 (12)(0) C : \ D o w n l o a d s
1757 (17)(0) ! I n c o m p l e t e F i l e s
1760 ------------------------------------------------------
1761 1044008766.137 192.168.0.3:37522 -> 80.26.114.12:13842 of len 20
1762 Browse directory
1764 (227)(15)(0)(0)(0)
1765 (94)
1766 (12)(0) C : \ D o w n l o a d s
1768 ------------------------------------------------------
1769 1044008769.045 80.26.114.12:13842 -> 192.168.0.3:37522 of len 300
1770 (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)]
1771 (227)(112)(8)(0)(0)
1773 (96)
1774 (12)(0) C : \ D o w n l o a d s
1775 (21)(0)(0)(0) 21 files
1777 (152)(50)(229)(158)(218)(141)(217)(138)(110)(181)(54)(40)(41)(104)(86)(179)
1778 (0)(0)(0)(0)
1779 (0)(0)
1780 (3)(0)(0)(0)
1782 (1)(0)(1)
1783 (11)(0) d e s k t o p . i n i
1785 (1)(0)(2)
1786 (180)(0)(0)(0)
1788 (1)(0)(19)
1789 (0)(0)(0)(0)
1791 (121)(16)(15)(57)(79)(90)(219)(105)(101)(200)(10)(124)(29)(27)(70)(128)
1792 (0)(0)(0)(0)
1793 (0)(0)
1794 (5)(0)(0)(0)
1796 (1)(0)(1)
1797 (15)(0) u t b o n u s p a c k . z i p
1799 (1)(0)(2)
1800 (74)(16)(221)(0)
1802 (1)(0)(3)
1803 (3)(0) Pro
1805 (1)(0)(4)
1806 (3)(0) zip
1808 (1)(0)(19)
1809 (0)(0)(0)(0)
1810 ....
1814 (* 92: Queue Rank *)