Hello, net-snmp-coders.
        I am a newbie to net-snmp, but definitely not to SNMP agent
development as such; I have been working with SNMP agents for 15+ years.
I was asked to whip together an agent that supports the
(not-yet-released-from-IETF) OSPFV3-MIB using the net-snmp agent API.
Trying to solve that task, I ran into a showstopper problem with the
internal representation of IpAddress in net-snmp.

        I am not certain that this mailing list is the right place - but
reporting a simple bug in a few tables seemed to be a bit out of place
- and the competence level on net-snmp-users seems to be a little below
the topic of this posting....  Please refer me elsewhere if you feel
like it.

        To start simply, I can report a bug in the agent implementation
of several tables.  An example is ipCidrRouteTable.  Net-SNMP version
is 5.1.2 as distributed by Debian GNU/Linux on i386 (the endianness of the
processor is important!).  Incidentally, the bug is verified to be still
present in CVS 20050815.  Documentation, an snmp walk outputs:

IP-FORWARD-MIB::ipCidrRouteDest.0.1.168.192.0.255.255.255.0.0.0.0.0 = 
IpAddress: 192.168.1.0
                                ^^^^^^^^^^^

        The encoding of the destination in the index part of the OID is
wrong - the sequence of bytes is reversed (the encoding of the Nexthop
part of the index is also wrong - you just can't see it in this example).

        How it should be is documented in RFC 3416, section 4.2.2.1.

        Supplementary information:  the (presumably much older
implementation of) RFC 1213 in the very same releases of net-snmp have got
the similar encoding of exactly the same piece of information right:

RFC1213-MIB::ipRouteDest.192.168.1.0 = IpAddress: 192.168.1.0
                         ^^^^^^^^^^^
        So the bug is dependent on the actual implementation of a given
table - it is not totally generic.

        I discovered the bug because I followed the Mib-for-dummies
technique to implement my OSPFV3-MIB - the index went wrong there, too.
I then snooped a little around in the agent, with mixed results.  For
instance, the TCP-MIB:

TCP-MIB::tcpConnRemAddress.192.168.1.252.33467.193.180.251.51.22 = IpAddress: 
193.180.251.51
                                               ^^^^^^^^^^^^^^
and the ipNetToMediaTable in IP-MIB:

IP-MIB::ipNetToMediaNetAddress.2.192.168.1.1 = IpAddress: 192.168.1.1
                                 ^^^^^^^^^^^

have both got the OID encoding right, while the UDP-MIB:

UDP-MIB::udpLocalAddress.252.1.168.192.53 = IpAddress: 192.168.1.252
                         ^^^^^^^^^^^^^

has got it wrong - the whole situation is a mess.

        And that is not so surprising.  For the internal representation of
IpAddress - what is called "MIB representation" in documentation - is a
u_long - but nowhere can I find documentation that states what endianness
to use when converting from what an IpAddress really is - an "unsigned
char [4]" - to a u_long.  The specific code for converting the
ipCidrRouteDest is illustrative:  a char[] - struct member rt_dest - is
simply type casted, with no regards for endianness, into the u_long -
argument for the call of function ipCidrRouteTable_indexes_set in function
_snarf_route_entry:

          *((u_long *) route_entry->rt_dest),

- that kind of coercing simply *cannot* be right on all kinds of
processors.

        Now, net-snmp is a big amount of code, and it is not easy to
search.  But I am pretty sure that I have found the OID index
encoding code, in function build_oid_segment in snmplib/mib.c:

    case ASN_IPADDRESS:
        var->name_length = 4;
        var->name = var->name_loc;
        var->name[0] =
            (((unsigned int) *(var->val.integer)) & 0xff000000) >> 24;
        var->name[1] =
            (((unsigned int) *(var->val.integer)) & 0x00ff0000) >> 16;
        var->name[2] =
            (((unsigned int) *(var->val.integer)) & 0x0000ff00) >> 8;
        var->name[3] =
            (((unsigned int) *(var->val.integer)) & 0x000000ff);
        break;

        Right?  This code clearly assumes that the var->val.integer is
encoded big-endian.  Which it isn't on an i386.  But the assignment in
_snarf_route_entry shown above blandly assumed that.

        I am less certain that I've found the place where the value part
of the varbind is (correctly on i386) encoded.  But I think it is in
function sprint_realloc_ipaddress in same source file:

    u_char         *ip = var->val.string;
        :
        :
    sprintf((char *) (*buf + *out_len), "%d.%d.%d.%d",
                                            ip[0], ip[1], ip[2], ip[3]);

        Here the original unsigned char[4] that was coerced to a u_long in
the IP-FORWARD-MIB instrumentation code - is simply coerced back to a
char* - that is why the encoding of the varbind ends up being correct ....

        How to solve this problem within net-snmp architecture?  I am not
certain.  The basic design error is that IpAddress is represented
internally by a u_long - had it been represented by a proper "unsigned
char [4]" the problem wouldn't have been there at all.  But that is
probably too late to change - too much code depending on the current
representation.  Second best solution, I think, would be for net-snmp
developer community to decide upon - and DOCUMENT - a conversion
convention - that the "u_long" representing an IpAddress is either big
endian or little endian (I would recommend big endian, because we then
have htonl(3) and ntohl(3) readily available for conversion on all
architectures).  And then adjust all encoding and decoding code
accordingly.  As it is, the OID index and the VarBind value encoding code
simply disagrees - hmm, actually, I am a bit surprised that some of the
tables are correct...

        Sorry for the long posting.  I spent most of the day, after being
bit by the bug, collecting auxiliary and supplemental information.  I hope
you can use it.  I can fix my personal, actual problem quite easily - it
is demonstration code, after all, not production code, and it is
restricted to little endian (i386)  architecture.  But I don't think that
the net-snmp community can live with this problem in the long run.

best regards
-- 
Peder Chr. Nørgaard             Senior System Developer, M. Sc.
Ericsson Denmark A/S, Telebit Division
Skanderborgvej 232              tel: +45 30 91 84 31
DK-8260 Viby J, Denmark         fax: +45 89 38 51 01
        e-mail: [EMAIL PROTECTED]
(old e-mail 2000-2003: [EMAIL PROTECTED])
         (old e-mail 1992-2000: [EMAIL PROTECTED])


-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to