Activating a scanner within a scanner?

Hi all,

as some of you will know, I am writing a SIP and (soonish) a RTCP analyzer
in BinPAC.

I have a question regarding the analyzation of protocols which are
inlined into other protocols.

The relation of SIP to SDP could losely be described as that of a HTML
header and body. When the Content-Length field in the SIP packet is
non-zero, there is a SDP payload that also needs to be parsed.

I am not sure if it would make more sense to hook another analyzer into
the SIP analyzer or to just parse the SDP payload within my SIP
analyzer.

Another consideration would be how to write the SDP analyzer in a way
that accounts for both for standalone detection and as a plugin for my
SIP analyzer (working on packets vs working on data i feed it directly).

Any feedback is appreciated,
Richard

(Disclaimer: I've no idea about SIP/SDP).

I am not sure if it would make more sense to hook another analyzer into
the SIP analyzer or to just parse the SDP payload within my SIP
analyzer.

How closely are the two coupled? Is there information which needs to
be passed between the two?

If the coupling is not too tight, I'd say separating the two looks
nicer, as it shows that semantically they are seperat. The outer
analyzer can instantiate an instance of the inner if necessary
(i.e., if there's a body) and then call it's DeliverStream() method
for the data.

Another consideration would be how to write the SDP analyzer in a way
that accounts for both for standalone detection and as a plugin for my
SIP analyzer (working on packets vs working on data i feed it directly).

Not sure I understand that. Does this mean SDP can be encapulated
inside SIP but does not have to?

Robin

How closely are the two coupled? Is there information which needs to
be passed between the two?
Not sure I understand that. Does this mean SDP can be encapulated
inside SIP but does not have to?

SIP may contain SDP, whereas SDP is mainly used in SIP. SDP could be
used for the description of other sessions, but from what I could find,
its main use is definately for SIP.

The only information about SDP in SIP is the Content-Length field, so I
know that when I see a Content-Length != 0, there will be SDP
encapsulated into my SIP packet.

If the coupling is not too tight, I'd say separating the two looks
nicer, as it shows that semantically they are seperat. The outer
analyzer can instantiate an instance of the inner if necessary
(i.e., if there's a body) and then call it's DeliverStream() method
for the data.

SIP is UDP-based. Would this work for DeliverPacket, as well?

A related problem I have is that SIP uses a blank line to show where the
SIP part ends and where the SDP part (if any) starts. What would be a
clean way to handle this situation?

Ideally, I would want to try two regular expressions. If the first one
matches, I know I am still in the SIP part. As soon as that regular
expression does not match any more, I could look for a blank line and
either set a status flag or invoke the secondary analyzer.

The problem is that from what I understand about BinPAC, it is impossible
to look at a line and just try to match. Either your whole type/record
matches or the whole rest of the packet is discarded.

Unfortunately, I can not simply look for a magic last item in the SIP
part as the order of the keywords may be completely random.

I tried looking at the HTTP analyzer, because this protocol uses a
newline to show when the header is finished, but to no avail.

Any help on this question would be greatly appreciated, as I am simply
unable to solve this problem.

For future versions on BinPAC, expanding the case statement so that one
could match the contents of a field against a regular expression and/or
text would probably help in a lot of situations.

What I have in mind is along the lines of

fork : case foo of {
  REGEXP_1 -> bar: REGEXP_1;
  REGEXP_2 -> baz: REGEXP_23;
  "string" -> qux: bytestring &restofdata;
  default -> quux: "hello";
};

Any help appreciated :slight_smile:
Richard

To elaborate on options to parse newlines which I can think of in the
order I would prefer to be able to do this:

1) Define a type like
type SIP_Headers = SIP_Header[] &until(foo);
where foo would be some way to tell the parser 'until you hit a blank
line'

2) Use a case statement to decide how to continue parsing of the data

3) Try to parse parts of the remaining buffer and continue with another
branch in the parsing tree if that first attempt fails

4) If all else fails, I will probably try to just grab the first letter
of the current line and decide based on what is in that field. This
would be an extremely kludgy (think several strings starting with the
same letter, resulting in even more branching) and hacky (just ugly,
hard to read and generally bad style)

Best regards,
Richard

SIP may contain SDP, whereas SDP is mainly used in SIP. SDP could be
used for the description of other sessions,

[...]

The only information about SDP in SIP is the Content-Length field,

Ok, so then I would go for a seperate analyzer.

SIP is UDP-based. Would this work for DeliverPacket, as well?

Yes. The "packet" is actually just a chunk of data, with the actual
interpretation being left to the analyzer.

I tried looking at the HTTP analyzer, because this protocol uses a
newline to show when the header is finished, but to no avail.

If I understand you correctly, you should be able to do this in the
same way as the HTTP analyer does it. I thinkt this is the relevant
type from http-protocol.pac:

     type HTTP_Headers = HTTP_Header[] &until($input.length() == 0);

Does something similar work for you?
     
Robin

> I tried looking at the HTTP analyzer, because this protocol uses a
> newline to show when the header is finished, but to no avail.

If I understand you correctly, you should be able to do this in the
same way as the HTTP analyer does it. I thinkt this is the relevant
type from http-protocol.pac:

     type HTTP_Headers = HTTP_Header[] &until($input.length() == 0);

Does something similar work for you?

Richard,

From what you described, it should work for you. Please keep us

updated if it doesn't.

To provide a bit of background, $input in the "until" clause
corresponds to a line without the trailing CRLF, because HTTP_Header
is defined with a &oneline attribute. By the way, this means $input
can also be used in more fancy conditions, such as ($input == "foo").

Ruoming