calmh / ipfix

IPFIX parser package for Go
MIT License
48 stars 26 forks source link

Reading from net.PacketConn #11

Closed isage closed 7 years ago

isage commented 7 years ago

Readme states, that: An input stream in the form of an io.Reader, net.PacketConn, or a []byte is read and chunked into messages.

However, there are no Session methods to read from PacketConn, and, obviously,

cannot use pc (type net.PacketConn) as type io.Reader in argument to s.ParseReader:
        net.PacketConn does not implement io.Reader (missing Read method)
calmh commented 7 years ago

Yeah, the readme is outdated. This is better accomplished by doing the reading yourself and then using ParseBuffer. Probably ParseReader should not exist either, but now it does. :)

isage commented 7 years ago

Hm. But how do i know, how big a buffer i should use? So i don't run into short read - malformed packet?

calmh commented 7 years ago

The largest possible payload size of a UDP packet is 65507 bytes.

isage commented 7 years ago

Oh, right. But with such a big buffer i'm getting unexpected EOF. Sorry for bothering you, but what am i doing wrong?

package main

import (
    "net"
    "log"
    "fmt"
    "github.com/calmh/ipfix"
)

func main() {

  pc, err := net.ListenPacket("udp", ":2055")
  if err != nil {
    log.Fatal(err)
  }
  defer pc.Close()

  s := ipfix.NewSession()
  i := ipfix.NewInterpreter(s)

  buffer := make([]byte, 65507)

  for {
    pc.ReadFrom(buffer)

    msg, err := s.ParseBuffer(buffer)
    if err != nil {
        panic(err)
    }

    var fieldList []ipfix.InterpretedField
    for _, record := range msg.DataRecords {
        fieldList = i.InterpretInto(record, fieldList)
        fmt.Println(fieldList)
    }
  }
}
calmh commented 7 years ago

You need to only give it the part of the buffer that was actually read into. See the example I just wrote up in the readme in the commit linked above^ and see if that helps

isage commented 7 years ago

Yep, that definitely helps. Thank you!