aregm / nff-go

NFF-Go -Network Function Framework for GO (former YANFF)
BSD 3-Clause "New" or "Revised" License
1.38k stars 156 forks source link

GetPacketPayload error:slice bounds out of range [90:60] #705

Open cang233 opened 4 years ago

cang233 commented 4 years ago

code:

    if global.CaptureWithRaw { //not zero copy
        raw := p.GetRawPacketBytes()
        defer catchPanic(raw, p)
        newp.RawBytes = make([]byte, len(raw))
        copy(newp.RawBytes, raw)
        pld, ok := p.GetPacketPayload()
        pldLen := len(pld)
        if ok && pldLen != 0 {
            newp.Payload = make([]byte, pldLen)
            copy(newp.Payload, pld)
            newp.PayLoadLen = pldLen
        }
    }
DROP: Flow functions together dropped 178997 packets
DEBUG: Start new instance for segment2
WARNING: Can't start new clone for segment2 instance 3
DEBUG: Error raw: 40,166,219,113,123,251,72,253,142,181,177,255,8,0,69,2,0,40,181,196,1,254,115,6,235,41,119,254,120,70,52,114,128,43,12,153,49,244,55,123,124,232,157,192,138,69,230,164,184,71,39,73,146,150,0,0,0,0,0,0
panic: runtime error: slice bounds out of range [90:60] [recovered]
    panic: runtime error: slice bounds out of range [90:60]

goroutine 23827 [running, locked to thread]:
flowparser/common.catchPanic(0x171cdd300, 0x3c, 0x40000000, 0x171cdd280)
    /home/pvs1/gopath/src/flowparser/common/flow.go:101 +0x1b9
panic(0xaa3360, 0xc0cfe5c8e0)
    /usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/intel-go/nff-go/packet.(*Packet).GetPacketPayload(0x171cdd280, 0x171cdd300, 0x3c, 0xc0da2d4740, 0xc04e575928)
    /home/pvs1/gopath/pkg/mod/github.com/intel-go/nff-go@v0.9.2/packet/packet.go:750 +0xf1
flowparser/common.NewIP4TCP(0x171cdd280, 0x0)
    /home/pvs1/gopath/src/flowparser/common/flow.go:73 +0x1e9
main.vHandleIPv4TCP(0xc001b74100, 0x20, 0x20, 0xc00054e508, 0xb70a20, 0xc002404060)
    /home/pvs1/gopath/src/flowparser/main.go:166 +0x5b
github.com/intel-go/nff-go/flow.vHandle(0xc001b74100, 0x20, 0x20, 0xc00054e508, 0xc002ef2340, 0xc00014c0e0, 0xb70a20, 0xc002404060)
    /home/pvs1/gopath/pkg/mod/github.com/intel-go/nff-go@v0.9.2/flow/flow.go:1845 +0x66
github.com/intel-go/nff-go/flow.segmentProcess(0xa230a0, 0xc000114930, 0xc003efe0a0, 0x11, 0x11, 0xc007782000, 0xc007782060, 0xc0013b6700, 0xc000112160, 0x2, ...)
    /home/pvs1/gopath/pkg/mod/github.com/intel-go/nff-go@v0.9.2/flow/flow.go:1496 +0x82d
github.com/intel-go/nff-go/flow.(*instance).startNewClone.func1(0xc00053cc00, 0x5, 0xc001bd6f00)
    /home/pvs1/gopath/pkg/mod/github.com/intel-go/nff-go@v0.9.2/flow/scheduler.go:289 +0x245
created by github.com/intel-go/nff-go/flow.(*instance).startNewClone
    /home/pvs1/gopath/pkg/mod/github.com/intel-go/nff-go@v0.9.2/flow/scheduler.go:283 +0x2b2
exit status 2

I read the source code and find that GetRawPacketBytes() only get mbuf length in one CMbuf struct,but ParseData parse all packets' payload if scattered?

Now update the pkt I capture,covert function is used to print the raw bytes as below.

func convert(b []byte) string {
    s := make([]string, len(b))
    for i := range b {
        s[i] = strconv.Itoa(int(b[i]))
    }
    return strings.Join(s, ",")
}

and I save the packet .pcap as follows: image

cang233 commented 4 years ago

According to source code,use -> as "point to",then p.ether->0, p.ipv4->14,

func (packet *Packet) unparsed() unsafe.Pointer {
    ether := unsafe.Pointer(packet.Ether)
    return unsafe.Pointer(uintptr(ether) + types.EtherLen)
}

p.tcp->34,header length is 20 here according to the screenshot,and code excatly compute correctly.

func (packet *Packet) ParseL4ForIPv4() {
    packet.L4 = unsafe.Pointer(uintptr(packet.L3) + uintptr((packet.GetIPv4NoCheck().VersionIhl&0x0f)<<2))
}

But the tcp head length flag in the packet is 28,nff-go is also not wrong. Seems that it does excce the allowed length.