Ejemplo n.º 1
0
/* Public entry point */
skplugin_err_t
skPrefixMapAddFields(
    uint16_t            major_version,
    uint16_t            minor_version,
    void        UNUSED(*data))
{
    skplugin_err_t err;

#define PMAP_FILE_HELP(str_arg)                                         \
    ("Prefix map file to read.  Def. None.  When the argument has\n"    \
     "\tthe form \"<mapfile>:<filename>\","                             \
     " the \"mapname\" is used to generate\n"                           \
     str_arg)

    assert(strlen(src_dir_name) == strlen(dst_dir_name));

    /* Check API version */
    err = skpinSimpleCheckVersion(major_version, minor_version,
                                  PLUGIN_API_VERSION_MAJOR,
                                  PLUGIN_API_VERSION_MINOR,
                                  skAppPrintErr);
    if (err != SKPLUGIN_OK) {
        return err;
    }

    /* Initialize global variables */
    pmap_vector = skVectorNew(sizeof(pmap_data_t *));
    if (pmap_vector == NULL) {
        ERR_NO_MEM(pmap_vector);
        return SKPLUGIN_ERR;
    }

    /* Add --pmap-file to apps that accept RWREC: rwcut, rwsort, etc */
    err = skpinRegOption2(pmap_file_option,
                          REQUIRED_ARG,
                          PMAP_FILE_HELP(
                              "\tfield names.  As such, this switch must"
                              " precede the --fields switch."), NULL,
                          pmapfile_handler, NULL,
                          2,
                          SKPLUGIN_FN_REC_TO_TEXT,
                          SKPLUGIN_FN_REC_TO_BIN);
    if (err == SKPLUGIN_ERR_FATAL) {
        return err;
    }

    /* Add --pmap-column-width to apps that produce TEXT: rwcut, rwuniq  */
    err = skpinRegOption2(pmap_column_width_option,
                          REQUIRED_ARG,
                          "Maximum column width to use for output.", NULL,
                          pmap_column_width_handler, NULL,
                          2,
                          SKPLUGIN_FN_REC_TO_TEXT,
                          SKPLUGIN_FN_BIN_TO_TEXT);
    if (err == SKPLUGIN_ERR_FATAL) {
        return err;
    }

    /* Add --pmap-file to rwfilter */
    err = skpinRegOption2(pmap_file_option,
                          REQUIRED_ARG,
                          PMAP_FILE_HELP(
                              "\tfiltering switches.  This switch must"
                              " precede other --pmap-* switches."), NULL,
                          pmapfile_handler, NULL,
                          1, SKPLUGIN_FN_FILTER);
    if (err == SKPLUGIN_ERR_FATAL) {
        return err;
    }

    /* Register cleanup function */
    skpinRegCleanup(pmap_teardown);

    return SKPLUGIN_OK;
}
Ejemplo n.º 2
0
/*
 *    Verify sensor by its class.  Verify that the sensor supports the
 *    type(s) of its probe(s).  Verify that enough information is
 *    present on the sensor to categorize a flow record.
 *
 *    Invoked from rwflowpack by packlogic->verify_sensor_fn
 */
