3838 *
3939 */
4040
41+ #define _GNU_SOURCE
4142#include <ipfixcol2.h>
4243#include <libtrap/trap.h>
44+ #include <stdio.h>
45+ #include <pthread.h>
4346#include <unirec/unirec.h>
4447
4548#include "unirecplugin.h"
4649
50+ static pthread_mutex_t urp_mutex = PTHREAD_MUTEX_INITIALIZER ;
51+
52+ /**
53+ * UniRec plugin reference counter
54+ *
55+ * This counter represents number of created instances (threads) of this plugin.
56+ * It must be incremented in init() and decremented in destroy().
57+ */
58+ static uint8_t urp_refcount = 0 ;
59+
60+ /* TODO move into unirec.h !!! */
61+ int ur_get_field_type_from_str (const char * type );
62+
4763/** Plugin description */
4864IPX_API struct ipx_plugin_info ipx_plugin_info = {
4965 // Plugin type
@@ -60,6 +76,24 @@ IPX_API struct ipx_plugin_info ipx_plugin_info = {
6076 .ipx_min = "2.0.0"
6177};
6278
79+ static char *
80+ clean_define_urtempl (const char * ut , void * pointer_to_ipx2urmap )
81+ {
82+ char * res = strdup (ut );
83+ size_t i , t ;
84+ size_t len = strlen (ut );
85+ for (i = 0 , t = 0 ; i < len ; i ++ , t ++ ) {
86+ if (res [i ] == '?' ) {
87+ i ++ ;
88+ }
89+ if (i > t ) {
90+ res [t ] = res [i ];
91+ }
92+ }
93+ res [t ] = 0 ;
94+ return res ;
95+ }
96+
6397// Storage plugin initialization function.
6498int
6599ipx_plugin_init (ipx_ctx_t * ctx , const char * params ) {
@@ -72,9 +106,27 @@ ipx_plugin_init(ipx_ctx_t *ctx, const char *params) {
72106 //}
73107 /* TODO delete: */
74108 struct conf_params * parsed_params = calloc (1 , sizeof (* parsed_params ));
109+ parsed_params -> trap_ifc_type = 'u' ;
110+ parsed_params -> trap_ifc_socket = strdup ("ipfix-ur" );
111+ parsed_params -> unirec_format = strdup ("SRC_IP,DST_IP,?SRC_PORT,?DST_PORT,?TCP_FLAGS" );
75112
113+ if (pthread_mutex_lock (& urp_mutex ) == -1 ) {
114+ return IPX_ERR_DENIED ;
115+ }
116+
117+ /* TODO replace with unirec-elements.txt */
118+ ur_define_field ("SRC_IP" , ur_get_field_type_from_str ("ipaddr" ));
119+ ur_define_field ("DST_IP" , ur_get_field_type_from_str ("ipaddr" ));
120+ ur_define_field ("SRC_PORT" , ur_get_field_type_from_str ("uint16" ));
121+ ur_define_field ("DST_PORT" , ur_get_field_type_from_str ("uint16" ));
122+ ur_define_field ("PROTOCOL" , ur_get_field_type_from_str ("uint8" ));
123+ ur_define_field ("TCP_FLAGS" , ur_get_field_type_from_str ("uint8" ));
124+
125+ if (pthread_mutex_unlock (& urp_mutex ) == -1 ) {
126+ return IPX_ERR_DENIED ;
127+ }
76128
77- //// Create main plugin structure
129+ // Create main plugin structure
78130 struct conf_unirec * conf = calloc (1 , sizeof (* conf ));
79131 if (!conf ) {
80132 IPX_CTX_ERROR (ctx , "Unable to allocate memory (%s:%d)" , __FILE__ , __LINE__ );
@@ -86,9 +138,38 @@ ipx_plugin_init(ipx_ctx_t *ctx, const char *params) {
86138
87139 /* Load IPFIX2UniRec mapping file */
88140
89- /* Allocate UniRec template */
141+ /* Clean UniRec template from '?' (optional fields) */
142+ char * cleaned_urtemplate = clean_define_urtempl (parsed_params -> unirec_format , NULL );
143+ IPX_CTX_INFO (ctx , "Cleaned UniRec template: '%s'." , cleaned_urtemplate );
90144
91145 /* Initialize TRAP Ctx */
146+ char * ifc_spec ;
147+ int ret = asprintf (& ifc_spec , "%c:%s" , parsed_params -> trap_ifc_type , parsed_params -> trap_ifc_socket );
148+ if (ret == -1 ) {
149+ IPX_CTX_ERROR (ctx , "Unable to create IFC spec (%s:%d)" , __FILE__ , __LINE__ );
150+ configuration_free (parsed_params );
151+ return IPX_ERR_DENIED ;
152+ }
153+ IPX_CTX_INFO (ctx , "Initialization of TRAP with IFCSPEC: '%s'." , ifc_spec );
154+ conf -> tctx = trap_ctx_init3 ("IPFIXcol2-UniRec" , "UniRec output plugin for IPFIXcol2." ,
155+ 0 , 1 , ifc_spec , NULL /* replace with uniq name of service IFC based on */ );
156+ free (ifc_spec );
157+ if (conf -> tctx == NULL ) {
158+ IPX_CTX_ERROR (ctx , "Failed to initialize TRAP (%s:%d)" , __FILE__ , __LINE__ );
159+ configuration_free (parsed_params );
160+ return IPX_ERR_DENIED ;
161+ }
162+
163+ /* Allocate UniRec template */
164+ IPX_CTX_INFO (ctx , "Initialization of UniRec template." , ifc_spec );
165+ char * errstring = NULL ;
166+ conf -> urtmpl = ur_ctx_create_output_template (conf -> tctx , 0 , cleaned_urtemplate , & errstring );
167+ if (conf -> urtmpl == NULL ) {
168+ IPX_CTX_ERROR (ctx , "Failed to create UniRec template '%s' (%s:%d)" , cleaned_urtemplate , __FILE__ , __LINE__ );
169+ ipx_plugin_destroy (ctx , conf );
170+ return IPX_ERR_DENIED ;
171+ }
172+ free (cleaned_urtemplate );
92173
93174
94175 //// Init a LNF record for conversion from IPFIX
@@ -124,8 +205,20 @@ ipx_plugin_init(ipx_ctx_t *ctx, const char *params) {
124205 // free(conf);
125206 //}
126207
208+
209+ if (pthread_mutex_lock (& urp_mutex ) == -1 ) {
210+ return IPX_ERR_DENIED ;
211+ }
212+ /* increase number of UniRec plugin references */
213+ urp_refcount ++ ;
214+ if (pthread_mutex_unlock (& urp_mutex ) == -1 ) {
215+ return IPX_ERR_DENIED ;
216+ }
217+
127218 // Save the configuration
128- //ipx_ctx_private_set(ctx, conf);
219+ ipx_ctx_private_set (ctx , conf );
220+
221+ IPX_CTX_INFO (ctx , "Plugin is ready." );
129222 return IPX_OK ;
130223}
131224
@@ -195,6 +288,9 @@ ipx_plugin_destroy(ipx_ctx_t *ctx, void *cfg)
195288{
196289 (void ) ctx ;
197290 struct conf_unirec * conf = (struct conf_unirec * ) cfg ;
291+ if (conf == NULL ) {
292+ IPX_CTX_ERROR (ctx , "configuration is NULL! Skipping ipx_plugin_destroy()" );
293+ }
198294
199295 IPX_CTX_INFO (ctx , "UniRec plugin finalization." );
200296
@@ -204,8 +300,21 @@ ipx_plugin_destroy(ipx_ctx_t *ctx, void *cfg)
204300 // Destroy parsed XML configuration
205301 configuration_free (conf -> params );
206302
303+ trap_ctx_finalize (& conf -> tctx );
207304
305+ ur_free_template (conf -> urtmpl );
208306
307+ if (pthread_mutex_lock (& urp_mutex ) == -1 ) {
308+ IPX_CTX_ERROR (ctx , "Could not lock. (%s:%d)" , __FILE__ , __LINE__ );
309+ }
310+
311+ if (-- urp_refcount == 0 ) {
312+ ur_finalize ();
313+ }
314+
315+ if (pthread_mutex_unlock (& urp_mutex ) == -1 ) {
316+ IPX_CTX_ERROR (ctx , "Could not unlock. (%s:%d)" , __FILE__ , __LINE__ );
317+ }
209318 // Destroy instance structure
210319 free (conf );
211320}
0 commit comments