Lua for Scripting

AT MY DAILY work we use MIB’s extensively for product configurations. This often brings up the need to recreate a certain configuration sequence. If the scequence is not included in the normal test suite, and the sequence is more that just a couple of OID’s, I usually create a small Lua script to perform the MIB configuration.

Currently I am using Lua for scripting and the Net-Snmp command line tools as backend.

Here follows a simplified example of my normal Lua scripts. First step is to define the OID’s to use. I collect these in a file called Mibs.lua

1
2
3
4
5
6
7
8
9
10
11
#!lua
--[[
      Net-Snmp datatypes:
         i: INTEGER, u: unsigned INTEGER, t: TIMETICKS, a: IPADDRESS
         o: OBJID, s: STRING, x: HEX STRING, d: DECIMAL STRING, b: BITS
         U: unsigned int64, I: signed int64, F: float, D: double
--]]
 
-- Standard MIB
Mib_sysName     = { "1.3.6.1.2.1.1.5", "s" }
Mib_sysLocation = { "1.3.6.1.2.1.1.6", "s" }

This file defines to tables containing each a OID prefix and the datatype.

Invoking the SNMP calls to perform the MIB manipulations is handled by a Lua class that wraps the Net-Snmp command line tools. This class is located in a file Snmp.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!lua
--[[
      SNMP by using Net-SNMP executeables
--]]
 
-- Mibs.lua provides MIB definitions.
mibs_lua = loadfile("Mibs.lua") -- Include the file in compilation
mibs_lua()                      -- Define its contents
 
 
CSnmp = {}
 
function CSnmp:new(o)
  -- Create object
  o = o or {}
 
  -- Set 'self' as prototype for the table (object)
  setmetatable(o, self)
  self.__index = self
 
  -- Initialize
  self:Initialize()
  return (o)
end
 
-- Initialize
function CSnmp:Initialize()
  self.dut  = "10.0.0.17"          -- IP of DUT
  --self.attr = "-r 3 -t 500 "     -- Three retry's with timeout of 500[ms]
  self.attr = "-r 0 "              -- No retry
  self.opt  = "-c private -v 2c "
  self.set  = "snmpset.exe "       -- Net-Snmp commandline tool for 'SET'
  self.get  = "snmpget.exe "       -- Net-Snmp commandline tool for 'GET'
end
 
--[[ MIB set.
     Set an OID for an optional line with a value.
     IN:    oid:       OID to set. Format is { "oid prefix", "type" }.
            component: Component specifier.
            value:     Value to set.
--]]
function CSnmp:Set(oid, component, value)
 
  -- Comprise OID prefix and component specifier (if any)
  local oidFull = oid[1] .. component;
 
  -- Append identify value type
  local cmdType = " " .. oid[2] .. " "
 
  -- Wrap string types in "'s
  local cmdValue
  if cmdType == " x " or cmdType == " s " then
    cmdValue = "\"" .. value .. "\""
  else
    cmdValue = value
  end
 
  -- Collect command line
  local cmd = self.set .. self.attr .. self.opt .. self.dut .. " " ..
          '"' .. oidFull .. '"' .. cmdType .. tostring(cmdValue)
 
  -- Run the external program with parameters
  --print(cmd)  -- Debug
  os.execute(cmd)
end
 
--[[ MIB get.
     Get an OID value.
     IN:    oid:    OID to set (including line if required).
--]]
function CSnmp:Get(oid)
  local cmd = self.get .. self.opt .. self.dut .. " " .. oid
  os.execute(cmd)
end

The table CSnmp defines a function new that provides object allocation and configuration for the Net-Snmp command line tools. Two methods are defined in the class: a Set and a Get. The method Set accepts a table of the kind defined in the file Mibs.lua. The component parameter is for adding “.0” or perhaps a table index to the OID. The simpler Get member accepts a full specified OID only.

The files created so far can be reused by all configuration scripts. An example of a configuration script could be to request the (configured) location of the device, and the set a new location.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!lua
 
-- Snmp.lua provides SNMP GET/SET functionality.
snmp_lua = loadfile("Snmp.lua") -- Include the file in compilation
snmp_lua()                      -- Define its contents
 
snmp = CSnmp:new()
 
print("GET Location:")
snmp:Get(Mib_sysLocation[1] .. ".0")
 
print("SET Location:")
snmp:Set(Mib_sysLocation, ".0", "Mars")
 
print("GET Location:")
snmp:Get(Mib_sysLocation[1] .. ".0")

Running the script produces the following output:

>sys.lua
  GET Location:
  iso.3.6.1.2.1.1.6.0 = STRING: "Moon"
  SET Location:
  1.3.6.1.2.1.1.6.0: "Mars"
  GET Location:
  iso.3.6.1.2.1.1.6.0 = STRING: "Mars"

