/*
** Copyright (C) 2004-2007 by Carnegie Mellon University.
**
** @OPENSOURCE_HEADER_START@
** 
** Use of the SILK system and related source code is subject to the terms 
** of the following licenses:
** 
** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013
** 
** NO WARRANTY
** 
** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER 
** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY 
** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN 
** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY 
** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT 
** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, 
** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE 
** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, 
** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY 
** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF 
** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. 
** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF 
** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON 
** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE 
** DELIVERABLES UNDER THIS LICENSE.
** 
** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie 
** Mellon University, its trustees, officers, employees, and agents from 
** all claims or demands made against them (and any related losses, 
** expenses, or attorney's fees) arising out of, or relating to Licensee's 
** and/or its sub licensees' negligent use or willful misuse of or 
** negligent conduct or willful misconduct regarding the Software, 
** facilities, or other rights or assistance granted by Carnegie Mellon 
** University under this License, including, but not limited to, any 
** claims of product liability, personal injury, death, damage to 
** property, or violation of any laws or regulations.
** 
** Carnegie Mellon University Software Engineering Institute authored 
** documents are sponsored by the U.S. Department of Defense under 
** Contract F19628-00-C-0003. Carnegie Mellon University retains 
** copyrights in all material produced under this contract. The U.S. 
** Government retains a non-exclusive, royalty-free license to publish or 
** reproduce these documents, or allow others to do so, for U.S. 
** Government purposes only pursuant to the copyright license under the 
** contract clause at 252.227.7013.
** 
** @OPENSOURCE_HEADER_END@
*/
#ifndef _PROBECONF_H
#define _PROBECONF_H

#include "silk.h"

RCSIDENTVAR(rcsID_PROBECONF_H, "$SiLK: probeconf.h 6821 2007-04-06 16:20:51Z mthomas $");


/*
**  probeconf.h
**
**  Functions to parse a probe configuration file and use the results.
**
*/

#include "rwpack.h"
#include "skvector.h"
#include "silk_site.h"


/*
 *  The probe definition.
 */
struct _probe_def;
typedef struct _probe_def probe_def_t;

/*
 *  Values for the type of a probe.
 */
typedef enum {
    PROBE_ENUM_NETFLOW = 0,
    PROBE_ENUM_IPFIX,
    PROBE_ENUM_SILK,
    /* Next entry MUST be last */
    PROBE_ENUM_INVALID
} probe_enum_t;

/*
 *  The number of probe types
 */
#define PROBE_TYPE_COUNT 3

/*
 *  Possible protocols
 */
typedef enum {
    PROBE_PROTO_SCTP = 0,
    PROBE_PROTO_TCP,
    PROBE_PROTO_UDP,
#if 0
    /* not sure if these should be here; we'll decide when we add SSL
     * support */
    PROBE_PROTO_DTLS_SCTP,
    PROBE_PROTO_TLS_TCP,
    PROBE_PROTO_DTLS_UDP,
#endif
    /* Next entry MUST be last */
    PROBE_PROTO_UNSET
} probe_proto_t;

/*
 *  The number of supported protocols
 */
#define PROBE_PROTOCOL_COUNT  3

/*
 *  The priority must be between these values, inclusive
 */
#define PROBE_MIN_PRIORITY   1
#define PROBE_MAX_PRIORITY 100

/*
 *  A type for the priority
 */
typedef uint16_t probe_priority_t;


/*
 *  *****  Probe configuration  **************************************
 */

/*
 *  Lifecycle:
 *
 *    The application calls probeConfSetup() to initialize the
 *    probeConf data structures and memory.
 *
 *    The application should call probeConfParse() to parse the
 *    application's configuration file.  probeConfParse() will create
 *    sensors (if any) and probes.  The probes are created and checked
 *    for validity--this means they have all the data they require.
 *    If valid they are added to the list maintained by the probeConf.
 *    If not valid, they are destroyed.
 *
 *    Once the probes have been created, the application can use
 *    probeConfCount() to get a list of valid probes, and
 *    probeConfProbeGetByPosition() to get each probe.
 *
 *    Finally, the application calls probeConfTeardown() to destroy
 *    the probes, sensors, and to fee all memory.
 *
 *    Note that probeConf allows one to create a "temporary" sensor;
 *    i.e., a sensor that will only exist as long as the application
 *    is running; this is useful for testing a new sensor without
 *    requiring a complete recompile of SiLK.  However, "temporary"
 *    sensors will NOT be available to the analysis applications.  For
 *    the analysis applications to know about a sensor, it MUST be
 *    listed in the sensorInfo[] array.
 */



