MoonGen
 All Files Functions Variables Pages
ethernet.lua
Go to the documentation of this file.
1 ------------------------------------------------------------------------
2 --- @file ethernet.lua
3 --- @brief Ethernet protocol utility.
4 --- Utility functions for the mac_address and ethernet_header structs
5 --- defined in \ref headers.lua . \n
6 --- Includes:
7 --- - Ethernet constants
8 --- - Mac address utility
9 --- - Ethernet header utility
10 --- - Definition of ethernet packets
11 ------------------------------------------------------------------------
12 
13 local ffi = require "ffi"
14 local pkt = require "packet"
15 
16 require "utils"
17 require "headers"
18 
19 local ntoh, hton = ntoh, hton
20 local ntoh16, hton16 = ntoh16, hton16
21 local bor, band, bnot, rshift, lshift= bit.bor, bit.band, bit.bnot, bit.rshift, bit.lshift
22 local istype = ffi.istype
23 local format = string.format
24 
25 
26 ------------------------------------------------------------------------
27 ---- Ethernet constants
28 ------------------------------------------------------------------------
29 
30 --- Ethernet protocol constants
31 local eth = {}
32 
33 --- EtherType for IP4
34 eth.TYPE_IP = 0x0800
35 --- EtherType for Arp
36 eth.TYPE_ARP = 0x0806
37 --- EtherType for IP6
38 eth.TYPE_IP6 = 0x86dd
39 --- EtherType for Ptp
40 eth.TYPE_PTP = 0x88f7
41 
42 --- Ethernet broadcast address
43 eth.BROADCAST = "ff:ff:ff:ff:ff:ff"
44 
45 
46 ------------------------------------------------------------------------
47 ---- Mac addresses
48 ------------------------------------------------------------------------
49 
50 --- Module for mac_address struct (see \ref headers.lua).
51 local macAddr = {}
52 macAddr.__index = macAddr
53 local macAddrType = ffi.typeof("struct mac_address")
54 
55 --- Retrieve the MAC address.
56 --- @return Address in 'struct mac_address' format.
57 function macAddr:get()
58  local addr = macAddrType()
59  for i = 0, 5 do
60  addr.uint8[i] = self.uint8[i]
61  end
62  return addr
63 end
64 
65 --- Set the MAC address.
66 --- @param addr Address in 'struct mac_address' format.
67 function macAddr:set(addr)
68  for i = 0, 5 do
69  self.uint8[i] = addr.uint8[i]
70  end
71 end
72 
73 --- Set the MAC address.
74 --- @param mac Address in string format.
75 function macAddr:setString(mac)
76  self:set(parseMacAddress(mac))
77 end
78 
79 --- Test equality of two MAC addresses.
80 --- @param lhs Address in 'struct mac_address' format.
81 --- @param rhs Address in 'struct mac_address' format.
82 --- @return true if equal, false otherwise.
83 function macAddr.__eq(lhs, rhs)
84  local isMAC = istype(macAddrType, lhs) and istype(macAddrType, rhs)
85  for i = 0, 5 do
86  isMAC = isMAC and lhs.uint8[i] == rhs.uint8[i]
87  end
88  return isMAC
89 end
90 
91 --- Retrieve the string representation of a MAC address.
92 --- @return Address in string format.
93 function macAddr:getString()
94  return ("%02x:%02x:%02x:%02x:%02x:%02x"):format(
95  self.uint8[0], self.uint8[1], self.uint8[2],
96  self.uint8[3], self.uint8[4], self.uint8[5]
97  )
98 end
99 
100 
101 ----------------------------------------------------------------------------
102 ---- Ethernet header
103 ----------------------------------------------------------------------------
104 
105 --- Module for ethernet_header struct (see \ref headers.lua).
106 local etherHeader = {}
107 etherHeader.__index = etherHeader
108 
109 --- Set the destination MAC address.
110 --- @param addr Address in 'struct mac_address' format.
111 function etherHeader:setDst(addr)
112  self.dst:set(addr)
113 end
114 
115 --- Retrieve the destination MAC address.
116 --- @return Address in 'struct mac_address' format.
117 function etherHeader:getDst(addr)
118  return self.dst:get()
119 end
120 
121 --- Set the source MAC address.
122 --- @param addr Address in 'struct mac_address' format.
123 function etherHeader:setSrc(addr)
124  self.src:set(addr)
125 end
126 
127 --- Retrieve the source MAC address.
128 --- @return Address in 'struct mac_address' format.
129 function etherHeader:getSrc(addr)
130  return self.src:get()
131 end
132 
133 --- Set the destination MAC address.
134 --- @param str Address in string format.
135 function etherHeader:setDstString(str)
136  self.dst:setString(str)
137 end
138 
139 --- Retrieve the destination MAC address.
140 --- @return Address in string format.
141 function etherHeader:getDstString()
142  return self.dst:getString()
143 end
144 
145 --- Set the source MAC address.
146 --- @param str Address in string format.
147 function etherHeader:setSrcString(str)
148  self.src:setString(str)
149 end
150 
151 --- Retrieve the source MAC address.
152 --- @return Address in string format.
153 function etherHeader:getSrcString()
154  return self.src:getString()
155 end
156 
157 --- Set the EtherType.
158 --- @param int EtherType as 16 bit integer.
159 function etherHeader:setType(int)
160  int = int or eth.TYPE_IP
161  self.type = hton16(int)
162 end
163 
164 --- Retrieve the EtherType.
165 --- @return EtherType as 16 bit integer.
166 function etherHeader:getType()
167  return hton16(self.type)
168 end
169 
170 --- Retrieve the ether type.
171 --- @return EtherType as string.
172 function etherHeader:getTypeString()
173  local type = self:getType()
174  local cleartext = ""
175 
176  if type == eth.TYPE_IP then
177  cleartext = "(IP4)"
178  elseif type == eth.TYPE_IP6 then
179  cleartext = "(IP6)"
180  elseif type == eth.TYPE_ARP then
181  cleartext = "(ARP)"
182  elseif type == eth.TYPE_PTP then
183  cleartext = "(PTP)"
184  else
185  cleartext = "(unknown)"
186  end
187 
188  return format("0x%04x %s", type, cleartext)
189 end
190 
191 --- Set all members of the ethernet header.
192 --- Per default, all members are set to default values specified in the respective set function.
193 --- Optional named arguments can be used to set a member to a user-provided value. \n
194 --- Exemplary invocations:
195 --- @code
196 --- fill() --- only default values
197 --- fill{ ethSrc="12:23:34:45:56:67", ethType=0x137 } --- default value for ethDst; ethSrc and ethType user-specified
198 --- @endcode
199 --- @param args Table of named arguments. Available arguments: Src, Dst, Type
200 --- @param pre Prefix for namedArgs. Default 'eth'.
201 function etherHeader:fill(args, pre)
202  args = args or {}
203  pre = pre or "eth"
204 
205  local src = pre .. "Src"
206  local dst = pre .. "Dst"
207  args[src] = args[src] or "01:02:03:04:05:06"
208  args[dst] = args[dst] or "07:08:09:0a:0b:0c"
209 
210  -- addresses can be either a string, a mac_address ctype or a device/queue object
211  if type(args[src]) == "string" then
212  self:setSrcString(args[src])
213  elseif istype(macAddrType, args[src]) then
214  self:setSrc(args[src])
215  elseif type(args[src]) == "table" and args[src].id then
216  self:setSrcString((args[src].dev or args[src]):getMacString())
217  end
218  if type(args[dst]) == "string" then
219  self:setDstString(args[dst])
220  elseif istype(macAddrType, args[dst]) then
221  self:setDst(args[dst])
222  elseif type(args[dst]) == "table" and args[dst].id then
223  self:setDstString((args[dst].dev or args[dst]):getMacString())
224  end
225  self:setType(args[pre .. "Type"])
226 end
227 
228 --- Retrieve the values of all members.
229 --- @param pre Prefix for namedArgs. Default 'eth'.
230 --- @return Table of named arguments. For a list of arguments see "See Also".
231 --- @see etherHeader:fill
232 function etherHeader:get(pre)
233  pre = pre or "eth"
234 
235  local args = {}
236  args[pre .. "Src"] = self:getSrcString()
237  args[pre .. "Dst"] = self:getDstString()
238  args[pre .. "Type"] = self:getType()
239 
240  return args
241 end
242 
243 --- Retrieve the values of all members.
244 --- @return Values in string format.
245 function etherHeader:getString()
246  return "ETH " .. self:getSrcString() .. " > " .. self:getDstString() .. " type " .. self:getTypeString()
247 end
248 
249 -- Maps headers to respective types.
250 -- This list should be extended whenever a new type is added to 'Ethernet constants'.
251 local mapNameType = {
252  ip4 = eth.TYPE_IP,
253  ip6 = eth.TYPE_IP6,
254  arp = eth.TYPE_ARP,
255  ptp = eth.TYPE_PTP,
256 }
257 
258 --- Resolve which header comes after this one (in a packet).
259 --- For instance: in tcp/udp based on the ports.
260 --- This function must exist and is only used when get/dump is executed on
261 --- an unknown (mbuf not yet casted to e.g. tcpv6 packet) packet (mbuf)
262 --- @return String next header (e.g. 'eth', 'ip4', nil)
264  local type = self:getType()
265  for name, _type in pairs(mapNameType) do
266  if type == _type then
267  return name
268  end
269  end
270  return nil
271 end
272 
273 --- Change the default values for namedArguments (for fill/get).
274 --- This can be used to for instance calculate a length value based on the total packet length.
275 --- See proto/ip4.setDefaultNamedArgs as an example.
276 --- This function must exist and is only used by packet.fill.
277 --- @param pre The prefix used for the namedArgs, e.g. 'eth'
278 --- @param namedArgs Table of named arguments (see See Also)
279 --- @param nextHeader The header following after this header in a packet
280 --- @param accumulatedLength The so far accumulated length for previous headers in a packet
281 --- @return Table of namedArgs
282 --- @see etherHeader:fill
283 function etherHeader:setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
284  -- only set Type
285  if not namedArgs[pre .. "Type"] then
286  for name, type in pairs(mapNameType) do
287  if nextHeader == name then
288  namedArgs[pre .. "Type"] = type
289  break
290  end
291  end
292  end
293  return namedArgs
294 end
295 
296 
297 ----------------------------------------------------------------------------------
298 ---- Packets
299 ----------------------------------------------------------------------------------
300 
301 --- Cast the packet to an ethernet packet
303 --- Cast the packet to an ethernet packet (alias for pkt.getEthernetPacket)
305 
306 
307 ----------------------------------------------------------------------------------
308 ---- Metatypes
309 ----------------------------------------------------------------------------------
310 
311 ffi.metatype("struct mac_address", macAddr)
312 ffi.metatype("struct ethernet_header", etherHeader)
313 
314 
315 return eth
function macAddr get()
Retrieve the MAC address.
function macAddr __eq(lhs, rhs)
Test equality of two MAC addresses.
function etherHeader setDst(addr)
Set the destination MAC address.
local ffi
low-level dpdk wrapper
Definition: dpdkc.lua:6
function etherHeader setSrc(addr)
Set the source MAC address.
eth TYPE_ARP
EtherType for Arp.
Definition: ethernet.lua:29
function etherHeader getSrc(addr)
Retrieve the source MAC address.
function packetCreate(...)
Create struct and functions for a new packet.
function macAddr setString(mac)
Set the MAC address.
pkt getEthernetPacket
Cast the packet to an ethernet packet.
Definition: ethernet.lua:174
function mod band(mask1, mask2, result)
Bitwise and.
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct.
function etherHeader getTypeString()
Retrieve the ether type.
function macAddr getString()
Retrieve the string representation of a MAC address.
function mod new(n)
function etherHeader setDstString(str)
Set the destination MAC address.
eth TYPE_PTP
EtherType for Ptp.
Definition: ethernet.lua:33
function etherHeader setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
Change the default values for namedArguments (for fill/get).
local udp
Udp protocol constants.
Definition: udp.lua:23
function mod bor(mask1, mask2, result)
Bitwise or.
local arp
Arp protocol constants.
Definition: arp.lua:32
function etherHeader fill(args, pre)
Set all members of the ethernet header.
function etherHeader getDstString()
Retrieve the destination MAC address.
local ptp
Ptp protocol constants.
Definition: ptp.lua:23
pkt getEthPacket
Cast the packet to an ethernet packet (alias for pkt.getEthernetPacket)
Definition: ethernet.lua:176
local macAddr
Module for mac_address struct (see headers.lua).
Definition: ethernet.lua:41
local etherHeader
Module for ethernet_header struct (see headers.lua).
Definition: ethernet.lua:70
function etherHeader setType(int)
Set the EtherType.
function etherHeader getType()
Retrieve the EtherType.
eth TYPE_IP6
EtherType for IP6.
Definition: ethernet.lua:31
eth TYPE_IP
EtherType for IP4.
Definition: ethernet.lua:27
function etherHeader setSrcString(str)
Set the source MAC address.
local eth
Ethernet protocol constants.
Definition: ethernet.lua:24
local ip6
IP6 protocol constants.
Definition: ip6.lua:25
function etherHeader resolveNextHeader()
Resolve which header comes after this one (in a packet).
local pkt
Module for packets (rte_mbuf)
Definition: packet.lua:20
function mod bnot(mask, result)
Bitwise not.
function etherHeader getDst(addr)
Retrieve the destination MAC address.
n
Create a new array of memory buffers (initialized to nil).
Definition: memory.lua:76
function macAddr set(addr)
Set the MAC address.
function parseMacAddress(mac)
Parse a string to a MAC address.
function etherHeader getSrcString()
Retrieve the source MAC address.