Net-Nmsg

 view release on metacpan or  search on metacpan

Nmsg.xs  view on Meta::CPAN

    MCE(NMSG_RES_MAGIC_MISMATCH,   nmsg_res_magic_mismatch  );
    MCE(NMSG_RES_VERSION_MISMATCH, nmsg_res_version_mismatch);

    MC(NMSG_FF_REPEATED);
    MC(NMSG_FF_REQUIRED);
    MC(NMSG_FF_HIDDEN);
    MC(NMSG_FF_NOPRINT);

    MCE(NMSG_FT_ENUM,       nmsg_msgmod_ft_enum    );
    MCE(NMSG_FT_BYTES,      nmsg_msgmod_ft_bytes   );
    MCE(NMSG_FT_STRING,     nmsg_msgmod_ft_string  );
    MCE(NMSG_FT_MLSTRING,   nmsg_msgmod_ft_mlstring);
    MCE(NMSG_FT_IP,         nmsg_msgmod_ft_ip      );
    MCE(NMSG_FT_UINT16,     nmsg_msgmod_ft_uint16  );
    MCE(NMSG_FT_UINT32,     nmsg_msgmod_ft_uint32  );
    MCE(NMSG_FT_UINT64,     nmsg_msgmod_ft_uint64  );
    MCE(NMSG_FT_INT16,      nmsg_msgmod_ft_int16   );
    MCE(NMSG_FT_INT32,      nmsg_msgmod_ft_int32   );
    MCE(NMSG_FT_INT64,      nmsg_msgmod_ft_int64   );
    MCE(NMSG_FT_DOUBLE,     nmsg_msgmod_ft_double  );
    MCE(NMSG_FT_BOOL,       nmsg_msgmod_ft_bool    );

    MCE(NMSG_ALIAS_OPERATOR,    nmsg_alias_operator);
    MCE(NMSG_ALIAS_GROUP,       nmsg_alias_group   );

    MATH_INT64_BOOT;
}


MODULE = Net::Nmsg		PACKAGE = Net::Nmsg     PREFIX = nmsg_

void
_nmsg_init_lib()
    PREINIT:
    nmsg_res    res;
    CODE:
    if (NULL == orig_perl)
        orig_perl = Perl_get_context();
    res = nmsg_init();
    if (res != nmsg_res_success)
        croak("nmsg_init failed: %s", nmsg_res_lookup(res));

void
nmsg_set_autoclose(autoclose)
    _Bool   autoclose

void
nmsg_set_debug(debug)
    int debug


MODULE = Net::Nmsg		PACKAGE = Net::Nmsg::Util   PREFIX = nmsg_

void
nmsg_chalias_lookup(ch)
    const char *ch
    PREINIT:
    char **alias = NULL;
    int num_aliases;
    int i;
    PPCODE:
    num_aliases = nmsg_chalias_lookup(ch, &alias);
    if (num_aliases > 0) {
        for (i = 0; i < num_aliases; i++)
            mXPUSHs(newSVpv(alias[i], 0));
    }
    if (alias != NULL)
        nmsg_chalias_free(&alias);

const char *
nmsg_alias_by_key(ae, key)
	nmsg_alias_e    ae
	unsigned        key

unsigned
nmsg_alias_by_value(ae, value)
	nmsg_alias_e    ae
	const char     *value

void
find_all_devs()
    PREINIT:
    char    err[PCAP_ERRBUF_SIZE];
    PPCODE:
    pcap_if_t *devs, *d;

    if (pcap_findalldevs(&devs, err) == -1)
        croak("%s", err);

    for (d=devs; d; d=d->next) {
        mXPUSHs(newSVpv(d->name, 0));
        if (d->description)
            mXPUSHs(newSVpv(d->description, 0));
        else {
            if ((strcmp(d->name,"lo")  == 0) || (strcmp(d->name,"lo0") == 0))
                mXPUSHs(newSVpv("loopback device", 0));
            else
                mXPUSHs(newSVpv("unknown device", 0));
        }
    }
    pcap_freealldevs(devs);

