nfrb 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.4"
12
+ gem "rcov", ">= 0"
13
+ gem "rdoc", ">= 2.4.2"
14
+ gem "rake-compiler", ">= 0"
15
+ end
@@ -0,0 +1,27 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ json (1.6.3)
10
+ rake (0.9.2)
11
+ rake-compiler (0.7.9)
12
+ rake
13
+ rcov (0.9.11)
14
+ rdoc (3.11)
15
+ json (~> 1.4)
16
+ shoulda (2.11.3)
17
+
18
+ PLATFORMS
19
+ ruby
20
+
21
+ DEPENDENCIES
22
+ bundler (~> 1.0.0)
23
+ jeweler (~> 1.6.4)
24
+ rake-compiler
25
+ rcov
26
+ rdoc (>= 2.4.2)
27
+ shoulda
@@ -0,0 +1,32 @@
1
+ The nfrb gem is derived from nfdump code and is distributed under the BSD
2
+ license:
3
+
4
+ Copyright (c) 2009, Peter Haag
5
+ Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
6
+ Copyright (c) 2011, Davide Guerri <davide.guerri@gmail.com>
7
+ All rights reserved.
8
+
9
+ Redistribution and use in source and binary forms, with or without
10
+ modification, are permitted provided that the following conditions are met:
11
+
12
+ * Redistributions of source code must retain the above copyright notice,
13
+ this list of conditions and the following disclaimer.
14
+ * Redistributions in binary form must reproduce the above copyright notice,
15
+ this list of conditions and the following disclaimer in the documentation
16
+ and/or other materials provided with the distribution.
17
+ * Neither the name of SWITCH nor the names of its contributors may be
18
+ used to endorse or promote products derived from this software without
19
+ specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ POSSIBILITY OF SUCH DAMAGE.
32
+
@@ -0,0 +1,56 @@
1
+ = nfrb
2
+
3
+ Nfrb is a very simple yet fast gem that can be used to parse nfcapd files.
4
+
5
+ == Usage
6
+
7
+ === Installation
8
+
9
+ # git clone git://github.com/dguerri/nfrb.git
10
+ # cd nfrb
11
+ # bundle install
12
+ # rake install
13
+
14
+ === Sample code
15
+
16
+ nfrb-bech.rb:
17
+
18
+ require 'nfrb'
19
+
20
+ raise ArgumentError, "Missing nfcapd files" if ARGV.count < 1
21
+
22
+ nfparser = NfRb::NfReader.new
23
+
24
+ i=0
25
+ start_t = Time.now
26
+
27
+ nfparser.process_files(ARGV) do |flow|
28
+ # puts flow.inspect();
29
+ i+=1
30
+ end
31
+
32
+ stop_t = Time.now
33
+
34
+ puts "#{i} flows processed in #{stop_t - start_t} seconds."
35
+ puts "Flows per seconds = #{i / (stop_t - start_t)}"
36
+
37
+ === Sample output benchmark (3.4 Ghz Intel Core i7)
38
+
39
+ # bundle exec ruby nfrb-bech.rb nfcapd.201112181720
40
+ 325602 flows processed in 0.67114 seconds.
41
+ Flows per seconds = 488513.404029311
42
+
43
+ == Contributing to nfrb
44
+
45
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
46
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
47
+ * Fork the project
48
+ * Start a feature/bugfix branch
49
+ * Commit and push until you are happy with your contribution
50
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
51
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
52
+
53
+ == Copyright
54
+
55
+ Copyright (c) 2011 Davide Guerri. See LICENSE.txt for further details.
56
+
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'rake/extensiontask'
15
+ Rake::ExtensionTask.new("rb_nfrb")
16
+
17
+ require 'jeweler'
18
+ require './lib/nfrb/version.rb'
19
+ Jeweler::Tasks.new do |gem|
20
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
21
+ gem.name = "nfrb"
22
+ gem.homepage = "http://github.com/dguerri/nfrb"
23
+ gem.license = "BSD license"
24
+ gem.summary = %Q{Nfrb: nfcapd files parser.}
25
+ gem.description = %Q{Nfrb is a very simple yet fast gem that can be used to parse nfcapd files.}
26
+ gem.email = "davide.guerri@gmail.com"
27
+ gem.authors = ["Davide Guerri"]
28
+ gem.version = NfRb::Version::STRING
29
+ # dependencies defined in Gemfile
30
+ end
31
+ Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.libs << 'lib' << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = true
45
+ test.rcov_opts << '--exclude "gems/*"'
46
+ end
47
+
48
+ task :default => :build
49
+
50
+ require 'rdoc/task'
51
+ RDoc::Task.new do |rdoc|
52
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
53
+
54
+ rdoc.rdoc_dir = 'rdoc'
55
+ rdoc.title = "nfrb #{version}"
56
+ rdoc.rdoc_files.include('README*')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
@@ -0,0 +1,14 @@
1
+ The following files are from nfdump v 1.6.4
2
+
3
+ fts_compat.c
4
+ fts_compat.h
5
+ lzoconf.h
6
+ lzodefs.h
7
+ minilzo.h
8
+ nf_common.h
9
+ nffile.c
10
+ nffile.h
11
+ nfx.c
12
+ nfx.h
13
+ util.c
14
+ util.h
@@ -0,0 +1,37 @@
1
+ #ifndef NFRB_CONFIG_H
2
+ #define NFRB_CONFIG_H 1
3
+
4
+ // TODO: The following values must be calculated...
5
+
6
+ /* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
7
+ */
8
+ #define HAVE_DIRENT_H 1
9
+
10
+ /* Define to 1 if you have the <stdint.h> header file. */
11
+ #define HAVE_STDINT_H 1
12
+
13
+ /* The size of `int', as computed by sizeof. */
14
+ #define SIZEOF_INT 4
15
+
16
+ /* The size of `long', as computed by sizeof. */
17
+ #define SIZEOF_LONG 8
18
+
19
+ /* The size of `long long', as computed by sizeof. */
20
+ #define SIZEOF_LONG_LONG 8
21
+
22
+ /* The size of `ptrdiff_t', as computed by sizeof. */
23
+ #define SIZEOF_PTRDIFF_T 8
24
+
25
+ /* The size of `short', as computed by sizeof. */
26
+ #define SIZEOF_SHORT 2
27
+
28
+ /* The size of `size_t', as computed by sizeof. */
29
+ #define SIZEOF_SIZE_T 8
30
+
31
+ /* The size of `void *', as computed by sizeof. */
32
+ #define SIZEOF_VOID_P 8
33
+
34
+ /* The size of `__int64', as computed by sizeof. */
35
+ #define SIZEOF___INT64 0
36
+
37
+ #endif
@@ -0,0 +1,579 @@
1
+ /*
2
+ * Copyright (c) 2009, Peter Haag
3
+ * Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ *
9
+ * * Redistributions of source code must retain the above copyright notice,
10
+ * this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright notice,
12
+ * this list of conditions and the following disclaimer in the documentation
13
+ * and/or other materials provided with the distribution.
14
+ * * Neither the name of SWITCH nor the names of its contributors may be
15
+ * used to endorse or promote products derived from this software without
16
+ * specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ * $Author: haag $
31
+ *
32
+ * $Id: nffile_inline.c 40 2009-12-16 10:41:44Z haag $
33
+ *
34
+ * $LastChangedRevision: 40 $
35
+ *
36
+ */
37
+
38
+ /*
39
+ * nffile_inline.c is needed for daemon code as well as normal stdio code
40
+ * therefore a generic LogError is defined, which maps to the
41
+ * approriate logging channel - either stderr or syslog
42
+ */
43
+ void LogError(char *format, ...);
44
+
45
+ static inline int CheckBufferSpace(nffile_t *nffile, size_t required);
46
+
47
+ static inline void AppendToBuffer(nffile_t *nffile, void *record, size_t required);
48
+
49
+ static inline void ExpandRecord_v2(common_record_t *input_record, extension_info_t *extension_info, master_record_t *output_record );
50
+
51
+ static void PackRecord(master_record_t *master_record, nffile_t *nffile);
52
+
53
+ static inline int CheckBufferSpace(nffile_t *nffile, size_t required) {
54
+
55
+ #ifdef DEVEL
56
+ // printf("Buffer Size %u\n", nffile->block_header->size);
57
+ #endif
58
+ // flush current buffer to disc
59
+ if ( (nffile->block_header->size + required ) > WRITE_BUFFSIZE ) {
60
+
61
+ // this should never happen, but catch it anyway
62
+ if ( required > WRITE_BUFFSIZE ) {
63
+ LogError("Required buffer size %zu too big for output buffer!" , required);
64
+ return 0;
65
+ }
66
+
67
+ if ( WriteBlock(nffile) <= 0 ) {
68
+ LogError("Failed to write output buffer to disk: '%s'" , strerror(errno));
69
+ return 0;
70
+ }
71
+ }
72
+
73
+ return 1;
74
+ } // End of CheckBufferSpace
75
+
76
+
77
+ /*
78
+ * Expand file record into master record for further processing
79
+ * LP64 CPUs need special 32bit operations as it is not guarateed, that 64bit
80
+ * values are aligned
81
+ */
82
+ static inline void ExpandRecord_v2(common_record_t *input_record, extension_info_t *extension_info, master_record_t *output_record ) {
83
+ extension_map_t *extension_map = extension_info->map;
84
+ uint32_t i, *u;
85
+ size_t size;
86
+ void *p = (void *)input_record;
87
+
88
+ // set map ref
89
+ output_record->map_ref = extension_map;
90
+
91
+ // Copy common data block
92
+ size = COMMON_RECORD_DATA_SIZE;
93
+ memcpy((void *)output_record, p, size);
94
+ p = (void *)input_record->data;
95
+
96
+ // Required extension 1 - IP addresses
97
+ if ( (input_record->flags & FLAG_IPV6_ADDR) != 0 ) { // IPv6
98
+ // IPv6
99
+ memcpy((void *)output_record->v6.srcaddr, p, 4 * sizeof(uint64_t));
100
+ p = (void *)((pointer_addr_t)p + 4 * sizeof(uint64_t));
101
+ } else {
102
+ // IPv4
103
+ u = (uint32_t *)p;
104
+ output_record->v6.srcaddr[0] = 0;
105
+ output_record->v6.srcaddr[1] = 0;
106
+ output_record->v4.srcaddr = u[0];
107
+
108
+ output_record->v6.dstaddr[0] = 0;
109
+ output_record->v6.dstaddr[1] = 0;
110
+ output_record->v4.dstaddr = u[1];
111
+ p = (void *)((pointer_addr_t)p + 2 * sizeof(uint32_t));
112
+ }
113
+
114
+ // Required extension 2 - packet counter
115
+ if ( (input_record->flags & FLAG_PKG_64 ) != 0 ) {
116
+ // 64bit packet counter
117
+ value64_t l, *v = (value64_t *)p;
118
+ l.val.val32[0] = v->val.val32[0];
119
+ l.val.val32[1] = v->val.val32[1];
120
+ output_record->dPkts = l.val.val64;
121
+ p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
122
+ } else {
123
+ // 32bit packet counter
124
+ output_record->dPkts = *((uint32_t *)p);
125
+ p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
126
+ }
127
+
128
+ // Required extension 3 - byte counter
129
+ if ( (input_record->flags & FLAG_BYTES_64 ) != 0 ) {
130
+ // 64bit byte counter
131
+ value64_t l, *v = (value64_t *)p;
132
+ l.val.val32[0] = v->val.val32[0];
133
+ l.val.val32[1] = v->val.val32[1];
134
+ output_record->dOctets = l.val.val64;
135
+ p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
136
+ } else {
137
+ // 32bit bytes counter
138
+ output_record->dOctets = *((uint32_t *)p);
139
+ p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
140
+ }
141
+
142
+ // preset one single flow
143
+ output_record->aggr_flows = 1;
144
+
145
+ // Process optional extensions
146
+ i=0;
147
+ while ( extension_map->ex_id[i] ) {
148
+ switch (extension_map->ex_id[i++]) {
149
+ // 0 - 3 should never be in an extension table so - ignore it
150
+ case 0:
151
+ case 1:
152
+ case 2:
153
+ case 3:
154
+ break;
155
+ case EX_IO_SNMP_2: {
156
+ tpl_ext_4_t *tpl = (tpl_ext_4_t *)p;
157
+ output_record->input = tpl->input;
158
+ output_record->output = tpl->output;
159
+ p = (void *)tpl->data;
160
+ } break;
161
+ case EX_IO_SNMP_4: {
162
+ tpl_ext_5_t *tpl = (tpl_ext_5_t *)p;
163
+ output_record->input = tpl->input;
164
+ output_record->output = tpl->output;
165
+ p = (void *)tpl->data;
166
+ } break;
167
+ case EX_AS_2: {
168
+ tpl_ext_6_t *tpl = (tpl_ext_6_t *)p;
169
+ output_record->srcas = tpl->src_as;
170
+ output_record->dstas = tpl->dst_as;
171
+ p = (void *)tpl->data;
172
+ } break;
173
+ case EX_AS_4: {
174
+ tpl_ext_7_t *tpl = (tpl_ext_7_t *)p;
175
+ output_record->srcas = tpl->src_as;
176
+ output_record->dstas = tpl->dst_as;
177
+ p = (void *)tpl->data;
178
+ } break;
179
+ case EX_MULIPLE: {
180
+ tpl_ext_8_t *tpl = (tpl_ext_8_t *)p;
181
+ // use a 32 bit int to copy all 4 fields
182
+ output_record->any = tpl->any;
183
+ p = (void *)tpl->data;
184
+ } break;
185
+ case EX_NEXT_HOP_v4: {
186
+ tpl_ext_9_t *tpl = (tpl_ext_9_t *)p;
187
+ output_record->ip_nexthop.v6[0] = 0;
188
+ output_record->ip_nexthop.v6[1] = 0;
189
+ output_record->ip_nexthop.v4 = tpl->nexthop;
190
+ p = (void *)tpl->data;
191
+ ClearFlag(output_record->flags, FLAG_IPV6_NH);
192
+ } break;
193
+ case EX_NEXT_HOP_v6: {
194
+ tpl_ext_10_t *tpl = (tpl_ext_10_t *)p;
195
+ output_record->ip_nexthop.v6[0] = tpl->nexthop[0];
196
+ output_record->ip_nexthop.v6[1] = tpl->nexthop[1];
197
+ p = (void *)tpl->data;
198
+ SetFlag(output_record->flags, FLAG_IPV6_NH);
199
+ } break;
200
+ case EX_NEXT_HOP_BGP_v4: {
201
+ tpl_ext_11_t *tpl = (tpl_ext_11_t *)p;
202
+ output_record->bgp_nexthop.v6[0] = 0;
203
+ output_record->bgp_nexthop.v6[1] = 0;
204
+ output_record->bgp_nexthop.v4 = tpl->bgp_nexthop;
205
+ ClearFlag(output_record->flags, FLAG_IPV6_NHB);
206
+ p = (void *)tpl->data;
207
+ } break;
208
+ case EX_NEXT_HOP_BGP_v6: {
209
+ tpl_ext_12_t *tpl = (tpl_ext_12_t *)p;
210
+ output_record->bgp_nexthop.v6[0] = tpl->bgp_nexthop[0];
211
+ output_record->bgp_nexthop.v6[1] = tpl->bgp_nexthop[1];
212
+ p = (void *)tpl->data;
213
+ SetFlag(output_record->flags, FLAG_IPV6_NHB);
214
+ } break;
215
+ case EX_VLAN: {
216
+ tpl_ext_13_t *tpl = (tpl_ext_13_t *)p;
217
+ output_record->src_vlan = tpl->src_vlan;
218
+ output_record->dst_vlan = tpl->dst_vlan;
219
+ p = (void *)tpl->data;
220
+ } break;
221
+ case EX_OUT_PKG_4: {
222
+ tpl_ext_14_t *tpl = (tpl_ext_14_t *)p;
223
+ output_record->out_pkts = tpl->out_pkts;
224
+ p = (void *)tpl->data;
225
+ } break;
226
+ case EX_OUT_PKG_8: {
227
+ tpl_ext_15_t v, *tpl = (tpl_ext_15_t *)p;
228
+ v.v[0] = tpl->v[0];
229
+ v.v[1] = tpl->v[1];
230
+ output_record->out_pkts = v.out_pkts;
231
+ p = (void *)tpl->data;
232
+ } break;
233
+ case EX_OUT_BYTES_4: {
234
+ tpl_ext_16_t *tpl = (tpl_ext_16_t *)p;
235
+ output_record->out_bytes = tpl->out_bytes;
236
+ p = (void *)tpl->data;
237
+ } break;
238
+ case EX_OUT_BYTES_8: {
239
+ tpl_ext_17_t v,*tpl = (tpl_ext_17_t *)p;
240
+ v.v[0] = tpl->v[0];
241
+ v.v[1] = tpl->v[1];
242
+ output_record->out_bytes = v.out_bytes;
243
+ p = (void *)tpl->data;
244
+ } break;
245
+ case EX_AGGR_FLOWS_4: {
246
+ tpl_ext_18_t *tpl = (tpl_ext_18_t *)p;
247
+ output_record->aggr_flows = tpl->aggr_flows;
248
+ p = (void *)tpl->data;
249
+ } break;
250
+ case EX_AGGR_FLOWS_8: {
251
+ tpl_ext_19_t v, *tpl = (tpl_ext_19_t *)p;
252
+ v.v[0] = tpl->v[0];
253
+ v.v[1] = tpl->v[1];
254
+ output_record->aggr_flows = v.aggr_flows;
255
+ p = (void *)tpl->data;
256
+ } break;
257
+ case EX_MAC_1: {
258
+ tpl_ext_20_t v, *tpl = (tpl_ext_20_t *)p;
259
+ v.v1[0] = tpl->v1[0];
260
+ v.v1[1] = tpl->v1[1];
261
+ output_record->in_src_mac = v.in_src_mac;
262
+
263
+ v.v2[0] = tpl->v2[0];
264
+ v.v2[1] = tpl->v2[1];
265
+ output_record->out_dst_mac = v.out_dst_mac;
266
+ p = (void *)tpl->data;
267
+ } break;
268
+ case EX_MAC_2: {
269
+ tpl_ext_21_t v, *tpl = (tpl_ext_21_t *)p;
270
+ v.v1[0] = tpl->v1[0];
271
+ v.v1[1] = tpl->v1[1];
272
+ output_record->in_dst_mac = v.in_dst_mac;
273
+ v.v2[0] = tpl->v2[0];
274
+ v.v2[1] = tpl->v2[1];
275
+ output_record->out_src_mac = v.out_src_mac;
276
+ p = (void *)tpl->data;
277
+ } break;
278
+ case EX_MPLS: {
279
+ tpl_ext_22_t *tpl = (tpl_ext_22_t *)p;
280
+ int j;
281
+ for (j=0; j<10; j++ ) {
282
+ output_record->mpls_label[j] = tpl->mpls_label[j];
283
+ }
284
+ p = (void *)tpl->data;
285
+ } break;
286
+ case EX_ROUTER_IP_v4: {
287
+ tpl_ext_23_t *tpl = (tpl_ext_23_t *)p;
288
+ output_record->ip_router.v6[0] = 0;
289
+ output_record->ip_router.v6[1] = 0;
290
+ output_record->ip_router.v4 = tpl->router_ip;
291
+ p = (void *)tpl->data;
292
+ ClearFlag(output_record->flags, FLAG_IPV6_EXP);
293
+ } break;
294
+ case EX_ROUTER_IP_v6: {
295
+ tpl_ext_24_t *tpl = (tpl_ext_24_t *)p;
296
+ output_record->ip_router.v6[0] = tpl->router_ip[0];
297
+ output_record->ip_router.v6[1] = tpl->router_ip[1];
298
+ p = (void *)tpl->data;
299
+ SetFlag(output_record->flags, FLAG_IPV6_EXP);
300
+ } break;
301
+ case EX_ROUTER_ID: {
302
+ tpl_ext_25_t *tpl = (tpl_ext_25_t *)p;
303
+ output_record->engine_type = tpl->engine_type;
304
+ output_record->engine_id = tpl->engine_id;
305
+ p = (void *)tpl->data;
306
+ } break;
307
+ }
308
+ }
309
+
310
+ } // End of ExpandRecord_v2
311
+
312
+ static void PackRecord(master_record_t *master_record, nffile_t *nffile) {
313
+ extension_map_t *extension_map = master_record->map_ref;
314
+ uint32_t required = COMMON_RECORD_DATA_SIZE + extension_map->extension_size;
315
+ size_t size;
316
+ void *p;
317
+ int i;
318
+
319
+ // check size of packets and bytes
320
+ if ( master_record->dPkts > 0xffffffffLL ) {
321
+ master_record->flags |= FLAG_PKG_64;
322
+ required += 8;
323
+ } else {
324
+ master_record->flags &= ~FLAG_PKG_64;
325
+ required += 4;
326
+ }
327
+
328
+ if ( master_record->dOctets > 0xffffffffLL ) {
329
+ master_record->flags |= FLAG_BYTES_64;
330
+ required += 8;
331
+ } else {
332
+ master_record->flags &= ~FLAG_BYTES_64;
333
+ required += 4;
334
+ }
335
+ if ( (master_record->flags & FLAG_IPV6_ADDR) != 0 ) // IPv6
336
+ required += 32;
337
+ else
338
+ required += 8;
339
+
340
+ master_record->size = required;
341
+
342
+ // flush current buffer to disc if not enough space
343
+ if ( !CheckBufferSpace(nffile, required) ) {
344
+ return;
345
+ }
346
+
347
+ // enough buffer space available at this point
348
+ p = nffile->buff_ptr;
349
+
350
+ // write common record
351
+ size = COMMON_RECORD_DATA_SIZE;
352
+ memcpy(p, (void *)master_record, size);
353
+ p = (void *)((pointer_addr_t)p + size);
354
+
355
+ // Required extension 1 - IP addresses
356
+ if ( (master_record->flags & FLAG_IPV6_ADDR) != 0 ) { // IPv6
357
+ // IPv6
358
+ memcpy(p, (void *)master_record->v6.srcaddr, 4 * sizeof(uint64_t));
359
+ p = (void *)((pointer_addr_t)p + 4 * sizeof(uint64_t));
360
+ } else {
361
+ // IPv4
362
+ uint32_t *u = (uint32_t *)p;
363
+ u[0] = master_record->v4.srcaddr;
364
+ u[1] = master_record->v4.dstaddr;
365
+ p = (void *)((pointer_addr_t)p + 2 * sizeof(uint32_t));
366
+ }
367
+
368
+ // Required extension 2 - packet counter
369
+ if ( (master_record->flags & FLAG_PKG_64 ) != 0 ) {
370
+ // 64bit packet counter
371
+ value64_t l, *v = (value64_t *)p;
372
+ l.val.val64 = master_record->dPkts;
373
+ v->val.val32[0] = l.val.val32[0];
374
+ v->val.val32[1] = l.val.val32[1];
375
+ p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
376
+ } else {
377
+ // 32bit packet counter
378
+ *((uint32_t *)p) = master_record->dPkts;
379
+ p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
380
+ }
381
+
382
+ // Required extension 3 - byte counter
383
+ if ( (master_record->flags & FLAG_BYTES_64 ) != 0 ) {
384
+ // 64bit byte counter
385
+ value64_t l, *v = (value64_t *)p;
386
+ l.val.val64 = master_record->dOctets;
387
+ v->val.val32[0] = l.val.val32[0];
388
+ v->val.val32[1] = l.val.val32[1];
389
+ p = (void *)((pointer_addr_t)p + sizeof(uint64_t));
390
+ } else {
391
+ // 32bit bytes counter
392
+ *((uint32_t *)p) = master_record->dOctets;
393
+ p = (void *)((pointer_addr_t)p + sizeof(uint32_t));
394
+ }
395
+
396
+ // Process optional extensions
397
+ i=0;
398
+ while ( extension_map->ex_id[i] ) {
399
+ switch (extension_map->ex_id[i++]) {
400
+ // 0 - 3 should never be in an extension table so - ignore it
401
+ case 0:
402
+ case 1:
403
+ case 2:
404
+ case 3:
405
+ break;
406
+ case EX_IO_SNMP_2: { // input/output SNMP 2 byte
407
+ tpl_ext_4_t *tpl = (tpl_ext_4_t *)p;
408
+ tpl->input = master_record->input;
409
+ tpl->output = master_record->output;
410
+ p = (void *)tpl->data;
411
+ } break;
412
+ case EX_IO_SNMP_4: { // input/output SNMP 4 byte
413
+ tpl_ext_5_t *tpl = (tpl_ext_5_t *)p;
414
+ tpl->input = master_record->input;
415
+ tpl->output = master_record->output;
416
+ p = (void *)tpl->data;
417
+ } break;
418
+ case EX_AS_2: { // srcas/dstas 2 byte
419
+ tpl_ext_6_t *tpl = (tpl_ext_6_t *)p;
420
+ tpl->src_as = master_record->srcas;
421
+ tpl->dst_as = master_record->dstas;
422
+ p = (void *)tpl->data;
423
+ } break;
424
+ case EX_AS_4: { // srcas/dstas 4 byte
425
+ tpl_ext_7_t *tpl = (tpl_ext_7_t *)p;
426
+ tpl->src_as = master_record->srcas;
427
+ tpl->dst_as = master_record->dstas;
428
+ p = (void *)tpl->data;
429
+ } break;
430
+ case EX_MULIPLE: {
431
+ tpl_ext_8_t *tpl = (tpl_ext_8_t *)p;
432
+ // use a 32 bit int to copy all 4 fields
433
+ tpl->any = master_record->any;
434
+ p = (void *)tpl->data;
435
+ } break;
436
+ case EX_NEXT_HOP_v4: {
437
+ tpl_ext_9_t *tpl = (tpl_ext_9_t *)p;
438
+ tpl->nexthop = master_record->ip_nexthop.v4;
439
+ p = (void *)tpl->data;
440
+ } break;
441
+ case EX_NEXT_HOP_v6: {
442
+ tpl_ext_10_t *tpl = (tpl_ext_10_t *)p;
443
+ tpl->nexthop[0] = master_record->ip_nexthop.v6[0];
444
+ tpl->nexthop[1] = master_record->ip_nexthop.v6[1];
445
+ p = (void *)tpl->data;
446
+ } break;
447
+ case EX_NEXT_HOP_BGP_v4: {
448
+ tpl_ext_11_t *tpl = (tpl_ext_11_t *)p;
449
+ tpl->bgp_nexthop = master_record->bgp_nexthop.v4;
450
+ p = (void *)tpl->data;
451
+ } break;
452
+ case EX_NEXT_HOP_BGP_v6: {
453
+ tpl_ext_12_t *tpl = (tpl_ext_12_t *)p;
454
+ tpl->bgp_nexthop[0] = master_record->bgp_nexthop.v6[0];
455
+ tpl->bgp_nexthop[1] = master_record->bgp_nexthop.v6[1];
456
+ p = (void *)tpl->data;
457
+ } break;
458
+ case EX_VLAN: {
459
+ tpl_ext_13_t *tpl = (tpl_ext_13_t *)p;
460
+ tpl->src_vlan = master_record->src_vlan;
461
+ tpl->dst_vlan = master_record->dst_vlan;
462
+ p = (void *)tpl->data;
463
+ } break;
464
+ case EX_OUT_PKG_4: {
465
+ tpl_ext_14_t *tpl = (tpl_ext_14_t *)p;
466
+ tpl->out_pkts = master_record->out_pkts;
467
+ p = (void *)tpl->data;
468
+ } break;
469
+ case EX_OUT_PKG_8: {
470
+ tpl_ext_15_t v, *tpl = (tpl_ext_15_t *)p;
471
+ v.out_pkts = master_record->out_pkts;
472
+ tpl->v[0] = v.v[0];
473
+ tpl->v[1] = v.v[1];
474
+ p = (void *)tpl->data;
475
+ } break;
476
+ case EX_OUT_BYTES_4: {
477
+ tpl_ext_16_t *tpl = (tpl_ext_16_t *)p;
478
+ tpl->out_bytes = master_record->out_bytes;
479
+ p = (void *)tpl->data;
480
+ } break;
481
+ case EX_OUT_BYTES_8: {
482
+ tpl_ext_17_t v, *tpl = (tpl_ext_17_t *)p;
483
+ v.out_bytes = master_record->out_bytes;
484
+ tpl->v[0] = v.v[0];
485
+ tpl->v[1] = v.v[1];
486
+ p = (void *)tpl->data;
487
+ } break;
488
+ case EX_AGGR_FLOWS_4: {
489
+ tpl_ext_18_t *tpl = (tpl_ext_18_t *)p;
490
+ tpl->aggr_flows = master_record->aggr_flows;
491
+ p = (void *)tpl->data;
492
+ } break;
493
+ case EX_AGGR_FLOWS_8: {
494
+ tpl_ext_19_t v, *tpl = (tpl_ext_19_t *)p;
495
+ v.aggr_flows = master_record->aggr_flows;
496
+ tpl->v[0] = v.v[0];
497
+ tpl->v[1] = v.v[1];
498
+ p = (void *)tpl->data;
499
+ } break;
500
+ case EX_MAC_1: {
501
+ tpl_ext_20_t v, *tpl = (tpl_ext_20_t *)p;
502
+ v.in_src_mac = master_record->in_src_mac;
503
+ tpl->v1[0] = v.v1[0];
504
+ tpl->v1[1] = v.v1[1];
505
+ v.out_dst_mac = master_record->out_dst_mac;
506
+ tpl->v2[0] = v.v2[0];
507
+ tpl->v2[1] = v.v2[1];
508
+ p = (void *)tpl->data;
509
+ } break;
510
+ case EX_MAC_2: {
511
+ tpl_ext_21_t v, *tpl = (tpl_ext_21_t *)p;
512
+ v.in_dst_mac = master_record->in_dst_mac;
513
+ tpl->v1[0] = v.v1[0];
514
+ tpl->v1[1] = v.v1[1];
515
+ v.out_src_mac = master_record->out_src_mac;
516
+ tpl->v2[0] = v.v2[0];
517
+ tpl->v2[1] = v.v2[1];
518
+ p = (void *)tpl->data;
519
+ } break;
520
+ case EX_MPLS: {
521
+ tpl_ext_22_t *tpl = (tpl_ext_22_t *)p;
522
+ int j;
523
+ for (j=0; j<10; j++ ) {
524
+ tpl->mpls_label[j] = master_record->mpls_label[j];
525
+ }
526
+ p = (void *)tpl->data;
527
+ } break;
528
+ case EX_ROUTER_IP_v4: {
529
+ tpl_ext_23_t *tpl = (tpl_ext_23_t *)p;
530
+ tpl->router_ip = master_record->ip_router.v4;
531
+ p = (void *)tpl->data;
532
+ } break;
533
+ case EX_ROUTER_IP_v6: {
534
+ tpl_ext_24_t *tpl = (tpl_ext_24_t *)p;
535
+ tpl->router_ip[0] = master_record->ip_router.v6[0];
536
+ tpl->router_ip[1] = master_record->ip_router.v6[1];
537
+ p = (void *)tpl->data;
538
+ } break;
539
+ case EX_ROUTER_ID: {
540
+ tpl_ext_25_t *tpl = (tpl_ext_25_t *)p;
541
+ tpl->engine_type = master_record->engine_type;
542
+ tpl->engine_id = master_record->engine_id;
543
+ p = (void *)tpl->data;
544
+ } break;
545
+
546
+ }
547
+ }
548
+
549
+ nffile->block_header->size += required;
550
+ nffile->block_header->NumRecords++;
551
+ #ifdef DEVEL
552
+ if ( ((pointer_addr_t)p - (pointer_addr_t)nffile->buff_ptr) != required ) {
553
+ fprintf(stderr, "Packrecord: size missmatch: required: %i, written: %li!\n",
554
+ required, (long)((ptrdiff_t)p - (ptrdiff_t)nffile->buff_ptr));
555
+ exit(255);
556
+ }
557
+ #endif
558
+ nffile->buff_ptr = p;
559
+
560
+ } // End of PackRecord
561
+
562
+ static inline void AppendToBuffer(nffile_t *nffile, void *record, size_t required) {
563
+
564
+ // flush current buffer to disc
565
+ if ( !CheckBufferSpace(nffile, required)) {
566
+ return;
567
+ }
568
+
569
+ // enough buffer space available at this point
570
+ memcpy(nffile->buff_ptr, record, required);
571
+
572
+ // update stat
573
+ nffile->block_header->NumRecords++;
574
+ nffile->block_header->size += required;
575
+
576
+ // advance write pointer
577
+ nffile->buff_ptr = (void *)((pointer_addr_t)nffile->buff_ptr + required);
578
+
579
+ } // End of AppendToBuffer