All of lore.kernel.org
 help / color / mirror / Atom feed
* ASN.1 decoder for h323-conntrack-nat
@ 2003-10-16 13:25 Alexander Nasonov
  2003-10-16 13:42 ` Jozsef Kadlecsik
  0 siblings, 1 reply; 5+ messages in thread
From: Alexander Nasonov @ 2003-10-16 13:25 UTC (permalink / raw)
  To: netfilter-devel

Hi!
Sorry, I don't have enough time right now to understand how current 
version of h323-conntrack-nat works. Probably, what I'm going to 
announce here is already implemented.
Anyway, here is what I have. I've implemented callback-based decoder of 
ASN.1 PER rules. With a help of this decoder it's possible to analyze 
H323 packet and to call user-defined function when the code came across 
an interesting type. For example, it's easy to jump from fastStart 
element to OpenLogicalChannel or to detect OpenLogicalChannel -> 
reverseLogicalChannelParameters -> mediaChannel -> ipAddress sequence.
Generated code doesn't have dynamic memory allocations and other 
undeterministic stuff. It just easts bits :))) In it's current state the 
code is ugly (due to deadline) and it is C++. If there is an interest, I 
can rewrite it later.
--
Alexander Nasonov

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ASN.1 decoder for h323-conntrack-nat
  2003-10-16 13:25 ASN.1 decoder for h323-conntrack-nat Alexander Nasonov
@ 2003-10-16 13:42 ` Jozsef Kadlecsik
  2003-10-16 14:11   ` Alexander Nasonov
  0 siblings, 1 reply; 5+ messages in thread
From: Jozsef Kadlecsik @ 2003-10-16 13:42 UTC (permalink / raw)
  To: Alexander Nasonov; +Cc: netfilter-devel

On Thu, 16 Oct 2003, Alexander Nasonov wrote:

> Sorry, I don't have enough time right now to understand how current
> version of h323-conntrack-nat works. Probably, what I'm going to
> announce here is already implemented.

No, not at all. The current code simply assumes that if we find the IP
address of the sender in the payload, then the next bytes give the port
we are looking for. :-| Naturally this brute force method can fail very
easily and does not support a few features of H.323.

> Anyway, here is what I have. I've implemented callback-based decoder of
> ASN.1 PER rules. With a help of this decoder it's possible to analyze
> H323 packet and to call user-defined function when the code came across
> an interesting type. For example, it's easy to jump from fastStart
> element to OpenLogicalChannel or to detect OpenLogicalChannel ->
> reverseLogicalChannelParameters -> mediaChannel -> ipAddress sequence.
> Generated code doesn't have dynamic memory allocations and other
> undeterministic stuff. It just easts bits :))) In it's current state the
> code is ugly (due to deadline) and it is C++. If there is an interest, I
> can rewrite it later.

That would be great! We cannot use code written in C++.

[Actually, I have just discovered that the source code of the most recent
ethereal contains ASN.1 PER/H225/H245 decoders written in C.]

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ASN.1 decoder for h323-conntrack-nat
  2003-10-16 13:42 ` Jozsef Kadlecsik
@ 2003-10-16 14:11   ` Alexander Nasonov
  2003-10-17  8:02     ` Jozsef Kadlecsik
  0 siblings, 1 reply; 5+ messages in thread
From: Alexander Nasonov @ 2003-10-16 14:11 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: netfilter-devel

Jozsef Kadlecsik wrote:

> That would be great! We cannot use code written in C++.

I'm using C++ simply because C++ has inline functions and if you put all 
these functions (with bodies) into the class scopr you don't need to 
worry about the order in which they should be placed. I can rewrite the 
generator to generate C code (the generator itself will be written in 
C++ anyway).

>[Actually, I have just discovered that the source code of the most recent
>ethereal contains ASN.1 PER/H225/H245 decoders written in C.]
>
This tool helped me a lot to understand what PER is. Hmm, I thought that 
ethereal is based on openh323 ASN.1 generator which is C++-based. I'll 
take a look at the code later. Is there any free ASN.1 decoder?
I wish I had a better code. I could implement more optimization then. 
For example, if a type after extention mark (...) doesn't have callbacks 
it could be just skiped as open type. I could also try to simplify  
parsing of fixed-length types. May be later I'll find more time to 
rewrite the code.
I forgot to mention that my code is based on 
http://iiiasn1.sourceforge.net (this project AFAIK is derived from 
openh323 decoder/encoder).

--
Alexander Nasonov

