зеркало из https://github.com/microsoft/ivy.git
103 строки
2.3 KiB
Plaintext
103 строки
2.3 KiB
Plaintext
|
#lang ivy1.7
|
||
|
|
||
|
|
||
|
include pcap
|
||
|
include order
|
||
|
|
||
|
type type_bits
|
||
|
|
||
|
interpret type_bits -> bv[7]
|
||
|
|
||
|
object quic_long_type = {
|
||
|
type this = {initial,retry,handshake,zero_rtt_protected}
|
||
|
}
|
||
|
|
||
|
type cid
|
||
|
interpret cid -> bv[64]
|
||
|
|
||
|
type version
|
||
|
interpret version -> bv[32]
|
||
|
|
||
|
type pkt_num
|
||
|
interpret pkt_num -> bv[32]
|
||
|
|
||
|
# a fake type for packets
|
||
|
|
||
|
type quic_packet = struct {
|
||
|
hdr_long : bool,
|
||
|
hdr_type : type_bits,
|
||
|
hdr_cid : cid,
|
||
|
hdr_version : version,
|
||
|
hdr_pkt_num : pkt_num
|
||
|
}
|
||
|
|
||
|
include quic_deser
|
||
|
|
||
|
instance pc : pcap(quic_packet,quic_deser)
|
||
|
|
||
|
action show_packet(src:ip.endpoint,dst:ip.endpoint,pkt:quic_packet)
|
||
|
import show_packet
|
||
|
|
||
|
# Monitor packets on the wire
|
||
|
|
||
|
# For each endpoint, the set of connectino ids that have been sent
|
||
|
relation conn_seen(E:ip.endpoint,C:cid)
|
||
|
|
||
|
# For each endpoint and connection id, track the last packet number sent
|
||
|
function last_pkt_num(E:ip.endpoint,C:cid) : pkt_num
|
||
|
|
||
|
after init {
|
||
|
conn_seen(E,C) := false;
|
||
|
}
|
||
|
|
||
|
implement pc.handle(src:ip.endpoint,dst:ip.endpoint,pkt:quic_packet) {
|
||
|
call show_packet(src,dst,pkt);
|
||
|
|
||
|
var cid := pkt.hdr_cid;
|
||
|
var pnum := pkt.hdr_pkt_num;
|
||
|
|
||
|
# If the connection is new, the packet number is exact. Just
|
||
|
# record we have seen this cid.
|
||
|
|
||
|
if ~conn_seen(src,cid) {
|
||
|
conn_seen(src,cid) := true;
|
||
|
}
|
||
|
|
||
|
# Else, we have to figure the current packet number based on the last.
|
||
|
# It should be the least packet number greater than the last whose
|
||
|
# low order bits match the number given in the packet. To compute
|
||
|
# this, we have to take into account the actual number of bits.
|
||
|
|
||
|
else {
|
||
|
var last := last_pkt_num(src,cid);
|
||
|
|
||
|
# If long format or type is 0x1d, we match 32 bits
|
||
|
|
||
|
if pkt.hdr_long | pkt.hdr_type = 0x1d {
|
||
|
if some(n:pkt_num) n > last & bfe[0][31](n) = pnum minimizing n {
|
||
|
pnum := n
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# else if long format or type is 0x1e, we match 16 bits
|
||
|
|
||
|
else if pkt.hdr_type = 0x1e {
|
||
|
if some(n:pkt_num) n > last & bfe[0][15](n) = pnum minimizing n {
|
||
|
pnum := n
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# else (type is 0x1f) we match 8 bits
|
||
|
|
||
|
else {
|
||
|
if some(n:pkt_num) n > last & bfe[0][7](n) = pnum minimizing n {
|
||
|
pnum := n
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
last_pkt_num(src,cid) := pnum
|
||
|
}
|
||
|
|
||
|
attribute radix=16
|