727 lines
12 KiB
Markdown
727 lines
12 KiB
Markdown
|
|
# bcap API 手册
|
|||
|
|
|
|||
|
|
开发者参考文档。快速接入说明见 [`../README.md`](../README.md)。
|
|||
|
|
|
|||
|
|
## 1. 主包职责
|
|||
|
|
|
|||
|
|
主包负责:
|
|||
|
|
|
|||
|
|
- 统一的报文事实层
|
|||
|
|
- 统一的 flow 表达
|
|||
|
|
- 统一的轻量 hint 层
|
|||
|
|
- 以 TCP 为重点的轻状态跟踪
|
|||
|
|
|
|||
|
|
主包不负责:
|
|||
|
|
|
|||
|
|
- 报告生成
|
|||
|
|
- 业务规则判断
|
|||
|
|
- 用户侧展示文案
|
|||
|
|
- 动作编排
|
|||
|
|
- 深度流重组
|
|||
|
|
- 应用层协议解析框架
|
|||
|
|
|
|||
|
|
核心对象:
|
|||
|
|
|
|||
|
|
- `Decoder`
|
|||
|
|
- 单包事实解码
|
|||
|
|
- `Tracker`
|
|||
|
|
- flow 状态与轻量提示
|
|||
|
|
- `Analyzer`
|
|||
|
|
- `Decoder + Tracker` 组合入口
|
|||
|
|
|
|||
|
|
## 2. 公开入口
|
|||
|
|
|
|||
|
|
### 2.1 `Decoder`
|
|||
|
|
|
|||
|
|
构造:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
decoder := bcap.NewDecoder()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
主要方法:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
Decode(packet gopacket.Packet) (Packet, error)
|
|||
|
|
DecodeWithOptions(packet gopacket.Packet, opts DecodeOptions) (Packet, error)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
使用时机:
|
|||
|
|
|
|||
|
|
- 只想获得单包事实
|
|||
|
|
- 自己维护状态机
|
|||
|
|
- 想把 `bcap` 当作标准化事实提取层
|
|||
|
|
|
|||
|
|
### 2.2 `Tracker`
|
|||
|
|
|
|||
|
|
构造:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
tracker := bcap.NewTracker()
|
|||
|
|
tracker := bcap.NewTrackerWithConfig(cfg)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
主要方法:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
Observe(packet Packet) (Observation, error)
|
|||
|
|
CleanupExpiredFlows() int
|
|||
|
|
ActiveFlowCount() int
|
|||
|
|
Stop()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
使用时机:
|
|||
|
|
|
|||
|
|
- 已经在别处完成解码
|
|||
|
|
- 只想复用 `bcap` 的 flow / hint 跟踪能力
|
|||
|
|
|
|||
|
|
### 2.3 `Analyzer`
|
|||
|
|
|
|||
|
|
构造:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
analyzer := bcap.NewAnalyzer()
|
|||
|
|
analyzer := bcap.NewAnalyzerWithConfig(cfg)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
主要方法:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
ObservePacket(packet gopacket.Packet) (Observation, error)
|
|||
|
|
ObservePacketWithOptions(packet gopacket.Packet, opts DecodeOptions) (Observation, error)
|
|||
|
|
Decoder() *Decoder
|
|||
|
|
Tracker() *Tracker
|
|||
|
|
Stop()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
使用时机:
|
|||
|
|
|
|||
|
|
- 在线抓包
|
|||
|
|
- 离线遍历
|
|||
|
|
- 绝大多数直接接入型工具
|
|||
|
|
|
|||
|
|
## 3. `DecodeOptions`
|
|||
|
|
|
|||
|
|
`DecodeOptions` 目前包含两个字段:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type DecodeOptions struct {
|
|||
|
|
BaseTime time.Time
|
|||
|
|
SrcMACOverride net.HardwareAddr
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
- `BaseTime`
|
|||
|
|
- 用于计算 `Packet.Meta.RelativeTime`
|
|||
|
|
- `Analyzer.ObservePacket(...)` 未显式传入时,会自动以首包时间作为基准
|
|||
|
|
- `SrcMACOverride`
|
|||
|
|
- 用于覆盖源 MAC
|
|||
|
|
|
|||
|
|
## 4. 数据模型
|
|||
|
|
|
|||
|
|
### 4.1 `Packet`
|
|||
|
|
|
|||
|
|
`Packet` 表示单包事实。
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type Packet struct {
|
|||
|
|
Meta Meta
|
|||
|
|
Link LinkFacts
|
|||
|
|
Network NetworkFacts
|
|||
|
|
Transport TransportFacts
|
|||
|
|
Raw RawFacts
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不包含跨包推断结果。
|
|||
|
|
|
|||
|
|
### 4.2 `Meta`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type Meta struct {
|
|||
|
|
Timestamp time.Time
|
|||
|
|
TimestampMicros int64
|
|||
|
|
RelativeTime time.Duration
|
|||
|
|
CaptureLength int
|
|||
|
|
Length int
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
- `Timestamp` / `TimestampMicros`
|
|||
|
|
- 捕获时间
|
|||
|
|
- `RelativeTime`
|
|||
|
|
- 相对 `BaseTime` 的时间差
|
|||
|
|
- `CaptureLength`
|
|||
|
|
- 实际捕获长度
|
|||
|
|
- `Length`
|
|||
|
|
- 原始报文长度
|
|||
|
|
|
|||
|
|
### 4.3 `LinkFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type LinkFacts struct {
|
|||
|
|
Kind LinkKind
|
|||
|
|
SrcMAC net.HardwareAddr
|
|||
|
|
DstMAC net.HardwareAddr
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当前支持的链路类型:
|
|||
|
|
|
|||
|
|
- `LinkKindEthernet`
|
|||
|
|
- `LinkKindLinuxSLL`
|
|||
|
|
- `LinkKindLinuxSLL2`
|
|||
|
|
- `LinkKindUnknown`
|
|||
|
|
|
|||
|
|
### 4.4 `NetworkFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type NetworkFacts struct {
|
|||
|
|
Family NetworkFamily
|
|||
|
|
SrcIP string
|
|||
|
|
DstIP string
|
|||
|
|
TTL uint8
|
|||
|
|
HopLimit uint8
|
|||
|
|
ProtocolNumber uint16
|
|||
|
|
ARP *ARPFacts
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当前支持的网络族:
|
|||
|
|
|
|||
|
|
- `NetworkFamilyIPv4`
|
|||
|
|
- `NetworkFamilyIPv6`
|
|||
|
|
- `NetworkFamilyARP`
|
|||
|
|
- `NetworkFamilyUnknown`
|
|||
|
|
|
|||
|
|
备注:
|
|||
|
|
|
|||
|
|
- IPv4 报文主要填 `TTL`
|
|||
|
|
- IPv6 报文主要填 `HopLimit`
|
|||
|
|
- ARP 报文会同时填充 `ARP`
|
|||
|
|
|
|||
|
|
### 4.5 `TransportFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type TransportFacts struct {
|
|||
|
|
Kind ProtocolKind
|
|||
|
|
Payload int
|
|||
|
|
TCP *TCPFacts
|
|||
|
|
UDP *UDPFacts
|
|||
|
|
ICMP *ICMPFacts
|
|||
|
|
Unknown *UnknownTransportFacts
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当前支持协议:
|
|||
|
|
|
|||
|
|
- `ProtocolTCP`
|
|||
|
|
- `ProtocolUDP`
|
|||
|
|
- `ProtocolICMPv4`
|
|||
|
|
- `ProtocolICMPv6`
|
|||
|
|
- `ProtocolARP`
|
|||
|
|
- `ProtocolUnknown`
|
|||
|
|
|
|||
|
|
### 4.6 协议事实结构
|
|||
|
|
|
|||
|
|
#### `TCPFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type TCPFacts struct {
|
|||
|
|
SrcPort string
|
|||
|
|
DstPort string
|
|||
|
|
Seq uint32
|
|||
|
|
Ack uint32
|
|||
|
|
Window uint16
|
|||
|
|
SYN bool
|
|||
|
|
ACK bool
|
|||
|
|
FIN bool
|
|||
|
|
RST bool
|
|||
|
|
ECE bool
|
|||
|
|
CWR bool
|
|||
|
|
PSH bool
|
|||
|
|
Checksum uint16
|
|||
|
|
Payload int
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### `UDPFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type UDPFacts struct {
|
|||
|
|
SrcPort string
|
|||
|
|
DstPort string
|
|||
|
|
Length uint16
|
|||
|
|
Payload int
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### `ICMPFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type ICMPFacts struct {
|
|||
|
|
Version int
|
|||
|
|
Type uint8
|
|||
|
|
Code uint8
|
|||
|
|
Checksum uint16
|
|||
|
|
ID uint16
|
|||
|
|
Seq uint16
|
|||
|
|
Payload int
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### `ARPFacts`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type ARPFacts struct {
|
|||
|
|
Operation uint16
|
|||
|
|
SenderMAC net.HardwareAddr
|
|||
|
|
TargetMAC net.HardwareAddr
|
|||
|
|
SenderIP string
|
|||
|
|
TargetIP string
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.7 `FlowKey` / `FlowRef`
|
|||
|
|
|
|||
|
|
推荐使用结构化 flow,不把字符串 key 当成唯一公共接口。
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type Endpoint struct {
|
|||
|
|
IP string
|
|||
|
|
Port string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type FlowKey struct {
|
|||
|
|
Family NetworkFamily
|
|||
|
|
Protocol ProtocolKind
|
|||
|
|
Src Endpoint
|
|||
|
|
Dst Endpoint
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type FlowRef struct {
|
|||
|
|
Forward FlowKey
|
|||
|
|
Reverse FlowKey
|
|||
|
|
Stable string
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
方法:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
func (f FlowKey) StableString() string
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
- `Forward`
|
|||
|
|
- 当前方向
|
|||
|
|
- `Reverse`
|
|||
|
|
- 反向方向
|
|||
|
|
- `Stable`
|
|||
|
|
- 稳定字符串表达,可用于日志和 map key
|
|||
|
|
|
|||
|
|
### 4.8 `Observation`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type Observation struct {
|
|||
|
|
Packet Packet
|
|||
|
|
Flow FlowRef
|
|||
|
|
Hints HintSet
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- `Packet`
|
|||
|
|
- 报文事实
|
|||
|
|
- `Flow`
|
|||
|
|
- 流引用
|
|||
|
|
- `Hints`
|
|||
|
|
- 推断结果
|
|||
|
|
|
|||
|
|
## 5. Hint 模型
|
|||
|
|
|
|||
|
|
### 5.1 `HintSet`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type HintSet struct {
|
|||
|
|
Summary SummaryHint
|
|||
|
|
Tags []Tag
|
|||
|
|
|
|||
|
|
TCP *TCPHint
|
|||
|
|
UDP *UDPHint
|
|||
|
|
ICMP *ICMPHint
|
|||
|
|
ARP *ARPHint
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- `Summary`
|
|||
|
|
- 摘要代码
|
|||
|
|
- `Tags`
|
|||
|
|
- 标签集合
|
|||
|
|
- 协议专属 hint
|
|||
|
|
- 放在对应子结构中
|
|||
|
|
|
|||
|
|
### 5.2 TCP hints
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type TCPHint struct {
|
|||
|
|
Phase TCPPhase
|
|||
|
|
Event TCPEvent
|
|||
|
|
LegacyState uint8
|
|||
|
|
Seq uint32
|
|||
|
|
Ack uint32
|
|||
|
|
Window uint16
|
|||
|
|
Payload int
|
|||
|
|
Retransmission bool
|
|||
|
|
Keepalive bool
|
|||
|
|
KeepaliveResponse bool
|
|||
|
|
RST bool
|
|||
|
|
ECE bool
|
|||
|
|
CWR bool
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Phase:
|
|||
|
|
|
|||
|
|
- `TCPPhaseHandshake`
|
|||
|
|
- `TCPPhaseEstablished`
|
|||
|
|
- `TCPPhaseTeardown`
|
|||
|
|
- `TCPPhaseSpecial`
|
|||
|
|
- `TCPPhaseUnknown`
|
|||
|
|
|
|||
|
|
Event:
|
|||
|
|
|
|||
|
|
- `TCPEventSYN`
|
|||
|
|
- `TCPEventSYNACK`
|
|||
|
|
- `TCPEventHandshakeACK`
|
|||
|
|
- `TCPEventACK`
|
|||
|
|
- `TCPEventRetransmission`
|
|||
|
|
- `TCPEventKeepalive`
|
|||
|
|
- `TCPEventKeepaliveResp`
|
|||
|
|
- `TCPEventFIN`
|
|||
|
|
- `TCPEventFINACK`
|
|||
|
|
- `TCPEventTeardownACK`
|
|||
|
|
- `TCPEventRST`
|
|||
|
|
- `TCPEventECE`
|
|||
|
|
- `TCPEventCWR`
|
|||
|
|
- `TCPEventUnknown`
|
|||
|
|
|
|||
|
|
常见 Tag:
|
|||
|
|
|
|||
|
|
- `TagTCPHandshakeSYN`
|
|||
|
|
- `TagTCPHandshakeSYNACK`
|
|||
|
|
- `TagTCPHandshakeACK`
|
|||
|
|
- `TagTCPTeardownFIN`
|
|||
|
|
- `TagTCPTeardownFINACK`
|
|||
|
|
- `TagTCPTeardownACK`
|
|||
|
|
- `TagTCPPacket`
|
|||
|
|
- `TagTCPRetransmit`
|
|||
|
|
- `TagTCPKeepalive`
|
|||
|
|
- `TagTCPKeepaliveResp`
|
|||
|
|
- `TagTCPRst`
|
|||
|
|
- `TagTCPEce`
|
|||
|
|
- `TagTCPCwr`
|
|||
|
|
|
|||
|
|
### 5.3 UDP / ICMP / ARP hints
|
|||
|
|
|
|||
|
|
#### `UDPHint`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type UDPHint struct {
|
|||
|
|
Payload int
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
对应 Tag:
|
|||
|
|
|
|||
|
|
- `TagUDPPacket`
|
|||
|
|
|
|||
|
|
#### `ICMPHint`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type ICMPHint struct {
|
|||
|
|
Version int
|
|||
|
|
Type uint8
|
|||
|
|
Code uint8
|
|||
|
|
IsEcho bool
|
|||
|
|
IsEchoReply bool
|
|||
|
|
IsUnreachable bool
|
|||
|
|
IsTimeExceeded bool
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
对应 Tag:
|
|||
|
|
|
|||
|
|
- `TagICMPPacket`
|
|||
|
|
- `TagICMPEchoRequest`
|
|||
|
|
- `TagICMPEchoReply`
|
|||
|
|
- `TagICMPUnreachable`
|
|||
|
|
- `TagICMPTimeExceeded`
|
|||
|
|
|
|||
|
|
#### `ARPHint`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type ARPHint struct {
|
|||
|
|
Operation uint16
|
|||
|
|
Request bool
|
|||
|
|
Reply bool
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
对应 Tag:
|
|||
|
|
|
|||
|
|
- `TagARPRequest`
|
|||
|
|
- `TagARPReply`
|
|||
|
|
|
|||
|
|
## 6. TCP 跟踪边界
|
|||
|
|
|
|||
|
|
`Tracker` 对 TCP 只做轻量跟踪,不做完整 TCP 栈模拟。
|
|||
|
|
|
|||
|
|
当前覆盖:
|
|||
|
|
|
|||
|
|
- 握手识别
|
|||
|
|
- 挥手识别
|
|||
|
|
- 普通 ACK 识别
|
|||
|
|
- 重传识别
|
|||
|
|
- keepalive 识别
|
|||
|
|
- keepalive response 识别
|
|||
|
|
- RST / ECE / CWR 识别
|
|||
|
|
|
|||
|
|
实现说明:
|
|||
|
|
|
|||
|
|
- 基于 flow 跟踪
|
|||
|
|
- 使用有限 segment 记忆辅助判断重传
|
|||
|
|
- keepalive 使用启发式判断
|
|||
|
|
- 支持超时清理
|
|||
|
|
|
|||
|
|
不覆盖:
|
|||
|
|
|
|||
|
|
- 严格 TCP 协议验证
|
|||
|
|
- 深度重组
|
|||
|
|
- 业务级根因结论
|
|||
|
|
|
|||
|
|
## 7. 配置
|
|||
|
|
|
|||
|
|
### 7.1 `PacketsConfig`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type PacketsConfig struct {
|
|||
|
|
ConnectionTimeout time.Duration
|
|||
|
|
CleanupInterval time.Duration
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
字段:
|
|||
|
|
|
|||
|
|
- `ConnectionTimeout`
|
|||
|
|
- flow 状态保留时长
|
|||
|
|
- `CleanupInterval`
|
|||
|
|
- 自动清理周期
|
|||
|
|
|
|||
|
|
默认值:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
const (
|
|||
|
|
DefaultConnectionTimeout = 5 * time.Minute
|
|||
|
|
DefaultCleanupInterval = 1 * time.Minute
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
默认配置:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
cfg := bcap.DefaultConfig()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 生命周期方法
|
|||
|
|
|
|||
|
|
`Tracker`:
|
|||
|
|
|
|||
|
|
- `CleanupExpiredFlows() int`
|
|||
|
|
- `ActiveFlowCount() int`
|
|||
|
|
- `Stop()`
|
|||
|
|
|
|||
|
|
`Analyzer`:
|
|||
|
|
|
|||
|
|
- `Decoder() *Decoder`
|
|||
|
|
- `Tracker() *Tracker`
|
|||
|
|
- `Stop()`
|
|||
|
|
|
|||
|
|
备注:
|
|||
|
|
|
|||
|
|
- 长生命周期进程退出前调用 `Stop()`
|
|||
|
|
- 如需自行控制清理节奏,可将 `CleanupInterval` 设为 `0`,再手动调用 `CleanupExpiredFlows()`
|
|||
|
|
|
|||
|
|
## 8. 错误模型
|
|||
|
|
|
|||
|
|
`bcap` 使用 `*ParseError` 表达解析问题:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type ParseError struct {
|
|||
|
|
Type ParseErrorType
|
|||
|
|
Layer string
|
|||
|
|
Message string
|
|||
|
|
Err error
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
错误类型:
|
|||
|
|
|
|||
|
|
- `ErrTypeLinkLayer`
|
|||
|
|
- `ErrTypeNetwork`
|
|||
|
|
- `ErrTypeTransport`
|
|||
|
|
- `ErrTypeUnsupported`
|
|||
|
|
|
|||
|
|
常见触发条件:
|
|||
|
|
|
|||
|
|
- 没有有效网络层
|
|||
|
|
- 协议层对象类型不匹配
|
|||
|
|
- 跟踪阶段缺少必须的协议事实
|
|||
|
|
|
|||
|
|
## 9. 子包
|
|||
|
|
|
|||
|
|
### 9.1 `libpcap`
|
|||
|
|
|
|||
|
|
`libpcap` 子包负责在线抓包输入。
|
|||
|
|
|
|||
|
|
入口:
|
|||
|
|
|
|||
|
|
- `FindAllDevs()`
|
|||
|
|
- `NewCatch(host, filter)`
|
|||
|
|
- `NewCatchEth(eth, filter)`
|
|||
|
|
- `SetRecall(func(gopacket.Packet))`
|
|||
|
|
- `Run()`
|
|||
|
|
- `Stop()`
|
|||
|
|
|
|||
|
|
常见组合:
|
|||
|
|
|
|||
|
|
- 子包接收 `gopacket.Packet`
|
|||
|
|
- 主包 `Analyzer` 做解析和提示
|
|||
|
|
- 上层工具做展示和统计
|
|||
|
|
|
|||
|
|
### 9.2 `nfq`
|
|||
|
|
|
|||
|
|
`nfq` 子包负责 NFQUEUE 输入适配。
|
|||
|
|
|
|||
|
|
入口:
|
|||
|
|
|
|||
|
|
- `NewNfQueue(ctx, queid, maxqueue)`
|
|||
|
|
- `SetRecall(func(id uint32, q *nfqueue.Nfqueue, p Packet))`
|
|||
|
|
- `Run()`
|
|||
|
|
- `Stop()`
|
|||
|
|
|
|||
|
|
备注:
|
|||
|
|
|
|||
|
|
- `nfq.Packet` 只是 NFQUEUE 输入包装
|
|||
|
|
- 它不是主包的 `bcap.Packet`
|
|||
|
|
- 一般仍然从其中取 `gopacket.Packet`,再交给 `Analyzer` 或 `Decoder`
|
|||
|
|
|
|||
|
|
## 10. 示例
|
|||
|
|
|
|||
|
|
### 10.1 直接用 `Analyzer`
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
analyzer := bcap.NewAnalyzer()
|
|||
|
|
defer analyzer.Stop()
|
|||
|
|
|
|||
|
|
obs, err := analyzer.ObservePacket(packet)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fmt.Println(obs.Flow.Stable)
|
|||
|
|
fmt.Println(obs.Packet.Transport.Kind)
|
|||
|
|
fmt.Println(obs.Hints.Summary.Code)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 10.2 自己管理解码和跟踪
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
decoder := bcap.NewDecoder()
|
|||
|
|
tracker := bcap.NewTracker()
|
|||
|
|
defer tracker.Stop()
|
|||
|
|
|
|||
|
|
decoded, err := decoder.DecodeWithOptions(packet, bcap.DecodeOptions{
|
|||
|
|
BaseTime: firstPacketTS,
|
|||
|
|
})
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
obs, err := tracker.Observe(decoded)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 10.3 典型离线遍历
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
f, err := os.Open("sample.pcap")
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
defer f.Close()
|
|||
|
|
|
|||
|
|
reader, err := pcapgo.NewReader(f)
|
|||
|
|
if err != nil {
|
|||
|
|
return err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
source := gopacket.NewPacketSource(reader, reader.LinkType())
|
|||
|
|
analyzer := bcap.NewAnalyzer()
|
|||
|
|
defer analyzer.Stop()
|
|||
|
|
|
|||
|
|
for packet := range source.Packets() {
|
|||
|
|
obs, err := analyzer.ObservePacket(packet)
|
|||
|
|
if err != nil {
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
fmt.Println(obs.Packet.Network.SrcIP, obs.Hints.Summary.Code)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 11. 辅助函数
|
|||
|
|
|
|||
|
|
主包还提供两个轻量格式化函数:
|
|||
|
|
|
|||
|
|
- `FormatDuration(time.Duration) string`
|
|||
|
|
- `FormatBytes(uint64) string`
|
|||
|
|
|
|||
|
|
用于轻量日志与终端展示。
|
|||
|
|
|
|||
|
|
## 12. 迁移说明
|
|||
|
|
|
|||
|
|
主包旧接口已经被清理,删除项包括:
|
|||
|
|
|
|||
|
|
- `Packets`
|
|||
|
|
- `PacketInfo`
|
|||
|
|
- `ParsePacket`
|
|||
|
|
- `NewPackets`
|
|||
|
|
- `NewPacketsWithConfig`
|
|||
|
|
- `LegacyPacketInfoFromObservation`
|
|||
|
|
- `GetStateDescription`
|
|||
|
|
- `PrintStats`
|
|||
|
|
- `ExportConnectionsToJSON`
|
|||
|
|
|
|||
|
|
迁移方向:
|
|||
|
|
|
|||
|
|
- 旧的单包解析入口迁到 `Decoder`
|
|||
|
|
- 旧的“包 + 状态”混合对象迁到 `Observation`
|
|||
|
|
- 旧的连接跟踪职责迁到 `Tracker`
|
|||
|
|
- 大部分调用场景直接迁到 `Analyzer`
|
|||
|
|
|
|||
|
|
旧代码如果大量依赖字符串 key:
|
|||
|
|
|
|||
|
|
- 新代码优先改为使用 `FlowRef.Forward` / `FlowRef.Reverse`
|
|||
|
|
- 如果只是为了日志或 map key,可以继续使用 `FlowRef.Stable`
|
|||
|
|
|
|||
|
|
## 13. 相关文档
|
|||
|
|
|
|||
|
|
- 快速入口见 [`../README.md`](../README.md)
|
|||
|
|
- 设计备忘见 [`dev.md`](./dev.md)
|