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.