int probeConfSetup(void);
/*
 *    Initialize the probe configuration data structures.
 */


void probeConfTeardown(void);
/*
 *    Destroy all probes and sensors and free all memory used by the
 *    probe configuration.
 */


int probeConfParse(const char *filename);
/*
 *    Parse the probe configuration file 'filename'.  This should only
 *    be called one time.
 *
 *    This function will parse the configuration file and create
 *    sensors and probes.  
 */


int probeConfProbeVerify(probe_def_t *probe);
/*
 *    Verify the 'probe' is valid.  For example, that it's name is
 *    unique among all probes for its sensors, that if collecting
 *    NetFlow the external interfaces are defined, etc.
 *
 *    If valid, add the probe to the list of probes and return 0.
 *    Otherwise return non-zero.
 */


size_t probeConfProbeCount(void);
/*
 *    Return the count of created and verified probes.
 */


const probe_def_t *probeConfProbeGetByPosition(
    size_t              probe_idx);
/*
 *    Return the verified probe at position 'probe_idx'.  This is a
 *    zero-based array.  If 'probe_idx' is invalid, return NULL.  The
 *    caller should not modify nor free the returned probe.
 */


int probeConfGetProbesForSensor(sk_vector_t *out_vec, sensorID_t sid);
/*
 *    Returns the number of probes that have the specified sensor-id.
 *    If 'out_vec' is non-null, it should be a valid vector whose
 *    elements are sizeof(probe_def_t*), and the probes that match
 *    the 'sid' will be appended to the vector.
 *
 *    Returns -1 for these error conditions: 'sid' is not valid,
 *    vector elements are wrong size, vector-append fails.
 */


const probe_def_t *probeConfGetProbeByName(
    const char *sensor_name,
    const char *probe_name);
/*
 *    Returns the probe named 'probe_name' that lives under
 *    'sensor_name'.  Returns NULL if not found.  The caller should
 *    not modify nor free the return value.
 */


/*
 *  *****  Probes  *****************************************************
 *
 *
 *  Flows are stored by SENSOR; a SENSOR is a logical construct made
 *  up of one or more physical PROBES.
 *
 *  A probe collects flows in one of three ways:
 *
 *  1.  The probe can listen to network traffic.  For this case,
 *  skProbeGetListenAsHost() will return the port on which to listen
 *  for traffic and the IP address that the probe should bind() to.
 *  In addition, the skProbeGetAcceptFromHost() method will give the
 *  IP address from which the probe should accept connections.
 *
 *  2.  The probe can listen on a UNIX domain socket.  The
 *  skProbeGetListenOnUnixDomainSocket() method returns the pathname
 *  to the socket.
 *
 *  3.  The probe can read from a file.  The skProbeGetFileSource()
 *  method returns the name of the file.
 *
 *  A probe is not valid it has been set to use one and only one of
 *  these collection methods.
 *
 *  Once the probe has collected a flow, it needs to determine whether
 *  the flow represents incoming traffic, outgoing traffic, ACL
 *  traffic, etc.  The skProbeDetermineFlowtype() will take an 'rwrec'
 *  and the probe where the record was collected and use the external,
 *  internal, and null interface values and the list of ISP IPs to
 *  update the 'flow_type' field on the rwrec.  The rwrec's sensor id
 *  ('sID') field is also updated.
 *
 */


int skProbeCreate(probe_def_t **probe);
/*
 *    Create a new probe and fill in 'probe' with the address of
 *    the newly allocated probe.
 */


void skProbeDestroy(probe_def_t **probe);
/*
 *    Destroy the probe at '**probe' and free all memory.  Sets *probe
 *    to NULL.
 */


int skProbeSetSensor(probe_def_t *probe, sensorID_t sensor_id);
sensorID_t skProbeGetSensorID(const probe_def_t *probe);
const char *skProbeGetSensorName(const probe_def_t *probe);
/*
 *    Each probe must be a collection point for one and only one
 *    sensor; these functions set and get the sensor for which this
 *    probe is a collector.
 *
 *    If a 'get' method is called before the 'set' method,
 *    SENSOR_INVALID_SID or NULL is returned.
 */


