///|
/// 解析 IPv6 头(NextHeader 偏移 6,src 8,dst 24,固定头 40 字节;帧内 +14)
fn parse_ipv6(
data : Bytes,
ts_sec : Int64,
ts_usec : Int,
local_ips : FixedArray[IpAddr],
) -> ParsedPacket? {
let total = data.length()
let l3 = ETH_HDR
guard total >= l3 + 40 else { return None }
let vtc = data[l3].to_int()
guard vtc >> 4 == 6 else { return None } // 非 IPv6
let payload_len = u16(data, l3 + 4) // 不含 40 字节固定头
let ip_total = 40 + payload_len
guard ip_total <= total - l3 else { return None }
let proto = classify_proto(data[l3 + 6])
let src = { v4: false, bytes: read_bytes(data, l3 + 8, 16) }
let dst = { v4: false, bytes: read_bytes(data, l3 + 24, 16) }
let l4 = match proto {
Tcp => parse_tcp(data, l3 + 40, payload_len)
Udp => parse_udp(data, l3 + 40, payload_len)
_ => Some((0, 0, payload_len))
}
let (sport, dport, payload) = match l4 {
Some(x) => x
None => return None
}
Some(
ParsedPacket::new(
ts_sec,
ts_usec,
{ src_ip: src, dst_ip: dst, src_port: sport, dst_port: dport, proto },
direction(src, dst, local_ips),
payload,
ip_total,
),
)
}