Wednesday, November 26, 2008

Extending Net-SNMP 5.4.2.1 Agent

This article describes how to extend Net-SNMP agent toolkit to instrument the EtherLike-MIB (RFC 3635) with hardcoded defaults. This article will describe the setup on windows (I used XP SP3) and Linux (I used openSUSE 11.0) required to develop this agent.

The following instructions were carried out for net-snmp source version 5.4.2.1. This article assumes the following default paths:

  1. Net-SNMP un-archived on windows in C:\net-snmp and ~/net-snmp on Linux.
  2. Net-SNMP installed in C:\usr on Windows and /usr/local on Linux.

1.1. Setup the development environment

  1. Download and install MSVC++ Express 2005 from http://www.microsoft.com/express/2005/download/default.aspx. There is some compilation issue of the net-snmp code with MSVC++ 2008 (Orcas) and i did not bother to fix it but used the 2005 instead.
  2. Download and setup platform sdk as described in http://www.microsoft.com/express/2005/platformsdk/default.aspx. Be sure to setup the development environment using the PSDK as described in the link step-wise.
  3. Download net-snmp source from http://www.net-snmp.org/download.html. The net-snmp version 5.4.2.1 can be downloaded from there.

1.2. Build and install net-snmp from source on windows

  1. Un-archive the net-snmp source to say c:\net-snmp.
  2. Follow the README.win32 to build the net-snmp code (Read the section Microsoft Visual C++ - Workspace – Building).
    1. We need to first load the winsdk.dsw in the MSVC++ 2005 express. Below is the screenshot of all projects that make up the win32sdk workspace in MSVC++.

clip_image002

Figure 1 - Projects in win32sdk.dsw

    1. Modify the win32\netsnmp\netsnmpconfig.h file to add:
               #define HAVE_WIN32_PLATFORM_SDK 1






    1. Build in order, the following project for (Release | Debug) configuration.





i. libagent



ii. libhelpers



iii. libnetsnmptrapd



iv. libsnmp



v. netsnmpmibsdk






    1. Go to Build > Batch Build… and select the (Debug | Release) configuration of all projects except for the ones you built in step c above.





  1. If everything is okay with setup, then build should go fine too.




  2. Using cmd line on windows, go to c:\net-snmp and run the command: win32\install_netsnmp.bat to install net-snmp you built above to location c:\usr.




  3. Set the c:\usr\bin to PATH environment variable for easy access to the command line snmp client and agent executables.




1.3. Build and install net-snmp from source on Linux





  1. Un-archive the net-snmp source to say ~/net-snmp.




  2. Follow the INSTALL to build the net-snmp code. Run the following commands on shell prompt:




    1. cd ~/net-snmp




    2. ./configure




    3. make




    4. make install (run as root)






The make install step will install the net-snmp binaries by default in /usr/local path.



1.4. Configuring the snmpd agent (snmpd.conf)





  1. Configure snmp agent by running snmpconf command (see man page) or copy the C:/net-snmp/Example.conf and modify.




    1. snmpconf –g basic_setup






  2. I used the following configuration. Copy-paste the text below into a file named snmpd.conf. The agent is configured for snmp v2c and with rwcommunity string of public.







com2sec local     localhost       public


 


group MyRWGroup    v1         local


group MyRWGroup    v2c        local


group MyRWGroup    usm        local


 


 


view all    included  .1                               80


 


 


#                context sec.model sec.level match  read   write  notif


access MyROGroup ""      any       noauth    exact  all    none   none


access MyRWGroup ""      any       noauth    exact  all    all    none


 


 


syslocation Right here, right now.


syscontact Me <me@somewhere.org>







  1. Save the file in path :




    1. C:\usr\etc\snmp\snmpd.conf (on Windows)




    2. /etc/snmp/snmpd.conf (on Linux)






1.5. Load the MIB module and generate the C code





  1. The EtherLike-MIB has 5 tables (columnar variables).




  2. For mib2c code generation I used linux host. Run the following commands on shell prompt:







mkdir ethmib_src


cd ethmib_src 


export MIBS=ALL 





EtherLike-MIB was part of the net-snmp distribution so all we need is to tell mib2c to use it by setting the environment variable MIBS.






mib2c –c mib2c.create-dataset.conf dot3StatsTable 





This will generate dot3StatsTable.c and dot3StatsTable.h files.



Similarly run the similar command for the other tables in the mib.






mib2c –c mib2c.create-dataset.conf dot3PauseTable 


mib2c –c mib2c.create-dataset.conf dot3HCStatsTable 


mib2c –c mib2c.create-dataset.conf dot3CollTable 


mib2c –c mib2c.create-dataset.conf dot3ControlTable 





Use the ethmib_src and use it for windows agent extension too.



