1212from scapy .compat import chb
1313from scapy .packet import Packet , bind_layers
1414from scapy .fields import BitField , ByteEnumField , ByteField , FieldLenField , \
15- IPField , ShortField , StrLenField , XByteField , XShortField
15+ IPField , IntField , ShortField , StrLenField , XByteField , XShortField
1616from scapy .layers .inet import IP , checksum
1717
1818rsvpmsgtypes = {0x01 : "Path" ,
2626
2727
2828class RSVP (Packet ):
29+ """Common RSVP message header. The header is followed by this message's objects,
30+ which chains to further RSVP_Object instances, forming the sequence of RSVP objects.
31+ """
2932 name = "RSVP"
3033 fields_desc = [BitField ("Version" , 1 , 4 ),
3134 BitField ("Flags" , 1 , 4 ),
@@ -36,6 +39,9 @@ class RSVP(Packet):
3639 ShortField ("Length" , None )]
3740
3841 def post_build (self , p , pay ):
42+ """Append payload bytes to the header, and patch in Length/checksum if unset.
43+ Returns the fully packet message bytes.
44+ """
3945 p += pay
4046 if self .Length is None :
4147 tmp_len = len (p )
@@ -47,7 +53,7 @@ def post_build(self, p, pay):
4753 return p
4854
4955
50- rsvptypes = {0x01 : "Session " ,
56+ rsvptypes = {0x01 : "SESSION " ,
5157 0x03 : "HOP" ,
5258 0x04 : "INTEGRITY" ,
5359 0x05 : "TIME_VALUES" ,
@@ -126,13 +132,22 @@ def post_build(self, p, pay):
126132
127133
128134class RSVP_Object (Packet ):
135+ """Common RSVP object header. Followed by exactly one RSVP object data structure,
136+ Dissection naturally chains into the next object if more bytes remain.
137+ """
129138 name = "RSVP_Object"
130139 fields_desc = [ShortField ("Length" , 4 ),
131140 ByteEnumField ("Class" , 0x01 , rsvptypes ),
132141 ByteField ("C_Type" , 1 )]
133142
134143 def guess_payload_class (self , payload ):
135- if self .Class == 0x03 :
144+ """Pick the data class to dissect based on Class.
145+ Falls back to a generic container.
146+ """
147+ if self .Class == 0x01 :
148+ if self .C_Type == 0x07 :
149+ return RSVP_SESSION
150+ elif self .Class == 0x03 :
136151 return RSVP_HOP
137152 elif self .Class == 0x05 :
138153 return RSVP_Time
@@ -147,49 +162,95 @@ def guess_payload_class(self, payload):
147162
148163
149164class RSVP_Data (Packet ):
165+ """Defines a generic/unknown RSVP object data structure for any Class value
166+ that doesn't have a dedicated class implemented yet.
167+ """
150168 name = "Data"
151169 overload_fields = {RSVP_Object : {"Class" : 0x01 }}
152- fields_desc = [StrLenField ("Data" , "" , length_from = lambda pkt :pkt .underlayer .Length - 4 )] # noqa: E501
170+ fields_desc = [
171+ StrLenField (
172+ "Data" ,
173+ "" ,
174+ length_from = lambda pkt : pkt .underlayer .Length - 4
175+ ),
176+ ]
177+
178+ def default_payload_class (self , payload ):
179+ return RSVP_Object
180+
181+
182+ class RSVP_SESSION (Packet ):
183+ """SESSION LSP_TUNNEL_IPV4 object data structure, RFC 3209 section 4.6.1.1.
184+ Identifies the session for which this message is sent.
185+ """
186+ name = "SESSION"
187+ overload_fields = {RSVP_Object : {"Class" : 0x01 , "C_Type" : 0x07 }}
188+ fields_desc = [IPField ("dest_addr" , "0.0.0.0" ),
189+ ShortField ("reserved" , 0 ),
190+ ShortField ("tunnel_id" , 0 ),
191+ IPField ("ext_tunnel_id" , "0.0.0.0" )]
153192
154193 def default_payload_class (self , payload ):
155194 return RSVP_Object
156195
157196
158197class RSVP_HOP (Packet ):
198+ """RSVP_HOP object data structure, RFC 2205 section A.2.
199+ Identifies the IP address and the Logical Interface Handle (LIH)
200+ of the interface this message was sent from.
201+ """
159202 name = "HOP"
160203 overload_fields = {RSVP_Object : {"Class" : 0x03 }}
161204 fields_desc = [IPField ("neighbor" , "0.0.0.0" ),
162- BitField ("inface" , 1 , 32 )]
205+ IntField ("inface" , 1 )]
163206
164207 def default_payload_class (self , payload ):
165208 return RSVP_Object
166209
167210
168211class RSVP_Time (Packet ):
212+ """TIME_VALUES object RFC 2205 section A.4.
213+ Carries the refresh period a sender will use to resend PATH/RESV messages,
214+ which the receiver can use to determine when to tear down
215+ the reservation if no further messages are received.
216+ """
169217 name = "Time Val"
170218 overload_fields = {RSVP_Object : {"Class" : 0x05 }}
171- fields_desc = [BitField ("refresh" , 1 , 32 )]
219+ fields_desc = [IntField ("refresh" , 1 )]
172220
173221 def default_payload_class (self , payload ):
174222 return RSVP_Object
175223
176224
177225class RSVP_SenderTSPEC (Packet ):
226+ """SENDER_TSPEC object RFC 2210 section 3.1.
227+ Carries the sender's traffic specification for the reservation.
228+ """
178229 name = "Sender_TSPEC"
179230 overload_fields = {RSVP_Object : {"Class" : 0x0c }}
180- fields_desc = [ByteField ("Msg_Format" , 0 ),
181- ByteField ("reserve" , 0 ),
182- ShortField ("Data_Length" , 4 ),
183- ByteField ("Srv_hdr" , 1 ),
184- ByteField ("reserve2" , 0 ),
185- ShortField ("Srv_Length" , 4 ),
186- StrLenField ("Tokens" , "" , length_from = lambda pkt :pkt .underlayer .Length - 12 )] # noqa: E501
231+ fields_desc = [
232+ ByteField ("Msg_Format" , 0 ),
233+ ByteField ("reserve" , 0 ),
234+ ShortField ("Data_Length" , 4 ),
235+ ByteField ("Srv_hdr" , 1 ),
236+ ByteField ("reserve2" , 0 ),
237+ ShortField ("Srv_Length" , 4 ),
238+ StrLenField (
239+ "Tokens" ,
240+ "" ,
241+ length_from = lambda pkt : pkt .underlayer .Length - 12
242+ ),
243+ ]
187244
188245 def default_payload_class (self , payload ):
189246 return RSVP_Object
190247
191248
192249class RSVP_LabelReq (Packet ):
250+ """LABEL_REQUEST object RFC 3209 section 4.2.
251+ Requests that a label be allocated for this LSP, and indicates
252+ which layer 3 protocol the label will carry.
253+ """
193254 name = "Label Req"
194255 overload_fields = {RSVP_Object : {"Class" : 0x13 }}
195256 fields_desc = [ShortField ("reserve" , 1 ),
@@ -200,18 +261,29 @@ def default_payload_class(self, payload):
200261
201262
202263class RSVP_SessionAttrb (Packet ):
264+ """SESSION_ATTRIBUTE object RFC 3209 section 4.7.
265+ Carries session data, mainly used for setup/recovery
266+ priority and human readable session name.
267+ """
203268 name = "Session_Attribute"
204269 overload_fields = {RSVP_Object : {"Class" : 0xCF }}
205- fields_desc = [ByteField ("Setup_priority" , 1 ),
206- ByteField ("Hold_priority" , 1 ),
207- ByteField ("flags" , 1 ),
208- FieldLenField ("Name_length" , None , length_of = "Name" ),
209- StrLenField ("Name" , "" , length_from = lambda pkt :pkt .Name_length ), # noqa: E501
210- ]
270+ fields_desc = [
271+ ByteField ("Setup_priority" , 1 ),
272+ ByteField ("Hold_priority" , 1 ),
273+ ByteField ("flags" , 1 ),
274+ FieldLenField ("Name_length" , None , length_of = "Name" ),
275+ StrLenField (
276+ "Name" ,
277+ "" ,
278+ length_from = lambda pkt : pkt .Name_length
279+ ),
280+ ]
211281
212282 def default_payload_class (self , payload ):
213283 return RSVP_Object
214284
215285
286+ # Decode IP packets with protocol number 46 as RSVP packets,
287+ # and RSVP packets as RSVP_Object packets.
216288bind_layers (IP , RSVP , {"proto" : 46 })
217289bind_layers (RSVP , RSVP_Object )
0 commit comments