0

I am working with bgp implementation on ubuntu. I want to do some malformation in bgp packets , bgp restrict us on size between 19 to 4096 , however for testing purpose I am changing the size less than 19 and greater than 4096. After this when I send this packet from one to second, on established bgp session between two speakers, second one should send notification message containing error: bad message length. But I am not getting that rather it is showing malformed packet in wireshark and also I am not able to open that packet in wireshark. Can anybody help me in this malformation of packet and to get notification error.

Just for information: I have tried every packets like open, update and keepalive. malformed open packet:

PrakashG
  • 1,642
  • 5
  • 20
  • 30

1 Answers1

0

UPDATED ANSWER BELOW

The BGP packet shown in Wireshark has marker field (16 x ff) followed by length 16 (00 10).

Thus, this is indeed the scenario that you wanted to test: your tester BGP speaker sent a BGP packet with an incorrect length, and the remote BGP speaker under test should respond by sending back a NOTIFICATION packet with error code "Message Header Error" and error sub-code "Bad Message Length".

Wireshark is showing the malformed BGP packet that was sent from the tester BGP speaker to the BGP speaker under test. Wireshark is correct to complain that it is a malformed BGP packet: it is malformed because the length is invalid. Evidently, Wireshark is not very specific about what it doesn't like about the packet.

You should look in the TCP stream in the reverse direction (source 10.0.0.2 destination 10.0.0.1) and look for the BGP NOTIFICATION packet that the BGP speaker under test sent back.

UPDATED ANSWER STARTS HERE

Based on the error message ([Error] bgp_read_packet error: Connection reset), it looks like you are testing Free Range Routing, or one of its predecessors Quagga or Zebra.

I reproduced the scenario you are testing.

I am running a Free Range Routing (FRR) BGP speaker with the following configuration:

Current configuration:
!
frr version 7.1-dev-MyOwnFRRVersion
frr defaults traditional
hostname ip-172-31-31-121
log file /var/log/frr/debug.log
log syslog
service integrated-vtysh-config
!
debug bgp neighbor-events
!
router bgp 100
 neighbor X.X.X.X remote-as 200   
!
line vty
!
end

I use the following Python test program to send a message with a "too short" header:

#!/usr/bin/env python3

import socket

BGP_IP = 'Y.Y.Y.Y'

SHORT_MSG = (b'\xff\xff\xff\xff\xff\xff\xff\xff'     # First 8 bytes of marker
             b'\xff\xff\xff\xff\xff\xff\xff\xff'     # Last 8 bytes of marker
             b'\x00\x10'                             # Length 16
             b'\x01')                                # Open

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created")
    sock.connect((BGP_IP, 179))
    print("Socket connected")
    sock.send(SHORT_MSG)
    print("Short message sent")
    while True:
        data = sock.recv(1)
        if data == b'':
            print("Connection closed or reset")
            break
        print("Received:", data)

if __name__ == "__main__":
    main()

Replace X.X.X.X with the IP address of the tester, and replace Y.Y.Y.Y with the IP address of the BGP speaker under test.

In this scenario, the BGP speaker under test does indeed send the correct NOTIFICATION message.

Here is what the FRR log reports:

2019/02/09 21:49:05 BGP: 172.31.17.121 [FSM] Timer (connect timer expire)
2019/02/09 21:49:05 BGP: 172.31.17.121 [FSM] ConnectRetry_timer_expired (Active->Connect), fd -1
2019/02/09 21:49:05 BGP: 172.31.17.121 [Event] Connect start to 172.31.17.121 fd 26
2019/02/09 21:49:05 BGP: 172.31.17.121 [FSM] Non blocking connect waiting result, fd 26
2019/02/09 21:49:05 BGP: bgp_fsm_change_status : vrf 0, established_peers 0
2019/02/09 21:49:05 BGP: 172.31.17.121 went from Active to Connect
2019/02/09 21:49:05 BGP: 172.31.17.121 [Event] Connect failed 111(Connection refused)
2019/02/09 21:49:05 BGP: 172.31.17.121 [FSM] TCP_connection_open_failed (Connect->Active), fd 26
2019/02/09 21:49:05 BGP: bgp_fsm_change_status : vrf 0, established_peers 0
2019/02/09 21:49:05 BGP: 172.31.17.121 went from Connect to Active
2019/02/09 21:49:08 BGP: [Event] BGP connection from host 172.31.17.121 fd 26
2019/02/09 21:49:08 BGP: bgp_fsm_change_status : vrf 0, established_peers 0
2019/02/09 21:49:08 BGP: 172.31.17.121 went from Idle to Active
2019/02/09 21:49:08 BGP: 172.31.17.121 [FSM] TCP_connection_open (Active->OpenSent), fd 26
2019/02/09 21:49:08 BGP: 172.31.17.121 passive open
2019/02/09 21:49:08 BGP: 172.31.17.121 Sending hostname cap with hn = ip-172-31-31-121, dn = (null)
2019/02/09 21:49:08 BGP: 172.31.17.121 sending OPEN, version 4, my as 100, holdtime 180, id 172.31.31.121
2019/02/09 21:49:08 BGP: bgp_fsm_change_status : vrf 0, established_peers 0
2019/02/09 21:49:08 BGP: 172.31.17.121 went from Active to OpenSent
2019/02/09 21:49:08 BGP: 172.31.17.121 bad message length - 16 for OPEN
2019/02/09 21:49:08 BGP: %NOTIFICATION: sent to neighbor 172.31.17.121 1/2 (Message Header Error/Bad Message Length) 2 bytes 00 10
2019/02/09 21:49:08 BGP: 172.31.17.121 [FSM] BGP_Stop (OpenSent->Idle), fd 26
2019/02/09 21:49:08 BGP: bgp_fsm_change_status : vrf 0, established_peers 0
2019/02/09 21:49:08 BGP: 172.31.17.121 went from OpenSent to Deleted

