[Bro] Syntax Question - Nested Switch Case

TQ nothinrandom at gmail.com
Sun Oct 28 20:40:39 PDT 2018


Hey Jon,

Thanks for the reply. Works great. However, what's the best way to continue
to keep on switching inside Record_A/B ? With your incorporated suggestions
previously:

enum cmd_codes {
NOP = 0x00000000,
DEVICE_HEADER = 0x AABBCCDD,
DEVICE_CMD2_1 = 0x0304,
        DEVICE_CMD2_2 = 0x0405
};

type Header = record {
header: uint32; # header
cmd1: uint16; # 0x0102
cmd2: uint16; # 0x0304 or 0x0405
} &byteorder=bigendian;

type Device_Response = record {
header: Device_Header;
data: case(header.header) of {
DEVICE_HEADER -> head:  HeaderCmd(header.cmd2);
# All the rest
default -> unknown: bytestring &restofdata;
};
} &byteorder=littleendian;

type HeaderCmd(cmd: uint16) = case cmd of {
  DEVICE_CMD2_1  -> info1: Record_A;
  DEVICE_CMD2_2  -> info2: Record_B;
};

type Record_A = record {
title: uint16;
author: uint32;
text: uint64;
ending: uint8;
}

type Record_B = record {
title: uint16;
author: uint32;
text: uint64;
ending: uint8;
}

Based on the ending for each Record, I'd switch to another set. Would I set
it up like Device_Response from above if Record_A and Record_B share some
data before the switch occurs?
type Record_Response = record {
header:  Record_A  ;
data: case(header.ending) of {
HAPPY -> happy:   EndingCmd(header.ending);
SAD  -> sad:   EndingCmd(header.ending);
# All the rest
default -> unknown: bytestring &restofdata;
};
} &byteorder=littleendian;

type EndingCmd(ending : uint16) = case  ending of {
  HAPPY_1  -> info1: Record_A;
  HAPPY_2  -> info2: Record_B;
};

type Ending = record {
ending: bytestring;
}

All of the above is under protocol.pac. How would one access information
from analyzer.pac? I could send you some files if none of this makes sense.

Thanks!

On Tue, Oct 16, 2018 at 9:42 AM Jon Siwek <jsiwek at corelight.com> wrote:

> On Tue, Oct 16, 2018 at 12:46 AM TQ <nothinrandom at gmail.com> wrote:
>
> > How do you do a nested switch case inside a record? I have some data
> 0xAABBCCDD01020304 or 0xAABBCCDD01020405 that I need to verify that the
> header is 0xAABBCCDD and switch based on the last two bytes, either 0x0304
> or 0x0405. Is this a good practice of switch record since data length will
> change based on the command. The nested case I have below is incorrect and
> is throwing error "make[3]: *** [test_pac.h] Segmentation fault (core
> dumped)"
>
> It's possible that you've just run into a binpac bug related to nested
> records and you can file a bug/issue for that on GitHub, but you may
> also be able to organize things differently.  For example, instead of
> nesting switch/case you can do:
>
> type HeaderCmd(cmd: uint16) = case cmd of {
>   DEVICE_CMD2_1  -> info1: Record_A;
>   DEVICE_CMD2_2  -> info2: Record_B;
> };
>
> type Device_Response = record {
>   header: Header;
>   data: case(header.header) of {
>     DEVICE_HEADER -> head_cmd: HeaderCmd(header.cmd2);
>     default       -> unknown: bytestring &restofdata;
>   };
> } &byteorder=littleendian;
>
> Also, if you only ever expect to see that DEVICE_HEADER value and not
> any other header values for this protocol, you might just use an
> &enforce attribute at the top level instead of a switch/case.
>
> - Jon
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.ICSI.Berkeley.EDU/pipermail/bro/attachments/20181028/37a43508/attachment.html 


More information about the Bro mailing list