1 ------------------------------------------------------------------------
3 --- @brief Internet protocol (v4) utility.
4 --- Utility functions for the ip4_address and ip4_header structs
5 --- defined in \ref headers.lua . \
n
8 --- - IP4 address utility
9 --- - IP4 header utility
10 --- - Definition of IP4 packets
11 ------------------------------------------------------------------------
14 local
pkt = require "packet"
19 local ntoh, hton = ntoh, hton
20 local ntoh16, hton16 = ntoh16, hton16
23 local
bor,
band,
bnot, rshift, lshift= bit.bor, bit.band, bit.bnot, bit.rshift, bit.lshift
24 local istype =
ffi.istype
25 local format =
string.format
27 ----------------------------------------------------------------------------------
29 ----------------------------------------------------------------------------------
31 --- IP4 protocol constants
34 --- Protocol field value
for Icmp
36 --- Protocol field value
for Tcp
38 --- Protocol field value
for Udp
44 ----------------------------------------------------------------------------------
46 ----------------------------------------------------------------------------------
48 --- Module
for ip4_address
struct (see \ref headers.lua).
51 local ip4AddrType =
ffi.typeof(
"union ip4_address")
53 --- Retrieve the IPv4 address.
54 --- @
return Address in uint32 format.
56 return bswap(
self.uint32)
59 --- Set the IPv4 address.
60 --- @param
ip Address in uint32 format.
62 self.uint32 = bswap(
ip)
65 --- Set the IPv4 address.
66 --- @param
ip Address in
string format.
71 --- Retrieve the
string representation of the IPv4 address.
72 --- @return Address in
string format.
74 return ("%d.%d.%d.%d"):format(self.uint8[0], self.uint8[1], self.uint8[2], self.uint8[3])
78 --- Test equality of two IPv4 addresses.
79 --- @param lhs Address in 'union ip4_address' format.
80 --- @param rhs Address in 'union ip4_address' format.
81 --- @return true if equal, false otherwise.
83 return istype(ip4AddrType, lhs) and istype(ip4AddrType, rhs) and lhs.uint32 == rhs.uint32
86 --- Add a number to an IPv4 address.
87 --- Max. 32 bit, commutative.
88 --- @param lhs Address in 'union ip4_address' format.
89 --- @param rhs Number to
add (32 bit integer).
90 --- @return Resulting address in uint32 format.
92 -- calc
ip (self) + number (val)
94 if istype(ip4AddrType, lhs) then
98 -- commutative for number +
ip
101 end -- TODO:
ip +
ip?
103 return self:
get() + val
106 --- Add a number to an IPv4 address in-place.
108 --- @param val Number to
add (32 bit integer).
110 self:
set(self:
get() + val)
113 --- Subtract a number from an IPv4 address.
115 --- @param val Number to substract (32 bit integer)
116 --- @return Resulting address in uint32 format.
122 -----------------------------------------------------------------------------------
124 -----------------------------------------------------------------------------------
126 --- Module for ip4_header struct (see \ref headers.lua).
132 --- @param
int IP header version as 4 bit integer. Should always be
'4'.
135 int =
band(lshift(
int, 4), 0xf0) --
fill to 8 bits
138 old =
band(old, 0x0f) -- remove old value
140 self.verihl =
bor(old,
int)
143 --- Retrieve the version.
144 --- @return Version as 4 bit integer.
146 return
band(rshift(self.verihl, 4), 0x0f)
149 --- Retrieve the version.
150 --- @return Version as
string.
155 --- Set the header length.
156 --- @param
int Length of the
ip header (in multiple of 32 bits) as 4 bit integer. Should always be '5'.
159 int =
band(
int, 0x0f)
162 old =
band(old, 0xf0)
164 self.verihl =
bor(old,
int)
167 --- Retrieve the header length.
168 --- @return Header length as 4 bit integer.
170 return
band(self.verihl, 0x0f)
173 --- Retrieve the header length.
174 --- @return Header length as
string.
179 --- Set the type of service (TOS).
180 --- @param
int TOS of the
ip header as 8 bit integer.
186 --- Retrieve the type of service.
187 --- @return TOS as 8 bit integer.
192 --- Retrieve the type of service.
193 --- @return TOS as
string.
198 --- Set the total length.
199 --- @param
int Length of the packet excluding layer 2. 16 bit integer.
201 int =
int or 48 -- with
eth + UDP -> minimum 64
202 self.len = hton16(
int)
205 --- Retrieve the length.
206 --- @return Length as 16 bit integer.
208 return hton16(self.len)
211 --- Retrieve the length.
212 --- @return Length as
string.
217 --- Set the identification.
218 --- @param
int ID of the
ip header as 16 bit integer.
221 self.
id = hton16(
int)
224 --- Retrieve the identification.
225 --- @return ID as 16 bit integer.
227 return hton16(self.
id)
230 --- Retrieve the identification.
231 --- @return ID as
string.
237 --- Bits: [ reserved (must be 0) | don't fragment | more fragments ]
238 --- @param
int Flags of the
ip header as 3 bit integer
241 int =
band(lshift(
int, 13), 0xe000) --
fill to 16 bits
243 old = hton16(self.frag)
244 old =
band(old, 0x1fff) -- remove old value
246 self.frag = hton16(
bor(old,
int))
249 --- Retrieve the flags.
250 --- @return Flags as 3 bit integer.
252 return
band(rshift(hton16(self.frag), 13), 0x000e)
255 --- Retrieve the flags.
256 --- @return Flags as
string.
259 --TODO show flags in a more clever manner: 1|1|1 or reserved|DF|MF
263 --- Set the fragment.
264 --- @param
int Fragment of the
ip header as 13 bit integer.
267 int =
band(
int, 0x1fff)
269 old = hton16(self.frag)
270 old =
band(old, 0xe000)
272 self.frag = hton16(
bor(old,
int))
275 --- Retrieve the fragment.
276 --- @return Fragment as 13 bit integer.
278 return
band(hton16(self.frag), 0x1fff)
281 --- Retrieve the fragemt.
282 --- @return Fragment as
string.
287 --- Set the time-to-live (TTL).
288 --- @param
int TTL of the
ip header as 8 bit integer.
294 --- Retrieve the time-to-live.
295 --- @return TTL as 8 bit integer.
300 --- Retrieve the time-to-live.
301 --- @return TTL as
string.
306 --- Set the next layer protocol.
307 --- @param
int Next layer protocol of the
ip header as 8 bit integer.
313 --- Retrieve the next layer protocol.
314 --- @return Next layer protocol as 8 bit integer.
319 --- Retrieve the next layer protocol.
320 --- @return Next layer protocol as
string.
331 elseif proto ==
ip.PROTO_ESP then
333 elseif proto ==
ip.PROTO_AH then
336 cleartext = "(unknown)"
339 return format("0x%02x %s", proto, cleartext)
343 --- @param
int Checksum of the
ip header as 16 bit integer.
348 self.cs = hton16(
int)
352 --- @return Checksum as 16 bit integer.
354 return hton16(self.cs)
358 --- @return Checksum as
string.
364 --- If possible use
checksum offloading instead.
367 self:
setChecksum() -- just to be sure (packet may be reused); must be 0
371 --- Set the destination address.
372 --- @param
int Address in 'union ip4_address' format.
377 --- Retrieve the destination IP address.
378 --- @return Address in 'union ip4_address' format.
380 return self.dst:
get()
383 --- Set the source address.
384 --- @param
int Address in 'union ip4_address' format.
389 --- Retrieve the source IP address.
390 --- @return Address in 'union ip4_address' format.
392 return self.src:
get()
395 --- Set the destination address.
396 --- @param str Address in
string format.
401 --- Retrieve the destination IP address.
402 --- @return Address in
string format.
407 --- Set the source address.
408 --- @param str Address in
string format.
413 --- Retrieve the source IP address.
414 --- @return Address in
string format.
419 --- Set all members of the
ip header.
420 --- Per default, all members are
set to default values specified in the respective
set function.
421 --- Optional named arguments can be used to
set a member to a user-provided value.
422 --- @param args Table of named arguments. Available arguments: Version, HeaderLength, TOS, Length, ID, Flags, Fragment, TTL, Protocol, Checksum, Src, Dst
423 --- @param pre prefix for namedArgs. Default 'ip4'.
425 ---
fill() --- only default values
426 ---
fill{ ipSrc=
"1.1.1.1", ipTTL=100 } --- all members are
set to
default values with the exception of ipSrc and ipTTL
434 self:
setTOS(args[pre ..
"TOS"])
436 self:
setID(args[pre ..
"ID"])
439 self:
setTTL(args[pre ..
"TTL"])
443 local src = pre ..
"Src"
444 local dst = pre ..
"Dst"
445 args[src] = args[src] or
"192.168.1.1"
446 args[dst] = args[dst] or
"192.168.1.2"
448 --
if for some reason the address is in
'union ip4_address' format, cope with it
449 if type(args[src]) ==
"string" then
454 if type(args[dst]) ==
"string" then
461 --- Retrieve the values of all members.
462 --- @param pre prefix
for namedArgs. Default
'ip4'.
463 --- @
return Table of named arguments. For a list of arguments see
"See also".
473 args[pre .. "TOS"] = self:
getTOS()
475 args[pre .. "ID"] = self:
getID()
476 args[pre .. "Flags"] = self:
getFlags()
478 args[pre .. "TTL"] = self:
getTTL()
485 --- Retrieve the values of all members.
486 --- @return Values in
string format.
494 -- Maps headers to respective protocol value.
495 -- This list should be extended whenever a
new protocol is added to 'IPv4 constants'.
496 local mapNameProto = {
504 --- Resolve which header comes after
this one (in a packet).
505 --- For instance: in tcp/
udp based on the ports.
506 --- This
function must exist and is only used when
get/
dump is executed on
507 --- an unknown (mbuf not yet casted to e.g. tcpv6 packet) packet (mbuf)
508 --- @
return String next header (e.g.
'udp',
'icmp', nil)
511 for name, _proto in pairs(mapNameProto) do
512 if proto == _proto then
519 --- Change the default values for namedArguments (for
fill/
get).
520 --- This can be used to for instance calculate a length value based on the total packet length.
522 --- This function must exist and is only used by packet.
fill.
523 --- @param pre The prefix used for the namedArgs, e.g. 'ip4'
524 --- @param namedArgs Table of named arguments (see See Also)
525 --- @param nextHeader The header following after this header in a packet
526 --- @param accumulatedLength The so far accumulated length for previous headers in a packet
527 --- @return Table of namedArgs
531 if not namedArgs[pre .. "Length"] and namedArgs["pktLength"] then
532 namedArgs[pre .. "Length"] = namedArgs["pktLength"] - accumulatedLength
536 if not namedArgs[pre .. "Protocol"] then
537 for name, type in pairs(mapNameProto) do
538 if nextHeader == name then
539 namedArgs[pre .. "Protocol"] = type
548 ----------------------------------------------------------------------------------
550 ----------------------------------------------------------------------------------
552 --- Cast the packet to an IP4 packet
554 --- Cast the packet to either an IP4 (nil/true) or IP6 (false) packet, depending on the passed
boolean.
556 ip4 = ip4 == nil or ip4
565 ------------------------------------------------------------------------
567 ------------------------------------------------------------------------
function ip4Header setProtocol(int)
Set the next layer protocol.
function ip4Header setFlags(int)
Set the flags.
pkt getIP6Packet
Cast the packet to an IP6 packet.
function ip4Header getChecksum()
Retrieve the checksum.
local ffi
low-level dpdk wrapper
function checksum(data, len)
Calculate a 16 bit checksum.
function ip4Header getFragment()
Retrieve the fragment.
function parseIPAddress(ip)
Parse a string to an IP address.
function ip4Header getProtocolString()
Retrieve the next layer protocol.
function pkt offloadUdpChecksum(ipv4, l2_len, l3_len)
Instruct the NIC to calculate the IP and UDP checksum for this packet.
function bswap16(n)
Byte swap for 16 bit integers.
function ip4Addr setString(ip)
Set the IPv4 address.
function ip4Header setSrc(int)
Set the source address.
function ip4Header getVersionString()
Retrieve the version.
function packetCreate(...)
Create struct and functions for a new packet.
function ip4Header getTTLString()
Retrieve the time-to-live.
function mod band(mask1, mask2, result)
Bitwise and.
function ip4Header setHeaderLength(int)
Set the header length.
function ip4Header getHeaderLength()
Retrieve the header length.
function ip4Header setSrcString(str)
Set the source address.
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct.
function ip4Header getFlags()
Retrieve the flags.
function ip4Header setDst(int)
Set the destination address.
function ip4Header getLengthString()
Retrieve the length.
function ip4Header getLength()
Retrieve the length.
function ip4Addr set(ip)
Set the IPv4 address.
function ip4Header fill(args, pre)
Set all members of the ip header.
function ip4Header setVersion(int)
Set the version.
function ip4Header getFragmentString()
Retrieve the fragemt.
local udp
Udp protocol constants.
function ip4Addr __eq(lhs, rhs)
Test equality of two IPv4 addresses.
ip PROTO_ICMP
Protocol field value for Icmp.
function ip4Header setLength(int)
Set the total length.
function ip4Addr get()
Retrieve the IPv4 address.
ip PROTO_TCP
Protocol field value for Tcp.
function mod bor(mask1, mask2, result)
Bitwise or.
function ip4Header setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
Change the default values for namedArguments (for fill/get).
function ip4Header setChecksum(int)
Set the checksum.
function ip4Header setDstString(str)
Set the destination address.
function ip4Header getDst()
Retrieve the destination IP address.
function ip4Header getSrc()
Retrieve the source IP address.
function ip4Addr __sub(val)
Subtract a number from an IPv4 address.
function ip4Addr add(val)
Add a number to an IPv4 address in-place.
function ip4Header getTOS()
Retrieve the type of service.
function ip4Addr getString()
Retrieve the string representation of the IPv4 address.
function ip4Header setID(int)
Set the identification.
function ip4Header setTOS(int)
Set the type of service (TOS).
local ip4Addr
Module for ip4_address struct (see headers.lua).
pkt getIP4Packet
Cast the packet to an IP4 packet.
function ip4Header getIDString()
Retrieve the identification.
function ip4Header getHeaderLengthString()
Retrieve the header length.
function ip4Header getTOSString()
Retrieve the type of service.
local eth
Ethernet protocol constants.
function ip4Header getChecksumString()
Retrieve the checksum.
ip PROTO_UDP
Protocol field value for Udp.
function ip4Header getProtocol()
Retrieve the next layer protocol.
local ip
IP4 protocol constants.
function ip4Header setFragment(int)
Set the fragment.
function ip4Header getSrcString()
Retrieve the source IP address.
local pkt
Module for packets (rte_mbuf)
function mod bnot(mask, result)
Bitwise not.
function ip4Header getFlagsString()
Retrieve the flags.
n
Create a new array of memory buffers (initialized to nil).
local ip4Header
Module for ip4_header struct (see headers.lua).
function ip4Header getTTL()
Retrieve the time-to-live.
function ip4Header getID()
Retrieve the identification.
function ip4Header calculateChecksum()
Calculate and set the checksum.
function ip4Header setTTL(int)
Set the time-to-live (TTL).
pkt getIPPacket
Cast the packet to either an IP4 (nil/true) or IP6 (false) packet, depending on the passed boolean...
function ip4Header getVersion()
Retrieve the version.
local icmp
Icmp4 protocol constants.
function ip4Addr __add(lhs, rhs)
Add a number to an IPv4 address.
function ip4Header getDstString()
Retrieve the destination IP address.
function ip4Header resolveNextHeader()
Resolve which header comes after this one (in a packet).