Just testing this blog, why not writing a post as an exercise. 🙂
In big projects I have hundreds of sub networks. There’s a lot of small transport networks with small subnet masks, that partition a summarizing net, and there are gateways. All these data is part of documentation and drawings. When I have a second project of the same kind, I can re-use documentation and drawings, just based on another IP address range. Will I calculate all again, typing the new IP addresses into each place at the drawings and docs? No, I like to automate it. TeX can do it.
You all know, what an IP address is:
I chose Lua for calculating things, and LuaLaTeX compiles my documents. I will post a simplified example here.
On the Internet, I found a nice snippet ipv4.lua by Nick Barret, so I did not have to program all myself. How to use it? Here are basic steps for a possible implementation:
- Add
\usepackage{luacode}
to your preamble - Get some Lua code (google for <keyword> and Lua) or program yourself
- Use the code as argument of a
\luaexec
command - Modify the Lua code a bit:
-
- remove Lua comments or change them (incompatible syntax)
- quote % by a backslash:
\%
- quote backslashes, such as here:
tex.sprint( "\\def\\ipDevice{#1}" )
- Instead of
print
, usetex.sprint
for handing over things to TeX
A compilable demo:
\documentclass{article} \usepackage{luacode} \newcommand{\ip}[2]{% \luaexec{ local ip1= string.gsub("#1", "\%.(\%d+).(\%d+).(\%d+)","") local ip2= string.gsub("#1", "(\%d+)\%.","",1) local ip2= string.gsub(ip2, "\%.(\%d+).(\%d+)","") local ip3= string.gsub("#1", "(\%d+)\%.(\%d+)\%.","",1) local ip3= string.gsub(ip3, "\%.(\%d+)","") local ip4= string.gsub("#1", "(\%d+)\%.(\%d+)\%.(\%d+)\%.","",1) local mask = #2 local ip = { tonumber( ip1 ), tonumber( ip2 ), tonumber( ip3 ), tonumber( ip4 ) } local masks = { [1] = { 127, 255, 255, 255 }, [2] = { 63, 255, 255, 255 }, [3] = { 31, 255, 255, 255 }, [4] = { 15, 255, 255, 255 }, [5] = { 7, 255, 255, 255 }, [6] = { 3, 255, 255, 255 }, [7] = { 1, 255, 255, 255 }, [8] = { 0, 255, 255, 255 }, [9] = { 0, 127, 255, 255 }, [10] = { 0, 63, 255, 255 }, [11] = { 0, 31, 255, 255 }, [12] = { 0, 15, 255, 255 }, [13] = { 0, 7, 255, 255 }, [14] = { 0, 3, 255, 255 }, [15] = { 0, 1, 255, 255 }, [16] = { 0, 0, 255, 255 }, [17] = { 0, 0, 127, 255 }, [18] = { 0, 0, 63, 255 }, [19] = { 0, 0, 31, 255 }, [20] = { 0, 0, 15, 255 }, [21] = { 0, 0, 7, 255 }, [22] = { 0, 0, 3, 255 }, [23] = { 0, 0, 1, 255 }, [24] = { 0, 0, 0, 255 }, [25] = { 0, 0, 0, 127 }, [26] = { 0, 0, 0, 63 }, [27] = { 0, 0, 0, 31 }, [28] = { 0, 0, 0, 15 }, [29] = { 0, 0, 0, 7 }, [30] = { 0, 0, 0, 3 }, [31] = { 0, 0, 0, 1 } } local wildcard = masks[tonumber( mask )] local ipcount = math.pow( 2, ( 32 - mask ) ) local bottomip = {} for k, v in pairs( ip ) do if wildcard[k] == 0 then bottomip[k] = v elseif wildcard[k] == 255 then bottomip[k] = 0 else local mod = v \% ( wildcard[k] + 1 ) bottomip[k] = v - mod end end local topip = {} for k, v in pairs( bottomip ) do topip[k] = v + wildcard[k] end tex.sprint( "\def\ipMask{" .. 255-wildcard[1] .. "." .. 255-wildcard[2] .. "." .. 255-wildcard[3] .. "." .. 255-wildcard[4].. "}" ) local isnetworkip = ( ip[1] == bottomip[1] and ip[2] == bottomip[2] and ip[3] == bottomip[3] and ip[4] == bottomip[4] ) local isbroadcastip = ( ip[1] == topip[1] and ip[2] == topip[2] and ip[3] == topip[3] and ip[4] == topip[4] ) tex.sprint( "\def\ipDevice{#1}" ) tex.sprint( "\def\ipNetwork{" .. bottomip[1] .. "." .. bottomip[2] .. "." .. bottomip[3] .. "." .. bottomip[4] .. "/" .. mask .. "}" ) tex.sprint( "\def\ipGateway{" .. bottomip[1] .. "." .. bottomip[2] .. "." .. bottomip[3] .. "." .. bottomip[4]+1 .. "}" ) tex.sprint( "\def\ipBroadcast{" .. topip[1] .. "." .. topip[2] .. "." .. topip[3] .. "." .. topip[4] .. "}" ) tex.sprint( "\def\ipHostRange{" .. bottomip[1] .. "." .. bottomip[2] .. "." .. bottomip[3] .. "." .. bottomip[4] + 2 .. " - " .. topip[1] .. "." .. topip[2] .. "." .. topip[3] .. "." .. topip[4] - 1 .. "}") }} \begin{document} \ip{10.240.3.38}{29} Network data for device \ipDevice: \bigskip \begin{tabular}{rl} Subnet: & \ipNetwork \ Subnet mask: & \ipMask \ Gateway: & \ipGateway \ Broadcast: & \ipBroadcast \ Host range: & \ipHostRange \ \end{tabular} \end{document}
In this demo, I specified a device IP and its net mask, an got these values in return:
Network data for device 10.240.3.38:
Subnet: 10.240.3.32/29
Subnet mask: 255.255.255.248
Gateway: 10.240.3.33
Broadcast: 10.240.3.39
Host range: 10.240.3.34 – 10.240.3.38
In the real world, I use loops to fill tables with such data or use it in labels on edges in TikZ drawings, such as here: