summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packet/bgp.go55
-rw-r--r--server/fsm.go6
2 files changed, 61 insertions, 0 deletions
diff --git a/packet/bgp.go b/packet/bgp.go
index ae222a34..8bff8485 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -2088,8 +2088,28 @@ type BGPUpdate struct {
}
func (msg *BGPUpdate) DecodeFromBytes(data []byte) error {
+
+ // cache error codes
+ eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
+ eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST)
+
+ // check withdrawn route length
+ if len(data) < 2 {
+ msg := "message length isn't enough for withdrawn route length"
+ e := NewPacketParseError(eCode, eSubCode, msg)
+ return e
+ }
+
msg.WithdrawnRoutesLen = binary.BigEndian.Uint16(data[0:2])
data = data[2:]
+
+ // check withdrawn route
+ if len(data) < int(msg.WithdrawnRoutesLen) {
+ msg := "withdrawn route length exceeds message length"
+ e := NewPacketParseError(eCode, eSubCode, msg)
+ return e
+ }
+
for routelen := msg.WithdrawnRoutesLen; routelen > 0; {
w := WithdrawnRoute{}
w.DecodeFromBytes(data)
@@ -2097,8 +2117,24 @@ func (msg *BGPUpdate) DecodeFromBytes(data []byte) error {
data = data[w.Len():]
msg.WithdrawnRoutes = append(msg.WithdrawnRoutes, w)
}
+
+ // check path total attribute length
+ if len(data) < 2 {
+ msg := "message length isn't enough for path total attribute length"
+ e := NewPacketParseError(eCode, eSubCode, msg)
+ return e
+ }
+
msg.TotalPathAttributeLen = binary.BigEndian.Uint16(data[0:2])
data = data[2:]
+
+ // check path attribute
+ if len(data) < int(msg.TotalPathAttributeLen) {
+ msg := "path total attribute length exceeds message length"
+ e := NewPacketParseError(eCode, eSubCode, msg)
+ return e
+ }
+
for pathlen := msg.TotalPathAttributeLen; pathlen > 0; {
p := getPathAttribute(data)
p.DecodeFromBytes(data)
@@ -2661,3 +2697,22 @@ func ParseBMPMessage(data []byte) (*BMPMessage, error) {
}
return msg, nil
}
+
+type PacketParseError struct {
+ TypeCode uint8
+ SubTypeCode uint8
+ Message string
+}
+
+func NewPacketParseError(typeCode, subTypeCode uint8, msg string) error {
+ e := &PacketParseError{
+ TypeCode: typeCode,
+ SubTypeCode: subTypeCode,
+ Message: msg,
+ }
+ return e
+}
+
+func (e *PacketParseError) Error() string {
+ return e.Message
+}
diff --git a/server/fsm.go b/server/fsm.go
index f3b6c3db..ee3d221e 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -347,6 +347,12 @@ func (h *FSMHandler) recvMessageloop() error {
for {
err := h.recvMessageWithError()
if err != nil {
+ switch e := err.(type) {
+ case *bgp.PacketParseError:
+ // enqueue notification message
+ n := bgp.NewBGPNotificationMessage(e.TypeCode, e.SubTypeCode, nil)
+ h.fsm.outgoing <- n
+ }
return nil
}
}