nfrb 0.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +27 -0
- data/LICENSE.txt +32 -0
- data/README.rdoc +56 -0
- data/Rakefile +58 -0
- data/ext/rb_nfrb/README.files +14 -0
- data/ext/rb_nfrb/config.h +37 -0
- data/ext/rb_nfrb/dnc/nffile_inline.c +579 -0
- data/ext/rb_nfrb/extconf.rb +3 -0
- data/ext/rb_nfrb/fts_compat.c +1129 -0
- data/ext/rb_nfrb/fts_compat.h +126 -0
- data/ext/rb_nfrb/lzoconf.h +413 -0
- data/ext/rb_nfrb/lzodefs.h +1545 -0
- data/ext/rb_nfrb/minilzo.h +102 -0
- data/ext/rb_nfrb/nf_common.h +117 -0
- data/ext/rb_nfrb/nffile.c +1167 -0
- data/ext/rb_nfrb/nffile.h +1439 -0
- data/ext/rb_nfrb/nfrb.c +368 -0
- data/ext/rb_nfrb/nfx.c +636 -0
- data/ext/rb_nfrb/nfx.h +83 -0
- data/ext/rb_nfrb/util.c +517 -0
- data/ext/rb_nfrb/util.h +84 -0
- data/lib/nfrb.rb +5 -0
- data/lib/nfrb/version.rb +16 -0
- data/test/helper.rb +18 -0
- data/test/test_nfrb.rb +7 -0
- metadata +184 -0
data/.document
ADDED
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
|
data/Gemfile.lock
ADDED
@@ -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
|
data/LICENSE.txt
ADDED
@@ -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
|
+
|
data/README.rdoc
ADDED
@@ -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
|
+
|
data/Rakefile
ADDED
@@ -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,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
|