9
9
References : IEEE 1588-2008
10
10
"""
11
11
12
+ import struct
13
+
12
14
from scapy .packet import Packet , bind_layers
13
15
from scapy .fields import (
14
16
BitEnumField ,
19
21
ShortField ,
20
22
ByteEnumField ,
21
23
FlagsField ,
22
- PacketField ,
23
24
XLongField ,
25
+ XByteField ,
26
+ ConditionalField ,
24
27
)
25
28
from scapy .layers .inet import UDP
26
29
75
78
}
76
79
77
80
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 ):
87
82
"""
88
- PTP Header based on IEEE 1588-2008 / Section 13.3.
83
+ PTP packet based on IEEE 1588-2008 / Section 13.3
89
84
"""
90
85
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"
129
87
match_subclass = True
130
88
fields_desc = [
131
89
BitField ("transportSpecific" , 0 , 4 ),
132
90
BitEnumField ("messageType" , 0x0 , 4 , _message_type ),
133
91
BitField ("reserved1" , 0 , 4 ),
134
92
BitField ("version" , 2 , 4 ),
135
- ShortField ("messageLength" , 0 ),
93
+ ShortField ("messageLength" , None ),
136
94
ByteField ("domainNumber" , 0 ),
137
95
ByteField ("reserved2" , 0 ),
138
96
FlagsField ("flags" , 0 , 16 , _flags ),
@@ -142,111 +100,61 @@ class PTPHeader(Packet):
142
100
ShortField ("portNumber" , 0 ),
143
101
ShortField ("sequenceId" , 0 ),
144
102
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 )
147
144
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
+ ]
175
146
176
147
def post_build (self , pkt , pay ): # type: (bytes, bytes) -> bytes
177
148
"""
178
149
Update the messageLength field after building the packet
179
150
"""
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 :]
197
153
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
245
155
246
156
247
- ##############################################################################
248
157
# Layer bindings
249
- ##############################################################################
250
158
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