# 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, typeint
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, typeint
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 : intstr
convert number to printable representation, e.g., from -123 to "-123"
• int_from_str : strint
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 : uintstr
convert number to printable representation, e.g., from 123 to "123"
• str_from_uint_hex : uintstr
convert number to printable hexadecimal representation, e.g., from 123 to "7b"
• uint_from_str : struint
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 : floatstr
convert number to printable representation, e.g., from -123.45 to "-123.45"
• float_from_str : strfloat
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 : regexstr
extract the string from the given regexp, e.g., str_from_regex(_REGEX("a*ba*")) returns "a*ba*"
• regex_from_str : strregex
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_ctimectimestr
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_strstrctime
convert string to ctime, expects string to be in IDMEF or seconds.microseconds format; in the second case, microseconds is ignored
• str_from_timeval : timevalstr
convert time to printable representation
format used is seconds.microseconds
• timeval_from_strstrtimeval
convert string to timeval, expects string to be in IDMEF or seconds.microseconds format
• str_from_ipv4 : ipv4str
convert IPv4 address to printable representation, e.g., from 128.0.0.1 to "128.0.0.1"
• str_from_ipv6 : ipv6str
convert IPv6 address to printable representation, as 8 digits separated by :
• ipv4_from_ipv6 : ipv6ipv4
convert IPv6 address to IPv4 address, by truncating it to its last 4 bytes
• ipv6_from_ipv4 : ipv4ipv6
convert IPv4 address to IPv6 address, by adding 12 zero bytes before the  4 bytes of the IPv4 address
• int_from_uint : uintint
convert monotonously unsigned integer to integer, i.e. returns LONG_MAX if the unsigned integer is bigger than LONG_MAX
• uint_from_int : intuint
convert monotonously integer to unsigned integer, i.e. returns 0 if the integer is negative
• int_from_float : floatint
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 : floatuint
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 : uintfloat
convert unsigned integer to float
• add_slashes : strstr
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 : strint
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)
• printfstr, … → 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