const char *
lookup_result(val)
    enum nmsg_res val
    CODE:
    RETVAL = nmsg_res_lookup(val);
    OUTPUT:
    RETVAL

void
get_timestring()
    PREINIT:
    char    now[32];
    struct  timespec ts;
    struct  tm *tm;
    time_t  t;
    char   *tstr;
    PPCODE:
    nmsg_timespec_get(&ts);
    t = (time_t) ts.tv_sec;
    tm = gmtime(&t);
    strftime(now, sizeof(now), "%Y%m%d.%H%M.%s", tm);
    nmsg_asprintf(&tstr, "%s.%09ld", now, ts.tv_nsec);
    if (tstr == NULL)
        croak("problem allocating time string");
    mXPUSHs(newSVpv(tstr, 0));
    Safefree(tstr);


MODULE = Net::Nmsg  PACKAGE = Net::Nmsg::Util   PREFIX = nmsg_msgmod_

PROTOTYPES: ENABLE

nmsg_msgmod_t
_msgmod_lookup(vid, msgtype)
    unsigned    vid
    unsigned    msgtype
    CODE:
    RETVAL = nmsg_msgmod_lookup(vid, msgtype);
    OUTPUT:
    RETVAL

size_t
nmsg_msgmod_get_max_vid()

size_t
nmsg_msgmod_get_max_msgtype(vid)
	unsigned    vid

unsigned
nmsg_msgmod_mname_to_msgtype(vid, mname)
	unsigned    vid
	const char *mname

const char *
nmsg_msgmod_msgtype_to_mname(vid, msgtype)
	unsigned    vid
	unsigned    msgtype

const char *
nmsg_msgmod_vid_to_vname(vid)
	unsigned    vid

unsigned
nmsg_msgmod_vname_to_vid(vname)
	char *vname


MODULE = Net::Nmsg  PACKAGE = Net::Nmsg::XS::io PREFIX = nmsg_io_

PROTOTYPES: ENABLE

Net::Nmsg::XS::io
init(CLASS)
  const char *CLASS
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = nmsg_io_init();

Nmsg.xs  view on Meta::CPAN

    if (RETVAL == NULL)
        croak("pcap_open_offline() failed: %s", err);
    OUTPUT:
    RETVAL

Net::Nmsg::XS::pcap
open_live(CLASS, iface, snaplen, promisc)
    const char *CLASS
    const char *iface
    int         snaplen
    int         promisc
    PREINIT:
    char    err[PCAP_ERRBUF_SIZE];
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = pcap_open_live(iface, snaplen, promisc, 0, err);
    if (RETVAL == NULL)
        croak("pcap_open_offline() failed: %s", err);
    OUTPUT:
    RETVAL

void
destroy(THIS)
    Net::Nmsg::XS::pcap THIS
    CODE:
    pcap_close(THIS);

int
set_snaplen(THIS, snaplen)
    Net::Nmsg::XS::pcap THIS
    int                 snaplen
    CODE:
#ifdef LIMITED_PCAP
    PERL_UNUSED_VAR(snaplen);
    croak("pcap_set_snaplen unavailable in this version of libpcap");
#else
    RETVAL = pcap_set_snaplen(THIS, snaplen);
#endif /* LIMITED_PCAP */
    OUTPUT:
    RETVAL

int
set_promisc(THIS, promisc)
    Net::Nmsg::XS::pcap THIS
    int                 promisc
    CODE:
#ifdef LIMITED_PCAP
    PERL_UNUSED_VAR(promisc);
    croak("pcap_set_promisc unavailable in this version of libpcap");
#else
    RETVAL = pcap_set_promisc(THIS, promisc);
#endif /* LIMITED_PCAP */
    OUTPUT:
    RETVAL

void
get_selectable_fd(THIS)
    Net::Nmsg::XS::pcap THIS
    PREINIT:
    int res;
    PPCODE:
    res = pcap_get_selectable_fd(THIS);
    if (res != -1)
        mXPUSHi(res);

int
pcap_fileno(THIS)
    Net::Nmsg::XS::pcap THIS

char *
pcap_geterr(THIS)
    Net::Nmsg::XS::pcap THIS


