diff --git a/protocols/bgp/packet/bgp.go b/protocols/bgp/packet/bgp.go
index 622b46f37b115dd27779a285284d177d75695230..8082f5dd8c02ae2c74a23013bcdb4c63d524d52b 100644
--- a/protocols/bgp/packet/bgp.go
+++ b/protocols/bgp/packet/bgp.go
@@ -92,9 +92,11 @@ const (
 	UnicastSAFI           = 1
 	CapabilitiesParamType = 2
 	AddPathCapabilityCode = 69
+	ASN4CapabilityCode    = 65
 	AddPathReceive        = 1
 	AddPathSend           = 2
 	AddPathSendReceive    = 3
+	ASTransASN            = 23456
 )
 
 type BGPError struct {
@@ -119,7 +121,7 @@ type BGPHeader struct {
 
 type BGPOpen struct {
 	Version       uint8
-	AS            uint16
+	ASN           uint16
 	HoldTime      uint16
 	BGPIdentifier uint32
 	OptParmLen    uint8
diff --git a/protocols/bgp/packet/decoder.go b/protocols/bgp/packet/decoder.go
index 31583bf1b68257625dfaa3d8b8e40893982d6713..e473f3edf38c208f5726ecc3b776dbf883f61197 100644
--- a/protocols/bgp/packet/decoder.go
+++ b/protocols/bgp/packet/decoder.go
@@ -141,7 +141,7 @@ func _decodeOpenMsg(buf *bytes.Buffer) (interface{}, error) {
 
 	fields := []interface{}{
 		&msg.Version,
-		&msg.AS,
+		&msg.ASN,
 		&msg.HoldTime,
 		&msg.BGPIdentifier,
 		&msg.OptParmLen,
diff --git a/protocols/bgp/packet/decoder_test.go b/protocols/bgp/packet/decoder_test.go
index a9ae237b9cb94a3e0ec6af0b988bc09f41d3f806..916660a3dd06e08b23d29ea4a8c48fb63ed68b47 100644
--- a/protocols/bgp/packet/decoder_test.go
+++ b/protocols/bgp/packet/decoder_test.go
@@ -156,7 +156,7 @@ func TestDecode(t *testing.T) {
 				},
 				Body: &BGPOpen{
 					Version:       4,
-					AS:            200,
+					ASN:           200,
 					HoldTime:      15,
 					BGPIdentifier: uint32(169090600),
 					OptParmLen:    0,
@@ -184,7 +184,7 @@ func TestDecode(t *testing.T) {
 				},
 				Body: &BGPOpen{
 					Version:       4,
-					AS:            200,
+					ASN:           200,
 					HoldTime:      15,
 					BGPIdentifier: uint32(100),
 				},
@@ -1512,7 +1512,7 @@ func TestDecodeOpenMsg(t *testing.T) {
 			wantFail: false,
 			expected: &BGPOpen{
 				Version:       4,
-				AS:            257,
+				ASN:           257,
 				HoldTime:      15,
 				BGPIdentifier: 169090600,
 				OptParmLen:    0,
diff --git a/protocols/bgp/packet/encoder.go b/protocols/bgp/packet/encoder.go
index ea87d1ff64cfc946688e738ae9f7ffa372cf10c7..de2966bfeb404c70828a72874b7f1f6788fc974c 100644
--- a/protocols/bgp/packet/encoder.go
+++ b/protocols/bgp/packet/encoder.go
@@ -35,7 +35,7 @@ func SerializeOpenMsg(msg *BGPOpen) []byte {
 	serializeHeader(buf, openLen, OpenMsg)
 
 	buf.WriteByte(msg.Version)
-	buf.Write(convert.Uint16Byte(msg.AS))
+	buf.Write(convert.Uint16Byte(msg.ASN))
 	buf.Write(convert.Uint16Byte(msg.HoldTime))
 	buf.Write(convert.Uint32Byte(msg.BGPIdentifier))
 
diff --git a/protocols/bgp/packet/parameters.go b/protocols/bgp/packet/parameters.go
index 8edf42fc58e05bb3b73cacd4272012844bedcd45..0ed9af66fe01f96600c02eeb2c00b69b11edc76c 100644
--- a/protocols/bgp/packet/parameters.go
+++ b/protocols/bgp/packet/parameters.go
@@ -52,3 +52,11 @@ func (a AddPathCapability) serialize(buf *bytes.Buffer) {
 	buf.WriteByte(a.SAFI)
 	buf.WriteByte(a.SendReceive)
 }
+
+type ASN4Capability struct {
+	ASN4 uint32
+}
+
+func (a ASN4Capability) serialize(buf *bytes.Buffer) {
+	buf.Write(convert.Uint32Byte(a.ASN4))
+}
diff --git a/protocols/bgp/server/fsm2.go b/protocols/bgp/server/fsm2.go
index 6e1682c71b7aaf47ff2858a30b199fc07cb43297..9b8163ab22dd53966f4efb25c38e1bfd7b826451 100644
--- a/protocols/bgp/server/fsm2.go
+++ b/protocols/bgp/server/fsm2.go
@@ -221,7 +221,7 @@ func (fsm *FSM) resetConnectRetryCounter() {
 func (fsm *FSM) sendOpen() error {
 	msg := packet.SerializeOpenMsg(&packet.BGPOpen{
 		Version:       BGPVersion,
-		AS:            uint16(fsm.peer.localASN),
+		ASN:           uint16(fsm.peer.localASN),
 		HoldTime:      uint16(fsm.peer.holdTime / time.Second),
 		BGPIdentifier: fsm.peer.server.routerID,
 		OptParams:     fsm.peer.optOpenParams,
diff --git a/protocols/bgp/server/fsm_open_sent.go b/protocols/bgp/server/fsm_open_sent.go
index 63680636d8e0c65afe1dad9ec9d1280c34e9c37d..aba1193dd9b75010e50a3d4e2de932e9bc87647e 100644
--- a/protocols/bgp/server/fsm_open_sent.go
+++ b/protocols/bgp/server/fsm_open_sent.go
@@ -10,7 +10,8 @@ import (
 )
 
 type openSentState struct {
-	fsm *FSM
+	fsm         *FSM
+	peerASNRcvd uint32
 }
 
 func newOpenSentState(fsm *FSM) *openSentState {
@@ -104,6 +105,8 @@ func (s *openSentState) unexpectedMessage() (state, string) {
 
 func (s *openSentState) openMsgReceived(msg *packet.BGPMessage) (state, string) {
 	openMsg := msg.Body.(*packet.BGPOpen)
+	s.peerASNRcvd = uint32(openMsg.ASN)
+
 	s.fsm.neighborID = openMsg.BGPIdentifier
 	stopTimer(s.fsm.connectRetryTimer)
 	if s.fsm.peer.collisionHandling(s.fsm) {
@@ -114,6 +117,10 @@ func (s *openSentState) openMsgReceived(msg *packet.BGPMessage) (state, string)
 		return s.tcpFailure()
 	}
 
+	return s.handleOpenMessage(openMsg)
+}
+
+func (s *openSentState) handleOpenMessage(openMsg *packet.BGPOpen) (state, string) {
 	s.fsm.holdTime = time.Duration(math.Min(float64(s.fsm.peer.holdTime), float64(time.Duration(openMsg.HoldTime)*time.Second)))
 	if s.fsm.holdTime != 0 {
 		if !s.fsm.holdTimer.Reset(s.fsm.holdTime) {
@@ -123,7 +130,13 @@ func (s *openSentState) openMsgReceived(msg *packet.BGPMessage) (state, string)
 		s.fsm.keepaliveTimer = time.NewTimer(s.fsm.keepaliveTime)
 	}
 
+	s.peerASNRcvd = uint32(openMsg.ASN)
 	s.processOpenOptions(openMsg.OptParams)
+
+	if s.peerASNRcvd != s.fsm.peer.peerASN {
+		return newCeaseState(), fmt.Sprintf("Expected session from %d, got open message with ASN %d", s.fsm.peer.peerASN, s.peerASNRcvd)
+	}
+
 	return newOpenConfirmState(s.fsm), "Received OPEN message"
 }
 
@@ -153,7 +166,8 @@ func (s *openSentState) processCapability(cap packet.Capability) {
 	switch cap.Code {
 	case packet.AddPathCapabilityCode:
 		s.processAddPathCapability(cap.Value.(packet.AddPathCapability))
-
+	case packet.ASN4CapabilityCode:
+		s.processASN4Capability(cap.Value.(packet.ASN4Capability))
 	}
 }
 
@@ -184,6 +198,12 @@ func (s *openSentState) processAddPathCapability(addPathCap packet.AddPathCapabi
 	}
 }
 
+func (s *openSentState) processASN4Capability(cap packet.ASN4Capability) {
+	if s.peerASNRcvd == packet.ASTransASN {
+		s.peerASNRcvd = cap.ASN4
+	}
+}
+
 func (s *openSentState) notification(msg *packet.BGPMessage) (state, string) {
 	stopTimer(s.fsm.connectRetryTimer)
 	s.fsm.con.Close()
diff --git a/protocols/bgp/server/fsm_open_sent_test.go b/protocols/bgp/server/fsm_open_sent_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d4f2634eac2adba7a70c9a636a8969388d0a7fc3
--- /dev/null
+++ b/protocols/bgp/server/fsm_open_sent_test.go
@@ -0,0 +1,87 @@
+package server
+
+import (
+	"testing"
+
+	"github.com/bio-routing/bio-rd/protocols/bgp/packet"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestOpenMsgReceived(t *testing.T) {
+	tests := []struct {
+		asn        uint32
+		name       string
+		msg        packet.BGPOpen
+		wantsCease bool
+	}{
+		{
+			name: "valid open message (16bit ASN)",
+			asn:  12345,
+			msg: packet.BGPOpen{
+				HoldTime:      90,
+				BGPIdentifier: 1,
+				Version:       4,
+				ASN:           12345,
+			},
+		},
+		{
+			name: "valid open message (32bit ASN)",
+			asn:  202739,
+			msg: packet.BGPOpen{
+				HoldTime:      90,
+				BGPIdentifier: 1,
+				Version:       4,
+				ASN:           23456,
+				OptParmLen:    1,
+				OptParams: []packet.OptParam{
+					{
+						Type:   packet.CapabilitiesParamType,
+						Length: 6,
+						Value: packet.Capabilities{
+							packet.Capability{
+								Code:   packet.ASN4CapabilityCode,
+								Length: 4,
+								Value: packet.ASN4Capability{
+									ASN4: 202739,
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+		{
+			name: "open message does not match configured remote ASN",
+			asn:  12345,
+			msg: packet.BGPOpen{
+				HoldTime:      90,
+				BGPIdentifier: 1,
+				Version:       4,
+				ASN:           54321,
+			},
+			wantsCease: true,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			fsm := newFSM2(&Peer{
+				peerASN: test.asn,
+			})
+
+			s := &openSentState{
+				fsm: fsm,
+			}
+
+			state, _ := s.handleOpenMessage(&test.msg)
+
+			if test.wantsCease {
+				assert.IsType(t, &ceaseState{}, state, "state")
+				return
+			}
+
+			assert.IsType(t, &openConfirmState{}, state, "state")
+			assert.Equal(t, test.asn, s.peerASNRcvd, "asn")
+		})
+	}
+}