PS. Example of generated code:

  void f_MSC__MultimediaSystemControlMessage()
  {
      // CHOICE { < 4 field(s) > ,... }
      size_t len;
      unsigned char* saved_byte;
      unsigned int choice = GetBits3();
      switch(choice)
      {
        case 0:
          f_MSC__MultimediaSystemControlMessage__request();
          break;
        case 1:
          f_MSC__MultimediaSystemControlMessage__response();
          break;
        case 2:
          f_MSC__MultimediaSystemControlMessage__command();
          break;
        case 3:
          f_MSC__MultimediaSystemControlMessage__indication();
          break;
        case 4: case 5: // small number bit is 0
          choice = GetBits5() + ((choice - 4) << 5);
          SkipDataWithSemiConstrainedLength();
          break;
        default: // small number bit is 1
          UngetBits(1);
          SkipDataWithSemiConstrainedLength();
          SkipDataWithSemiConstrainedLength();
          break;
      }
  }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ASN.1 decoder for h323-conntrack-nat
  2003-10-16 14:11   ` Alexander Nasonov
@ 2003-10-17  8:02     ` Jozsef Kadlecsik
  2003-10-17  9:37       ` Alexander Nasonov
  0 siblings, 1 reply; 5+ messages in thread
From: Jozsef Kadlecsik @ 2003-10-17  8:02 UTC (permalink / raw)
  To: Alexander Nasonov; +Cc: netfilter-devel

On Thu, 16 Oct 2003, Alexander Nasonov wrote:

> >[Actually, I have just discovered that the source code of the most recent
> >ethereal contains ASN.1 PER/H225/H245 decoders written in C.]
> >
> This tool helped me a lot to understand what PER is. Hmm, I thought that
> ethereal is based on openh323 ASN.1 generator which is C++-based. I'll
> take a look at the code later. Is there any free ASN.1 decoder?

Earlier there was a H.323 plugin for ethereal, which was based on openh323
and therefore was in C++. Now H.323 support is integrated into ethereal
(no external plugin) and written in pure C. As far as I see it's not based
on openh323.

> I wish I had a better code. I could implement more optimization then.
> For example, if a type after extention mark (...) doesn't have callbacks
> it could be just skiped as open type. I could also try to simplify
> parsing of fixed-length types. May be later I'll find more time to
> rewrite the code.

Such optimizations would be highly preferred. The code ran not only
faster but I think were smaller as well.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ASN.1 decoder for h323-conntrack-nat
  2003-10-17  8:02     ` Jozsef Kadlecsik
@ 2003-10-17  9:37       ` Alexander Nasonov
  0 siblings, 0 replies; 5+ messages in thread
From: Alexander Nasonov @ 2003-10-17  9:37 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: netfilter-devel

Jozsef Kadlecsik wrote:

>Such optimizations would be highly preferred. The code ran not only
>faster but I think were smaller as well.
>  
>
I've just finished an analysis of CloseLogicalChannel. It's amazing how 
greatly it can be reduced after optimization.

LogicalChannelNumber    ::=INTEGER (1..65535)

CloseLogicalChannel    ::=SEQUENCE
{
    forwardLogicalChannelNumber    LogicalChannelNumber,
    source        CHOICE
    {
        user    NULL,
        lcse    NULL
    },
    ...,
    reason        CHOICE
    {
        unknown    NULL,
        reopen    NULL,
        reservationFailure    NULL,
        ...
    }
}

1. CloseLogicalChannel is a sequence without optional/default fields and 
with extention => first bit signal the presense of extention(s)
2. LogicalChannelNumber is aligned two bytes => data after this field is 
aligned
3. "source" choice has two choices and no extention => one bit: 0 for 
user, 1 for lcse. This is bit 7 (most significant) because of previous item.
4. user and lcse are NULL => no bits

int CloseLogicalChannel(asn1_message_data* asn)
{
    // 3 = one byte for alignement + two bytes for LogicalChannelNumber 
+ one byte for "source" field
    if(asn->bytes_left <= 3)
        return ERROR_UNEXPECTED_END;
    bool hasExtentions = asn->current_byte & (1 << asn->bit_position);
    asn->bytes_left -= 3;
    asn->current_byte += 3;
    asn->bit_position = 6; // bit 7 is used by "source" field
    return hasExtentions ? skip_sequence_extentions(asn) : SUCCESS;
}

Compare it with a current code to see the difference (unexpected end of 
data is signaled by throwing C++ exception from functions):

  void f_MSC__CloseLogicalChannel_source__user()
  {
      // NULL
  }

  void f_MSC__CloseLogicalChannel_source__lcse()
  {
      // NULL
  }

  void f_MSC__CloseLogicalChannel_source()
  {
      // CHOICE { < 2 field(s) > }
      size_t len;
      unsigned char* saved_byte;
      unsigned int choice = GetBits1();
      switch(choice)
      {
        case 0:
          f_MSC__CloseLogicalChannel_source__user();
          break;
        case 1:
          f_MSC__CloseLogicalChannel_source__lcse();
          break;
      }
  }

  void f_MSC__LogicalChannelNumber()
  {
      // INTEGER(1..65535)
      Align();
      unsigned int byte1 = GetByte();
      unsigned int byte2 = GetByte();
      unsigned long value = 1 + (256 * byte1 + byte2);
  }

  void f_MSC__CloseLogicalChannel__forwardLogicalChannelNumber()
  {
      f_MSC__LogicalChannelNumber();
  }

  void f_MSC__CloseLogicalChannel__source()
  {
      f_MSC__CloseLogicalChannel_source();
  }

  void f_MSC__CloseLogicalChannel()
  {
      // SEQUENCE { < 2 field(s) > ,..., < 1 field(s) > }
      unsigned int bits = GetBits1();
      f_MSC__CloseLogicalChannel__forwardLogicalChannelNumber();
      f_MSC__CloseLogicalChannel__source();

      if(bits) // extentions?
      {
          bool ext[1];
          size_t extCount = GetNormallySmallLength();
          ReadBitmap(ext, extCount > 1 ? 1 : extCount);
          size_t extSkip = extCount > 1 ? CountSetBits(extCount - 1) : 0;

          if(extCount > 0 && ext[0])
          {
              size_t len = GetSemiConstrainedLength();
              unsigned char* saved_byte = m_byte;
              f_MSC__CloseLogicalChannel__reason();
              m_byte = saved_byte;
              SkipBytes(len);
          }

          for(; extSkip; --extSkip)
              SkipDataWithSemiConstrainedLength();
      }
  }

--
Alexaner Nasonov

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-10-17  9:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-10-16 13:25 ASN.1 decoder for h323-conntrack-nat Alexander Nasonov
2003-10-16 13:42 ` Jozsef Kadlecsik
2003-10-16 14:11   ` Alexander Nasonov
2003-10-17  8:02     ` Jozsef Kadlecsik
2003-10-17  9:37       ` Alexander Nasonov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.