MODULE = Net::Nmsg  PACKAGE = Net::Nmsg::XS::input  PREFIX = nmsg_input_

PROTOTYPES: ENABLE

void
destroy(THIS)
    Net::Nmsg::XS::input    THIS
    CODE:
    nmsg_input_close(&THIS);

Net::Nmsg::XS::input_file
nmsg_input_open_file(CLASS, fh)
    const char   *CLASS
    PerlIO *fh
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = nmsg_input_open_file(PerlIO_fileno(fh));
    if (RETVAL == NULL)
        croak("nmsg_input_open_file() failed");
    OUTPUT:
    RETVAL

Net::Nmsg::XS::input_json
nmsg_input_open_json(CLASS, fh)
    const char   *CLASS
    PerlIO *fh
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = nmsg_input_open_json(PerlIO_fileno(fh));
    if (RETVAL == NULL)
        croak("nmsg_input_open_json() failed");
    OUTPUT:
    RETVAL

Net::Nmsg::XS::input_sock
nmsg_input_open_sock(CLASS, fh)
    const char   *CLASS
    PerlIO *fh
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = nmsg_input_open_sock(PerlIO_fileno(fh));
    if (RETVAL == NULL)
        croak("nmsg_input_open_sock() failed");
    OUTPUT:
    RETVAL

Net::Nmsg::XS::input_pres

Nmsg.xs  view on Meta::CPAN

    if (mod == NULL)
        croak("unknown vendor id '%d' or message type '%d'", vid, mid);
    RETVAL = nmsg_input_open_pres(PerlIO_fileno(fh), mod);
    if (RETVAL == NULL)
        croak("nmsg_input_open_pres() failed");
    OUTPUT:
    RETVAL

Net::Nmsg::XS::input_pcap
_open_pcap(CLASS, pcap, vid, mid)
    const char                 *CLASS
    Net::Nmsg::XS::nmsg_pcap    pcap
    unsigned                    vid
    unsigned                    mid
    PREINIT:
    nmsg_msgmod_t   mod;
    CODE:
    PERL_UNUSED_VAR(CLASS);
    mod = nmsg_msgmod_lookup(vid, mid);
    if (mod == NULL)
        croak("unknown vendor id '%d' or message type '%d'", vid, mid);
    RETVAL = nmsg_input_open_pcap(pcap, mod);
    if (RETVAL == NULL)
        croak("nmsg_input_open_pcap() failed");
    OUTPUT:
    RETVAL

void
nmsg_input_set_filter_source(THIS, value)
	Net::Nmsg::XS::input    THIS
	unsigned    value

void
_set_filter_group(THIS, value)
	Net::Nmsg::XS::input    THIS
	unsigned    value
        CODE:
        nmsg_input_set_filter_group(THIS, value);

void
_set_filter_operator(THIS, value)
	Net::Nmsg::XS::input    THIS
	unsigned    value
        CODE:
        nmsg_input_set_filter_operator(THIS, value);

void
_set_filter_msgtype(THIS, vid, mid)
	Net::Nmsg::XS::input    THIS
	unsigned    vid
	unsigned    mid
    CODE:
    nmsg_input_set_filter_msgtype(THIS, vid, mid);

void
nmsg_input_set_blocking_io(THIS, flag)
    Net::Nmsg::XS::input    THIS
    bool    flag
    PREINIT:
    nmsg_res    res;
    PPCODE:
    res = nmsg_input_set_blocking_io(THIS, flag);
    if (res == nmsg_res_success)
        mXPUSHi(flag);

void
read(THIS, blocking_io=true)
    Net::Nmsg::XS::input    THIS
    bool                    blocking_io
    PREINIT:
    nmsg_message_t  m;
    nmsg_res        res;
    U32             SAVE_signals;      
    PPCODE:
    res = nmsg_res_failure;
    while (res != nmsg_res_success) {
        SAVE_signals = PL_signals;
        PL_signals |= PERL_SIGNALS_UNSAFE_FLAG;
        res = nmsg_input_read(THIS, &m);
        PL_signals = SAVE_signals;
        switch (res) {
        case (nmsg_res_success):
            mXPUSHs(_xs_wrap_msg(aTHX_ m));
            goto last_read;
        case (nmsg_res_again):
            if (blocking_io != true)
                goto last_read;
            break;
        case (nmsg_res_eof):
            goto last_read;
        default:
            croak("nmsg_input_read() failed: %s", nmsg_res_lookup(res));
        }
    }
    last_read:
        // return

