// Saves stats from the socket to the TPacket instance func (h *TPacket) SocketStats() (SocketStats, SocketStatsV3, error) { h.mu.Lock() defer h.mu.Unlock() // We need to save the counters since asking for the stats will clear them if h.tpVersion == TPacketVersion3 { prevStats := h.socketStatsV3 socklen := unsafe.Sizeof(h.socketStatsV3) var slt C.socklen_t = C.socklen_t(socklen) _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStatsV3), &slt) if err != nil { return SocketStats{}, SocketStatsV3{}, err } h.socketStatsV3.tp_packets += prevStats.tp_packets h.socketStatsV3.tp_drops += prevStats.tp_drops h.socketStatsV3.tp_freeze_q_cnt += prevStats.tp_freeze_q_cnt return h.socketStats, h.socketStatsV3, nil } else { prevStats := h.socketStats socklen := unsafe.Sizeof(h.socketStats) var slt C.socklen_t = C.socklen_t(socklen) _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStats), &slt) if err != nil { return SocketStats{}, SocketStatsV3{}, err } h.socketStats.tp_packets += prevStats.tp_packets h.socketStats.tp_drops += prevStats.tp_drops return h.socketStats, h.socketStatsV3, nil } }
// Clear socket counters and return empty stats func (h *TPacket) InitSocketStats() error { if h.tpVersion == TPacketVersion3 { socklen := unsafe.Sizeof(h.socketStatsV3) var slt C.socklen_t = C.socklen_t(socklen) _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStatsV3), &slt) if err != nil { return err } h.socketStatsV3 = SocketStatsV3{} } else { socklen := unsafe.Sizeof(h.socketStats) var slt C.socklen_t = C.socklen_t(socklen) _, err := C.getsockopt(h.fd, C.SOL_PACKET, C.PACKET_STATISTICS, unsafe.Pointer(&h.socketStats), &slt) if err != nil { return err } h.socketStats = SocketStats{} } return nil }