int skProbeSetName(probe_def_t *probe, const char *name);
const char *skProbeGetName(const probe_def_t *probe);
/*
 *    Functions to set and get the name of a probe.  A probe name must
 *    meet all the requirements of a sensor name.  Each probe that is
 *    a collection point for a single sensor must have a unique name.
 *
 *    The set function makes a copy of 'name' and returns 0 on
 *    success, non-zero on memory allocation failure.
 *
 *    The get function returns the name of the probe.  The caller
 *    should not modify the name, and does not need to free() it.
 */


const char *skProbeGetUniqueName(const probe_def_t *probe);
/*
 *    Function to get the unique name of a probe from among all
 *    probes.  Returns the probe's sensor's name if there is a single
 *    probe for the sensor; otherwise returns sensor_name/probe_name.
 *
 *    The get function returns the unique name of the probe.  The
 *    caller should not modify the name, and does not need to free()
 *    it.
 */


int skProbeSetPriority(probe_def_t *probe, probe_priority_t priority);
probe_priority_t skProbeGetPriority(const probe_def_t *probe);
/*
 *    Functions to set and get the probe's priority.
 *
 *    The set method expects the priority to be between
 *    PROBE_MIN_PRIORITY and PROBE_MAX_PRIORITY inclusive.
 *
 *    When not set by the user, the default priority is
 *    PROBE_MIN_PRIORITY.
 */


int skProbeSetType(probe_def_t *probe, probe_enum_t probe_type);
probe_enum_t skProbeGetType(const probe_def_t *probe);
/*
 *    Functions to set and get the probe's type.
 *
 *    If not set by the user, the probe's type is PROBE_ENUM_INVALID.
 */


int skProbeSetProtocol(probe_def_t *probe, probe_proto_t probe_protocol);
probe_proto_t skProbeGetProtocol(const probe_def_t *probe);
/*
 *    Functions to set and get the probe's protocol.
 *
 *    If not set by the user, the probe's protocol is the default for
 *    the type of probe, or PROBE_PROTO_UNSET if the type has not been
 *    set.
 */


int skProbeSetLogFlags(
    probe_def_t        *probe,
    uint32_t            log_flags);
uint8_t skProbeGetLogFlags(
    const probe_def_t  *probe);
/*
 *    Functions to get and set the probe's logging-flags; these
 *    logging flags refer to the log messages regarding missing and
 *    bad packet counts that some of the flow sources support.
 *
 *    The value of log_flags can be SOURCE_LOG_NONE to log nothing;
 *    SOURCE_LOG_ALL to log everything (the default); or a bitwise OR
 *    of the SOURCE_LOG_* values defined in libflowsource.h.
 */


int skProbeSetIspIps(
    probe_def_t        *probe,
    const sk_vector_t  *isp_ip_vec);
uint32_t skProbeGetIspIps(
    const uint32_t    **out_ip_list,
    const probe_def_t  *probe);
/*
 *    Functions to set and get the IP addresses of the ISP routers
 *    that this probe receives data from.  When flows are sent to the
 *    null-interface, these IP addresses are used to distinguish
 *    between flows that were ACL'ed and those that were probably
 *    IP-routing messages sent from the ISP to this probe.
 *
 *    The 'set' method takes a vector of uint32_t's containing the
 *    list of IP addresses.  The function will copy the values from
 *    the vector.  It returns 0 on success, or -1 on memory allocation
 *    errors.
 *
 *    The 'get' method returns the length of the list of ISP-IPs.  If
 *    the 'out' parameter is provided, it will be modified to point to
 *    the list of IP addresses (a C-array).  The caller should NOT
 *    modify the ISP-IP list that she receives, nor should she free()
 *    it.  When the 'get' method is called before the 'set' method, 0
 *    is returned and the out parameter is not modified.
 */


int skProbeSetIpBlock(
    probe_def_t            *probe,
    const sk_vector_t      *ipblock_vec,
    int                     is_negated,
    ifmap_group_id_t        if_group_id);
uint32_t skProbeGetIpBlock(
    sk_vector_t            *out_ipblock_vec,
    int                    *out_is_negated,
    const probe_def_t      *probe,
    ifmap_group_id_t        if_group_id);