1.6. Use the generated source files to instrument the mib on Windows





  • On Windows, the above generated source files can be copied to c:\net-snmp\agent\mibgroups. You may also create a folder names EtherLike-MIB and sub-folders for each table like dot3StatsTable etc, and keep the respective table *.c and *.h files in the folder with the table name.




  • Add the generated sources in the MSVC++ netsnmpmibssdk project as shown below:




clip_image004



Figure 2 - EtherLike-MIB files added to the netsnmpmibssdk project.





  • Add the dot3StatsTable.h and dot3StatsTable.c files to your 'netsnmpmibssdk' project in VC++.




  • Next edit the '<sourcedir>\win32\mib_module_includes.h' file to add an include to your .h file.







#include "mibgroup/EtherLike-MIB/dot3StatsTable/dot3StatsTable.h"


#include "mibgroup/EtherLike-MIB/dot3HCStatsTable/dot3HCStatsTable.h"


#include "mibgroup/EtherLike-MIB/dot3CollTable/dot3CollTable.h"


#include "mibgroup/EtherLike-MIB/dot3ControlTable/dot3ControlTable.h"


#include "mibgroup/EtherLike-MIB/dot3PauseTable/dot3PauseTable.h"





 





  • Next edit the '<sourcedir>\win32\mib_module_inits.h' file to add code to call your initialize function.







if (should_init("dot3StatsTable")) init_dot3StatsTable();


if (should_init("dot3HCStatsTable")) init_dot3HCStatsTable();


if (should_init("dot3CollTable")) init_dot3CollTable();


if (should_init("dot3ControlTable")) init_dot3ControlTable();


if (should_init("dot3PauseTable")) init_dot3PauseTable();





 



1.7. Instrument the EtherLike-MIB



This section only instruments the dot3StatsTable generated source to return some default data. Other table instrumentation can be done in the similar manner.





  1. Edit the dot3StatsTable.c file as shown below to return some hardcoded data. The changes to the generated code have been highlighted.







/*


 * Note: this file originally auto-generated by mib2c using


 *        : mib2c.create-dataset.conf 9375 2004-02-02 19:06:54Z rstory $


 */


 


#include <net-snmp/net-snmp-config.h>


#include <net-snmp/net-snmp-includes.h>


#include <net-snmp/agent/net-snmp-agent-includes.h>


#include "dot3StatsTable.h"


 


/** Initialize the dot3StatsTable table by defining its contents and how it's structured */


void


initialize_table_dot3StatsTable(void)


{


    static oid dot3StatsTable_oid[] = {1,3,6,1,2,1,10,7,2};


    size_t dot3StatsTable_oid_len = OID_LENGTH(dot3StatsTable_oid);


    netsnmp_table_data_set *table_set;


    


    // variables declared – wrajnees


    netsnmp_table_row *row;


    static int _max_cols = 21; // there are 18 columns in this table.


    int column = 0;


    int index = 1;


    int val = 20;


    static oid      objid_etherchipset[] = { 0 };     /* ethernetChipset vendor oid */


 


    // end variables declared.


 


    /* create the table structure itself */


    table_set = netsnmp_create_table_data_set("dot3StatsTable");


 


    /* comment this out or delete if you don't support creation of new rows */


    


    table_set->allow_creation = 1;


 


    /***************************************************


     * Adding indexes


     */


    DEBUGMSGTL(("initialize_table_dot3StatsTable",


                "adding indexes to table dot3StatsTable\n"));


 


    netsnmp_table_set_add_indexes(table_set,


                           ASN_INTEGER,  /* index: dot3StatsIndex */


                           0);


 


    


    DEBUGMSGTL(("initialize_table_dot3StatsTable",


                "adding column types to table dot3StatsTable\n"));         


    netsnmp_table_set_multi_add_default_row(table_set,


                                            /*COLUMN_DOT3STATSINDEX, ASN_INTEGER, 0,


                                            NULL, 0,*/


                                            COLUMN_DOT3STATSALIGNMENTERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSFCSERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSSINGLECOLLISIONFRAMES, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSMULTIPLECOLLISIONFRAMES, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSSQETESTERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSDEFERREDTRANSMISSIONS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSLATECOLLISIONS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSEXCESSIVECOLLISIONS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSCARRIERSENSEERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSFRAMETOOLONGS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSETHERCHIPSET, ASN_OBJECT_ID, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSSYMBOLERRORS, ASN_COUNTER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSDUPLEXSTATUS, ASN_INTEGER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSRATECONTROLABILITY, ASN_INTEGER, 0,


                                            NULL, 0,


                                            COLUMN_DOT3STATSRATECONTROLSTATUS, ASN_INTEGER, 0,


                                            NULL, 0,


                              0);


 


 


    


    /* registering the table with the master agent */


    /* note: if you don't need a subhandler to deal with any aspects


       of the request, change dot3StatsTable_handler to "NULL" */


    netsnmp_register_table_data_set(netsnmp_create_handler_registration("dot3StatsTable", NULL,


                                                        dot3StatsTable_oid,


                                                        dot3StatsTable_oid_len,


                                                        HANDLER_CAN_RONLY),


                            table_set, NULL);


    // Add code - wrajnees


 


    /*


     * create the a row for the table, and add the data 


     */


    row = netsnmp_create_table_data_row();


    /*


     * set the index to the IETF WG name "snmpv3" 


     */


    netsnmp_table_row_add_index(row, ASN_INTEGER, (u_char*)&index, sizeof(index));


    /*


     * set the column 2 and above


     */


    for (column = 2; column <= _max_cols; column++) {


        // Following columns are not valid.


        switch(column) {


            case 12: // INVALIDs


            case 14:


            case 15:


                break;


            case 17: // OID


                netsnmp_set_row_column(row, column, ASN_OBJECT_ID,


                               (u_char*)objid_etherchipset, 1*sizeof(oid));


                break;


            case 19: // INTEGER


            case 21:


                netsnmp_set_row_column(row, column, ASN_INTEGER,


                               (u_char*)&val, sizeof(val));    


                break;


            case 20: // TRUTH_VALUE


                netsnmp_set_row_column(row, column, ASN_INTEGER,


                               (u_char*)&val, sizeof(val));    


                break;


            default: // COUNTER


                netsnmp_set_row_column(row, column, ASN_COUNTER,


                               (u_char*)&val, sizeof(val));    


                break;


        }


 


 


    }


    /*


     * add the row to the table 


     */


    netsnmp_table_dataset_add_row(table_set, row);


 


    /*


     * Finally, this actually allows the "add_row" token it the


     * * snmpd.conf file to add rows to this table.


     * * Example snmpd.conf line:


     * *   add_row netSnmpIETFWGTable eos "Glenn Waters" "Dale Francisco"


     */


    netsnmp_register_auto_data_table(table_set, NULL);


 


    // End add code - wrajnees


}


 


