# Primitives

Each primitive is given with its signature, consisting of a list of allowed typings, tried in order.  A typing is of the form: type1, …, typenreturn-type

• n may be 0, in which case we write just: → return-type
• the symbol * used in place of typei means that any type is admissible for argument  i.

### Arithmetic and logic

• `random` : → `int`
draw a pseudo-random number
• `bitdist` : type, type`int`
where type is any type from  `int`, `uint`, `ipv4`, `ipv6`, `str`, `bstr`, `ctime`, `timeval`, `float`; note that the type of the two arguments must be the same

• returns: the number of bit positions at which the two arguments differ
• `bytedist` : type, type`int`
where type is any type from  `int`, `uint`, `ipv4`, `ipv6`, `str`, `bstr`, `ctime`, `timeval`, `float`; note that the type of the two arguments must be the same

• returns: the number of byte positions at which the two arguments differ
• `defined` : * → `int`
test whether the argument is null

• returns: 1 (true) if the argument is not null, 0 (false) if the argument is null

### Conversions

• `sprintf` : `str`, … → `str`
convert with format string (for formatting, see `printf`)

• e.g., `\$cmd = sprintf ("kill -9 %u, \$pid)` with `\$pid` containing 432 will compute the string `kill -9 432` and store it into `\$cmd` (note that `sprintf` works differently from C)
• `str_from_int` : `int``str`
convert number to printable representation, e.g., from -123 to `"-123"`
• `int_from_str` : `str``int`
convert string to number, e.g., from `"-123"` to -123

• ignores any suffix that does not make sense, hence will convert `"-123ab45"` to -123, for example
• `str_from_uint` : `uint``str`
convert number to printable representation, e.g., from 123 to `"123"`
• `str_from_uint_hex` : `uint``str`
convert number to printable hexadecimal representation, e.g., from 123 to `"7b"`
• `uint_from_str` : `str``uint`
convert string to number, e.g., from `"123"` to 123

• ignores any suffix that does not make sense, hence will convert `"123ab45"` to 123, for example
• `str_from_float` : `float``str`
convert number to printable representation, e.g., from -123.45 to `"-123.45"`
• `float_from_str` : `str``float`
convert string to number, e.g., from `"-123.45E2"` to -12345.0

• ignores any suffix that does not make sense, hence will convert `"-123ab45"` to -123.0, for example
• `str_from_regex` : `regex``str`
extract the string from the given regexp, e.g., `str_from_regex(_REGEX("a*ba*"))` returns `"a*ba*"`
• `regex_from_str` : `str``regex`
compile the argument string to a regexp, that is, a regular expression matching machine

• may return the null object if argument string has invalid syntax
• equivalent to `_REGEX` construct, except the latter constructs a regexp at compile-time, and requires a string constant as argument; `regex_from_str` can be applied to any string computed at run-time
• `str_from_ctime``ctime``str`
convert time to printable representation
format used is `"%Y-%m-%dT%H:%M:%S%z"` (IDMEF time format, with final time zone),
so output will be `"2015-02-22T15:22:34+1"` for February 22, 2015, 15 h. 22 min. 34 sec., UTC+1 time zone
• `ctime_from_str``str``ctime`
convert string to ctime, expects string to be in IDMEF or seconds`.`microseconds format; in the second case, microseconds is ignored
• `str_from_timeval` : `timeval``str`
convert time to printable representation
format used is seconds`.`microseconds
• `timeval_from_str``str``timeval`
convert string to timeval, expects string to be in IDMEF or seconds`.`microseconds format
• `str_from_ipv4` : `ipv4``str`
convert IPv4 address to printable representation, e.g., from 128.0.0.1 to `"128.0.0.1"`
• `str_from_ipv6` : `ipv6``str`
convert IPv6 address to printable representation, as 8 digits separated by `:`
• `ipv4_from_ipv6` : `ipv6``ipv4`
convert IPv6 address to IPv4 address, by truncating it to its last 4 bytes
• `ipv6_from_ipv4` : `ipv4``ipv6`
• `int_from_uint` : `uint``int`
convert monotonously unsigned integer to integer, i.e. returns LONG_MAX if the unsigned integer is bigger than LONG_MAX
• `uint_from_int` : `int``uint`
convert monotonously integer to unsigned integer, i.e. returns 0 if the integer is negative
• `int_from_float` : `float``int`
convert monotonously float to integer, i.e. returns LONG_MAX if the float is bigger than LONG_MAX and LONG_MIN if the float is smaller than LONG_MIN
• `float_from_int` : `int` → `float`
convert integer to float
• `uint_from_float` : `float``uint`
convert monotonously float to unsigned integer, i.e. returns ULONG_MAX if the float is bigger than ULONG_MAX and 0 if the float is negative
• `float_from_uint` : `uint``float`
convert unsigned integer to float
• `add_slashes` : `str``str`
escape special characters: add a backslash `\` in front of `'`, `"`, and `\`, replace ASCII code 7 by `\a` (two characters), 8 by `\b`, 9 by `\t`, 10 by `\n`, 11 by `\v`, 12 by `\f`, 13 by `\t`, all other characters with ASCII code <32 or >126 by a backslash followed by their octal value on three digits, and leave all other characters unchanged

