Browse Source

messages: implement top level message decode

William Pitcock 3 years ago
parent
commit
590d2f2320
1 changed files with 28 additions and 4 deletions
  1. 28
    4
      aiobgp/messages.py

+ 28
- 4
aiobgp/messages.py View File

@@ -29,7 +29,10 @@ BGP_MESSAGE_MARKER = b'\xff' * 16
29 29
 class BGPMessage:
30 30
     """The BGPMessage class provides an abstract view of a BGP message, given a collection of bytes.  It
31 31
     also handles rendering a message back to a collection of bytes, through the ``encode()`` function.  Messages
32
-    are decoded via the ``decode()`` function."""
32
+    are decoded via the ``decode()`` function.
33
+
34
+    To implement a message, one should subclass the BGPMessage class and subclass the ``encode()`` and ``decode()``
35
+    methods."""
33 36
     __messagetype__ = BGP_MESSAGE_NIL
34 37
     def __init__(self):
35 38
         self.length = BGP_MESSAGE_HEADERLEN
@@ -46,7 +49,7 @@ class BGPMessage:
46 49
 
47 50
     @staticmethod
48 51
     def decode_header(data):
49
-        if len(data) < 19:
52
+        if len(data) < BGP_MESSAGE_HEADERLEN:
50 53
             return None
51 54
 
52 55
         length, msg_type = struct.unpack_from('!HB', data, offset=16)
@@ -54,7 +57,7 @@ class BGPMessage:
54 57
 
55 58
     @classmethod
56 59
     def decode(cls, data):
57
-        if len(data) < 19:
60
+        if len(data) < BGP_MESSAGE_HEADERLEN:
58 61
             return None
59 62
 
60 63
         header = BGPMessage.decode_header(data)
@@ -86,7 +89,7 @@ class KeepAliveMessage(BGPMessage):
86 89
     __messagetype__ = BGP_MESSAGE_KEEPALIVE
87 90
 
88 91
 
89
-message_types = {
92
+bgp_message_types = {
90 93
     BGP_MESSAGE_OPEN: OpenMessage,
91 94
     BGP_MESSAGE_UPDATE: UpdateMessage,
92 95
     BGP_MESSAGE_NOTIFICATION: NotificationMessage,
@@ -94,6 +97,27 @@ message_types = {
94 97
 }
95 98
 
96 99
 
100
+def bgp_read_message(data):
101
+    """Read in a message from a buffer.  If sufficient data is available, return a BGPMessage object
102
+    representing the message as well as the amount of data consumed as a tuple.  The caller should then
103
+    advance their buffer by the amount of data consumed.  Otherwise, it returns None plus the message data
104
+    that should be consumed."""
105
+    global bgp_message_types
106
+
107
+    if len(data) < BGP_MESSAGE_HEADERLEN:
108
+        return (None, 0)
109
+
110
+    header = BGPMessage.decode(data[0:BGP_MESSAGE_HEADERLEN])
111
+    if len(data) < header.length:
112
+        return (None, 0)
113
+
114
+    msgclass = bgp_message_types.get(header.msg_type, None)
115
+    if not msgclass:
116
+        return (None, header.length)
117
+
118
+    return (msgclass.decode(data[0:header.length]), header.length)
119
+
120
+
97 121
 if __name__ == '__main__':
98 122
     print(repr(KeepAliveMessage()))
99 123
     print(repr(KeepAliveMessage().encode()))