nmsg_res
loop(THIS, cb, count)
    Net::Nmsg::XS::input    THIS
    int     count
    CV     *cb
    PREINIT:
    nmsg_res    res;
    U32         SAVE_signals;
    CODE:
    SAVE_signals = PL_signals;
    PL_signals |= PERL_SIGNALS_UNSAFE_FLAG;
    res = nmsg_input_loop(THIS, count, output_callback, (void *)cb);
    PL_signals = SAVE_signals;
    if (res != nmsg_res_success && res != nmsg_res_eof)
        croak("nmsg_input_loop() failed(%d): %s", res, nmsg_res_lookup(res));
    RETVAL = res;
    OUTPUT:
    RETVAL


MODULE = Net::Nmsg  PACKAGE = Net::Nmsg::XS::output PREFIX = nmsg_output_

PROTOTYPES: ENABLE

void
destroy(THIS)
    Net::Nmsg::XS::output   THIS
    CODE:
    nmsg_output_close(&THIS);

Net::Nmsg::XS::output_file
open_file(CLASS, fh, bufsz)
    const char   *CLASS
    PerlIO *fh
    size_t  bufsz
    CODE:
    PERL_UNUSED_VAR(CLASS);

Nmsg.xs  view on Meta::CPAN


PROTOTYPES: ENABLE

Net::Nmsg::XS::rate
nmsg_rate_init(CLASS, rate, freq)
    char           *CLASS
    unsigned        rate
    unsigned        freq
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = nmsg_rate_init(rate, freq);
    if (RETVAL == NULL)
        croak("rate error %d/%d", rate, freq);
    OUTPUT:
    RETVAL

void
DESTROY(THIS)
    Net::Nmsg::XS::rate THIS
    CODE:
    nmsg_rate_destroy(&THIS);


MODULE = Net::Nmsg  PACKAGE = Net::Nmsg::XS::msg PREFIX = nmsg_message_

PROTOTYPES: ENABLE

Net::Nmsg::XS::msg
nmsg_message_init(CLASS, mod)
    char           *CLASS
    nmsg_msgmod_t   mod
    CODE:
    PERL_UNUSED_VAR(CLASS);
    RETVAL = nmsg_message_init(mod);
    OUTPUT:
    RETVAL

void
DESTROY(THIS)
    Net::Nmsg::XS::msg  THIS
    CODE:
    nmsg_message_destroy(&THIS);

uint32_t
nmsg_message_get_source(THIS)
    Net::Nmsg::XS::msg  THIS

uint32_t
nmsg_message_get_operator(THIS)
    Net::Nmsg::XS::msg  THIS

uint32_t
nmsg_message_get_group(THIS)
    Net::Nmsg::XS::msg  THIS

void
get_time(THIS)
    Net::Nmsg::XS::msg  THIS
    PREINIT:
    struct timespec ts;
    PPCODE:
    nmsg_message_get_time(THIS, &ts);
    mXPUSHi(ts.tv_sec);
    mXPUSHi(ts.tv_nsec);

void
get_num_fields(THIS)
    Net::Nmsg::XS::msg  THIS
    PREINIT:
    nmsg_res  res;
    size_t    len;
    PPCODE:
    res = nmsg_message_get_num_fields(THIS, &len);
    if (res == nmsg_res_success)
        mXPUSHu(len);

void
get_num_field_values(THIS, field)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    PREINIT:
    nmsg_res  res;
    size_t    len;
    PPCODE:
    res = nmsg_message_get_num_field_values(THIS, field, &len);
    if (res == nmsg_res_success)
        mXPUSHu(len);

