diff --git a/ChangeLog b/ChangeLog
index c2db933..0b120d4 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2019-09-01
+- Cleanup configure.ac
+
+2019-08-31
+- Fix various c11 compile issues
+- Cleanup old compat15 comments
+
+2019-08-24
+- Add vlan tags dot1qVlanId, 243, 254 - #182
+- Fix sflow issue with Arista switches
+
+2019-08-19
+- Fix ft2nfdump next hop and ip router fields
+
+2019-08-16
+- Cleanup and fix IPv6 network display in war records.
+
 2019-08-14
 - Fix compile issues
 - Fix output buffer size for lzo1x_decompress_safe()
diff --git a/README.md b/README.md
index 1d25646..76d98d4 100755
--- a/README.md
+++ b/README.md
@@ -53,8 +53,9 @@ Build sflow collector sfcpad; default is __NO__
 Build nfprofile used by NfSen; default is __NO__
 * __--enable-nftrack__  
 Build nftrack used by PortTracker; default is __NO__
-* __--enable-compat15__  
-Build nfdump, to read nfdump data files created with nfdump 1.5.x; default is __NO__
+
+This code no longer reads nfdump-1.5.x data files. If needed use nfdump up
+to v1.6.17
 
 Development and beta options
 
diff --git a/bin/collector.c b/bin/collector.c
index 184d9da..9d67a32 100755
--- a/bin/collector.c
+++ b/bin/collector.c
@@ -1,8 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2016, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -56,12 +53,6 @@
 #include <stdint.h>
 #endif
 
-#ifndef DEVEL
-#   define dbg_printf(...) /* printf(__VA_ARGS__) */
-#else
-#   define dbg_printf(...) printf(__VA_ARGS__)
-#endif
-
 #include "util.h"
 #include "nf_common.h"
 #include "nffile.h"
