···18let empty = { ptrs = []; srvs = []; txts = []; addrs = []; addrs6 = [] }
1920(* Binary helpers *)
21-let get_u16 buf off = (Char.code buf.[off] lsl 8) lor Char.code buf.[off + 1]
2223(* Collect labels from a DNS name, following compression pointers *)
24let collect_labels buf off =
···32 | b when b land 0xc0 = 0xc0 ->
33 (* Compression pointer: need 2 bytes *)
34 if off + 2 > len then acc
35- else loop (get_u16 buf off land 0x3fff) (followed + 1) acc
36 | b ->
37 (* Label: need 1 + b bytes *)
38 if off + 1 + b > len then acc
···82let random_u16 () = Random.int 0x10000
8384(* Create mDNS query using dns library *)
85-let make_query name =
86 let header = (random_u16 (), Dns.Packet.Flags.empty) in
87 Dns.Packet.create header
88 (Dns.Packet.Question.create name Dns.Rr_map.Ptr)
89 `Query
9091let encode_query name =
92- let pkt = make_query name in
93 fst (Dns.Packet.encode `Udp pkt)
9495(* Parse mDNS response *)
···97 let len = String.length buf in
98 if len < 12 then None
99 else
100- let qdcount = get_u16 buf 4 in
101- let rr_count = get_u16 buf 6 + get_u16 buf 8 + get_u16 buf 10 in
102 let off = ref 12 in
103 (* Skip question section with bounds checking *)
104 for _ = 1 to qdcount do
···116 let off' = skip_name buf !off in
117 (* Verify off' + 10 <= len before reading RR header *)
118 if off' + 10 <= len then begin
119- let typ = get_u16 buf off' in
120- let rdlen = get_u16 buf (off' + 8) in
121 let rdata = off' + 10 in
122 off := rdata + rdlen;
123 (* Verify rdata region is within bounds *)
···135 let lo = String.get_int64_be buf (rdata + 8) in
136 addrs6 := (name, Ipaddr.V6.of_int64 (hi, lo)) :: !addrs6
137 | 33 when rdlen >= 6 ->
138- let port = get_u16 buf (rdata + 4) in
139 let target =
140 domain_of_labels (collect_labels buf (rdata + 6))
141 in
···18let empty = { ptrs = []; srvs = []; txts = []; addrs = []; addrs6 = [] }
1920(* Binary helpers *)
21+let u16 buf off = (Char.code buf.[off] lsl 8) lor Char.code buf.[off + 1]
2223(* Collect labels from a DNS name, following compression pointers *)
24let collect_labels buf off =
···32 | b when b land 0xc0 = 0xc0 ->
33 (* Compression pointer: need 2 bytes *)
34 if off + 2 > len then acc
35+ else loop (u16 buf off land 0x3fff) (followed + 1) acc
36 | b ->
37 (* Label: need 1 + b bytes *)
38 if off + 1 + b > len then acc
···82let random_u16 () = Random.int 0x10000
8384(* Create mDNS query using dns library *)
85+let query name =
86 let header = (random_u16 (), Dns.Packet.Flags.empty) in
87 Dns.Packet.create header
88 (Dns.Packet.Question.create name Dns.Rr_map.Ptr)
89 `Query
9091let encode_query name =
92+ let pkt = query name in
93 fst (Dns.Packet.encode `Udp pkt)
9495(* Parse mDNS response *)
···97 let len = String.length buf in
98 if len < 12 then None
99 else
100+ let qdcount = u16 buf 4 in
101+ let rr_count = u16 buf 6 + u16 buf 8 + u16 buf 10 in
102 let off = ref 12 in
103 (* Skip question section with bounds checking *)
104 for _ = 1 to qdcount do
···116 let off' = skip_name buf !off in
117 (* Verify off' + 10 <= len before reading RR header *)
118 if off' + 10 <= len then begin
119+ let typ = u16 buf off' in
120+ let rdlen = u16 buf (off' + 8) in
121 let rdata = off' + 10 in
122 off := rdata + rdlen;
123 (* Verify rdata region is within bounds *)
···135 let lo = String.get_int64_be buf (rdata + 8) in
136 addrs6 := (name, Ipaddr.V6.of_int64 (hi, lo)) :: !addrs6
137 | 33 when rdlen >= 6 ->
138+ let port = u16 buf (rdata + 4) in
139 let target =
140 domain_of_labels (collect_labels buf (rdata + 6))
141 in