diff --git a/capture/afpacket/afring/afring.go b/capture/afpacket/afring/afring.go index 7ff428a..0472b7d 100644 --- a/capture/afpacket/afring/afring.go +++ b/capture/afpacket/afring/afring.go @@ -121,7 +121,7 @@ func NewSourceFromLink(link *link.Link, options ...Option) (*Source, error) { // NextIPPacket() methods (the latter two by calling .Payload() / .IPLayer() on the created buffer). It ensures // that a valid packet of appropriate structure / length is created func (s *Source) NewPacket() capture.Packet { - p := make(capture.Packet, 6+s.snapLen) + p := make(capture.Packet, capture.PacketHdrOffset+s.snapLen) return p } diff --git a/capture/afpacket/afring/afring_mock.go b/capture/afpacket/afring/afring_mock.go index aba8e1f..a086e58 100644 --- a/capture/afpacket/afring/afring_mock.go +++ b/capture/afpacket/afring/afring_mock.go @@ -141,7 +141,7 @@ func (m *MockSource) addPacket(payload []byte, totalLen uint32, pktType, ipLayer block := m.ringBuffer.ring[thisBlock*m.blockSize : thisBlock*m.blockSize+m.blockSize] *(*tPacketHeaderV3Mock)(unsafe.Pointer(&block[m.curBlockPos+12])) = tPacketHeaderV3Mock{ - snaplen: min(uint32(m.snapLen), totalLen), // The snaplen is set to the totalLen if a packet is shorter + snaplen: min(uint32(m.snapLen), uint32(len(payload))), // The snaplen is set to the actual payload length if a packet is shorter pktLen: totalLen, pktMac: mac, pktNet: mac + uint16(m.ipLayerOffset), diff --git a/capture/capture.go b/capture/capture.go index 6cb6611..641cf0b 100644 --- a/capture/capture.go +++ b/capture/capture.go @@ -22,10 +22,13 @@ import ( "golang.org/x/net/ipv6" ) -var ( +const ( // PacketHdrOffset denotes the header offset / length for storing information about the packet PacketHdrOffset = 6 +) + +var ( // ErrCaptureStopped denotes that the capture was stopped ErrCaptureStopped = errors.New("capture was stopped") @@ -85,8 +88,12 @@ func (i IPLayer) String() (res string) { if ipLayerType == 4 { protocol := i[9] if protocol == 6 || protocol == 17 { - dport = binary.BigEndian.Uint16(i[ipv4.HeaderLen+2 : ipv4.HeaderLen+4]) - sport = binary.BigEndian.Uint16(i[ipv4.HeaderLen : ipv4.HeaderLen+2]) + if len(i) >= ipv4.HeaderLen+4 { + dport = binary.BigEndian.Uint16(i[ipv4.HeaderLen+2 : ipv4.HeaderLen+4]) + } + if len(i) >= ipv4.HeaderLen+2 { + sport = binary.BigEndian.Uint16(i[ipv4.HeaderLen : ipv4.HeaderLen+2]) + } } return fmt.Sprintf("%s:%d => %s:%d (proto: %d)", net.IP(i[12:16]).String(), @@ -98,8 +105,12 @@ func (i IPLayer) String() (res string) { } else if ipLayerType == 6 { protocol := i[6] if protocol == 6 || protocol == 17 { - dport = binary.BigEndian.Uint16(i[ipv6.HeaderLen+2 : ipv6.HeaderLen+4]) - sport = binary.BigEndian.Uint16(i[ipv6.HeaderLen : ipv6.HeaderLen+2]) + if len(i) >= ipv6.HeaderLen+4 { + dport = binary.BigEndian.Uint16(i[ipv6.HeaderLen+2 : ipv6.HeaderLen+4]) + } + if len(i) >= ipv6.HeaderLen+2 { + sport = binary.BigEndian.Uint16(i[ipv6.HeaderLen : ipv6.HeaderLen+2]) + } } return fmt.Sprintf("%s:%d => %s:%d (proto: %d)", net.IP(i[8:24]).String(), @@ -188,9 +199,9 @@ func NewIPPacket(buf Packet, payload []byte, pktType PacketType, totalLen int, i buf[0] = pktType buf[1] = ipLayerOffset *(*uint32)(unsafe.Pointer(&buf[2])) = uint32(totalLen) // #nosec G103 - copy(buf[PacketHdrOffset:], payload) + n := copy(buf[PacketHdrOffset:], payload) - return buf + return buf[:PacketHdrOffset+n] } // TotalLen returnsthe total packet length, including all headers