The scripts started out as Python scripts. I then ported them all to Ruby just to compare the two languages. Finally I ported the scripts to Lua. For basic scripting, there is actually not much difference between Python, Ruby or Lua, other than perhaps the storage needs. The Lua interpreter and library footprint is about 200KB which is only a fraction of the space occupied by the ActivePython or ActiveRuby allowed for installation on our company computers. The small size is handy if moving the scripts to run directly on the closed network test equipment.

Placement new

REPLACEMENT NEW CAME to mind, when working on a C++ project of mine. In this project some large objects of short lifetime led to a concerns about memory fragmentation on the targeted embedded platform that have only sparse memory ressources. The life cycle of the objects was to create an object, then fill the large data member structures, store data for a while until time for transmitting the data and terminate the object. The object data where always different so they could not be reused, and the lifetime of each object was inditerminable. However it was certain that only a known maximum amount of objects would exist at the same time.

This senario made me think of a rarely used memory allocation functionality called placement new that would handle the above concerns perfectly. With this variant of new you allocate a memory pool of fixed memory address and size, from which allocations can be made from. This way placement new allows reuse of the same memory again and again and thus containing any memory fragmentation within the disposable memory pool.

Below is a simple example of how to use the placement new functionality.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <iomanip>
#include <new>
#include <stdio.h>
using namespace std;
 
class C
{
  public:
            C() : data(0x11) { ; }
            ~C() { data = 0x22; }
 
            char data;
};
 
int main(int argc, char *argv[])
{
  const int PoolItems = 6;
  const int PoolSize  = PoolItems * sizeof(C);
 
  // Allocate a memory pool
  char *pool = new char[PoolSize];
  memset(pool, 0x00, PoolSize);
 
  // Create some pointers to access pooled objects
  C *pC[PoolItems] = { 0 };
 
  // Allotate objects at "arbitary" addresses in the pool
  pC[1] = new (pool + sizeof(C)*1) C;
  pC[4] = new (pool + sizeof(C)*4) C;
 
  // Display constructed data
  for (int i = 0; i < PoolSize; i++)
    cout << setfill('0') << setw(2) << std::hex << (int)pool[i] << " ";
  cout << endl;
 
  // Explicit destruction of objects in pool
  for (int i = 0; i < PoolItems; i++)
  {
    if (pC[i] != NULL)
    {
      pC[i]->~C();  // Explicit destructor call
      pC[i] = NULL;
    }
  }
 
  // Display destructed data
  for (int i = 0; i < PoolSize; i++)
    cout << setfill('0') << setw(2) << std::hex << (int)pool[i] << " ";
  cout << endl;
 
  // Release memory in pool
  delete [] pool;
  pool = NULL;
 
  return EXIT_SUCCESS;
}

Explanation: First a memory pool is created that fits a fixed amount of the designated class objects. Two object are then created within pool slots 1 and 4. The simple byte sized class C has a contructor initialization of the member data.

The first printing of the pool will display the following contents:

00 11 00 00 11 00

This indicates that two slots are allocated with objects of the class C.

Destructing the objects are done by calling the destructor explicitly, NOT by normal delete action (as the memory pool original was created as a char array, the memory it occupies is tagged as a char array that must be deleted the approriate array delete operation). After destruction, the pool contents is displayed again, and it is seen that the same memory has been rewritten by the destructor assigning:

00 22 00 00 22 00

Finally the memory pool is deleted and the memory is released.

Stribed Cow

DON’T HAVE A cow man. Well I got one. I was given a Stribed Cow of the CowParade brand.

CowParade - Stribed Cow

At first one might get put off by this odd looking cow which is obviously contrary to the ways of nature (or you might just be repulsed by the pricetag on this thingy) – but I like it! There’s just something about it that makes me smile every time I look at it :-)

Beginning Lua Programming

I BOUGHT THIS book as a supplement to Programming in Lua, second edition in hope of getting things explained with more practical examples.

Beginning Lua Programming

Thankfully this is also the case for this book. There are many programming samples in this book that all takes great effort in elaborating the features or problems of the topic at hand.
The book starts out with the usual history lessen, but there after gets straight to the business of teaching Lua programming at beginners level. Beyond the explanation of variables, program flow controllers, calculation with numbers and string operations the writers spend lots of time explaining the immanent dynamic nature of Lua. Lua provides only a few versatile variable types and enforces only a few rules to what can’t be done, but for people not used to static language programming, it sometimes can be hard to wrap your mind around the dynamic possibilities. Luckily this book excels with thorough explanations along with carefully designed samples, all together giving great help during the learning process.

Overall I think this is a very good book for Lua beginners. It starts out with the basics and progresses to more advanced Lua programming topics. Especially the chapters explaining the inner workings of Lua and how to debug Lua applications are excellent qualities of this book. Otherwise the book covers in more or less details, just about all thinkable aspects of the Lua language, ranging from simple scripting to embedding Lua in C/C++ applications. And as a good jumping board into further Lua adventures, the book finishes of with some very good chapters describing how Lua can be used and extended with various 3rd party libraries.