static int
packLogicVerifySensor(
    skpc_sensor_t      *sensor)
{
    skpc_probe_t *probe;
    sk_vector_t *probe_vec;
    uint32_t count;

    /* There is a single class, so no per-class verification is
     * necessary.  Make certain we have either snmp interface values
     * or ip-blocks depending on the type of probe(s) associated with
     * this sensor. */

    /* get the probes for the sensor */
    probe_vec = skVectorNew(sizeof(skpc_probe_t*));
    if (probe_vec == NULL) {
        return -1;
    }
    count = skpcSensorGetProbes(sensor, probe_vec);

    /* this packing logic only supports a single probe per sensor */
    if (count != 1) {
        skAppPrintErr(("Cannot verify sensor '%s':\n"
                       "\tOnly one probe per sensor is supported"
                       " by the packing-logic\n\tfile '%s'"),
                      sensor->sensor_name,
                      plugin_path);
        skVectorDestroy(probe_vec);
        return -1;
    }
    skVectorGetValue(&probe, probe_vec, 0);
    skVectorDestroy(probe_vec);

    /* make certain the probe's type is valid */
    switch (probe->probe_type) {
      case PROBE_ENUM_NETFLOW_V5:
      case PROBE_ENUM_NETFLOW_V9:
      case PROBE_ENUM_IPFIX:
        /* expected probe types */
        break;

      default:
        assert(skpcProbetypeEnumtoName(probe->probe_type));
        skAppPrintErr(("Cannot verify sensor '%s':\n"
                       "\tThe probe type '%s' is not supported in the"
                       " packing-logic\n\tfile '%s'"),
                      sensor->sensor_name,
                      skpcProbetypeEnumtoName(probe->probe_type),
                      plugin_path);
        return -1;
    }


    /* Verify that we have enough information to determine the
     * flowtype for every flow.  These are the rules:
     *
     * 1. One of external-interface, external-ipblock, or
     * external-ipset must be specified.
     *
     * 2. You cannot mix interfaces, ipblocks, and ipsets, with the
     * excption that a null-interface which is always allowed.
     *
     * 3. Only one network may claim the remainder.
     *
     * 4. Using remainder for an ipblock or ipset requires that
     * another interface has set an IPblock or an IPset.
     */
    switch (sensor->decider[NETWORK_EXTERNAL].nd_type) {
      case SKPC_UNSET:
        /* It is an error when neither SNMP interfaces nor IP-blocks
         * were specified for the external network. */
        skAppPrintErr(("Cannot verify sensor '%s':\n"
                       "\tMust specify %s-interface, %s-ipblock, or %s-ipset"),
                      sensor->sensor_name,
                      net_names[NETWORK_EXTERNAL],
                      net_names[NETWORK_EXTERNAL],
                      net_names[NETWORK_EXTERNAL]);
        return -1;

      case SKPC_NEG_IPBLOCK:
        skAppPrintErr("Negated IPblock logic not implemented");
        exit(EXIT_FAILURE);
      case SKPC_NEG_IPSET:
        skAppPrintErr("Negated IPset logic not implemented");
        exit(EXIT_FAILURE);

      case SKPC_IPBLOCK:
        /* Fine as long as INTERNAL is either empty or also contains
         * IPblocks */
        switch (sensor->decider[NETWORK_INTERNAL].nd_type) {
          case SKPC_UNSET:
          case SKPC_IPBLOCK:
          case SKPC_REMAIN_IPBLOCK:
            /* These are fine */
            break;

          case SKPC_NEG_IPBLOCK:
            skAppPrintErr("Negated IPblock logic not implemented");
            exit(EXIT_FAILURE);
          case SKPC_NEG_IPSET:
            skAppPrintErr("Negated IPset logic not implemented");
            exit(EXIT_FAILURE);

          case SKPC_INTERFACE:
          case SKPC_REMAIN_INTERFACE:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipblock and %s-interface"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;

          case SKPC_IPSET:
          case SKPC_REMAIN_IPSET:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipblock and %s-ipset"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;
        }
        break;

      case SKPC_REMAIN_IPBLOCK:
        switch (sensor->decider[NETWORK_INTERNAL].nd_type) {
          case SKPC_UNSET:
            /* Accept for now, though this will be an error if
             * NETWORK_NULL does not define an IPblock */
            break;

          case SKPC_NEG_IPBLOCK:
            skAppPrintErr("Negated IPblock logic not implemented");
            exit(EXIT_FAILURE);
          case SKPC_NEG_IPSET:
            skAppPrintErr("Negated IPset logic not implemented");
            exit(EXIT_FAILURE);

          case SKPC_REMAIN_IPBLOCK:
            /* Cannot have multiple things requesting "remainder" */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tOnly one network value may use 'remainder'"),
                          sensor->sensor_name);
            return -1;

          case SKPC_IPBLOCK:
            /* This is fine */
            break;

          case SKPC_INTERFACE:
          case SKPC_REMAIN_INTERFACE:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipblock and %s-interface"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;

          case SKPC_IPSET:
          case SKPC_REMAIN_IPSET:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipblock and %s-ipset"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;
        }
        break;

      case SKPC_INTERFACE:
      case SKPC_REMAIN_INTERFACE:
        /* Fine as long as INTERNAL and NULL are either empty or also
         * contain interfaces */
        switch (sensor->decider[NETWORK_INTERNAL].nd_type) {
          case SKPC_UNSET:
          case SKPC_INTERFACE:
          case SKPC_REMAIN_INTERFACE:
            switch (sensor->decider[NETWORK_NULL].nd_type) {
              case SKPC_IPBLOCK:
              case SKPC_NEG_IPBLOCK:
              case SKPC_REMAIN_IPBLOCK:
                /* Bad mix */
                skAppPrintErr(("Cannot verify sensor '%s':\n"
                               "\tCannot mix %s-interface and %s-ipblock"),
                              sensor->sensor_name,
                              net_names[NETWORK_EXTERNAL],
                              net_names[NETWORK_NULL]);
                return -1;
              case SKPC_IPSET:
              case SKPC_NEG_IPSET:
              case SKPC_REMAIN_IPSET:
                /* Bad mix */
                skAppPrintErr(("Cannot verify sensor '%s':\n"
                               "\tCannot mix %s-interface and %s-ipset"),
                              sensor->sensor_name,
                              net_names[NETWORK_EXTERNAL],
                              net_names[NETWORK_NULL]);
                return -1;
              default:
                break;
            }
            break;

          case SKPC_IPBLOCK:
          case SKPC_NEG_IPBLOCK:
          case SKPC_REMAIN_IPBLOCK:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-interface and %s-ipblock"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;

          case SKPC_IPSET:
          case SKPC_NEG_IPSET:
          case SKPC_REMAIN_IPSET:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-interface and %s-ipset"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;
        }
        break;

      case SKPC_IPSET:
        /* Fine as long as INTERNAL is either empty or also contains
         * IPsets */
        switch (sensor->decider[NETWORK_INTERNAL].nd_type) {
          case SKPC_UNSET:
          case SKPC_IPSET:
          case SKPC_REMAIN_IPSET:
            /* These are fine */
            break;

          case SKPC_NEG_IPSET:
            skAppPrintErr("Negated IPset logic not implemented");
            exit(EXIT_FAILURE);
          case SKPC_NEG_IPBLOCK:
            skAppPrintErr("Negated IPblock logic not implemented");
            exit(EXIT_FAILURE);

          case SKPC_INTERFACE:
          case SKPC_REMAIN_INTERFACE:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipset and %s-interface"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;

          case SKPC_IPBLOCK:
          case SKPC_REMAIN_IPBLOCK:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipset and %s-ipblock"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;
        }
        break;

      case SKPC_REMAIN_IPSET:
        switch (sensor->decider[NETWORK_INTERNAL].nd_type) {
          case SKPC_UNSET:
            /* Accept for now, though this will be an error if
             * NETWORK_NULL does not define an IPset */
            break;

          case SKPC_NEG_IPSET:
            skAppPrintErr("Negated IPset logic not implemented");
            exit(EXIT_FAILURE);
          case SKPC_NEG_IPBLOCK:
            skAppPrintErr("Negated IPblock logic not implemented");
            exit(EXIT_FAILURE);

          case SKPC_REMAIN_IPSET:
            /* Cannot have multiple things requesting "remainder" */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tOnly one network value may use 'remainder'"),
                          sensor->sensor_name);
            return -1;

          case SKPC_IPSET:
            /* This is fine */
            break;

          case SKPC_INTERFACE:
          case SKPC_REMAIN_INTERFACE:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipset and %s-interface"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;

          case SKPC_IPBLOCK:
          case SKPC_REMAIN_IPBLOCK:
            /* Bad mix */
            skAppPrintErr(("Cannot verify sensor '%s':\n"
                           "\tCannot mix %s-ipset and %s-ipblock"),
                          sensor->sensor_name,
                          net_names[NETWORK_EXTERNAL],
                          net_names[NETWORK_INTERNAL]);
            return -1;
        }
        break;
    }

    return 0;
}
Ejemplo n.º 3
0
static skplugin_err_t
parseFlowtypes(
    const char         *opt_arg,
    void               *v_bitmap)
{
    static int registered_fields = 0;
    sk_bitmap_t **ft_bitmap;
    sksite_error_iterator_t *err_iter = NULL;
    sk_vector_t *ft_vec = NULL;
    sk_flowtype_id_t ft;
    int i = 0;
    skplugin_err_t err = SKPLUGIN_OK;
    int rv;

    assert(v_bitmap);
    ft_bitmap = (sk_bitmap_t**)v_bitmap;

    if (NULL != *ft_bitmap) {
        /* this is an attempt to re-create a list of flowtypes, which
         * could happen if the first pass was generated by parsing an
         * environment variable.  clear the bitmap */
        skBitmapClearAllBits(*ft_bitmap);

    } else if (skBitmapCreate(ft_bitmap, SK_MAX_NUM_FLOWTYPES)) {
        skAppPrintErr("Unable to create bitmap");
        err = SKPLUGIN_ERR;
        goto END;
    }

    ft_vec = skVectorNew(sizeof(sk_flowtype_id_t));
    if (NULL == ft_vec) {
        skAppPrintErr("Unable to create vector");
        err = SKPLUGIN_ERR;
        goto END;
    }
    rv = sksiteParseFlowtypeList(ft_vec, opt_arg, NULL, NULL, NULL, NULL,
                                 &err_iter);
    if (rv) {
        if (rv < 0) {
            skAppPrintErr("Memory or internal error while parsing flowtypes");
        } else if (1 == rv) {
            sksiteErrorIteratorNext(err_iter);
            skAppPrintErr("Invalid flowtypes '%s': %s",
                          opt_arg, sksiteErrorIteratorGetMessage(err_iter));
            assert(sksiteErrorIteratorNext(err_iter)
                   == SK_ITERATOR_NO_MORE_ENTRIES);
        } else {
            skAppPrintErr("Invalid flowtypes '%s': Found multiple errors:",
                          opt_arg);
            while (sksiteErrorIteratorNext(err_iter) == SK_ITERATOR_OK) {
                skAppPrintErr("%s", sksiteErrorIteratorGetMessage(err_iter));
            }
        }
        err = SKPLUGIN_ERR;
        goto END;
    }
    if (0 == skVectorGetCount(ft_vec)) {
        skAppPrintErr("Invalid flowtypes '%s': No valid flowtypes found",
                      opt_arg);
        err = SKPLUGIN_ERR;
        goto END;
    }

    for (i = 0; 0 == skVectorGetValue(&ft, ft_vec, i); ++i) {
        skBitmapSetBit(*ft_bitmap, ft);
    }

    if (incoming_flowtypes && outgoing_flowtypes && !registered_fields) {
        registered_fields = 1;

        err = skpinRegIPAddressField("int-ip", &internalIp, 0);
        if (SKPLUGIN_OK != err) {
            goto END;
        }
        err = skpinRegIPAddressField("ext-ip", &externalIp, 0);
        if (SKPLUGIN_OK != err) {
            goto END;
        }
        err = skpinRegIntField("int-port", 0, UINT16_MAX, &internalPort, 0);
        if (SKPLUGIN_OK != err) {
            goto END;
        }
        err = skpinRegIntField("ext-port", 0, UINT16_MAX, &externalPort, 0);
        if (SKPLUGIN_OK != err) {
            goto END;
        }
    }

  END:
    skVectorDestroy(ft_vec);
    sksiteErrorIteratorFree(err_iter);
    if (*ft_bitmap && err != SKPLUGIN_OK) {
        skBitmapDestroy(ft_bitmap);
        *ft_bitmap = NULL;
    }
    return err;
}