void
get_num_field_values_by_idx(THIS, idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            idx
    PREINIT:
    nmsg_res  res;
    size_t    len;
    PPCODE:
    res = nmsg_message_get_num_field_values_by_idx(THIS, idx, &len);
    if (res == nmsg_res_success)
        mXPUSHu(len);

void
get_field(THIS, field, v_idx = 0)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    unsigned            v_idx
    PREINIT:
    nmsg_res                res;
    size_t                  len;
    void                   *data;
    nmsg_msgmod_field_type  type;
    PPCODE:
    res = nmsg_message_get_field(THIS, field, v_idx, &data, &len);
    if (res == nmsg_res_success && data != NULL) {
        res = nmsg_message_get_field_type(THIS, field, &type);
        if (res == nmsg_res_success) {
            mXPUSHs(_xs_field_to_sv(aTHX_ data, len, type));
        }
        else
            croak("nmsg_message_get_field_type failed: %s",
                  nmsg_res_lookup(res));
    }

void
get_field_vals(THIS, field)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    PREINIT:
    nmsg_res                res;
    size_t                  len;
    void                   *data;
    nmsg_msgmod_field_type  type;
    int                     i;
    PPCODE:
    res = nmsg_message_get_field_type(THIS, field, &type);
    if (res != nmsg_res_success)
        croak("nmsg_message_get_field_type failed: %s", nmsg_res_lookup(res));
    for (i = 0; ; i++) {
        res = nmsg_message_get_field(THIS, field, i, &data, &len);
        if (res != nmsg_res_success || data == NULL)
            break;
        mXPUSHs(_xs_field_to_sv(aTHX_ data, len, type));
    }

void
get_field_by_idx(THIS, f_idx, v_idx = 0)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    unsigned            v_idx
    PREINIT:
    nmsg_res               res;
    nmsg_msgmod_field_type type;
    size_t                 len;
    void                  *data;
    PPCODE:
    res = nmsg_message_get_field_by_idx(THIS, f_idx, v_idx, &data, &len);
    if (res == nmsg_res_success) {
        res = nmsg_message_get_field_type_by_idx(THIS, f_idx, &type);
        if (res == nmsg_res_success && data != NULL) {
            mXPUSHs(_xs_field_to_sv(aTHX_ data, len, type));
        }
        else if (res != nmsg_res_success)
            croak("nmsg_message_get_field_type_by_idx failed: %s",
                  nmsg_res_lookup(res));
    }

void
get_field_vals_by_idx(THIS, f_idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    size_t                  len;
    void                   *data;
    int                     i;
    PPCODE:
    res = nmsg_message_get_field_type_by_idx(THIS, f_idx, &type);
    if (res == nmsg_res_success) {
        for (i = 0; ; i++) {
            res = nmsg_message_get_field_by_idx(THIS, f_idx, i, &data, &len);
            if (res != nmsg_res_success || data == NULL)
                break;
            mXPUSHs(_xs_field_to_sv(aTHX_ data, len, type));
        }
    }

void
get_field_flags(THIS, field)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    PREINIT:
    nmsg_res    res;
    unsigned    flags;
    PPCODE:
    res = nmsg_message_get_field_flags(THIS, field, &flags);
    if (res == nmsg_res_success)
        mXPUSHu(flags);

void
get_field_flags_by_idx(THIS, f_idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    PREINIT:
    nmsg_res    res;
    unsigned    flags;
    PPCODE:
    res = nmsg_message_get_field_flags_by_idx(THIS, f_idx, &flags);
    if (res == nmsg_res_success)
        mXPUSHu(flags);

void
get_field_idx(THIS, name)
    Net::Nmsg::XS::msg  THIS
    const char         *name
    PREINIT:
    nmsg_res    res;
    unsigned    idx;
    PPCODE:
    res = nmsg_message_get_field_idx(THIS, name, &idx);
    if (res == nmsg_res_success)
        mXPUSHu(idx);

void
get_field_name(THIS, idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            idx
    PREINIT:
    nmsg_res    res;
    const char *name;
    PPCODE:
    res = nmsg_message_get_field_name(THIS, idx, &name);
    if (res == nmsg_res_success)
        mXPUSHs(newSVpv(name, 0));

void
get_field_type(THIS, name)
    Net::Nmsg::XS::msg  THIS
    const char         *name;
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    PPCODE:
    res = nmsg_message_get_field_type(THIS, name, &type);
    if (res == nmsg_res_success)
        mXPUSHi(type);

void
get_field_type_by_idx(THIS, idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            idx
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    PPCODE:
    res = nmsg_message_get_field_type_by_idx(THIS, idx, &type);
    if (res == nmsg_res_success)
        mXPUSHi(type);

void
enum_name_to_value(THIS, field, name)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    const char         *name
    PREINIT:
    nmsg_res    res;
    unsigned    value;
    PPCODE:
    res = nmsg_message_enum_name_to_value(THIS, field, name, &value);
    if (res == nmsg_res_success)
        mXPUSHu(value);

void
enum_name_to_value_by_idx(THIS, f_idx, name)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    const char         *name
    PREINIT:
    nmsg_res    res;
    unsigned    value;
    PPCODE:
    res = nmsg_message_enum_name_to_value_by_idx(THIS, f_idx, name, &value);
    if (res == nmsg_res_success)
        mXPUSHu(value);

void
enum_value_to_name(THIS, field, value)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    unsigned            value
    PREINIT:
    nmsg_res    res;
    const char *name;
    PPCODE:
    res = nmsg_message_enum_value_to_name(THIS, field, value, &name);
    if (res == nmsg_res_success)
        mXPUSHs(newSVpv(name, 0));

void
enum_value_to_name_by_idx(THIS, f_idx, value)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    unsigned            value
    PREINIT:
    nmsg_res    res;
    const char *name;
    PPCODE:
    res = nmsg_message_enum_value_to_name_by_idx(THIS, f_idx, value, &name);
    if (res == nmsg_res_success)
        mXPUSHs(newSVpv(name, 0));

void
set_field(THIS, field, v_idx, sv)
    Net::Nmsg::XS::msg  THIS
    const char         *field
    unsigned            v_idx
    SV                 *sv
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    nmsg_field_val_u        data;
    uint8_t                *bp;
    size_t                  len;
    CODE:
    res = nmsg_message_get_field_type(THIS, field, &type);
    if (res == nmsg_res_success) {
        bp = _xs_sv_to_field(aTHX_ sv, type, &data, &len);
        res = nmsg_message_set_field(THIS, field, v_idx, bp, len);
        if (res != nmsg_res_success)
            croak("nmsg_message_set_field failed: %s", nmsg_res_lookup(res));
    }
    else
        croak("nmsg_message_get_field_type failed: %s", nmsg_res_lookup(res));

void
set_field_by_idx(THIS, f_idx, v_idx, sv)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    unsigned            v_idx
    SV                 *sv;
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    nmsg_field_val_u        data;
    uint8_t                *bp;
    size_t                  len;
    CODE:
    res = nmsg_message_get_field_type_by_idx(THIS, f_idx, &type);
    if (res == nmsg_res_success) {
        bp = _xs_sv_to_field(aTHX_ sv, type, &data, &len);
        res = nmsg_message_set_field_by_idx(THIS, f_idx, v_idx, bp, len);
        if (res != nmsg_res_success)
            croak("nmsg_message_set_field_by_idx failed: %s",
                  nmsg_res_lookup(res));
    }
    else
        croak("nmsg_message_get_field_type_by_idx failed: %s",
              nmsg_res_lookup(res));

void
nmsg_message_set_source(THIS, source)
    Net::Nmsg::XS::msg  THIS
    uint32_t            source

void
nmsg_message_set_operator(THIS, operator)
    Net::Nmsg::XS::msg  THIS
    uint32_t            operator

void
nmsg_message_set_group(THIS, group)
    Net::Nmsg::XS::msg  THIS
    uint32_t            group

void
set_time(THIS, time_sec, time_nsec)
    Net::Nmsg::XS::msg  THIS
    long                time_sec
    int                 time_nsec
    PREINIT:
    struct timespec ts;
    PPCODE:
    ts.tv_sec = time_sec;
    ts.tv_nsec = time_nsec;
    nmsg_message_set_time(THIS, &ts);

void
message_to_pres(THIS, endline)
    Net::Nmsg::XS::msg    THIS
    const char           *endline
    PREINIT:
    nmsg_res  res;
    char     *pres;
    PPCODE:
    pthread_mutex_lock(&presentation_lock);
    res = nmsg_message_to_pres(THIS, &pres, endline);
    if (res != nmsg_res_success)
        goto out;
    mXPUSHs(newSVpv(pres, 0));
    Safefree(pres);
    out:
    pthread_mutex_unlock(&presentation_lock);
    if (res != nmsg_res_success)
        croak("nmsg_message_to_pres failed: %s", nmsg_res_lookup(res));

void
get_field_type_descr_by_idx(THIS, f_idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    PPCODE:
    res = nmsg_message_get_field_type_by_idx(THIS, f_idx, &type);
    if (res == nmsg_res_success) {
        mXPUSHs(newSViv(type));

        switch (type) {

        case nmsg_msgmod_ft_enum:
            mXPUSHs(newSVpvs("enum"));
            break;
        case nmsg_msgmod_ft_int16:
            mXPUSHs(newSVpvs("int16"));
            break;
        case nmsg_msgmod_ft_int32:
            mXPUSHs(newSVpvs("int32"));
            break;
        case nmsg_msgmod_ft_uint16:
            mXPUSHs(newSVpvs("uint16"));
            break;
        case nmsg_msgmod_ft_uint32:
            mXPUSHs(newSVpvs("uint32"));
            break;
        case nmsg_msgmod_ft_uint64:
            mXPUSHs(newSVpvs("uint64"));
            break;
        case nmsg_msgmod_ft_int64:
            mXPUSHs(newSVpvs("int64"));
            break;
        case nmsg_msgmod_ft_string:
            mXPUSHs(newSVpvs("string"));
            break;
        case nmsg_msgmod_ft_mlstring:
            mXPUSHs(newSVpvs("mlstring"));
            break;
        case nmsg_msgmod_ft_bytes:
            mXPUSHs(newSVpvs("bytes"));
            break;
        case nmsg_msgmod_ft_ip:
            mXPUSHs(newSVpvs("ip"));
            break;
        default:
            mXPUSHs(newSVpvs("unknown"));
        }
    }

void
get_field_flag_descr_by_idx(THIS, f_idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    PREINIT:
    nmsg_res    res;
    unsigned    flags;
    PPCODE:
    res = nmsg_message_get_field_flags_by_idx(THIS, f_idx, &flags);
    if (res == nmsg_res_success) {
        if (flags & NMSG_FF_REPEATED)
            mXPUSHs(newSViv(NMSG_FF_REPEATED));
            mXPUSHs(newSVpvs("repeated"));
        if (flags & NMSG_FF_REQUIRED)
            mXPUSHs(newSViv(NMSG_FF_REQUIRED));
            mXPUSHs(newSVpvs("required"));
        if (flags & NMSG_FF_HIDDEN)
            mXPUSHs(newSViv(NMSG_FF_HIDDEN));
            mXPUSHs(newSVpvs("hidden"));
        if (flags & NMSG_FF_NOPRINT)
            mXPUSHs(newSViv(NMSG_FF_NOPRINT));
            mXPUSHs(newSVpvs("noprint"));
    }

void
get_field_enum_descr_by_idx(THIS, f_idx)
    Net::Nmsg::XS::msg  THIS
    unsigned            f_idx
    PREINIT:
    nmsg_res                res;
    nmsg_msgmod_field_type  type;
    unsigned                v;
    const char             *name;
    PPCODE:
    res = nmsg_message_get_field_type_by_idx(THIS, f_idx, &type);
    if (res == nmsg_res_success && type == nmsg_msgmod_ft_enum) {
        for (v = 0;  ; v++) {
            res = nmsg_message_enum_value_to_name_by_idx(
                    THIS, f_idx, v, &name);
            if (res != nmsg_res_success)
                break;
            mXPUSHu(v);
            mXPUSHs(newSVpv(name, 0));
        }
    }



( run in 1.477 second using v1.01-cache-2.11-cpan-71847e10f99 )