commit b279623885dd86032d8478f50aa68dd50a36b2f7
parent 45d38afd3229304a1d6893ed350bd33edb47f7ce
Author: atomic <atomic@2f30.org>
Date: Tue, 17 Feb 2015 06:54:29 +0100
added general structure of the bgp message parser
Diffstat:
A | bgp/bgp.go | | | 134 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | 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")
+}