A packet parse bug that causes wrong value for `My AS` field
grandnew opened this issue · 1 comments
There is a parse bug in gobgp.
The config of the under-test node is as follows, and its IP is 10.0.255.6
[global.config]
as = 65001
router-id = "192.168.10.6"
[[neighbors]]
[neighbors.config]
neighbor-address = "10.0.255.5"
peer-as = 64512
Send an OPEN packet to this node on the host 10.0.255.5
using the following script:
import socket
from time import sleep
payload = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00;\x01\x04\xfc\x00\x00\x05\xc0\xa8\n\x05\x1e\x02\x1c\x01\x04\x00\x01\x00\x01\x02\x00@\x02\x00xA\x04\x00\x00\x00\x02F\x00G\x06\x00\x01\x01\x01\x00x'
s = socket.socket(type=socket.SOCK_STREAM)
s.connect(("10.0.255.6", 179))
s.send(payload)
sleep(1)
s.close()
Then, the logs of the under-test node (with IP 10.0.255.6
) are as follows.
{"level":"info","msg":"gobgpd started","time":"2023-10-21T12:56:25Z"}
{"Topic":"Config","level":"info","msg":"Finished reading the config file","time":"2023-10-21T12:56:25Z"}
{"Key":"10.0.255.5","Topic":"config","level":"info","msg":"Add Peer","time":"2023-10-21T12:56:25Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"info","msg":"Add a peer configuration","time":"2023-10-21T12:56:25Z"}
{"Duration":0,"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"IdleHoldTimer expired","time":"2023-10-21T12:56:25Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_ACTIVE","old":"BGP_FSM_IDLE","reason":{"Type":7,"BGPNotification":null,"Data":null},"time":"2023-10-21T12:56:25Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"try to connect","time":"2023-10-21T12:56:30Z"}
{"Error":"dial tcp 0.0.0.0:0-\u003e10.0.255.5:179: connect: connection refused","Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"failed to connect","time":"2023-10-21T12:56:30Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"Accepted a new passive connection","time":"2023-10-21T12:56:35Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"stop connect loop","time":"2023-10-21T12:56:35Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_OPENSENT","old":"BGP_FSM_ACTIVE","reason":{"Type":11,"BGPNotification":null,"Data":null},"time":"2023-10-21T12:56:35Z"}
{"Data":"as number mismatch expected 64512, received 2","Key":"10.0.255.5","Topic":"Peer","level":"warning","msg":"sent notification","time":"2023-10-21T12:56:35Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_IDLE","old":"BGP_FSM_OPENSENT","reason":{"Type":10,"BGPNotification":{"Header":{"Marker":null,"Len":21,"Type":3},"Body":{"ErrorCode":2,"ErrorSubcode":2,"Data":null}},"Data":null},"time":"2023-10-21T12:56:35Z"}
{"Duration":5,"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"IdleHoldTimer expired","time":"2023-10-21T12:56:40Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_ACTIVE","old":"BGP_FSM_IDLE","reason":{"Type":7,"BGPNotification":null,"Data":null},"time":"2023-10-21T12:56:40Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"try to connect","time":"2023-10-21T12:56:45Z"}
The logs indicate that the My AS
field is parsed as 2 instead of 64512 (the line with content {"Data":"as number mismatch expected 64512, received 2","Key":"10.0.255.5","Topic":"Peer","level":"warning","msg":"sent notification","time":"2023-10-21T12:56:35Z"}
)
However, the parse results of the wireshark indicate that the My AS
field is 64512, as shown in the sixth packet in BGP_parse_bug.pcap.zip.
Besides, the parse results of scapy also align with that of wireshark:
from scapy.all import *
from scapy.contrib.bgp import BGP
payload = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00;\x01\x04\xfc\x00\x00\x05\xc0\xa8\n\x05\x1e\x02\x1c\x01\x04\x00\x01\x00\x01\x02\x00@\x02\x00xA\x04\x00\x00\x00\x02F\x00G\x06\x00\x01\x01\x01\x00x'
bgp=BGP(payload)
bgp.show()
The output is:
###[ HEADER ]###
marker = 0xffffffffffffffffffffffffffffffff
len = 59
type = OPEN
###[ OPEN ]###
version = 4
my_as = 64512
hold_time = 5
bgp_id = 192.168.10.5
opt_param_len= 30
\opt_params\
|###[ Optional parameter ]###
| param_type= Capabilities
| param_length= 28
| \param_value\
| |###[ Multiprotocol Extensions for BGP-4 ]###
| | code = Multiprotocol Extensions for BGP-4
| | length = 4
| | afi = IP (IP version 4)
| | reserved = 0
| | safi = Network Layer Reachability Information used for unicast forwarding
| |###[ Raw ]###
| | load = '\x02\x00@\x02\x00xA\x04\x00\x00\x00\x02F\x00G\x06\x00\x01\x01\x01\x00x'