go-bgp

a collection of golang BGP tools to monitor, archive and serve
git clone git://git.2f30.org/go-bgp.git
Log | Files | Refs | README

commit b279623885dd86032d8478f50aa68dd50a36b2f7
parent 45d38afd3229304a1d6893ed350bd33edb47f7ce
Author: atomic <atomic@2f30.org>
Date:   Tue Feb 17 06:54:29 +0100

added general structure of the bgp message parser

Diffstat:
bgp/bgp.go | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bgp/bgp_test.go | 9+++++++++
2 files changed, 143 insertions(+), 0 deletions(-)
diff --git a/bgp/bgp.go b/bgp/bgp.go @@ -0,0 +1,134 @@ +package bgp + +import ( + "bytes" + "encoding/binary" + "fmt" + "io/ioutil" +) + +type uint128 struct { + H uint64 + L uint64 +} + +// magic numbers explained +const ( + MinMsgLen = 19 + MinNotifiMsgLen = 21 +) + +// bgp msg types +const ( + _ = iota + OPEN + UPDATE + NOTIFICATION + KEEPALIVE +) + +type BgpHdr struct { + Marker uint128 + Len uint16 + Type uint8 +} + +type BgpMsg struct { + h BgpHdr +} + +type BgpOpenMsg struct { + Hdr BgpHdr + Ver uint8 + MyAs uint16 + Htime uint16 + BgpId uint32 + OptLen uint8 + Opt []byte +} + +type BgpUpdateMsg struct { + Hdr BgpHdr + UnfRoutesLen uint16 + WithdRoutes []byte + TotalPathAttrLen uint16 + NetLayerReachInfo []byte +} +type BgpNotifiMsg struct { + Hdr BgpHdr + ErrCode uint8 + ErrSubCode uint8 + Data []byte +} + +type BgpKeepaliveMsg struct { + Hdr BgpHdr +} + +func parse(b []byte) (interface{}, error) { + var h BgpHdr + + // parse header + buf := bytes.NewReader(b) + err := binary.Read(buf, binary.BigEndian, &h.Marker) + + err = binary.Read(buf, binary.BigEndian, &h.Len) + err = binary.Read(buf, binary.BigEndian, &h.Type) + + switch h.Type { + case OPEN: + var m BgpOpenMsg + m.Hdr = h + + err = binary.Read(buf, binary.BigEndian, &m.Ver) + err = binary.Read(buf, binary.BigEndian, &m.MyAs) + err = binary.Read(buf, binary.BigEndian, &m.Htime) + err = binary.Read(buf, binary.BigEndian, &m.BgpId) + err = binary.Read(buf, binary.BigEndian, &m.OptLen) + + if m.OptLen > 0 { + m.Opt = make([]byte, m.OptLen) + err = binary.Read(buf, binary.BigEndian, &m.Opt) + } + return m, nil + + case UPDATE: + var m BgpUpdateMsg + m.Hdr = h + + if h.Len == MinMsgLen { + return m, nil + } + + err = binary.Read(buf, binary.BigEndian, &m.UnfRoutesLen) + if m.UnfRoutesLen > 0 { + m.WithdRoutes = make([]byte, m.UnfRoutesLen) + err = binary.Read(buf, binary.BigEndian, &m.WithdRoutes) + } + + err = binary.Read(buf, binary.BigEndian, &m.TotalPathAttrLen) + if m.TotalPathAttrLen > 0 { + m.NetLayerReachInfo = make([]byte, m.TotalPathAttrLen) + err = binary.Read(buf, binary.BigEndian, &m.NetLayerReachInfo) + } + return m, nil + + case NOTIFICATION: + var m BgpNotifiMsg + m.Hdr = h + + err = binary.Read(buf, binary.BigEndian, &m.ErrCode) + err = binary.Read(buf, binary.BigEndian, &m.ErrSubCode) + + if h.Len > MinNotifiMsgLen { + m.Data = make([]byte, h.Len-MinNotifiMsgLen) + err = binary.Read(buf, binary.BigEndian, &m.ErrSubCode) + } + + return m, nil + + case KEEPALIVE: + return BgpKeepaliveMsg{h}, nil + } + return nil, err +} diff --git a/bgp/bgp_test.go b/bgp/bgp_test.go @@ -0,0 +1,9 @@ +package bgp + +import ( + "testing" +) + +func TestParse(t *testing.T) { + t.Fatal("Test not implemented") +}