MoonGen
 All Files Functions Variables Pages
ptp.lua
Go to the documentation of this file.
1 ------------------------------------------------------------------------
2 --- @file ptp.lua
3 --- @brief Precision time protocol (PTP) utility.
4 --- Utility functions for the ptp_header struct
5 --- defined in \ref headers.lua . \n
6 --- Includes:
7 --- - PTP constants
8 --- - PTP header utility
9 --- - Definition of PTP packets
10 ------------------------------------------------------------------------
11 
12 local ffi = require "ffi"
13 local pkt = require "packet"
14 
15 require "utils"
16 require "headers"
17 
18 local ntoh, hton = ntoh, hton
19 local ntoh16, hton16 = ntoh16, hton16
20 local bor, band, bnot, rshift, lshift= bit.bor, bit.band, bit.bnot, bit.rshift, bit.lshift
21 local istype = ffi.istype
22 local format = string.format
23 
24 
25 ---------------------------------------------------------------------------
26 ---- PTP constants
27 ---------------------------------------------------------------------------
28 
29 --- Ptp protocol constants
30 local ptp = {}
31 
32 -- Message type: sync
33 ptp.TYPE_SYNC = 0
34 -- Message type: delay req
35 ptp.TYPE_DELAY_REQ = 1
36 -- Message type: follow up
37 ptp.TYPE_FOLLOW_UP = 8
38 -- Message type: delay resp
39 ptp.TYPE_DELAY_RESP = 9
40 
41 -- Message control: sync
42 ptp.CONTROL_SYNC = 0
43 -- Message control: delay req
44 ptp.CONTROL_DELAY_REQ = 1
45 -- Message control: follow up
46 ptp.CONTROL_FOLLOW_UP = 2
47 -- Message control: delay resp
48 ptp.CONTROL_DELAY_RESP = 3
49 
50 
51 ---------------------------------------------------------------------------
52 ---- PTP header
53 ---------------------------------------------------------------------------
54 
55 --- Module for ptp_header struct (see \ref headers.lua).
56 local ptpHeader = {}
57 ptpHeader.__index = ptpHeader
58 
59 --- Set the message type.
60 --- @param mt Message type as 8 bit integer.
61 function ptpHeader:setMessageType(mt)
62  mt = mt or ptp.TYPE_SYNC
63  self.messageType = mt
64 end
65 
66 --- Retrieve the message type.
67 --- @return Message type as 8 bit integer.
68 function ptpHeader:getMessageType()
69  return self.messageType
70 end
71 
72 --- Retrieve the message type.
73 --- @return Message type in string format.
75  local type = self:getMessageType()
76  local cleartext = ""
77 
78  if type == ptp.TYPE_SYNC then
79  cleartext = "(sync)"
80  elseif type == ptp.TYPE_DELAY_REQ then
81  cleartext = "(delay req)"
82  elseif type == ptp.TYPE_FOLLOW_UP then
83  cleartext = "(follow up)"
84  elseif type == ptp.TYPE_DELAY_RESP then
85  cleartext = "(delay resp)"
86  else
87  cleartext = "(unknown)"
88  end
89 
90  return format("0x%02x %s", type, cleartext)
91 end
92 
93 --- Set the version.
94 --- @param v Version as 8 bit integer.
95 function ptpHeader:setVersion(v)
96  v = v or 0x02 -- version 2
97  self.versionPTP = v
98 end
99 
100 --- Retrieve the version.
101 --- @return Version as 8 bit integer.
102 function ptpHeader:getVersion()
103  return self.versionPTP
104 end
105 
106 --- Retrieve the version.
107 --- @return Version in string format.
108 function ptpHeader:getVersionString()
109  return self:getVersion()
110 end
111 
112 --- Set the length.
113 --- @param l Length as 16 bit integer.
114 function ptpHeader:setLength(l)
115  l = l or 34 + 10 + 0 -- header, body, suffix
116  self.len = hton16(l)
117 end
118 
119 --- Retrieve the length.
120 --- @return Length as 16 bit integer.
121 function ptpHeader:getLength()
122  return hton16(self.len)
123 end
124 
125 --- Retrieve the length.
126 --- @return Length in string format.
127 function ptpHeader:getLengthString()
128  return self:getLength()
129 end
130 
131 --- Set the domain.
132 --- @param d Domain as 8 bit integer.
133 function ptpHeader:setDomain(d)
134  d = d or 0 -- default domain
135  self.domain = d
136 end
137 
138 --- Retrieve the domain.
139 --- @return Domain as 8 bit integer.
140 function ptpHeader:getDomain()
141  return self.domain
142 end
143 
144 --- Retrieve the domain.
145 --- @return Domain in string format.
146 function ptpHeader:getDomainString()
147  return self:getDomain()
148 end
149 
150 --- Set the reserved field.
151 --- @param uint8 Reserved as 8 bit integer.
152 function ptpHeader:setReserved(uint8)
153  uint8 = uint8 or 0
154  self.reserved = uint8
155 end
156 
157 --- Retrieve the reserved field.
158 --- @return Reserved field as 8 bit integer.
159 function ptpHeader:getReserved()
160  return self.reserved
161 end
162 
163 --- Retrieve the reserved field.
164 --- @return Reserved field in string format.
165 function ptpHeader:getReservedString()
166  return format("0x%02x", self:getReserved())
167 end
168 
169 --- Set the flags.
170 --- @param f Flags as 16 bit integer.
171 function ptpHeader:setFlags(f)
172  f = f or 0 -- no flags
173  self.flags = hton16(f)
174 end
175 
176 --- Retrieve the flags.
177 --- @return Flags as 16 bit integer.
178 function ptpHeader:getFlags()
179  return hton16(self.flags)
180 end
181 
182 --- Retrieve the flags.
183 --- @return Flags in string format.
184 function ptpHeader:getFlagsString()
185  return format("0x%04x", self:getFlags())
186 end
187 
188 --- Set the correction field.
189 --- @param c Correction field as table of two 32 bit integers { high, low }.
190 --- @todo find something better for this, 64 bit seems to be trouble for lua?
191 --- c = { high32bit, low32bit }
192 function ptpHeader:setCorrection(c)
193  c = c or { high=0, low=0 } -- correction offset 0
194  self.correction[0] = hton(c.low)
195  self.correction[1] = hton(c.high)
196 end
197 
198 --- Retrieve the correction field.
199 --- @return Correction field as table two 32 bit integers { high, low }.
200 function ptpHeader:getCorrection()
201  return { high = hton(self.correction[1]), low = hton(self.correction[0]) }
202 end
203 
204 --- Retrieve the correction field.
205 --- @return Correction field in string format.
207  local t = self:getCorrection()
208  return format("0x%08x%08x", t.high, t.low)
209 end
210 
211 --- Set the reserved2 field.
212 --- @param uint32 Reserved2 as 32 bit integer.
213 function ptpHeader:setReserved2(uint32)
214  uint32 = uint32 or 0
215  self.reserved2 = hton(uint32)
216 end
217 
218 --- Retrieve the reserved2 field.
219 --- @return Reserved2 field as 32 bit integer.
220 function ptpHeader:getReserved2()
221  return hton(self.reserved2)
222 end
223 
224 --- Retrieve the reserved2 field.
225 --- @return Reserved2 field in string format.
226 function ptpHeader:getReserved2String()
227  return format("0x%08x", self:getReserved2())
228 end
229 
230 --- Set the oui.
231 --- @param int Oui as 24 bit integer.
232 function ptpHeader:setOui(int)
233  int = int or 0
234 
235  -- X 3 2 1 -> 1 2 3
236  self.oui[0] = rshift(band(int, 0xFF0000), 16)
237  self.oui[1] = rshift(band(int, 0x00FF00), 8)
238  self.oui[2] = band(int, 0x0000FF)
239 end
240 
241 --- Retrieve the oui.
242 --- @return Oui as 24 bit integer.
243 function ptpHeader:getOui()
244  return bor(lshift(self.oui[0], 16), bor(lshift(self.oui[1], 8), self.oui[2]))
245 end
246 
247 --- Retrieve the oui.
248 --- @return Oui in string format.
249 function ptpHeader:getOuiString()
250  return format("0x%06x", self:getOui())
251 end
252 
253 --- Set the uuid.
254 --- @param int Uuis as table of two integers { high, low }, high as 8 bit integer and low as 32 bit integer.
255 --- @todo same problem as with correction field
256 --- c = { high8bit, low32bit }
257 function ptpHeader:setUuid(int)
258  int = int or { high=0, low=0 }
259 
260  -- X X X 1 5 4 3 2 -> 1 2 3 4 5
261  self.uuid[0] = int.high
262  self.uuid[1] = rshift(band(int.low, 0xFF000000), 24)
263  self.uuid[2] = rshift(band(int.low, 0x00FF0000), 16)
264  self.uuid[3] = rshift(band(int.low, 0x0000FF00), 8)
265  self.uuid[4] = band(int.low, 0x000000FF)
266 end
268 --- Retrieve the Uuid.
269 --- @return Uuid as table of two integers { high, low }, high is an 8 bit integer, low 32 bit integer.
270 function ptpHeader:getUuid()
271  local t = {}
272  t.high = self.uuid[0]
273  t.low = bor(lshift(self.uuid[1], 24), bor(lshift(self.uuid[2], 16), bor(lshift(self.uuid[3], 8), self.uuid[4])))
274  return t
275 end
276 
277 --- Retrieve the Uuid.
278 --- @return Uuid in string format.
279 function ptpHeader:getUuidString()
280  local t = self:getUuid()
281  return format("0x%02x%08x", t.high, t.low)
282 end
283 
284 --- Set the node port.
285 --- @param p Node port as 16 bit integer.
286 function ptpHeader:setNodePort(p)
287  p = p or 1
288  self.ptpNodePort = hton16(p)
289 end
290 
291 --- Retrieve the node port.
292 --- @return Node port as 16 bit integer.
293 function ptpHeader:getNodePort()
294  return hton16(self.ptpNodePort)
295 end
296 
297 --- Retrieve the node port.
298 --- @return Node port in string format.
299 function ptpHeader:getNodePortString()
300  return self:getNodePort()
301 end
302 
303 --- Set the sequence ID.
304 --- @param s Sequence ID as 16 bit integer.
305 function ptpHeader:setSequenceID(s)
306  s = s or 0
307  self.sequenceId = hton16(s)
308 end
309 
310 --- Retrieve the sequence ID.
311 --- @return Sequence ID as 16 bit integer.
312 function ptpHeader:getSequenceID()
313  return hton16(self.sequenceId)
314 end
315 
316 --- Retrieve the sequence ID.
317 --- @return Sequence ID in string format.
319  return self:getSequenceID()
320 end
321 
322 --- Set the control field.
323 --- @param c Control field as 8 bit integer.
324 function ptpHeader:setControl(c)
325  c = c or ptp.CONTROL_SYNC
326  self.control = c
327 end
328 
329 --- Retrieve the control field.
330 --- @return Control field as 8 bit integer.
331 function ptpHeader:getControl()
332  return self.control
333 end
334 
335 --- Retrieve the control field.
336 --- @return Control field in string format.
337 function ptpHeader:getControlString()
338  local type = self:getControl()
339  local cleartext = ""
340 
341  if type == ptp.CONTROL_SYNC then
342  cleartext = "(sync)"
343  elseif type == ptp.CONTROL_DELAY_REQ then
344  cleartext = "(delay req)"
345  elseif type == ptp.CONTROL_FOLLOW_UP then
346  cleartext = "(follow up)"
347  elseif type == ptp.CONTROL_DELAY_RESP then
348  cleartext = "(delay resp)"
349  else
350  cleartext = "(unknown)"
351  end
352 
353  return format("0x%02x %s", type, cleartext)
354 end
355 
356 --- Set the log message interval.
357 --- @param l Log message interval as 8 bit integer.
359  l = l or 0x7F -- default value
360  self.logMessageInterval = l
361 end
362 
363 --- Retrieve the log message interval.
364 --- @return Log message interval as 8 bit integer.
366  return self.logMessageInterval
367 end
368 
369 --- Retrieve the log message interval.
370 --- @return Log message interval in string format.
372  return self:getLogMessageInterval()
373 end
374 
375 --- Set all members of the ip header.
376 --- Per default, all members are set to default values specified in the respective set function.
377 --- Optional named arguments can be used to set a member to a user-provided value.
378 --- @param args Table of named arguments. Available arguments: MessageType, Version, Length, Domain, Reserved, Flags, Correction, Reserved2, Oui, Uuid, NodePort, SequenceID, Control, LogMessageInterval
379 --- @param pre prefix for namedArgs. Default 'ptp'.
380 --- @code
381 --- fill() --- only default values
382 --- fill{ ptpLenght=123, ipTTL=100 } --- all members are set to default values with the exception of ptpLength
383 --- @endcode
384 function ptpHeader:fill(args, pre)
385  args = args or {}
386  pre = pre or "ptp"
387 
388  self:setMessageType(args[pre .. "MessageType"])
389  self:setVersion(args[pre .. "Version"])
390  self:setLength(args[pre .. "Length"])
391  self:setDomain(args[pre .. "Domain"])
392  self:setReserved(args[pre .. "Reserved"])
393  self:setFlags(args[pre .. "Flags"])
394  self:setCorrection(args[pre .. "Correction"])
395  self:setReserved2(args[pre .. "Reserved2"])
396  self:setOui(args[pre .. "Oui"])
397  self:setUuid(args[pre .. "Uuid"])
398  self:setNodePort(args[pre .. "NodePort"])
399  self:setSequenceID(args[pre .. "SequenceID"])
400  self:setControl(args[pre .. "Control"])
401  self:setLogMessageInterval(args[pre .. "LogMessageInterval"])
402 end
403 
404 --- Retrieve the values of all members.
405 --- @param pre prefix for namedArgs. Default 'ptp'.
406 --- @return Table of named arguments. For a list of arguments see "See also".
407 --- @see ptpHeader:fill
408 function ptpHeader:get(pre)
409  pre = pre or "ptp"
410 
411  local args = {}
412  args[pre .. "MessageTyp"] = self:getMessageType()
413  args[pre .. "Version"] = self:getVersion()
414  args[pre .. "Length"] = self:getLength()
415  args[pre .. "Domain"] = self:getDomain()
416  args[pre .. "Reserved"] = self:getReserved()
417  args[pre .. "Flags"] = self:getFlags()
418  args[pre .. "Correction"] = self:getCorrection()
419  args[pre .. "Reserved2"] = self:getReserved2()
420  args[pre .. "Oui"] = self:getOui()
421  args[pre .. "Uuid"] = self:getUuid()
422  args[pre .. "NodePort"] = self:getNodePort()
423  args[pre .. "SequenceID"] = self:getSequenceID()
424  args[pre .. "Control"] = self:getControl()
425  args[pre .. "LogMessageInterval"] = self:getLogMessageInterval()
426 
427  return args
428 end
429 
430 --- Retrieve the values of all members.
431 --- @return Values in string format.
432 function ptpHeader:getString()
433  return "PTP typ " .. self:getMessageTypeString()
434  .. " ver " .. self:getVersionString()
435  .. " len " .. self:getLengthString()
436  .. " dom " .. self:getDomainString()
437  .. " res " .. self:getReservedString()
438  .. " fla " .. self:getFlagsString()
439  .. " cor " .. self:getCorrectionString()
440  .. " res " .. self:getReserved2String()
441  .. " oui " .. self:getOuiString()
442  .. " uuid " .. self:getUuidString()
443  .. " nod " .. self:getNodePortString()
444  .. " seq " .. self:getSequenceIDString()
445  .. " ctrl " .. self:getControlString()
446  .. " log " .. self:getLogMessageIntervalString()
447 end
448 
449 --- Resolve which header comes after this one (in a packet).
450 --- For instance: in tcp/udp based on the ports.
451 --- This function must exist and is only used when get/dump is executed on
452 --- an unknown (mbuf not yet casted to e.g. tcpv6 packet) packet (mbuf)
453 --- @return String next header (e.g. 'udp', 'icmp', nil)
454 function ptpHeader:resolveNextHeader()
455  return nil
456 end
457 
458 --- Change the default values for namedArguments (for fill/get).
459 --- This can be used to for instance calculate a length value based on the total packet length.
460 --- See proto/ip4.setDefaultNamedArgs as an example.
461 --- This function must exist and is only used by packet.fill.
462 --- @param pre The prefix used for the namedArgs, e.g. 'ptp'
463 --- @param namedArgs Table of named arguments (see See Also)
464 --- @param nextHeader The header following after this header in a packet
465 --- @param accumulatedLength The so far accumulated length for previous headers in a packet
466 --- @return Table of namedArgs
467 --- @see ptpHeader:fill
468 function ptpHeader:setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
469  -- set length
470  if not namedArgs[pre .. "Length"] and namedArgs["pktLength"] then
471  namedArgs[pre .. "Length"] = namedArgs["pktLength"] - accumulatedLength
472  end
473  return namedArgs
474 end
475 
476 
477 ---------------------------------------------------------------------------------
478 ---- Packets
479 ---------------------------------------------------------------------------------
480 
481 --- Cast the packet to a layer 2 Ptp packet
483 --- Cast the packet to a Ptp over Udp (IP4) packet
484 pkt.getUdpPtpPacket = packetCreate("eth", "ip4", "udp", "ptp")
485 
486 
487 ------------------------------------------------------------------------
488 ---- Metatypes
489 ------------------------------------------------------------------------
490 
491 ffi.metatype("struct ptp_header", ptpHeader)
492 
493 return ptp
function ptpHeader getSequenceID()
Retrieve the sequence ID.
function ptpHeader getSequenceIDString()
Retrieve the sequence ID.
function ptpHeader setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
Change the default values for namedArguments (for fill/get).
local ffi
low-level dpdk wrapper
Definition: dpdkc.lua:6
pkt getPtpPacket
Cast the packet to a layer 2 Ptp packet.
Definition: ptp.lua:265
function ptpHeader getReserved2()
Retrieve the reserved2 field.
function packetCreate(...)
Create struct and functions for a new packet.
function ptpHeader getLogMessageIntervalString()
Retrieve the log message interval.
function ptpHeader get(pre)
Retrieve the values of all members.
function ptpHeader setNodePort(p)
Set the node port.
function ptpHeader setLogMessageInterval(l)
Set the log message interval.
function mod band(mask1, mask2, result)
Bitwise and.
function ptpHeader setMessageType(mt)
Set the message type.
function ptpHeader setCorrection(c)
Set the correction field.
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct.
function ptpHeader getDomain()
Retrieve the domain.
function ptpHeader getUuid()
Retrieve the Uuid.
function ptpHeader getReservedString()
Retrieve the reserved field.
function ipsecICV set(icv)
Set the IPsec ICV.
function ptpHeader getMessageType()
Retrieve the message type.
function ptpHeader getFlags()
Retrieve the flags.
function ptpHeader getString()
Retrieve the values of all members.
function ptpHeader fill(args, pre)
Set all members of the ip header.
function ptpHeader getLength()
Retrieve the length.
local udp
Udp protocol constants.
Definition: udp.lua:23
function ptpHeader getVersion()
Retrieve the version.
function ptpHeader setUuid(int)
Set the uuid.
function ptpHeader getUuidString()
Retrieve the Uuid.
function ptpHeader getCorrection()
Retrieve the correction field.
function mod bor(mask1, mask2, result)
Bitwise or.
function ptpHeader getReserved2String()
Retrieve the reserved2 field.
function ptpHeader setVersion(v)
Set the version.
function ptpHeader getOuiString()
Retrieve the oui.
function ptpHeader getReserved()
Retrieve the reserved field.
function ptpHeader setReserved(uint8)
Set the reserved field.
function ptpHeader getControl()
Retrieve the control field.
local ptp
Ptp protocol constants.
Definition: ptp.lua:23
function ptpHeader setReserved2(uint32)
Set the reserved2 field.
pkt getUdpPtpPacket
Cast the packet to a Ptp over Udp (IP4) packet.
Definition: ptp.lua:267
function ptpHeader getOui()
Retrieve the oui.
function ptpHeader setOui(int)
Set the oui.
function ptpHeader getCorrectionString()
Retrieve the correction field.
function ptpHeader setDomain(d)
Set the domain.
function ptpHeader getFlagsString()
Retrieve the flags.
local eth
Ethernet protocol constants.
Definition: ethernet.lua:24
function ptpHeader setLength(l)
Set the length.
local ip
IP4 protocol constants.
Definition: ip4.lua:25
function ptpHeader getNodePort()
Retrieve the node port.
local pkt
Module for packets (rte_mbuf)
Definition: packet.lua:20
function mod bnot(mask, result)
Bitwise not.
function ptpHeader getControlString()
Retrieve the control field.
n
Create a new array of memory buffers (initialized to nil).
Definition: memory.lua:76
function ptpHeader setControl(c)
Set the control field.
local ptpHeader
Module for ptp_header struct (see headers.lua).
Definition: ptp.lua:38
function ptpHeader getDomainString()
Retrieve the domain.
function ptpHeader getNodePortString()
Retrieve the node port.
function ptpHeader setSequenceID(s)
Set the sequence ID.
function ptpHeader getVersionString()
Retrieve the version.
function ptpHeader getMessageTypeString()
Retrieve the message type.
local icmp
Icmp4 protocol constants.
Definition: icmp.lua:25
function ptpHeader resolveNextHeader()
Resolve which header comes after this one (in a packet).
function ptpHeader getLogMessageInterval()
Retrieve the log message interval.
function ptpHeader setFlags(f)
Set the flags.
function ptpHeader getLengthString()
Retrieve the length.