* * * * *

      An update to a quick note on embedding languages within languages

In making this comment [1] I came across this old post of mine from 2007 [2]
where I lament the amount of code required to query SNMP (Simple Network
Management Protocol) values in C. I took one look at the code I wanted:

> OID sys = SNMPv2-MIB::sysObjectID.0;
>
> if (sys == SNMPv2-SMI::enterprises.5567.1.1)  /* riverstone */
> {
>   IpAddress destination[] = IP-MIB::ip.24.4.1.1;
>   IpAddress mask[]        = IP-MIB::ip.24.4.1.2;
>   IpAddress nexthop[]     = IP-MIB::ip.24.4.1.4;
>   int       protocol[]    = IP-MIB::ip.24.4.1.7;
>   int       age[]         = IP-MIB::ip.24.4.1.8;
>   int       metric[]      = IP-MIB::ip.24.4.1.11;
>   int       type[]        = IP-MIB::ip.24.4.1.6;
> }
> else if (sys == SNMPv2-SMI::enterprises.9.1)  /* cisco */
> {
>   IpAddress destination[] = RFC1213-MIB::ipRouteDest;
>   IpAddress mask[]        = RFC1213-MIB::ipRouteMask;
>   IpAddress nexthop[]     = RFC1213-MIB::ipRouteNextHop;
>   int       protocol[]    = RFC1213-MIB::ipRouteProto;
>   int       age[]         = RFC1213-MIB::ipRouteAge;
>   int       metric[]      = RFC1213-MIB::ipRouteMetric1;
>   int       type[]        = RFC1213-MIB::ipRouteType;
> }
>
> for (i = 0 ; i < destination.length; i++)
> {
>     print(
>         destination[i],
>         mask[i],
>         nexthop[i],
>         snmp.protocol(protocol[i]),
>         metric[i],
>         age[i]
>     );
> }
>

and remembered—I did that!

Yup. Back in September of 2009 when I first started playing around with Lua
[3]. I installed the SNMP bindings for Lua [4] and wrote the following:

> #!/usr/local/bin/lua
>
> -- http://luasnmp.luaforge.net/snmp.html
>
> snmp = require "snmp"
> OID  = snmp.mib.oid
>
> routeprotos =
> {
>   "other    ",  "local    ",  "netmgmt  ",  "redirect ",
>   "egp      ",  "ggp      ",  "hello    ",  "rip      ",
>   "is-is    ",  "es-is    ",  "igrp     ",  "bbnspf   ",
>   "ospf     ",  "bgp      "
> }
>
> print("  Dest           Mask           NextHop         Proto   Metric Age")
> print("-------------------------------------------------------------------------------")
>
> router = assert(snmp.open{
>                 peer      = arg[1] or "XXXXXXXXXXXXXXXXXXXXXXXXX" ,
>                 community = arg[2] or "XXXXXXXXX"
>                 })
>
> cisco      = OID "SNMPv2-SMI::enterprises.9.1"
> riverstone = OID "SNMPv2-SMI::enterprises.5567.1.1"
> sysid      = router["SNMPv2-MIB::sysObjectID.0"]
>
> if string.find(sysid,cisco,1,true) then
>   shouldbe = OID "RFC1213-MIB::ipRouteDest"
>   result   =
>   {
>     { oid = "RFC1213-MIB::ipRouteDest" } ,
>     { oid = "RFC1213-MIB::ipRouteMask" } ,
>     { oid = "RFC1213-MIB::ipRouteNextHop" } ,
>     { oid = "RFC1213-MIB::ipRouteProto" } ,
>     { oid = "RFC1213-MIB::ipRouteMetric1" } ,
>     { oid = "RFC1213-MIB::ipRouteAge" } ,
>   }
> elseif string.find(sysid,riverstone,1,true) then
>   shouldbe = OID "IP-MIB::ip.24.4.1.1"
>   result =
>   {
>     { oid = "IP-MIB::ip.24.4.1.1"  } ,
>     { oid = "IP-MIB::ip.24.4.1.2"  } ,
>     { oid = "IP-MIB::ip.24.4.1.4"  } ,
>     { oid = "IP-MIB::ip.24.4.1.7"  } ,
>     { oid = "IP-MIB::ip.24.4.1.11" } ,
>     { oid = "IP-MIB::ip.24.4.1.8" } ,
>   }
> end
>
> repeat
>   result,err = snmp.getnext(router,result);
>
>   if result ~= nil then
>     if string.find(result[1].oid,shouldbe,1,true) == nil then break end
>
>     print(string.format("%-16s",result[1].value)
>         .. string.format("%-16s",result[2].value)
>         .. string.format("%-16s",result[3].value)
>         .. routeprotos[result[4].value]
>         .. string.format("%-6d",result[5].value)
>         .. string.format("%-6d",result[6].value)
>     )
>   end
> until false
> os.exit(0)
>

[1] http://www.flutterby.com/archives/comments/13301.html#artid_46233
[2] gopher://gopher.conman.org/0Phlog:2007/01/19.2
[3] http://www.lua.org/
[4] http://luasnmp.luaforge.net/snmp.html

Email author at [email protected]