1 ------------------------------------------------------------------------
3 --- @brief Internet protocol (v6) utility.
4 --- Utility functions for the ip6_address and ip6_header structs
5 --- defined in \ref headers.lua . \
n
8 --- - IP6 address utility
9 --- - IP6 header utility
10 --- - Definition of IP6 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 --- IP6 protocol constants
34 --- NextHeader field value
for Tcp
36 --- NextHeader field value
for Udp
38 --- NextHeader field value
for Icmp
39 ip6.PROTO_ICMP = 0x3a -- 58
44 -------------------------------------------------------------------------------------
46 -------------------------------------------------------------------------------------
48 --- Module
for ip6_address
struct (see \ref headers.lua).
51 local ip6AddrType =
ffi.typeof(
"union ip6_address")
53 --- Retrieve the IPv6 address.
54 --- @
return Address in
'union ip6_address' format.
56 local addr = ip6AddrType()
57 addr.uint32[0] = bswap(
self.uint32[3])
58 addr.uint32[1] = bswap(self.uint32[2])
59 addr.uint32[2] = bswap(self.uint32[1])
60 addr.uint32[3] = bswap(self.uint32[0])
64 --- Set the IPv6 address.
65 --- @param addr Address in 'union ip6_address' format.
67 self.uint32[0] = bswap(addr.uint32[3])
68 self.uint32[1] = bswap(addr.uint32[2])
69 self.uint32[2] = bswap(addr.uint32[1])
70 self.uint32[3] = bswap(addr.uint32[0])
73 --- Set the IPv6 address.
74 --- @param
ip Address in
string format.
79 --- Test equality of two IPv6 addresses.
80 --- @param lhs Address in 'union ip6_address' format.
81 --- @param rhs Address in 'union ip6_address' format.
82 --- @return true if equal, false otherwise.
84 return istype(ip6AddrType, lhs) and istype(ip6AddrType, rhs) and lhs.uint64[0] == rhs.uint64[0] and lhs.uint64[1] == rhs.uint64[1]
87 --- Add a number to an IPv6 address.
88 --- Max. 64bit, commutative.
89 --- @param lhs Address in 'union ip6_address' format.
90 --- @param rhs Number to
add (64 bit integer).
91 --- @return Resulting address in 'union ip6_address' format.
93 -- calc
ip (self) + number (val)
95 if istype(ip6AddrType, lhs) then
99 -- commutative for number +
ip
102 end -- TODO:
ip +
ip?
103 local addr = ip6AddrType()
104 local low, high = self.uint64[0], self.uint64[1]
107 if low < val and val > 0 then
110 elseif low > -val and val < 0 then
114 addr.uint64[1] = high
118 --- Add a number to an IPv6 address in-place.
120 --- @param val Number to
add (64 bit integer).
122 -- calc
ip (self) + number (val)
123 local low, high = bswap(self.uint64[1]), bswap(self.uint64[0])
126 if low < val and val > 0 then
129 elseif low > -val and val < 0 then
132 self.uint64[1] = bswap(low)
133 self.uint64[0] = bswap(high)
136 --- Subtract a number from an IPv6 address.
138 --- @param val Number to substract (64 bit integer).
139 --- @return Resulting address in 'union ip6_address' format.
144 --- Retrieve the
string representation of an IPv6 address.
145 --- Assumes 'union ip6_address' is in network byteorder.
146 --- @param doByteSwap Optional change the byteorder of the
ip6 address before returning the
string representation.
147 --- @return Address in
string format.
149 doByteSwap = doByteSwap or false
154 return ("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"):format(
155 self.uint8[0], self.uint8[1], self.uint8[2], self.uint8[3],
156 self.uint8[4], self.uint8[5], self.uint8[6], self.uint8[7],
157 self.uint8[8], self.uint8[9], self.uint8[10], self.uint8[11],
158 self.uint8[12], self.uint8[13], self.uint8[14], self.uint8[15]
163 ------------------------------------------------------------------------------
165 ------------------------------------------------------------------------------
167 --- Module for ip6_header struct (see \ref headers.lua).
172 --- @param
int IP6 header version as 4 bit integer. Should always be
'6'.
175 int =
band(lshift(
int, 28), 0xf0000000) --
fill to 32 bits
177 old = bswap(self.vtf)
178 old =
band(old, 0x0fffffff) -- remove old value
180 self.vtf = bswap(
bor(old,
int))
183 --- Retrieve the version.
184 --- @return Version as 4 bit integer.
186 return
band(rshift(bswap(self.vtf), 28), 0x0000000f)
189 --- Retrieve the version.
190 --- @return Version as
string.
195 --- Set the traffic class.
196 --- @param
int Traffic class of the
ip6 header as 8 bit integer.
199 int =
band(lshift(
int, 20), 0x0ff00000)
201 old = bswap(self.vtf)
202 old =
band(old, 0xf00fffff)
204 self.vtf = bswap(
bor(old,
int))
207 --- Retrieve the traffic class.
208 --- @return Traffic class as 8 bit integer.
210 return
band(rshift(bswap(self.vtf), 20), 0x000000ff)
213 --- Retrieve the traffic class.
214 --- @return Traffic class as
string.
219 --- Set the flow label.
220 --- @param
int Flow label of the
ip6 header as 20 bit integer.
223 int =
band(
int, 0x000fffff)
225 old = bswap(self.vtf)
226 old =
band(old, 0xfff00000)
228 self.vtf = bswap(
bor(old,
int))
231 --- Retrieve the flow label.
232 --- @return Flow label as 20 bit integer.
234 return
band(bswap(self.vtf), 0x000fffff)
237 --- Retrieve the flow label.
238 --- @return Flow label as
string.
243 --- Set the payload length.
244 --- @param
int Length of the
ip6 header payload (hence, excluding l2 and l3 headers). 16 bit integer.
246 int =
int or 8 -- with
eth + UDP -> minimum 66
247 self.len = hton16(
int)
250 --- Retrieve the length.
251 --- @return Length as 16 bit integer.
253 return hton16(self.len)
256 --- Retrieve the length.
257 --- @return Length as
string.
262 --- Set the next header.
263 --- @param
int Next header of the
ip6 header as 8 bit integer.
266 self.nextHeader =
int
269 --- Retrieve the next header.
270 --- @return Next header as 8 bit integer.
272 return self.nextHeader
275 --- Retrieve the next header.
276 --- @return Next header as
string.
287 elseif proto ==
ip6.PROTO_ESP then
289 elseif proto ==
ip6.PROTO_AH then
292 cleartext = "(unknown)"
295 return format("0x%02x %s", proto, cleartext)
298 --- Set the time-to-live (TTL).
299 --- @param
int TTL of the
ip6 header as 8 bit integer.
305 --- Retrieve the time-to-live.
306 --- @return TTL as 8 bit integer.
311 --- Retrieve the time-to-live.
312 --- @return TTL as
string.
317 --- Set the destination address.
318 --- @param addr Address in 'union ip6_address' format.
323 --- Retrieve the IP6 destination address.
324 --- @return Address in 'union ip6_address' format.
326 return self.dst:
get()
329 --- Set the source address.
330 --- @param addr Address in 'union ip6_address' format.
335 --- Retrieve the IP6 source address.
336 --- @return Address in 'union ip6_address' format.
338 return self.src:
get()
341 --- Set the destination address.
342 --- @param str Address in
string format.
347 --- Retrieve the IP6 destination address.
348 --- @return Address in
string format.
353 --- Set the source address.
354 --- @param str Address in
string format.
359 --- Retrieve the IP6 source address.
360 --- @return Address in source format.
365 --- Set all members of the
ip6 header.
366 --- Per default, all members are
set to default values specified in the respective
set function.
367 --- Optional named arguments can be used to
set a member to a user-provided value.
368 --- @param args Table of named arguments. Available arguments: ip6Version, ip6TrafficClass, ip6FlowLabel, ip6Length, ip6NextHeader, ip6TTL, ip6Src, ip6Dst
369 --- @param pre prefix for namedArgs. Default '
ip6'.
371 ---
fill() --- only default values
372 ---
fill{ ip6Src=
"f880::ab", ip6TTL=101 } --- all members are
set to
default values with the exception of ip6Src and ip6TTL
383 self:
setTTL(args[pre ..
"TTL"])
385 local src = pre ..
"Src"
386 local dst = pre ..
"Dst"
387 args[src] = args[src] or
"fe80::1"
388 args[dst] = args[dst] or
"fe80::2"
390 --
if for some reason the address is in
'union ip6_address' format, cope with it
391 if type(args[src]) ==
"string" then
396 if type(args[dst]) ==
"string" then
403 --- Retrieve the values of all members.
404 --- @param pre prefix
for namedArgs. Default
'ip6'.
405 --- @
return Table of named arguments. For a list of arguments see
"See also".
418 args[pre .. "TTL"] = self:
getTTL()
423 --- Retrieve the values of all members.
424 --- @return Values in
string format.
431 -- Maps headers to respective nextHeader value.
432 -- This list should be extended whenever a
new protocol is added to 'IPv6 constants'.
433 local mapNameProto = {
441 --- Resolve which header comes after
this one (in a packet).
442 --- For instance: in tcp/
udp based on the ports.
443 --- This
function must exist and is only used when
get/
dump is executed on
444 --- an unknown (mbuf not yet casted to e.g. tcpv6 packet) packet (mbuf)
445 --- @
return String next header (e.g.
'udp',
'icmp', nil)
448 for name, _proto in pairs(mapNameProto) do
449 if proto == _proto then
456 --- Change the default values for namedArguments (for
fill/
get).
457 --- This can be used to for instance calculate a length value based on the total packet length.
459 --- This function must exist and is only used by packet.
fill.
460 --- @param pre The prefix used for the namedArgs, e.g. '
ip6'
461 --- @param namedArgs Table of named arguments (see See Also)
462 --- @param nextHeader The header following after this header in a packet
463 --- @param accumulatedLength The so far accumulated length for previous headers in a packet
464 --- @return Table of namedArgs
468 if not namedArgs[pre .. "Length"] and namedArgs["pktLength"] then
469 namedArgs[pre .. "Length"] = namedArgs["pktLength"] - (accumulatedLength + 40)
473 if not namedArgs[pre .. "NextHeader"] then
474 for name, type in pairs(mapNameProto) do
475 if nextHeader == name then
476 namedArgs[pre .. "NextHeader"] = type
484 ----------------------------------------------------------------------------------
486 ----------------------------------------------------------------------------------
488 --- Cast the packet to an IP6 packet
492 ------------------------------------------------------------------------
494 ------------------------------------------------------------------------
local ip6Addr
Module for ip6_address struct (see headers.lua).
pkt getIP6Packet
Cast the packet to an IP6 packet.
function ip6Header getFlowLabelString()
Retrieve the flow label.
local ffi
low-level dpdk wrapper
function ip6Header getDstString()
Retrieve the IP6 destination address.
function ip6Addr getString(doByteSwap)
Retrieve the string representation of an IPv6 address.
function ip6Header setNextHeader(int)
Set the next header.
function ip6Header setFlowLabel(int)
Set the flow label.
function ip6Header getNextHeader()
Retrieve the next header.
function bswap16(n)
Byte swap for 16 bit integers.
function packetCreate(...)
Create struct and functions for a new packet.
function ip6Header setSrc(addr)
Set the source address.
ip6 PROTO_ICMP
NextHeader field value for Icmp.
function mod band(mask1, mask2, result)
Bitwise and.
function ip6Header setSrcString(str)
Set the source address.
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct.
function ip6Header fill(args, pre)
Set all members of the ip6 header.
function ip6Addr get()
Retrieve the IPv6 address.
function ip6Header getSrcString()
Retrieve the IP6 source address.
function ip6Addr add(val)
Add a number to an IPv6 address in-place.
function ip6Addr __eq(lhs, rhs)
Test equality of two IPv6 addresses.
local udp
Udp protocol constants.
function mod bor(mask1, mask2, result)
Bitwise or.
function ip6Header getTTLString()
Retrieve the time-to-live.
ip6 PROTO_TCP
NextHeader field value for Tcp.
function ip6Header getTrafficClass()
Retrieve the traffic class.
function ip6Header setLength(int)
Set the payload length.
function ip6Header getVersionString()
Retrieve the version.
function ip6Header setTTL(int)
Set the time-to-live (TTL).
function ip6Header setDst(addr)
Set the destination address.
function ip6Addr set(addr)
Set the IPv6 address.
function ip6Header getTTL()
Retrieve the time-to-live.
function parseIP6Address(ip)
Parse a string to an IPv6 address.
local eth
Ethernet protocol constants.
local ip6
IP6 protocol constants.
function ip6Header getSrc()
Retrieve the IP6 source address.
local ip
IP4 protocol constants.
local pkt
Module for packets (rte_mbuf)
function ip6Header getLengthString()
Retrieve the length.
function mod bnot(mask, result)
Bitwise not.
ip6 PROTO_UDP
NextHeader field value for Udp.
function ip6Header getLength()
Retrieve the length.
n
Create a new array of memory buffers (initialized to nil).
function ip6Addr __sub(val)
Subtract a number from an IPv6 address.
function ip6Header resolveNextHeader()
Resolve which header comes after this one (in a packet).
function ip6Header getVersion()
Retrieve the version.
function ip6Header getTrafficClassString()
Retrieve the traffic class.
function ip6Header getDst()
Retrieve the IP6 destination address.
local ip6Header
Module for ip6_header struct (see headers.lua).
function ip6Header setVersion(int)
Set the version.
function ip6Header setTrafficClass(int)
Set the traffic class.
function ip6Header setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
Change the default values for namedArguments (for fill/get).
local icmp
Icmp4 protocol constants.
function ip6Header getNextHeaderString()
Retrieve the next header.
function ip6Header getFlowLabel()
Retrieve the flow label.
function ip6Addr setString(ip)
Set the IPv6 address.
function ip6Addr __add(lhs, rhs)
Add a number to an IPv6 address.
function ip6Header setDstString(str)
Set the destination address.