int reexport (ipfixt_node_t *t, ipfix_datarecord_t *d) { ipfix_template_t* outtemplate; if (hi_get_str(templates, t->ident, (void**)&outtemplate )) { if ( ipfix_new_data_template( ipfixh, &outtemplate, t->ipfixt->nfields ) <0 ) { fprintf( stderr, "ipfix_new_template() failed in reexport: %s\n", strerror(errno) ); exit(1); } int i; fprintf( stdout, "reexporting template %s as id %i.\n", t->ident, outtemplate->tid ); for (i=0; i < t->ipfixt->nfields; i++) { if (ipfix_add_field( ipfixh, outtemplate, t->ipfixt->fields[i].elem->ft->eno, t->ipfixt->fields[i].elem->ft->ftype, t->ipfixt->fields[i].flength ) <0 ) { fprintf( stderr, "ipfix_add_field() failed in reexport: %s - eno = %i, type = %i, length = %i\n", strerror(errno), t->ipfixt->fields[i].elem->ft->eno, t->ipfixt->fields[i].elem->ft->ftype, t->ipfixt->fields[i].flength); exit(1); } //fprintf( stdout, " added field %i:%i(%i||%i,%i)\n", outtemplate->fields[i].elem->ft->eno, outtemplate->fields[i].elem->ft->ftype, outtemplate->fields[i].elem->ft->length, t->ipfixt->fields[i].flength, t->ipfixt->fields[i].elem->ft->length ); } hi_insert_str(templates, t->ident, outtemplate); } if (verbose_level>1) { int i; char tmps[256]; fprintf( stdout, "data record, tid = %i.\n", outtemplate->tid); for (i=0; i < outtemplate->nfields; i++) { t->ipfixt->fields[i].elem->snprint(tmps, 255, d->addrs[i], d->lens[i]); fprintf( stdout, "%i: %s\n", i, tmps); } } ipfix_export_array(ipfixh, outtemplate, outtemplate->nfields, d->addrs, d->lens); /* TODO FIXME do a flush only every now and then instead of each time */ ipfix_export_flush(ipfixh); return 0; }
/* name : export_ipflows * remarks : */ static int export_ipflows( probe_t *probe, time_t now, int flag ) { ipflow_t *flows = probe->ipflows; ipflowinfo_t *n, *node; int a=0, d=0, e=0; uint64_t msec_start; uint64_t msec_end; if ( flows->biflows ) return export_biflows( probe, now, flag ); node = flows?flows->flows:NULL; while( node ) { msec_start = ((uint64_t)node->tstart.tv_sec*1000) +((uint64_t)node->tstart.tv_usec/1000); msec_end = ((uint64_t)node->tlast.tv_sec*1000) +((uint64_t)node->tlast.tv_usec/1000); a++; /* check if the flow is idle */ if ( flag || (g_par.ipflow_timeout && ((now - node->tlast.tv_sec) > g_par.ipflow_timeout)) || (g_par.ipflow_lifetime && ((node->tlast.tv_sec-node->tstart.tv_sec) > g_par.ipflow_lifetime)) ) { if ( mlog_get_vlevel() > 2 ) { if ( g_par.ipflow_timeout && ((now - node->tlast.tv_sec) > g_par.ipflow_timeout) ) { mlogf( 3, "[%s] %ds idle timeout expired! " "id=%d, start=%ld, duration=%ld, idle=%ld\n", g_par.progname, g_par.ipflow_timeout, node->flowid, node->tstart.tv_sec, node->tlast.tv_sec-node->tstart.tv_sec, now - node->tlast.tv_sec ); } else if ( g_par.ipflow_lifetime && ((node->tlast.tv_sec-node->tstart.tv_sec) > g_par.ipflow_lifetime) ) { mlogf( 3, "[%s] %ds flow lifetime expired! " "id=%d, start=%ld, duration=%ld, idle=%ld\n", g_par.progname, g_par.ipflow_lifetime, node->flowid, node->tstart.tv_sec, node->tlast.tv_sec-node->tstart.tv_sec, now - node->tlast.tv_sec ); } } /* flow has expired * -> export flow end * -> delete node */ (void) ipfix_export( probe->ipfix, (node->elems.version==6)? probe->templ6:probe->templ, &msec_start, &msec_end, node->saddr, node->daddr, &node->elems.sport, &node->elems.dport, &node->elems.protocol, &node->elems.tos, &node->packets, &node->bytes ); n = node->next; (void) flow_drop( flows, node ); node = n; e++; d++; continue; } if ( (g_par.ipflow_timeout<1) && (node->packets) ) { /* flow is still active * -> export counters */ msec_end = 0; (void) ipfix_export( probe->ipfix, (node->elems.version==6)? probe->templ6:probe->templ, &msec_start, &msec_end, node->saddr, node->daddr, &node->elems.sport, &node->elems.dport, &node->elems.protocol, &node->elems.tos, &node->packets, &node->bytes ); node->packets =0; node->bytes =0; e++; } node = node->next; } if ( ipfix_export_flush( probe->ipfix ) <0 ) { mlogf( 3, "[%s] ipfix_export() failed: %s\n", __func__, strerror(errno) ); } else { mlogf( 2, "[%s] %d active flows, %d exported, %d dropped.\n", g_par.progname, a, e, d ); } probe->npkts = 0; probe->nbytes = 0; return 0; }