Note the "Bad Message Length" message.

Here is what the test program reports:

Socket created
Socket connected
Short message sent
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\xff'
Received: b'\x00'
Received: b'\x17'
Received: b'\x03'
Received: b'\x01'
Received: b'\x02'
Received: b'\x00'
Received: b'\x10'
Connection closed or reset

Note that this is the correct Bad Message Length NOTIFICATION.

Here is the Wireshark decode of the bad message:

enter image description here

Here is the Wireshark decode of the NOTIFICATION:

enter image description here

If the test program terminates without attempting to read the NOTIFICATION message, then the BGP speaker under test will not be able to send the NOTIFICATION message on the wire. This is because it will receive a TCP RST message before it is able to send the NOTIFICATION. This is most likely why you did not see the NOTIFICATION on the wire.

Indeed, I was able to reproduce this hypothesis by modifying the test program as follows:

#!/usr/bin/env python3

import socket
import struct

BGP_IP = '172.31.31.121'

SHORT_MSG = (b'\xff\xff\xff\xff\xff\xff\xff\xff'     # First 8 bytes of marker
             b'\xff\xff\xff\xff\xff\xff\xff\xff'     # Last 8 bytes of marker
             b'\x00\x10'                             # Length 16
             b'\x01')                                # Open

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created")
    sock.connect((BGP_IP, 179))
    print("Socket connected")
    sock.send(SHORT_MSG)
    # Trick TCP into sending a RST when the socket is closed
    on_off = 1
    linger = 0
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', on_off, linger))
    print("Socket linger time set to 0")
    # Close the socket
    sock.close()
    print("Socket closed")
    # Terminate without reading the response NOTIFICATION

if __name__ == "__main__":
    main()

Using this test program, the NOTIFICATION is missing from the Wireshark trace (exactly as you reported it):

enter image description here

Note that I had to jump through some hoops (specifically setting the linger time to zero) to force the test program to send a RST as opposed to a FIN ACK. (See Sending a reset in TCP/IP Socket connection for details.)

If the test program sends a FIN ACK instead of a RST (which happens if you gracefully close the socket, or even terminate normally without closing the socket), then the BGP speaker under test will be able to send the NOTIFICATION after receiving the FIN ACK but before sending its own FIN ACK.

Bruno Rijsman
  • 3,715
  • 4
  • 31
  • 61
  • hey thanks for the help , as you said i checked the tcpdump on one who sent the packet but there also it is having same result. and it is understandable coz whichever packets are being sent or received at the particular interface, all the entries will be captured there ( as we are capturing at receiver side all the entries are being captured there). however as per your guidance i captured at the sender side also but getting same results. – dharmendra kariya Jan 31 '19 at 07:21
  • If you see the malformed packet (the one with length 16) in the tcpdump, but you don't see the NOTIFICATION from the other side in the tcpdump, and you are sure that you are capturing traffic in both directions, then the logical conclusion would be that the BGP implementation under test contains a bug and is not sending a NOTIFICATION in this test case. Can you turn on logging on the BGP implementation under test and see what it says? – Bruno Rijsman Feb 01 '19 at 19:47
  • yes, once when i sent malformed keepalive (length 16) message from Router-A to Router-B , i got something at A's and B's tcpdump stating "[|BGP Bogus header length 16 < 19]" but not getting any notification. as per your guidance i checked logs on both the sides and i got "[Error] bgp_read_packet error: Connection reset" whenever i sent that malformed packet. – dharmendra kariya Feb 04 '19 at 06:54
  • thank you so much for the help . and also i want to know that is this a bug!!??, coz it it is not performing task as it supposed to do. or you can raise issue about this also i guess. – dharmendra kariya Feb 13 '19 at 05:48
  • Based on the data that you provided, I don't see any evidence that there is a bug in the BGP under implementation. I suspect that the bug is in the test code that your wrote; I suspect that it contains some logic causing a RST to be sent before the BGP implementation under test has a chance to send the NOTIFICATION back. – Bruno Rijsman Feb 18 '19 at 02:40
  • Just to let you know ,I didnt write any code , i just set bgp implementation with quagga and i was just sending malformed packet stored in pcap file , may be implementation has some issue but I don't know what. And one more thing is based on your solution i am not able to send malformed update packet ( i am testing erroe : 'Optional Attribute Error' ), i wrote one more question on that – dharmendra kariya Feb 18 '19 at 03:13
  • What method do you use the send the pcap file? For example, do you use netcat? – Bruno Rijsman Feb 18 '19 at 08:55