Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/netflow/flow-dumpv9.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
#define FLOW_TEMPLATE 0
31
#define FLOW_OPTION 1
32
#define FLOW_META 255
33
34
#define BE2(p) ((p)+=2,(*(p-2)<<8)|(*(p-1)))
35
#define BE4(p) ((p)+=4,(*(p-4)<<24)|(*(p-3)<<16)|(*(p-2)<<8)|(*(p-1)))
36
37
/*
38
* identf
39
*/
40
41
static int
42
dumpv9ident(Dssfile_t* file, void* buf, size_t n, Dssdisc_t* disc)
43
{
44
register unsigned char* b = buf;
45
46
return n >= 20 && BE2(b) == 9 && (n = BE2(b)) >= 1 && n <= 255;
47
}
48
49
/*
50
* fopenf
51
*/
52
53
static int
54
dumpv9fopen(Dssfile_t* file, Dssdisc_t* disc)
55
{
56
Netflow_file_t* pp;
57
58
if (!(pp = vmnewof(file->vm, 0, Netflow_file_t, 1, (file->flags & DSS_FILE_WRITE) ? NETFLOW_PACKET : 0)))
59
{
60
if (disc->errorf)
61
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
62
return -1;
63
}
64
file->data = pp;
65
pp->data = pp->last = 0;
66
pp->data++;
67
return 0;
68
}
69
70
/*
71
* freadf
72
*/
73
74
static int
75
dumpv9fread(register Dssfile_t* file, register Dssrecord_t* record, Dssdisc_t* disc)
76
{
77
register Netflow_file_t* pp = (Netflow_file_t*)file->data;
78
register Netflow_method_t* mp = (Netflow_method_t*)file->dss->data;
79
register Netflow_t* rp = &pp->record;
80
register Netflow_template_t* tp;
81
register Netflow_template_t* bp;
82
register Netflow_field_t* fp;
83
int n;
84
int m;
85
int k;
86
int z;
87
int o;
88
89
if ((pp->data += pp->next) <= (pp->last - pp->next))
90
{
91
if (file->dss->flags & DSS_DEBUG)
92
sfprintf(sfstderr, "count %d\n", pp->count);
93
pp->count--;
94
}
95
else
96
{
97
pp->data = pp->last;
98
for (;;)
99
{
100
if (file->dss->flags & DSS_DEBUG)
101
sfprintf(sfstderr, "count %d\n", pp->count);
102
while (!pp->count--)
103
{
104
file->offset = sftell(file->io);
105
if (!(pp->data = (unsigned char*)sfreserve(file->io, NETFLOW_PACKET, 0)))
106
{
107
if (sfvalue(file->io))
108
goto incomplete;
109
return 0;
110
}
111
if ((rp->version = BE2(pp->data)) != 9)
112
goto corrupt;
113
pp->count = rp->count = BE2(pp->data);
114
if (file->dss->flags & DSS_DEBUG)
115
sfprintf(sfstderr, "header version %d size %d flowsets %d offset %I*d\n", rp->version, 20, pp->count, sizeof(file->offset), file->offset);
116
rp->uptime = BE4(pp->data);
117
rp->time = BE4(pp->data);
118
rp->flow_sequence = BE4(pp->data);
119
rp->source_id = BE4(pp->data);
120
pp->boot = ((Nftime_t)rp->time * MS - (Nftime_t)rp->uptime) * US + (Nftime_t)rp->nsec;
121
}
122
if (file->dss->flags & DSS_DEBUG)
123
sfprintf(sfstderr, "record %d flowset %d\n", file->count, rp->count - pp->count);
124
n = BE2(pp->data);
125
if ((z = BE2(pp->data) - 4) <= 0)
126
{
127
pp->count = 0;
128
continue;
129
}
130
pp->last = pp->data + z;
131
if (file->dss->flags & DSS_DEBUG)
132
sfprintf(sfstderr, "id %d size %d\n", n, z);
133
if (n > FLOW_META)
134
{
135
for (tp = mp->templates; tp && tp->id != n; tp = tp->next);
136
if (!tp || !tp->size)
137
{
138
if (!(file->dss->flags & DSS_QUIET) && disc->errorf)
139
(*disc->errorf)(NiL, disc, 1, "%s%d: undefined template -- flowset ignored", cxlocation(file->dss->cx, record), n);
140
file->count++;
141
pp->count = 0;
142
continue;
143
}
144
145
/* HERE: add an options indicator to the record schema instead of discarding? */
146
147
if (tp->options)
148
{
149
pp->count = 0;
150
continue;
151
}
152
pp->template = tp;
153
pp->next = tp->size;
154
break;
155
}
156
if (n == FLOW_TEMPLATE)
157
{
158
bp = ((Netflow_method_t*)file->dss->data)->base;
159
pp->count++;
160
while (pp->data < (pp->last - 4))
161
{
162
n = BE2(pp->data);
163
m = BE2(pp->data);
164
if (file->dss->flags & DSS_DEBUG)
165
sfprintf(sfstderr, "template %d elements %d\n", n, m);
166
if ((pp->last - pp->data) < m * 4)
167
break;
168
for (tp = mp->templates; tp && tp->id != n; tp = tp->next);
169
if (tp)
170
memset(tp->field, 0, sizeof(tp->field));
171
else if (!(tp = vmnewof(file->dss->vm, 0, Netflow_template_t, 1, 0)))
172
{
173
if (disc->errorf)
174
(*disc->errorf)(NiL, disc, 2, "out of space");
175
return -1;
176
}
177
else
178
{
179
tp->id = n;
180
tp->next = mp->templates;
181
mp->templates = tp;
182
}
183
tp->elements = m;
184
pp->count--;
185
file->count++;
186
o = 0;
187
while (m--)
188
{
189
n = BE2(pp->data);
190
z = BE2(pp->data);
191
if (n >= 1 && n <= NETFLOW_TEMPLATE)
192
{
193
fp = &tp->field[n - 1];
194
fp->type = bp->field[n - 1].type;
195
fp->offset = o;
196
o += (fp->size = z);
197
if (file->dss->flags & DSS_DEBUG)
198
sfprintf(sfstderr, "template %2d field %2d type %2d size %2d offset %3d\n", tp->id, n, fp->type, fp->size, fp->offset);
199
}
200
}
201
tp->size = o;
202
if (file->dss->flags & DSS_DEBUG)
203
sfprintf(sfstderr, "template %d elements %d size %d\n", tp->id, tp->elements, tp->size);
204
}
205
}
206
else if (n == FLOW_OPTION)
207
{
208
pp->count++;
209
bp = ((Netflow_method_t*)file->dss->data)->base;
210
while (pp->data < (pp->last - 6))
211
{
212
n = BE2(pp->data);
213
m = BE2(pp->data) / 4;
214
k = BE2(pp->data) / 4;
215
if (file->dss->flags & DSS_DEBUG)
216
sfprintf(sfstderr, "template %d scopes %d options %d\n", n, m, k);
217
for (tp = mp->templates; tp && tp->id != n; tp = tp->next);
218
if (tp)
219
memset(tp->field, 0, sizeof(tp->field));
220
else if (!(tp = vmnewof(file->dss->vm, 0, Netflow_template_t, 1, 0)))
221
{
222
if (disc->errorf)
223
(*disc->errorf)(NiL, disc, 2, "out of space");
224
return -1;
225
}
226
else
227
{
228
tp->id = n;
229
tp->next = mp->templates;
230
mp->templates = tp;
231
}
232
tp->elements = m + k;
233
tp->options = k;
234
pp->count--;
235
file->count++;
236
o = 0;
237
while (m--)
238
{
239
n = BE2(pp->data);
240
z = BE2(pp->data);
241
if (file->dss->flags & DSS_DEBUG)
242
sfprintf(sfstderr, "template %2d scope %2d size %2d offset %3d\n", tp->id, n, z, o);
243
o += z;
244
}
245
while (k--)
246
{
247
n = BE2(pp->data);
248
z = BE2(pp->data);
249
if (n >= 1 && n <= NETFLOW_TEMPLATE)
250
{
251
fp = &tp->field[n - 1];
252
fp->type = bp->field[n - 1].type;
253
fp->offset = o;
254
fp->size = z;
255
if (file->dss->flags & DSS_DEBUG)
256
sfprintf(sfstderr, "template %2d field %2d type %2d size %2d offset %3d\n", tp->id, n, fp->type, fp->size, fp->offset);
257
}
258
o += z;
259
}
260
tp->size = o;
261
if ((file->dss->flags & DSS_DEBUG) && disc->errorf)
262
sfprintf(sfstderr, "template %d elements %d size %d\n", tp->id, tp->elements, tp->size);
263
}
264
}
265
else
266
{
267
if (!(file->dss->flags & DSS_QUIET) && disc->errorf)
268
(*disc->errorf)(NiL, disc, 1, "%s%d: template index %d definition ignored", cxlocation(file->dss->cx, record), n);
269
file->count++;
270
}
271
pp->data = pp->last;
272
}
273
}
274
record->size = sizeof(*rp);
275
record->data = rp;
276
return 1;
277
corrupt:
278
if (disc->errorf)
279
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%sheader corrupt", cxlocation(file->dss->cx, record));
280
return -1;
281
incomplete:
282
if (disc->errorf)
283
(*disc->errorf)(NiL, disc, 2, "%slast packet incomplete", cxlocation(file->dss->cx, record));
284
return -1;
285
}
286
287
/*
288
* fwritef
289
*/
290
291
static int
292
dumpv9fwrite(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
293
{
294
if (disc->errorf)
295
(*disc->errorf)(NiL, disc, 2, "%s: record write not implemented", file->format->name);
296
return -1;
297
}
298
299
/*
300
* fclosef
301
*/
302
303
static int
304
dumpv9fclose(Dssfile_t* file, Dssdisc_t* disc)
305
{
306
return 0;
307
}
308
309
Dssformat_t netflow_dumpv9_format =
310
{
311
"dumpv9",
312
"Cisco netflow v9 dump format (2008-12-10) flow templates are retained across input files",
313
CXH,
314
dumpv9ident,
315
dumpv9fopen,
316
dumpv9fread,
317
dumpv9fwrite,
318
0,
319
dumpv9fclose,
320
0,
321
0,
322
netflow_dumpv9_next
323
};
324
325