/** Initializes the dot3StatsTable module */


void


init_dot3StatsTable(void)


{


 


  /* here we initialize all the tables we're planning on supporting */


    initialize_table_dot3StatsTable();


}







  1. Now rebuild the netsnmpmibssdk project and then snmpdsdk project, in order.




  2. Run the following command to re-install the modified agent with the dot3StatsTable changes.







cd c:\net-snmp 


win32\install_netsnmp.bat 







  1. Start the new agent as follows:







cd c:\usr\bin 


snmpd.exe –f –Lo –V 







  1. Open a MIB Browser to walk the dot3StatsTable instrumentation:




clip_image006



1.8. Instrumentation on Linux





  1. Copy the generated source to the path ~/net-snmp/agent/mibgroups and run the following commands:







./configure –with-mib-modules=”dot3StatsTable dot3PauseTable dot3HCStatsTable dot3CollTable dot3ControlTable” 


make 


make install (run as root)







  1. Start the snmpd as:







/usr/local/sbin/snmpd –f –Lo –V 







  1. Run a command line snmpwalk to test it.







$ snmpwalk -v 2c -mAll -c public localhost dot3StatsTable 


 


EtherLike-MIB::dot3StatsAlignmentErrors.1 = Counter32: 20 


EtherLike-MIB::dot3StatsFCSErrors.1 = Counter32: 20 


EtherLike-MIB::dot3StatsSingleCollisionFrames.1 = Counter32: 20 


EtherLike-MIB::dot3StatsMultipleCollisionFrames.1 = Counter32: 20 


EtherLike-MIB::dot3StatsSQETestErrors.1 = Counter32: 20 


EtherLike-MIB::dot3StatsDeferredTransmissions.1 = Counter32: 20 


EtherLike-MIB::dot3StatsLateCollisions.1 = Counter32: 20 


EtherLike-MIB::dot3StatsExcessiveCollisions.1 = Counter32: 20 


EtherLike-MIB::dot3StatsInternalMacTransmitErrors.1 = Counter32: 20 


EtherLike-MIB::dot3StatsCarrierSenseErrors.1 = Counter32: 20





2. Co-existance with MS Windows SNMP Agent



