This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,169 @@
(*
* Copyright (c) 2012-2016 Anil Madhavapeddy <anil@recoil.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
[%%cstruct
type pcap_header = {
magic_number: uint32_t; (* magic number *)
version_major: uint16_t; (* major version number *)
version_minor: uint16_t; (* minor version number *)
thiszone: uint32_t; (* GMT to local correction *)
sigfigs: uint32_t; (* accuracy of timestamps *)
snaplen: uint32_t; (* max length of captured packets, in octets *)
network: uint32_t; (* data link type *)
} [@@little_endian]]
[%%cstruct
type pcap_packet = {
ts_sec: uint32_t; (* timestamp seconds *)
ts_usec: uint32_t; (* timestamp microseconds *)
incl_len: uint32_t; (* number of octets of packet saved in file *)
orig_len: uint32_t; (* actual length of packet *)
} [@@little_endian]]
[%%cstruct
type ethernet = {
dst: uint8_t [@len 6];
src: uint8_t [@len 6];
ethertype: uint16_t;
} [@@big_endian]]
[%%cstruct
type ipv4 = {
hlen_version: uint8_t;
tos: uint8_t;
len: uint16_t;
id: uint16_t;
off: uint16_t;
ttl: uint8_t;
proto: uint8_t;
csum: uint16_t;
src: uint8_t [@len 4];
dst: uint8_t [@len 4];
} [@@big_endian]]
[%%cstruct
type tcpv4 = {
src_port: uint16_t;
dst_port: uint16_t;
seqnum: uint32_t;
acknum: uint32_t;
offset_flags: uint16_t;
window: uint16_t;
checksum: uint16_t;
urg: uint16_t;
} [@@big_endian]]
let mac_to_string buf =
let i n = Cstruct.get_uint8 buf n in
Printf.sprintf "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"
(i 0) (i 1) (i 2) (i 3) (i 4) (i 5)
open Printf
let print_packet p =
let dst_mac = mac_to_string (get_ethernet_dst p) in
let src_mac = mac_to_string (get_ethernet_src p) in
let ethertype = get_ethernet_ethertype p in
printf "ether %s -> %s etype %x\n" src_mac dst_mac ethertype;
match ethertype with
|0x0800 -> begin
let ip = Cstruct.shift p sizeof_ethernet in
let version = get_ipv4_hlen_version ip lsr 4 in
let hlen = (get_ipv4_hlen_version ip land 0xf) * 4 in
let ttl = get_ipv4_ttl ip in
let proto = get_ipv4_proto ip in
printf "ipv%d hlen %d ttl %d proto %d\n" version hlen ttl proto;
match proto with
|6 -> begin (* tcp *)
let tcp = Cstruct.shift ip sizeof_ipv4 in
let off = 0 in
let x = get_tcpv4_offset_flags tcp in
let data_offset = (x lsr 12) * 4 in
let options =
match data_offset - sizeof_tcpv4 with
|0 -> 0
|n -> n (* TODO parse *)
in
let payload = Cstruct.shift tcp data_offset in
let fin = (x land 1) = 1 in
let syn = (x land 2) = 2 in
let flags = "?" in
let src_port = get_tcpv4_src_port tcp in
let dst_port = get_tcpv4_dst_port tcp in
let seqnum = get_tcpv4_seqnum tcp in
let acknum = get_tcpv4_acknum tcp in
let window = get_tcpv4_window tcp in
printf "tcpv4 port %d->%d seq %lu ack %lu win %d off %d flags %s opt %d fin %b syn %b payload_len=%d\n"
src_port dst_port seqnum
acknum window off flags options fin syn (Cstruct.length payload);
()
end
|_ -> printf "unknown ip proto %d\n" proto
end
|x -> printf "unknown body %x\n" x
let print_pcap_packet (hdr,pkt) =
let ts_sec = get_pcap_packet_ts_sec hdr in
let ts_usec = get_pcap_packet_ts_usec hdr in
let incl_len = get_pcap_packet_incl_len hdr in
let orig_len = get_pcap_packet_orig_len hdr in
printf "\n** %lu.%lu bytes %lu (of %lu)\n"
ts_sec ts_usec incl_len orig_len;
print_packet pkt
let print_pcap_header buf =
let magic = get_pcap_header_magic_number buf in
let endian =
match magic with
|0xa1b2c3d4l -> "bigendian"
|0xd4c3b2a1l -> "littlendian"
|_ -> "not a pcap file"
in
let version_major = get_pcap_header_version_major buf in
let version_minor = get_pcap_header_version_minor buf in
let thiszone = get_pcap_header_thiszone buf in
let sigfis = get_pcap_header_sigfigs buf in
let snaplen = get_pcap_header_snaplen buf in
let header_network = get_pcap_header_network buf in
printf "pcap_header (len %d)\n" sizeof_pcap_header;
printf "magic_number %lx (%s)\n%!" magic endian;
printf "version %d %d\n" version_major version_minor;
printf "timezone shift %lu\n" thiszone;
printf "timestamp accuracy %lu\n" sigfis;
printf "snaplen %lu\n" snaplen;
printf "lltype %lx\n" header_network
let parse () =
printf "start parse\n%!";
let fd = Unix.(openfile "http.cap" [O_RDONLY] 0) in
let t = Unix_cstruct.of_fd fd in
printf "total pcap file length %d\n%!" (Cstruct.length t);
let header, body = Cstruct.split t sizeof_pcap_header in
print_pcap_header header;
let packets = Cstruct.iter
(fun buf -> Some (sizeof_pcap_packet + Int32.to_int (get_pcap_packet_incl_len buf)))
(fun buf -> buf, Cstruct.shift buf sizeof_pcap_packet)
body
in
let num_packets = Cstruct.fold
(fun a packet -> print_pcap_packet packet; (a+1))
packets 0
in
printf "num_packets %d\n%!" num_packets
let () = parse ()