int main(int argc, char *argv[]) { int ret; int i; ipfix_exporter *my_exporter; #ifdef TEST_INIT_LOOP for (i = 0; i < TEST_ITERATIONS; i++) { int j; #endif ret = ipfix_init_exporter(MY_SOURCE_ID, &my_exporter); if (ret != 0) { fprintf(stderr, "ipfix_init_exporter failed!\n"); exit(-1); } ret=ipfix_add_collector(my_exporter, "127.0.0.1", 4711, UDP, NULL, ""); if (ret != 0) { fprintf(stderr, "ipfix_add_collector failed!\n"); exit(-1); } #ifdef TEST_TEMPLATE_LOOP for (j = 0; j < TEST_ITERATIONS; j++) { #endif uint16_t my_template_id=707; ret=0; ret|=ipfix_start_template_set(my_exporter, my_template_id, 1); ret|=ipfix_put_template_field(my_exporter, my_template_id, 2, 8, 0); ret|=ipfix_end_template_set(my_exporter, my_template_id); if (ret != 0) { fprintf(stderr, "ipfix_add_collector failed!\n"); exit(-1); } #ifdef TEST_TEMPLATE_LOOP } #endif ret=ipfix_send(my_exporter); if (ret != 0) { fprintf(stderr, "ipfix_send failed!\n"); exit(-1); } ret=ipfix_remove_collector(my_exporter, "127.0.0.1", 4711); if (ret != 0) { fprintf(stderr, "ipfix_remove_collector failed!\n"); exit(-1); } ipfix_deinit_exporter(my_exporter); #ifdef TEST_INIT_LOOP } #endif printf("bravo\n"); exit(0); }
/** * Add another IPFIX collector to export the stream to * the lowlevel stuff in handled by underlying ipfixlolib */ int IpfixFileWriter::addCollector(uint16_t observationDomainId, std::string filenamePrefix, std::string destinationPath, uint32_t maximumFilesize) { ipfix_exporter *ex = (ipfix_exporter *)ipfixExporter; if(destinationPath.at(destinationPath.length()-1) != '/') destinationPath += "/"; std::string my_filename = destinationPath + filenamePrefix; if (maximumFilesize <= 0) maximumFilesize = DEFAULTFILESIZE; if(maximumFilesize < 64) msg(LOG_ERR, "maximum filsize < maximum message length - this could lead to serious problems"); if(ipfix_add_collector(ex, my_filename.c_str(), maximumFilesize, DATAFILE, NULL, "") != 0) { msg(LOG_CRIT, "IpfixFileWriter: ipfix_add_collector of %s failed", my_filename.c_str()); return -1; } msg(LOG_NOTICE, "IpfixFileWriter: adding %s to exporter", my_filename.c_str()); msg(LOG_NOTICE, "IpfixFileWriter initialized with the following parameters"); msg(LOG_NOTICE, " - Basename = %s", my_filename.c_str()); msg(LOG_NOTICE, " - maximumFilesize = %d KiB" , maximumFilesize); return 0; }
/** * Add another IPFIX collector to export the stream to * the lowlevel stuff in handled by underlying ipfixlolib * @param packetDirectoryName path to create raw packet files in */ int IpfixRawdirWriter::addCollector(std::string packetDirectoryName) { ipfix_exporter *ex = (ipfix_exporter *)ipfixExporter; if(ipfix_add_collector(ex, packetDirectoryName.c_str(), 0, RAWDIR) != 0) { msg(MSG_FATAL, "IpfixRawdirWriter: ipfix_add_collector of %s failed", packetDirectoryName.c_str()); return -1; } msg(MSG_INFO, "IpfixRawdirWriter: adding %s to exporter", packetDirectoryName.c_str()); return 0; }
/** * Takes all collectors from config file <conf> * and adds them to the exporter <exporter> * by calling the appropriate ipfixlolib function. */ void init_collectors(config_file_descriptor* conf, ipfix_exporter* exporter){ list_node* cur; for(cur = conf->collectors->first;cur!=NULL;cur=cur->next){ collector_descriptor* cur_descriptor = (collector_descriptor*)cur->data; void *aux = NULL; switch (cur_descriptor->transport_protocol) { case UDP: { ipfix_aux_config_udp aux_config; /* Auxiliary parameter for UDP */ aux_config.mtu = 1500; /* MTU */ aux = &aux_config; break; } #ifdef SUPPORT_DTLS case DTLS_OVER_UDP: { ipfix_aux_config_dtls_over_udp aux_config; aux_config.udp.mtu = 1500; aux_config.dtls.peer_fqdn = cur_descriptor->fqdn; aux_config.max_connection_lifetime = 360; aux = &aux_config; break; } case DTLS_OVER_SCTP: { ipfix_aux_config_dtls_over_sctp aux_config; aux_config.dtls.peer_fqdn = cur_descriptor->fqdn; aux = &aux_config; break; } #endif default: break; } int ret = ipfix_add_collector(exporter, cur_descriptor->ip, cur_descriptor->port, cur_descriptor->transport_protocol, aux); msg(MSG_INFO, "Added collector %s:%d (return: %d)", cur_descriptor->ip,cur_descriptor->port, ret); } }
int main(int argc, char **argv) { int ret =0; char *collector_ip; int collector_port; if (argc != 3) { fprintf(stderr, "Usage: %s <server_ip_address> <server_port>\nWill use UDP.\n", argv[0]); exit(1); } collector_ip=argv[1]; collector_port=atoi(argv[2]); /* Initialize an exporter sourceID: the source ID the exported stream gets exporter: an ipfix_exporter * to be initialized */ ipfix_exporter *my_exporter; ret=ipfix_init_exporter(MY_SOURCE_ID, &my_exporter); if (ret != 0) { fprintf(stderr, "ipfix_init_exporter failed!\n"); exit(-1); } /* Add a collector (the one who gets the data) to the exporting process exporter: a previous init()ed exporter coll_ip4_addr : the collector's ipv4 address (in dot notation, e.g. "123.123.123.123") coll_port: port number of the collector proto: transport protocol to use, TCP/UDP/SCTP You can add up to IPFIX_MAX_COLLECTORS collectors. */ ret = ipfix_add_collector(my_exporter, collector_ip, collector_port, UDP); printf("ipfix_add_collector returned %i\n", ret); /* You have to define a template set with the ID 12345 before the exporting process starts The template shall contain the following fields: # | IPFIX name of field | IPFIX field ID | length of associated datatype ------------------------------------------------------------------------------- 1 | sourceAddressV4 | 8 | 4 2 | destinationAddressV4 | 12 | 4 3 | transportSourcePort | 7 | 2 4 | transportDestinationPort | 11 | 2 5 | deltaOctetCount | 1 | 8 6 | deltaPacketCount | 2 | 8 FIXME - ??? As none of these fields is vendor specific, the length of the template fields is 6*4 bytes. FIXME */ uint16_t my_template_id = 12345; uint16_t my_n_template_id = htons(my_template_id); /* Now start the adding of fields. exporter: the exporter template_id: an ID for this template field_count: # of entries/fields */ ret=ipfix_start_template_set(my_exporter, my_template_id, 6); /* Add fields to the exporter. exporter: the exporter template_id: the template ID chosen beforehand type: the IPFIX field ID for this entry length: sizeof() datatype enterprise: FIXME ??? */ ret=ipfix_put_template_field(my_exporter, my_template_id, 8, 4, 0); ret=ipfix_put_template_field(my_exporter, my_template_id, 12, 4, 0); ret=ipfix_put_template_field(my_exporter, my_template_id, 7, 2, 0); ret=ipfix_put_template_field(my_exporter, my_template_id, 11, 2, 0); ret=ipfix_put_template_field(my_exporter, my_template_id, 1, 8, 0); ret=ipfix_put_template_field(my_exporter, my_template_id, 2, 8, 0); /* Finalize the template */ ret=ipfix_end_template_set(my_exporter, my_template_id); /* Main exporting loop What you basically do is 1) get data 2) start a data set 3) add the fields 4) send data set */ /* let's specify the number of data packets */ int exporting = 2; while(exporting) { int i; meter_data my_meter_data; meter_data my_meter_data2; /* you may loop and add one or more data-sets */ for (i = 0; i < 2; i++) { /* start a data-set */ ret=ipfix_start_data_set(my_exporter, &my_n_template_id); if (ret != 0 ) { // do not try use ipfix_put_data_field or ipfix_put_end_field, // if ret=ipfix_start_data_set has failed! fprintf(stderr, "ipfix_start_data_set failed!\n"); } else { printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", (*(*my_exporter).data_sendbuffer).current); /* get data - must be in Network Byte Order for interoperability */ meter_process_gimme_data(&my_meter_data); /* now fill the pre-defined data fields NOTE: supplied data is NOT copied and has to stay valid until the ipfix_send() below! NOTE: It's the user's responsability to ensure that the added data is conform to the indicated template. */ ipfix_put_data_field(my_exporter, &(my_meter_data.ip_src_addr), 4); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data.ip_dst_addr), 4); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data.src_port), 2); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data.dst_port), 2); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data.byte_count), 8); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data.packet_count), 8); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); /* more than one record can be added to a data set, so let's add another one */ /* NOTE: we need another my_meter_data2 here, because the data of my_meter_data has to remain valid till ipfix_send() is called */ meter_process_gimme_data2(&my_meter_data2); ipfix_put_data_field(my_exporter, &(my_meter_data2.ip_src_addr), 4); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data2.ip_dst_addr), 4); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data2.src_port), 2); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data2.dst_port), 2); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data2.byte_count), 8); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); ipfix_put_data_field(my_exporter, &(my_meter_data2.packet_count), 8); printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); /* finish the data-set remark: the main task of ipfix_end_data_set is to calculate the length of the data set */ ret=ipfix_end_data_set(my_exporter); // printf("main: (*(*my_exporter).data_sendbuffer).current %i\n", my_exporter->data_sendbuffer->current); if (ret != 0) fprintf(stderr, "ipfix_end_data_set failed!\n"); } } /* send the data-set(s) template sending is handled entirely by the library, too. NOTE: ALL DATA added via ipfix_put_data_field has to stay valid until ipfix_send() returns. */ ret=ipfix_send(my_exporter); if (ret != 0) fprintf(stderr, "ipfix_send failed!\n"); exporting--; } /* if you no longer need the exporter: free resources */ ret=ipfix_remove_collector(my_exporter, collector_ip, collector_port); ipfix_deinit_exporter(my_exporter); printf("bravo\n"); exit(0); }
int main (int argc, char *argv[]) { char opt; /* short options: character */ char optstr[] = "hp:c:P:r:stuvlf:"; int port; /* port number */ int cport = 4740; /* target collector port number */ int protocol = IPFIX_PROTO_TCP; int do_log = 0; /* flag to stre whether logging to stdout was enabled */ /** set default options */ port = 4739; datadir = NULL; snprintf( progname, sizeof(progname), "%s", basename( argv[0]) ); /* --- command line parsing --- */ int cisset = 0; while( ( opt = getopt( argc, argv, optstr ) ) != EOF ) { switch ( opt ) { case 'o': if ((sourceid=atoi(optarg)) <0) { fprintf( stderr, "Invalid -o argument!\n" ); exit(1); } break; case 'p': if ((port=atoi(optarg)) <0) { fprintf( stderr, "Invalid -p argument!\n" ); exit(1); } break; case 'v': verbose_level ++; break; case 'l': do_log = 1; break; case 'P': if ((cport=atoi(optarg)) <0) { fprintf( stderr, "Invalid -P argument!\n" ); exit(1); } break; case 'r': if ((degrade=atoi(optarg)) <0) { fprintf( stderr, "Invalid -r argument!\n" ); exit(1); } break; case 'c': if (chost) free(chost); /* executed in case of multiple "-c <collectorhost>" */ chost = strdup(optarg); cisset = 1; break; case 'f': if (datadir) free(datadir); /* executed in case of multiple "-f <datadir>" */ datadir = strdup(optarg); break; case 's': protocol = IPFIX_PROTO_SCTP; break; case 't': protocol = IPFIX_PROTO_TCP; break; case 'u': protocol = IPFIX_PROTO_UDP; break; case 'h': default: usage(progname); exit(1); } } if (!chost && !datadir && !do_log) { fprintf( stderr, "You must specify either an IPFIX target collector host or a datadir or enable log to stdout. Type option '-h' for help.\n"); exit(1); } /** init hashtable structures */ hi_init_uint32_t(&indegree, 1000); hi_init_uint32_t(&outdegree, 1000); hi_init_uint32_t(&flows, 1000); hi_init_str (&templates, 100); /** init logging */ mlog_set_vlevel( verbose_level ); /** init ipfix lib */ if ( ipfix_init() <0 ) { fprintf( stderr, "ipfix_init() failed: %s\n", strerror(errno) ); exit(1); } if ( ipfix_add_vendor_information_elements( ipfix_ft_fokus ) <0 ) { fprintf( stderr, "ipfix_add_ie() failed: %s\n", strerror(errno) ); exit(1); } /** init ipfix import/export */ if ( ipfix_open( &ipfixh, sourceid, IPFIX_VERSION ) <0 ) { fprintf( stderr, "ipfix_open() failed: %s\n", strerror(errno) ); exit(1); } /** signal handler */ signal( SIGKILL, exit_func ); signal( SIGTERM, exit_func ); signal( SIGINT, exit_func ); /** initialize callback methods */ /** activate stdout log output * if "-l" was specified on cmd line */ if (do_log) { (void) ipfix_col_start_msglog( stdout ); } /** activate file export * if "-f <datadir>" was specified on cmd line */ if (datadir) { (void) ipfix_col_init_fileexport( datadir ); } if (chost) { if ( ipfix_add_collector( ipfixh, chost, cport, protocol ) <0 ) { fprintf( stderr, "ipfix_add_collector(%s,%d) failed: %s\n", chost, cport, strerror(errno)); exit(1); } /** activate callback for re-export */ if ( (g_colinfo=calloc( 1, sizeof(ipfix_col_info_t))) ==NULL) { fprintf( stderr, "a calloc failed while initializing callback methods.\n" ); return -1; } g_colinfo->export_newsource = export_newsource_cb; g_colinfo->export_newmsg = export_newmsg_cb; g_colinfo->export_trecord = export_trecord_cb; g_colinfo->export_drecord = export_drecord_cb; g_colinfo->export_cleanup = export_cleanup_cb; g_colinfo->data = NULL; if ( ipfix_col_register_export( g_colinfo ) <0 ) { fprintf( stderr, "ipfix_col_register_export() failed: %s\n", strerror(errno) ); exit(1); } } /** open ipfix collector port(s) */ if ( ipfix_col_listen( &ntcp_s, &tcp_s, IPFIX_PROTO_TCP, port, AF_INET, 10 ) <0 ) { fprintf( stderr, "[%s] ipfix_listen(tcp) failed.\n", progname ); return -1; } /** event loop */ (void) mpoll_loop( -1 ); exit(1); }
/* name : export_init */ static int export_init( probe_t *probe ) { ipfix_t *ifh =NULL; ipfix_template_t *t4, *t6; char *p, *host; int port; if ( (ipfix_init() <0) || (ipfix_add_vendor_information_elements( ipfix_ft_fokus ) <0 ) ) { mlogf( 0, "[%s] cannot init ipfix module\n", __func__ ); return -1; } if ( ipfix_open( &ifh, g_par.odid, IPFIX_VERSION ) <0 ) { mlogf( 0, "[%s] ipfix_open() failed: %s\n", __func__, strerror(errno) ); ipfix_cleanup(); return -1; } for ( host=g_par.collector, port=g_par.port;; ) { /* check if hostname has :portno suffix */ if ( ((p=strrchr( host, ':' )) !=NULL) && (p==strchr( host, ':' )) && ((port=atoi(p+1))>0) ) { *p = '\0'; } if ( !port ) port = IPFIX_PORTNO; #ifdef SSLSUPPORT if ( g_par.ssl ) { ipfix_ssl_opts_t opts; opts.cafile = g_par.cafile; opts.cadir = g_par.cadir; opts.keyfile = g_par.keyfile; opts.certfile= g_par.certfile; if ( ipfix_add_collector_ssl( ifh, host, port, g_par.protocol, &opts ) <0 ) { mlogf( 0, "[%s] ipfix_add_collector_ssl() failed: %s\n", __func__, strerror(errno) ); goto err; } break; } #endif if ( ipfix_add_collector( ifh, host, port, g_par.protocol ) <0 ) { mlogf( 0, "[%s] ipfix_add_collector() failed: %s\n", __func__, strerror(errno) ); goto err; } break; } if ( g_par.biflows ) { if ( ipfix_make_template( ifh, &t4, ipbiflow4_fields, ipbiflow4_nfields ) <0) { goto err; } if ( ipfix_make_template( ifh, &t6, ipbiflow6_fields, ipbiflow6_nfields ) <0) { ipfix_delete_template( ifh, t4 ); goto err; } } else { if ( ipfix_make_template( ifh, &t4, ipflow4_fields, ipflow4_nfields ) <0) { goto err; } if ( ipfix_make_template( ifh, &t6, ipflow6_fields, ipflow6_nfields ) <0) { ipfix_delete_template( ifh, t4 ); goto err; } } probe->ipfix = ifh; probe->templ = t4; probe->templ6 = t6; return 0; err: ipfix_close( ifh ); ipfix_cleanup(); return -1; }