/*
 *    Functions to set and get the list of IPs associated with the
 *    interface ID 'if_group_id'.  The list of if_group_id's is set in
 *    silk_site.h.
 *
 *    In general, a flow whose source IP is specified in the list of
 *    IFMAP_EXTERNAL addresses will be considered incoming.
 *
 *    The 'set' method takes a vector of skOctetMap_t's containing the
 *    IPs to assign to the 'if_group_id'.  The function will copy the
 *    values from the vector.  The 'is_negated' value, if non-zero,
 *    means that the list of IPs to assign to 'if_group_id' are all
 *    those NOT given in the vector.  The function returns 0 on
 *    success, or -1 if the vector is NULL or empty.
 *
 *    The 'get' method returns the number skOctetMap_t's assigned to
 *    'if_group_id'.  When the 'out_ipblock_vec' parameter is
 *    provided, the skOctetMap_t's will be appended to the vector.
 *    The 'out_is_negated' parameter will be set to 1 if the
 *    skOctetMap_t's are the IPs that are NOT assigned to
 *    'IFMAP_EXTERNAL'.  The caller should NOT modify the
 *    skOctetMap_t's that she receives, nor should she free() them.
 *    When the 'get' method is called before the 'set' method, 0 is
 *    returned and the out parameter is not modified.
 *
 *    The skProbeSetIpBlock() function will return an error if
 *    skProbeSetInterfaces() function is called before it.
 */


int skProbeSetIpBlockRemainingIps(
    probe_def_t        *probe,
    ifmap_group_id_t    if_group_id);
/*
 *    Sets the interface ID 'if_group_id' to all IPs that not assigned
 *    to another interface.  The list of if_group_id's is set in
 *    silk_site.h.
 */


int skProbeSetInterfaces(
    probe_def_t        *probe,
    const sk_vector_t  *if_vec,
    ifmap_group_id_t    if_group_id);
uint32_t skProbeGetInterfaces(
    const sk_bitmap_t **out_if_map,
    const probe_def_t  *probe,
    ifmap_group_id_t    if_group_id);
/*
 *    Functions to set and get the SNMP interfaces associated with the
 *    interface ID 'if_group_id'.  The list of if_group_id's is set in
 *    silk_site.h.
 *
 *    In general, a flow that enters the router on one of the
 *    interfaces assigned to IFMAP_EXTERNAL will be considered
 *    incoming.  The determination of "outgoing" depends on whether
 *    IFMAP_INTERNAL interfaces are specified.
 *
 *    The 'set' method takes a vector of uint32_t's containing the
 *    list of SNMP interfaces to assign to the 'if_group_id'
 *    interface.  The function will copy the values from the vector.
 *    It returns 0 on success, or -1 if the vector is NULL or empty.
 *
 *    The 'get' method returns the number interfaces assigned to
 *    'if_group_id'.  When the 'out_if_map' parameter is provided, it
 *    will be modified to point to a BITMAP of length
 *    SK_SNMP_INDEX_LIMIT, where a high bit represents an external
 *    interface.  The caller should NOT modify the BITMAP that she
 *    receives, nor should she free() it.  When the 'get' method is
 *    called before the 'set' method, 0 is returned and the out
 *    parameter is not modified.
 */


int skProbeSetInterfaceToRemainder(
    probe_def_t        *probe,
    ifmap_group_id_t    if_group_id);
/*
 *    Sets the interface ID 'if_group_id' to any SNMP interface that
 *    is not assigned to another interface.  The list of if_group_id's
 *    is set in silk_site.h.
 */


int skProbeSetListenAsAddr(
    probe_def_t        *probe,
    in_addr_t           addr);
int skProbeSetListenOnPort(
    probe_def_t        *probe,
    uint32_t            port);
int skProbeGetListenAsHost(
    in_addr_t          *out_addr,
    uint16_t           *out_port,
    const probe_def_t  *probe);
/*
 *    Functions to set and get the port on which the probe listens for
 *    connections, and, for multi-homed hosts, the IP address that the
 *    probe should consider to be its IP.
 *
 *    When setting the information, the 'addr' must be non-zero and
 *    the port must be valid.
 *
 *    When getting the information, the caller may pass in locations
 *    to be filled with the address and port; either parameter may be
 *    NULL to ignore that value.
 *
 *    The probe simply stores the address; it does not manipulate
 *    it in any way.
 *
 *    If the IP address to listen as is not set, the 'get' function
 *    returns INADDR_ANY in the 'out_addr'.  If the port has not been
 *    set, the 'get' function returns -1 and neither 'out' parameter
 *    is modified.
 */