@@ -574,11 +565,11 @@ int FlushInfoSampler(FlowSource_t *fs, sampler_info_record_t *sampler) {
 } // End of FlushInfoSampler
 
 void FlushStdRecords(FlowSource_t *fs) {
-generic_exporter_t *e = fs->exporter_data;
+exporter_t *e = fs->exporter_data;
 int i;
 
 	while ( e ) {
-		generic_sampler_t *sampler = e->sampler;
+		sampler_t *sampler = e->sampler;
 		AppendToBuffer(fs->nffile, (void *)&(e->info), e->info.header.size);
 		while ( sampler ) {
 			AppendToBuffer(fs->nffile, (void *)&(sampler->info), sampler->info.header.size);
@@ -596,7 +587,7 @@ int i;
 } // End of FlushStdRecords
 
 void FlushExporterStats(FlowSource_t *fs) {
-generic_exporter_t *e = fs->exporter_data;
+exporter_t *e = fs->exporter_data;
 exporter_stats_record_t	*exporter_stats;
 uint32_t i, size;
 
@@ -654,17 +645,3 @@ uint32_t i, size;
  
 } // End of FlushExporterStats
 
-
-
-int HasOptionTable(FlowSource_t *fs, uint16_t id ) {
-option_offset_t *t;
-
-	t = fs->option_offset_table;
-	while ( t && t->id != id )
-		t = t->next;
-
-	dbg_printf("Has option table: %s\n", t == NULL ? "not found" : "found");
-
-	return t != NULL;
-
-} // End of HasOptionTable
diff --git a/bin/collector.h b/bin/collector.h
index 8ffe756..7c416d8 100755
--- a/bin/collector.h
+++ b/bin/collector.h
@@ -1,7 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -42,62 +40,13 @@
 #endif
 #include <sys/socket.h>
 
+#include "exporter.h"
 #include "bookkeeper.h"
 #include "nffile.h"
 
 #define FNAME_SIZE  256
 #define IDENT_SIZE  32
 
-typedef struct srecord_s {
-    char    fname[FNAME_SIZE];      // file name
-    char    subdir[FNAME_SIZE];     // subdir name
-    char    tstring[16];            // actually 12 needed e.g. 200411011230
-    time_t  tstamp;                 // UNIX time stamp
-	int		failed;					// in case of an error
-} srecord_t;
-
-// common_record_t defines ext_map as uint_8, so max 256 extension maps allowed.
-// should be enough anyway
-
-typedef struct option_offset_s {
-	struct option_offset_s *next;
-	uint32_t	id;					// table id
-	uint32_t	flags;				// info about this map
-
-	// sampling offsets
-#define HAS_SAMPLER_DATA	1
-	uint16_t	offset_id;
-	uint16_t    sampler_id_length;
-	uint16_t	offset_mode;
-	uint16_t	offset_interval;
-
-#define HAS_STD_SAMPLER_DATA 2
-	uint16_t	offset_std_sampler_interval;
-	uint16_t	offset_std_sampler_algorithm;
-
-} option_offset_t;
-
-typedef struct generic_sampler_s {
-	struct generic_sampler_s *next;
-	sampler_info_record_t	info;
-} generic_sampler_t;
-
-typedef struct generic_exporter_s {
-	// link chain
-	struct generic_exporter_s *next;
-
-	// generic exporter information
-	exporter_info_record_t info;
-
-	uint64_t	packets;			// number of packets sent by this exporter
-	uint64_t	flows;				// number of flow records sent by this exporter
-	uint32_t	sequence_failure;	// number of sequence failues
-	uint32_t	padding_errors;		// number of sequence failues
-
-	generic_sampler_t		*sampler;
-
-} generic_exporter_t;
-
 typedef struct FlowSource_s {
 	// link
 	struct FlowSource_s *next;
@@ -121,7 +70,7 @@ typedef struct FlowSource_s {
 	uint64_t			last_seen;		// in msec
 
 	// Any exporter specific data
-	generic_exporter_t	*exporter_data;
+	exporter_t			*exporter_data;
 	uint32_t			exporter_count;
 	struct timeval		received;
 
@@ -134,8 +83,6 @@ typedef struct FlowSource_s {
 		extension_map_t	**maps;
 	} extension_map_list;
 
-	option_offset_t *option_offset_table;
-
 } FlowSource_t;
 
 /* input buffer size, to read data from the network */
@@ -166,10 +113,6 @@ int FlushInfoExporter(FlowSource_t *fs, exporter_info_record_t *exporter);
 
 int FlushInfoSampler(FlowSource_t *fs, sampler_info_record_t *sampler);
 
-int HasOptionTable(FlowSource_t *fs, uint16_t id );
-
-void launcher (char *commbuff, FlowSource_t *FlowSource, char *process, int expire);
-
 /* Default time window in seconds to rotate files */
 #define TIME_WINDOW	  	300
 
diff --git a/bin/exporter.c b/bin/exporter.c
index d979c6b..4619ada 100755
--- a/bin/exporter.c
+++ b/bin/exporter.c
@@ -1,8 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2016, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2012, Peter Haag
+ *  Copyright (c) 2012-2019, Peter Haag
  *  
  *  Redistribution and use in source and binary forms, with or without 
  *  modification, are permitted provided that the following conditions are met:
@@ -51,12 +48,6 @@
 #include <stdint.h>
 #endif
 
-#ifndef DEVEL
-#   define dbg_printf(...) /* printf(__VA_ARGS__) */
-#else
-#   define dbg_printf(...) printf(__VA_ARGS__)
-#endif
-
 #include "util.h"
 #include "nffile.h"
 #include "nfx.h"
@@ -71,11 +62,11 @@
 #include "ipfix.h"
 
 /* global */
-generic_exporter_t **exporter_list;
+exporter_t **exporter_list;
 
 /* local variables */
 #define MAX_EXPORTERS 65536
-static generic_exporter_t *exporter_root;
+static exporter_t *exporter_root;
 
 #include "nffile_inline.c"
 
@@ -84,7 +75,7 @@ static generic_exporter_t *exporter_root;
 /* functions */
 int InitExporterList(void) {
 
-	exporter_list = calloc(MAX_EXPORTERS, sizeof(generic_exporter_t *));
+	exporter_list = calloc(MAX_EXPORTERS, sizeof(exporter_t *));
 	if ( !exporter_list ) {
 		LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
 		return 0;
@@ -136,7 +127,7 @@ char *p1, *p2;
 	}
 
 	// slot[id] is now available
-	exporter_list[id] = (generic_exporter_t *)calloc(1, sizeof(generic_exporter_t));
+	exporter_list[id] = (exporter_t *)calloc(1, sizeof(exporter_t));
 	if ( !exporter_list[id] ) {
 		LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
 		return 0;
@@ -185,7 +176,7 @@ char *p1, *p2;
 
 int AddSamplerInfo(sampler_info_record_t *sampler_record) {
 uint32_t id;
-generic_sampler_t	**sampler;
+sampler_t	**sampler;
 
 	if ( sampler_record->header.size != sizeof(sampler_info_record_t) ) {
 		LogError("Corrupt sampler record in %s line %d\n", __FILE__, __LINE__);
@@ -213,7 +204,7 @@ generic_sampler_t	**sampler;
 		sampler = &((*sampler)->next);
 	}
 
-	*sampler = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+	*sampler = (sampler_t *)malloc(sizeof(sampler_t));
 	if ( !*sampler ) {
 		LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
 		return 0;
@@ -300,7 +291,7 @@ int i;
 	i = 1;
 	while ( i < MAX_EXPORTERS  && exporter_list[i] != NULL ) {
 		exporter_info_record_t *exporter;
-       	generic_sampler_t *sampler;
+       	sampler_t *sampler;
 
 		exporter = &exporter_list[i]->info;
 		AppendToBuffer(nffile, (void *)exporter, exporter->header.size);
@@ -438,7 +429,7 @@ uint64_t total_bytes;
 		char ipstr[IP_STRING_LEN];
 
 		exporter_info_record_t *exporter;
-       	generic_sampler_t *sampler;
+       	sampler_t *sampler;
 
 		printf("\n");
 		exporter = &exporter_list[i]->info;
diff --git a/bin/exporter.h b/bin/exporter.h
index 275f7bb..cad714a 100755
--- a/bin/exporter.h
+++ b/bin/exporter.h
@@ -1,7 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2012, Peter Haag
+ *  Copyright (c) 2012-2019, Peter Haag
  *  
  *  Redistribution and use in source and binary forms, with or without 
  *  modification, are permitted provided that the following conditions are met:
@@ -41,6 +39,55 @@
 
 #include "nffile.h"
 
+typedef struct optionTag_s {
+	uint16_t offset;
+	uint16_t length;
+} optionTag_t;
+
+typedef struct samplerOption_s {
+	struct samplerOption_s *next;
+	uint32_t	tableID;	// table id
+#define STDSAMPLING34	1
+#define STDSAMPLING35	2
+#define STDMASK			0x3
+#define STDFLAGS		0x3
+
+#define SAMPLER302		4
+#define SAMPLER304		8
+#define SAMPLER305		16
+#define SAMPLERMASK		0x1C
+#define SAMPLERFLAGS	0x1C
+
+	uint32_t	flags;		// info about this map
+
+	// sampling offset/length values
+	optionTag_t id;
+	optionTag_t mode;
+	optionTag_t interval;
+
+} samplerOption_t;
+
+typedef struct sampler_s {
+	struct sampler_s *next;
+	sampler_info_record_t	info;	// sampler record nffile
+} sampler_t;
+
+typedef struct exporter_s {
+	// linked chain
+	struct exporter_s *next;
+
+	// exporter information
+	exporter_info_record_t info;	// exporter record nffile
+
+	uint64_t	packets;			// number of packets sent by this exporter
+	uint64_t	flows;				// number of flow records sent by this exporter
+	uint32_t	sequence_failure;	// number of sequence failues
+	uint32_t	padding_errors;		// number of sequence failues
+
+	sampler_t *sampler;				// list of samplers associated with this exporter
+
+} exporter_t;
+
 int InitExporterList(void);
 
 int AddExporterInfo(exporter_info_record_t *exporter_record);
diff --git a/bin/ft2nfdump.c b/bin/ft2nfdump.c
index 86e7fa1..2491f5b 100644
--- a/bin/ft2nfdump.c
+++ b/bin/ft2nfdump.c
@@ -1,9 +1,6 @@
 /*
  *  All rights reserved.
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2016, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  Copyright (c) 2001 Mark Fullmer and The Ohio State University
  *  All rights reserved.
@@ -156,7 +153,7 @@ int	i;
 		extension_info->map->ex_id[i++] = EX_MULIPLE;
 	}
 
-   	if (!ftio_check_xfield(ftio, FT_XFIELD_NEXTHOP )) {
+   	if (!ftio_check_xfield(ftio, FT_XFIELD_PEER_NEXTHOP )) {
 		extension_info->map->ex_id[i++] = EX_NEXT_HOP_v4;
 	}
 
@@ -268,11 +265,11 @@ uint32_t			cnt;
 					record.dir			= 0;
 					record.dst_tos  	= 0;
 					break;
-				case EX_ROUTER_IP_v4:
+				case EX_NEXT_HOP_v4:
 					record.ip_nexthop.V4 = *((uint32_t*)(rec+fo.peer_nexthop));
 					break;
-				case EX_NEXT_HOP_v4:
-					record.ip_router.V4 = *((uint32_t*)(rec+fo.router_sc));
+				case EX_ROUTER_IP_v4:
+					record.ip_router.V4 = *((uint32_t*)(rec+fo.exaddr));
 					break;
 				case EX_ROUTER_ID:
 					record.engine_type = *((uint8_t*)(rec+fo.engine_type));
diff --git a/bin/inline.c b/bin/inline.c
index 3eb5c71..6ba2175 100644
--- a/bin/inline.c
+++ b/bin/inline.c
@@ -50,6 +50,8 @@ static inline uint64_t	Get_val56(void *p);
 
 static inline uint64_t	Get_val64(void *p);
 
+static inline uint64_t	Get_val(void *p, uint32_t index, uint32_t length);
+
 static inline void	Put_val16(uint16_t v, void *p);
 
 static inline void	Put_val24(uint32_t v, void *p);
@@ -230,6 +232,40 @@ type_mask_t mask;
 
 } // End of Get_val64
 
+static inline uint64_t Get_val(void *p, uint32_t index, uint32_t length) {
+
+	switch (length)  {
+		case 1:
+			return *((uint8_t *)(p + index));
+			break;
+		case 2:
+			return Get_val16(p + index);
+			break;
+		case 3:
+			return Get_val24(p + index);
+			break;
+		case 4:
+			return Get_val32(p + index);
+			break;
+		case 5:
+			return Get_val40(p + index);
+			break;
+		case 6:
+			return Get_val48(p + index);
+			break;
+		case 7:
+			return Get_val56(p + index);
+			break;
+		case 8:
+			return Get_val64(p + index);
+			break;
+		default:
+			return 0;
+	}
+	return 0;
+
+} // End of Get_val
+
 static inline void	Put_val16(uint16_t v, void *p) {
 uint8_t		*out = (uint8_t *)p;
 type_mask_t mask;
diff --git a/bin/ipfix.c b/bin/ipfix.c
index 52f1060..dbf60c3 100644
--- a/bin/ipfix.c
+++ b/bin/ipfix.c
@@ -55,22 +55,15 @@
 #include "exporter.h"
 #include "ipfix.h"
 
-#ifndef DEVEL
-#   define dbg_printf(...) /* printf(__VA_ARGS__) */
-#else
-#   define dbg_printf(...) printf(__VA_ARGS__)
-#endif
-
-// a few handy macros
 #define GET_FLOWSET_ID(p) 	  (Get_val16(p))
 #define GET_FLOWSET_LENGTH(p) (Get_val16((void *)((p) + 2)))
 
 #define GET_TEMPLATE_ID(p) 	  (Get_val16(p))
 #define GET_TEMPLATE_COUNT(p) (Get_val16((void *)((p) + 2)))
 
-#define GET_OPTION_TEMPLATE_ID(p) 	  		  		 (Get_val16(p))
-#define GET_OPTION_TEMPLATE_FIELD_COUNT(p)   (Get_val16((void *)((p) + 2)))
-#define GET_OPTION_TEMPLATE_SCOPE_FIELD_COUNT(p)   		 (Get_val16((void *)((p) + 4)))
+#define GET_OPTION_TEMPLATE_ID(p)				 (Get_val16(p))
+#define GET_OPTION_TEMPLATE_FIELD_COUNT(p)		 (Get_val16((void *)((p) + 2)))
+#define GET_OPTION_TEMPLATE_SCOPE_FIELD_COUNT(p) (Get_val16((void *)((p) + 4)))
 
 #define DYN_FIELD_LENGTH	65535
 
@@ -159,10 +152,10 @@ typedef struct input_translation_s {
  * 	All Obervation Domains from all exporter are stored in a linked list
  *	which uniquely can identify each exporter/Observation Domain
  */
-typedef struct exporter_ipfix_domain_s {
-	struct exporter_ipfix_domain_s	*next;	// linkes list to next exporter
+typedef struct exporterDomain_s {
+	struct exporterDomain_s *next;	// linkes list to next exporter
 
-	// generic exporter information
+	// exporter information
 	exporter_info_record_t info;
 
 	uint64_t	packets;			// number of packets sent by this exporter
@@ -170,8 +163,9 @@ typedef struct exporter_ipfix_domain_s {
 	uint32_t	sequence_failure;	// number of sequence failues
 	uint32_t	padding_errors;		// number of sequence failues
 
-	// generic sampler
-	generic_sampler_t		*sampler;
+	//  sampler
+	sampler_t		*sampler;		// sampler info
+	samplerOption_t *samplerOption; // sampler options table info
 
 	// exporter parameters
 	uint32_t	ExportTime;
@@ -190,7 +184,7 @@ typedef struct exporter_ipfix_domain_s {
 	// the last template we processed as a cache
 	input_translation_t *current_table;
 
-} exporter_ipfix_domain_t;
+} exporterDomain_t;
 
 
 static struct ipfix_element_map_s {
@@ -300,18 +294,19 @@ extern uint32_t default_sampling;
 extern uint32_t overwrite_sampling;
 
 // prototypes
-static void InsertStdSamplerOffset(FlowSource_t *fs, uint16_t id, uint16_t offset_std_sampler_interval, 
-	uint16_t offset_std_sampler_algorithm);
+static int HasOptionTable(exporterDomain_t *exporter, uint16_t tableID );
 
-static void InsertSampler(FlowSource_t *fs, exporter_ipfix_domain_t *exporter, int32_t id, uint16_t mode, uint32_t interval);
+static void InsertSamplerOption(exporterDomain_t *exporter, samplerOption_t *samplerOption);
 
-static input_translation_t *add_translation_table(exporter_ipfix_domain_t *exporter, uint16_t id);
+static void InsertSampler(FlowSource_t *fs, exporterDomain_t *exporter, int32_t id, uint16_t mode, uint32_t interval);
 
-static void remove_translation_table(FlowSource_t *fs, exporter_ipfix_domain_t *exporter, uint16_t id);
+static input_translation_t *add_translation_table(exporterDomain_t *exporter, uint16_t id);
 
-static void remove_all_translation_tables(exporter_ipfix_domain_t *exporter);
+static void remove_translation_table(FlowSource_t *fs, exporterDomain_t *exporter, uint16_t id);
 
-static exporter_ipfix_domain_t *GetExporter(FlowSource_t *fs, ipfix_header_t *ipfix_header);
+static void remove_all_translation_tables(exporterDomain_t *exporter);
+
+static exporterDomain_t *GetExporter(FlowSource_t *fs, ipfix_header_t *ipfix_header);
 
 static uint32_t MapElement(uint16_t Type, uint16_t Length, uint32_t order);
 
@@ -321,15 +316,15 @@ static int compact_input_order(void);
 
 static int reorder_sequencer(input_translation_t *table);
 
-static void Process_ipfix_templates(exporter_ipfix_domain_t *exporter, void *flowset_header, uint32_t size_left, FlowSource_t *fs);
+static void Process_ipfix_templates(exporterDomain_t *exporter, void *flowset_header, uint32_t size_left, FlowSource_t *fs);
 
-static void Process_ipfix_template_add(exporter_ipfix_domain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs);
+static void Process_ipfix_template_add(exporterDomain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs);
 
-static void Process_ipfix_template_withdraw(exporter_ipfix_domain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs);
+static void Process_ipfix_template_withdraw(exporterDomain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs);
 
-static void  Process_ipfix_option_data(exporter_ipfix_domain_t *exporter, void *data_flowset, FlowSource_t *fs);
+static void  Process_ipfix_option_data(exporterDomain_t *exporter, void *data_flowset, FlowSource_t *fs);
 
-static void Process_ipfix_data(exporter_ipfix_domain_t *exporter, uint32_t ExportTime, void *data_flowset, FlowSource_t *fs, input_translation_t *table );
+static void Process_ipfix_data(exporterDomain_t *exporter, uint32_t ExportTime, void *data_flowset, FlowSource_t *fs, input_translation_t *table );
 
 #include "inline.c"
 #include "nffile_inline.c"
@@ -361,10 +356,23 @@ int i;
 
 } // End of Init_IPFIX
 
-static exporter_ipfix_domain_t *GetExporter(FlowSource_t *fs, ipfix_header_t *ipfix_header) {
+static int HasOptionTable(exporterDomain_t *exporter, uint16_t tableID ) {
+samplerOption_t *s;
+
+	s = exporter->samplerOption;
+	while ( s && s->tableID != tableID )
+		s = s->next;
+
+	dbg_printf("Has option table: %s\n", s == NULL ? "not found" : "found");
+
+	return s != NULL;
+
+} // End of HasOptionTable
+
+static exporterDomain_t *GetExporter(FlowSource_t *fs, ipfix_header_t *ipfix_header) {
 #define IP_STRING_LEN   40
 char ipstr[IP_STRING_LEN];
-exporter_ipfix_domain_t **e = (exporter_ipfix_domain_t **)&(fs->exporter_data);
+exporterDomain_t **e = (exporterDomain_t **)&(fs->exporter_data);
 uint32_t ObservationDomain = ntohl(ipfix_header->ObservationDomain);
 
 	while ( *e ) {
@@ -387,12 +395,12 @@ uint32_t ObservationDomain = ntohl(ipfix_header->ObservationDomain);
 	}
 
 	// nothing found
-	*e = (exporter_ipfix_domain_t *)malloc(sizeof(exporter_ipfix_domain_t));
+	*e = (exporterDomain_t *)malloc(sizeof(exporterDomain_t));
 	if ( !(*e)) {
 		LogError("Process_ipfix: Panic! malloc() %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 		return NULL;
 	}
-	memset((void *)(*e), 0, sizeof(exporter_ipfix_domain_t));
+	memset((void *)(*e), 0, sizeof(exporterDomain_t));
 	(*e)->info.header.type  = ExporterInfoRecordType;
 	(*e)->info.header.size  = sizeof(exporter_info_record_t);
 	(*e)->info.id 			= ObservationDomain;
@@ -450,7 +458,7 @@ int	index;
 
 } // End of MapElement
 
-static input_translation_t *GetTranslationTable(exporter_ipfix_domain_t *exporter, uint16_t id) {
+static input_translation_t *GetTranslationTable(exporterDomain_t *exporter, uint16_t id) {
 input_translation_t *table;
 
 	if ( exporter->current_table && ( exporter->current_table->id == id ) )
@@ -473,7 +481,7 @@ input_translation_t *table;
 
 } // End of GetTranslationTable
 
-static input_translation_t *add_translation_table(exporter_ipfix_domain_t *exporter, uint16_t id) {
+static input_translation_t *add_translation_table(exporterDomain_t *exporter, uint16_t id) {
 input_translation_t **table;
 
 	table = &(exporter->input_translation_table);
@@ -500,7 +508,7 @@ input_translation_t **table;
 
 } // End of add_translation_table
 
-static void remove_translation_table(FlowSource_t *fs, exporter_ipfix_domain_t *exporter, uint16_t id) {
+static void remove_translation_table(FlowSource_t *fs, exporterDomain_t *exporter, uint16_t id) {
 input_translation_t *table, *parent;
 
 	LogInfo("Process_ipfix: [%u] Withdraw template id: %i", 
@@ -540,7 +548,7 @@ input_translation_t *table, *parent;
 
 } // End of remove_translation_table
 
-static void remove_all_translation_tables(exporter_ipfix_domain_t *exporter) {
+static void remove_all_translation_tables(exporterDomain_t *exporter) {
 input_translation_t *table, *next;
 
 	LogInfo("Process_ipfix: Withdraw all templates from observation domain %u\n", 
@@ -765,7 +773,7 @@ sequence_map_t *sequence = table->sequence;
 
 } // End of reorder_sequencer
 
-static input_translation_t *setup_translation_table (exporter_ipfix_domain_t *exporter, uint16_t id) {
+static input_translation_t *setup_translation_table (exporterDomain_t *exporter, uint16_t id) {
 input_translation_t *table;
 extension_map_t 	*extension_map;
 uint32_t			i, ipv6, offset, next_extension;
@@ -1093,48 +1101,13 @@ size_t				size_required;
 
 } // End of setup_translation_table
 
-static void InsertStdSamplerOffset( FlowSource_t *fs, uint16_t id, uint16_t offset_std_sampler_interval, uint16_t offset_std_sampler_algorithm) {
-option_offset_t **t;
-
-	t = &(fs->option_offset_table);
-	while ( *t ) {
-		if ( (*t)->id == id ) { // table already known to us - update data
-			dbg_printf("Found existing std sampling info in template %i\n", id);
-			break;
-		}
-	
-		t = &((*t)->next);
-	}
-
-	if ( *t == NULL ) { // new table
-		dbg_printf("Allocate new std sampling info from template %i\n", id);
-		*t = (option_offset_t *)calloc(1, sizeof(option_offset_t));
-		if ( !*t ) {
-			LogError("malloc() allocation error at %s line %u: %s" , __FILE__, __LINE__, strerror (errno));
-			return ;
-		} 
-		LogInfo("Process_v9: New std sampler: interval: %i, algorithm: %i", 
-			offset_std_sampler_interval, offset_std_sampler_algorithm);
-	}   // else existing table
-
-	dbg_printf("Insert/Update sampling info from template %i\n", id);
-	SetFlag((*t)->flags, HAS_STD_SAMPLER_DATA);
-	(*t)->id				= id;
-	(*t)->offset_id			= 0;
-	(*t)->offset_mode		= 0;
-	(*t)->offset_interval	= 0;
-	(*t)->offset_std_sampler_interval   = offset_std_sampler_interval;
-	(*t)->offset_std_sampler_algorithm  = offset_std_sampler_algorithm;
-	
-} // End of InsertStdSamplerOffset
-
-static void InsertSampler(FlowSource_t *fs, exporter_ipfix_domain_t *exporter, int32_t id, uint16_t mode, uint32_t interval) {
-generic_sampler_t *sampler;
+static void InsertSampler(FlowSource_t *fs, exporterDomain_t *exporter, int32_t id, uint16_t mode, uint32_t interval) {
+sampler_t *sampler;
 
 	dbg_printf("[%u] Insert Sampler: Exporter is 0x%llu\n", exporter->info.id, (long long unsigned)exporter);
 	if ( !exporter->sampler ) {
 		// no samplers so far 
-		sampler = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+		sampler = (sampler_t *)malloc(sizeof(sampler_t));
 		if ( !sampler ) {
 			LogError( "Process_v9: Panic! malloc(): %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 			return;
@@ -1181,7 +1154,7 @@ generic_sampler_t *sampler;
 			// test for end of chain
 			if ( sampler->next == NULL ) {
 				// end of sampler chain - insert new sampler
-				sampler->next = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+				sampler->next = (sampler_t *)malloc(sizeof(sampler_t));
 				if ( !sampler->next ) {
 					LogError( "Process_v9: Panic! malloc(): %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 					return;
@@ -1212,7 +1185,47 @@ generic_sampler_t *sampler;
 	
 } // End of InsertSampler
 
-static void Process_ipfix_templates(exporter_ipfix_domain_t *exporter, void *flowset_header, uint32_t size_left, FlowSource_t *fs) {
+static void InsertSamplerOption(exporterDomain_t *exporter, samplerOption_t *samplerOption) {
+samplerOption_t *s, *parent;
+
+	parent = NULL;
+	s = exporter->samplerOption;
+	while (s) {
+		if ( s->tableID == samplerOption->tableID ) { // table already known to us - update data
+			dbg_printf("Found existing sampling info in template %i\n", samplerOption->tableID);
+			break;
+		}
+		parent = s;
+		s = s->next;
+	}
+
+	if ( s != NULL ) { // existing entry
+		// replace existing table
+		dbg_printf("Replace existing sampler table ID %i\n", samplerOption->tableID);
+		if ( parent ) {
+			parent->next = samplerOption;
+		} else {
+			exporter->samplerOption = samplerOption;
+		}
+		samplerOption->next = s->next;
+		free(s);
+		s = NULL;
+	} else { // new entry
+		dbg_printf("New sampling table ID %i\n", samplerOption->tableID);
+		// push new sampling table
+		samplerOption->next = exporter->samplerOption;
+		exporter->samplerOption = samplerOption;
+	}
+
+	dbg_printf("Update/Insert sampler table id: %u flags: 0x%x - sampler ID: %u/%u, mode: %u/%u, interval: %u/%u\n",
+		samplerOption->tableID, samplerOption->flags, 
+		samplerOption->id.offset, samplerOption->id.length,
+		samplerOption->mode.offset, samplerOption->mode.length,
+		samplerOption->interval.offset, samplerOption->interval.length);
+
+} // End of InsertSamplerOption
+
+static void Process_ipfix_templates(exporterDomain_t *exporter, void *flowset_header, uint32_t size_left, FlowSource_t *fs) {
 ipfix_template_record_t *ipfix_template_record;
 void *DataPtr;
 uint32_t count;
@@ -1235,7 +1248,7 @@ uint32_t count;
 
 } // End of Process_ipfix_templates
 
-static void Process_ipfix_template_add(exporter_ipfix_domain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs) {
+static void Process_ipfix_template_add(exporterDomain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs) {
 input_translation_t *translation_table;
 ipfix_template_record_t *ipfix_template_record;
 ipfix_template_elements_std_t *NextElement;
@@ -1418,7 +1431,7 @@ int i;
 
 } // End of Process_ipfix_template_add
 
-static void Process_ipfix_template_withdraw(exporter_ipfix_domain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs) {
+static void Process_ipfix_template_withdraw(exporterDomain_t *exporter, void *DataPtr, uint32_t size_left, FlowSource_t *fs) {
 ipfix_template_record_t *ipfix_template_record;
 
 	// a template flowset can contain multiple records ( templates )
@@ -1458,30 +1471,29 @@ ipfix_template_record_t *ipfix_template_record;
  
 } // End of Process_ipfix_template_withdraw
 
-static void Process_ipfix_option_templates(exporter_ipfix_domain_t *exporter, void *option_template_flowset, FlowSource_t *fs) {
-uint8_t		*DataPtr;
-uint32_t	size_left, size_required, i;
+static void Process_ipfix_option_templates(exporterDomain_t *exporter, void *option_template_flowset, FlowSource_t *fs) {
+uint8_t		*option_template;
+uint32_t	size_left, size_required;
 // uint32_t nr_scopes, nr_options;
-uint16_t	id, field_count, scope_field_count, offset;
-uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sampling;
+uint16_t	tableID, field_count, scope_field_count, offset;
+samplerOption_t *samplerOption;
 
-	i = 0;	// keep compiler happy
-	size_left 		  = GET_FLOWSET_LENGTH(option_template_flowset) - 4; // -4 for flowset header -> id and length
+	size_left = GET_FLOWSET_LENGTH(option_template_flowset) - 4; // -4 for flowset header -> id and length
 	if ( size_left < 6 ) {
 		LogError("Process_ipfix: [%u] option template length error: size left %u too small for an options template", 
 			exporter->info.id, size_left);
 		return;
 	}
 
-	DataPtr   		  = option_template_flowset + 4;
-	id 	  			  = GET_OPTION_TEMPLATE_ID(DataPtr); 
-	field_count 	  = GET_OPTION_TEMPLATE_FIELD_COUNT(DataPtr);
-	scope_field_count = GET_OPTION_TEMPLATE_SCOPE_FIELD_COUNT(DataPtr);
-	DataPtr   += 6;
+	option_template	  = option_template_flowset + 4;
+	tableID 		  = GET_OPTION_TEMPLATE_ID(option_template); 
+	field_count 	  = GET_OPTION_TEMPLATE_FIELD_COUNT(option_template);
+	scope_field_count = GET_OPTION_TEMPLATE_SCOPE_FIELD_COUNT(option_template);
+	option_template   += 6;
 	size_left -= 6;
 
-	dbg_printf("Decode Option Template. id: %u, field count: %u, scope field count: %u\n",
-		id, field_count, scope_field_count);
+	dbg_printf("Decode Option Template. tableID: %u, field count: %u, scope field count: %u\n",
+		tableID, field_count, scope_field_count);
 
 	if ( scope_field_count == 0  ) {
 		LogError("Process_ipfx: [%u] scope field count error: length must not be zero", 
@@ -1506,11 +1518,17 @@ uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sa
 		return;
 	}
 
-	offset_std_sampler_interval  = 0;
-	offset_std_sampler_algorithm = 0;
-	found_std_sampling			 = 0;
-	offset = 0;
+	samplerOption = (samplerOption_t *)malloc(sizeof(samplerOption_t));
+	if ( !samplerOption ) {
+		LogError("Error malloc(): %s in %s:%d", strerror (errno), __FILE__, __LINE__);
+		return;
+	}
+	memset((void *)samplerOption, 0, sizeof(samplerOption_t));
+
+	samplerOption->tableID = tableID;
 
+	int i;
+	offset = 0;
 	for ( i=0; i<scope_field_count; i++ ) {
 		uint16_t id, length;
 		int Enterprise;
@@ -1520,8 +1538,8 @@ uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sa
 				exporter->info.id, __FILE__, __LINE__, strerror (errno));
 			return;
 		}
-		id 	   = Get_val16(DataPtr); DataPtr += 2;
-		length = Get_val16(DataPtr); DataPtr += 2;
+		id 	   = Get_val16(option_template); option_template += 2;
+		length = Get_val16(option_template); option_template += 2;
 		size_left -= 4;
 		Enterprise = id & 0x8000 ? 1 : 0;
 		if ( Enterprise ) {
@@ -1532,28 +1550,27 @@ uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sa
 				dbg_printf("option template length error: size left %u too small\n", size_left);
 				return;
 			}
-			DataPtr += 4;
+			option_template += 4;
 			size_left -= 4;
 			dbg_printf(" [%i] Enterprise: 1, scope id: %u, scope length %u enterprise value: %u\n", 
-				i, id, length, Get_val32(DataPtr));
+				i, id, length, Get_val32(option_template));
 		} else {
 			dbg_printf(" [%i] Enterprise: 0, scope id: %u, scope length %u\n", i, id, length);
 		}
-
 		offset += length;
 	}
 
 	for ( ;i<field_count; i++ ) {
 		uint32_t enterprise_value;
-		uint16_t id, length;
+		uint16_t type, length;
 		int Enterprise;
 
 		// keep compiler happy
 		UNUSED(enterprise_value);
-		id 	   = Get_val16(DataPtr); DataPtr += 2;
-		length = Get_val16(DataPtr); DataPtr += 2;
+		type   = Get_val16(option_template); option_template += 2;
+		length = Get_val16(option_template); option_template += 2;
 		size_left -= 4;
-		Enterprise = id & 0x8000 ? 1 : 0;
+		Enterprise = type & 0x8000 ? 1 : 0;
 		if ( Enterprise ) {
 			size_required += 4;
 			if ( size_left < 4 ) {
@@ -1562,60 +1579,66 @@ uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sa
 				dbg_printf("option template length error: size left %u too small\n", size_left);
 				return;
 			}
-			enterprise_value = Get_val32(DataPtr);
-			DataPtr += 4;
+			enterprise_value = Get_val32(option_template);
+			option_template += 4;
 			size_left -= 4;
-			dbg_printf(" [%i] Enterprise: 1, option id: %u, option length %u enterprise value: %u\n", 
-				i, id, length, enterprise_value);
+			dbg_printf(" [%i] Enterprise: 1, option type: %u, option length %u enterprise value: %u\n", 
+				i, type, length, enterprise_value);
 		} else {
-			dbg_printf(" [%i] Enterprise: 0, option id: %u, option length %u\n", i, id, length);
+			dbg_printf(" [%i] Enterprise: 0, option type: %u, option length %u\n", i, type, length);
 		}
 
-		switch (id) {
+		switch (type) {
 			// general sampling
-			case IPFIX_samplingInterval:		// legacy #34
-			case IPFIX_samplingPacketInterval:	// #305
-				if ( length == 4 ) {
-					offset_std_sampler_interval = offset;
-					found_std_sampling++;
-					dbg_printf("	4 byte sampling interval option at offset: %u\n", offset);
-				} else {
-					LogError("Process_ipfix: [%u] option template error: sampling option lenth != 4 bytes: %u", 
-						exporter->info.id, length);
-				}
+			case IPFIX_samplingInterval: // #34
+				samplerOption->interval.length = length;
+				samplerOption->interval.offset = offset;
+				SetFlag(samplerOption->flags, STDSAMPLING34);
 				break;
-			case IPFIX_samplingAlgorithm:	// legacy #35
-			case IPFIX_selectorAlgorithm:	// #304
-				if ( length == 1 ) {
-					offset_std_sampler_algorithm = offset;
-					dbg_printf("	1 byte sampling algorithm option at offset: %u\n", offset);
-					found_std_sampling++;
-				} else {
-					LogError("Process_ipfix: [%u] option template error: algorithm option lenth != 1 byte: %u", 
-						exporter->info.id, length);
-				}
+			case IPFIX_samplingAlgorithm: // #35
+				samplerOption->mode.length = length;
+				samplerOption->mode.offset = offset;
+				SetFlag(samplerOption->flags, STDSAMPLING35);
 				break;
-		}
 
+			// individual samplers
+			case IPFIX_samplerId:	// #48 depricated - fall through
+			case IPFIX_selectorId:	// #302
+				samplerOption->id.length = length;
+				samplerOption->id.offset = offset;
+				SetFlag(samplerOption->flags, SAMPLER302);
+				break;
+			case IPFIX_samplerMode:		  // #49 depricated - fall through
+			case IPFIX_selectorAlgorithm: // #304
+				samplerOption->mode.length = length;
+				samplerOption->mode.offset = offset;
+				SetFlag(samplerOption->flags, SAMPLER304);
+				break;
+			case IPFIX_samplerRandomInterval:  // #50 depricated - fall through
+			case IPFIX_samplingPacketInterval: // #305
+				samplerOption->interval.length = length;
+				samplerOption->interval.offset = offset;
+				SetFlag(samplerOption->flags, SAMPLER305);
+				break;
+		}
 		offset += length;
 	}
 
-	if ( offset_std_sampler_interval ) {
-        dbg_printf("[%u] Std sampling interval found. offset: %u\n", 
-			exporter->info.id, offset_std_sampler_interval);
-		if ( offset_std_sampler_algorithm )
-        	dbg_printf("[%u] Std sampling algorithm found. offset: %u\n", 
-			exporter->info.id, offset_std_sampler_algorithm);
-        InsertStdSamplerOffset(fs, id, offset_std_sampler_interval, offset_std_sampler_algorithm);
-		dbg_printf("\n");
+	if ( (samplerOption->flags & SAMPLERMASK ) == SAMPLERFLAGS) {
+		dbg_printf("[%u] Sampler information found\n", exporter->info.id);
+		InsertSamplerOption(exporter, samplerOption);
+	} else if ( (samplerOption->flags & STDMASK ) == STDFLAGS) {
+		dbg_printf("[%u] Std sampling information found\n", exporter->info.id);
+		InsertSamplerOption(exporter, samplerOption);
+	} else {
+		free(samplerOption);
+		dbg_printf("[%u] No Sampling information found\n", exporter->info.id);
 	}
-
 	processed_records++;
 
 } // End of Process_ipfix_option_templates
 
-
-static void Process_ipfix_data(exporter_ipfix_domain_t *exporter, uint32_t ExportTime, void *data_flowset, FlowSource_t *fs, input_translation_t *table ){
+static void Process_ipfix_data(exporterDomain_t *exporter, uint32_t ExportTime, void *data_flowset, FlowSource_t *fs, input_translation_t *table ){
 uint64_t			sampling_rate;
 uint32_t			size_left;
 uint8_t				*in, *out;
@@ -1633,7 +1656,7 @@ char				*string;
 	// Check if sampling is announced
 	sampling_rate = 1;
 
-	generic_sampler_t *sampler = exporter->sampler;
+	sampler_t *sampler = exporter->sampler;
 	while ( sampler && sampler->info.id != -1 ) 
 		sampler = sampler->next;
 
@@ -1981,18 +2004,18 @@ char				*string;
 
 } // End of Process_ipfix_data
 
-static void  Process_ipfix_option_data(exporter_ipfix_domain_t *exporter, void *data_flowset, FlowSource_t *fs) {
-option_offset_t *offset_table;
-uint32_t	id;
+static void  Process_ipfix_option_data(exporterDomain_t *exporter, void *data_flowset, FlowSource_t *fs) {
+samplerOption_t *samplerOption;
+uint32_t	tableID;
 uint8_t	 *in;
 
-	id  = GET_FLOWSET_ID(data_flowset);
+	tableID  = GET_FLOWSET_ID(data_flowset);
 
-	offset_table = fs->option_offset_table;
-	while ( offset_table && offset_table->id != id )
-		offset_table = offset_table->next;
+	samplerOption = exporter->samplerOption;
+	while ( samplerOption && samplerOption->tableID != tableID )
+		samplerOption = samplerOption->next;
 
-	if ( !offset_table ) {
+	if ( !samplerOption ) {
 		// should never happen - catch it anyway
 		LogError( "Process_ipfix: Panic! - No Offset table found! : %s line %d", __FILE__, __LINE__);
 		return;
@@ -2006,36 +2029,36 @@ uint8_t	 *in;
 	// map input buffer as a byte array
 	in	= (uint8_t *)(data_flowset + 4);  // skip flowset header
 
-	if ( TestFlag(offset_table->flags, HAS_SAMPLER_DATA) ) {
+	if ( (samplerOption->flags & SAMPLERMASK ) == SAMPLERFLAGS) {
 		int32_t  id;
 		uint16_t mode;
 		uint32_t interval;
-		if (offset_table->sampler_id_length == 2) {
-			id = Get_val16((void *)&in[offset_table->offset_id]);
-		} else {
-			id = in[offset_table->offset_id];
-		}
 
-		mode = offset_table->offset_mode ? in[offset_table->offset_mode] : 0;
-		interval = Get_val32((void *)&in[offset_table->offset_interval]); 
-	
+		id	 = Get_val(in, samplerOption->id.offset, samplerOption->id.length);
+		mode = Get_val(in, samplerOption->mode.offset, samplerOption->mode.length);
+		interval = Get_val(in, samplerOption->interval.offset, samplerOption->interval.length);
+
 		InsertSampler(fs, exporter, id, mode, interval);
 
 		dbg_printf("Extracted Sampler data:\n");
-		dbg_printf("Sampler ID	  : %u\n", id);
+		dbg_printf("Sampler ID	    : %u\n", id);
 		dbg_printf("Sampler mode	: %u\n", mode);
 		dbg_printf("Sampler interval: %u\n", interval);
 	}
 
-	if ( TestFlag(offset_table->flags, HAS_STD_SAMPLER_DATA) ) {
-		int32_t  id	   = -1;
-		uint16_t mode	 = offset_table->offset_std_sampler_algorithm ? in[offset_table->offset_std_sampler_algorithm] : 0;
-		uint32_t interval = Get_val32((void *)&in[offset_table->offset_std_sampler_interval]);
+	if ( (samplerOption->flags & STDMASK ) == STDFLAGS) {
+		int32_t  id;
+		uint16_t mode;
+		uint32_t interval;
+
+		id		 = -1;
+		mode	 = Get_val(in, samplerOption->mode.offset, samplerOption->mode.length);
+		interval = Get_val(in, samplerOption->interval.offset, samplerOption->interval.length);
 
  		InsertSampler(fs, exporter, id, mode, interval);
 
 		dbg_printf("Extracted Std Sampler data:\n");
-		dbg_printf("Sampler ID	   : %i\n", id);
+		dbg_printf("Sampler ID	     : %i\n", id);
 		dbg_printf("Sampler algorithm: %u\n", mode);
 		dbg_printf("Sampler interval : %u\n", interval);
 
@@ -2047,7 +2070,7 @@ uint8_t	 *in;
 } // End of Process_ipfix_option_data
 
 void Process_IPFIX(void *in_buff, ssize_t in_buff_cnt, FlowSource_t *fs) {
-exporter_ipfix_domain_t	*exporter;
+exporterDomain_t	*exporter;
 ssize_t				size_left;
 uint32_t			ExportTime, Sequence, flowset_length;
 ipfix_header_t		*ipfix_header;
@@ -2177,7 +2200,7 @@ uint32_t 			ObservationDomain;
 					if ( table ) {
 						Process_ipfix_data(exporter, ExportTime, flowset_header, fs, table);
 						exporter->DataRecords++;
-					} else if ( HasOptionTable(fs, flowset_id) ) {
+					} else if ( HasOptionTable(exporter, flowset_id) ) {
 						Process_ipfix_option_data(exporter, flowset_header, fs);
 					} else {
 						// maybe a flowset with option data
diff --git a/bin/ipfix.h b/bin/ipfix.h
index 3ee8487..864ce42 100644
--- a/bin/ipfix.h
+++ b/bin/ipfix.h
@@ -231,14 +231,12 @@ typedef struct ipfix_template_elements_e_s {
 // deprecated elements for sampling 
 #define IPFIX_samplingInterval				 34
 #define IPFIX_samplingAlgorithm				 35
-// 1 - Deterministic Sampling,
-// 2 - Random Sampling.
 
-#define IPFIX_samplingPacketInterval		305
-#define IPFIX_selectorAlgorithm				304
+// depricated 38, 39
 
-// reserved 38, 39
-// reserved 48, 49, 50, 51
+#define IPFIX_samplerId						48
+#define IPFIX_samplerMode					49
+#define IPFIX_samplerRandomInterval			50
 
 // #define IPFIX_MIN_TTL			52
 // #define IPFIX_MAX_TTL			53
@@ -275,6 +273,13 @@ typedef struct ipfix_template_elements_e_s {
 #define IPFIX_flowEndMilliseconds			153
 #define IPFIX_flowStartDeltaMicroseconds	158
 #define IPFIX_flowEndDeltaMicroseconds		159
+#define IPFIX_postOctetTotalCount	 	 	171
+#define IPFIX_postPacketTotalCount	 	 	172
+
+// sampling
+#define IPFIX_selectorId					302
+#define IPFIX_selectorAlgorithm				304
+#define IPFIX_samplingPacketInterval		305
 
 // Private Enterprise Numbers
 #define IPFIX_ReverseInformationElement		29305
diff --git a/bin/ipfrag.c b/bin/ipfrag.c
index 26b443b..766ef19 100644
--- a/bin/ipfrag.c
+++ b/bin/ipfrag.c
@@ -45,6 +45,7 @@
 #include <netinet/in.h>
 #endif
 
+#include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <arpa/inet.h>
diff --git a/bin/launch.c b/bin/launch.c
index da3ca92..08d47f6 100644
--- a/bin/launch.c
+++ b/bin/launch.c
@@ -1,8 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2016, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -71,6 +68,7 @@
 #include "nffile.h"
 #include "collector.h"
 #include "util.h"
+#include "launch.h"
 
 static int done, launch, child_exit;
 
@@ -137,11 +135,7 @@ int  i;
 					s = InfoRecord->tstring;
 					break;
 				case 'u' :
-#if defined __OpenBSD__ || defined __FreeBSD__
-					snprintf(tmp, 16, "%i", InfoRecord->tstamp);
-#else
-					snprintf(tmp, 16, "%li", InfoRecord->tstamp);
-#endif
+					snprintf(tmp, 16, "%lli", (long long)InfoRecord->tstamp);
 					tmp[15] = 0;
 					s = tmp;
 					break;
@@ -320,7 +314,7 @@ int				ret, bookkeeper_stat, do_rescan;
 
 } // End of do_expire
 
-void launcher (char *commbuff, FlowSource_t *FlowSource, char *process, int expire) {
+void launcher (void *commbuff, FlowSource_t *FlowSource, char *process, int expire) {
 FlowSource_t	*fs;
 struct sigaction act;
 char 		*args[MAXARGS];
diff --git a/bin/launch.h b/bin/launch.h
index ba2736b..8c64d95 100644
--- a/bin/launch.h
+++ b/bin/launch.h
@@ -1,7 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -37,6 +35,7 @@
 #include "config.h"
 
 #include <time.h>
+#include "collector.h"
 
 #define FNAME_SIZE	256
 #define IDENT_SIZE	32
@@ -45,10 +44,11 @@ typedef struct srecord_s {
 	char	fname[FNAME_SIZE];		// file name
 	char	subdir[FNAME_SIZE];		// subdir name
 	char	ident[IDENT_SIZE];		// -I ident string
-	char	tstring[16];			// actually 12 needed e.g. 200411011230
+	char	tstring[24];			// 12 needed for YYYYmmddHHMM + opt. timezone
 	time_t	tstamp;					// UNIX time stamp
+	int		failed;					// in case of an error
 } srecord_t;
 
-void launcher (char *commbuff, char *datadir, char *process, int expire);
+void launcher (void *commbuff, FlowSource_t *FlowSource, char *process, int expire);
 
 #endif //_LAUNCH_H
diff --git a/bin/netflow_v1.c b/bin/netflow_v1.c
index 82c3080..7084bc1 100644
--- a/bin/netflow_v1.c
+++ b/bin/netflow_v1.c
@@ -80,10 +80,10 @@ typedef struct v1_block_s {
 #define V1_BLOCK_DATA_SIZE (sizeof(v1_block_t) - sizeof(uint32_t))
 
 typedef struct exporter_v1_s {
-	// identical to generic_exporter_t
+	// identical to exporter_t
 	struct exporter_v1_s *next;
 
-	// generic exporter information
+	// exporter information
 	exporter_info_record_t info;
 
 	uint64_t	packets;			// number of packets sent by this exporter
@@ -91,8 +91,8 @@ typedef struct exporter_v1_s {
 	uint32_t	sequence_failure;	// number of sequence failues
 	uint32_t	padding_errors;		// number of sequence failues
 
-	generic_sampler_t		*sampler;
-	// End of generic_exporter_t
+	sampler_t		*sampler;
+	// End of exporter_t
 
 	// extension map
 	extension_map_t 	 *extension_map;
@@ -139,7 +139,7 @@ uint16_t	map_size;
 	if ( ( map_size & 0x3 ) != 0 )
 		map_size += 2;
 
-	// Create a generic netflow v1 extension map
+	// Create a netflow v1 extension map
 	v1_extension_info.map = (extension_map_t *)malloc((size_t)map_size);
 	if ( !v1_extension_info.map ) {
 		LogError("Process_v1: malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
@@ -203,7 +203,7 @@ char ipstr[IP_STRING_LEN];
 	(*e)->padding_errors	= 0;
 	(*e)->sampler			= NULL;
 
-	// copy the v1 generic extension map
+	// copy the v1 extension map
 	(*e)->extension_map		= (extension_map_t *)malloc(v1_extension_info.map->size);
 	if ( !(*e)->extension_map ) {
 		LogError("Process_v1: malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
diff --git a/bin/netflow_v5_v7.c b/bin/netflow_v5_v7.c
index ff88aef..8cb545a 100644
--- a/bin/netflow_v5_v7.c
+++ b/bin/netflow_v5_v7.c
@@ -83,10 +83,10 @@ static uint16_t v5_full_mapp[] = { EX_IO_SNMP_2, EX_AS_2, EX_MULIPLE, EX_NEXT_HO
 #define V5_BLOCK_DATA_SIZE (sizeof(ipv4_block_t) - sizeof(uint32_t) + 2 * sizeof(uint64_t))
 
 typedef struct exporter_v5_s {
-	// identical to generic_exporter_t
+	// identical to exporter_t
 	struct exporter_v5_s *next;
 
-	// generic exporter information
+	// exporter information
 	exporter_info_record_t info;
 
 	uint64_t	packets;			// number of packets sent by this exporter
@@ -94,9 +94,9 @@ typedef struct exporter_v5_s {
 	uint32_t	sequence_failure;	// number of sequence failues
 	uint32_t	padding_errors;		// number of sequence failues
 
-	// generic sampler
-	generic_sampler_t		*sampler;
-	// end of generic_exporter_t
+	// sampler
+	sampler_t		*sampler;
+	// end of exporter_t
 
 	// sequence vars
 	int64_t	 last_sequence;
@@ -153,7 +153,7 @@ uint16_t	map_size;
 	if ( ( map_size & 0x3 ) != 0 )
 		map_size += 2;
 
-	// Create a generic v5 extension map
+	// Create a v5 extension map
 	v5_extension_info.map = (extension_map_t *)malloc((size_t)map_size);
 	if ( !v5_extension_info.map ) {
 		LogError("Process_v5: malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
@@ -184,7 +184,7 @@ uint16_t	map_size;
 
 static inline exporter_v5_t *GetExporter(FlowSource_t *fs, netflow_v5_header_t *header) {
 exporter_v5_t **e = (exporter_v5_t **)&(fs->exporter_data);
-generic_sampler_t *sampler;
+sampler_t *sampler;
 uint16_t	engine_tag = ntohs(header->engine_tag);
 uint16_t	version    = ntohs(header->version);
 #define IP_STRING_LEN   40
@@ -218,7 +218,7 @@ char ipstr[IP_STRING_LEN];
 	(*e)->flows				= 0;
 	(*e)->first	 			= 1;
 
-	sampler = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+	sampler = (sampler_t *)malloc(sizeof(sampler_t));
 	if ( !sampler ) {
 		LogError("Process_v5: malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
 		return NULL;
@@ -236,7 +236,7 @@ char ipstr[IP_STRING_LEN];
 	if ( sampler->info.interval == 0 )
 		sampler->info.interval = default_sampling;
 
-	// copy the v5 generic extension map
+	// copy the v5 extension map
 	(*e)->extension_map		= (extension_map_t *)malloc(v5_extension_info.map->size);
 	if ( !(*e)->extension_map ) {
 		LogError("Process_v5: malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror (errno));
diff --git a/bin/netflow_v9.c b/bin/netflow_v9.c
index 87bad7f..354776e 100644
--- a/bin/netflow_v9.c
+++ b/bin/netflow_v9.c
@@ -1,7 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -58,13 +56,6 @@
 #include "exporter.h"
 #include "netflow_v9.h"
 
-#ifndef DEVEL
-#   define dbg_printf(...) /* printf(__VA_ARGS__) */
-#else
-#   define dbg_printf(...) printf(__VA_ARGS__)
-#endif
-
-// a few handy macros
 #define GET_FLOWSET_ID(p) 	  (Get_val16(p))
 #define GET_FLOWSET_LENGTH(p) (Get_val16((void *)((p) + 2)))
 
@@ -158,11 +149,11 @@ typedef struct input_translation_s {
 
 } input_translation_t;
 
-typedef struct exporter_v9_domain_s {
-	// identical to generic_exporter_t
-	struct exporter_v9_domain_s	*next;
+typedef struct exporter_domain_s {
+	// identical to exporter_t
+	struct exporter_domain_s *next;
 
-	// generic exporter information
+	// exporter information
 	exporter_info_record_t info;
 
 	uint64_t	packets;			// number of packets sent by this exporter
@@ -170,9 +161,9 @@ typedef struct exporter_v9_domain_s {
 	uint32_t	sequence_failure;	// number of sequence failues
 	uint32_t	padding_errors;		// number of padding errors
 
-	// generic sampler
-	generic_sampler_t		*sampler;
-	// end of generic_exporter_t
+	// sampler
+	sampler_t		*sampler;
+	samplerOption_t *samplerOption; // sampler options table info
 
 	// exporter parameters
 	uint64_t	boot_time;
@@ -192,7 +183,7 @@ typedef struct exporter_v9_domain_s {
 	// translation table
 	input_translation_t	*input_translation_table; 
 	input_translation_t *current_table;
-} exporter_v9_domain_t;
+} exporterDomain_t;
 
 
 /* module limited globals */
@@ -274,6 +265,8 @@ static struct v9_element_map_s {
 
 	{ NF9_SRC_VLAN, 			 "src vlan",		_2bytes,  _2bytes, move16, zero16, EX_VLAN}, 
 	{ NF9_DST_VLAN, 			 "dst vlan",		_2bytes,  _2bytes, move16, zero16, EX_VLAN},
+	{ NF9_dot1qVlanId,		 	 "src vlan",		_2bytes,  _2bytes, move16, zero16, EX_VLAN}, 
+	{ NF9_postDot1qVlanId,		 "dst vlan",		_2bytes,  _2bytes, move16, zero16, EX_VLAN},
 
 	{ NF9_DIRECTION, 	 	 	 "direction",		_1byte,   _1byte,  move8, zero8, EX_MULIPLE },
 
@@ -398,29 +391,27 @@ static uint32_t				Max_num_v9_tags;
 static uint32_t				processed_records;
 
 /* local function prototypes */
-static void InsertSamplerOffset( FlowSource_t *fs, uint16_t id, uint16_t offset_sampler_id, uint16_t sampler_id_length, 
-	uint16_t offset_sampler_mode, uint16_t offset_sampler_interval);
+static int HasOptionTable(exporterDomain_t *exporter, uint16_t tableID );
 
-static void InsertStdSamplerOffset( FlowSource_t *fs, uint16_t id, uint16_t offset_std_sampler_interval, 
-	uint16_t offset_std_sampler_algorithm);
+static void InsertSamplerOption(exporterDomain_t *exporter, samplerOption_t *samplerOption);
 
-static void InsertSampler( FlowSource_t *fs, exporter_v9_domain_t *exporter, int32_t id, uint16_t mode, uint32_t interval);
+static void InsertSampler( FlowSource_t *fs, exporterDomain_t *exporter, int32_t id, uint16_t mode, uint32_t interval);
 
-static inline void Process_v9_templates(exporter_v9_domain_t *exporter, void *template_flowset, FlowSource_t *fs);
+static inline void Process_v9_templates(exporterDomain_t *exporter, void *template_flowset, FlowSource_t *fs);
 
-static inline void Process_v9_option_templates(exporter_v9_domain_t *exporter, void *option_template_flowset, FlowSource_t *fs);
+static inline void Process_v9_option_templates(exporterDomain_t *exporter, void *option_template_flowset, FlowSource_t *fs);
 
-static inline void Process_v9_data(exporter_v9_domain_t *exporter, void *data_flowset, FlowSource_t *fs, input_translation_t *table );
+static inline void Process_v9_data(exporterDomain_t *exporter, void *data_flowset, FlowSource_t *fs, input_translation_t *table );
 
-static inline void Process_v9_option_data(exporter_v9_domain_t *exporter, void *data_flowset, FlowSource_t *fs);
+static inline void Process_v9_option_data(exporterDomain_t *exporter, void *data_flowset, FlowSource_t *fs);
 
-static inline exporter_v9_domain_t *GetExporter(FlowSource_t *fs, uint32_t exporter_id);
+static inline exporterDomain_t *GetExporter(FlowSource_t *fs, uint32_t exporter_id);
 
-static inline input_translation_t *GetTranslationTable(exporter_v9_domain_t *exporter, uint16_t id);
+static inline input_translation_t *GetTranslationTable(exporterDomain_t *exporter, uint16_t id);
 
-static input_translation_t *setup_translation_table (exporter_v9_domain_t *exporter, uint16_t id, uint16_t input_record_size);
+static input_translation_t *setup_translation_table (exporterDomain_t *exporter, uint16_t id, uint16_t input_record_size);
 
-static input_translation_t *add_translation_table(exporter_v9_domain_t *exporter, uint16_t id);
+static input_translation_t *add_translation_table(exporterDomain_t *exporter, uint16_t id);
 
 static output_template_t *GetOutputTemplate(uint32_t flags, extension_map_t *extension_map);
 
@@ -471,10 +462,23 @@ int i;
 	
 } // End of Init_v9
 
-static inline exporter_v9_domain_t *GetExporter(FlowSource_t *fs, uint32_t exporter_id) {
+static int HasOptionTable(exporterDomain_t *exporter, uint16_t tableID ) {
+samplerOption_t *s;
+
+	s = exporter->samplerOption;
+	while ( s && s->tableID != tableID )
+		s = s->next;
+
+	dbg_printf("Has option table: %s\n", s == NULL ? "not found" : "found");
+
+	return s != NULL;
+
+} // End of HasOptionTable
+
+static inline exporterDomain_t *GetExporter(FlowSource_t *fs, uint32_t exporter_id) {
 #define IP_STRING_LEN   40
 char ipstr[IP_STRING_LEN];
-exporter_v9_domain_t **e = (exporter_v9_domain_t **)&(fs->exporter_data);
+exporterDomain_t **e = (exporterDomain_t **)&(fs->exporter_data);
 
 	while ( *e ) {
 		if ( (*e)->info.id == exporter_id && (*e)->info.version == 9 && 
@@ -496,12 +500,12 @@ exporter_v9_domain_t **e = (exporter_v9_domain_t **)&(fs->exporter_data);
 	}
 
 	// nothing found
-	*e = (exporter_v9_domain_t *)malloc(sizeof(exporter_v9_domain_t));
+	*e = (exporterDomain_t *)malloc(sizeof(exporterDomain_t));
 	if ( !(*e)) {
 		LogError( "Process_v9: Panic! malloc() %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 		return NULL;
 	}
-	memset((void *)(*e), 0, sizeof(exporter_v9_domain_t));
+	memset((void *)(*e), 0, sizeof(exporterDomain_t));
 	(*e)->info.header.type  = ExporterInfoRecordType;
 	(*e)->info.header.size  = sizeof(exporter_info_record_t);
 	(*e)->info.version 		= 9;
@@ -561,7 +565,7 @@ int	index;
 
 } // End of MapElement
 
-static inline input_translation_t *GetTranslationTable(exporter_v9_domain_t *exporter, uint16_t id) {
+static inline input_translation_t *GetTranslationTable(exporterDomain_t *exporter, uint16_t id) {
 input_translation_t *table;
 
 	if ( exporter->current_table && ( exporter->current_table->id == id ) )
@@ -585,7 +589,7 @@ input_translation_t *table;
 
 } // End of GetTranslationTable
 
-static input_translation_t *add_translation_table(exporter_v9_domain_t *exporter, uint16_t id) {
+static input_translation_t *add_translation_table(exporterDomain_t *exporter, uint16_t id) {
 input_translation_t **table;
 
 	table = &(exporter->input_translation_table);
@@ -652,7 +656,7 @@ uint32_t index = cache.lookup_info[Type].index;
 } // End of PushSequence
 
 
-static input_translation_t *setup_translation_table (exporter_v9_domain_t *exporter, uint16_t id, uint16_t input_record_size) {
+static input_translation_t *setup_translation_table (exporterDomain_t *exporter, uint16_t id, uint16_t input_record_size) {
 input_translation_t *table;
 extension_map_t 	*extension_map;
 uint32_t			i, ipv6, offset, next_extension;
@@ -868,8 +872,13 @@ size_t				size_required;
 				SetFlag(table->flags, FLAG_IPV6_NHB);
 				break;
 			case EX_VLAN:
-				PushSequence( table, NF9_SRC_VLAN, &offset, NULL, 0);
-				PushSequence( table, NF9_DST_VLAN, &offset, NULL, 0);
+				if ( cache.lookup_info[NF9_dot1qVlanId].found ) {
+					PushSequence( table, NF9_dot1qVlanId, &offset, NULL, 0);
+					PushSequence( table, NF9_postDot1qVlanId, &offset, NULL, 0);
+				} else {
+					PushSequence( table, NF9_SRC_VLAN, &offset, NULL, 0);
+					PushSequence( table, NF9_DST_VLAN, &offset, NULL, 0);
+				}
 				break;
 			case EX_OUT_PKG_4:
 				PushSequence( table, NF9_OUT_PKTS, &offset, &table->out_packets, 0);
@@ -1150,77 +1159,47 @@ size_t				size_required;
 
 } // End of setup_translation_table
 
-static void InsertSamplerOffset( FlowSource_t *fs, uint16_t id, uint16_t offset_sampler_id, uint16_t sampler_id_length,
-	uint16_t offset_sampler_mode, uint16_t offset_sampler_interval) {
-option_offset_t	**t;
+static void InsertSamplerOption(exporterDomain_t *exporter, samplerOption_t *samplerOption) {
+samplerOption_t *s, *parent;
 
-	t = &(fs->option_offset_table);
-	while ( *t ) {
-		if ( (*t)->id == id ) { // table already known to us - update data
-			dbg_printf("Found existing sampling info in template %i\n", id);
+	parent = NULL;
+	s = exporter->samplerOption;
+	while (s) {
+		if ( s->tableID == samplerOption->tableID ) { // table already known to us - update data
+			dbg_printf("Found existing sampling info in template %i\n", samplerOption->tableID);
 			break;
 		}
-	
-		t = &((*t)->next);
+		parent = s;
+		s = s->next;
 	}
 
-	if ( *t == NULL ) {	// new table
-		dbg_printf("Allocate new sampling info from template %i\n", id);
-		*t = (option_offset_t *)calloc(1, sizeof(option_offset_t));
-		if ( !*t ) {
-			fprintf(stderr, "malloc() allocation error: %s\n", strerror(errno));
-			return ;
-		} 
-		dbg_printf("Process_v9: New sampler: ID %i, mode: %i, interval: %i\n", 
-			offset_sampler_id, offset_sampler_mode, offset_sampler_interval);
-	}	// else existing table
-
-	dbg_printf("Insert/Update sampling info from template %i\n", id);
-	SetFlag((*t)->flags, HAS_SAMPLER_DATA);
-	(*t)->id 				= id;
-	(*t)->offset_id			= offset_sampler_id;
-	(*t)->sampler_id_length = sampler_id_length;
-	(*t)->offset_mode		= offset_sampler_mode;
-	(*t)->offset_interval	= offset_sampler_interval;
-
-} // End of InsertSamplerOffset
-
-static void InsertStdSamplerOffset( FlowSource_t *fs, uint16_t id, uint16_t offset_std_sampler_interval, uint16_t offset_std_sampler_algorithm) {
-option_offset_t	**t;
-
-	t = &(fs->option_offset_table);
-	while ( *t ) {
-		if ( (*t)->id == id ) { // table already known to us - update data
-			dbg_printf("Found existing std sampling info in template %i\n", id);
-			break;
+	if ( s != NULL ) { // existing entry
+		// replace existing table
+		dbg_printf("Replace existing sampler table ID %i\n", samplerOption->tableID);
+		if ( parent ) {
+			parent->next = samplerOption;
+		} else {
+			exporter->samplerOption = samplerOption;
 		}
-	
-		t = &((*t)->next);
+		samplerOption->next = s->next;
+		free(s);
+		s = NULL;
+	} else { // new entry
+		dbg_printf("New sampling table ID %i\n", samplerOption->tableID);
+		// push new sampling table
+		samplerOption->next = exporter->samplerOption;
+		exporter->samplerOption = samplerOption;
 	}
 
-	if ( *t == NULL ) {	// new table
-		dbg_printf("Allocate new std sampling info from template %i\n", id);
-		*t = (option_offset_t *)calloc(1, sizeof(option_offset_t));
-		if ( !*t ) {
-			fprintf(stderr, "malloc() allocation error: %s\n", strerror(errno));
-			return ;
-		} 
-		LogError( "Process_v9: New std sampler: interval: %i, algorithm: %i", 
-			offset_std_sampler_interval, offset_std_sampler_algorithm);
-	}	// else existing table
-
-	dbg_printf("Insert/Update sampling info from template %i\n", id);
-	SetFlag((*t)->flags, HAS_STD_SAMPLER_DATA);
-	(*t)->id 				= id;
-	(*t)->offset_id			= 0;
-	(*t)->offset_mode		= 0;
-	(*t)->offset_interval	= 0;
-	(*t)->offset_std_sampler_interval	= offset_std_sampler_interval;
-	(*t)->offset_std_sampler_algorithm	= offset_std_sampler_algorithm;
-	
-} // End of InsertStdSamplerOffset
+	dbg_printf("Update/Insert sampler table id: %u flags: 0x%x - sampler ID: %u/%u, mode: %u/%u, interval: %u/%u\n",
+		samplerOption->tableID, samplerOption->flags, 
+		samplerOption->id.offset, samplerOption->id.length,
+		samplerOption->mode.offset, samplerOption->mode.length,
+		samplerOption->interval.offset, samplerOption->interval.length);
+
+} // End of InsertSamplerOption
 
-static inline void Process_v9_templates(exporter_v9_domain_t *exporter, void *template_flowset, FlowSource_t *fs) {
+static inline void Process_v9_templates(exporterDomain_t *exporter, void *template_flowset, FlowSource_t *fs) {
 void				*template;
 input_translation_t *translation_table;
 uint16_t	id, count, Offset;
@@ -1245,7 +1224,7 @@ int			i;
 			if ( v9_element_map[i].id == v9_element_map[i-1].id )
 				continue;
 			cache.lookup_info[Type].index  = i;
-			// other elements cleard be memset
+			// other elements cleared by memset
 		}
 
 		id 	  = GET_TEMPLATE_ID(template);
@@ -1349,17 +1328,15 @@ int			i;
 
 } // End of Process_v9_templates
 
-static inline void Process_v9_option_templates(exporter_v9_domain_t *exporter, void *option_template_flowset, FlowSource_t *fs) {
+static inline void Process_v9_option_templates(exporterDomain_t *exporter, void *option_template_flowset, FlowSource_t *fs) {
 uint8_t		*option_template, *p;
-uint32_t	size_left, nr_scopes, nr_options, i;
-uint16_t	id, scope_length, option_length, offset, sampler_id_length;
-uint16_t	offset_sampler_id, offset_sampler_mode, offset_sampler_interval, found_sampler;
-uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sampling;
+uint32_t	size_left, nr_scopes, nr_options;
+uint16_t	tableID, scope_length, option_length;
+samplerOption_t *samplerOption;
 
-	i = 0;	// keep compiler happy
 	size_left 		= GET_FLOWSET_LENGTH(option_template_flowset) - 4; // -4 for flowset header -> id and length
 	option_template = option_template_flowset + 4;
-	id 	  			= GET_OPTION_TEMPLATE_ID(option_template); 
+	tableID			= GET_OPTION_TEMPLATE_ID(option_template); 
 	scope_length 	= GET_OPTION_TEMPLATE_OPTION_SCOPE_LENGTH(option_template);
 	option_length 	= GET_OPTION_TEMPLATE_OPTION_LENGTH(option_template);
 
@@ -1384,19 +1361,20 @@ uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sa
 	nr_scopes  = scope_length >> 2;
 	nr_options = option_length >> 2;
 
-	dbg_printf("\n[%u] Option Template ID: %u\n", exporter->info.id, id);
+	dbg_printf("\n[%u] Option Template ID: %u\n", exporter->info.id, tableID);
 	dbg_printf("Scope length: %u Option length: %u\n", scope_length, option_length);
 
-	sampler_id_length			 = 0;
-	offset_sampler_id 			 = 0;
-	offset_sampler_mode 		 = 0;
-	offset_sampler_interval 	 = 0;
-	offset_std_sampler_interval  = 0;
-	offset_std_sampler_algorithm = 0;
-	found_sampler				 = 0;
-	found_std_sampling			 = 0;
-	offset = 0;
+	samplerOption = (samplerOption_t *)malloc(sizeof(samplerOption_t));
+	if ( !samplerOption ) {
+		LogError("Error malloc(): %s in %s:%d", strerror (errno), __FILE__, __LINE__);
+		return;
+	}
+	memset((void *)samplerOption, 0, sizeof(samplerOption_t));
+
+	samplerOption->tableID = tableID;
 
+	int i;
+	uint16_t offset = 0;
 	p = option_template + 6;	// start of length/type data
 	for ( i=0; i<nr_scopes; i++ ) {
 #ifdef DEVEL
@@ -1435,77 +1413,60 @@ uint16_t	offset_std_sampler_interval, offset_std_sampler_algorithm, found_std_sa
 	for ( ; i<(nr_scopes+nr_options); i++ ) {
 		uint16_t type 	= Get_val16(p); p = p + 2;
 		uint16_t length = Get_val16(p); p = p + 2;
-		uint32_t index  = cache.lookup_info[type].index;
 		dbg_printf("Option field Type: %u, length %u\n", type, length);
-		if ( !index ) {
-			dbg_printf("Unsupported: Option field Type: %u, length %u\n", type, length);
-			offset += length;
-			continue;
-		}
-		while ( index && v9_element_map[index].id == type ) {
-			if ( length == v9_element_map[index].length ) {
-				break;
-			}
-			index++;
-		}
 
-		if ( index && v9_element_map[index].length != length ) {
-			LogError("Process_v9: Option field Type: %u, length %u not supported\n", type, length);
-			dbg_printf("Process_v9: Option field Type: %u, length %u not supported\n", type, length);
-			offset += length;
-			continue;
-		}
 		switch (type) {
 			// general sampling
-			case NF9_SAMPLING_INTERVAL:
-				offset_std_sampler_interval = offset;
-				found_std_sampling++;
+			case NF9_SAMPLING_INTERVAL:	// #34
+				samplerOption->interval.length = length;
+				samplerOption->interval.offset = offset;
+				SetFlag(samplerOption->flags, STDSAMPLING34);
 				break;
-			case NF9_SAMPLING_ALGORITHM:
-				offset_std_sampler_algorithm = offset;
-				found_std_sampling++;
+			case NF9_SAMPLING_ALGORITHM: // #35
+				samplerOption->mode.length = length;
+				samplerOption->mode.offset = offset;
+				SetFlag(samplerOption->flags, STDSAMPLING35);
 				break;
 
 			// individual samplers
-			case NF9_FLOW_SAMPLER_ID:	// depricated
-			case NF_SELECTOR_ID:
-				offset_sampler_id = offset;
-				sampler_id_length = length;
-				found_sampler++;
-				break;
-			case FLOW_SAMPLER_MODE:		// 	// depricated
-			case NF_SELECTOR_ALGORITHM:
-				offset_sampler_mode = offset;
-				found_sampler++;
-				break;
-			case NF9_FLOW_SAMPLER_RANDOM_INTERVAL: // depricated 
-			case NF_SAMPLING_INTERVAL:
-				offset_sampler_interval = offset;
-				offset_std_sampler_interval = offset;
-				found_sampler++;
-				found_std_sampling++;
+			case NF9_FLOW_SAMPLER_ID:	// #48 depricated - fall through
+			case NF_SELECTOR_ID:		// #302
+				samplerOption->id.length = length;
+				samplerOption->id.offset = offset;
+				SetFlag(samplerOption->flags, SAMPLER302);
+				break;
+			case FLOW_SAMPLER_MODE:		// #49 depricated - fall through
+			case NF_SELECTOR_ALGORITHM: // #304
+				samplerOption->mode.length = length;
+				samplerOption->mode.offset = offset;
+				SetFlag(samplerOption->flags, SAMPLER304);
+				break;
+			case NF9_FLOW_SAMPLER_RANDOM_INTERVAL: // #50 depricated - fall through
+			case NF_SAMPLING_INTERVAL:			   // #305
+				samplerOption->interval.length = length;
+				samplerOption->interval.offset = offset;
+				SetFlag(samplerOption->flags, SAMPLER305);
 				break;
 		}
 		offset += length;
 	}
 
-	if ( found_sampler == 3 ) { // need all three tags
-		dbg_printf("[%u] Sampling information found\n", exporter->info.id);
-		InsertSamplerOffset(fs, id, offset_sampler_id, sampler_id_length, offset_sampler_mode, offset_sampler_interval);
-	} else if ( found_std_sampling == 2 ) { // need all two tags
-		dbg_printf("[%u] Std sampling information found. offset intervall: %u, offset algo: %u\n", 
-			exporter->info.id, offset_std_sampler_interval, offset_std_sampler_algorithm);
-		InsertStdSamplerOffset(fs, id, offset_std_sampler_interval, offset_std_sampler_algorithm);
+	if ( (samplerOption->flags & SAMPLERMASK ) == SAMPLERFLAGS) {
+		dbg_printf("[%u] Sampler information found\n", exporter->info.id);
+		InsertSamplerOption(exporter, samplerOption);
+	} else if ( (samplerOption->flags & STDMASK ) == STDFLAGS) {
+		dbg_printf("[%u] Std sampling information found\n", exporter->info.id);
+		InsertSamplerOption(exporter, samplerOption);
 	} else {
+		free(samplerOption);
 		dbg_printf("[%u] No Sampling information found\n", exporter->info.id);
 	}
-	dbg_printf("\n");
 	processed_records++;
+	dbg_printf("\n");
 
 } // End of Process_v9_option_templates
 
-
-static inline void Process_v9_data(exporter_v9_domain_t *exporter, void *data_flowset, FlowSource_t *fs, input_translation_t *table ){
+static inline void Process_v9_data(exporterDomain_t *exporter, void *data_flowset, FlowSource_t *fs, input_translation_t *table ){
 uint64_t			start_time, end_time, sampling_rate;
 uint32_t			size_left;
 uint8_t				*in, *out;
@@ -1526,7 +1487,7 @@ char				*string;
 
 	// Check if sampling is announced
 	if ( table->sampler_offset && exporter->sampler  ) {
-		generic_sampler_t *sampler = exporter->sampler;
+		sampler_t *sampler = exporter->sampler;
 		uint32_t sampler_id;
 		if ( table->sampler_size == 2 ) {
 			sampler_id = Get_val16((void *)&in[table->sampler_offset]);
@@ -1550,7 +1511,7 @@ char				*string;
 		}
 
 	} else {
-		generic_sampler_t *sampler = exporter->sampler;
+		sampler_t *sampler = exporter->sampler;
 		while ( sampler && sampler->info.id != -1 ) 
 			sampler = sampler->next;
 
@@ -1985,18 +1946,18 @@ char				*string;
 
 } // End of Process_v9_data
 
-static inline void 	Process_v9_option_data(exporter_v9_domain_t *exporter, void *data_flowset, FlowSource_t *fs) {
-option_offset_t *offset_table;
-uint32_t	id;
+static inline void 	Process_v9_option_data(exporterDomain_t *exporter, void *data_flowset, FlowSource_t *fs) {
+samplerOption_t *samplerOption;
+uint32_t	tableID;
 uint8_t		*in;
 
-	id 	= GET_FLOWSET_ID(data_flowset);
+	tableID	= GET_FLOWSET_ID(data_flowset);
 
-	offset_table = fs->option_offset_table;
-	while ( offset_table && offset_table->id != id )
-		offset_table = offset_table->next;
+	samplerOption = exporter->samplerOption;
+	while ( samplerOption && samplerOption->tableID != tableID )
+		samplerOption = samplerOption->next;
 
-	if ( !offset_table ) {
+	if ( !samplerOption ) {
 		// should never happen - catch it anyway
 		LogError( "Process_v9: Panic! - No Offset table found! : %s line %d", __FILE__, __LINE__);
 		return;
@@ -2010,17 +1971,14 @@ uint8_t		*in;
 	// map input buffer as a byte array
 	in	  = (uint8_t *)(data_flowset + 4);	// skip flowset header
 
-	if ( TestFlag(offset_table->flags, HAS_SAMPLER_DATA) ) {
+	if ( (samplerOption->flags & SAMPLERMASK ) == SAMPLERFLAGS) {
 		int32_t  id;
 		uint16_t mode;
 		uint32_t interval;
-		if (offset_table->sampler_id_length == 2) {
-			id = Get_val16((void *)&in[offset_table->offset_id]);
-		} else {
-			id = in[offset_table->offset_id];
-		}
-		mode 	 = in[offset_table->offset_mode];
-		interval = Get_val32((void *)&in[offset_table->offset_interval]); 
+
+		id	 = Get_val(in, samplerOption->id.offset, samplerOption->id.length);
+		mode = Get_val(in, samplerOption->mode.offset, samplerOption->mode.length);
+		interval = Get_val(in, samplerOption->interval.offset, samplerOption->interval.length);
 	
 		dbg_printf("Extracted Sampler data:\n");
 		dbg_printf("Sampler ID      : %u\n", id);
@@ -2030,10 +1988,14 @@ uint8_t		*in;
 		InsertSampler(fs, exporter, id, mode, interval);
 	}
 
-	if ( TestFlag(offset_table->flags, HAS_STD_SAMPLER_DATA) ) {
-		int32_t  id 	  = -1;
-		uint16_t mode 	  = in[offset_table->offset_std_sampler_algorithm];
-		uint32_t interval = Get_val32((void *)&in[offset_table->offset_std_sampler_interval]);
+	if ( (samplerOption->flags & STDMASK ) == STDFLAGS) {
+		int32_t  id;
+		uint16_t mode;
+		uint32_t interval;
+
+		id		 = -1;
+		mode	 = Get_val(in, samplerOption->mode.offset, samplerOption->mode.length);
+		interval = Get_val(in, samplerOption->interval.offset, samplerOption->interval.length);
 
 		InsertSampler(fs, exporter, id, mode, interval);
 
@@ -2042,8 +2004,6 @@ uint8_t		*in;
 		dbg_printf("Sampler algorithm: %u\n", mode);
 		dbg_printf("Sampler interval : %u\n", interval);
 
-		LogInfo( "Set std sampler: algorithm: %u, interval: %u\n", 
-				mode, interval);
 		dbg_printf("Set std sampler: algorithm: %u, interval: %u\n", 
 				mode, interval);
 	}
@@ -2052,7 +2012,7 @@ uint8_t		*in;
 } // End of Process_v9_option_data
 
 void Process_v9(void *in_buff, ssize_t in_buff_cnt, FlowSource_t *fs) {
-exporter_v9_domain_t	*exporter;
+exporterDomain_t	*exporter;
 void				*flowset_header;
 netflow_v9_header_t	*v9_header;
 int64_t 			distance;
@@ -2191,7 +2151,7 @@ static int pkg_num = 0;
 					table = GetTranslationTable(exporter, flowset_id);
 					if ( table ) {
 						Process_v9_data(exporter, flowset_header, fs, table);
-					} else if ( HasOptionTable(fs, flowset_id) ) {
+					} else if ( HasOptionTable(exporter, flowset_id) ) {
 						Process_v9_option_data(exporter, flowset_header, fs);
 					} else {
 						// maybe a flowset with option data
@@ -3026,13 +2986,13 @@ time_t		now = time(NULL);
 } // End of Add_v9_output_record
 
 
-static void InsertSampler( FlowSource_t *fs, exporter_v9_domain_t *exporter, int32_t id, uint16_t mode, uint32_t interval) {
-generic_sampler_t *sampler;
+static void InsertSampler( FlowSource_t *fs, exporterDomain_t *exporter, int32_t id, uint16_t mode, uint32_t interval) {
+sampler_t *sampler;
 
 	dbg_printf("[%u] Insert Sampler: Exporter is 0x%llu\n", exporter->info.id, (long long unsigned)exporter);
 	if ( !exporter->sampler ) {
 		// no samplers so far 
-		sampler = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+		sampler = (sampler_t *)malloc(sizeof(sampler_t));
 		if ( !sampler ) {
 			LogError( "Process_v9: Panic! malloc(): %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 			return;
@@ -3079,7 +3039,7 @@ generic_sampler_t *sampler;
 			// test for end of chain
 			if ( sampler->next == NULL ) {
 				// end of sampler chain - insert new sampler
-				sampler->next = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+				sampler->next = (sampler_t *)malloc(sizeof(sampler_t));
 				if ( !sampler->next ) {
 					LogError( "Process_v9: Panic! malloc(): %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 					return;
diff --git a/bin/netflow_v9.h b/bin/netflow_v9.h
index 61be692..0e3d366 100644
--- a/bin/netflow_v9.h
+++ b/bin/netflow_v9.h
@@ -257,6 +257,8 @@ typedef struct common_header_s {
 
 #define NF9_BGP_ADJ_NEXT_AS 	128
 #define NF9_BGP_ADJ_PREV_AS 	129
+#define NF9_dot1qVlanId			243
+#define NF9_postDot1qVlanId		254
 
 // CISCO ASA NSEL extension - Network Security Event Logging
 #define NF_F_FLOW_BYTES				   85
@@ -299,6 +301,7 @@ typedef struct common_header_s {
 #define NF_N_NAT_EVENT				230
 #define NF_N_INGRESS_VRFID			234
 #define NF_N_EGRESS_VRFID			235
+
 #define NF_F_XLATE_PORT_BLOCK_START 361
 #define NF_F_XLATE_PORT_BLOCK_END   362
 #define NF_F_XLATE_PORT_BLOCK_STEP  363
diff --git a/bin/nf_common.c b/bin/nf_common.c
index 2a8290c..438d325 100644
--- a/bin/nf_common.c
+++ b/bin/nf_common.c
@@ -686,41 +686,40 @@ extension_map_t	*extension_map = r->map_ref;
 		uint64_t snet[2];
 		uint64_t dnet[2];
 
-		// remember IPs for network 
-		snet[0] = r->V6.srcaddr[0];
-		snet[1] = r->V6.srcaddr[1];
-		dnet[0] = r->V6.dstaddr[0];
-		dnet[1] = r->V6.dstaddr[1];
-		r->V6.srcaddr[0] = htonll(r->V6.srcaddr[0]);
-		r->V6.srcaddr[1] = htonll(r->V6.srcaddr[1]);
-		r->V6.dstaddr[0] = htonll(r->V6.dstaddr[0]);
-		r->V6.dstaddr[1] = htonll(r->V6.dstaddr[1]);
-		inet_ntop(AF_INET6, r->V6.srcaddr, as, sizeof(as));
-		inet_ntop(AF_INET6, r->V6.dstaddr, ds, sizeof(ds));
+		snet[0] = htonll(r->V6.srcaddr[0]);
+		snet[1] = htonll(r->V6.srcaddr[1]);
+		dnet[0] = htonll(r->V6.dstaddr[0]);
+		dnet[1] = htonll(r->V6.dstaddr[1]);
+		inet_ntop(AF_INET6, snet, as, sizeof(as));
+		inet_ntop(AF_INET6, dnet, ds, sizeof(ds));
 		if ( ! long_v6 ) {
 			condense_v6(as);
 			condense_v6(ds);
 		}
+
 		if ( r->src_mask || r->dst_mask) {
-			if ( r->src_mask > 64 )
-				snet[1] &= 0xffffffffffffffffLL << ( 128 - r->src_mask );
-			else {
-				snet[1] &= 0xffffffffffffffffLL << ( 64 - r->src_mask );
+			if ( r->src_mask >= 64 ) {
+				snet[0] = r->V6.srcaddr[0] & (0xffffffffffffffffLL << (r->src_mask - 64));
 				snet[1] = 0;
+			} else {
+				snet[0] = r->V6.srcaddr[0];
+				snet[1] = r->V6.srcaddr[1] & (0xffffffffffffffffLL << r->src_mask);
 			}
 			snet[0] = htonll(snet[0]);
 			snet[1] = htonll(snet[1]);
-			inet_ntop(AF_INET6, &snet, s_snet, sizeof(s_snet));
+			inet_ntop(AF_INET6, snet, s_snet, sizeof(s_snet));
 
-			if ( r->dst_mask > 64 )
-				dnet[1] &= 0xffffffffffffffffLL << ( 128 - r->dst_mask );
-			else {
-				dnet[1] &= 0xffffffffffffffffLL << ( 64 - r->dst_mask );
+			if ( r->dst_mask >= 64 ) {
+				dnet[0] = r->V6.dstaddr[0] & (0xffffffffffffffffLL << (r->dst_mask - 64));
 				dnet[1] = 0;
+			} else {
+				dnet[0] = r->V6.dstaddr[0];
+				dnet[1] = r->V6.dstaddr[1] & (0xffffffffffffffffLL << r->dst_mask);
 			}
 			dnet[0] = htonll(dnet[0]);
 			dnet[1] = htonll(dnet[1]);
-			inet_ntop(AF_INET6, &dnet, s_dnet, sizeof(s_dnet));
+			inet_ntop(AF_INET6, dnet, s_dnet, sizeof(s_dnet));
+
 			if ( ! long_v6 ) {
 				condense_v6(s_snet);
 				condense_v6(s_dnet);
@@ -1253,38 +1252,35 @@ master_record_t *r = (master_record_t *)record;
 		uint64_t snet[2];
 		uint64_t dnet[2];
 
-		// remember IPs for network 
-		snet[0] = r->V6.srcaddr[0];
-		snet[1] = r->V6.srcaddr[1];
-		dnet[0] = r->V6.dstaddr[0];
-		dnet[1] = r->V6.dstaddr[1];
-		r->V6.srcaddr[0] = htonll(r->V6.srcaddr[0]);
-		r->V6.srcaddr[1] = htonll(r->V6.srcaddr[1]);
-		r->V6.dstaddr[0] = htonll(r->V6.dstaddr[0]);
-		r->V6.dstaddr[1] = htonll(r->V6.dstaddr[1]);
-		inet_ntop(AF_INET6, r->V6.srcaddr, as, sizeof(as));
-		inet_ntop(AF_INET6, r->V6.dstaddr, ds, sizeof(ds));
+		snet[0] = htonll(r->V6.srcaddr[0]);
+		snet[1] = htonll(r->V6.srcaddr[1]);
+		dnet[0] = htonll(r->V6.dstaddr[0]);
+		dnet[1] = htonll(r->V6.dstaddr[1]);
+		inet_ntop(AF_INET6, snet, as, sizeof(as));
+		inet_ntop(AF_INET6, dnet, ds, sizeof(ds));
 
 		if ( r->src_mask || r->dst_mask) {
-			if ( r->src_mask > 64 )
-				snet[1] &= 0xffffffffffffffffLL << ( 128 - r->src_mask );
-			else {
-				snet[1] &= 0xffffffffffffffffLL << ( 64 - r->src_mask );
+			if ( r->src_mask >= 64 ) {
+				snet[0] = r->V6.srcaddr[0] & (0xffffffffffffffffLL << (r->src_mask - 64));
 				snet[1] = 0;
+			} else {
+				snet[0] = r->V6.srcaddr[0];
+				snet[1] = r->V6.srcaddr[1] & (0xffffffffffffffffLL << r->src_mask);
 			}
 			snet[0] = htonll(snet[0]);
 			snet[1] = htonll(snet[1]);
-			inet_ntop(AF_INET6, &snet, s_snet, sizeof(s_snet));
+			inet_ntop(AF_INET6, snet, s_snet, sizeof(s_snet));
 
-			if ( r->dst_mask > 64 )
-				dnet[1] &= 0xffffffffffffffffLL << ( 128 - r->dst_mask );
-			else {
-				dnet[1] &= 0xffffffffffffffffLL << ( 64 - r->dst_mask );
+			if ( r->dst_mask >= 64 ) {
+				dnet[0] = r->V6.dstaddr[0] & (0xffffffffffffffffLL << (r->dst_mask - 64));
 				dnet[1] = 0;
+			} else {
+				dnet[0] = r->V6.dstaddr[0];
+				dnet[1] = r->V6.dstaddr[1] & (0xffffffffffffffffLL << r->dst_mask);
 			}
 			dnet[0] = htonll(dnet[0]);
 			dnet[1] = htonll(dnet[1]);
-			inet_ntop(AF_INET6, &dnet, s_dnet, sizeof(s_dnet));
+			inet_ntop(AF_INET6, dnet, s_dnet, sizeof(s_dnet));
 
 		} else {
 			s_snet[0] = '\0';
diff --git a/bin/nfcapd.c b/bin/nfcapd.c
index 695c049..fd75252 100644
--- a/bin/nfcapd.c
+++ b/bin/nfcapd.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2009-2017, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -29,17 +29,6 @@
  *  
  */
 
-/*
- * Because NetFlow export uses UDP to send export datagrams, it is possible 
- * for datagrams to be lost. To determine whether flow export information has 
- * been lost, Version 5, Version 7, and Version 8 headers contain a flow 
- * sequence number. The sequence number is equal to the sequence number of the 
- * previous datagram plus the number of flows in the previous datagram. After 
- * receiving a new datagram, the receiving application can subtract the expected 
- * sequence number from the sequence number in the header to derive the number 
- * of missed flows.
- */
-
 #include "config.h"
 
 #include <stdio.h>
@@ -82,6 +71,7 @@
 #include "flist.h"
 #include "nfstatfile.h"
 #include "bookkeeper.h"
+#include "launch.h"
 #include "collector.h"
 #include "exporter.h"
 #include "netflow_v1.h"
@@ -106,14 +96,8 @@
 #define DEFAULTHOSTNAME "127.0.0.1"
 #define SENDSOCK_BUFFSIZE 200000
 
-#ifndef DEVEL
-#   define dbg_printf(...) /* printf(__VA_ARGS__) */
-#else
-#   define dbg_printf(...) printf(__VA_ARGS__)
-#endif
-
 /* globals */
-caddr_t		shmem;
+void *shmem;
 int verbose = 0;
 
 extern uint32_t default_sampling;   // the default sampling rate when nothing else applies. set by -S
@@ -463,11 +447,11 @@ srecord_t	*commbuff;
 		if ( ((t_now - t_start) >= twin) || done ) {
 			char subfilename[64];
 			struct  tm *now;
-			char	*subdir, fmt[64];
+			char	*subdir, fmt[24];
 
 			alarm(0);
 			now = localtime(&t_start);
-			strftime(fmt, sizeof fmt, time_extension, now);
+			strftime(fmt, sizeof(fmt), time_extension, now);
 
 			// prepare sub dir hierarchy
 			if ( use_subdirs ) {
@@ -593,9 +577,10 @@ srecord_t	*commbuff;
 				commbuff->tstring[15] = 0;
 				commbuff->tstamp = t_start;
 				if ( subdir ) 
-					strncpy(commbuff->subdir, subdir, FNAME_SIZE);
+					strncpy(commbuff->subdir, subdir, FNAME_SIZE-1);
 				else
 					commbuff->subdir[0] = '\0';
+				commbuff->subdir[FNAME_SIZE-1] = '\0';
 
 				if ( launcher_alive ) {
 					LogInfo("Signal launcher");
@@ -1154,7 +1139,7 @@ char	*pcap_file;
 		// as well as shared memory
 		// prepare shared memory
 		shmem = mmap(0, sizeof(srecord_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
-		if ( shmem == (caddr_t)-1 ) {
+		if ( shmem == MAP_FAILED ) {
 			LogError("mmap() error: %s", strerror(errno));
 			close(sock);
 			exit(255);
@@ -1165,7 +1150,7 @@ char	*pcap_file;
 			case 0:
 				// child
 				close(sock);
-				launcher((char *)shmem, FlowSource, launch_process, expire);
+				launcher(shmem, FlowSource, launch_process, expire);
 				_exit(0);
 				break;
 			case -1:
diff --git a/bin/nfdump.c b/bin/nfdump.c
index 7a24d74..358b74d 100644
--- a/bin/nfdump.c
+++ b/bin/nfdump.c
@@ -106,7 +106,7 @@ int hash_skip = 0;
 
 extension_map_list_t *extension_map_list;
 
-extern generic_exporter_t **exporter_list;
+extern exporter_t **exporter_list;
 /*
  * Output Formats:
  * User defined output formats can be compiled into nfdump, for easy access
@@ -464,7 +464,7 @@ int 				done, write_file;
 
 		if ( nffile_r->block_header->id != DATA_BLOCK_TYPE_2 ) {
 			if ( nffile_r->block_header->id == DATA_BLOCK_TYPE_1 ) {
-				LogError("Can't process nfdump 1.5.x block type 1. Add --enable-compat15 to compile compatibility code. Skip block.\n");
+				LogError("nfdump 1.5.x block type 1 no longer supported. Skip block.\n");
 			} else {
 				LogError("Can't process block type %u. Skip block.\n", nffile_r->block_header->id);
 			}
@@ -488,7 +488,7 @@ int 				done, write_file;
 				case CommonRecordType: {
 					int match;
 					uint32_t map_id;
-					generic_exporter_t *exp_info;
+					exporter_t *exp_info;
 
 					// valid flow_record converted if needed
 					map_id = flow_record->ext_map;
diff --git a/bin/nfdump.test.out b/bin/nfdump.test.out
index df9dbef..7d8ab52 100755
--- a/bin/nfdump.test.out
+++ b/bin/nfdump.test.out
@@ -846,8 +846,8 @@ Flow Record:
   output       =                14
   src as       =               775
   dst as       =              8404
-  src mask     =                16 fe80::/16
-  dst mask     =                24 fe80::/24
+  src mask     =                16 fe80::2..:1234:0/16
+  dst mask     =                24 fe80::2..:1200:0/24
   dst tos      =               128
   direction    =                 1
   ip next hop  =        172.72.1.2
@@ -901,8 +901,8 @@ Flow Record:
   output       =                14
   src as       =               775
   dst as       =              8404
-  src mask     =                16 2001:234:aabb::/16
-  dst mask     =                24 2001:620:0:8::/24
+  src mask     =                16 2001:23..:fe80:0/16
+  dst mask     =                24 2001:62..:fe00:0/24
   dst tos      =               128
   direction    =                 1
   ip next hop  =        172.72.1.2
@@ -956,8 +956,8 @@ Flow Record:
   output       =                14
   src as       =               775
   dst as       =              8404
-  src mask     =                16 2001:234:aabb::/16
-  dst mask     =                24 2001:620:0:8::/24
+  src mask     =                16 2001:23..:fe80:0/16
+  dst mask     =                24 2001:62..:fe00:0/24
   dst tos      =               128
   direction    =                 1
   ip next hop  =        172.72.1.2
@@ -1011,8 +1011,8 @@ Flow Record:
   output       =                14
   src as       =               775
   dst as       =              8404
-  src mask     =                16 2001:234:aabb::/16
-  dst mask     =                24 2001:620:0:8::/24
+  src mask     =                16 2001:23..:fe80:0/16
+  dst mask     =                24 2001:62..:fe00:0/24
   dst tos      =               128
   direction    =                 1
   ip next hop  =        172.72.1.2
@@ -1066,8 +1066,8 @@ Flow Record:
   output       =                14
   src as       =               775
   dst as       =              8404
-  src mask     =                16 2001:234:aabb::/16
-  dst mask     =                24 2001:620:0:8::/24
+  src mask     =                16 2001:23..:fe80:0/16
+  dst mask     =                24 2001:62..:fe00:0/24
   dst tos      =               128
   direction    =                 1
   ip next hop  =        172.72.1.2
diff --git a/bin/nfprofile.c b/bin/nfprofile.c
index e6e8d86..2d14c58 100644
--- a/bin/nfprofile.c
+++ b/bin/nfprofile.c
@@ -65,7 +65,7 @@
 #include "profile.h"
 
 /* externals */
-extern generic_exporter_t **exporter_list;
+extern exporter_t **exporter_list;
 
 /* Local Variables */
 static const char *nfdump_version = VERSION;
@@ -184,7 +184,7 @@ int 		i, j, done, ret ;
 
 			switch ( flow_record->type ) { 
 					case CommonRecordType: {
-					generic_exporter_t *exp_info = exporter_list[flow_record->exporter_sysid];
+					exporter_t *exp_info = exporter_list[flow_record->exporter_sysid];
 					uint32_t map_id = flow_record->ext_map;
 					master_record_t	*master_record;
 
diff --git a/bin/nfreader.c b/bin/nfreader.c
index 101a90e..3838f82 100755
--- a/bin/nfreader.c
+++ b/bin/nfreader.c
@@ -86,7 +86,7 @@ typedef uint32_t    pointer_addr_t;
 // module limited globals
 extension_map_list_t *extension_map_list;
 
-extern generic_exporter_t **exporter_list;
+extern exporter_t **exporter_list;
 
 /* Function Prototypes */
 static void usage(char *name);
@@ -229,7 +229,7 @@ int 		i, done, ret;
 			switch ( flow_record->type ) {
 				case CommonRecordType: {
 					uint32_t map_id = flow_record->ext_map;
-					generic_exporter_t *exp_info = exporter_list[flow_record->exporter_sysid];
+					exporter_t *exp_info = exporter_list[flow_record->exporter_sysid];
 					if ( extension_map_list->slot[map_id] == NULL ) {
 						snprintf(string, 1024, "Corrupt data file! No such extension map id: %u. Skip record", flow_record->ext_map );
 						string[1023] = '\0';
diff --git a/bin/nfreplay.c b/bin/nfreplay.c
index 6a87138..522e207 100644
--- a/bin/nfreplay.c
+++ b/bin/nfreplay.c
@@ -1,7 +1,5 @@
 /*
- *  Copyright (c) 2018, 2017, 2016 Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -54,6 +52,10 @@
 #include <stdint.h>
 #endif
 
+#ifdef HAVE_STDIO_EXT_H
+#include <stdio_ext.h>
+#endif
+
 #include "nffile.h"
 #include "nfx.h"
 #include "nf_common.h"
@@ -96,8 +98,6 @@ send_peer_t peer;
 
 extension_map_list_t *extension_map_list;
 
-generic_exporter_t **exporter_list;
-
 /* Function Prototypes */
 static void usage(char *name);
 
diff --git a/bin/nftest.c b/bin/nftest.c
index 8091d41..81996af 100644
--- a/bin/nftest.c
+++ b/bin/nftest.c
@@ -211,7 +211,7 @@ int main(int argc, char **argv) {
 master_record_t flow_record;
 common_record_t c_record;
 uint64_t *blocks, l;
-uint32_t size, in[2];
+uint32_t in[2];
 time_t	now;
 int ret, i;
 value64_t	v;
@@ -262,7 +262,6 @@ void *p;
 	}
 
 
-	size = COMMON_RECORD_DATA_SIZE;
 	memset((void *)&flow_record, 0, sizeof(master_record_t));
 	blocks = (uint64_t *)&flow_record;
 
diff --git a/bin/sfcapd.c b/bin/sfcapd.c
index 5443786..7aa2a31 100644
--- a/bin/sfcapd.c
+++ b/bin/sfcapd.c
@@ -1,9 +1,5 @@
 /*
- *  Copyright (c) 2018, Peter Haag
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2016, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -76,6 +72,7 @@
 #include "nfnet.h"
 #include "bookkeeper.h"
 #include "collector.h"
+#include "launch.h"
 #include "flist.h"
 #include "nfstatfile.h"
 
@@ -97,7 +94,7 @@
 #define DEFAULTSFLOWPORT "6343"
 
 /* Global Variables */
-caddr_t		shmem;
+void *shmem;
 
 /* globals */
 int verbose = 0;
@@ -436,10 +433,10 @@ srecord_t	*commbuff;
 		if ( ((t_now - t_start) >= twin) || done ) {
 			char subfilename[64];
 			struct  tm *now;
-			char	*subdir, fmt[64];
+			char	*subdir, fmt[24];
 			alarm(0);
 			now = localtime(&t_start);
-			strftime(fmt, sizeof fmt, time_extension, now);
+			strftime(fmt, sizeof(fmt), time_extension, now);
 
 			// prepare sub dir hierarchy
 			if ( use_subdirs ) {
@@ -524,7 +521,8 @@ srecord_t	*commbuff;
 
 				// log stats
 				LogInfo("Ident: '%s' Flows: %llu, Packets: %llu, Bytes: %llu, Sequence Errors: %u, Bad Packets: %u", 
-					fs->Ident, (unsigned long long)nffile->stat_record->numflows, (unsigned long long)nffile->stat_record->numpackets, 
+					fs->Ident, (unsigned long long)nffile->stat_record->numflows,
+					(unsigned long long)nffile->stat_record->numpackets, 
 					(unsigned long long)nffile->stat_record->numbytes, nffile->stat_record->sequence_failure, fs->bad_packets);
 
 				// reset stat record
@@ -559,9 +557,10 @@ srecord_t	*commbuff;
 				commbuff->tstring[15] = 0;
 				commbuff->tstamp = t_start;
 				if ( subdir ) 
-					strncpy(commbuff->subdir, subdir, FNAME_SIZE);
+					strncpy(commbuff->subdir, subdir, FNAME_SIZE-1);
 				else
 					commbuff->subdir[0] = '\0';
+				commbuff->subdir[FNAME_SIZE-1] = '\0';
 
 				if ( launcher_alive ) {
 					LogInfo("Signal launcher");
@@ -1024,7 +1023,7 @@ int		c, i;
 		// as well as shared memory
 		// prepare shared memory
 		shmem = mmap(0, sizeof(srecord_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
-		if ( shmem == (caddr_t)-1 ) {
+		if ( shmem == MAP_FAILED ) {
 			LogError("mmap() error: %s", strerror(errno));
 			close(sock);
 			exit(255);
@@ -1035,7 +1034,7 @@ int		c, i;
 			case 0:
 				// child
 				close(sock);
-				launcher((char *)shmem, FlowSource, launch_process, expire);
+				launcher(shmem, FlowSource, launch_process, expire);
 				exit(0);
 				break;
 			case -1:
diff --git a/bin/sflow_nfdump.c b/bin/sflow_nfdump.c
index ddff414..ff1a4e9 100644
--- a/bin/sflow_nfdump.c
+++ b/bin/sflow_nfdump.c
@@ -1,8 +1,5 @@
 /*
- *  Copyright (c) 2017, Peter Haag
- *  Copyright (c) 2016, Peter Haag
- *  Copyright (c) 2014, Peter Haag
- *  Copyright (c) 2009, Peter Haag
+ *  Copyright (c) 2009-2019, Peter Haag
  *  Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
  *  All rights reserved.
  *  
@@ -73,26 +70,20 @@
 #include "sflow_process.h"
 #include "sflow_nfdump.h"
 
-#ifndef DEVEL
-#   define dbg_printf(...) /* printf(__VA_ARGS__) */
-#else
-#   define dbg_printf(...) printf(__VA_ARGS__)
-#endif
-
 #define MAX_SFLOW_EXTENSIONS 8
 
 typedef struct exporter_sflow_s {
 	// link chain
 	struct exporter_sflow_s *next;
 
-	// generic exporter information
+	// exporter information
 	exporter_info_record_t info;
 
     uint64_t    packets;            // number of packets sent by this exporter
     uint64_t    flows;              // number of flow records sent by this exporter
     uint32_t    sequence_failure;   // number of sequence failues
 
-    generic_sampler_t       *sampler;
+    sampler_t       *sampler;
 
 	// extension map
 	// extension maps are common for all exporters
@@ -101,7 +92,6 @@ typedef struct exporter_sflow_s {
 } exporter_sflow_t;
 
 extern extension_descriptor_t extension_descriptor[];
-extern FlowSource_t *FlowSource;
 
 /* module limited globals */
 
@@ -162,7 +152,6 @@ static exporter_sflow_t *GetExporter(FlowSource_t *fs, uint32_t agentSubId, uint
 
 #include "inline.c"
 #include "nffile_inline.c"
-#include "collector_inline.c"
 
 void Init_sflow(void) {
 int i, id;
@@ -251,7 +240,7 @@ int i, id, extension_size, map_size, map_index;
 		map_size += 2;
 
 
-	// Create a generic sflow extension map
+	// Create a sflow extension map
 	exporter->sflow_extension_info[num].map = (extension_map_t *)malloc((size_t)map_size);
 	if ( !exporter->sflow_extension_info[num].map ) {
 		LogError("SFLOW: malloc() allocation error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
@@ -322,7 +311,7 @@ int i, id, extension_size, map_size, map_index;
 
 static exporter_sflow_t *GetExporter(FlowSource_t *fs, uint32_t agentSubId, uint32_t meanSkipCount) {
 exporter_sflow_t **e = (exporter_sflow_t **)&(fs->exporter_data);
-generic_sampler_t *sampler;
+sampler_t *sampler;
 #define IP_STRING_LEN   40
 char ipstr[IP_STRING_LEN];
 int i;
@@ -370,7 +359,7 @@ int i;
 		(*e)->sflow_extension_info[i].map = NULL;
 	}
 
-	sampler = (generic_sampler_t *)malloc(sizeof(generic_sampler_t));
+	sampler = (sampler_t *)malloc(sizeof(sampler_t));
 	if ( !sampler ) {
 		LogError("SFLOW: malloc() error in %s line %d: %s", __FILE__, __LINE__, strerror (errno));
 		return NULL;
diff --git a/bin/sflow_process.c b/bin/sflow_process.c
index 5accbff..edc2bc6 100644
--- a/bin/sflow_process.c
+++ b/bin/sflow_process.c
@@ -3374,8 +3374,7 @@ static void readFlowSample_v2v4(SFSample *sample, FlowSource_t *fs, int verbose)
 		}
 	}
 
-	if(sample->gotIPV4 || sample->gotIPV6) 
-		StoreSflowRecord(sample, fs);
+	StoreSflowRecord(sample, fs);
 
 	if ( verbose ) 
 		writeFlowLine(sample);
@@ -3453,6 +3452,7 @@ uint8_t *sampleStart;
 	num_elements = getData32(sample);
 	{
 		uint32_t el;
+printf("numElements: %i\n", num_elements);
 		for(el = 0; el < num_elements; el++) {
 			uint32_t tag, length;
 			uint8_t *start;
@@ -3514,8 +3514,7 @@ uint8_t *sampleStart;
 	}
 	lengthCheck(sample, "flow_sample", sampleStart, sampleLength);
 
- 	if ( sample->gotIPV4 || sample->gotIPV6 )
-		StoreSflowRecord(sample, fs);
+	StoreSflowRecord(sample, fs);
 
 	/* or line-by-line output... */
 	if ( verbose ) 
diff --git a/configure.ac b/configure.ac
index 3b7e91c..08f73be 100755
--- a/configure.ac
+++ b/configure.ac
@@ -2,26 +2,19 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_REVISION($Revision: 243 $)dnl 
+AC_REVISION($Revision: 244 $)dnl 
 AC_INIT(nfdump, 1.6.18, peter@people.ops-trust.net)
-# $Date: 2014-11-16 14:10:20 +0100 (Sun, 16 Nov 2014) $
-#AC_CONFIG_SRCDIR([grammar.y])
+
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE([subdir-objects])
 
-LT_INIT
-# AC_ENABLE_SHARED
-# AC_ENABLE_STATIC
- 
 # Checks for programs.
-AC_PROG_CC
-AM_PROG_CC_C_O
+CFLAGS="-g -O3"
+AC_PROG_CC([clang gcc])
+AX_CHECK_C11
+CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -fno-strict-aliasing"
 
-dnl get the flags
-CFLAGS="${CFLAGS=}"
-if test $ac_cv_prog_gcc = yes -a "x$CFLAGS" = "x-g -O2"; then
-	CFLAGS="-g -O2 -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -fno-strict-aliasing"
-fi
+LT_INIT
 
 AC_ARG_ENABLE(devel,
 [  --enable-devel       compile debug and development code into nfdump; default is NO])
@@ -29,13 +22,6 @@ AC_ARG_ENABLE(devel,
 # Which way is better?
 if test "${enable_devel}" = "yes" ; then
 	CFLAGS="$CFLAGS -DDEVEL"
-cat >>config.h <<_ACEOF
-#define dbg_printf(...) printf(__VA_ARGS__)
-_ACEOF
-else
-cat >>config.h <<_ACEOF
-#define dbg_printf(...) /* printf(__VA_ARGS__) */
-_ACEOF
 fi
 
 AC_ARG_ENABLE(nsel,
@@ -313,6 +299,7 @@ AC_LINK_IFELSE(
 # Checks for header files.
 AC_HEADER_DIRENT
 AC_HEADER_STDC
+AC_CHECK_HEADERS(stdio_ext.h)
 AC_CHECK_HEADERS([nameser8_compat.h])
 AC_CHECK_HEADERS([features.h arpa/inet.h fcntl.h netinet/in.h fts.h stdint.h stdlib.h stddef.h string.h sys/socket.h syslog.h unistd.h iso/limits_iso.h])
 AC_CHECK_HEADERS(pcap-bpf.h net/bpf.h)
@@ -395,6 +382,7 @@ AC_CHECK_SIZEOF(long long)
 AC_CHECK_SIZEOF(__int64)
 AC_CHECK_SIZEOF(void *)
 AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(time_t)
 AC_CHECK_SIZEOF(ptrdiff_t)
 AC_C_CONST
 AC_CHECK_FUNCS(memcmp memcpy memmove memset)
diff --git a/debian/changelog b/debian/changelog
index d565f32..9c5bae8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+nfdump (1.6.18+git20190901.955a662-1) UNRELEASED; urgency=medium
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 26 Sep 2019 05:35:25 +0000
+
 nfdump (1.6.18-1) unstable; urgency=medium
 
   [ Bernhard Schmidt ]
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..dd6d8b6
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,50 @@
+# ===========================================================================
+#      https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+#   FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+#   added in between.
+#
+#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+#   CFLAGS) is used.  FLAGS-VARIABLE is not changed if it already contains
+#   FLAG.  If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+#   FLAG.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 8
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+  AS_CASE([" AS_VAR_GET(FLAGS) "],
+    [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+    [
+     AS_VAR_APPEND(FLAGS,[" $1"])
+     AC_RUN_LOG([: FLAGS="$FLAGS"])
+    ])
+  ],
+  [
+  AS_VAR_SET(FLAGS,[$1])
+  AC_RUN_LOG([: FLAGS="$FLAGS"])
+  ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..bd753b3
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,53 @@
+# ===========================================================================
+#  https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 6
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/c11.m4 b/m4/c11.m4
new file mode 100644
index 0000000..6c659e6
--- /dev/null
+++ b/m4/c11.m4
@@ -0,0 +1,11 @@
+AC_DEFUN([AX_CHECK_C11],
+[AX_CHECK_COMPILE_FLAG([-std=gnu11],
+    [AX_APPEND_FLAG([-std=gnu11])],
+    [AX_CHECK_COMPILE_FLAG([-std=c11],
+        [AX_APPEND_FLAG([-std=c11])],
+        [AX_CHECK_COMPILE_FLAG([-std=c99],
+            [AX_APPEND_FLAG([-std=c99])],
+            [AC_MSG_ERROR([C compiled does not support at least C99!])])
+        ])
+    ])
+])