Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/netflow/flow-dump.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-2011 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 dump type
23
*
24
* Glenn Fowler
25
* AT&T Research
26
*/
27
28
#include "flowlib.h"
29
30
#include <swap.h>
31
32
typedef struct Hdr_1_s
33
{
34
Nfshort_t version;
35
Nfshort_t count;
36
Nflong_t uptime;
37
Nflong_t sec;
38
Nflong_t nsec;
39
} Hdr_1_t;
40
41
typedef struct Rec_1_s
42
{
43
Nflong_t src_addr;
44
Nflong_t dst_addr;
45
Nflong_t hop;
46
Nfshort_t input;
47
Nfshort_t output;
48
Nflong_t packets;
49
Nflong_t bytes;
50
Nflong_t first;
51
Nflong_t last;
52
Nfshort_t src_port;
53
Nfshort_t dst_port;
54
Nfshort_t pad1;
55
Nfbyte_t prot;
56
Nfbyte_t tos;
57
Nfbyte_t flags;
58
Nfbyte_t tcp_retx_cnt;
59
Nfbyte_t tcp_retx_secs;
60
Nfbyte_t tcp_misseq_cnt;
61
Nflong_t pad2;
62
} Rec_1_t;
63
64
typedef struct Hdr_5_s
65
{
66
Nfshort_t version;
67
Nfshort_t count;
68
Nflong_t uptime;
69
Nflong_t sec;
70
Nflong_t nsec;
71
Nflong_t flow_sequence;
72
Nfbyte_t engine_type;
73
Nfbyte_t engine_id;
74
Nfshort_t sampling_interval;
75
} Hdr_5_t;
76
77
typedef struct Rec_5_s
78
{
79
Nflong_t src_addr;
80
Nflong_t dst_addr;
81
Nflong_t hop;
82
Nfshort_t input;
83
Nfshort_t output;
84
Nflong_t packets;
85
Nflong_t bytes;
86
Nflong_t first;
87
Nflong_t last;
88
Nfshort_t src_port;
89
Nfshort_t dst_port;
90
Nfbyte_t pad1;
91
Nfbyte_t tcp_flags;
92
Nfbyte_t prot;
93
Nfbyte_t tos;
94
Nfshort_t src_as;
95
Nfshort_t dst_as;
96
Nfbyte_t src_mask;
97
Nfbyte_t dst_mask;
98
Nfshort_t pad2;
99
} Rec_5_t;
100
101
typedef struct Hdr_7_s
102
{
103
Nfshort_t version;
104
Nfshort_t count;
105
Nflong_t uptime;
106
Nflong_t sec;
107
Nflong_t nsec;
108
Nflong_t flow_sequence;
109
} Hdr_7_t;
110
111
typedef struct Rec_7_s
112
{
113
Nflong_t src_addr;
114
Nflong_t dst_addr;
115
Nflong_t hop;
116
Nfshort_t input;
117
Nfshort_t output;
118
Nflong_t packets;
119
Nflong_t bytes;
120
Nflong_t first;
121
Nflong_t last;
122
Nfshort_t src_port;
123
Nfshort_t dst_port;
124
Nfbyte_t flags;
125
Nfbyte_t tcp_flags;
126
Nfbyte_t prot;
127
Nfbyte_t tos;
128
Nfshort_t src_as;
129
Nfshort_t dst_as;
130
Nfbyte_t src_mask;
131
Nfbyte_t dst_mask;
132
Nfshort_t pad2;
133
Nflong_t router_sc;
134
} Rec_7_t;
135
136
#define FLOW_TEMPLATE 0
137
#define FLOW_OPTION 1
138
#define FLOW_META 255
139
140
typedef struct Rec_9_s
141
{
142
Nflong_t flowset;
143
Nflong_t size;
144
} Rec_9_t;
145
146
typedef struct State_s
147
{
148
Netflow_t record;
149
char* data;
150
char* next;
151
int swap;
152
int count;
153
int flush;
154
int version;
155
Nftime_t boot;
156
} State_t;
157
158
/*
159
* identf
160
*/
161
162
static int
163
dumpident(Dssfile_t* file, void* buf, size_t n, Dssdisc_t* disc)
164
{
165
if (n < sizeof(Hdr_1_t))
166
return 0;
167
switch (((Hdr_1_t*)buf)->version)
168
{
169
case 1:
170
case 5:
171
case 7:
172
n = ((Hdr_1_t*)buf)->count;
173
return n >= 1 && n <= 30;
174
}
175
switch ((int)swapget(0, buf, 2))
176
{
177
case 1:
178
case 5:
179
case 7:
180
n = (int)swapget(0, (char*)buf + 2, 2);
181
return n >= 1 && n <= 30;
182
}
183
return 0;
184
}
185
186
/*
187
* fopenf
188
*/
189
190
static int
191
dumpfopen(Dssfile_t* file, Dssdisc_t* disc)
192
{
193
State_t* state;
194
195
if (!(state = vmnewof(file->dss->vm, 0, State_t, 1, (file->flags & DSS_FILE_WRITE) ? NETFLOW_PACKET : 0)))
196
{
197
if (disc->errorf)
198
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
199
return -1;
200
}
201
file->data = state;
202
if (file->flags & DSS_FILE_WRITE)
203
state->data = (char*)(state + 1);
204
return 0;
205
}
206
207
/*
208
* freadf
209
*/
210
211
static int
212
dumpfread(register Dssfile_t* file, register Dssrecord_t* record, Dssdisc_t* disc)
213
{
214
register State_t* state = (State_t*)file->data;
215
register Netflow_t* rp = &state->record;
216
Rec_1_t* r1;
217
int n;
218
219
while (!rp->count--)
220
{
221
if (!(state->data = (char*)sfreserve(file->io, NETFLOW_PACKET, 0)))
222
{
223
if (sfvalue(file->io))
224
{
225
if (disc->errorf)
226
(*disc->errorf)(NiL, disc, 2, "%slast packet incomplete", cxlocation(file->dss->cx, record));
227
return -1;
228
}
229
return 0;
230
}
231
state->swap = 0;
232
n = ((Hdr_1_t*)state->data)->version;
233
for (;;)
234
{
235
switch (n)
236
{
237
case 1:
238
n = 16;
239
if (state->swap)
240
{
241
swapmem(1, state->data, &rp->version, 4);
242
swapmem(3, state->data + 4, &rp->uptime, 12);
243
}
244
else
245
memcpy(&rp->version, state->data, n);
246
break;
247
case 5:
248
n = 24;
249
if (state->swap)
250
{
251
swapmem(1, state->data, &rp->version, 4);
252
swapmem(3, state->data + 4, &rp->uptime, 16);
253
memcpy(&rp->engine_type, state->data + 20, 2);
254
swapmem(1, state->data + 22, &rp->sampler_interval, 2);
255
}
256
else
257
memcpy(&rp->version, state->data, n);
258
rp->sampler_mode = (rp->sampler_interval >> 14) & ((1<<2)-1);
259
rp->sampler_interval &= ((1<<14)-1);
260
break;
261
case 7:
262
n = 24;
263
if (state->swap)
264
{
265
swapmem(1, state->data, &rp->version, 4);
266
swapmem(3, state->data + 4, &rp->uptime, 16);
267
}
268
else
269
memcpy(&rp->version, state->data, n);
270
break;
271
default:
272
if (state->swap)
273
{
274
if (disc->errorf)
275
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%sheader corrupted", cxlocation(file->dss->cx, record));
276
return -1;
277
}
278
state->swap = 7;
279
n = swapget(2, state->data, 2);
280
continue;
281
}
282
state->boot = ((Nftime_t)rp->time * MS - (Nftime_t)rp->uptime) * US + (Nftime_t)rp->nsec;
283
break;
284
}
285
state->data += n;
286
}
287
switch (rp->version)
288
{
289
case 1:
290
r1 = (Rec_1_t*)state->data;
291
if (state->swap)
292
{
293
swapmem(3, state->data, &rp->src_addrv4, 12);
294
swapmem(1, state->data + 12, &rp->input, 4);
295
swapmem(3, state->data + 16, &rp->packets, 16);
296
swapmem(1, state->data + 32, &rp->src_port, 4);
297
memcpy(&rp->flags, state->data + 36, 4);
298
}
299
else
300
memcpy(rp, r1, sizeof(Rec_1_t));
301
state->data += sizeof(Rec_1_t);
302
rp->flags = r1->flags;
303
memset(&rp->src_as16, 0, 12);
304
break;
305
case 5:
306
if (state->swap)
307
{
308
swapmem(3, state->data, &rp->src_addrv4, 12);
309
swapmem(1, state->data + 12, &rp->input, 4);
310
swapmem(3, state->data + 16, &rp->packets, 16);
311
swapmem(1, state->data + 32, &rp->src_port, 4);
312
memcpy(&rp->flags, state->data + 36, 4);
313
swapmem(1, state->data + 40, &rp->src_as16, 4);
314
memcpy(&rp->src_maskv4, state->data + 44, 2);
315
}
316
else
317
memcpy(rp, state->data, sizeof(Rec_5_t));
318
state->data += sizeof(Rec_5_t);
319
rp->flags = 0;
320
break;
321
case 7:
322
if (state->swap)
323
{
324
swapmem(3, state->data, &rp->src_addrv4, 12);
325
swapmem(1, state->data + 12, &rp->input, 4);
326
swapmem(3, state->data + 16, &rp->packets, 16);
327
swapmem(1, state->data + 32, &rp->src_port, 4);
328
memcpy(&rp->flags, state->data + 36, 4);
329
swapmem(1, state->data + 40, &rp->src_as16, 4);
330
memcpy(&rp->src_maskv4, state->data + 44, 2);
331
swapmem(1, state->data + 48, &rp->router_scv4, 4);
332
}
333
else
334
memcpy(rp, state->data, sizeof(Rec_7_t));
335
state->data += sizeof(Rec_7_t);
336
break;
337
}
338
rp->start = state->boot + (Nftime_t)rp->first * US;
339
rp->end = state->boot + (Nftime_t)rp->last * US;
340
record->size = sizeof(*rp);
341
record->data = rp;
342
return 1;
343
}
344
345
/*
346
* fwritef
347
*/
348
349
static int
350
dumpfwrite(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
351
{
352
register State_t* state = (State_t*)file->data;
353
register Netflow_t* rp = (Netflow_t*)record->data;
354
register size_t n;
355
356
if (!state->count++)
357
{
358
state->swap = _ast_intswap;
359
switch (rp->version)
360
{
361
case 1:
362
state->flush = 24;
363
n = 16;
364
if (state->swap)
365
{
366
swapmem(1, &rp->version, state->data, 4);
367
swapmem(3, &rp->uptime, state->data + 4, 12);
368
}
369
else
370
memcpy(state->data, &rp->version, n);
371
break;
372
case 5:
373
state->flush = 30;
374
n = 24;
375
if (state->swap)
376
{
377
swapmem(1, &rp->version, state->data, 4);
378
swapmem(3, &rp->uptime, state->data + 4, 16);
379
memcpy(state->data + 20, &rp->engine_type, 2);
380
swapmem(1, &rp->sampler_interval, state->data + 22, 2);
381
*(state->data + 23) |= rp->sampler_mode << 6;
382
}
383
else
384
{
385
memcpy(state->data, &rp->version, n);
386
*(state->data + 22) |= rp->sampler_mode << 6;
387
}
388
break;
389
case 7:
390
state->flush = 27;
391
n = 24;
392
if (state->swap)
393
{
394
swapmem(1, &rp->version, state->data, 4);
395
swapmem(3, &rp->uptime, state->data + 4, 16);
396
}
397
else
398
memcpy(state->data, &rp->version, n);
399
break;
400
}
401
state->next = state->data + n;
402
state->version = rp->version;
403
}
404
if (rp->version != state->version)
405
{
406
if (disc->errorf)
407
(*disc->errorf)(NiL, disc, 2, "%s%d: record version does not match header version %d", cxlocation(file->dss->cx, record), rp->version, state->version);
408
return -1;
409
}
410
switch (rp->version)
411
{
412
case 1:
413
n = sizeof(Rec_1_t);
414
if (state->swap)
415
{
416
swapmem(3, &rp->src_addrv4, state->next, 12);
417
swapmem(1, &rp->input, state->next + 12, 4);
418
swapmem(3, &rp->packets, state->next + 16, 16);
419
swapmem(1, &rp->src_port, state->next + 32, 4);
420
memcpy(state->next + 36, &rp->flags, 4);
421
}
422
else
423
memcpy(state->next, rp, n);
424
#if 0
425
memcpy(&rp->pad1, state->next + 40, 4);
426
#endif
427
*(state->next + 44) = rp->flags;
428
break;
429
case 5:
430
n = sizeof(Rec_5_t);
431
if (state->swap)
432
{
433
swapmem(3, &rp->src_addrv4, state->next, 12);
434
swapmem(1, &rp->input, state->next + 12, 4);
435
swapmem(3, &rp->packets, state->next + 16, 16);
436
swapmem(1, &rp->src_port, state->next + 32, 4);
437
memcpy(state->next + 36, &rp->flags, 4);
438
swapmem(1, &rp->src_as16, state->next + 40, 4);
439
memcpy(state->next + 44, &rp->src_maskv4, 2);
440
}
441
else
442
memcpy(state->next, rp, n);
443
*(state->next + 36) = 0;
444
*(state->next + 46) = 0;
445
*(state->next + 47) = 0;
446
break;
447
case 7:
448
n = sizeof(Rec_7_t);
449
if (state->swap)
450
{
451
swapmem(3, &rp->src_addrv4, state->next, 12);
452
swapmem(1, &rp->input, state->next + 12, 4);
453
swapmem(3, &rp->packets, state->next + 16, 16);
454
swapmem(1, &rp->src_port, state->next + 32, 4);
455
memcpy(state->next + 36, &rp->flags, 4);
456
swapmem(1, &rp->src_as16, state->next + 40, 4);
457
memcpy(state->next + 44, &rp->src_maskv4, 2);
458
swapmem(1, &rp->router_scv4, state->next + 48, 4);
459
}
460
else
461
memcpy(state->next, rp, n);
462
break;
463
}
464
state->next += n;
465
if (state->count >= state->flush)
466
{
467
((Hdr_1_t*)state->data)->count = state->count;
468
if (state->swap)
469
swapmem(1, &((Hdr_1_t*)state->data)->count, &((Hdr_1_t*)state->data)->count, 2);
470
state->count = 0;
471
if (sfwrite(file->io, state->data, NETFLOW_PACKET) != NETFLOW_PACKET)
472
{
473
if (disc->errorf)
474
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: packet write error", file->format->name);
475
return -1;
476
}
477
}
478
return 0;
479
}
480
481
/*
482
* fclosef
483
*/
484
485
static int
486
dumpfclose(Dssfile_t* file, Dssdisc_t* disc)
487
{
488
register State_t* state = (State_t*)file->data;
489
490
if (!state)
491
return -1;
492
if ((file->flags & DSS_FILE_WRITE) && state->count)
493
{
494
((Hdr_1_t*)state->data)->count = state->count;
495
if (state->swap)
496
swapmem(1, &((Hdr_1_t*)state->data)->count, &((Hdr_1_t*)state->data)->count, 2);
497
memset(state->next, 0, NETFLOW_PACKET - (state->next - state->data));
498
if (sfwrite(file->io, state->data, NETFLOW_PACKET) != NETFLOW_PACKET)
499
{
500
if (disc->errorf)
501
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: last packet write error", file->format->name);
502
return -1;
503
}
504
}
505
vmfree(file->dss->vm, state);
506
return 0;
507
}
508
509
Dssformat_t netflow_dump_format =
510
{
511
"dump",
512
"Cisco netflow dump format (2008-06-24)",
513
CXH,
514
dumpident,
515
dumpfopen,
516
dumpfread,
517
dumpfwrite,
518
0,
519
dumpfclose,
520
0,
521
0,
522
netflow_dump_next
523
};
524
525