int skProbeSetListenOnUnixDomainSocket(
    probe_def_t        *probe,
    const char *        u_socket);
const char *skProbeGetListenOnUnixDomainSocket(const probe_def_t *probe);
/*
 *    Functions to set and get the unix domain socket on which the
 *    probe listens for connections.
 *
 *    The 'set' method will make a copy of the 'u_socket' value.
 *
 *    The caller should neither modify nor free the value returned by
 *    the 'get' method.  The 'get' method returns NULL if the 'set'
 *    method has not yet been called.
 */


int skProbeSetFileSource(
    probe_def_t        *probe,
    const char         *pathname);
const char *skProbeGetFileSource(const probe_def_t *probe);
/*
 *    Functions to set and get the file name from which to read data.
 *
 *    The 'set' function will make a copy of the 'pathname' value.
 *
 *    The caller should neither modify nor free the value returned by
 *    the 'get' method.  The 'get' method returns NULL if the 'set'
 *    method has not yet been called.
 */


int skProbeSetPollDirectory(
    probe_def_t        *probe,
    const char         *pathname);
const char *skProbeGetPollDirectory(const probe_def_t *probe);
/*
 *    Functions to set and get the name of the directory to poll for
 *    files containing flow records.
 *
 *    The 'set' function will make a copy of the 'pathname' value.
 *
 *    The caller should neither modify nor free the value returned by
 *    the 'get' method.  The 'get' method returns NULL if the 'set'
 *    method has not yet been called.
 */


int skProbeSetAcceptFromHost(
    probe_def_t        *probe,
    const char         *host_name,
    in_addr_t           host_addr);
const char *skProbeGetAcceptFromHost(
    in_addr_t          *out_addr,
    const probe_def_t  *probe);
/*
 *    Functions to set and get the host the probe accepts connections
 *    from.
 *
 *    When setting the information, the host_addr must be non-zero.
 *    If the host_name is provided, the probe will make a copy of it.
 *
 *    When getting the information, the caller should pass in a
 *    location to be filled with the address; the host name is the
 *    return value of the function.  The caller should not modify or
 *    free the hostname.
 *
 *    The probe simply stores the host_address; it does not manipulate
 *    it in any way.
 *
 *    If the 'get' function is called before the 'set' function, NULL
 *    is returned and INADDR_ANY is stored in 'out_addr'.
 */


probe_enum_t skProbetypeNameToEnum(const char *name);
const char *skProbetypeEnumtoName(probe_enum_t type);
/*
 *    Functions to convert between probe types and a printable
 *    respresentation of the types.
 *
 *    Return PROBE_ENUM_INVALID or NULL when given an illegal value.
 */


probe_proto_t skProbeNameToProtocol(const char *name);
const char *skProbeProtocolToName(probe_proto_t proto);
/*
 *    Functions to convert between probe protocol values and a
 *    printable respresentation of the protocol.
 *
 *    Return PROBE_PROTO_UNSET or NULL when given an illegal value.
 */


int skProbeDetermineFlowtype(
    const probe_def_t  *probe,
    const rwRec        *rwrec,
    uint8_t            *ftypes,
    sensorID_t         *sensorids);
/*
 *    A function that determines the flow type(s) and sensorID(s) of
 *    a flow record 'rwrec' and was collected from the 'probe'.  The
 *    function will compare the SNMP interfaces on the record with
 *    those specified in the probe for external, internal, and null
 *    flows.
 *
 *    'ftypes' and 'sensorids' should each be arrays having enough
 *    space to hold the expected number of flow_types and sensorIDs;
 *    NUM_FLOW_TYPES is the maximum that could be returned.  These
 *    arrays will be populated with the flow_type and sensorID pair(s)
 *    into which the record should be packed.
 *
 *    Excepting errors, the return value is always the number of
 *    flow_type/sensorID pairs into which the record should be packed.
 *
 *    A return value of 0 indicates no packing rules existed for this
 *    record from this probe; a value of -1 indicates an error
 *    condition.
 */


#endif /* _PROBECONF_H */

/*
** Local variables:
** mode:c
** indent-tabs-mode:nil
** c-basic-offset:4
** End:
*/
