99References : IEEE 1588-2008
1010"""
1111
12+ import struct
13+
1214from scapy .packet import Packet , bind_layers
1315from scapy .fields import (
1416 BitEnumField ,
1921 ShortField ,
2022 ByteEnumField ,
2123 FlagsField ,
22- PacketField ,
2324 XLongField ,
25+ XByteField ,
26+ ConditionalField ,
2427)
2528from scapy .layers .inet import UDP
2629
7578}
7679
7780
78- class OriginTimestamp (Packet ):
79- name = "originTimestamp"
80- fields_desc = [
81- BitField ("seconds" , 0 , 48 ),
82- IntField ("nanoseconds" , 0 )
83- ]
84-
85-
86- class PTPHeader (Packet ):
81+ class PTP (Packet ):
8782 """
88- PTP Header based on IEEE 1588-2008 / Section 13.3.
83+ PTP packet based on IEEE 1588-2008 / Section 13.3
8984 """
9085
91- ########################################################################################
92- # IEEE 1588-2008 / Section 13.3 Header / Table 18
93- ########################################################################################
94- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95- # | Bits | | |
96- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Octets | Offset |
97- # | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | |
98- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99- # | transportSpecific | messageType | 1 | 0 |
100- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101- # | reserved | versionPTP | 1 | 1 |
102- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103- # | messageLength | 2 | 2 |
104- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105- # | domainNumber | 1 | 4 |
106- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107- # | reserved | 1 | 5 |
108- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109- # | flagField | 2 | 6 |
110- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111- # | correctionField | 8 | 8 |
112- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113- # | reserved | 4 | 16 |
114- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115- # | sourcePortIdentity | 10 | 20 |
116- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117- # | sequenceId | 2 | 30 |
118- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119- # | controlField | 1 | 32 |
120- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
121- # | logMessageInterval | 1 | 33 |
122- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123- ########################################################################################
124- #
125- # sourcePortIdentity(10 bytes) contain clockIdentity(8 bytes) and portNumber(2 bytes)
126- #
127-
128- name = "PTPHeader"
86+ name = "PTP"
12987 match_subclass = True
13088 fields_desc = [
13189 BitField ("transportSpecific" , 0 , 4 ),
13290 BitEnumField ("messageType" , 0x0 , 4 , _message_type ),
13391 BitField ("reserved1" , 0 , 4 ),
13492 BitField ("version" , 2 , 4 ),
135- ShortField ("messageLength" , 0 ),
93+ ShortField ("messageLength" , None ),
13694 ByteField ("domainNumber" , 0 ),
13795 ByteField ("reserved2" , 0 ),
13896 FlagsField ("flags" , 0 , 16 , _flags ),
@@ -142,111 +100,61 @@ class PTPHeader(Packet):
142100 ShortField ("portNumber" , 0 ),
143101 ShortField ("sequenceId" , 0 ),
144102 ByteEnumField ("controlField" , 0 , _control_field ),
145- ByteField ("logMessageInterval" , 0 )
146- ]
103+ ByteField ("logMessageInterval" , 0 ),
104+ ConditionalField (BitField ("originTimestamp_seconds" , 0 , 48 ),
105+ lambda pkt : pkt .messageType in [0x0 , 0x1 , 0x2 , 0xB ]),
106+ ConditionalField (IntField ("originTimestamp_nanoseconds" , 0 ),
107+ lambda pkt : pkt .messageType in [0x0 , 0x1 , 0x2 , 0xB ]),
108+ ConditionalField (BitField ("preciseOriginTimestamp_seconds" , 0 , 48 ),
109+ lambda pkt : pkt .messageType == 0x8 ),
110+ ConditionalField (IntField ("preciseOriginTimestamp_nanoseconds" , 0 ),
111+ lambda pkt : pkt .messageType == 0x8 ),
112+ ConditionalField (BitField ("requestReceiptTimestamp_seconds" , 0 , 48 ),
113+ lambda pkt : pkt .messageType == 0x3 ),
114+ ConditionalField (IntField ("requestReceiptTimestamp_nanoseconds" , 0 ),
115+ lambda pkt : pkt .messageType == 0x3 ),
116+ ConditionalField (BitField ("receiveTimestamp_seconds" , 0 , 48 ),
117+ lambda pkt : pkt .messageType == 0x9 ),
118+ ConditionalField (IntField ("receiveTimestamp_nanoseconds" , 0 ),
119+ lambda pkt : pkt .messageType == 0x9 ),
120+ ConditionalField (BitField ("responseOriginTimestamp_seconds" , 0 , 48 ),
121+ lambda pkt : pkt .messageType == 0xA ),
122+ ConditionalField (IntField ("responseOriginTimestamp_nanoseconds" , 0 ),
123+ lambda pkt : pkt .messageType == 0xA ),
124+ ConditionalField (ShortField ("currentUtcOffset" , 0 ),
125+ lambda pkt : pkt .messageType == 0xB ),
126+ ConditionalField (ByteField ("reserved4" , 0 ),
127+ lambda pkt : pkt .messageType == 0xB ),
128+ ConditionalField (ByteField ("grandmasterPriority1" , 0 ),
129+ lambda pkt : pkt .messageType == 0xB ),
130+ ConditionalField (ByteField ("grandmasterClockClass" , 0 ),
131+ lambda pkt : pkt .messageType == 0xB ),
132+ ConditionalField (XByteField ("grandmasterClockAccuracy" , 0 ),
133+ lambda pkt : pkt .messageType == 0xB ),
134+ ConditionalField (ShortField ("grandmasterClockVariance" , 0 ),
135+ lambda pkt : pkt .messageType == 0xB ),
136+ ConditionalField (ByteField ("grandmasterPriority2" , 0 ),
137+ lambda pkt : pkt .messageType == 0xB ),
138+ ConditionalField (XLongField ("grandmasterIdentity" , 0 ),
139+ lambda pkt : pkt .messageType == 0xB ),
140+ ConditionalField (ShortField ("stepsRemoved" , 0 ),
141+ lambda pkt : pkt .messageType == 0xB ),
142+ ConditionalField (XByteField ("timeSource" , 0 ),
143+ lambda pkt : pkt .messageType == 0xB )
147144
148- def guess_payload_class (self , payload ): # type: (bytes) -> Type[Packet]
149- """
150- Guess payload class based on messageType
151- """
152-
153- if self .messageType == 0x0 :
154- return Sync
155- elif self .messageType == 0x1 :
156- return DelayReq
157- elif self .messageType == 0x2 :
158- return PDelayReq
159- elif self .messageType == 0x3 :
160- return PDelayResp
161- elif self .messageType == 0x8 :
162- return FollowUp
163- elif self .messageType == 0x9 :
164- return DelayResp
165- elif self .messageType == 0xA :
166- return PDelayRespFollow
167- elif self .messageType == 0xB :
168- return Announce
169- elif self .messageType == 0xC :
170- return Signaling
171- elif self .messageType == 0xD :
172- return Management
173-
174- return Packet .guess_payload_class (self , payload )
145+ ]
175146
176147 def post_build (self , pkt , pay ): # type: (bytes, bytes) -> bytes
177148 """
178149 Update the messageLength field after building the packet
179150 """
180- pass
181-
182-
183- class Sync (Packet ):
184- """
185- Handle the Sync message type in PTP
186- """
187- name = "Sync"
188- fields_desc = [
189- PacketField ("originTimestamp" , 0 , OriginTimestamp )
190- ]
191-
192-
193- class DelayReq (Packet ):
194- """
195- Handle the DelayReq message type in PTP
196- """
151+ if self .messageLength is None :
152+ pkt = pkt [:2 ] + struct .pack ("!H" , len (pkt )) + pkt [4 :]
197153
198-
199- class PDelayReq (Packet ):
200- """
201- Handle the PDelayReq message type in PTP
202- """
203-
204-
205- class FollowUp (Packet ):
206- """
207- Handle the FollowUp message type in PTP
208- """
209-
210-
211- class PDelayResp (Packet ):
212- """
213- Handle the PDelayResp message type in PTP
214- """
215-
216-
217- class DelayResp (Packet ):
218- """
219- Handle the DelayResp message type in PTP
220- """
221-
222-
223- class PDelayRespFollow (Packet ):
224- """
225- Handle the PDelayRespFollow message type in PTP
226- """
227-
228-
229- class Announce (Packet ):
230- """
231- Handle the Announce message type in PTP
232- """
233-
234-
235- class Signaling (Packet ):
236- """
237- Handle the Signaling message type in PTP
238- """
239-
240-
241- class Management (Packet ):
242- """
243- Handle the Management message type in PTP
244- """
154+ return pkt + pay
245155
246156
247- ##############################################################################
248157# Layer bindings
249- ##############################################################################
250158
251- bind_layers (UDP , PTPHeader , sport = 319 , dport = 319 )
252- bind_layers (UDP , PTPHeader , sport = 320 , dport = 320 )
159+ bind_layers (UDP , PTP , sport = 319 , dport = 319 )
160+ bind_layers (UDP , PTP , sport = 320 , dport = 320 )
0 commit comments