We have 2 approaches to getting the net-snmp agent to co-exist with the Microsoft provided SNMP agent:





  • As of Net-SNMP 5.4, the Net-SNMP agent is able to load the Windows SNMP service extension DLLs by using the Net-SNMP winExtDLL extension. In this scenario, MS SNMP agent is installed but disabled. This is required because winExtDLL extension and existing windows extensions use Windows SNMP API from snmpapi.dll. The limitations of this approach are:





    • linkUp/Down generic traps are not received for some unknown reason.




    • sysUpTime.0 does not report the correct uptime for the agent. This is because the Windows extension checks for the uptime of the SNMP service, which is not running when Net-SNMP is running.





  • Alternatively, Net-SNMP agent can run as a proxy SNMP agent and will proxy for the MS SNMP agent (running at a non-default port) for those MIBs that MS SNMP agent instruments. For all other MIBs, Net-SNMP agent can service the SNMP requests. This approach does not suffer from the winExtDLL approach’s limitation, but then we need to run two snmp agents (net-snmp and MS snmp agents).




This sums up in short, the development setup required to get started with extending the net-snmp agent.

Sunday, August 17, 2008

Vim quick reference

The following content is excerpted from http://linuxconfig.org/Vim_Tutorial. It covers most of the essentials that one needs while editing code. One thing which i know and use and is not covered is :e < filename > to open multiple files without exiting vim and then navigating among the open files using :b < num > , where num is file buffer number for the open files . Other than that, there were quite a few points in the tutorial that were really good and i did not use/know them before. Also see other good links to learn more on vi/vim at http://delicious.com/rwatsh/vi.

Vim Tutorial Summary

VIM novice level Summary

  • Moving around with cursor:
    h key = LEFT, l key = RIGHT, k key = UP, j key = DOWN
  • Exiting vim editor without saving:
    press ESC to get into command mode, enter :q! to exit.
  • Deleting characters in vim command mode:
    delete with x key
  • Inserting / appending text:
    Press i or a in command mode and type
  • Saving changes and exit:
    in command mode :wq or SHIFT+zz

VIM Operators and Motions summary

  • Deleting words:
    delete word with d operator and w or e motion
  • Deleting to the end of the line:
    delete to th end of the line with d operator and $ motion
  • Using operators, motions and counts:
    beginning of th line 0, end of the line $, end of the 2nd word 2e beginning of the 4th word 4w
  • Deleting multiple words:
    to delete 3 words you would use d3w
  • Deleting lines:
    to delete single line dd, delete n lines ndd
  • Undo changes:
    undo changes with u

VIM apprentice user summary

  • Paste command:
    paste your cache memory with p command
  • Replace characters:
    rt replace current character with t
  • Change characters:
    ce to change single word, c$ to change to the end of the line

VIM experienced user summary

  • Advanced Navigation:
    end of the file G, begging of the file gg or 1G, to get on line n use nG
    instruct vim display file information CTRL+g
  • Search text with vim:
    search forward /, search backward ?, next search n , previous search N
  • Vim Substitution :
    first occurrence single line :s/bash/perl/
    all occurrences single line :s/bash/perl/g
    first occurrence between line range: :23,100s/bash/perl/
    all occurrences between line range: :23,100s/bash/perl/g
    first occurrence in whole text: :%s/bash/perl/
    all occurrences whole text: :%s/bash/perl/g

VIM veteran user summary

  • Execute external commands on shell from vim:
    :!ls will execute ls command on your shell
  • Writing to files advanced::w saves current file without quit, :w bash.sh whites to file bash.sh
  • Highlight text ans save to different file:highlight text with v operator and save it with :w
  • Retrieve text from different file::r will retrieve content of file

VIM expert user summary

  • Using o operator:
    :o insert line bellow you cursor, O inserts line above your cursor
  • Copy and paste:
    yank line with y and paste it with p
  • Customize vim's environment:
    edit ~/.vimrc file to customize vim's environment

Friday, April 18, 2008

Free Java Programmer's Test



I stumbled on the site http://www.betterprogrammer.com today and found that it offers an open book programming test meaning you can use all reference (like one can do at work) but complete 5 programming exercises pertaining to use of core Java language for writing algorithms. It requires lots of Java collections framework usage and writing some recursion algorithms, writing tree traversal code, calculating prime numbers and stuff like that. The time limit is not very strict and it even allows you to take a break and then continue with the test. In the end you are given a free certificate based on percentile (which it states will keep changing - read may improve - with time, as more people take this free test). The questions were good quality and if you have some free time and like to write code then its quite a good avenue to spend some time on.

My certificate is here: http://www.betterprogrammer.com/certificate/BP1Q9GB5

They claim to maintain this certificate for you in their database and that you can retake the tests to improve (not sure if the questions remain the same - if they dont change then thats a bummer) but anyway take it once and you will love it. If you have taken this test already then feel free to leave your comments on how you liked it or discuss the questions you liked/found interesting.

Popular micro services patterns

Here are some popular Microservice design patterns that a programmer should know: Service Registry  pattern provides a  central location  fo...