Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/netflow/netflow.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* netflow method
23
*
24
* Glenn Fowler
25
* AT&T Research
26
*/
27
28
#include "flowlib.h"
29
30
Dssformat_t* netflow_formats = netflow_first_format;
31
32
static Cxvariable_t fields[] =
33
{
34
35
CXV("bytes", "number", NETFLOW_bytes, "Bytes sent in duration (synthesized).")
36
CXV("count", "number", NETFLOW_count, "Number of records that follow in packet (header).")
37
CXV("direction", "number", NETFLOW_direction, "Flow direction: 0 - ingress flow, 1 - egress flow.")
38
CXV("dst_addr", "ipaddr_t", NETFLOW_dst_addr, "Destination ip address.")
39
CXV("dst_addrv4", "ipv4addr_t", NETFLOW_dst_addrv4, "Destination ipv4 address.")
40
CXV("dst_addrv6", "ipv6addr_t", NETFLOW_dst_addrv6, "Destination ipv6 address.")
41
CXV("dst_as", "as_t", NETFLOW_dst_as, "Destination BGP AS number.")
42
CXV("dst_as16", "as16_t", NETFLOW_dst_as16, "Destination BGP AS16 number.")
43
CXV("dst_as32", "as32_t", NETFLOW_dst_as32, "Destination BGP AS32 number.")
44
CXV("dst_mask", "number", NETFLOW_dst_mask, "Destination address prefix mask bits.")
45
CXV("dst_maskv4", "number", NETFLOW_dst_maskv4, "Destination ipv4 address prefix mask bits.")
46
CXV("dst_maskv6", "number", NETFLOW_dst_maskv6, "Destination ipv6 address prefix mask bits.")
47
CXV("dst_port", "number", NETFLOW_dst_port, "TCP/UDP destination port number.")
48
CXV("dst_prefix", "ipprefix_t", NETFLOW_dst_prefix, "Destination ip prefix.")
49
CXV("dst_prefixv4", "ipv4prefix_t", NETFLOW_dst_prefixv4, "Destination ipv4 prefix.")
50
CXV("dst_prefixv6", "ipv6prefix_t", NETFLOW_dst_prefixv6, "Destination ipv6 prefix.")
51
CXV("dst_tos", "number", NETFLOW_dst_tos, "Type of Service on exiting outgoing interface.")
52
CXV("dst_vlan", "number", NETFLOW_dst_vlan, "Virtual LAN identifier associated with egress interface.")
53
CXV("end", "ns_t", NETFLOW_end, "Flow end time in 64 bit nanoseconds since the epoch (synthesized).")
54
CXV("engine_id", "number", NETFLOW_engine_id, "ID number of the flow switching engine.")
55
CXV("engine_type", "number", NETFLOW_engine_type, "Type of flow switching engine 0: RP, 1: VIP/linecard.")
56
CXV("first", "elapsed_t", NETFLOW_first, "Elapsed milliseconds at flow start.")
57
CXV("flags", "number", NETFLOW_flags, "Reason flow was discarded, etc.")
58
CXV("flow_active_timeout", "number", NETFLOW_flow_active_timeout, "Timeout value (in seconds) for active flow cache entries.")
59
CXV("flow_inactive_timeout", "number", NETFLOW_flow_inactive_timeout, "Timeout value (in seconds) for inactive flow cache entries.")
60
CXV("flow_label", "number", NETFLOW_flow_label, "ipv6 RFC 2460 flow label.")
61
CXV("flow_sequence", "number", NETFLOW_flow_sequence, "Flow sequence counter (header).")
62
CXV("flows", "number", NETFLOW_flows, "Number of flows that were aggregated.")
63
CXV("forwarding_code", "number", NETFLOW_forwarding_code, "Forwarding reason code.")
64
CXV("forwarding_status", "number", NETFLOW_forwarding_status, "Forwarding status 0: unknown, 1: forwarded, 2: dropped, 3: consumed.")
65
CXV("fragment_offset", "number", NETFLOW_fragment_offset, "Fragmented packet fragment-offset.")
66
CXV("hop", "ipaddr_t", NETFLOW_hop, "Next hop ip address.")
67
CXV("hopv4", "ipv4addr_t", NETFLOW_hopv4, "Next hop ipv4 address.")
68
CXV("hopv6", "ipv6addr_t", NETFLOW_hopv6, "Next hop ipv6 address.")
69
CXV("icmp_type", "number", NETFLOW_icmp_type, "Internet Control Message Protocol packet type coded as ((type*256)+code).")
70
CXV("ident", "number", NETFLOW_ident, "Identification field.")
71
CXV("if_desc", "string", NETFLOW_if_desc, "Full interface name.")
72
CXV("if_name", "string", NETFLOW_if_name, "Shortened interface name.")
73
CXV("in_bytes", "number", NETFLOW_in_bytes, "Incoming counter for the number of bytes associated with an ip Flow.")
74
CXV("in_dst_mac", "number", NETFLOW_in_dst_mac, "Incoming destination MAC address.")
75
CXV("in_permanent_bytes", "number", NETFLOW_in_permanent_bytes, "Permanent flow byte count.")
76
CXV("in_permanent_packets", "number", NETFLOW_in_permanent_packets, "Permanent flow packet count.")
77
CXV("in_packets", "number", NETFLOW_in_packets, "Incoming counter for the number of packets associated with an ip Flow.")
78
CXV("in_src_mac", "number", NETFLOW_in_src_mac, "Incoming source MAC address.")
79
CXV("input_snmp", "number", NETFLOW_input_snmp, "Input interface index.")
80
CXV("ip_protocol_version", "number", NETFLOW_ip_protocol_version, "ip version 6: ipv6, 4 or not specified: ipv4.")
81
CXV("last", "elapsed_t", NETFLOW_last, "Elapsed milliseconds at flow end.")
82
CXV("max_packet_length", "number", NETFLOW_max_packet_length, "Maximum incoming ip packet length.")
83
CXV("max_ttl", "number", NETFLOW_max_ttl, "Maximum TTL on incoming packets.")
84
CXV("min_packet_length", "number", NETFLOW_min_packet_length, "Minimum incoming ip packet length.")
85
CXV("min_ttl", "number", NETFLOW_min_ttl, "Minimum TTL on incoming packets.")
86
CXV("mpls_label_1", "number", NETFLOW_mpls_label_1, "Stack position 1 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
87
CXV("mpls_label_2", "number", NETFLOW_mpls_label_2, "Stack position 2 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
88
CXV("mpls_label_3", "number", NETFLOW_mpls_label_3, "Stack position 3 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
89
CXV("mpls_label_4", "number", NETFLOW_mpls_label_4, "Stack position 4 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
90
CXV("mpls_label_5", "number", NETFLOW_mpls_label_5, "Stack position 5 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
91
CXV("mpls_label_6", "number", NETFLOW_mpls_label_6, "Stack position 6 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
92
CXV("mpls_label_7", "number", NETFLOW_mpls_label_7, "Stack position 7 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
93
CXV("mpls_label_8", "number", NETFLOW_mpls_label_8, "Stack position 8 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
94
CXV("mpls_label_9", "number", NETFLOW_mpls_label_9, "Stack position 9 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
95
CXV("mpls_label_10", "number", NETFLOW_mpls_label_10, "Stack position 10 MPLS label: 20 bits MPLS label, 3 bits experimental, 1 bit end-of-stack.")
96
CXV("mpls_top_label_class", "number", NETFLOW_mpls_top_label_class, "Forwarding Equivalent Class corresponding to the MPLS Top Label.")
97
CXV("mpls_top_label_type", "number", NETFLOW_mpls_top_label_type, "MPLS top label type: 0x00 UNKNOWN 0x01 TE-MIDPT 0x02 ATOM 0x03 VPN 0x04 BGP 0x05 LDP.")
98
CXV("mul_dst_bytes", "number", NETFLOW_mul_dst_bytes, "Multicast outgoing byte count.")
99
CXV("mul_dst_packets", "number", NETFLOW_mul_dst_packets, "Multicast outgoing packet count.")
100
CXV("mul_igmp_type", "number", NETFLOW_mul_igmp_type, "Internet Group Management Protocol packet type coded.")
101
CXV("nsec", "number", NETFLOW_nsec, "Residual nanoseconds (header).")
102
CXV("option_headers", "number", NETFLOW_option_headers, "Bit-encoded field identifying ipv6 option headers found in the flow.")
103
CXV("out_bytes", "number", NETFLOW_out_bytes, "Outgoing counter for the number of bytes associated with an ip Flow.")
104
CXV("out_dst_mac", "number", NETFLOW_out_dst_mac, "Outgoing destination MAC address.")
105
CXV("out_packets", "number", NETFLOW_out_packets, "Outgoing counter for the number of packets associated with an ip Flow.")
106
CXV("out_src_mac", "number", NETFLOW_out_src_mac, "Outgoing source MAC address.")
107
CXV("output_snmp", "number", NETFLOW_output_snmp, "Output interface index.")
108
CXV("packets", "number", NETFLOW_packets, "Number of packets in flow.")
109
CXV("prot", "number", NETFLOW_protocol, "ip protocol, e.g., 6=TCP, 17=UDP, ...")
110
CXV("router_sc", "ipaddr_t", NETFLOW_router_sc, "Router shortcut ip address (V7).")
111
CXV("router_scv4", "ipv4addr_t", NETFLOW_router_scv4, "Router shortcut ipv4 address.")
112
CXV("router_scv6", "ipv6addr_t", NETFLOW_router_scv6, "Router shortcut ipv6 address.")
113
CXV("sampler_algorithm", "number", NETFLOW_sampler_algorithm, "0x01: deterministic, 0x02: random.")
114
CXV("sampler_interval", "number", NETFLOW_sampler_interval, "Sampling interval.")
115
CXV("sampler_mode", "number", NETFLOW_sampler_mode, "Sampling mode.")
116
CXV("sampler_name", "string", NETFLOW_sampler_name, "Flow sampler name.")
117
CXV("src_addr", "ipaddr_t", NETFLOW_src_addr, "Source ip address.")
118
CXV("src_addrv4", "ipv4addr_t", NETFLOW_src_addrv4, "Source ipv4 address.")
119
CXV("src_addrv6", "ipv6addr_t", NETFLOW_src_addrv6, "Source ipv6 address.")
120
CXV("src_as", "as_t", NETFLOW_src_as, "Source BGP AS number.")
121
CXV("src_as16", "as16_t", NETFLOW_src_as16, "Source BGP AS16 number.")
122
CXV("src_as32", "as32_t", NETFLOW_src_as32, "Source BGP AS32 number.")
123
CXV("src_mask", "number", NETFLOW_src_mask, "Source address prefix mask bits.")
124
CXV("src_maskv4", "number", NETFLOW_src_maskv4, "Source ipv4 address prefix mask bits.")
125
CXV("src_maskv6", "number", NETFLOW_src_maskv6, "Source ipv6 address prefix mask bits.")
126
CXV("src_port", "number", NETFLOW_src_port, "TCP/UDP source port number.")
127
CXV("src_prefix", "ipprefix_t", NETFLOW_src_prefix, "Source ip prefix.")
128
CXV("src_prefixv4", "ipv4prefix_t", NETFLOW_src_prefixv4, "Source ipv4 prefix.")
129
CXV("src_prefixv6", "ipv6prefix_t", NETFLOW_src_prefixv6, "Source ipv6 prefix.")
130
CXV("src_tos", "number", NETFLOW_src_tos, "ip type-of-service upon entering incoming interface.")
131
CXV("src_vlan", "number", NETFLOW_src_vlan, "Virtual LAN identifier associated with ingress interface.")
132
CXV("start", "ns_t", NETFLOW_start, "Flow start time in 64 bit nanoseconds since the epoch (synthesized).")
133
CXV("tcp_flags", "number", NETFLOW_tcp_flags, "Cumulative OR of tcp flags for this flow.")
134
CXV("tcp_misseq_cnt", "number", NETFLOW_tcp_misseq_cnt, "Number of mis-sequenced tcp packets (V1).")
135
CXV("tcp_retx_cnt", "number", NETFLOW_tcp_retx_cnt, "Number of mis-seq with delay > 1sec (V1).")
136
CXV("tcp_retx_secs", "number", NETFLOW_tcp_retx_secs, "Number of seconds between mis-sequenced packets (V1).")
137
CXV("time", "time_t", NETFLOW_time, "Current time in seconds since the epoch (header).")
138
CXV("tos", "number", NETFLOW_tos, "ip type-of-service (synthesized).")
139
CXV("total_bytes_exp", "number", NETFLOW_total_bytes_exp, "The number of bytes exported by the observation domain.")
140
CXV("total_flows_exp", "number", NETFLOW_total_flows_exp, "The number of flows exported by the observation domain.")
141
CXV("total_packets_exp", "number", NETFLOW_total_packets_exp, "The number of packets exported by the observation domain.")
142
CXV("uptime", "elapsed_t", NETFLOW_uptime, "Elapsed milliseconds since the router booted (header).")
143
CXV("vendor_43", "number", NETFLOW_vendor_43, "Vendor private value.")
144
CXV("vendor_51", "number", NETFLOW_vendor_51, "Vendor private value.")
145
CXV("vendor_65", "number", NETFLOW_vendor_65, "Vendor private value.")
146
CXV("vendor_66", "number", NETFLOW_vendor_66, "Vendor private value.")
147
CXV("vendor_67", "number", NETFLOW_vendor_67, "Vendor private value.")
148
CXV("vendor_68", "number", NETFLOW_vendor_68, "Vendor private value.")
149
CXV("vendor_69", "number", NETFLOW_vendor_69, "Vendor private value.")
150
CXV("vendor_87", "number", NETFLOW_vendor_87, "Vendor private value.")
151
CXV("version", "number", NETFLOW_version, "Record version (header).")
152
153
{0}
154
};
155
156
static int
157
op_get(Cx_t* cx, Cxinstruction_t* pc, Cxoperand_t* r, Cxoperand_t* a, Cxoperand_t* b, void* data, Cxdisc_t* disc)
158
{
159
Netflow_method_t* gp = (Netflow_method_t*)(((Dssrecord_t*)(data))->file)->dss->data;
160
Netflow_file_t* pp = (Netflow_file_t*)(((Dssrecord_t*)(data))->file)->data;
161
Netflow_t* rp = (Netflow_t*)DSSDATA(data);
162
Cxvariable_t* vp = pc->data.variable;
163
Netflow_field_t* fp;
164
165
if (pp->template && vp->index > 0 && vp->index <= NETFLOW_TEMPLATE)
166
{
167
fp = &pp->template->field[vp->index - 1];
168
switch (fp->type)
169
{
170
case NETFLOW_BUFFER:
171
r->value.buffer.data = pp->data + fp->offset;
172
r->value.buffer.size = fp->size;
173
break;
174
case NETFLOW_NUMBER:
175
r->value.number = swapget(0, pp->data + fp->offset, fp->size);
176
break;
177
default:
178
memset(&r->value, 0, sizeof(r->value));
179
break;
180
}
181
return 0;
182
}
183
switch (vp->index)
184
{
185
case NETFLOW_bytes:
186
r->value.number = rp->bytes ? rp->bytes : rp->in_bytes;
187
break;
188
case NETFLOW_count:
189
r->value.number = rp->count;
190
break;
191
case NETFLOW_direction:
192
r->value.number = rp->direction;
193
break;
194
case NETFLOW_dst_addr:
195
if (rp->set & NETFLOW_SET_dst_addrv6)
196
{
197
r->value.buffer.data = rp->dst_addrv6;
198
r->value.buffer.size = sizeof(rp->dst_addrv6) - 1;
199
r->type = gp->type_ipv6addr;
200
}
201
else
202
{
203
r->value.number = rp->dst_addrv4;
204
r->type = gp->type_ipv4addr;
205
}
206
break;
207
case NETFLOW_dst_addrv4:
208
r->value.number = rp->dst_addrv4;
209
break;
210
case NETFLOW_dst_addrv6:
211
r->value.buffer.data = rp->dst_addrv6;
212
r->value.buffer.size = sizeof(rp->dst_addrv6) - 1;
213
break;
214
case NETFLOW_dst_as:
215
r->value.number = rp->dst_as16 ? rp->dst_as16 : rp->dst_as32;
216
break;
217
case NETFLOW_dst_as16:
218
r->value.number = rp->dst_as16;
219
break;
220
case NETFLOW_dst_as32:
221
r->value.number = rp->dst_as32;
222
break;
223
case NETFLOW_dst_mask:
224
r->value.number = (rp->set & NETFLOW_SET_dst_addrv6) ? rp->dst_addrv6[IP6BITS] : rp->dst_maskv4;
225
break;
226
case NETFLOW_dst_maskv4:
227
r->value.number = rp->dst_maskv4;
228
break;
229
case NETFLOW_dst_maskv6:
230
r->value.number = rp->dst_addrv6[IP6BITS];
231
break;
232
case NETFLOW_dst_port:
233
r->value.number = rp->dst_port;
234
break;
235
case NETFLOW_dst_prefix:
236
if (rp->set & NETFLOW_SET_dst_addrv6)
237
{
238
r->value.buffer.data = rp->dst_addrv6;
239
r->value.buffer.size = sizeof(rp->dst_addrv6);
240
r->type = gp->type_ipv6prefix;
241
}
242
else
243
{
244
r->value.number = (Cxnumber_t)rp->dst_addrv4 * 64 + rp->dst_maskv4;
245
r->type = gp->type_ipv4prefix;
246
}
247
break;
248
case NETFLOW_dst_prefixv4:
249
r->value.number = (Cxnumber_t)rp->dst_addrv4 * 64 + rp->dst_maskv4;
250
break;
251
case NETFLOW_dst_prefixv6:
252
r->value.buffer.data = rp->dst_addrv6;
253
r->value.buffer.size = sizeof(rp->dst_addrv6);
254
break;
255
case NETFLOW_dst_tos:
256
r->value.number = rp->dst_tos ? rp->dst_tos : rp->src_tos;
257
break;
258
case NETFLOW_dst_vlan:
259
r->value.number = rp->dst_vlan;
260
break;
261
case NETFLOW_end:
262
#if _typ_int64_t
263
r->value.number = (int64_t)rp->end; /* ms cc requires signed */
264
#else
265
r->value.number = rp->end;
266
#endif
267
break;
268
case NETFLOW_engine_id:
269
r->value.number = rp->engine_id;
270
break;
271
case NETFLOW_engine_type:
272
r->value.number = rp->engine_type;
273
break;
274
case NETFLOW_first:
275
r->value.number = rp->first;
276
break;
277
case NETFLOW_flags:
278
r->value.number = rp->forwarding_code;
279
break;
280
case NETFLOW_flow_active_timeout:
281
r->value.number = rp->flow_active_timeout;
282
break;
283
case NETFLOW_flow_inactive_timeout:
284
r->value.number = rp->flow_inactive_timeout;
285
break;
286
case NETFLOW_flow_label:
287
r->value.number = rp->flow_label;
288
break;
289
case NETFLOW_sampler_random_interval:
290
r->value.number = rp->sampler_random_interval;
291
break;
292
case NETFLOW_flow_sequence:
293
r->value.number = rp->flow_sequence;
294
break;
295
case NETFLOW_flows:
296
r->value.number = rp->flows;
297
break;
298
case NETFLOW_forwarding_code:
299
r->value.number = rp->forwarding_code;
300
break;
301
case NETFLOW_forwarding_status:
302
r->value.number = rp->forwarding_status;
303
break;
304
case NETFLOW_fragment_offset:
305
r->value.number = rp->fragment_offset;
306
break;
307
case NETFLOW_hop:
308
if (rp->set & NETFLOW_SET_hopv6)
309
{
310
r->value.buffer.data = rp->hopv6;
311
r->value.buffer.size = sizeof(rp->hopv6);
312
r->type = gp->type_ipv6addr;
313
}
314
else
315
{
316
r->value.number = rp->hopv4;
317
r->type = gp->type_ipv4addr;
318
}
319
break;
320
case NETFLOW_hopv4:
321
r->value.number = rp->hopv4;
322
break;
323
case NETFLOW_hopv6:
324
r->value.buffer.data = rp->hopv6;
325
r->value.buffer.size = sizeof(rp->hopv6);
326
break;
327
case NETFLOW_ident:
328
r->value.number = rp->ident;
329
break;
330
case NETFLOW_icmp_type:
331
r->value.number = rp->icmp_type;
332
break;
333
case NETFLOW_if_desc:
334
r->value.string.size = strlen(r->value.string.data = (char*)rp->if_desc);
335
break;
336
case NETFLOW_if_name:
337
r->value.string.size = strlen(r->value.string.data = (char*)rp->if_name);
338
break;
339
case NETFLOW_in_bytes:
340
r->value.number = rp->in_bytes;
341
break;
342
case NETFLOW_in_dst_mac:
343
r->value.number = rp->in_dst_mac;
344
break;
345
case NETFLOW_in_permanent_bytes:
346
r->value.number = rp->in_permanent_bytes;
347
break;
348
case NETFLOW_in_permanent_packets:
349
r->value.number = rp->in_permanent_packets;
350
break;
351
case NETFLOW_in_packets:
352
r->value.number = rp->in_packets ? rp->in_packets : rp->packets;
353
break;
354
case NETFLOW_in_src_mac:
355
r->value.number = rp->in_src_mac;
356
break;
357
case NETFLOW_input_snmp:
358
r->value.number = rp->input_snmp ? rp->input_snmp : rp->input;
359
break;
360
case NETFLOW_ip_protocol_version:
361
r->value.number = rp->ip_protocol_version;
362
break;
363
case NETFLOW_last:
364
r->value.number = rp->last;
365
break;
366
case NETFLOW_max_packet_length:
367
r->value.number = rp->max_packet_length;
368
break;
369
case NETFLOW_max_ttl:
370
r->value.number = rp->max_ttl;
371
break;
372
case NETFLOW_min_packet_length:
373
r->value.number = rp->min_packet_length;
374
break;
375
case NETFLOW_min_ttl:
376
r->value.number = rp->min_ttl;
377
break;
378
case NETFLOW_mpls_label_1:
379
r->value.number = rp->mpls_label_1;
380
break;
381
case NETFLOW_mpls_label_2:
382
r->value.number = rp->mpls_label_2;
383
break;
384
case NETFLOW_mpls_label_3:
385
r->value.number = rp->mpls_label_3;
386
break;
387
case NETFLOW_mpls_label_4:
388
r->value.number = rp->mpls_label_4;
389
break;
390
case NETFLOW_mpls_label_5:
391
r->value.number = rp->mpls_label_5;
392
break;
393
case NETFLOW_mpls_label_6:
394
r->value.number = rp->mpls_label_6;
395
break;
396
case NETFLOW_mpls_label_7:
397
r->value.number = rp->mpls_label_7;
398
break;
399
case NETFLOW_mpls_label_8:
400
r->value.number = rp->mpls_label_8;
401
break;
402
case NETFLOW_mpls_label_9:
403
r->value.number = rp->mpls_label_9;
404
break;
405
case NETFLOW_mpls_label_10:
406
r->value.number = rp->mpls_label_10;
407
break;
408
case NETFLOW_mpls_top_label_class:
409
r->value.number = rp->mpls_top_label_class;
410
break;
411
case NETFLOW_mpls_top_label_type:
412
r->value.number = rp->mpls_top_label_type;
413
break;
414
case NETFLOW_mul_dst_bytes:
415
r->value.number = rp->mul_dst_bytes;
416
break;
417
case NETFLOW_mul_dst_packets:
418
r->value.number = rp->mul_dst_packets;
419
break;
420
case NETFLOW_mul_igmp_type:
421
r->value.number = rp->mul_igmp_type;
422
break;
423
case NETFLOW_nsec:
424
r->value.number = rp->nsec;
425
break;
426
case NETFLOW_option_headers:
427
r->value.number = rp->option_headers;
428
break;
429
case NETFLOW_out_bytes:
430
r->value.number = rp->out_bytes;
431
break;
432
case NETFLOW_out_dst_mac:
433
r->value.number = rp->out_dst_mac;
434
break;
435
case NETFLOW_out_packets:
436
r->value.number = rp->out_packets ? rp->out_packets : rp->packets;
437
break;
438
case NETFLOW_out_src_mac:
439
r->value.number = rp->out_src_mac;
440
break;
441
case NETFLOW_output_snmp:
442
r->value.number = rp->output_snmp ? rp->output_snmp : rp->output;
443
break;
444
case NETFLOW_packets:
445
r->value.number = rp->packets ? rp->packets : rp->out_packets ? rp->out_packets : rp->in_packets;
446
break;
447
case NETFLOW_protocol:
448
r->value.number = rp->protocol;
449
break;
450
case NETFLOW_router_sc:
451
if (rp->set & NETFLOW_SET_router_scv6)
452
{
453
r->value.buffer.data = rp->router_scv6;
454
r->value.buffer.size = sizeof(rp->router_scv6);
455
r->type = gp->type_ipv6addr;
456
}
457
else
458
{
459
r->value.number = rp->router_scv4;
460
r->type = gp->type_ipv4addr;
461
}
462
break;
463
case NETFLOW_router_scv4:
464
r->value.number = rp->router_scv4;
465
break;
466
case NETFLOW_router_scv6:
467
r->value.buffer.data = rp->router_scv6;
468
r->value.buffer.size = sizeof(rp->router_scv6);
469
break;
470
case NETFLOW_sampler_algorithm:
471
r->value.number = rp->sampler_algorithm;
472
break;
473
case NETFLOW_sampler_interval:
474
r->value.number = rp->sampler_interval;
475
break;
476
case NETFLOW_sampler_mode:
477
r->value.number = rp->sampler_mode;
478
break;
479
case NETFLOW_sampler_name:
480
r->value.string.size = strlen(r->value.string.data = (char*)rp->sampler_name);
481
break;
482
case NETFLOW_src_addr:
483
if (rp->set & NETFLOW_SET_src_addrv6)
484
{
485
r->value.buffer.data = rp->src_addrv6;
486
r->value.buffer.size = sizeof(rp->src_addrv6) - 1;
487
r->type = gp->type_ipv6addr;
488
}
489
else
490
{
491
r->value.number = rp->src_addrv4;
492
r->type = gp->type_ipv4addr;
493
}
494
break;
495
case NETFLOW_src_addrv4:
496
r->value.number = rp->src_addrv4;
497
break;
498
case NETFLOW_src_addrv6:
499
r->value.buffer.data = rp->src_addrv6;
500
r->value.buffer.size = sizeof(rp->src_addrv6) - 1;
501
break;
502
case NETFLOW_src_as:
503
r->value.number = rp->src_as16 ? rp->src_as16 : rp->src_as32;
504
break;
505
case NETFLOW_src_as16:
506
r->value.number = rp->src_as16;
507
break;
508
case NETFLOW_src_as32:
509
r->value.number = rp->src_as32;
510
break;
511
case NETFLOW_src_mask:
512
r->value.number = (rp->set & NETFLOW_SET_src_addrv6) ? rp->src_addrv6[IP6BITS] : rp->src_maskv4;
513
break;
514
case NETFLOW_src_maskv4:
515
r->value.number = rp->src_maskv4;
516
break;
517
case NETFLOW_src_maskv6:
518
r->value.number = rp->src_addrv6[IP6BITS];
519
break;
520
case NETFLOW_src_port:
521
r->value.number = rp->src_port;
522
break;
523
case NETFLOW_src_prefix:
524
if (rp->set & NETFLOW_SET_src_addrv6)
525
{
526
r->value.buffer.data = rp->src_addrv6;
527
r->value.buffer.size = sizeof(rp->src_addrv6);
528
r->type = gp->type_ipv6prefix;
529
}
530
else
531
{
532
r->value.number = (Cxnumber_t)rp->src_addrv4 * 64 + rp->src_maskv4;
533
r->type = gp->type_ipv4prefix;
534
}
535
break;
536
case NETFLOW_src_prefixv4:
537
r->value.number = (Cxnumber_t)rp->src_addrv4 * 64 + rp->src_maskv4;
538
break;
539
case NETFLOW_src_prefixv6:
540
r->value.buffer.data = rp->src_addrv6;
541
r->value.buffer.size = sizeof(rp->src_addrv6);
542
break;
543
case NETFLOW_src_tos:
544
r->value.number = rp->src_tos;
545
break;
546
case NETFLOW_src_vlan:
547
r->value.number = rp->src_vlan;
548
break;
549
case NETFLOW_start:
550
#if _typ_int64_t
551
r->value.number = (int64_t)rp->start; /* ms cc requires signed */
552
#else
553
r->value.number = rp->start;
554
#endif
555
break;
556
case NETFLOW_tcp_flags:
557
r->value.number = rp->tcp_flags;
558
break;
559
case NETFLOW_tcp_misseq_cnt:
560
r->value.number = rp->tcp_misseq_cnt;
561
break;
562
case NETFLOW_tcp_retx_cnt:
563
r->value.number = rp->tcp_retx_cnt;
564
break;
565
case NETFLOW_tcp_retx_secs:
566
r->value.number = rp->tcp_retx_secs;
567
break;
568
case NETFLOW_time:
569
r->value.number = rp->time;
570
break;
571
case NETFLOW_tos:
572
r->value.number = rp->src_tos;
573
break;
574
case NETFLOW_total_bytes_exp:
575
r->value.number = rp->total_bytes_exp;
576
break;
577
case NETFLOW_total_flows_exp:
578
r->value.number = rp->total_flows_exp;
579
break;
580
case NETFLOW_total_packets_exp:
581
r->value.number = rp->total_packets_exp;
582
break;
583
case NETFLOW_uptime:
584
r->value.number = rp->uptime;
585
break;
586
case NETFLOW_vendor_43:
587
r->value.number = rp->vendor_43;
588
break;
589
case NETFLOW_vendor_51:
590
r->value.number = rp->vendor_51;
591
break;
592
case NETFLOW_vendor_65:
593
r->value.number = rp->vendor_65;
594
break;
595
case NETFLOW_vendor_66:
596
r->value.number = rp->vendor_66;
597
break;
598
case NETFLOW_vendor_67:
599
r->value.number = rp->vendor_67;
600
break;
601
case NETFLOW_vendor_68:
602
r->value.number = rp->vendor_68;
603
break;
604
case NETFLOW_vendor_69:
605
r->value.number = rp->vendor_69;
606
break;
607
case NETFLOW_vendor_87:
608
r->value.number = rp->vendor_87;
609
break;
610
case NETFLOW_version:
611
r->value.number = rp->version;
612
break;
613
default:
614
if (disc->errorf)
615
(*disc->errorf)(cx, disc, ERROR_PANIC, "%s: variable index %d not implemented", vp->name, vp->index);
616
return -1;
617
}
618
return 0;
619
}
620
621
static Cxcallout_t local_callouts[] =
622
{
623
CXC(CX_GET, "void", "void", op_get, 0)
624
};
625
626
/*
627
* methf
628
*/
629
630
extern Dsslib_t dss_lib_netflow;
631
632
static Dssmeth_t*
633
netflowmeth(const char* name, const char* options, const char* schema, Dssdisc_t* disc, Dssmeth_t* meth)
634
{
635
Dssformat_t* fp;
636
char* s;
637
int i;
638
639
for (fp = netflow_formats; fp; fp = fp->next)
640
dtinsert(meth->formats, fp);
641
for (i = 0; i < elementsof(local_callouts); i++)
642
if (cxaddcallout(meth->cx, &local_callouts[i], disc))
643
return 0;
644
for (i = 0; fields[i].name; i++)
645
if (cxaddvariable(meth->cx, &fields[i], disc))
646
return 0;
647
if (options)
648
{
649
if (dssoptlib(meth->cx->buf, &dss_lib_netflow, NiL, disc))
650
return 0;
651
s = sfstruse(meth->cx->buf);
652
for (;;)
653
{
654
switch (optstr(options, s))
655
{
656
case '?':
657
if (disc->errorf)
658
(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
659
return 0;
660
case ':':
661
if (disc->errorf)
662
(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
663
return 0;
664
}
665
break;
666
}
667
}
668
return meth;
669
}
670
671
#define BUFFER(n,f) { offsetof(Netflow_t,n), sizeof(flow->n), NETFLOW_BUFFER, f }
672
#define NUMBER(n,f) { offsetof(Netflow_t,n), sizeof(flow->n), NETFLOW_NUMBER, f }
673
674
static Netflow_t* flow;
675
676
/*
677
* NOTE: template.field[] order, NETFLOW_* and Netflow_t must all match
678
*/
679
680
static const Netflow_template_t template =
681
{
682
0,
683
0,
684
0,
685
0,
686
0,
687
0,
688
{
689
NUMBER(in_bytes, 0),
690
NUMBER(in_packets, 0),
691
NUMBER(flows, 0),
692
NUMBER(protocol, 0),
693
NUMBER(src_tos, 0),
694
NUMBER(tcp_flags, 0),
695
NUMBER(src_port, 0),
696
NUMBER(src_addrv4, NETFLOW_SET_src_addrv4),
697
NUMBER(src_maskv4, 0),
698
NUMBER(input_snmp, 0),
699
NUMBER(dst_port, 0),
700
NUMBER(dst_addrv4, NETFLOW_SET_dst_addrv4),
701
NUMBER(dst_maskv4, 0),
702
NUMBER(output_snmp, 0),
703
NUMBER(hopv4, NETFLOW_SET_hopv4),
704
NUMBER(src_as16, 0),
705
NUMBER(dst_as16, 0),
706
NUMBER(bgp_hopv4, NETFLOW_SET_bgp_hopv4),
707
NUMBER(mul_dst_packets, 0),
708
NUMBER(mul_dst_bytes, 0),
709
NUMBER(last, 0),
710
NUMBER(first, 0),
711
NUMBER(out_bytes, 0),
712
NUMBER(out_packets, 0),
713
NUMBER(min_packet_length, 0),
714
NUMBER(max_packet_length, 0),
715
BUFFER(src_addrv6, NETFLOW_SET_src_addrv6),
716
BUFFER(dst_addrv6, NETFLOW_SET_dst_addrv6),
717
NUMBER(src_maskv6, 0),
718
NUMBER(dst_maskv6, 0),
719
NUMBER(flow_label, 0),
720
NUMBER(icmp_type, 0),
721
NUMBER(mul_igmp_type, 0),
722
NUMBER(sampler_interval, 0),
723
NUMBER(sampler_algorithm, 0),
724
NUMBER(flow_active_timeout, 0),
725
NUMBER(flow_inactive_timeout, 0),
726
NUMBER(engine_type, 0),
727
NUMBER(engine_id, 0),
728
NUMBER(total_bytes_exp, 0),
729
NUMBER(total_packets_exp, 0),
730
NUMBER(total_flows_exp, 0),
731
BUFFER(vendor_43, 0),
732
NUMBER(src_prefixv4, NETFLOW_SET_src_addrv4),
733
NUMBER(dst_prefixv4, NETFLOW_SET_dst_addrv4),
734
NUMBER(mpls_top_label_type, 0),
735
NUMBER(mpls_top_label_class, 0),
736
NUMBER(sampler_id, 0),
737
NUMBER(sampler_mode, 0),
738
NUMBER(sampler_random_interval, 0),
739
BUFFER(vendor_51, 0),
740
NUMBER(min_ttl, 0),
741
NUMBER(max_ttl, 0),
742
NUMBER(ident, 0),
743
NUMBER(dst_tos, 0),
744
NUMBER(in_src_mac, 0),
745
NUMBER(out_dst_mac, 0),
746
NUMBER(src_vlan, 0),
747
NUMBER(dst_vlan, 0),
748
NUMBER(ip_protocol_version, 0),
749
NUMBER(direction, 0),
750
BUFFER(hopv6, NETFLOW_SET_hopv6),
751
BUFFER(bgp_hopv6, NETFLOW_SET_bgp_hopv6),
752
NUMBER(option_headers, 0),
753
BUFFER(vendor_65, 0),
754
BUFFER(vendor_66, 0),
755
BUFFER(vendor_67, 0),
756
BUFFER(vendor_68, 0),
757
BUFFER(vendor_69, 0),
758
NUMBER(mpls_label_1, 0),
759
NUMBER(mpls_label_2, 0),
760
NUMBER(mpls_label_3, 0),
761
NUMBER(mpls_label_4, 0),
762
NUMBER(mpls_label_5, 0),
763
NUMBER(mpls_label_6, 0),
764
NUMBER(mpls_label_7, 0),
765
NUMBER(mpls_label_8, 0),
766
NUMBER(mpls_label_9, 0),
767
NUMBER(mpls_label_10, 0),
768
NUMBER(in_dst_mac, 0),
769
NUMBER(out_src_mac, 0),
770
BUFFER(if_name, 0),
771
BUFFER(if_desc, 0),
772
BUFFER(sampler_name, 0),
773
NUMBER(in_permanent_bytes, 0),
774
NUMBER(in_permanent_packets, 0),
775
BUFFER(vendor_87, 0),
776
NUMBER(fragment_offset, 0),
777
NUMBER(forwarding_status, 0),
778
}
779
};
780
781
/*
782
* openf
783
*/
784
785
static int
786
netflowopen(Dss_t* dss, Dssdisc_t* disc)
787
{
788
Netflow_method_t* flow;
789
790
if (!(flow = vmnewof(dss->vm, 0, Netflow_method_t, 1, 0)) ||
791
!(flow->type_ipv4addr = cxtype(dss->cx, "ipv4addr_t", disc)) ||
792
!(flow->type_ipv4prefix = cxtype(dss->cx, "ipv4prefix_t", disc)) ||
793
!(flow->type_ipv6addr = cxtype(dss->cx, "ipv6addr_t", disc)) ||
794
!(flow->type_ipv6prefix = cxtype(dss->cx, "ipv6prefix_t", disc)) ||
795
!(flow->tmp = sfstropen()))
796
{
797
if (flow)
798
vmfree(dss->vm, flow);
799
if (disc->errorf)
800
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
801
return -1;
802
}
803
flow->base = (Netflow_template_t*)&template;
804
dss->data = flow;
805
return 0;
806
}
807
808
static const char* libraries[] = { "time_t", "ip_t", 0 };
809
810
static Dssmeth_t method =
811
{
812
"netflow",
813
"Cisco router netflow dump data",
814
CXH,
815
netflowmeth,
816
netflowopen,
817
0,
818
0,
819
"%(time:%+u%K)s %(prot)d %(src_addr)s:%(src_port)d %(dst_addr)s:%(dst_port)d %(hop)s"
820
};
821
822
Dsslib_t dss_lib_netflow =
823
{
824
"netflow",
825
"netflow method"
826
"[-1ls5Pp0?\n@(#)$Id: dss netflow method (AT&T Research) 2010-02-02 $\n]"
827
USAGE_LICENSE,
828
CXH,
829
&libraries[0],
830
&method,
831
};
832
833