diff --git a/protocols/bmp/packet/decode.go b/protocols/bmp/packet/decode.go
index 581411d64ec782636245a159b2545babf68f720d..d7989e28bb5955a294b195962d06c980cd0b645b 100644
--- a/protocols/bmp/packet/decode.go
+++ b/protocols/bmp/packet/decode.go
@@ -99,6 +99,4 @@ func Decode(msg []byte) (Msg, error) {
 		return nil, fmt.Errorf("Unexpected message type: %d", ch.MsgType)
 
 	}
-
-	return nil, fmt.Errorf("Unexpected message type: %d", ch.MsgType)
 }
diff --git a/protocols/bmp/packet/initiation_message.go b/protocols/bmp/packet/initiation_message.go
index 076d0f4b8a7c9713b1f75a76086c310140daf28f..6d4ee7ecc707702bfa4277901cab76be56c826a8 100644
--- a/protocols/bmp/packet/initiation_message.go
+++ b/protocols/bmp/packet/initiation_message.go
@@ -18,7 +18,8 @@ func (im *InitiationMessage) MsgType() uint8 {
 
 func decodeInitiationMessage(buf *bytes.Buffer, ch *CommonHeader) (Msg, error) {
 	im := &InitiationMessage{
-		TLVs: make([]*InformationTLV, 0, 2),
+		CommonHeader: ch,
+		TLVs:         make([]*InformationTLV, 0, 2),
 	}
 
 	read := uint32(0)
diff --git a/protocols/bmp/packet/peer_down.go b/protocols/bmp/packet/peer_down.go
index 347ffa2c51df7a371506183a30f3683df875795f..27f75c4be59822816e4f714e07920fc6935ee630 100644
--- a/protocols/bmp/packet/peer_down.go
+++ b/protocols/bmp/packet/peer_down.go
@@ -2,15 +2,17 @@ package packet
 
 import (
 	"bytes"
+	"fmt"
 
 	"github.com/bio-routing/bio-rd/util/decoder"
 )
 
 // PeerDownNotification represents a peer down notification
 type PeerDownNotification struct {
-	CommonHeader *CommonHeader
-	Reason       uint8
-	Data         []byte
+	CommonHeader  *CommonHeader
+	PerPeerHeader *PerPeerHeader
+	Reason        uint8
+	Data          []byte
 }
 
 // MsgType returns the type of this message
@@ -19,13 +21,22 @@ func (p *PeerDownNotification) MsgType() uint8 {
 }
 
 func decodePeerDownNotification(buf *bytes.Buffer, ch *CommonHeader) (*PeerDownNotification, error) {
-	p := &PeerDownNotification{}
+	p := &PeerDownNotification{
+		CommonHeader: ch,
+	}
+
+	pph, err := decodePerPeerHeader(buf)
+	if err != nil {
+		return nil, fmt.Errorf("Unable to decode per peer header: %v", err)
+	}
+
+	p.PerPeerHeader = pph
 
 	fields := []interface{}{
 		&p.Reason,
 	}
 
-	err := decoder.Decode(buf, fields)
+	err = decoder.Decode(buf, fields)
 	if err != nil {
 		return nil, err
 	}
@@ -34,7 +45,7 @@ func decodePeerDownNotification(buf *bytes.Buffer, ch *CommonHeader) (*PeerDownN
 		return p, nil
 	}
 
-	p.Data = make([]byte, ch.MsgLength-CommonHeaderLen-1)
+	p.Data = make([]byte, ch.MsgLength-PerPeerHeaderLen-CommonHeaderLen-1)
 	fields = []interface{}{
 		p.Data,
 	}
diff --git a/protocols/bmp/packet/peer_down_test.go b/protocols/bmp/packet/peer_down_test.go
index 61f2e9a6d76ee3900c55ba32851e900d57fcb698..b1df8b55e84d9ae6bf5854e4a2aea51357d73c3a 100644
--- a/protocols/bmp/packet/peer_down_test.go
+++ b/protocols/bmp/packet/peer_down_test.go
@@ -30,14 +30,36 @@ func TestDecodePeerDownNotification(t *testing.T) {
 		{
 			name: "Full",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
+
 				1,
 				1, 2, 3,
 			},
 			ch: &CommonHeader{
-				MsgLength: CommonHeaderLen + 4,
+				MsgLength: CommonHeaderLen + 4 + 38,
 			},
 			wantFail: false,
 			expected: &PeerDownNotification{
+				CommonHeader: &CommonHeader{
+					MsgLength: CommonHeaderLen + 4 + 38,
+				},
+				PerPeerHeader: &PerPeerHeader{
+					PeerType:              1,
+					PeerFlags:             2,
+					PeerDistinguisher:     3,
+					PeerAddress:           [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+					PeerAS:                51324,
+					PeerBGPID:             123,
+					Timestamp:             100,
+					TimestampMicroSeconds: 200,
+				},
 				Reason: 1,
 				Data: []byte{
 					1, 2, 3,
@@ -47,20 +69,65 @@ func TestDecodePeerDownNotification(t *testing.T) {
 		{
 			name: "Full no data",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
 				4,
 			},
 			ch: &CommonHeader{
-				MsgLength: CommonHeaderLen + 4,
+				MsgLength: CommonHeaderLen + PerPeerHeaderLen + 4,
 			},
 			wantFail: false,
 			expected: &PeerDownNotification{
+				CommonHeader: &CommonHeader{
+					MsgLength: CommonHeaderLen + PerPeerHeaderLen + 4,
+				},
+				PerPeerHeader: &PerPeerHeader{
+					PeerType:              1,
+					PeerFlags:             2,
+					PeerDistinguisher:     3,
+					PeerAddress:           [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+					PeerAS:                51324,
+					PeerBGPID:             123,
+					Timestamp:             100,
+					TimestampMicroSeconds: 200,
+				},
 				Reason: 4,
 				Data:   nil,
 			},
 		},
+		{
+			name: "Incomplete per peer header",
+			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0,
+			},
+			ch: &CommonHeader{
+				MsgLength: CommonHeaderLen + 5,
+			},
+			wantFail: true,
+		},
 		{
 			name: "Incomplete data",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
+
 				1,
 				1, 2, 3,
 			},
diff --git a/protocols/bmp/packet/peer_up.go b/protocols/bmp/packet/peer_up.go
index 8675fdc92f0f88b4d68941aca28bd510f8add28d..58adc4cc5e6cd294c88758333f6aa26c214f46b0 100644
--- a/protocols/bmp/packet/peer_up.go
+++ b/protocols/bmp/packet/peer_up.go
@@ -8,12 +8,14 @@ import (
 )
 
 const (
+	// OpenMsgMinLen is the minimal length of a BGP open message
 	OpenMsgMinLen = 10
 )
 
 // PeerUpNotification represents a peer up notification
 type PeerUpNotification struct {
 	CommonHeader    *CommonHeader
+	PerPeerHeader   *PerPeerHeader
 	LocalAddress    [16]byte
 	LocalPort       uint16
 	RemotePort      uint16
@@ -28,7 +30,16 @@ func (p *PeerUpNotification) MsgType() uint8 {
 }
 
 func decodePeerUpNotification(buf *bytes.Buffer, ch *CommonHeader) (*PeerUpNotification, error) {
-	p := &PeerUpNotification{}
+	p := &PeerUpNotification{
+		CommonHeader: ch,
+	}
+
+	pph, err := decodePerPeerHeader(buf)
+	if err != nil {
+		return nil, fmt.Errorf("Unable to decode per peer header: %v", err)
+	}
+
+	p.PerPeerHeader = pph
 
 	fields := []interface{}{
 		&p.LocalAddress,
@@ -36,7 +47,7 @@ func decodePeerUpNotification(buf *bytes.Buffer, ch *CommonHeader) (*PeerUpNotif
 		&p.RemotePort,
 	}
 
-	err := decoder.Decode(buf, fields)
+	err = decoder.Decode(buf, fields)
 	if err != nil {
 		return nil, err
 	}
diff --git a/protocols/bmp/packet/peer_up_test.go b/protocols/bmp/packet/peer_up_test.go
index 6f7578fb899163c4e45c99ab41e200bfd905f45a..d29ec7550cc757ee8e3332d1de69509e590948bd 100644
--- a/protocols/bmp/packet/peer_up_test.go
+++ b/protocols/bmp/packet/peer_up_test.go
@@ -29,6 +29,15 @@ func TestDecodePeerUp(t *testing.T) {
 		{
 			name: "Full",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
+
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 100,
 				0, 200,
@@ -55,6 +64,19 @@ func TestDecodePeerUp(t *testing.T) {
 			},
 			wantFail: false,
 			expected: &PeerUpNotification{
+				CommonHeader: &CommonHeader{
+					MsgLength: 47,
+				},
+				PerPeerHeader: &PerPeerHeader{
+					PeerType:              1,
+					PeerFlags:             2,
+					PeerDistinguisher:     3,
+					PeerAddress:           [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+					PeerAS:                51324,
+					PeerBGPID:             123,
+					Timestamp:             100,
+					TimestampMicroSeconds: 200,
+				},
 				LocalAddress: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
 				LocalPort:    100,
 				RemotePort:   200,
@@ -82,6 +104,15 @@ func TestDecodePeerUp(t *testing.T) {
 		{
 			name: "Full #2",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
+
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 100,
 				0, 200,
@@ -106,6 +137,19 @@ func TestDecodePeerUp(t *testing.T) {
 			},
 			wantFail: false,
 			expected: &PeerUpNotification{
+				CommonHeader: &CommonHeader{
+					MsgLength: 44,
+				},
+				PerPeerHeader: &PerPeerHeader{
+					PeerType:              1,
+					PeerFlags:             2,
+					PeerDistinguisher:     3,
+					PeerAddress:           [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
+					PeerAS:                51324,
+					PeerBGPID:             123,
+					Timestamp:             100,
+					TimestampMicroSeconds: 200,
+				},
 				LocalAddress: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
 				LocalPort:    100,
 				RemotePort:   200,
@@ -127,9 +171,33 @@ func TestDecodePeerUp(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "Incomplete #0",
+			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0,
+			},
+			ch: &CommonHeader{
+				MsgLength: 47,
+			},
+			wantFail: true,
+		},
 		{
 			name: "Incomplete #1",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
+
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 100,
 			},
@@ -141,6 +209,15 @@ func TestDecodePeerUp(t *testing.T) {
 		{
 			name: "Incomplete #2",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
+
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 100,
 				0, 200,
@@ -158,6 +235,14 @@ func TestDecodePeerUp(t *testing.T) {
 		{
 			name: "Incomplete #3",
 			input: []byte{
+				1,
+				2,
+				0, 0, 0, 3,
+				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+				0, 0, 200, 124,
+				0, 0, 0, 123,
+				0, 0, 0, 100,
+				0, 0, 0, 200,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 				0, 100,
 				0, 200,
diff --git a/protocols/bmp/packet/termination_message.go b/protocols/bmp/packet/termination_message.go
index 8bf69afe3315ce38b26a4512f0ffc851c8a24af6..8021fbebacfce9b8f642c2493fedd39acc9a45f6 100644
--- a/protocols/bmp/packet/termination_message.go
+++ b/protocols/bmp/packet/termination_message.go
@@ -18,7 +18,8 @@ func (t *TerminationMessage) MsgType() uint8 {
 
 func decodeTerminationMessage(buf *bytes.Buffer, ch *CommonHeader) (*TerminationMessage, error) {
 	tm := &TerminationMessage{
-		TLVs: make([]*InformationTLV, 0, 2),
+		CommonHeader: ch,
+		TLVs:         make([]*InformationTLV, 0, 2),
 	}
 
 	read := uint32(0)