A bit disappointing about this book however, is the minimal attention devoted to explain the object oriented capabilities of Lua. This is a powerful feature set of the language that deserves much better exposure than what is included in this book.
Another negative remark to the book is that the writers sometimes derail the context flow, and suddenly explain topics in sections or chapters where the topic otherwise seems unrelated and not directly associable.

Regarding the object oriented features of Lua, I have personally used this feature to convert some Python and Ruby scripts to Lua, and this was done with minimal effort thanks to the simple but versatile object system offered by Lua. Some would argue that OO issues would belong in a professional edition of the book but I disagree. There is not much more to tell about Lua than otherwise covered in this book. Except for the OO system, the rest is more a matter of “practices makes perfect”.

Rating: ★★★★☆

Programming in Lua, Second Edition

THIS BOOK IS indispensable when it comes to Lua programming.

Programming in Lua, Second Edition

It is written with great insight of the Lua language and its history (not surprisingly as it’s written by the creators for the official Lua implementation). The book starts of with the simple stuff and then progresses into the more advanced features, and even though the book is one of the thinner programming books, it manages to cover all aspects in Lua in great detail. This is possible due to the concise and to the point explanations supplemented with programming examples of equal qualities. The Lua concept of a multipurpose variable type called tables is thoroughly explained, also in the regards of utilizing tables for object oriented concepts in Lua.
The chapters of embedding Lua into C/C++ programs are very strong chapters, giving invaluable insight and information on the topic. I find myself returning to these chapters when in doubt on Lua and C/C++ interaction principals.

I would not recommend this book as the sole learning book if one is totally new to the Lua language. Several times one is urged to look topics up in the official reference book to totally grasp the situations highlighted. Also no repeating of previously learned facts is done in later pages. This is great if you are on top of things, but if being a complete beginner, repetition helps remembering.
The beginner will probably get a more gentle introduction to Lua with the book Beginning Lua Programming, but “Programming in Lua” is absolutely a must-have for the Lua enthusiast.

Rating: ★★★★☆

TheCamp

SO DID YOU get any hacking done this summer? I certainly did! I spent a hole week of my summer vacation attending the geek camp TheCamp (Danish). Along with roughly twenty of the forty participants, this was the first time of TheCamp’s six years of existence that I attended. The purpose of the TheCamp is to provide an opportunity for (whitehat) hackers to unite and do what they like the most: spend time at the computer. For people not to fuse entirely with their computers, the TheCamp had scheduled three daily informative speeches or educational lectures from various guest speakers and TheCamp attendees. Topics included beginner Linux training, advanced Vim usage, computer security, audio on Linux, network understanding and much more. Most sessions were informal (kind of BoF-session manor), allowing for everybody to fill in with additional information or personal views and experiences. This often led to very exiting discussions.

It was indeed a mixed group of people at the TheCamp. Ages ranged from a thirteen year old, accompanying his father, incrementing to a couple of people, of undisclosed age, who have had enjoyed their retirement for some years. The knowledgebase was very versatile too. Some were experts in Linux, others in networking, MAC OS X, Vim, security, audio, programming or even 3D graphics design (no Windows people it seemed). Others were at TheCamp to learn and benefit from the vast collective knowledgebase.

I started the week playing a bit with Elsa and Antlr, to investigate the possibilities of incorporating some C++ awareness to the old IDE we use at work. In both parsers I hit major problems when trying to parse STL code, so I ended up abandoned the idea (for now).

I then installed a InspIRCd IRC server on my headless Linux box. This was actually surprisingly easy to install and configure (although more tweaking can be done I’m sure), so with that success story I ventured on to learn some new programming skills.

At work I mainly program in C++ but I have decided to learn C# on the Mono framework. Additionally I want to learn some Lua for scripting and possibly some QT 4. I’ve bought a C# book (Professional C#) and a couple of Lua books (Beginning Lua Programming, Programming in Lua) to aid the learning process. I was somewhat disappointed by MonoDevelop. Apart from the instability problems, it was just to heavy an IDE for my laptop and the GUI is utter useless in a 1024×768 pixels resolution, so I settled on my usual editor of choice: Scribes. In a days work I managed to create a little C# program that had a QT 4 frontend (via Qyoto) and a small Lua script engine (via Tao.Lua) – it were lots of fun and a really exiting process, so definitely not my last programming with that constellation.

On the last day at TheCamp I was fortunate to be offered a used MacBook. My trusty old Asus A1000 laptop (600 MHz Celeron, 320 MB RAM) really really qualified for retirement and coincidentally I had long thought about acquiring a MAC. It didn’t require much consideration and now I am the happy owner of a cool black MacBook.

In conclusion the week at TheCamp was awesome, and I’ll definitely be ready next year when the ticket sale open.

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress