mattedug has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I am humble in your presence and ask for forgiveness for writing such poor code. I humbly request 5 minutes of your meditation time.

I am currently trying to decode OSPF LSA's that I am retrieving from the OSPF MIB (ospfLsdbAdvertisement) via SNMP.

I have two networks running OSPF to test against and appear to have sucesfully managed to decode the LSA 20-byte header and Network LSA's using unpack.
(I must add that I am fairly new to unpack/pack).

However, I am experiencing some very odd behaviour and wondered if you could give me any hints or tips.

Here is the 20-byte OSPF LSA Header according to the RFC:

# 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 +1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ++-+ # | LS age | Options | LS type + | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ++-+ # | Link State ID + | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ++-+ # | Advertising Router + | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ++-+ # | LS sequence number + | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ++-+ # | LS checksum | length + | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- ++-+

Here is the function I am using to decode the header:**
** Note that it does do some enumeration and calls a couple of other functions that aren't shown.

sub decode_header { my $buff = shift; my %lsa; print dump_hex(substr($buff,0,20)); ($lsa{age}, $lsa{options}, $lsa{type}, $lsa{lsid}, $lsa{advRouter}, $lsa{seqNo}, $lsa{checksum}, $lsa{length}) = unpack('nCCNNNnn',$buff); $lsa{lsid} = N_to_dottedQuad($lsa{lsid}); $lsa{advRouter} = N_to_dottedQuad($lsa{advRouter}); $lsa{type} = $OSPF{LSTYPE}{$lsa{type}}; $lsa{options} = decode_lsa_options($lsa{options}); return \%lsa; }

If the results of the function are Data::Dumped I get something like the following:

Dump: [000] 00 05 22 01 AC 32 00 02 AC 32 00 02 80 20 FF 99 [016] 05 90 00 48 $VAR1 = { 'seqNo' => '2149646233', 'length' => 72, 'checksum' => 1424, 'advRouter' => '172.50.0.2', 'options' => '*|-|DC|-|-|-|E|*', 'lsid' => '172.50.0.2', 'type' => 'Router-LSA', 'age' => 5 };

This looks okay, some sniffing with Ethereal and checking of the standard mib variables have shown that this LSA appears to contain the correct checksum, advertising router and lsid etc. Oddly though, age never seems to be right for some reason...

However, this is where things start to get a little strange. A couple of our routers are using IP addresses with 10 as one of the octets. If the decoder comes across such a value it converts the 10 into 32 for some reason. Other octets within the IP address are represented correctly.
Consider the following example:-

[000] 00 00 22 02 20 01 01 02 20 01 FE 01 80 00 00 10 [016] 41 A5 00 20 $VAR1 = { 'seqNo' => '2147483664', 'length' => 32, 'checksum' => 16805, 'advRouter' => '32.1.254.1', 'options' => '*|-|DC|-|-|-|E|*', 'lsid' => '32.1.1.2', 'type' => 'Network-LSA', 'age' => '0' };

Both the LSID and advertising router should have 10 as their first octet. I've tried a number of things:

  • Renumbering the interfaces and re-checking, it is fine with all IP addresses other than ones with .10 in them.
  • Trying different routers from both Cisco and Juniper, again, the same result.
  • Trying a different network altogether, again, the same result.

    In light of the tests I presume it must be something with my unpack of the packet. If anyone can make any suggestions or give any advice that would be very much appreciated.

    Regards, Matt
  • Replies are listed 'Best First'.
    Re: Strange results from unpack when trying to decode OSPF LSA's from the OSPF MIB
    by ikegami (Patriarch) on Aug 05, 2005 at 00:28 UTC

      You say that both the LSID and advertising router should have 10 as their first octet when the data is

      00 00 22 02 20 01 01 02 20 01 FE 01 80 00 00 10 41 A5 00 20

      10 decimal is 0A in hex, but 0A does not appear anywhere in the data. Your statement is either false, or your dump is inaccurate.

      In fact, the bytes for the LSID are 20, 01, 01, 02, which corresponds to the decimal numbers 32, 1, 1, 2. That's exactly what your code prints out (32.1.1.2), so there is no error in your code (if your dump is accurate).

        Hi,

        Thanks for the reply. I also noticed that but I find it hard to believe that 6 different routers running different operating systems and from two different vendors would give me the same data, i.e. the 32.

        Ethereal has the same hex data for the ospfLsdbAdvertisement from the devices as my dump.

        I've also checked the LSDB's in the routers themselves and they're reporting the correct data, as expected.

        Any other ideas? Do you think the decode looks okay?

        thanks, Matt
          Do you think the decode looks okay?

          I have no idea what OSPF, LSDB or LSA means. All I know is that your data is consistent with your dump.

    Re: Strange results from unpack when trying to decode OSPF LSA's from the OSPF MIB
    by polettix (Vicar) on Aug 05, 2005 at 01:47 UTC
      Where are you getting the dumps (with Ethereal) exactly? Do you get them at the source or at the destination machine? 10 indicates private addresses, are you sure there's nothing doing some smart NATting somewhere between the routers and you?

      Flavio
      perl -ple'$_=reverse' <<<ti.xittelop@oivalf

      Don't fool yourself.
        Hi,

        Ethereal is running on my local machine. I do an SNMP walk of the routers mib from there. The routers belong in private test networks, hence the use of private address space.

        I'm not aware of any NAT going on and even if there was it shouldn't affect IP addresses with 10 as any of the octets.

        regards, Matt
          I would only be sure that those values aren't changed along the way by some "smart" node. If your local machine is directly connected to the routers this shouldn't be the problem, anyway.

          Flavio
          perl -ple'$_=reverse' <<<ti.xittelop@oivalf

          Don't fool yourself.
    Re: Strange results from unpack when trying to decode OSPF LSA's from the OSPF MIB
    by g0n (Priest) on Aug 05, 2005 at 09:59 UTC
      I concur with other comments in the thread - your hex dump is consistent with the output (and, FWIW, your unpack looks consistent with the RFC definition).

      Logic suggests therefore that the problem is arising before the data arrives in your function. I have two suggestions there:

      • Post the code that captures the packet, in case there's a problem or invalid assumption in it
      • You say in a response that "The routers belong in private test networks, hence the use of private address space" - that's true of 10.x.x.x, but 172.50.x.x is not a private address as defined in rfc1918, so if (although it seems unlikely) some special processing for private addresses is happening, it won't affect addresses in that range.

      --------------------------------------------------------------

      g0n, backpropagated monk

        Hi,

        Thanks for your suggestions. You were right, it was the SNMP get code that was causing the problem. I've upgraded that now and it is spot on, here is an example.

        LSA Header Dump: [000] 00 00 22 02 0A 01 01 02 0A 01 FE 01 80 00 00 29 [016] 0F BE 00 20 $VAR1 = { 'seqNo' => '2147483689', 'length' => 32, 'checksum' => 4030, 'advRouter' => '10.1.254.1', 'options' => '*|-|DC|-|-|-|E|*', 'lsid' => '10.1.1.2', 'type' => 'Network-LSA', 'age' => '0' };

        Thanks once again.

        Matt
    Re: Strange results from unpack when trying to decode OSPF LSA's from the OSPF MIB
    by Anonymous Monk on Mar 04, 2016 at 04:35 UTC
      Hi I am trying to achieve same , but unable to do so. New to Pack and UNpack , can share the code behine dump_hex thanks