diff --git a/bpf/kprobe_pwru.c b/bpf/kprobe_pwru.c index 73dbec0c..499ecfbd 100644 --- a/bpf/kprobe_pwru.c +++ b/bpf/kprobe_pwru.c @@ -64,7 +64,7 @@ struct tuple { u16 dport; u16 l3_proto; u8 l4_proto; - u8 pad; + u8 tcp_flags; } __attribute__((packed)); enum event_type { @@ -311,6 +311,7 @@ __set_tuple(struct tuple *tpl, void *data, u16 l3_off, bool is_ipv4) { struct tcphdr *tcp = (struct tcphdr *) (data + l4_off); tpl->sport= BPF_CORE_READ(tcp, source); tpl->dport= BPF_CORE_READ(tcp, dest); + bpf_probe_read_kernel(&tpl->tcp_flags, sizeof(tpl->tcp_flags), (void *)tcp + offsetof(struct tcphdr, window) - 1); } else if (tpl->l4_proto == IPPROTO_UDP) { struct udphdr *udp = (struct udphdr *) (data + l4_off); tpl->sport= BPF_CORE_READ(udp, source); diff --git a/internal/pwru/output.go b/internal/pwru/output.go index 877053f3..5048e665 100644 --- a/internal/pwru/output.go +++ b/internal/pwru/output.go @@ -76,6 +76,7 @@ type jsonTuple struct { Sport uint16 `json:"sport,omitempty"` Dport uint16 `json:"dport,omitempty"` Proto uint8 `json:"proto,omitempty"` + Flags string `json:"flags,omitempty"` } func centerAlignString(s string, width int) string { @@ -100,7 +101,7 @@ func NewOutput(flags *Flags, printSkbMap, printShinfoMap, printStackMap *ebpf.Ma reasons, err := getKFreeSKBReasons(btfSpec) if err != nil { - log.Printf("Unable to load packet drop reaons: %v", err) + log.Printf("Unable to load packet drop reasons: %v", err) } var ifs map[uint64]map[uint32]string @@ -203,6 +204,7 @@ func (o *output) PrintJson(event *Event) { t.Sport = byteorder.NetworkToHost16(event.Tuple.Sport) t.Dport = byteorder.NetworkToHost16(event.Tuple.Dport) t.Proto = event.Tuple.L4Proto + t.Flags = event.Tuple.TCPFlag.String() d.Tuple = t } @@ -271,10 +273,16 @@ func getAddrByArch(event *Event, o *output) (addr uint64) { } func getTupleData(event *Event) (tupleData string) { + var l4Info string + if event.Tuple.L4Proto == syscall.IPPROTO_TCP && event.Tuple.TCPFlag != 0 { + l4Info = fmt.Sprintf("%s:%s", protoToStr(event.Tuple.L4Proto), event.Tuple.TCPFlag) + } else { + l4Info = protoToStr(event.Tuple.L4Proto) + } tupleData = fmt.Sprintf("%s:%d->%s:%d(%s)", addrToStr(event.Tuple.L3Proto, event.Tuple.Saddr), byteorder.NetworkToHost16(event.Tuple.Sport), addrToStr(event.Tuple.L3Proto, event.Tuple.Daddr), byteorder.NetworkToHost16(event.Tuple.Dport), - protoToStr(event.Tuple.L4Proto)) + l4Info) return tupleData } @@ -498,7 +506,7 @@ func addrToStr(proto uint16, addr [16]byte) string { } } -// getKFreeSKBReasons dervices SKB drop reasons from the "skb_drop_reason" enum +// getKFreeSKBReasons derives SKB drop reasons from the "skb_drop_reason" enum // defined in /include/net/dropreason.h. func getKFreeSKBReasons(spec *btf.Spec) (map[uint64]string, error) { if _, err := spec.AnyTypeByName("kfree_skb_reason"); err != nil { diff --git a/internal/pwru/types.go b/internal/pwru/types.go index 2abb1372..8de699f9 100644 --- a/internal/pwru/types.go +++ b/internal/pwru/types.go @@ -115,6 +115,30 @@ func (f *Flags) Parse() { } } +type tcpFlag uint8 + +func (f tcpFlag) String() string { + tcpFlags := []string{ + "FIN", + "SYN", + "RST", + "PSH", + "ACK", + "URG", + "ECE", + "CWR", + } + + var flags []string + for i, flag := range tcpFlags { + if f&(1<