### Reaction and control

• `report`: → `int`
generate report in standard report directories (by default, `/usr/local/var/orchids/reports/`).
The report includes the values of the currently defined OrchIDS variables: if you want to report something, just have it stored into some variable.
Depending on which modules are installed, this will generate a report in a variety of formats.

• if `mod_htmlstate` is installed, then a report will be created in a file located in the standard report directory (by default, `/usr/local/var/orchids/reports/`);
the file will be named `report-`secs`-`msecs`.html`, where secs and msecs are the current time, split into seconds and microseconds, as 8 hexadecimal digits;
the file can be inspected from a remote Web browser;
• if `mod_iodef` is installed, then a report will be created in a file located in the IODEF report directory (configurable through the IODEF module’s `IODEFOutputDir` directive);
the file will be named `report-`secs`-`msecs`.xml`, where secs and msecs are the current time, split into seconds and microseconds, as 8 hexadecimal digits, and is obtained by instanciating a template file;
• returns: `1` (true) in normal situations; `0` (false) if no active rule
• `system` : `str``int`
execute a system command

• returns: the error code, 0 if everything went well
• `systemf` : `str`, … → `int`
execute a system command with a format string (see `printf`), e.g., `systemf("kill -9 %u", \$pid);`

• returns: the error code, 0 if everything went well
• `systemf`(fmt, …) is equivalent to `system`(`sprintf`(fmt, …))

### Debugging

• `print` : * → `int`
print its argument on `stdout` (for debugging purposes)

• returns: `1` (true)
• `print_string` : `str` → `int`
print its argument, which must be a string, on ```stdout ```it prints it verbatim, without enclosing quotes and type info as `print`() does

• returns: `1` (true)
• `printf``str`, … → `int`
print its argument, which must be a string, with formatting, on ```stdout ```it prints it verbatim, without enclosing quotes, just like `print_string`() does

• e.g. `printf("pid=%u, source address=%i, sending 'ssh \"%S\"' command", \$pid, \$source, \$cmd)` will print `pid=433, source address=196.1.5.42, sending 'ssh "cat \"collected data\""' command` if `pid`=433, `\$source` holds the ipv4 address 196.1.5.42, and `\$cmd` contains the string `cat "collected data"` (note the subtle use of `%S`, instead of `%s`: that adds the required backslashes around the double quotes from the latter string).
• returns: `1` (true)
• formatting is similar to C’s `printf`, but format specifiers are different:
• `%d`: print an `int` in decimal
• `%u`: print an `uint` in decimal
• `%x`: print an `uint` in hexadecimal
• `%s`: print a `str` argument
• `%S`: print an `str` argument, calling `addslashes` on it before
• `%f`: print a `float`
• `%i`: print an `ipv4`
• `%I`: print an `ipv6`
• `%r`: print an `regex`
• `%t`: print an `ctime`
• `%T`: print an `timeval`
• `%%`: print a `%` sign
• `shutdown` : → `int`
shut Orchids down

• does not return