1 /*
2 * Argus Software. Argus files - Modeler
3 * Copyright (c) 2000-2015 QoSient, LLC
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Written by Carter Bullard
21 * QoSient, LLC
22 *
23 */
24
25 /*
26 * $Id: //depot/argus/argus/argus/ArgusModeler.c#137 $
27 * $DateTime: 2016/04/05 12:00:14 $
28 * $Change: 3135 $
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "argus_config.h"
33 #endif
34
35
36 #if !defined(ArgusModeler)
37 #define ArgusModeler
38 #endif
39
40 #include <unistd.h>
41 #include <stdlib.h>
42 #include <errno.h>
43
44 #include <argus.h>
45
46 #include <argus/bootp.h>
47 #include <signal.h>
48
49 #include <sched.h>
50 #include <errno.h>
51 #include <math.h>
52
53 #include <net/ppp.h>
54 #include <argus/extract.h>
55
56 #include <argus_ethertype.h>
57
58 extern int ArgusShutDownFlag;
59
60 extern struct ArgusHashTable *ArgusNewHashTable (size_t, int);
61 extern int ArgusUpdateParentFlow (struct ArgusModelerStruct *, struct ArgusFlowStruct *);
62 extern int ArgusControlPlaneProtocol (struct ArgusModelerStruct *, struct ArgusFlowStruct *);
63
64 unsigned short ArgusProcessUdpHdr (struct ArgusModelerStruct *, struct ip *, int);
65 unsigned short ArgusProcessTtpHdr (struct ArgusModelerStruct *, struct ip *, int);
66 int ArgusProcessGreHdr (struct ArgusModelerStruct *, struct ip *, int);
67 int ArgusProcessPPPHdr (struct ArgusModelerStruct *, char *, int);
68
69 extern void ArgusTCPKeystroke (struct ArgusModelerStruct *, struct ArgusFlowStruct *, unsigned char *);
70
71 struct ArgusModelerStruct *
ArgusCloneModeler(struct ArgusModelerStruct * src)72 ArgusCloneModeler(struct ArgusModelerStruct *src)
73 {
74 struct ArgusModelerStruct *retn;
75
76 if ((retn = (struct ArgusModelerStruct *) ArgusCalloc (1, sizeof (struct ArgusModelerStruct))) == NULL)
77 ArgusLog (LOG_ERR, "ArgusCloneModeler () ArgusCalloc error %s\n", strerror(errno));
78
79 bcopy((char *)src, (char *)retn, sizeof(*src));
80
81 retn->ArgusSrc = NULL;
82 retn->ArgusHashTable = NULL;
83 retn->hstruct = NULL;
84 retn->ArgusStatusQueue = NULL;
85 retn->ArgusTimeOutQueues = NULL;
86 retn->ArgusThisFlow = NULL;
87 retn->ArgusOutputList = NULL;
88
89 bzero (retn->ArgusTimeOutQueue, sizeof(retn->ArgusTimeOutQueue));
90
91 #if defined(ARGUS_THREADS)
92 pthread_mutex_init(&retn->lock, NULL);
93 #endif
94
95 return (retn);
96 }
97
98
99 struct ArgusModelerStruct *
ArgusNewModeler()100 ArgusNewModeler()
101 {
102 struct ArgusModelerStruct *retn = NULL;
103
104 if ((retn = (struct ArgusModelerStruct *) ArgusCalloc (1, sizeof (struct ArgusModelerStruct))) == NULL)
105 ArgusLog (LOG_ERR, "ArgusNewModeler () ArgusCalloc error %s\n", strerror(errno));
106
107 #ifdef ARGUSDEBUG
108 ArgusDebug (1, "ArgusNewModeler() returning %p\n", retn);
109 #endif
110
111 return (retn);
112 }
113
114
115
116 void *ArgusQueueManager(void *);
117
118 void
ArgusInitModeler(struct ArgusModelerStruct * model)119 ArgusInitModeler(struct ArgusModelerStruct *model)
120 {
121 struct timeval *tvp = NULL;
122 #if defined(ARGUS_HASH_DEBUG)
123 int debug = ARGUSHASHTABLETRACK;
124 #else
125 int debug = 0;
126 #endif
127
128 bzero (model->ArgusTimeOutQueue, sizeof(model->ArgusTimeOutQueue));
129 model->ArgusInProtocol = 1;
130 model->ArgusMajorVersion = VERSION_MAJOR;
131 model->ArgusMinorVersion = VERSION_MINOR;
132 model->ArgusSnapLen = ARGUS_MINSNAPLEN;
133
134 model->ArgusUpdateInterval.tv_usec = 200000;
135 model->ival = ((model->ArgusUpdateInterval.tv_sec * 1000000LL) + model->ArgusUpdateInterval.tv_usec);
136
137 if ((model->ArgusHashTable = ArgusNewHashTable(ARGUS_HASHTABLESIZE, debug)) == NULL)
138 ArgusLog (LOG_ERR, "ArgusNewModeler () ArgusNewHashTable error %s\n", strerror(errno));
139
140 if ((model->hstruct = (struct ArgusHashStruct *) ArgusCalloc (1, sizeof (struct ArgusHashStruct))) == NULL)
141 ArgusLog (LOG_ERR, "ArgusNewModeler () ArgusCalloc error %s\n", strerror(errno));
142
143 if ((model->ArgusStatusQueue = ArgusNewQueue()) == NULL)
144 ArgusLog (LOG_ERR, "ArgusNewModeler () ArgusNewQueue error %s\n", strerror(errno));
145
146 if ((model->ArgusTimeOutQueues = ArgusNewQueue()) == NULL)
147 ArgusLog (LOG_ERR, "ArgusNewModeler () ArgusNewQueue error %s\n", strerror(errno));
148
149 /* align the ArgusThisFlow buffer */
150
151 if ((model->ArgusThisFlow = (struct ArgusSystemFlow *) ArgusCalloc (1, sizeof (struct ArgusSystemFlow) + 32)) == NULL)
152 ArgusLog (LOG_ERR, "ArgusNewModeler () ArgusCalloc error %s\n", strerror(errno));
153
154 model->ArgusOutputList = ArgusOutputTask->ArgusInputList;
155
156 gettimeofday (&model->ArgusGlobalTime, 0L);
157 ArgusModel->ArgusGlobalTime = model->ArgusGlobalTime;
158
159 if ((model->ArgusThisLLC = (struct llc *) ArgusCalloc (1, sizeof (struct llc ) + 32)) == NULL)
160 ArgusLog (LOG_ERR, "ArgusInitModeler () ArgusCalloc error %s\n", strerror(errno));
161
162 model->ArgusSeqNum = 1;
163 model->ArgusReportAllTime = 1;
164
165 if (!(model->ArgusFlowKey))
166 model->ArgusFlowKey = ARGUS_FLOW_KEY_CLASSIC5TUPLE;
167
168 if (!(model->ArgusFlowType)) {
169 if (model->ArgusFlowKey == ARGUS_FLOW_KEY_CLASSIC5TUPLE)
170 model->ArgusFlowType = ARGUS_BIDIRECTIONAL;
171 else
172 model->ArgusFlowType = ARGUS_UNIDIRECTIONAL;
173 }
174
175 model->ArgusQueueInterval.tv_usec = 50000;
176 model->ArgusListenInterval.tv_usec = 250000;
177
178 model->ArgusIPTimeout = (model->ArgusIPTimeout == 0) ? ARGUS_IPTIMEOUT : model->ArgusIPTimeout;
179 model->ArgusTCPTimeout = (model->ArgusTCPTimeout == 0) ? ARGUS_TCPTIMEOUT : model->ArgusTCPTimeout;
180 model->ArgusICMPTimeout = (model->ArgusICMPTimeout == 0) ? ARGUS_ICMPTIMEOUT : model->ArgusICMPTimeout;
181 model->ArgusIGMPTimeout = (model->ArgusIGMPTimeout == 0) ? ARGUS_IGMPTIMEOUT : model->ArgusIGMPTimeout;
182 model->ArgusFRAGTimeout = (model->ArgusFRAGTimeout == 0) ? ARGUS_FRAGTIMEOUT : model->ArgusFRAGTimeout;
183 model->ArgusARPTimeout = (model->ArgusARPTimeout == 0) ? ARGUS_ARPTIMEOUT : model->ArgusARPTimeout;
184 model->ArgusOtherTimeout = (model->ArgusOtherTimeout == 0) ? ARGUS_OTHERTIMEOUT : model->ArgusOtherTimeout;
185
186 if ((tvp = getArgusFarReportInterval(model)) != NULL)
187 model->ArgusStatusQueue->timeout = tvp->tv_sec;
188
189 model->ArgusTCPflag = 1;
190
191 model->ArgusThisDir = 0;
192
193 ArgusInitMallocList(sizeof(struct ArgusRecordStruct));
194
195 #ifdef ARGUSDEBUG
196 ArgusDebug (1, "ArgusInitModeler(%p) done\n", model);
197 #endif
198 }
199
200
201 void
ArgusCloseModeler(struct ArgusModelerStruct * model)202 ArgusCloseModeler(struct ArgusModelerStruct *model)
203 {
204 struct ArgusRecordStruct *argus = NULL;
205
206 if (model) {
207 ArgusModelerCleanUp (model);
208
209 if (model->ArgusHashTable) {
210 struct ArgusHashTable *htbl = model->ArgusHashTable;
211 if (htbl->array)
212 ArgusFree(htbl->array);
213 ArgusFree(htbl);
214 model->ArgusHashTable = NULL;
215 }
216
217 if (model->ArgusOutputList) {
218 if ((argus = ArgusGenerateListRecord (model, NULL, ARGUS_STOP)) != NULL) {
219 model->ArgusTotalSends++;
220 ArgusPushBackList (model->ArgusOutputList, (struct ArgusListRecord *) argus, ARGUS_LOCK);
221
222 #if defined(ARGUS_THREADS)
223 pthread_mutex_lock(&model->ArgusOutputList->lock);
224 pthread_cond_signal(&model->ArgusOutputList->cond);
225 pthread_mutex_unlock(&model->ArgusOutputList->lock);
226 #endif
227
228 #ifdef ARGUSDEBUG
229 ArgusDebug (4, "ArgusCloseModeler(%p) pushing close record %p as rec %d\n", model, argus, ArgusGetListCount(model->ArgusOutputList));
230 #endif
231 } else
232 ArgusLog (LOG_ERR, "ArgusCloseModeler(%p) ArgusGenerateListRecord failed\n", model);
233
234 }
235
236 if (model->hstruct != NULL) {
237 ArgusFree(model->hstruct);
238 model->hstruct = NULL;
239 }
240 if (model->ArgusThisFlow != NULL) {
241 ArgusFree(model->ArgusThisFlow);
242 model->ArgusThisFlow = NULL;
243 }
244 if (model->ArgusStatusQueue != NULL) {
245 ArgusDeleteQueue(model->ArgusStatusQueue);
246 model->ArgusStatusQueue = NULL;
247 }
248 if (model->ArgusTimeOutQueues != NULL) {
249 ArgusDeleteQueue(model->ArgusTimeOutQueues);
250 model->ArgusTimeOutQueues = NULL;
251 }
252 if (model->ArgusThisLLC != NULL) {
253 ArgusFree(model->ArgusThisLLC);
254 model->ArgusThisLLC = NULL;
255 }
256 }
257
258 #ifdef ARGUSDEBUG
259 ArgusDebug (3, "ArgusCloseModeler(%p) Total Sends %d\n", model, model->ArgusTotalSends);
260 #endif
261 }
262
263
264
265 void ArgusProcessQueueTimeout (struct ArgusModelerStruct *, struct ArgusQueueStruct *);
266 int ArgusQMTurns = 0;
267
268 void *
ArgusQueueManager(void * param)269 ArgusQueueManager(void *param)
270 {
271 struct ArgusModelerStruct *model = param;
272 struct ArgusQueueStruct *queue = NULL;
273 void *retn = NULL;
274
275 /*
276 * so there are two things to do.
277 * 1. process the status queue. this is a FIFO
278 * queue, and any object at the end of the queue
279 * is printed and moved to the timeout queue.
280 * (objects can be moved by the packet handler,
281 * so locking is important here.
282 *
283 * 2. process the timeout queue. this queue we can
284 * get to on a slower time scale, until resources
285 * are getting used up.
286 */
287
288 ArgusQMTurns++;
289
290 if (model->ArgusStatusQueue != NULL)
291 ArgusProcessQueueTimeout (model, model->ArgusStatusQueue);
292 else
293 return (retn);
294
295 if ((model->ArgusTimeOutQueues != NULL) && (model->ArgusTimeOutQueues->count > 0)) {
296 int i, cnt = model->ArgusTimeOutQueues->count;
297
298 for (i = 0; i < cnt; i++) {
299 queue = (struct ArgusQueueStruct *)ArgusPopQueue (model->ArgusTimeOutQueues, ARGUS_LOCK);
300 ArgusProcessQueueTimeout (model, queue);
301 ArgusAddToQueue (model->ArgusTimeOutQueues, &queue->qhdr, ARGUS_LOCK);
302 }
303 }
304
305 #ifdef ARGUSDEBUG
306 /*
307 {
308 struct timeval now, testime = {0,0}, update = {1,0};
309 gettimeofday(&now, 0L);
310
311 if (testime.tv_sec == 0) {
312 testime = now;
313 }
314
315 if ((now.tv_sec > testime.tv_sec) ||
316 ((now.tv_sec == testime.tv_sec) &&
317 (now.tv_usec >= testime.tv_usec)) ) {
318
319 unsigned int qs = 0, count = 0, reclaim = 0;
320 int i, cnt = model->ArgusTimeOutQueues->count;
321
322 for (i = 0; i < cnt; i++) {
323 queue = (struct ArgusQueueStruct *)ArgusPopQueue (model->ArgusTimeOutQueues, ARGUS_LOCK);
324 qs++;
325 count += queue->count;
326 reclaim += queue->reclaim;
327 ArgusAddToQueue (model->ArgusTimeOutQueues, &queue->qhdr, ARGUS_LOCK);
328 }
329
330 ArgusDebug (7, "ArgusQueueManager() turns %-4d statusQueue %-4d qs %-2d items %-4d cache %-6lld resort %-6d reclaim %-6d new %-6lld sends %-8lld bsends %-8lld\n",
331 ArgusQMTurns, model->ArgusStatusQueue->count, qs, count, model->ArgusTotalCacheHits, model->ArgusStatusQueue->reclaim, reclaim,
332 model->ArgusTotalNewFlows, model->ArgusTotalSends, model->ArgusTotalBadSends);
333
334 testime.tv_sec += update.tv_sec;
335 testime.tv_usec += update.tv_usec;
336 if (testime.tv_usec > 1000000) {
337 testime.tv_sec++;
338 testime.tv_usec -= 1000000;
339 }
340 }
341 }
342 */
343 #endif
344
345 return (retn);
346 }
347
348
349 void
ArgusProcessQueueTimeout(struct ArgusModelerStruct * model,struct ArgusQueueStruct * queue)350 ArgusProcessQueueTimeout (struct ArgusModelerStruct *model, struct ArgusQueueStruct *queue)
351 {
352 struct ArgusFlowStruct *last = NULL;
353 int done = 0, timedout = 0;
354
355 queue->turns++;
356 #if defined(ARGUS_THREADS)
357 pthread_mutex_lock(&queue->lock);
358 #endif
359 while ((!done)) {
360 if (queue->start != NULL) {
361 if ((last = (struct ArgusFlowStruct *) queue->start->prv) != NULL) {
362 if (queue == model->ArgusStatusQueue) {
363 struct timeval nowbuf, *now;
364
365 if (ArgusSourceTask->ArgusReadingOffLine) {
366 now = &model->ArgusGlobalTime;
367 } else {
368 now = &nowbuf;
369 gettimeofday(now, 0L);
370 }
371
372 if (ArgusCheckTimeout(model, &last->qhdr.qtime, getArgusFarReportInterval(model))) {
373 struct ArgusFlowStruct *frag;
374
375 timedout++;
376 ArgusRemoveFromQueue(queue, &last->qhdr, ARGUS_NOLOCK);
377
378 if ((frag = (struct ArgusFlowStruct *)last->frag.start) != NULL) {
379 struct timeval timeout = {2,0};
380 do {
381 struct ArgusFlowStruct *nxt = (struct ArgusFlowStruct *)frag->qhdr.nxt;
382 ArgusUpdateParentFlow(model, frag);
383
384 if (ArgusCheckTimeout(model, &frag->qhdr.qtime, &timeout))
385 ArgusDeleteObject(frag);
386
387 frag = nxt;
388
389 } while (last->frag.start && (frag != (struct ArgusFlowStruct *)last->frag.start));
390 }
391
392 if (!(last->status & ARGUS_RECORD_WRITTEN)) {
393 ArgusSendFlowRecord (model, last, last->status);
394 }
395
396 if (last->timeout > 0) {
397 if (last->timeout > ARGUSTIMEOUTQS)
398 last->timeout = ARGUSTIMEOUTQS;
399
400 if (model->ArgusTimeOutQueue[last->timeout] == NULL) {
401 model->ArgusTimeOutQueue[last->timeout] = ArgusNewQueue();
402 model->ArgusTimeOutQueue[last->timeout]->timeout = last->timeout;
403 ArgusPushQueue(model->ArgusTimeOutQueues, &model->ArgusTimeOutQueue[last->timeout]->qhdr, ARGUS_LOCK);
404 }
405
406 ArgusPushQueue(model->ArgusTimeOutQueue[last->timeout], &last->qhdr, ARGUS_LOCK);
407
408 } else
409 ArgusDeleteObject(last);
410
411 } else {
412 #ifdef ARGUSDEBUG
413 ArgusDebug (10, "ArgusProcessQueueTimeout(%p, %p) done with %d records\n", model, queue, queue->count);
414 #endif
415 done++;
416 }
417
418 } else {
419 struct timeval timeout = {0,0};
420 timeout.tv_sec = queue->timeout;
421
422 if (ArgusCheckTimeout(model, &last->qhdr.qtime, &timeout)) {
423 ArgusRemoveFromQueue(queue, &last->qhdr, ARGUS_NOLOCK);
424 ArgusDeleteObject(last);
425 timedout++;
426 } else {
427 done++;
428 }
429 }
430
431 } else
432 done++;
433
434 } else
435 done++;
436 }
437 #if defined(ARGUS_THREADS)
438 pthread_mutex_unlock(&queue->lock);
439 #endif
440
441 #ifdef ARGUSDEBUG
442 ArgusDebug (5, "ArgusProcessQueueTimeout(%p, %d) timedout %d remaining %d\n", model, queue->timeout, timedout, queue->count);
443 #endif
444 }
445
446 void ArgusModelerStats(struct ArgusModelerStruct *);
447
448 void
ArgusModelerStats(struct ArgusModelerStruct * model)449 ArgusModelerStats(struct ArgusModelerStruct *model)
450 {
451
452 }
453
454
455 #include <argus_ethertype.h>
456
457 #if !defined(__OpenBSD__)
458 #include <netinet/if_ether.h>
459 #endif
460
461 int ArgusProcessISLHdr (struct ArgusModelerStruct *, struct ether_header *, int);
462 int ArgusProcessNetbeuiHdr (struct ArgusModelerStruct *, struct ether_header *, int);
463 int ArgusProcessNetbiosHdr (struct ArgusModelerStruct *, struct ether_header *, int);
464 int ArgusProcessIsoclnsHdr (struct ArgusModelerStruct *, struct ether_header *, int);
465
466
467 #define ARGUS_ISL_ETHERHDR_LEN 26
468
469 int
ArgusProcessISLHdr(struct ArgusModelerStruct * model,struct ether_header * ep,int length)470 ArgusProcessISLHdr (struct ArgusModelerStruct *model, struct ether_header *ep, int length)
471 {
472 int type = (((unsigned char *)ep)[5] >> 4) & 0x0F;
473 int retn = 0;
474
475 #define ARGUS_ISLTYPE_ETHER 0x0
476 #define ARGUS_ISLTYPE_TR 0x0
477 #define ARGUS_ISLTYPE_FDDI 0x2
478 #define ARGUS_ISLTYPE_ATM 0x3
479
480 switch (type) {
481 case ARGUS_ISLTYPE_ETHER:
482 model->ArgusThisLength -= ARGUS_ISL_ETHERHDR_LEN;
483 model->ArgusSnapLength -= ARGUS_ISL_ETHERHDR_LEN;
484 model->ArgusThisUpHdr = ((unsigned char *)ep + ARGUS_ISL_ETHERHDR_LEN);
485 model->ArgusThisEncaps |= ARGUS_ENCAPS_ISL;
486
487 ep = (struct ether_header *) ((unsigned char *)ep + ARGUS_ISL_ETHERHDR_LEN);
488 retn = ArgusProcessEtherHdr(model, ep, length - ARGUS_ISL_ETHERHDR_LEN);
489 }
490 return (retn);
491 }
492
493 int
ArgusProcessNetbeuiHdr(struct ArgusModelerStruct * model,struct ether_header * ep,int length)494 ArgusProcessNetbeuiHdr (struct ArgusModelerStruct *model, struct ether_header *ep, int length)
495 {
496 int retn = 0;
497 return (retn);
498 }
499
500 int
ArgusProcessNetbiosHdr(struct ArgusModelerStruct * model,struct ether_header * ep,int length)501 ArgusProcessNetbiosHdr (struct ArgusModelerStruct *model, struct ether_header *ep, int length)
502 {
503 int retn = 0;
504 return (retn);
505 }
506
507
508 int
ArgusProcessIsoclnsHdr(struct ArgusModelerStruct * model,struct ether_header * ep,int length)509 ArgusProcessIsoclnsHdr (struct ArgusModelerStruct *model, struct ether_header *ep, int length)
510 {
511 int retn = 0;
512 unsigned char *ptr = (unsigned char *)ep;
513
514 ptr += 3;
515
516 switch (*ptr) {
517 case ARGUS_CLNS: model->ArgusThisNetworkFlowType = ARGUS_CLNS; break;
518 case ARGUS_ESIS: model->ArgusThisNetworkFlowType = ARGUS_ESIS; break;
519 case ARGUS_ISIS: model->ArgusThisNetworkFlowType = ARGUS_ISIS; break;
520 case 0: model->ArgusThisNetworkFlowType = ARGUS_NULLNS; break;
521 default: model->ArgusThisNetworkFlowType = ARGUS_CLNS; break;
522 }
523
524 /*
525 model->ArgusThisLength -= sizeof(struct llc);
526 model->ArgusSnapLength -= sizeof(struct llc);
527 model->ArgusThisUpHdr = (ptr + sizeof(struct llc));
528 */
529 model->ArgusThisLength -= 3;
530 model->ArgusSnapLength -= 3;
531
532 model->ArgusThisUpHdr = ptr;
533 model->ArgusThisEncaps |= ARGUS_ENCAPS_LLC;
534 return (retn);
535 }
536
537 #if !defined(IPV6_VERSION_MASK)
538 #define IPV6_VERSION_MASK 0xF0
539 #define IPV6_VERSION 0x60
540 #endif
541
542 unsigned short
ArgusDiscoverNetworkProtocol(unsigned char * ptr)543 ArgusDiscoverNetworkProtocol (unsigned char *ptr)
544 {
545 unsigned short retn = ETHERTYPE_MPLS;
546
547 /* test for IPv4, IPv6, and vlan tags */
548
549 if (ptr != NULL) {
550 if ((((struct ip *)ptr)->ip_v == 4) && (((struct ip *)ptr)->ip_hl >= 5) &&
551 (ntohs(((struct ip *)ptr)->ip_len) >= 20)) {
552 retn = ETHERTYPE_IP;
553 } else {
554 if (((((struct ip6_hdr *)ptr)->ip6_vfc & IPV6_VERSION_MASK) == IPV6_VERSION) &&
555 (ntohs(((struct ip6_hdr *)ptr)->ip6_plen) <= 2048)) {
556 retn = ETHERTYPE_IPV6;
557 } else {
558 switch (ntohs(*(unsigned short *)(ptr + 2))) {
559 case ETHERTYPE_IP:
560 case ETHERTYPE_IPV6:
561 retn = ETHERTYPE_8021Q;
562 break;
563 default:
564 retn = ARGUS_ETHER_HDR;
565 }
566 }
567 }
568 }
569
570 return (retn);
571 }
572
573 void
ArgusParseMPLSLabel(unsigned int value,unsigned int * label,unsigned char * exp,unsigned char * bos,unsigned char * ttl)574 ArgusParseMPLSLabel (unsigned int value, unsigned int *label, unsigned char *exp, unsigned char *bos, unsigned char *ttl)
575 {
576 *label = value >> 12;
577 *exp = (value >> 9) & 0x07;
578 *bos = (value >> 8) & 0x01;
579 *ttl = value & 0xFF;
580 }
581
582
583 /*
584 ArgusProcessPacketHdrs - this routine should take in a pointer and
585 a packet header type and process that header, returning the next
586 layer type, or zero if the routine has found the IP layer.
587 This is the entry point for handling packets from any of the
588 source interface layers.
589 */
590
591
592 int ArgusProcessPacketHdrs (struct ArgusModelerStruct *, char *, int, int);
593 int ArgusProcessPPPoEHdr (struct ArgusModelerStruct *, char *, int);
594 int ArgusProcessLLCHdr (struct ArgusModelerStruct *, char *, int);
595 int ArgusProcess80211Hdr (struct ArgusModelerStruct *, char *, int);
596 int ArgusProcessUDToEHdr (struct ArgusModelerStruct *, char *, int);
597 int ArgusProcessErspanIIHdr (struct ArgusModelerStruct *, char *, int);
598
599
600 int
ArgusProcessPacketHdrs(struct ArgusModelerStruct * model,char * p,int length,int type)601 ArgusProcessPacketHdrs (struct ArgusModelerStruct *model, char *p, int length, int type)
602 {
603 int retn = 0;
604
605 switch (type) {
606 case ETHERTYPE_ERSPAN_II:
607 model->ArgusThisNetworkFlowType = ETHERTYPE_ERSPAN_II;
608 if ((retn = ArgusProcessErspanIIHdr(model, p, length)) < 0)
609 model->ArgusThisUpHdr = (void *)p;
610 break;
611
612 case ETHERTYPE_TRANS_BRIDGE:
613 case ARGUS_ETHER_HDR:
614 model->ArgusThisNetworkFlowType = ARGUS_ETHER_HDR;
615 if ((retn = ArgusProcessEtherHdr(model, (struct ether_header *)p, length)) < 0)
616 model->ArgusThisUpHdr = (void *)p;
617 break;
618
619 case ARGUS_802_11_HDR:
620 model->ArgusThisNetworkFlowType = type;
621 if ((retn = ArgusProcess80211Hdr(model, p, length)) < 0)
622 model->ArgusThisUpHdr = (void *)p;
623 break;
624
625 case ETHERTYPE_PPP:
626 model->ArgusThisNetworkFlowType = type;
627 if ((retn = ArgusProcessPPPHdr(model, p, length)) < 0)
628 model->ArgusThisUpHdr = (void *)p;
629 break;
630
631 case ETHERTYPE_PPPOED:
632 case ETHERTYPE_PPPOES:
633 model->ArgusThisNetworkFlowType = type;
634 if ((retn = ArgusProcessPPPoEHdr(model, p, length)) < 0)
635 model->ArgusThisUpHdr = (void *)p;
636 break;
637
638 case ETHERTYPE_UDTOE:
639 model->ArgusThisNetworkFlowType = type;
640 if ((retn = ArgusProcessUDToEHdr (model, p, length)) < 0)
641 model->ArgusThisUpHdr = (void *)p;
642 break;
643
644 case ETHERTYPE_8021Q: {
645 model->ArgusThisNetworkFlowType = type;
646 model->ArgusThisPacket8021QEncaps = ntohs(*(unsigned short *)(p));
647 model->ArgusThisEncaps |= ARGUS_ENCAPS_8021Q;
648
649 retn = ntohs(*(unsigned short *)(p + 2));
650
651 if (retn <= ETHERMTU) { /* 802.3 Encapsulation */
652 if (p[0] == 0x01 && p[1] == 0x00 &&
653 p[2] == 0x0C && p[3] == 0x00 && p[4] == 0x00) {
654 return (ArgusProcessISLHdr (model, (struct ether_header *)p, length));
655 }
656
657 model->ArgusThisUpHdr += 4;
658 model->ArgusThisLength -= 4;
659 model->ArgusSnapLength -= 4;
660
661 p = (void *) model->ArgusThisUpHdr;
662 if ((retn = ArgusProcessLLCHdr(model, p, length)) < 0)
663 model->ArgusThisUpHdr = (void *)p;
664
665 } else {
666 model->ArgusThisUpHdr += 4;
667 model->ArgusThisLength -= 4;
668 model->ArgusSnapLength -= 4;
669 }
670 break;
671 }
672
673 case ETHERTYPE_MPLS_MULTI:
674 case ETHERTYPE_MPLS: {
675 unsigned char exp, bos = 0, ttl;
676 unsigned int labelbuf, *label = &labelbuf;
677
678 model->ArgusThisNetworkFlowType = type;
679 while (!(bos)) {
680 unsigned int tlabel = ntohl(*(unsigned int *)(model->ArgusThisUpHdr));
681 if (!(model->ArgusThisMplsLabelIndex)) {
682 model->ArgusThisMplsLabel = tlabel;
683 model->ArgusThisMplsLabelIndex++;
684 }
685 ArgusParseMPLSLabel (tlabel, label, &exp, &bos, &ttl);
686 model->ArgusThisUpHdr += 4;
687 model->ArgusThisLength -= 4;
688 model->ArgusSnapLength -= 4;
689 model->ArgusThisEncaps |= ARGUS_ENCAPS_MPLS;
690
691 retn = ArgusDiscoverNetworkProtocol(model->ArgusThisUpHdr);
692 }
693 break;
694 }
695
696 case ETHERTYPE_IP: {
697 struct ip *ip = (struct ip *) p;
698
699 if (STRUCTCAPTURED(model,*ip)) {
700 if ((ntohs(ip->ip_len)) >= 20) {
701 if (ip->ip_v == 4)
702 model->ArgusThisNetworkFlowType = ETHERTYPE_IP;
703 else if (ip->ip_v == 6)
704 model->ArgusThisNetworkFlowType = ETHERTYPE_IPV6;
705
706 model->ArgusThisIpHdr = (void *)ip;
707 switch (ip->ip_p) {
708 case IPPROTO_TTP: { /* Preparation for Juniper TTP */
709 retn = ArgusProcessTtpHdr(model, ip, length);
710 break;
711 }
712 case IPPROTO_UDP: { /* RCP 4380 */
713 if (getArgusTunnelDiscovery(model))
714 retn = ArgusProcessUdpHdr(model, ip, length);
715 break;
716 }
717 case IPPROTO_GRE: { /* RFC 2784 */
718 retn = ArgusProcessGreHdr(model, ip, length);
719 break;
720 }
721 default:
722 retn = 0;
723 break;
724 }
725
726 } else
727 break;
728 }
729 break;
730 }
731
732 case ETHERTYPE_IPV6:
733 model->ArgusThisIpHdr = (void *)p;
734
735 case ETHERTYPE_ARP:
736 case ETHERTYPE_REVARP: {
737 model->ArgusThisNetworkFlowType = type;
738 retn = 0;
739 break;
740 }
741
742 default:
743 retn = -1;
744 break;
745 }
746
747 #ifdef ARGUSDEBUG
748 ArgusDebug (9, "ArgusProcessPacketHdrs(%p, %p, %d, %d) returning %d\n", model, p, length, type, retn);
749 #endif
750
751 return (retn);
752 }
753
754 struct teredoAuthHeader {
755 unsigned char idlen, aulen;
756 };
757
758 struct teredoOriginHdr {
759 unsigned char idlen, aulen;
760 };
761
762 #include <netinet/ip6.h>
763
764 struct teredo {
765 unsigned short tid;
766 struct teredoAuthHeader tauth;
767 };
768
769 struct ttp_header {
770 u_char type;
771 u_char priority;
772 u_char proto;
773 u_char queue;
774 u_int ifl_input;
775 u_short len;
776 u_short destmask;
777 u_int nh_index;
778 u_int hint;
779 };
780
781
782 unsigned short
ArgusProcessTtpHdr(struct ArgusModelerStruct * model,struct ip * ip,int length)783 ArgusProcessTtpHdr (struct ArgusModelerStruct *model, struct ip *ip, int length)
784 {
785 int retn = 0;
786 int hlen = ip->ip_hl << 2;
787 struct ttp_header *ttp = (struct ttp_header *) ((char *)ip + hlen);
788
789 if (STRUCTCAPTURED(model, *ttp)) {
790 ttp->ifl_input = ntohl(ttp->ifl_input);
791 ttp->len = ntohs(ttp->len);
792 ttp->destmask = ntohs(ttp->destmask);
793 ttp->nh_index = ntohl(ttp->nh_index);
794 ttp->hint = ntohl(ttp->hint);
795
796 switch(ttp->type) {
797 case 0x1:
798 case 0x2: {
799 int slen = (hlen + sizeof(*ttp));
800 length -= slen;
801 model->ArgusThisUpHdr += slen;
802 model->ArgusSnapLength -= slen;
803 model->ArgusThisLength -= slen;
804 retn = ArgusProcessPacketHdrs (model, (char *)(ttp + 1), length, ARGUS_ETHER_HDR);
805 break;
806 }
807
808 case 0x3:
809 case 0x4: {
810 int slen = (hlen + sizeof(*ttp));
811 length -= slen;
812 model->ArgusThisUpHdr += slen;
813 model->ArgusSnapLength -= slen;
814 model->ArgusThisLength -= slen;
815 retn = ArgusProcessPacketHdrs (model, (char *)(ttp + 1), length, ETHERTYPE_IP);
816 break;
817 }
818
819 case 0x0:
820 default:
821 break;
822 }
823 }
824
825 #ifdef ARGUSDEBUG
826 ArgusDebug (8, "ArgusProcessTtpHdr(%p, %p, %d) returning 0x%x\n", model, ip, length, retn);
827 #endif
828 return (retn);
829 }
830
831 unsigned short
ArgusProcessUdpHdr(struct ArgusModelerStruct * model,struct ip * ip,int length)832 ArgusProcessUdpHdr (struct ArgusModelerStruct *model, struct ip *ip, int length)
833 {
834 int retn = 0;
835 int len = 0, hlen = ip->ip_hl << 2;
836 char *bp = ((char *)ip + hlen);
837 struct udphdr *up = (struct udphdr *) bp;
838
839 if (STRUCTCAPTURED(model, *up)) {
840 unsigned short dport, sport;
841
842 sport = ntohs(up->uh_sport);
843 dport = ntohs(up->uh_dport);
844
845 if (!((sport == 53) || (dport == 53))) {
846 char *ptr = (char *) (up + 1);
847 struct ip6_hdr *ipv6 = (struct ip6_hdr *) ptr;
848 int isipv6 = 0;
849
850 len += sizeof (*up);
851
852 if (STRUCTCAPTURED(model, *ipv6)) {
853 if ((isipv6 = (ipv6->ip6_vfc & IPV6_VERSION_MASK)) == IPV6_VERSION) {
854 retn = ETHERTYPE_IPV6;
855 len = ((char *) ipv6 - (char *)ip);
856 model->ArgusThisEncaps |= ARGUS_ENCAPS_TEREDO;
857 model->ArgusThisUpHdr = (unsigned char *) ipv6;
858 model->ArgusThisLength -= len;
859 model->ArgusSnapLength -= len;
860 } else {
861 struct teredo *tptr = (struct teredo *) (up + 1);
862
863 if (STRUCTCAPTURED(model, *tptr)) {
864 u_short type = ntohs(tptr->tid);
865
866 int offset = 0;
867 switch (type) {
868 case 0x0000: offset = 8; break;
869 case 0x0001: offset = (4 + (tptr->tauth.idlen + tptr->tauth.aulen) + 8 + 1); break;
870 default: isipv6 = -1;
871 }
872
873 if (isipv6 == 0) {
874 ipv6 = (struct ip6_hdr *)(((u_char *)tptr) + offset);
875
876 if (STRUCTCAPTURED(model, *ipv6)) {
877 if ((isipv6 = (ipv6->ip6_vfc & IPV6_VERSION_MASK)) == IPV6_VERSION) {
878 retn = ETHERTYPE_IPV6;
879 len = ((char *) ipv6 - (char *)ip);
880 model->ArgusThisEncaps |= ARGUS_ENCAPS_TEREDO;
881 model->ArgusThisUpHdr = (unsigned char *) ipv6;
882 model->ArgusThisLength -= len;
883 model->ArgusSnapLength -= len;
884
885 } else {
886 struct teredo *iptr = (struct teredo *) ((char *)tptr + offset);
887 if (STRUCTCAPTURED(model, *iptr)) {
888 u_short type = ntohs(iptr->tid);
889 int offset = 0;
890 switch (type) {
891 case 0x0000: offset = 8; break;
892 case 0x0001: offset = (4 + (iptr->tauth.idlen + iptr->tauth.aulen) + 8 + 1); break;
893 default: isipv6 = -1;
894 }
895
896 if (isipv6 == 0) {
897 ipv6 = (struct ip6_hdr *)(((u_char *)iptr) + offset);
898 if ((isipv6 = (ipv6->ip6_vfc & IPV6_VERSION_MASK)) == IPV6_VERSION) {
899 retn = ETHERTYPE_IPV6;
900 len = ((char *) ipv6 - (char *)ip);
901 model->ArgusThisEncaps |= ARGUS_ENCAPS_TEREDO;
902 model->ArgusThisUpHdr = (unsigned char *) ipv6;
903 model->ArgusThisLength -= len;
904 model->ArgusSnapLength -= len;
905 }
906 }
907 }
908 }
909 }
910 }
911 }
912 }
913 }
914 }
915 }
916
917 #ifdef ARGUSDEBUG
918 ArgusDebug (8, "ArgusProcessUdpHdr(%p, %p, %d) returning 0x%x\n", model, ip, length, retn);
919 #endif
920
921 return (retn);
922 }
923
924
925 #define GRE_VERS_MASK 0x0007 /* protocol version */
926 #define GRESRE_IP 0x0800 /* IP */
927 #define GRESRE_ASN 0xfffe /* ASN */
928 #define GRE_CP 0x8000 /* checksum present */
929 #define GRE_RP 0x4000 /* routing present */
930 #define GRE_KP 0x2000 /* key present */
931 #define GRE_SP 0x1000 /* sequence# present */
932 #define GRE_sP 0x0800 /* source routing */
933 #define GRE_RECRS 0x0700 /* recursion count */
934 #define GRE_AP 0x0080 /* acknowledgment# present */
935
936 int
ArgusProcessGreHdr(struct ArgusModelerStruct * model,struct ip * ip,int length)937 ArgusProcessGreHdr (struct ArgusModelerStruct *model, struct ip *ip, int length)
938 {
939 int retn = 0, grelen = 4, hlen = ip->ip_hl << 2;
940 char *bp = ((char *)ip + hlen);
941 unsigned short flags;
942
943 model->ArgusThisLength -= hlen;
944 model->ArgusSnapLength -= hlen;
945 length -= hlen;
946
947 if (BYTESCAPTURED(model, *bp, 4)) {
948 flags = EXTRACT_16BITS(bp);
949 bp += sizeof(unsigned short);
950
951 retn = EXTRACT_16BITS(bp);
952 bp += sizeof(unsigned short);
953
954 model->ArgusThisEncaps |= ARGUS_ENCAPS_GRE;
955
956 switch(flags & GRE_VERS_MASK) {
957 case 0:
958 if ((flags & GRE_CP) | (flags & GRE_RP)) {
959 grelen += 4;
960 bp += 4;
961 }
962
963 if (flags & GRE_KP) {
964 bp += 4;
965 grelen -= 4;
966 }
967
968 if (flags & GRE_SP) {
969 bp += 4;
970 grelen += 4;
971 }
972
973 if (flags & GRE_RP) {
974 for (;;) {
975 u_int16_t af;
976 u_int8_t srelen;
977
978 if (BYTESCAPTURED(model, *bp, 4)) {
979 af = EXTRACT_16BITS(bp);
980 srelen = *(bp + 3);
981 bp += 4;
982 grelen -= 4;
983
984 if (af == 0 && srelen == 0)
985 break;
986
987 bp += srelen;
988 grelen += srelen;
989
990 } else
991 break;
992 }
993 }
994 break;
995
996 case 1:
997 if (flags & GRE_KP) {
998 bp += 4;
999 grelen -= 4;
1000 }
1001
1002 if (flags & GRE_SP) {
1003 bp += 4;
1004 grelen += 4;
1005 }
1006
1007 if (flags & GRE_AP) {
1008 bp += 4;
1009 grelen += 4;
1010 }
1011 break;
1012 }
1013
1014 model->ArgusThisUpHdr = (unsigned char *) bp;
1015 model->ArgusThisLength -= grelen;
1016 model->ArgusSnapLength -= grelen;
1017 length -= grelen;
1018 }
1019
1020 #ifdef ARGUSDEBUG
1021 ArgusDebug (8, "ArgusProcessGreHdr(%p, %p, %d) returning 0x%x\n", model, ip, length, retn);
1022 #endif
1023
1024 return (retn);
1025 }
1026
1027
1028 int
ArgusProcessEtherHdr(struct ArgusModelerStruct * model,struct ether_header * ep,int length)1029 ArgusProcessEtherHdr (struct ArgusModelerStruct *model, struct ether_header *ep, int length)
1030 {
1031 int len = sizeof(struct ether_header);
1032 unsigned char *ptr;
1033 int retn = 0;
1034
1035 length -= len;
1036 model->ArgusThisEpHdr = ep;
1037 model->ArgusThisUpHdr = (unsigned char *) (ep + 1);
1038 model->ArgusThisLength -= len;
1039 model->ArgusSnapLength -= len;
1040
1041 model->ArgusThisIpHdr = NULL;
1042
1043 model->ArgusThisEncaps |= ARGUS_ENCAPS_ETHER;
1044 retn = ntohs(ep->ether_type);
1045
1046 if (retn <= ETHERMTU) { /* 802.3 Encapsulation */
1047 struct llc *llc = NULL;
1048 unsigned short ether_type = 0;
1049
1050 ptr = (unsigned char *) ep;
1051 if (ptr[0] == 0x01 && ptr[1] == 0x00 &&
1052 ptr[2] == 0x0C && ptr[3] == 0x00 && ptr[4] == 0x00) {
1053 return (ArgusProcessISLHdr (model, ep, length));
1054 }
1055
1056 ptr = (unsigned char *) model->ArgusThisUpHdr;
1057 llc = (struct llc *) ptr;
1058
1059 if (BYTESCAPTURED(model,*llc, 3) && ((llc = model->ArgusThisLLC) != NULL)) {
1060 model->ArgusThisEncaps |= ARGUS_ENCAPS_LLC;
1061
1062 bcopy((char *) ptr, (char *) llc, sizeof (struct llc));
1063
1064 #define ARGUS_IPX_TAG 100
1065
1066 if (llc->ssap == LLCSAP_GLOBAL && llc->dsap == LLCSAP_GLOBAL) {
1067 model->ArgusThisNetworkFlowType = ARGUS_IPX_TAG;
1068 return (retn);
1069 }
1070
1071 if ((((u_char *)ep)[0] == 0xf0) && (((u_char *)ep)[1] == 0xf0))
1072 return (ArgusProcessNetbeuiHdr (model, ep, length));
1073
1074 if ((llc->ssap == LLCSAP_ISONS) && (llc->dsap == LLCSAP_ISONS) && (llc->llcui == LLC_UI))
1075 return(ArgusProcessIsoclnsHdr(model, (struct ether_header *)ptr, length));
1076
1077 if ((llc->ssap == LLCSAP_SNAP) && (llc->dsap == LLCSAP_SNAP)) {
1078 if (llc->llcui == LLC_UI) {
1079 ((unsigned char *)ðer_type)[0] = ((unsigned char *)&llc->ethertype)[0];
1080 ((unsigned char *)ðer_type)[1] = ((unsigned char *)&llc->ethertype)[1];
1081
1082 model->ArgusThisNetworkFlowType = ntohs(ether_type);
1083 retn = model->ArgusThisNetworkFlowType;
1084
1085 model->ArgusThisLength -= sizeof(struct llc);
1086 model->ArgusSnapLength -= sizeof(struct llc);
1087 model->ArgusThisUpHdr = (ptr + sizeof(struct llc));
1088 }
1089
1090 } else {
1091 if ((llc->llcu & LLC_U_FMT) == LLC_U_FMT) {
1092 model->ArgusThisUpHdr += 3;
1093 model->ArgusThisLength -= 3;
1094 model->ArgusSnapLength -= 3;
1095
1096 if ((llc->llcu & ~LLC_U_POLL) == LLC_XID) {
1097 if (*model->ArgusThisUpHdr == LLC_XID_FI) {
1098 model->ArgusThisUpHdr += 3;
1099 model->ArgusThisLength -= 3;
1100 model->ArgusSnapLength -= 3;
1101 }
1102 }
1103 } else {
1104 model->ArgusThisUpHdr += 4;
1105 model->ArgusThisLength -= 4;
1106 model->ArgusSnapLength -= 4;
1107 }
1108 }
1109 }
1110 }
1111
1112 #ifdef ARGUSDEBUG
1113 ArgusDebug (8, "ArgusProcessEtherHdr(%p, %d) returning 0x%x\n", ep, length, retn);
1114 #endif
1115
1116 return (retn);
1117 }
1118
1119
1120 #include <argus/ieee802_11.h>
1121
1122 extern int ArgusExtract802_11HeaderLength(u_int16_t);
1123
1124
1125 int
ArgusProcess80211Hdr(struct ArgusModelerStruct * model,char * p,int length)1126 ArgusProcess80211Hdr (struct ArgusModelerStruct *model, char *p, int length)
1127 {
1128 int retn = 0, hdrlen;
1129
1130 u_int16_t fc;
1131
1132 fc = EXTRACT_LE_16BITS(p);
1133 hdrlen = ArgusExtract802_11HeaderLength(fc);
1134
1135 switch (FC_TYPE(fc)) {
1136 case T_MGMT:
1137 case T_CTRL:
1138 break;
1139
1140 case T_DATA: {
1141 if (!(DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))) {
1142 if (model->ArgusSrc->ArgusThisRadioTap.flags & IEEE80211_RADIOTAP_F_DATAPAD)
1143 hdrlen = ((hdrlen + 3) / 4) * 4;
1144
1145 if (FC_WEP(fc)) {
1146 } else {
1147 retn = ArgusProcessLLCHdr(model, p + hdrlen, length - hdrlen);
1148 }
1149 }
1150 break;
1151 }
1152 }
1153
1154 #ifdef ARGUSDEBUG
1155 ArgusDebug (8, "ArgusProcess80211Hdr(%p, %p, %d) returning 0x%x\n", model, p, length, retn);
1156 #endif
1157
1158 return(retn);
1159 }
1160
1161
1162 int
ArgusProcessLLCHdr(struct ArgusModelerStruct * model,char * p,int length)1163 ArgusProcessLLCHdr (struct ArgusModelerStruct *model, char *p, int length)
1164 {
1165 int retn = 0;
1166 struct llc *llc = NULL;
1167 unsigned short ether_type = 0;
1168 unsigned char *ptr = (unsigned char *) p;
1169 /*
1170 ptr = (unsigned char *) model->ArgusThisUpHdr;
1171 */
1172 llc = (struct llc *) ptr;
1173
1174 if (BYTESCAPTURED(model,*llc,3)) {
1175 model->ArgusThisEncaps |= ARGUS_ENCAPS_LLC;
1176
1177 llc = model->ArgusThisLLC;
1178 bcopy((char *) ptr, (char *) llc, sizeof (struct llc));
1179
1180 #define ARGUS_IPX_TAG 100
1181
1182 if (llc->ssap == LLCSAP_GLOBAL && llc->dsap == LLCSAP_GLOBAL) {
1183 model->ArgusThisNetworkFlowType = ARGUS_IPX_TAG;
1184 return (retn);
1185 }
1186
1187 if ((((u_char *)p)[0] == 0xf0) && (((u_char *)p)[1] == 0xf0))
1188 return (ArgusProcessNetbeuiHdr (model, (struct ether_header *)p, length));
1189
1190 if ((llc->ssap == LLCSAP_ISONS) && (llc->dsap == LLCSAP_ISONS) && (llc->llcui == LLC_UI))
1191 return(ArgusProcessIsoclnsHdr(model, (struct ether_header *)ptr, length));
1192
1193 if ((llc->ssap == LLCSAP_SNAP) && (llc->dsap == LLCSAP_SNAP)) {
1194 if (llc->llcui == LLC_UI) {
1195 ((unsigned char *)ðer_type)[0] = ((unsigned char *)&llc->ethertype)[0];
1196 ((unsigned char *)ðer_type)[1] = ((unsigned char *)&llc->ethertype)[1];
1197
1198 retn = ntohs(ether_type);
1199
1200 model->ArgusThisLength -= sizeof(struct llc);
1201 model->ArgusSnapLength -= sizeof(struct llc);
1202 model->ArgusThisUpHdr = (ptr + sizeof(struct llc));
1203 }
1204
1205 } else {
1206 if ((llc->llcu & LLC_U_FMT) == LLC_U_FMT) {
1207 model->ArgusThisUpHdr += 3;
1208 model->ArgusThisLength -= 3;
1209 model->ArgusSnapLength -= 3;
1210
1211 if ((llc->llcu & ~LLC_U_POLL) == LLC_XID) {
1212 if (*model->ArgusThisUpHdr == LLC_XID_FI) {
1213 model->ArgusThisUpHdr += 3;
1214 model->ArgusThisLength -= 3;
1215 model->ArgusSnapLength -= 3;
1216 }
1217 }
1218
1219 } else {
1220 model->ArgusThisUpHdr += 4;
1221 model->ArgusThisLength -= 4;
1222 model->ArgusSnapLength -= 4;
1223 }
1224 }
1225 }
1226
1227 #ifdef ARGUSDEBUG
1228 ArgusDebug (8, "ArgusProcessLLCHdr(%p, %p, %d) returning 0x%x\n", model, p, length, retn);
1229 #endif
1230
1231 return(retn);
1232 }
1233
1234
1235 int
ArgusProcessPPPHdr(struct ArgusModelerStruct * model,char * p,int length)1236 ArgusProcessPPPHdr (struct ArgusModelerStruct *model, char *p, int length)
1237 {
1238 u_int proto = 0;
1239 int retn = 0, hdr_len = 0;
1240
1241 if (length >= PPP_HDRLEN) {
1242 model->ArgusThisEncaps |= ARGUS_ENCAPS_PPP;
1243 switch (EXTRACT_16BITS(p)) {
1244 case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL):
1245 p += 2;
1246 length -= 2;
1247 hdr_len += 2;
1248 break;
1249 case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL):
1250 p += 2;
1251 length -= 2;
1252 hdr_len += 2;
1253 break;
1254 case (PPP_ADDRESS << 8 | PPP_CONTROL):
1255 p += 2; /* ACFC not used */
1256 length -= 2;
1257 hdr_len += 2;
1258 break;
1259
1260 default:
1261 break;
1262 }
1263
1264 if (*p % 2) {
1265 proto = *p;
1266 p++;
1267 length--;
1268 hdr_len++;
1269 } else {
1270 proto = EXTRACT_16BITS(p);
1271 p += 2; /* ACFC not used */
1272 length -= 2;
1273 hdr_len += 2;
1274 }
1275
1276 switch (proto) {
1277 case PPP_IP:
1278 model->ArgusThisNetworkFlowType = PPP_IP;
1279 retn = ETHERTYPE_IP;
1280 break;
1281
1282 case PPP_IPV6:
1283 model->ArgusThisNetworkFlowType = PPP_IPV6;
1284 retn = ETHERTYPE_IPV6;
1285 break;
1286
1287 case PPP_OSI:
1288 case PPP_NS:
1289 case PPP_DECNET:
1290 case PPP_APPLE:
1291 case PPP_IPX:
1292 case PPP_VJC:
1293 case PPP_VJNC:
1294 case PPP_BRPDU:
1295 case PPP_STII:
1296 case PPP_VINES:
1297
1298 case PPP_MPLS_UCAST:
1299 case PPP_MPLS_MCAST:
1300
1301 case PPP_COMP:
1302 case PPP_HELLO:
1303 case PPP_LUXCOM:
1304 case PPP_SNS:
1305 case PPP_IPCP:
1306 case PPP_OSICP:
1307 case PPP_NSCP:
1308 case PPP_DECNETCP:
1309 case PPP_APPLECP:
1310 case PPP_IPXCP:
1311 case PPP_STIICP:
1312 case PPP_VINESCP:
1313 case PPP_IPV6CP:
1314 case PPP_CCP:
1315 break;
1316
1317 case PPP_LCP:
1318 case PPP_PAP:
1319 case PPP_LQM:
1320 case PPP_CHAP:
1321 case PPP_BACP:
1322 case PPP_BAP:
1323 case PPP_MP:
1324 break;
1325 }
1326
1327 model->ArgusThisUpHdr += hdr_len;
1328 model->ArgusThisLength -= hdr_len;
1329 model->ArgusSnapLength -= hdr_len;
1330 }
1331
1332 #ifdef ARGUSDEBUG
1333 ArgusDebug (8, "ArgusProcessPPPHdr(%p, %p, %d) returning %d\n", model, p, length, retn);
1334 #endif
1335 return (retn);
1336 }
1337
1338
1339 #define PPPOE_HDRLEN 6
1340
1341 int
ArgusProcessPPPoEHdr(struct ArgusModelerStruct * model,char * p,int length)1342 ArgusProcessPPPoEHdr (struct ArgusModelerStruct *model, char *p, int length)
1343 {
1344 const u_char *pload = (u_char *)p + PPPOE_HDRLEN;
1345 int retn = 0, hdr_len = PPPOE_HDRLEN;
1346 u_int proto;
1347
1348 model->ArgusThisEncaps |= ARGUS_ENCAPS_ETHER | ARGUS_ENCAPS_PPP;
1349
1350 if (!p[1]) {
1351 switch(EXTRACT_16BITS(p)) {
1352 case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL):
1353 pload += 2;
1354 hdr_len += 2;
1355 break;
1356 case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL):
1357 pload += 2;
1358 hdr_len += 2;
1359 break;
1360 case (PPP_ADDRESS << 8 | PPP_CONTROL):
1361 pload += 2; /* ACFC not used */
1362 hdr_len += 2;
1363 break;
1364 default:
1365 break;
1366 }
1367 if (*pload % 2) {
1368 proto = *pload; /* PFC is used */
1369 pload++;
1370 hdr_len++;
1371 } else {
1372 proto = EXTRACT_16BITS(pload);
1373 pload += 2;
1374 hdr_len += 2;
1375 }
1376 switch (proto) {
1377 case PPP_IP:
1378 model->ArgusThisNetworkFlowType = PPP_IP;
1379 retn = ETHERTYPE_IP;
1380 break;
1381
1382 case PPP_IPV6:
1383 model->ArgusThisNetworkFlowType = PPP_IPV6;
1384 retn = ETHERTYPE_IPV6;
1385 break;
1386
1387 case PPP_OSI:
1388 case PPP_NS:
1389 case PPP_DECNET:
1390 case PPP_APPLE:
1391 case PPP_IPX:
1392 case PPP_VJC:
1393 case PPP_VJNC:
1394 case PPP_BRPDU:
1395 case PPP_STII:
1396 case PPP_VINES:
1397
1398 case PPP_MPLS_UCAST:
1399 case PPP_MPLS_MCAST:
1400
1401 case PPP_COMP:
1402 case PPP_HELLO:
1403 case PPP_LUXCOM:
1404 case PPP_SNS:
1405 case PPP_IPCP:
1406 case PPP_OSICP:
1407 case PPP_NSCP:
1408 case PPP_DECNETCP:
1409 case PPP_APPLECP:
1410 case PPP_IPXCP:
1411 case PPP_STIICP:
1412 case PPP_VINESCP:
1413 case PPP_IPV6CP:
1414 case PPP_CCP:
1415 case PPP_LCP:
1416 case PPP_PAP:
1417 case PPP_LQM:
1418 case PPP_CHAP:
1419 case PPP_BACP:
1420 case PPP_BAP:
1421 case PPP_MP:
1422 break;
1423 }
1424 model->ArgusThisUpHdr += hdr_len;
1425 model->ArgusThisLength -= hdr_len;
1426 model->ArgusSnapLength -= hdr_len;
1427 }
1428
1429 #ifdef ARGUSDEBUG
1430 ArgusDebug (8, "ArgusProcessPPPoEHdr(%p, %p, %d) returning %d\n", model, p, length, retn);
1431 #endif
1432 return (retn);
1433 }
1434
1435 #define UDT2_DATA_PACKET 0x00
1436 #define UDT2_CONTROL_PACKET 0x80
1437 #define UDT2_PACKET_MASK 0x80
1438
1439 #define UDT2_HANDSHAKE 0x00
1440 #define UDT2_KEEPALIVE 0x01
1441 #define UDT2_ACK 0x02
1442 #define UDT2_NACK 0x03
1443 #define UDT2_ACK2 0x06
1444
1445 int
ArgusProcessUDToEHdr(struct ArgusModelerStruct * model,char * p,int length)1446 ArgusProcessUDToEHdr (struct ArgusModelerStruct *model, char *p, int length)
1447 {
1448 int retn = 0;
1449
1450 p += 2; // add 2 byte pad
1451 model->ArgusThisEncaps |= ARGUS_ENCAPS_UDT;
1452 model->ArgusThisUpHdr += 2;
1453 model->ArgusThisLength -= 2;
1454 model->ArgusSnapLength -= 2;
1455
1456 #ifdef ARGUSDEBUG
1457 ArgusDebug (8, "ArgusProcessUDToEHdr(%p, %p, %d) returning %d\n", model, p, length, retn);
1458 #endif
1459 return (retn);
1460 }
1461
1462
ArgusProcessErspanIIHdr(struct ArgusModelerStruct * model,char * p,int length)1463 int ArgusProcessErspanIIHdr(struct ArgusModelerStruct *model, char *p, int length)
1464 {
1465 int retn = 0;
1466 struct erspan_ii_header *erspan;
1467
1468 if ((erspan = (struct erspan_ii_header *) p) != NULL) {
1469 if (length <= sizeof (struct erspan_ii_header))
1470 return retn;
1471
1472 if ( ERSPAN_VER(erspan) != 0x1)
1473 return retn;
1474
1475 model->ArgusThisEncaps |= ARGUS_ENCAPS_ERSPAN_II;
1476 model->ArgusThisUpHdr = (unsigned char *)p + sizeof(struct erspan_ii_header);
1477 model->ArgusThisLength -= sizeof(struct erspan_ii_header);
1478 model->ArgusSnapLength -= sizeof(struct erspan_ii_header);
1479 retn = ARGUS_ETHER_HDR;
1480 }
1481 return retn;
1482 }
1483
1484
1485 int ArgusProcessLcpPacket (struct ArgusSourceStruct *, struct lcp_hdr *, int, struct timeval *);
1486
1487 int
ArgusProcessLcpPacket(struct ArgusSourceStruct * src,struct lcp_hdr * lcp,int length,struct timeval * tvp)1488 ArgusProcessLcpPacket (struct ArgusSourceStruct *src, struct lcp_hdr *lcp, int length, struct timeval *tvp)
1489 {
1490 struct ArgusModelerStruct *model = src->ArgusModel;
1491 struct ArgusSystemFlow *tflow = NULL;
1492 struct ArgusFlowStruct *flow;
1493 int retn = 0, status = 0;
1494
1495 model->ArgusTotalPacket++;
1496 model->state &= ~ARGUS_DIRECTION;
1497
1498 if (!(length) && !(tvp) && !(lcp))
1499 ArgusModelerCleanUp (model);
1500 else {
1501 if ((tflow = ArgusCreateLcpFlow(model, lcp)) != NULL) {
1502 ArgusCreateFlowKey(model, tflow, model->hstruct);
1503
1504 if ((flow = ArgusFindFlow (model, model->hstruct)) == NULL) {
1505 if ((flow = ArgusNewFlow(model, model->ArgusThisFlow, model->hstruct, model->ArgusStatusQueue)) != NULL) {
1506 if (getArgusControlMonitor(model))
1507 flow->userlen = ARGUS_MAXSNAPLEN;
1508 status = ARGUS_START;
1509 }
1510
1511 } else
1512 status = ARGUS_STATUS;
1513
1514 if (flow != NULL) {
1515 switch (lcp->code) {
1516 case PPP_LCP_CONF_REQ:
1517 break;
1518 case PPP_LCP_CONF_ACK:
1519 break;
1520 case PPP_LCP_CONF_NACK:
1521 break;
1522 case PPP_LCP_CONF_REJ:
1523 break;
1524 case PPP_LCP_TERM_REQ:
1525 break;
1526 case PPP_LCP_TERM_ACK:
1527 break;
1528 case PPP_LCP_CODE_REJ:
1529 break;
1530 case PPP_LCP_PROTO_REJ:
1531 break;
1532 case PPP_LCP_ECHO_REQ:
1533 break;
1534 case PPP_LCP_ECHO_REPLY:
1535 break;
1536 case PPP_LCP_DISCARD:
1537 break;
1538 }
1539 ArgusUpdateFlow (model, flow, status, 1);
1540 }
1541 }
1542 }
1543
1544 if (ArgusUpdateTime (model)) {
1545 ArgusQueueManager(model);
1546 #if !defined(ARGUS_THREADS)
1547 ArgusOutputProcess(ArgusOutputTask);
1548 #endif
1549 }
1550
1551 if (ArgusShutDownFlag)
1552 ArgusShutDown(0);
1553
1554 #ifdef ARGUSDEBUG
1555 ArgusDebug (5, "ArgusProcessLcpPacket(%p, %p, %d, %p) returning %d\n", model, lcp, length, tvp, retn);
1556 #endif
1557 return (retn);
1558 }
1559
1560 int ArgusProcessPacket (struct ArgusSourceStruct *, char *, int, struct timeval *, int);
1561
1562 int
ArgusProcessPacket(struct ArgusSourceStruct * src,char * p,int length,struct timeval * tvp,int type)1563 ArgusProcessPacket (struct ArgusSourceStruct *src, char *p, int length, struct timeval *tvp, int type)
1564 {
1565 struct ArgusModelerStruct *model = src->ArgusModel;
1566 struct ArgusSystemFlow *tflow = NULL;
1567 struct ArgusFlowStruct *flow = NULL;
1568 char *ptr = p;
1569 float value;
1570 int retn = 0;
1571
1572 model->ArgusTotalPacket++;
1573
1574 if (model->ArgusSrc->sNflag >= model->ArgusTotalPacket)
1575 return (retn);
1576
1577 model->ArgusThisInterface = src->ArgusThisIndex;
1578 model->ArgusThisStats = NULL;
1579 model->ArgusThisEpHdr = NULL;
1580 model->ArgusThisIpHdr = NULL;
1581 model->ArgusThisMplsLabelIndex = 0;
1582 model->ArgusThisNetworkFlowType = 0;
1583 model->ArgusInProtocol = 1;
1584
1585 if ((value = getArgusRealTime (model->ArgusSrc)) > 0) {
1586 long long tdiff, rtdiff;
1587 int tvalue;
1588
1589 gettimeofday(&model->ArgusNowTime, 0L);
1590 /*
1591 #ifdef ARGUSDEBUG
1592 ArgusDebug (3, "ArgusProcessPacket: now %d.%06d global %d.%06d \n",
1593 model->ArgusNowTime.tv_sec, model->ArgusNowTime.tv_usec,
1594 model->ArgusGlobalTime.tv_sec, model->ArgusGlobalTime.tv_usec);
1595 #endif
1596 */
1597 if (model->ArgusLastPacketTimer.tv_sec) {
1598 tdiff = ArgusTimeDiff (tvp, &model->ArgusLastPacketTimer);
1599 rtdiff = ArgusTimeDiff (&model->ArgusNowTime, &model->ArgusAdjustedTimer);
1600 tvalue = (int)(rtdiff * value);
1601
1602 if (tvalue > 0) {
1603 struct timespec tsbuf, *ts = &tsbuf;
1604 if (tvalue < 100000) {
1605 ts->tv_sec = 0;
1606 ts->tv_nsec = tvalue * 1000;
1607 } else {
1608 ts->tv_sec = 0;
1609 ts->tv_nsec = 100000000;
1610 }
1611 nanosleep (ts, NULL);
1612
1613 while (((tdiff - tvalue) > 0) && !(ArgusShutDownFlag)) {
1614 #ifdef ARGUSDEBUG
1615 ArgusDebug (8, "ArgusProcessPacket: stalling tdiff %lld rtdiff %lld tvalue %d\n", tdiff, rtdiff, tvalue);
1616 #endif
1617 model->ArgusGlobalTime = model->ArgusLastPacketTimer;
1618 model->ArgusGlobalTime.tv_sec += (tvalue / 1000000);
1619 model->ArgusGlobalTime.tv_usec += (tvalue % 1000000);
1620
1621 while (model->ArgusGlobalTime.tv_usec > 1000000) {
1622 model->ArgusGlobalTime.tv_sec++;
1623 model->ArgusGlobalTime.tv_usec -= 1000000;
1624 }
1625
1626 if (ArgusUpdateTime (model)) {
1627 ArgusQueueManager(model);
1628 ArgusModelerStats(model);
1629 #if !defined(ARGUS_THREADS)
1630 ArgusOutputProcess(ArgusOutputTask);
1631 #endif
1632 }
1633
1634 gettimeofday(&model->ArgusNowTime, 0L);
1635 rtdiff = ArgusTimeDiff (&model->ArgusNowTime, &model->ArgusAdjustedTimer);
1636 tvalue = (long long)(rtdiff * value);
1637 }
1638 }
1639 }
1640
1641 model->ArgusGlobalTime = *tvp;
1642 model->ArgusLastPacketTimer = *tvp;
1643 model->ArgusAdjustedTimer = model->ArgusNowTime;
1644 }
1645
1646 if (!(length) && !(tvp) && !(p) && !(ArgusShutDownFlag))
1647 ArgusModelerCleanUp (model);
1648 else {
1649 model->ArgusThisUpHdr = (unsigned char *)p;
1650 model->ArgusThisBytes = length;
1651
1652 while (type > 0)
1653 if ((type = ArgusProcessPacketHdrs (model, ptr, model->ArgusThisLength, type)) >= 0)
1654 ptr = (char *)model->ArgusThisUpHdr;
1655
1656 if (model->ArgusThisEpHdr)
1657 ptr = (char *)model->ArgusThisEpHdr;
1658
1659 if ((tflow = ArgusCreateFlow(model, ptr, length)) != NULL) {
1660 ArgusCreateFlowKey(model, tflow, model->hstruct);
1661
1662 if ((flow = ArgusFindFlow (model, model->hstruct)) != NULL) {
1663 struct ArgusQueueStruct *queue;
1664
1665 if ((queue = flow->qhdr.queue) != NULL) {
1666 model->ArgusTotalCacheHits++;
1667 if (queue == model->ArgusStatusQueue) {
1668 if (ArgusCheckTimeout(model, &flow->qhdr.qtime, getArgusFarReportInterval(model))) {
1669 ArgusProcessQueueTimeout (model, model->ArgusStatusQueue);
1670 ArgusRemoveFromQueue(flow->qhdr.queue, &flow->qhdr, ARGUS_LOCK);
1671 ArgusPushQueue(model->ArgusStatusQueue, &flow->qhdr, ARGUS_LOCK);
1672 queue->reclaim++;
1673 }
1674
1675 } else {
1676 if (!(tflow->hdr.argus_dsrvl8.qual & ARGUS_FRAGMENT)) {
1677 ArgusRemoveFromQueue(queue, &flow->qhdr, ARGUS_LOCK);
1678 ArgusPushQueue(model->ArgusStatusQueue, &flow->qhdr, ARGUS_LOCK);
1679 }
1680 }
1681
1682 if ((flow->qhdr.lasttime.tv_sec < model->ArgusGlobalTime.tv_sec) ||
1683 ((flow->qhdr.lasttime.tv_sec == model->ArgusGlobalTime.tv_sec) &&
1684 (flow->qhdr.lasttime.tv_usec < model->ArgusGlobalTime.tv_usec))) {
1685
1686 flow->qhdr.lasttime.tv_sec = model->ArgusGlobalTime.tv_sec;
1687 flow->qhdr.lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
1688 }
1689
1690 ArgusUpdateFlow (model, flow, ARGUS_STATUS, 1);
1691
1692 } else {
1693 struct ArgusFlowStruct *nflow;
1694 ArgusRemoveHashEntry(flow->htblhdr);
1695 flow->htblhdr = NULL;
1696 if ((nflow = ArgusNewFlow(model, (struct ArgusSystemFlow *)flow->dsrs[ARGUS_FLOW_INDEX], model->hstruct, model->ArgusStatusQueue)) != NULL)
1697 ArgusUpdateFlow (model, nflow, ARGUS_STATUS, 1);
1698 }
1699
1700 } else {
1701 if ((flow = ArgusNewFlow(model, model->ArgusThisFlow, model->hstruct, model->ArgusStatusQueue)) != NULL)
1702 ArgusUpdateFlow (model, flow, ARGUS_START, 1);
1703 }
1704 }
1705 if (flow == NULL)
1706 retn = 1;
1707 }
1708
1709 if (ArgusUpdateTime (model)) {
1710 ArgusQueueManager (model);
1711 #if !defined(ARGUS_THREADS)
1712 ArgusOutputProcess(ArgusOutputTask);
1713 #endif
1714 }
1715
1716 if (ArgusShutDownFlag)
1717 ArgusShutDown(0);
1718
1719 #ifdef ARGUSDEBUG
1720 ArgusDebug (8, "ArgusProcessPacket(%p, %p, %d, %p, %d) returning %d\n", model, p, length, tvp, type, retn);
1721 #endif
1722 return (retn);
1723 }
1724
1725 int
ArgusProcessIpPacket(struct ArgusModelerStruct * model,struct ip * ip,int length,struct timeval * tvp)1726 ArgusProcessIpPacket (struct ArgusModelerStruct *model, struct ip *ip, int length, struct timeval *tvp)
1727 {
1728 struct ArgusSystemFlow *tflow = NULL;
1729 struct ArgusFlowStruct *flow = NULL;
1730 char *ptr = (char *)ip;
1731
1732 int retn = 0, pass = 0, type = ETHERTYPE_IP;
1733
1734
1735 model->ArgusTotalPacket++;
1736
1737 while (type > 0)
1738 if ((type = ArgusProcessPacketHdrs (model, ptr, model->ArgusThisLength, type)) >= 0)
1739 ptr = (char *)model->ArgusThisUpHdr;
1740
1741 ip = model->ArgusThisIpHdr;
1742
1743 if (model->ArgusSrc->sNflag >= model->ArgusTotalPacket)
1744 return (retn);
1745
1746 model->state &= ~ARGUS_DIRECTION;
1747
1748 if (!(length) && !(tvp) && !(ip))
1749 ArgusModelerCleanUp (model);
1750
1751 else {
1752 if (ip->ip_v == 4) {
1753 model->ArgusThisNetworkFlowType = ETHERTYPE_IP;
1754 pass = STRUCTCAPTURED(model,*ip);
1755 } else {
1756 struct ip6_hdr *ipv6 = (struct ip6_hdr *) ip;
1757 model->ArgusThisNetworkFlowType = ETHERTYPE_IPV6;
1758 pass = STRUCTCAPTURED(model,*ipv6);
1759 }
1760 /*
1761 model->ArgusThisIpHdr = (unsigned char *)ip;
1762 model->ArgusThisUpHdr = (unsigned char *)ip;
1763 */
1764 model->ArgusThisBytes = length;
1765
1766 if (pass) {
1767 if ((tflow = ArgusCreateFlow(model, ip, length)) != NULL) {
1768 ArgusCreateFlowKey (model, tflow, model->hstruct);
1769 if ((flow = ArgusFindFlow (model, model->hstruct)) != NULL) {
1770 struct ArgusQueueStruct *queue;
1771
1772 if ((queue = flow->qhdr.queue) != NULL) {
1773 model->ArgusTotalCacheHits++;
1774
1775 if ((queue = flow->qhdr.queue) == model->ArgusStatusQueue) {
1776 if (ArgusCheckTimeout(model, &flow->qhdr.qtime, getArgusFarReportInterval(model))) {
1777 if (flow != (struct ArgusFlowStruct *) queue->start->prv)
1778 ArgusProcessQueueTimeout (model, model->ArgusStatusQueue); // if this record is timed out, all entries in status queue need to be timed out
1779 if (!(flow->status & ARGUS_RECORD_WRITTEN))
1780 ArgusSendFlowRecord (model, flow, flow->status);
1781 ArgusRemoveFromQueue(flow->qhdr.queue, &flow->qhdr, ARGUS_LOCK);
1782 ArgusPushQueue(model->ArgusStatusQueue, &flow->qhdr, ARGUS_LOCK);
1783 queue->reclaim++;
1784
1785 }
1786
1787 } else {
1788 if (queue) {
1789 ArgusRemoveFromQueue(queue, &flow->qhdr, ARGUS_LOCK);
1790 ArgusPushQueue(model->ArgusStatusQueue, &flow->qhdr, ARGUS_LOCK);
1791 }
1792 }
1793
1794 if ((flow->qhdr.lasttime.tv_sec < model->ArgusGlobalTime.tv_sec) ||
1795 ((flow->qhdr.lasttime.tv_sec == model->ArgusGlobalTime.tv_sec) &&
1796 (flow->qhdr.lasttime.tv_usec < model->ArgusGlobalTime.tv_usec))) {
1797
1798 flow->qhdr.lasttime.tv_sec = model->ArgusGlobalTime.tv_sec;
1799 flow->qhdr.lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
1800 }
1801
1802 ArgusUpdateFlow (model, flow, ARGUS_STATUS, 1);
1803
1804 } else {
1805 struct ArgusFlowStruct *nflow;
1806 ArgusRemoveHashEntry(flow->htblhdr);
1807 flow->htblhdr = NULL;
1808 if ((nflow = ArgusNewFlow(model, (struct ArgusSystemFlow *)flow->dsrs[ARGUS_FLOW_INDEX], model->hstruct, model->ArgusStatusQueue)) != NULL)
1809 ArgusUpdateFlow (model, nflow, ARGUS_STATUS, 1);
1810 }
1811
1812 } else {
1813 if ((flow = ArgusNewFlow(model, model->ArgusThisFlow, model->hstruct, model->ArgusStatusQueue)) != NULL)
1814 ArgusUpdateFlow (model, flow, ARGUS_START, 1);
1815 }
1816 }
1817 }
1818 if (flow == NULL)
1819 retn = 1;
1820 }
1821
1822 if (ArgusUpdateTime (model)) {
1823 ArgusQueueManager (model);
1824 #if !defined(ARGUS_THREADS)
1825 ArgusOutputProcess(ArgusOutputTask);
1826 #endif
1827 }
1828
1829 if (ArgusShutDownFlag)
1830 ArgusShutDown(0);
1831
1832 #ifdef ARGUSDEBUG
1833 ArgusDebug (5, "ArgusProcessIpPacket(%p, %d, %p) returning %d\n", ip, length, tvp, retn);
1834 #endif
1835
1836 return (retn);
1837 }
1838
1839 int
ArgusProcessEtherPacket(struct ArgusModelerStruct * model,struct ether_header * ep,int length,struct timeval * tvp)1840 ArgusProcessEtherPacket (struct ArgusModelerStruct *model, struct ether_header *ep, int length, struct timeval *tvp)
1841 {
1842 struct ArgusSystemFlow *tflow = NULL;
1843 struct ArgusFlowStruct *flow = NULL;
1844 int retn = 0, type;
1845
1846 char *ptr = (char *)ep;
1847
1848 model->ArgusTotalPacket++;
1849
1850 if (model->ArgusSrc->sNflag >= model->ArgusTotalPacket)
1851 return (retn);
1852
1853 model->state &= ~ARGUS_DIRECTION;
1854
1855 if (!(length) && !(tvp) && !(ep))
1856 ArgusModelerCleanUp (model);
1857
1858 else {
1859 if (STRUCTCAPTURED(model,*ep)) {
1860 type = ARGUS_ETHER_HDR;
1861 model->ArgusThisBytes = length;
1862
1863 while (type) {
1864 type = ArgusProcessPacketHdrs (model, ptr, model->ArgusThisLength, type);
1865 ptr = (char *)model->ArgusThisUpHdr;
1866 }
1867
1868 if ((tflow = ArgusCreateFlow(model, model->ArgusThisEpHdr, length)) != NULL) {
1869 ArgusCreateFlowKey(model, tflow, model->hstruct);
1870 if ((flow = ArgusFindFlow (model, model->hstruct)) != NULL) {
1871 struct ArgusQueueStruct *queue;
1872
1873 if ((queue = flow->qhdr.queue) != NULL) {
1874 model->ArgusTotalCacheHits++;
1875 if ((queue = flow->qhdr.queue) == model->ArgusStatusQueue) {
1876 if (ArgusCheckTimeout(model, &flow->qhdr.qtime, getArgusFarReportInterval(model))) {
1877 if (flow != (struct ArgusFlowStruct *) queue->start->prv)
1878 ArgusProcessQueueTimeout (model, model->ArgusStatusQueue); // if this record is not last, other entries in status queue need to be timed out
1879 if (!(flow->status & ARGUS_RECORD_WRITTEN))
1880 ArgusSendFlowRecord (model, flow, flow->status);
1881 ArgusRemoveFromQueue(flow->qhdr.queue, &flow->qhdr, ARGUS_LOCK);
1882 ArgusPushQueue(model->ArgusStatusQueue, &flow->qhdr, ARGUS_LOCK);
1883 queue->reclaim++;
1884 }
1885
1886 } else {
1887 if (queue) {
1888 ArgusRemoveFromQueue(queue, &flow->qhdr, ARGUS_LOCK);
1889 ArgusPushQueue(model->ArgusStatusQueue, &flow->qhdr, ARGUS_LOCK);
1890 }
1891 }
1892
1893 if ((flow->qhdr.lasttime.tv_sec < model->ArgusGlobalTime.tv_sec) ||
1894 ((flow->qhdr.lasttime.tv_sec == model->ArgusGlobalTime.tv_sec) &&
1895 (flow->qhdr.lasttime.tv_usec < model->ArgusGlobalTime.tv_usec))) {
1896
1897 flow->qhdr.lasttime.tv_sec = model->ArgusGlobalTime.tv_sec;
1898 flow->qhdr.lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
1899 }
1900
1901 ArgusUpdateFlow (model, flow, ARGUS_STATUS, 1);
1902
1903 } else {
1904 struct ArgusFlowStruct *nflow;
1905 ArgusRemoveHashEntry(flow->htblhdr);
1906 flow->htblhdr = NULL;
1907 if ((nflow = ArgusNewFlow(model, (struct ArgusSystemFlow *)flow->dsrs[ARGUS_FLOW_INDEX], model->hstruct, model->ArgusStatusQueue)) != NULL)
1908 ArgusUpdateFlow (model, nflow, ARGUS_STATUS, 1);
1909 }
1910
1911 } else {
1912 if ((flow = ArgusNewFlow(model, model->ArgusThisFlow, model->hstruct, model->ArgusStatusQueue)) != NULL)
1913 ArgusUpdateFlow (model, flow, ARGUS_START, 1);
1914 }
1915 }
1916 }
1917 if (flow == NULL)
1918 retn = 1;
1919 }
1920
1921 if (ArgusUpdateTime (model)) {
1922 ArgusQueueManager (model);
1923 #if !defined(ARGUS_THREADS)
1924 ArgusOutputProcess(ArgusOutputTask);
1925 #endif
1926 }
1927
1928 if (ArgusShutDownFlag)
1929 ArgusShutDown(0);
1930
1931 #ifdef ARGUSDEBUG
1932 ArgusDebug (5, "ArgusProcessEtherPacket(%p, %d, %p) returning %d\n", ep, length, tvp, retn);
1933 #endif
1934
1935 return (retn);
1936 }
1937
1938
1939 void *
ArgusCreateFlow(struct ArgusModelerStruct * model,void * ptr,int length)1940 ArgusCreateFlow (struct ArgusModelerStruct *model, void *ptr, int length)
1941 {
1942 void *retn = model->ArgusThisFlow;
1943 struct ether_header *ep = ptr;
1944 unsigned int keys = model->ArgusFlowKey;
1945 unsigned int index = 0;
1946 int i;
1947
1948 model->state &= ~ARGUS_DIRECTION;
1949 memset (model->ArgusThisFlow, 0, sizeof(*model->ArgusThisFlow));
1950
1951 for (i = 0; (keys && (i < ARGUS_FLOW_KEYS)); i++) {
1952 index = 0x01 << i;
1953 if (keys & index) {
1954 switch (index) {
1955 case ARGUS_FLOW_KEY_CLASSIC5TUPLE:
1956 case ARGUS_FLOW_KEY_LAYER_3_MATRIX:
1957 switch (model->ArgusThisNetworkFlowType & 0xFFFF) {
1958 case ETHERTYPE_IP: {
1959 retn = ArgusCreateIPv4Flow (model, (struct ip *)model->ArgusThisIpHdr);
1960 return (retn);
1961 }
1962 case ETHERTYPE_IPV6: {
1963 retn = ArgusCreateIPv6Flow (model, (struct ip6_hdr *)model->ArgusThisIpHdr);
1964 return (retn);
1965 }
1966 case ETHERTYPE_ARP:
1967 case ETHERTYPE_REVARP: {
1968 model->ArgusThisLength = length;
1969 retn = ArgusCreateArpFlow (model, ep);
1970 return (retn);
1971 }
1972
1973 case ARGUS_802_11_HDR: {
1974 model->ArgusThisLength = length;
1975 retn = ArgusCreate80211Flow (model, ptr);
1976 return (retn);
1977 }
1978
1979 case ARGUS_ISIS:
1980 retn = ArgusCreateIsisFlow (model, (struct isis_common_header *) model->ArgusThisUpHdr);
1981 return (retn);
1982
1983 case ETHERTYPE_UDTOE:
1984 retn = ArgusCreateUDTFlow (model, (struct udt_header *) model->ArgusThisUpHdr);
1985 return (retn);
1986 }
1987
1988 if (model->ArgusThisIpHdr) {
1989 model->ArgusThisNetworkFlowType &= 0xFFFF0000;
1990 model->ArgusThisNetworkFlowType |= ETHERTYPE_IP;
1991 retn = ArgusCreateIPv4Flow (model, (struct ip *)model->ArgusThisIpHdr);
1992 break;
1993 }
1994
1995 /* drop through to here if above protocols didn't do it */
1996 case ARGUS_FLOW_KEY_LAYER_2_MATRIX:
1997 if (ep != NULL) {
1998 int dstgteq = 1, i;
1999 model->ArgusThisLength = length;
2000 model->ArgusThisFlow->hdr.type = ARGUS_FLOW_DSR;
2001 model->ArgusThisFlow->hdr.subtype = ARGUS_FLOW_CLASSIC5TUPLE;
2002 model->ArgusThisFlow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_ETHER;
2003 model->ArgusThisFlow->hdr.argus_dsrvl8.len = 5;
2004
2005 #if !defined(ETH_ALEN)
2006 #define ETH_ALEN 6
2007 #endif
2008 if (model->ArgusFlowType == ARGUS_BIDIRECTIONAL) {
2009 for (i = 0; i < ETH_ALEN; i++) {
2010 if (((unsigned char *)&ep->ether_shost)[i] != ((unsigned char *)&ep->ether_dhost)[i]) {
2011 if (((unsigned char *)&ep->ether_shost)[i] > ((unsigned char *)&ep->ether_dhost)[i])
2012 dstgteq = 0;
2013 break;
2014 }
2015 }
2016 }
2017
2018 if (dstgteq) {
2019 bcopy ((char *) ep, (char *)&model->ArgusThisFlow->mac_flow.ehdr, sizeof (struct ether_header));
2020 } else {
2021 model->state |= ARGUS_DIRECTION;
2022 bcopy ((char *)&ep->ether_shost, (char *)&model->ArgusThisFlow->mac_flow.ehdr.ether_dhost, ETH_ALEN);
2023 bcopy ((char *)&ep->ether_dhost, (char *)&model->ArgusThisFlow->mac_flow.ehdr.ether_shost, ETH_ALEN);
2024 }
2025 model->ArgusThisFlow->mac_flow.ehdr.ether_type = ntohs(ep->ether_type);
2026
2027 if (model->ArgusThisEncaps & ARGUS_ENCAPS_LLC) {
2028 model->ArgusThisFlow->mac_flow.ehdr.ether_type = 0;
2029 switch (model->ArgusThisNetworkFlowType & 0xFFFF) {
2030 case ARGUS_CLNS:
2031 case ARGUS_ESIS:
2032 case ARGUS_NULLNS:
2033 break;
2034
2035 default:
2036 model->ArgusThisNetworkFlowType &= ~(0xFFFF);
2037 break;
2038 }
2039 if (dstgteq) {
2040 model->ArgusThisFlow->mac_flow.ssap = model->ArgusThisLLC->ssap;
2041 model->ArgusThisFlow->mac_flow.dsap = model->ArgusThisLLC->dsap;
2042 } else {
2043 model->ArgusThisFlow->mac_flow.ssap = model->ArgusThisLLC->dsap;
2044 model->ArgusThisFlow->mac_flow.dsap = model->ArgusThisLLC->ssap;
2045 }
2046 } else {
2047 model->ArgusThisFlow->mac_flow.ssap = 0;
2048 model->ArgusThisFlow->mac_flow.dsap = 0;
2049 }
2050 }
2051 break;
2052
2053 case ARGUS_FLOW_KEY_LOCAL_MPLS:
2054 case ARGUS_FLOW_KEY_COMPLETE_MPLS:
2055 break;
2056
2057 case ARGUS_FLOW_KEY_VLAN:
2058 break;
2059 }
2060 }
2061 }
2062
2063 #ifdef ARGUSDEBUG
2064 ArgusDebug (9, "ArgusCreateFlow() returning %p\n", retn);
2065 #endif
2066
2067 return (retn);
2068 }
2069
2070
2071 int ArgusGenerateStartRecords = 0;
2072
2073 struct ArgusFlowStruct *
ArgusNewFlow(struct ArgusModelerStruct * model,struct ArgusSystemFlow * flow,struct ArgusHashStruct * hstruct,struct ArgusQueueStruct * queue)2074 ArgusNewFlow (struct ArgusModelerStruct *model, struct ArgusSystemFlow *flow, struct ArgusHashStruct *hstruct, struct ArgusQueueStruct *queue)
2075 {
2076 struct ArgusFlowStruct *retn = NULL;
2077 int timeout = ARGUS_OTHERTIMEOUT, userlen = 0;
2078 int len = flow->hdr.argus_dsrvl8.len;
2079
2080 if (len > 0) {
2081 model->ArgusTotalNewFlows++;
2082 userlen = getArgusUserDataLen(model);
2083
2084 if ((retn = (struct ArgusFlowStruct *) ArgusCalloc (1, sizeof(*retn))) != NULL) {
2085 int value;
2086 retn->status = ARGUS_START;
2087 retn->state = model->state & ARGUS_DIRECTION;
2088 retn->trans = model->ArgusTransactionNum++;
2089 retn->userlen = userlen;
2090
2091 retn->srcint = -1;
2092 retn->dstint = -1;
2093
2094 if (queue != NULL) {
2095 retn->qhdr.lasttime.tv_sec = model->ArgusGlobalTime.tv_sec;
2096 retn->qhdr.lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
2097 }
2098
2099 retn->dsrs[ARGUS_FLOW_INDEX] = (struct ArgusDSRHeader *) &retn->canon.flow.hdr;
2100 retn->canon.flow.hdr = flow->hdr;
2101
2102 bcopy ((char *)&flow->flow_un, (char *)&retn->canon.flow.flow_un, (flow->hdr.argus_dsrvl8.len - 1) * 4);
2103 retn->dsrindex |= 1 << ARGUS_FLOW_INDEX;
2104
2105 if (retn->state & ARGUS_DIRECTION)
2106 retn->dsrs[ARGUS_FLOW_INDEX]->subtype |= ARGUS_REVERSE;
2107
2108 if (hstruct != NULL) {
2109 if ((retn->htblhdr = ArgusAddHashEntry (model->ArgusHashTable, retn, hstruct)) != NULL) {
2110 if (queue != NULL)
2111 ArgusPushQueue(queue, &retn->qhdr, ARGUS_LOCK);
2112 } else
2113 ArgusLog (LOG_ERR, "ArgusNewFlow() ArgusAddHashEntry error %s.\n", strerror(errno));
2114 }
2115
2116 if ((value = getArgusKeystroke(model)) > 0) {
2117 if (value & ARGUS_SSH_KEYSTROKE)
2118 retn->status |= ARGUS_SSH_MONITOR;
2119 retn->skey.prev_pno = 0 - model->ArgusKeyStroke.gpc_max;
2120 }
2121
2122 } else
2123 ArgusLog (LOG_WARNING, "ArgusNewFlow() ArgusMalloc error %s.\n", strerror(errno));
2124
2125 switch (model->ArgusThisNetworkFlowType & 0xFFFF) {
2126 case ETHERTYPE_IPV6:
2127 case ETHERTYPE_IP:
2128 timeout = model->ArgusIPTimeout;
2129 model->ArgusTotalIPFlows++;
2130 if (ArgusControlPlaneProtocol(model, retn))
2131 retn->userlen = ARGUS_MAXSNAPLEN;
2132 break;
2133
2134 case ETHERTYPE_ARP:
2135 case ETHERTYPE_REVARP:
2136 timeout = model->ArgusARPTimeout;
2137 model->ArgusTotalNonIPFlows++;
2138 if (getArgusControlMonitor(model))
2139 retn->userlen = ARGUS_MAXSNAPLEN;
2140 break;
2141
2142 case ARGUS_ISIS:
2143 timeout = ARGUS_OTHERTIMEOUT;
2144 model->ArgusTotalNonIPFlows++;
2145 if (getArgusControlMonitor(model))
2146 retn->userlen = ARGUS_MAXSNAPLEN;
2147 break;
2148
2149 default:
2150 model->ArgusTotalNonIPFlows++;
2151 timeout = ARGUS_OTHERTIMEOUT;
2152 break;
2153 }
2154
2155 retn->timeout = timeout;
2156
2157 } else
2158 ArgusLog (LOG_WARNING, "ArgusNewFlow() flow key is not correct len equals zero\n");
2159
2160 #ifdef ARGUSDEBUG
2161 ArgusDebug (8, "ArgusNewFlow() returning %p\n", retn);
2162 #endif
2163
2164 return (retn);
2165 }
2166
2167
2168 extern void ArgusZeroRecord(struct ArgusFlowStruct *);
2169 void ArgusUpdateBasicFlow (struct ArgusModelerStruct *, struct ArgusFlowStruct *, unsigned char);
2170
2171
2172 void
ArgusUpdateBasicFlow(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flow,unsigned char state)2173 ArgusUpdateBasicFlow (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flow, unsigned char state)
2174 {
2175 struct ArgusTransportStruct *trans;
2176 struct ArgusTimeStruct *dtime, *otime = NULL;
2177 struct ArgusEncapsStruct *encaps;
2178 struct ArgusMetricStruct *metric;
2179 struct ArgusNetworkStruct *net;
2180 struct ArgusMplsStruct *mpls;
2181 struct ArgusVlanStruct *vlan;
2182 struct ArgusTimeObject *time;
2183 struct ArgusJitterStruct *jitter;
2184 model->ArgusTotalUpdates++;
2185
2186 if (flow->status & ARGUS_RECORD_WRITTEN)
2187 ArgusZeroRecord(flow);
2188
2189 model->ArgusThisDir = ((flow->state & ARGUS_DIRECTION) == (model->state & ARGUS_DIRECTION));
2190
2191 if ((trans = (struct ArgusTransportStruct *) flow->dsrs[ARGUS_TRANSPORT_INDEX]) == NULL) {
2192 struct ArgusDeviceStruct *device = model->ArgusSrc->ArgusInterface[model->ArgusSrc->ArgusThisIndex].ArgusDevice;
2193
2194 flow->dsrs[ARGUS_TRANSPORT_INDEX] = &flow->canon.trans.hdr;
2195 trans = (struct ArgusTransportStruct *) flow->dsrs[ARGUS_TRANSPORT_INDEX];
2196 trans->hdr.type = ARGUS_TRANSPORT_DSR;
2197 trans->hdr.subtype = ARGUS_SRCID | ARGUS_SEQ;
2198 trans->hdr.argus_dsrvl8.len = 3;
2199
2200 trans->srcid.a_un.value = device->ArgusID.a_un.value;
2201 trans->hdr.argus_dsrvl8.qual = device->idtype;
2202
2203 flow->dsrindex |= 0x01 << ARGUS_TRANSPORT_INDEX;
2204 }
2205
2206 if (model->ArgusThisDir) {
2207 if (flow->srcint >= 0) {
2208 if (flow->srcint != model->ArgusThisInterface) {
2209 flow->canon.encaps.hdr.argus_dsrvl8.qual |= ARGUS_SRC_INT_CHANGED;
2210 }
2211 } else
2212 flow->srcint = model->ArgusThisInterface;
2213 } else {
2214 if (flow->dstint >= 0) {
2215 if (flow->dstint != model->ArgusThisInterface) {
2216 flow->canon.encaps.hdr.argus_dsrvl8.qual |= ARGUS_DST_INT_CHANGED;
2217 }
2218 } else
2219 flow->dstint = model->ArgusThisInterface;
2220 }
2221
2222 if ((encaps = (struct ArgusEncapsStruct *) flow->dsrs[ARGUS_ENCAPS_INDEX]) == NULL) {
2223 flow->dsrs[ARGUS_ENCAPS_INDEX] = (struct ArgusDSRHeader *) &flow->canon.encaps.hdr;
2224 encaps = (struct ArgusEncapsStruct *) flow->dsrs[ARGUS_ENCAPS_INDEX];
2225 memset(encaps, 0, sizeof(*encaps));
2226 encaps->hdr.type = ARGUS_ENCAPS_DSR;
2227 encaps->hdr.argus_dsrvl8.len = 3;
2228 flow->dsrindex |= 0x01 << ARGUS_ENCAPS_INDEX;
2229
2230 if (model->ArgusThisDir)
2231 encaps->src = model->ArgusThisEncaps;
2232 else
2233 encaps->dst = model->ArgusThisEncaps;
2234
2235 } else {
2236 if (model->ArgusThisDir) {
2237 if (flow->canon.encaps.src != model->ArgusThisEncaps) {
2238 if (flow->canon.encaps.src)
2239 flow->canon.encaps.hdr.argus_dsrvl8.qual |= ARGUS_SRC_CHANGED;
2240 flow->canon.encaps.src |= model->ArgusThisEncaps;
2241 }
2242
2243 } else {
2244 if (flow->canon.encaps.dst != model->ArgusThisEncaps) {
2245 if (flow->canon.encaps.dst)
2246 flow->canon.encaps.hdr.argus_dsrvl8.qual |= ARGUS_DST_CHANGED;
2247 flow->canon.encaps.dst |= model->ArgusThisEncaps;
2248 }
2249 }
2250 }
2251
2252 if ((metric = (struct ArgusMetricStruct *) flow->dsrs[ARGUS_METRIC_INDEX]) == NULL) {
2253 metric = (struct ArgusMetricStruct *)&flow->canon.metric.hdr;
2254 memset(metric, 0, sizeof(*metric));
2255 flow->dsrs[ARGUS_METRIC_INDEX] = (struct ArgusDSRHeader *) metric;
2256 metric->hdr.type = ARGUS_METER_DSR;
2257 metric->hdr.argus_dsrvl8.len = (sizeof(struct ArgusMetricStruct) + 3) / 4;
2258
2259 flow->dsrindex |= 1 << ARGUS_METRIC_INDEX;
2260 }
2261
2262 if ((time = (struct ArgusTimeObject *) flow->dsrs[ARGUS_TIME_INDEX]) == NULL) {
2263 time = &flow->canon.time;
2264 memset(time, 0, sizeof(*time));
2265 flow->dsrs[ARGUS_TIME_INDEX] = (struct ArgusDSRHeader *) time;
2266 time->hdr.type = ARGUS_TIME_DSR;
2267 time->hdr.subtype = ARGUS_TIME_ABSOLUTE_TIMESTAMP;
2268 time->hdr.argus_dsrvl8.qual = ARGUS_TYPE_UTC_MICROSECONDS;
2269 time->hdr.argus_dsrvl8.len = 3;
2270
2271 if (model->ArgusThisDir) {
2272 dtime = &time->src;
2273 otime = &time->dst;
2274 } else {
2275 dtime = &time->dst;
2276 otime = &time->src;
2277 }
2278 dtime->start.tv_sec = model->ArgusGlobalTime.tv_sec;
2279 dtime->start.tv_usec = model->ArgusGlobalTime.tv_usec;
2280
2281 } else {
2282 if (model->ArgusThisDir) {
2283 dtime = &time->src;
2284 otime = &time->dst;
2285 } else {
2286 dtime = &time->dst;
2287 otime = &time->src;
2288 }
2289 if (dtime->start.tv_sec == 0) {
2290 dtime->start.tv_sec = model->ArgusGlobalTime.tv_sec;
2291 dtime->start.tv_usec = model->ArgusGlobalTime.tv_usec;
2292 if (otime->start.tv_sec) {
2293 time->hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
2294 }
2295
2296 } else {
2297 dtime->end.tv_sec = model->ArgusGlobalTime.tv_sec;
2298 dtime->end.tv_usec = model->ArgusGlobalTime.tv_usec;
2299 time->hdr.subtype = ARGUS_TIME_ABSOLUTE_RANGE;
2300 }
2301 }
2302
2303 flow->dsrindex |= 1 << ARGUS_TIME_INDEX;
2304
2305 if (getArgusmflag (model)) {
2306 struct ArgusMacStruct *mac;
2307 if ((mac = (struct ArgusMacStruct *) flow->dsrs[ARGUS_MAC_INDEX]) == NULL) {
2308 if (model->ArgusThisEpHdr != NULL) {
2309 mac = (struct ArgusMacStruct *) &flow->canon.mac.hdr;
2310 memset(mac, 0, sizeof(*mac));
2311 flow->dsrs[ARGUS_MAC_INDEX] = &mac->hdr;
2312 mac->hdr.type = ARGUS_MAC_DSR;
2313 mac->hdr.subtype = 0;
2314 mac->hdr.argus_dsrvl8.qual = 0;
2315 mac->hdr.argus_dsrvl8.len = 5;
2316
2317 if (model->ArgusThisDir) {
2318 bcopy ((char *)model->ArgusThisEpHdr, (char *)&mac->mac.mac_union.ether, sizeof(struct ether_header));
2319 } else {
2320 bcopy ((char *)&model->ArgusThisEpHdr->ether_dhost,
2321 (char *)&mac->mac.mac_union.ether.ehdr.ether_shost, sizeof(struct ether_addr));
2322 bcopy ((char *)&model->ArgusThisEpHdr->ether_shost,
2323 (char *)&mac->mac.mac_union.ether.ehdr.ether_dhost, sizeof(struct ether_header));
2324 }
2325 mac->mac.mac_union.ether.ehdr.ether_type = ntohs(model->ArgusThisEpHdr->ether_type);
2326
2327 flow->dsrindex |= 1 << ARGUS_MAC_INDEX;
2328 }
2329
2330 } else {
2331 if (model->ArgusThisDir) {
2332 if (bcmp ((char *)&model->ArgusThisEpHdr->ether_shost,
2333 (char *)&mac->mac.mac_union.ether.ehdr.ether_shost, sizeof(struct ether_addr)) ||
2334 bcmp ((char *)&model->ArgusThisEpHdr->ether_dhost,
2335 (char *)&mac->mac.mac_union.ether.ehdr.ether_dhost, sizeof(struct ether_addr)) ||
2336 mac->mac.mac_union.ether.ehdr.ether_type != ntohs(model->ArgusThisEpHdr->ether_type))
2337 mac->hdr.argus_dsrvl8.qual |= ARGUS_SRC_MULTIPATH;
2338
2339 } else {
2340 if (bcmp ((char *)&model->ArgusThisEpHdr->ether_dhost,
2341 (char *)&mac->mac.mac_union.ether.ehdr.ether_shost, sizeof(struct ether_addr)) ||
2342 bcmp ((char *)&model->ArgusThisEpHdr->ether_shost,
2343 (char *)&mac->mac.mac_union.ether.ehdr.ether_dhost, sizeof(struct ether_addr)) ||
2344 mac->mac.mac_union.ether.ehdr.ether_type != ntohs(model->ArgusThisEpHdr->ether_type))
2345 mac->hdr.argus_dsrvl8.qual |= ARGUS_DST_MULTIPATH;
2346 }
2347 }
2348 }
2349
2350 if ((net = (struct ArgusNetworkStruct *) flow->dsrs[ARGUS_NETWORK_INDEX]) == NULL) {
2351 net = (struct ArgusNetworkStruct *) &flow->canon.net;
2352 memset(net, 0, sizeof(*net));
2353 flow->dsrs[ARGUS_NETWORK_INDEX] = (struct ArgusDSRHeader *) net;
2354
2355 if ((state == ARGUS_START) && (model->ArgusThisFlow->hdr.argus_dsrvl8.qual & ARGUS_FRAGMENT)) {
2356 net->hdr.type = ARGUS_NETWORK_DSR;
2357 net->hdr.subtype = ARGUS_NETWORK_SUBTYPE_FRAG;
2358 net->hdr.argus_dsrvl8.qual = 0;
2359 net->hdr.argus_dsrvl8.len = ((sizeof(struct ArgusFragObject) + 3)/4) + 1;
2360 } else {
2361 net->hdr.type = ARGUS_NETWORK_DSR;
2362 net->hdr.argus_dsrvl8.len = 1;
2363 flow->dsrindex |= 1 << ARGUS_NETWORK_INDEX;
2364 }
2365 }
2366 if (model->ArgusThisEncaps & ARGUS_ENCAPS_MPLS) {
2367 int test = 0, value;
2368 if ((mpls = (struct ArgusMplsStruct *) flow->dsrs[ARGUS_MPLS_INDEX]) == NULL) {
2369 mpls = (struct ArgusMplsStruct *) &flow->canon.mpls;
2370 memset(mpls, 0, sizeof(*mpls));
2371 flow->dsrs[ARGUS_MPLS_INDEX] = (struct ArgusDSRHeader *) mpls;
2372 mpls->hdr.type = ARGUS_MPLS_DSR;
2373 mpls->hdr.subtype = 0;
2374 mpls->hdr.argus_dsrvl8.qual = 0;
2375 mpls->hdr.argus_dsrvl8.len = 1;
2376 flow->dsrindex |= 1 << ARGUS_MPLS_INDEX;
2377 } else
2378 test++;
2379
2380 if (model->ArgusThisDir) {
2381 value = mpls->hdr.argus_dsrvl8.qual & 0x0F;
2382 mpls->hdr.argus_dsrvl8.qual = ((model->ArgusThisMplsLabelIndex & 0x0F) << 4) | value;
2383 mpls->slabel = model->ArgusThisMplsLabel;
2384
2385 } else {
2386 value = mpls->hdr.argus_dsrvl8.qual & 0xF0;
2387 mpls->hdr.argus_dsrvl8.qual = (model->ArgusThisMplsLabelIndex & 0x0F) | value;
2388 mpls->dlabel = model->ArgusThisMplsLabel;
2389 }
2390 }
2391
2392 if (model->ArgusThisEncaps & ARGUS_ENCAPS_8021Q) {
2393 if ((vlan = (struct ArgusVlanStruct *) flow->dsrs[ARGUS_VLAN_INDEX]) == NULL) {
2394 vlan = (struct ArgusVlanStruct *) &flow->canon.vlan;
2395 memset(vlan, 0, sizeof(*vlan));
2396 flow->dsrs[ARGUS_VLAN_INDEX] = (struct ArgusDSRHeader *) vlan;
2397 vlan->hdr.type = ARGUS_VLAN_DSR;
2398 vlan->hdr.subtype = 0;
2399 vlan->hdr.argus_dsrvl8.qual = 0;
2400 vlan->hdr.argus_dsrvl8.len = 2;
2401 flow->dsrindex |= 1 << ARGUS_VLAN_INDEX;
2402 }
2403
2404 if (model->ArgusThisDir) {
2405 vlan->sid = model->ArgusThisPacket8021QEncaps;
2406 vlan->hdr.argus_dsrvl8.qual |= ARGUS_SRC_VLAN;
2407
2408 } else {
2409 vlan->did = model->ArgusThisPacket8021QEncaps;
2410 vlan->hdr.argus_dsrvl8.qual |= ARGUS_DST_VLAN;
2411 }
2412 }
2413
2414 if (model->ArgusGenerateTime) {
2415 if ((jitter = (struct ArgusJitterStruct *) flow->dsrs[ARGUS_JITTER_INDEX]) == NULL) {
2416 jitter = (struct ArgusJitterStruct *) &flow->canon.jitter;
2417 memset(jitter, 0, sizeof(*jitter));
2418 flow->dsrs[ARGUS_JITTER_INDEX] = (struct ArgusDSRHeader *) jitter;
2419 jitter->hdr.type = ARGUS_JITTER_DSR;
2420 jitter->hdr.subtype = 0;
2421 jitter->hdr.argus_dsrvl8.len = 1;
2422
2423 flow->dsrindex |= 1 << ARGUS_JITTER_INDEX;
2424
2425 bzero((char *)&jitter->act, sizeof(struct ArgusJitterObject));
2426 bzero((char *)&jitter->idle, sizeof(struct ArgusJitterObject));
2427
2428 memset(&flow->stime.act, 0, sizeof(flow->stime.act));
2429 memset(&flow->stime.idle, 0, sizeof(flow->stime.idle));
2430 memset(&flow->dtime.act, 0, sizeof(flow->dtime.act));
2431 memset(&flow->dtime.idle, 0, sizeof(flow->dtime.idle));
2432 flow->stime.act.minval = 0xffffffff;
2433 flow->stime.idle.minval = 0xffffffff;
2434 flow->dtime.act.minval = 0xffffffff;
2435 flow->dtime.idle.minval = 0xffffffff;
2436 }
2437 }
2438 }
2439
2440
2441 struct ArgusFlowStruct *
ArgusUpdateFlow(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flow,unsigned char state,unsigned char update)2442 ArgusUpdateFlow (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flow, unsigned char state, unsigned char update)
2443 {
2444 struct ArgusFlowStruct *retn = flow;
2445
2446 ArgusUpdateBasicFlow (model, flow, state);
2447
2448 if (model->ArgusThisIpHdr) {
2449 struct ArgusIPAttrStruct *attr = NULL;
2450
2451 if ((attr = (struct ArgusIPAttrStruct *) flow->dsrs[ARGUS_IPATTR_INDEX]) == NULL) {
2452 flow->dsrs[ARGUS_IPATTR_INDEX] = &flow->canon.attr.hdr;
2453 attr = &flow->canon.attr;
2454 memset(attr, 0, sizeof(*attr));
2455 attr->hdr.type = ARGUS_IPATTR_DSR;
2456 attr->hdr.subtype = 0;
2457 attr->hdr.argus_dsrvl8.qual = 0;
2458 attr->hdr.argus_dsrvl8.len = 1;
2459 flow->dsrindex |= 1 << ARGUS_IPATTR_INDEX;
2460 }
2461
2462 #if !defined(IPTOS_CE)
2463 #define IPTOS_CE 0x01 /* congestion experienced */
2464 #define IPTOS_ECT 0x02 /* ECN-capable transport */
2465 #endif
2466
2467 switch (model->ArgusThisNetworkFlowType & 0xFFFF) {
2468 case ETHERTYPE_IP: {
2469 struct ip *iphdr = (struct ip *) model->ArgusThisIpHdr;
2470 u_short ip_off = ntohs(iphdr->ip_off);
2471
2472 if (model->ArgusThisDir) {
2473 if (!(attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)) {
2474 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC;
2475 }
2476
2477 attr->src.ttl = iphdr->ip_ttl;
2478 attr->src.tos = iphdr->ip_tos;
2479 attr->src.ip_id = iphdr->ip_id;
2480
2481 if ((attr->src.options = model->ArgusOptionIndicator) != 0)
2482 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_OPTIONS;
2483 if ((attr->src.tos & (IPTOS_CE | IPTOS_ECT)) == (IPTOS_CE | IPTOS_ECT))
2484 attr->src.status |= ARGUS_ECN_CONGESTED;
2485 } else {
2486 if (!(attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)) {
2487 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST;
2488 }
2489
2490 attr->dst.ttl = iphdr->ip_ttl;
2491 attr->dst.tos = iphdr->ip_tos;
2492 attr->dst.ip_id = iphdr->ip_id;
2493
2494 if ((attr->dst.options = model->ArgusOptionIndicator) != 0)
2495 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_OPTIONS;
2496
2497 if ((attr->dst.tos & (IPTOS_CE | IPTOS_ECT)) == (IPTOS_CE | IPTOS_ECT))
2498 attr->dst.status |= ARGUS_ECN_CONGESTED;
2499 }
2500
2501 retn = ArgusUpdateState (model, flow, state, update);
2502
2503 if ((model->ArgusFlowKey & ARGUS_FLOW_KEY_CLASSIC5TUPLE) &&
2504 (((ip_off & 0x1fff) == 0) && (ip_off & IP_MF))) {
2505 /*
2506 This is also a fragment, so we need to setup the expected fragment
2507 cache, so we can find the fragments that will be coming in.
2508 So get the fragment flow descriptor, and either find the flow
2509 or install one. If the fragment descriptor exists, then we're
2510 now able to update the parent flow, if it hasn't been done.
2511
2512 Add this fragment to the parents fragment list, so we can find
2513 them if we have to deallocate the parent.
2514 */
2515 struct ArgusSystemFlow *fflow = NULL;
2516 struct ArgusFlowStruct *frag = NULL;
2517 int tstate = model->state;
2518
2519 if ((fflow = ArgusCreateFRAGFlow (model, iphdr, ETHERTYPE_IP)) == NULL)
2520 ArgusLog (LOG_ERR, "ArgusCreateFRAGFlow() returned NULL.\n");
2521
2522 ArgusCreateFlowKey(model, fflow, model->hstruct);
2523
2524 if ((frag = ArgusFindFlow (model, model->hstruct)) == NULL) {
2525 if ((frag = ArgusNewFlow (model, fflow, model->hstruct, &flow->frag)) == NULL)
2526 ArgusLog (LOG_ERR, "ArgusNewFragFlow() returned NULL.\n");
2527
2528 memset (&frag->canon.net, 0, sizeof(struct ArgusFragObject) + 4);
2529 frag->canon.net.hdr.type = ARGUS_NETWORK_DSR;
2530 frag->canon.net.hdr.subtype = ARGUS_NETWORK_SUBTYPE_FRAG;
2531 frag->canon.net.hdr.argus_dsrvl8.qual = 0;
2532 frag->canon.net.hdr.argus_dsrvl8.len = ((sizeof(struct ArgusFragObject) + 3)/4) + 1;
2533 frag->dsrs[ARGUS_FRAG_INDEX] = (struct ArgusDSRHeader *) &frag->canon.net.hdr;
2534
2535 frag->canon.net.net_union.frag.parent = flow;
2536 frag->canon.net.net_union.frag.frag_id = iphdr->ip_id;
2537
2538 ArgusUpdateBasicFlow (model, frag, state);
2539
2540 } else {
2541 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *)frag->dsrs[ARGUS_FRAG_INDEX];
2542 struct ArgusFragObject *ofrag = &net->net_union.frag;
2543
2544 net->hdr.argus_dsrvl8.qual |= ARGUS_FRAG_OUT_OF_ORDER;
2545 if (ofrag->parent == NULL) {
2546 ofrag->parent = flow;
2547 if (frag->qhdr.queue != &flow->frag) {
2548 ArgusRemoveFromQueue(frag->qhdr.queue, &frag->qhdr, ARGUS_LOCK);
2549 ArgusAddToQueue(&flow->frag, &frag->qhdr, ARGUS_LOCK);
2550 }
2551 }
2552 }
2553
2554 if (ArgusUpdateFRAGState (model, frag, state, ETHERTYPE_IP))
2555 ArgusDeleteObject (frag);
2556
2557 model->state = tstate;
2558
2559 if (model->ArgusThisDir)
2560 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_FRAGMENTS;
2561 else
2562 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_FRAGMENTS;
2563
2564 }
2565 break;
2566 }
2567
2568 case ETHERTYPE_IPV6: {
2569 struct ip6_hdr *iphdr = (struct ip6_hdr *) model->ArgusThisIpHdr;
2570 unsigned int flowid = iphdr->ip6_flow;
2571 unsigned short ftos = (flowid >> 16);
2572 unsigned char tos = ((ntohs(ftos) >> 4) & 0x00FF);
2573 unsigned char ttl = iphdr->ip6_hlim;
2574 struct ip6_frag *tfrag = NULL;
2575
2576 if (model->ArgusThisDir) {
2577 if (!(attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC)) {
2578 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC;
2579 }
2580 attr->src.ttl = ttl;
2581 attr->src.tos = tos;
2582 attr->src.ip_id = 0;
2583 if ((attr->src.options = model->ArgusOptionIndicator) != 0)
2584 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_OPTIONS;
2585 if ((attr->src.tos & (IPTOS_CE | IPTOS_ECT)) == (IPTOS_CE | IPTOS_ECT))
2586 attr->src.status |= ARGUS_ECN_CONGESTED;
2587 } else {
2588 if (!(attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST)) {
2589 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST;
2590 }
2591 attr->dst.ttl = ttl;
2592 attr->dst.tos = tos;
2593 attr->dst.ip_id = 0;
2594 if ((attr->dst.options = model->ArgusOptionIndicator) != 0)
2595 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_OPTIONS;
2596
2597 if ((attr->dst.tos & (IPTOS_CE | IPTOS_ECT)) == (IPTOS_CE | IPTOS_ECT))
2598 attr->dst.status |= ARGUS_ECN_CONGESTED;
2599 }
2600
2601 retn = ArgusUpdateState (model, flow, state, update);
2602
2603 if ((model->ArgusFlowKey & ARGUS_FLOW_KEY_CLASSIC5TUPLE) &&
2604 (((tfrag = model->ArgusThisIpv6Frag) != NULL) && (((ntohs(tfrag->ip6f_offlg) & IP6F_OFF_MASK) == 0) &&
2605 (tfrag->ip6f_offlg & IP6F_MORE_FRAG)))) {
2606 /*
2607 This is also a fragment, so we need to setup the expected fragment
2608 cache, so we can find the fragments that will be coming in.
2609 So get the fragment flow descriptor, and either find the flow
2610 or install one. If the fragment descriptor exists, then we're
2611 now able to update the parent flow, if it hasn't been done.
2612
2613 Add this fragment to the parents fragment list, so we can find
2614 them if we have to deallocate the parent.
2615 */
2616
2617 struct ArgusSystemFlow *fflow = NULL;
2618 struct ArgusFlowStruct *frag = NULL;
2619 int tstate = model->state;
2620
2621 if ((fflow = ArgusCreateFRAGFlow (model, iphdr, ETHERTYPE_IPV6)) != NULL) {
2622 ArgusCreateFlowKey(model, fflow, model->hstruct);
2623
2624 if ((frag = ArgusFindFlow (model, model->hstruct)) == NULL) {
2625
2626 /* ok so here things are correct, we're going to schedule the expected frag struct
2627 onto the parent flow, and proceed */
2628
2629 if ((frag = ArgusNewFlow (model, fflow, model->hstruct, &flow->frag)) == NULL)
2630 ArgusLog (LOG_ERR, "ArgusNewFragFlow() returned NULL.\n");
2631
2632 memset (&frag->canon.net, 0, sizeof(struct ArgusFragObject) + 4);
2633 frag->canon.net.hdr.type = ARGUS_NETWORK_DSR;
2634 frag->canon.net.hdr.subtype = ARGUS_NETWORK_SUBTYPE_FRAG;
2635 frag->canon.net.hdr.argus_dsrvl8.qual = 0;
2636 frag->canon.net.hdr.argus_dsrvl8.len = (sizeof(struct ArgusFragObject) + 3)/4 + 1;
2637 frag->dsrs[ARGUS_FRAG_INDEX] = (struct ArgusDSRHeader *) &frag->canon.net.hdr;
2638
2639 frag->canon.net.net_union.frag.parent = flow;
2640
2641 ArgusUpdateBasicFlow (model, frag, state);
2642
2643 } else {
2644
2645 /* oops, here we've seen parts of the fragment and are just now seeing the 0 offset
2646 fragment, so need to move the frag from the general run queue and put it on this
2647 parent frag queue */
2648
2649 if (frag->dsrs[ARGUS_FRAG_INDEX] != NULL)
2650 frag->dsrs[ARGUS_FRAG_INDEX]->argus_dsrvl8.qual |= ARGUS_FRAG_OUT_OF_ORDER;
2651
2652 if (frag->qhdr.queue != &flow->frag) {
2653 ArgusRemoveFromQueue(frag->qhdr.queue, &frag->qhdr, ARGUS_LOCK);
2654 ArgusAddToQueue(&flow->frag, &frag->qhdr, ARGUS_LOCK);
2655 }
2656 }
2657
2658 if (ArgusUpdateFRAGState (model, frag, state, ETHERTYPE_IPV6))
2659 ArgusDeleteObject (frag);
2660 model->state = tstate;
2661
2662 if (model->ArgusThisDir)
2663 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_SRC_FRAGMENTS;
2664 else
2665 attr->hdr.argus_dsrvl8.qual |= ARGUS_IPATTR_DST_FRAGMENTS;
2666 }
2667
2668 }
2669 }
2670 }
2671
2672 } else
2673 retn = ArgusUpdateState (model, flow, state, update);
2674
2675 if ((state == ARGUS_START) && ArgusGenerateStartRecords)
2676 ArgusSendFlowRecord(model, flow, ARGUS_START);
2677
2678 #ifdef ARGUSDEBUG
2679 ArgusDebug (8, "ArgusUpdateFlow (%p, %d) returning %p\n", flow, state, retn);
2680 #endif
2681 return (retn);
2682 }
2683
2684 void
ArgusTallyStats(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flow)2685 ArgusTallyStats (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flow)
2686 {
2687 struct ArgusMetricStruct *metric = (void *)flow->dsrs[ARGUS_METRIC_INDEX];
2688 int bytes = model->ArgusThisBytes;
2689
2690 if (metric != NULL) {
2691 if (model->ArgusThisDir)
2692 model->ArgusThisStats = &metric->src;
2693 else
2694 model->ArgusThisStats = &metric->dst;
2695
2696 model->ArgusThisStats->pkts++;
2697 model->ArgusThisStats->bytes += bytes;
2698 }
2699
2700 if (model->ArgusGeneratePacketSize) {
2701 struct ArgusPacketSizeStruct *psize = (void *)flow->dsrs[ARGUS_PSIZE_INDEX];
2702 struct ArgusPacketSizeObject *tpsize;
2703
2704 if (psize == NULL) {
2705 psize = &flow->canon.psize;
2706 memset (psize, 0, sizeof(*psize));
2707 psize->hdr.type = ARGUS_PSIZE_DSR;
2708 psize->src.psizemin = 0xFFFF;
2709 psize->dst.psizemin = 0xFFFF;
2710 flow->dsrs[ARGUS_PSIZE_INDEX] = &flow->canon.psize.hdr;
2711 flow->dsrindex |= 1 << ARGUS_PSIZE_INDEX;
2712 }
2713
2714 if (model->ArgusThisDir)
2715 tpsize = &psize->src;
2716 else
2717 tpsize = &psize->dst;
2718
2719 if (bytes > tpsize->psizemax)
2720 tpsize->psizemax = bytes;
2721 if (bytes < tpsize->psizemin)
2722 tpsize->psizemin = bytes;
2723 }
2724
2725 if (model->ArgusGenerateTime) {
2726 struct ArgusTimeStat *ArgusThisTime;
2727 struct ArgusTimeStats *ArgusThisTimeStat;
2728 unsigned long long ArgusThisInterval, tout;
2729 struct timeval timeout;
2730
2731 if (model->ArgusThisDir) {
2732 ArgusThisTime = &flow->stime;
2733 } else {
2734 ArgusThisTime = &flow->dtime;
2735 }
2736
2737 if (model->ArgusInProtocol)
2738 ArgusThisTimeStat = &ArgusThisTime->act;
2739 else
2740 ArgusThisTimeStat = &ArgusThisTime->idle;
2741
2742 if ((ArgusThisTime->lasttime.tv_sec < model->ArgusGlobalTime.tv_sec) ||
2743 ((ArgusThisTime->lasttime.tv_sec == model->ArgusGlobalTime.tv_sec) &&
2744 (ArgusThisTime->lasttime.tv_usec < model->ArgusGlobalTime.tv_usec))) {
2745
2746 if (ArgusThisTime->lasttime.tv_sec > 0) {
2747 if ((ArgusThisInterval = ArgusAbsTimeDiff (&model->ArgusGlobalTime, &ArgusThisTime->lasttime)) > 0) {
2748 timeout = *getArgusFarReportInterval (model);
2749 tout = (timeout.tv_sec * 1000000LL) + timeout.tv_usec;
2750
2751 if (tout > 0) {
2752 if (ArgusThisInterval < (tout * 2)) {
2753 if (ArgusThisTimeStat->minval > ArgusThisInterval)
2754 ArgusThisTimeStat->minval = ArgusThisInterval;
2755
2756 if (ArgusThisTimeStat->maxval < ArgusThisInterval)
2757 ArgusThisTimeStat->maxval = ArgusThisInterval;
2758
2759 ArgusThisTimeStat->sum += ArgusThisInterval;
2760 ArgusThisTimeStat->sumsqrd += (double)ArgusThisInterval * (double)ArgusThisInterval;
2761 ArgusThisTimeStat->n++;
2762 }
2763 }
2764 }
2765 }
2766
2767 ArgusThisTime->lasttime.tv_sec = model->ArgusGlobalTime.tv_sec;
2768 ArgusThisTime->lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
2769 }
2770 }
2771
2772 #ifdef ARGUSDEBUG
2773 ArgusDebug (8, "ArgusTallyStats (0x%x, 0x%x) returning\n", model, flow);
2774 #endif
2775 }
2776
2777
2778 void ArgusUpdateMACState (struct ArgusModelerStruct *, struct ArgusFlowStruct *, unsigned char *);
2779
2780 void
ArgusUpdateMACState(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flowstr,unsigned char * state)2781 ArgusUpdateMACState (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flowstr, unsigned char *state)
2782 {
2783
2784 }
2785
2786
2787 int ArgusUpdateICMPState (struct ArgusModelerStruct *, struct ArgusFlowStruct *, unsigned char *);
2788 int ArgusUpdateICMPv6State (struct ArgusModelerStruct *, struct ArgusFlowStruct *, unsigned char *);
2789
2790 struct ArgusFlowStruct *
ArgusUpdateState(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flowstr,unsigned char state,unsigned char update)2791 ArgusUpdateState (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flowstr, unsigned char state, unsigned char update)
2792 {
2793 struct ArgusFlowStruct *retn = flowstr;
2794 struct ArgusSystemFlow *flow;
2795 unsigned short proto;
2796 unsigned char ip_p;
2797
2798 if ((flowstr->status & 0xF0) == 0) {
2799 flowstr->status |= state & 0xF0;
2800 } else {
2801 switch (state & 0xF0) {
2802 case ARGUS_START:
2803 case ARGUS_STOP:
2804 case ARGUS_TIMEOUT:
2805 case ARGUS_SHUTDOWN:
2806 case ARGUS_CLOSED:
2807 case ARGUS_ERROR:
2808 flowstr->status &= ~0xF0;
2809 flowstr->status |= state & 0xF0;
2810 break;
2811 }
2812 }
2813
2814 ArgusUpdateMACState(model, flowstr, &state);
2815
2816 flow = (struct ArgusSystemFlow *) flowstr->dsrs[ARGUS_FLOW_INDEX];
2817
2818 switch (proto = (model->ArgusThisNetworkFlowType & 0xFFFF)) {
2819 case ETHERTYPE_IPV6:
2820 case ETHERTYPE_IP: {
2821 if (proto == ETHERTYPE_IPV6)
2822 ip_p = flow->ipv6_flow.ip_p;
2823 else
2824 ip_p = flow->ip_flow.ip_p;
2825
2826 if (model->ArgusThisFlow->hdr.argus_dsrvl8.qual & ARGUS_FRAGMENT) {
2827 ArgusTallyStats (model, flowstr);
2828 if (ArgusUpdateFRAGState (model, flowstr, state, proto)) {
2829 ArgusDeleteObject(flowstr);
2830 return(NULL);
2831 }
2832
2833 } else {
2834 switch (ip_p) {
2835 case IPPROTO_TCP: {
2836 if (model->ArgusKeyStroke.status)
2837 ArgusTCPKeystroke(model, flowstr, &state);
2838
2839 ArgusUpdateTCPState (model, flowstr, &state);
2840
2841 if (flowstr->timeout != model->ArgusTCPTimeout)
2842 flowstr->timeout = model->ArgusTCPTimeout;
2843 break;
2844 }
2845
2846 case IPPROTO_ICMP:
2847 ArgusUpdateICMPState (model, flowstr, &state);
2848 if (flowstr->timeout != model->ArgusICMPTimeout)
2849 flowstr->timeout = model->ArgusICMPTimeout;
2850 break;
2851
2852 case IPPROTO_ICMPV6:
2853 ArgusUpdateICMPv6State (model, flowstr, &state);
2854 if (flowstr->timeout != model->ArgusICMPTimeout)
2855 flowstr->timeout = model->ArgusICMPTimeout;
2856 break;
2857
2858 case IPPROTO_IGMP:
2859 if (flowstr->timeout == model->ArgusIGMPTimeout)
2860 flowstr->timeout = model->ArgusIGMPTimeout;
2861 break;
2862
2863 case IPPROTO_UDP:
2864 ArgusUpdateUDPState (model, flowstr, &state);
2865 if (flowstr->timeout == model->ArgusIPTimeout)
2866 flowstr->timeout = model->ArgusIPTimeout;
2867 break;
2868
2869 case IPPROTO_ESP:
2870 ArgusUpdateESPState (model, flowstr, &state);
2871 if (flowstr->timeout == model->ArgusIPTimeout)
2872 flowstr->timeout = model->ArgusIPTimeout;
2873 break;
2874
2875 default:
2876 if (flowstr->timeout == model->ArgusIPTimeout)
2877 flowstr->timeout = model->ArgusIPTimeout;
2878 break;
2879 }
2880 }
2881 break;
2882 }
2883
2884 case ETHERTYPE_ARP:
2885 case ETHERTYPE_REVARP:
2886 ArgusUpdateArpState (model, flowstr, &state);
2887 break;
2888
2889 default:
2890 break;
2891 }
2892
2893 if (update) {
2894 if (!(model->ArgusThisFlow->hdr.argus_dsrvl8.qual & ARGUS_FRAGMENT))
2895 ArgusTallyStats (model, flowstr);
2896
2897 ArgusUpdateAppState (model, flowstr, state);
2898 }
2899
2900 #ifdef ARGUSDEBUG
2901 ArgusDebug (8, "ArgusUpdateState (%p, %d) returning %d\n", flowstr, state, retn);
2902 #endif
2903
2904 return (retn);
2905 }
2906
2907
2908 /*
2909 ArgusGenerateRecord
2910 Build the contiguous argus output record for output.
2911 Struct ArgusRecord is really just an array of 32-bit values, so lets build
2912 it that way to deal with 32 and 64-bit machines.
2913 */
2914
2915 struct ArgusRecord *
ArgusGenerateRecord(struct ArgusModelerStruct * model,struct ArgusRecordStruct * rec,unsigned char state,struct ArgusRecord * retn)2916 ArgusGenerateRecord (struct ArgusModelerStruct *model, struct ArgusRecordStruct *rec,
2917 unsigned char state, struct ArgusRecord *retn)
2918 {
2919
2920 if (rec) {
2921 switch (rec->hdr.type & 0xF0) {
2922 case ARGUS_FAR:
2923 case ARGUS_EVENT:
2924 case ARGUS_NETFLOW: {
2925 unsigned int ind, dsrindex, *dsrptr;
2926 int i, x, len = 0, dsrlen = 1;
2927 struct ArgusDSRHeader *dsr;
2928
2929 bcopy ((char *)&rec->hdr, (char *)&retn->hdr, sizeof(retn->hdr));
2930 dsrptr = (unsigned int *)&retn->ar_un.mar;
2931
2932 dsrindex = rec->dsrindex;
2933
2934 if (!(dsrindex & (0x01 << ARGUS_TIME_INDEX)))
2935 ArgusLog (LOG_ERR, "ArgusGenerateRecord: time dsr not set");
2936
2937 for (i = 0, ind = 1; (dsrindex && (i < ARGUSMAXDSRTYPE)); i++, ind <<= 1) {
2938 if ((dsr = rec->dsrs[i]) != NULL) {
2939 len = ((dsr->type & 0x80) ? 1 :
2940 ((dsr->type == ARGUS_DATA_DSR) ? dsr->argus_dsrvl16.len :
2941 dsr->argus_dsrvl8.len ));
2942 switch (i) {
2943 default:
2944 for (x = 0; x < len; x++)
2945 *dsrptr++ = ((unsigned int *)rec->dsrs[i])[x];
2946 break;
2947
2948 case ARGUS_FLOW_INDEX: {
2949 switch (dsr->subtype) {
2950 case ARGUS_FLOW_ARP:
2951 switch (dsr->argus_dsrvl8.qual & 0x1F) {
2952 case ARGUS_TYPE_RARP: {
2953 struct ArgusRarpFlow *rarp = &((struct ArgusFlow *)dsr)->flow_un.rarp;
2954 dsr->argus_dsrvl8.len = 4 + ((rarp->hln * 2) + 3)/4;
2955 len = dsr->argus_dsrvl8.len;
2956
2957 dsrptr[0] = ((unsigned int *)dsr)[0];
2958 dsrptr[1] = ((unsigned int *)dsr)[1];
2959 dsrptr[2] = ((unsigned int *)dsr)[2];
2960 dsrptr[3] = ((unsigned int *)dsr)[3];
2961
2962 bcopy (&rarp->shaddr, &((char *)&dsrptr[4])[0], rarp->hln);
2963 bcopy (&rarp->dhaddr, &((char *)&dsrptr[4])[rarp->hln], rarp->hln);
2964 dsrptr += dsr->argus_dsrvl8.len;
2965 break;
2966 }
2967
2968 case ARGUS_TYPE_ARP: {
2969 struct ArgusArpFlow *arp = &((struct ArgusFlow *)dsr)->flow_un.arp;
2970 dsr->argus_dsrvl8.len = 4 + (arp->hln + 3)/4;
2971 len = dsr->argus_dsrvl8.len;
2972
2973 dsrptr[0] = ((unsigned int *)dsr)[0];
2974 dsrptr[1] = ((unsigned int *)dsr)[1];
2975 dsrptr[2] = ((unsigned int *)dsr)[2];
2976 dsrptr[3] = ((unsigned int *)dsr)[3];
2977 dsrptr[4] = ((unsigned int *)dsr)[4];
2978 bcopy (&arp->haddr, &((char *)&dsrptr[5])[0], arp->hln);
2979 dsrptr += dsr->argus_dsrvl8.len;
2980 break;
2981 }
2982 }
2983 break;
2984
2985 default:
2986 for (x = 0; x < len; x++)
2987 *dsrptr++ = ((unsigned int *)rec->dsrs[i])[x];
2988 break;
2989 }
2990 break;
2991 }
2992
2993 case ARGUS_NETWORK_INDEX: {
2994 switch (dsr->subtype) {
2995 case ARGUS_TCP_INIT: {
2996 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *)rec->dsrs[i];
2997 struct ArgusTCPObject *tobj = &net->net_union.tcp;
2998 struct ArgusTCPInitStatus *tcp = (void *)(dsrptr + 1);
2999 *dsrptr = *(unsigned int *)&net->hdr;
3000 tcp->status = tobj->status;
3001 tcp->seqbase = tobj->src.seqbase;
3002 tcp->options = tobj->options;
3003 tcp->flags = tobj->src.flags;
3004 tcp->winshift = tobj->src.winshift;
3005 dsrptr += len;
3006 break;
3007 }
3008
3009 case ARGUS_TCP_STATUS: {
3010 struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *)rec->dsrs[i];
3011 struct ArgusTCPObject *tobj = &net->net_union.tcp;
3012 struct ArgusTCPStatus *tcp = (struct ArgusTCPStatus *)(dsrptr + 1);
3013 *dsrptr = *(unsigned int *)&net->hdr;
3014 tcp->status = tobj->status;
3015 tcp->src = tobj->src.flags;
3016 tcp->dst = tobj->dst.flags;
3017 bzero(&tcp->pad, sizeof(tcp->pad));
3018 dsrptr += len;
3019 break;
3020 }
3021
3022 default:
3023 for (x = 0; x < len; x++)
3024 *dsrptr++ = ((unsigned int *)rec->dsrs[i])[x];
3025 break;
3026 }
3027 break;
3028 }
3029
3030 case ARGUS_TIME_INDEX: {
3031 struct ArgusTimeObject *dtime = (struct ArgusTimeObject *) dsr;
3032 struct ArgusTime *mint, *maxt;
3033 unsigned char subtype = 0;
3034 unsigned char tlen = 1;
3035
3036 if (model->ArgusReportAllTime) {
3037 if (dtime->src.start.tv_sec) {
3038 subtype |= ARGUS_TIME_SRC_START;
3039 tlen += 2;
3040 }
3041 if (dtime->src.end.tv_sec) {
3042 subtype |= ARGUS_TIME_SRC_END;
3043 tlen += 2;
3044 }
3045 if (dtime->dst.start.tv_sec) {
3046 subtype |= ARGUS_TIME_DST_START;
3047 tlen += 2;
3048 }
3049 if (dtime->dst.end.tv_sec) {
3050 subtype |= ARGUS_TIME_DST_END;
3051 tlen += 2;
3052 }
3053
3054 dtime->hdr.argus_dsrvl8.len = tlen;
3055 dtime->hdr.subtype &= ~(0x78);
3056 dtime->hdr.subtype |= subtype;
3057
3058 *dsrptr++ = ((unsigned int *)rec->dsrs[i])[0];
3059
3060 for (x = 0; x < 4; x++) {
3061 if (subtype & (ARGUS_TIME_SRC_START << x)) {
3062 switch (ARGUS_TIME_SRC_START << x) {
3063 case ARGUS_TIME_SRC_START:
3064 *dsrptr++ = dtime->src.start.tv_sec;
3065 *dsrptr++ = dtime->src.start.tv_usec;
3066 break;
3067 case ARGUS_TIME_SRC_END:
3068 *dsrptr++ = dtime->src.end.tv_sec;
3069 *dsrptr++ = dtime->src.end.tv_usec;
3070 break;
3071 case ARGUS_TIME_DST_START:
3072 *dsrptr++ = dtime->dst.start.tv_sec;
3073 *dsrptr++ = dtime->dst.start.tv_usec;
3074 break;
3075 case ARGUS_TIME_DST_END:
3076 *dsrptr++ = dtime->dst.end.tv_sec;
3077 *dsrptr++ = dtime->dst.end.tv_usec;
3078 break;
3079 }
3080 }
3081 }
3082 len = tlen;
3083
3084 } else {
3085 struct ArgusTime tmax = {0, 0}, tmin = {0xEFFFFFFF,0};
3086 struct ArgusTime *atime;
3087
3088 for (x = 0; x < 4; x++) {
3089 switch (ARGUS_TIME_SRC_START << x) {
3090 case ARGUS_TIME_SRC_START: atime = &dtime->src.start; break;
3091 case ARGUS_TIME_SRC_END: atime = &dtime->src.end; break;
3092 case ARGUS_TIME_DST_START: atime = &dtime->dst.start; break;
3093 case ARGUS_TIME_DST_END: atime = &dtime->dst.end; break;
3094 }
3095
3096 if (atime->tv_sec) {
3097 if ((tmax.tv_sec < atime->tv_sec) ||
3098 ((tmax.tv_sec == atime->tv_sec) &&
3099 (tmax.tv_usec < atime->tv_usec))) {
3100 tmax = *atime;
3101 }
3102
3103 if ((tmin.tv_sec > atime->tv_sec) ||
3104 ((tmin.tv_sec == atime->tv_sec) &&
3105 (tmin.tv_sec > atime->tv_sec))) {
3106 tmin = *atime;
3107 }
3108 }
3109 }
3110
3111 maxt = &tmax;
3112 mint = &tmin;
3113
3114 if ((maxt->tv_sec != mint->tv_sec) ||
3115 ((maxt->tv_sec == mint->tv_sec) &&
3116 (maxt->tv_usec != mint->tv_usec))) {
3117 dsr->argus_dsrvl8.len = 5;
3118 len = 5;
3119 } else {
3120 dsr->argus_dsrvl8.len = 3;
3121 len = 3;
3122 }
3123
3124 *dsrptr++ = ((unsigned int *)rec->dsrs[i])[0];
3125 *dsrptr++ = mint->tv_sec;
3126 *dsrptr++ = mint->tv_usec;
3127 if (len == 5) {
3128 *dsrptr++ = maxt->tv_sec;
3129 *dsrptr++ = maxt->tv_usec;
3130 }
3131 }
3132 break;
3133 }
3134
3135 case ARGUS_METRIC_INDEX: {
3136 struct ArgusMetricStruct *metric = (struct ArgusMetricStruct *) dsr;
3137 unsigned char type = 0;
3138
3139 if ((metric->src.pkts + metric->dst.pkts) > 0) {
3140 if (metric->src.pkts && metric->dst.pkts) {
3141 if ((0xFF >= metric->src.pkts) && (0xFF >= metric->dst.pkts) &&
3142 (0xFF >= metric->src.bytes) && (0xFF >= metric->dst.bytes))
3143 type = ARGUS_SRCDST_BYTE;
3144 else
3145 if ((0xFFFF >= metric->src.bytes) && (0xFFFF >= metric->dst.bytes))
3146 type = ARGUS_SRCDST_SHORT;
3147 else
3148 if ((0xFFFFFFFF >= metric->src.bytes) && (0xFFFFFFFF >= metric->dst.bytes))
3149 type = ARGUS_SRCDST_INT;
3150 else
3151 type = ARGUS_SRCDST_LONGLONG;
3152
3153 } else {
3154 if (metric->src.pkts) {
3155 if (0xFFFF >= metric->src.bytes)
3156 type = ARGUS_SRC_SHORT;
3157 else
3158 if (0xFFFFFFFF >= metric->src.bytes)
3159 type = ARGUS_SRC_INT;
3160 else
3161 type = ARGUS_SRC_LONGLONG;
3162 } else {
3163 if (0xFFFF >= metric->dst.bytes)
3164 type = ARGUS_DST_SHORT;
3165 else
3166 if (0xFFFFFFFF >= metric->dst.bytes)
3167 type = ARGUS_DST_INT;
3168 else
3169 type = ARGUS_DST_LONGLONG;
3170 }
3171 }
3172 }
3173
3174 dsr = (struct ArgusDSRHeader *)dsrptr;
3175 dsr->type = ARGUS_METER_DSR;
3176
3177 if (getArgusAflag(model) && (metric->src.appbytes || metric->dst.appbytes)) {
3178 dsr->subtype = ARGUS_METER_PKTS_BYTES_APP;
3179 switch (type) {
3180 case ARGUS_SRCDST_BYTE:
3181 dsr->argus_dsrvl8.qual = type;
3182 dsr->argus_dsrvl8.len = 3;
3183 ((unsigned char *)(dsr + 1))[0] = (unsigned char) metric->src.pkts;
3184 ((unsigned char *)(dsr + 1))[1] = (unsigned char) metric->src.bytes;
3185 ((unsigned char *)(dsr + 1))[2] = (unsigned char) metric->src.appbytes;
3186 ((unsigned char *)(dsr + 1))[3] = (unsigned char) metric->dst.pkts;
3187 ((unsigned char *)(dsr + 1))[4] = (unsigned char) metric->dst.bytes;
3188 ((unsigned char *)(dsr + 1))[5] = (unsigned char) metric->dst.appbytes;
3189 break;
3190 case ARGUS_SRCDST_SHORT:
3191 dsr->argus_dsrvl8.qual = type;
3192 dsr->argus_dsrvl8.len = 4;
3193 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
3194 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
3195 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->src.appbytes);
3196 ((unsigned short *)(dsr + 1))[3] = ((unsigned short) metric->dst.pkts);
3197 ((unsigned short *)(dsr + 1))[4] = ((unsigned short) metric->dst.bytes);
3198 ((unsigned short *)(dsr + 1))[5] = ((unsigned short) metric->dst.appbytes);
3199 break;
3200 case ARGUS_SRCDST_INT:
3201 dsr->argus_dsrvl8.qual = type;
3202 dsr->argus_dsrvl8.len = 7;
3203 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
3204 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
3205 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->src.appbytes);
3206 ((unsigned int *)(dsr + 1))[3] = ((unsigned int) metric->dst.pkts);
3207 ((unsigned int *)(dsr + 1))[4] = ((unsigned int) metric->dst.bytes);
3208 ((unsigned int *)(dsr + 1))[5] = ((unsigned int) metric->dst.appbytes);
3209 break;
3210
3211 case ARGUS_SRC_BYTE: {
3212 dsr->argus_dsrvl8.qual = type;
3213 dsr->argus_dsrvl8.len = 2;
3214 ((unsigned char *)(dsr + 1))[0] = ((unsigned char) metric->src.pkts);
3215 ((unsigned char *)(dsr + 1))[1] = ((unsigned char) metric->src.bytes);
3216 ((unsigned char *)(dsr + 1))[2] = ((unsigned char) metric->src.appbytes);
3217 break;
3218 }
3219 case ARGUS_SRC_SHORT: {
3220 dsr->argus_dsrvl8.qual = type;
3221 dsr->argus_dsrvl8.len = 3;
3222 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
3223 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
3224 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->src.appbytes);
3225 break;
3226 }
3227 case ARGUS_SRC_INT:
3228 dsr->argus_dsrvl8.qual = type;
3229 dsr->argus_dsrvl8.len = 4;
3230 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
3231 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
3232 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->src.appbytes);
3233 break;
3234 case ARGUS_DST_BYTE:
3235 dsr->argus_dsrvl8.qual = type;
3236 dsr->argus_dsrvl8.len = 2;
3237 ((unsigned char *)(dsr + 1))[0] = ((unsigned char) metric->dst.pkts);
3238 ((unsigned char *)(dsr + 1))[1] = ((unsigned char) metric->dst.bytes);
3239 ((unsigned char *)(dsr + 1))[2] = ((unsigned char) metric->dst.appbytes);
3240 break;
3241 case ARGUS_DST_SHORT:
3242 dsr->argus_dsrvl8.qual = type;
3243 dsr->argus_dsrvl8.len = 3;
3244 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->dst.pkts);
3245 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->dst.bytes);
3246 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->dst.appbytes);
3247 break;
3248 case ARGUS_DST_INT:
3249 dsr->argus_dsrvl8.qual = type;
3250 dsr->argus_dsrvl8.len = 4;
3251 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->dst.pkts);
3252 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->dst.bytes);
3253 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->dst.appbytes);
3254 break;
3255 }
3256 } else {
3257 dsr->subtype = ARGUS_METER_PKTS_BYTES;
3258 switch (type) {
3259 case ARGUS_SRCDST_BYTE:
3260 dsr->argus_dsrvl8.qual = type;
3261 dsr->argus_dsrvl8.len = 2;
3262 ((unsigned char *)(dsr + 1))[0] = (unsigned char) metric->src.pkts;
3263 ((unsigned char *)(dsr + 1))[1] = (unsigned char) metric->src.bytes;
3264 ((unsigned char *)(dsr + 1))[2] = (unsigned char) metric->dst.pkts;
3265 ((unsigned char *)(dsr + 1))[3] = (unsigned char) metric->dst.bytes;
3266 break;
3267 case ARGUS_SRCDST_SHORT:
3268 dsr->argus_dsrvl8.qual = type;
3269 dsr->argus_dsrvl8.len = 3;
3270 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->src.pkts);
3271 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->src.bytes);
3272 ((unsigned short *)(dsr + 1))[2] = ((unsigned short) metric->dst.pkts);
3273 ((unsigned short *)(dsr + 1))[3] = ((unsigned short) metric->dst.bytes);
3274 break;
3275 case ARGUS_SRCDST_INT:
3276 dsr->argus_dsrvl8.qual = type;
3277 dsr->argus_dsrvl8.len = 5;
3278 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
3279 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
3280 ((unsigned int *)(dsr + 1))[2] = ((unsigned int) metric->dst.pkts);
3281 ((unsigned int *)(dsr + 1))[3] = ((unsigned int) metric->dst.bytes);
3282 break;
3283 case ARGUS_SRCDST_LONGLONG:
3284 dsr->argus_dsrvl8.qual = type;
3285 dsr->argus_dsrvl8.len = 9;
3286 break;
3287
3288 case ARGUS_SRC_SHORT: {
3289 unsigned short value;
3290 dsr->argus_dsrvl8.qual = type;
3291 dsr->argus_dsrvl8.len = 2;
3292 value = metric->src.pkts;
3293 ((unsigned short *)(dsr + 1))[0] = value;
3294 value = metric->src.bytes;
3295 ((unsigned short *)(dsr + 1))[1] = value;
3296 break;
3297 }
3298 case ARGUS_SRC_INT:
3299 dsr->argus_dsrvl8.qual = type;
3300 dsr->argus_dsrvl8.len = 3;
3301 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->src.pkts);
3302 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->src.bytes);
3303 break;
3304 case ARGUS_SRC_LONGLONG:
3305 dsr->argus_dsrvl8.qual = type;
3306 dsr->argus_dsrvl8.len = 5;
3307 break;
3308
3309 case ARGUS_DST_SHORT:
3310 dsr->argus_dsrvl8.qual = type;
3311 dsr->argus_dsrvl8.len = 2;
3312 ((unsigned short *)(dsr + 1))[0] = ((unsigned short) metric->dst.pkts);
3313 ((unsigned short *)(dsr + 1))[1] = ((unsigned short) metric->dst.bytes);
3314 break;
3315 case ARGUS_DST_INT:
3316 dsr->argus_dsrvl8.qual = type;
3317 dsr->argus_dsrvl8.len = 3;
3318 ((unsigned int *)(dsr + 1))[0] = ((unsigned int) metric->dst.pkts);
3319 ((unsigned int *)(dsr + 1))[1] = ((unsigned int) metric->dst.bytes);
3320 break;
3321 case ARGUS_DST_LONGLONG:
3322 dsr->argus_dsrvl8.qual = type;
3323 dsr->argus_dsrvl8.len = 5;
3324 ((unsigned int *)(dsr + 1))[0] = (((unsigned int *)&metric->dst.pkts)[0]);
3325 ((unsigned int *)(dsr + 1))[1] = (((unsigned int *)&metric->dst.pkts)[1]);
3326 ((unsigned int *)(dsr + 1))[2] = (((unsigned int *)&metric->dst.bytes)[0]);
3327 ((unsigned int *)(dsr + 1))[3] = (((unsigned int *)&metric->dst.bytes)[1]);
3328 break;
3329 }
3330 }
3331 len = dsr->argus_dsrvl8.len;
3332 dsrptr += len;
3333 break;
3334 }
3335
3336 case ARGUS_PSIZE_INDEX: {
3337 struct ArgusPacketSizeStruct *psize = (struct ArgusPacketSizeStruct *) dsr;
3338 unsigned char type = 0;
3339
3340 if ((psize->src.psizemax > 0) && (psize->dst.psizemax > 0))
3341 type = ARGUS_SRCDST_SHORT;
3342 else
3343 if (psize->src.psizemax > 0)
3344 type = ARGUS_SRC_SHORT;
3345 else
3346 if (psize->dst.psizemax > 0)
3347 type = ARGUS_DST_SHORT;
3348
3349 if (type != 0) {
3350 dsr = (struct ArgusDSRHeader *)dsrptr;
3351 dsr->type = ARGUS_PSIZE_DSR;
3352 dsr->subtype = 0;
3353
3354 switch (type) {
3355 case ARGUS_SRCDST_SHORT:
3356 dsr->argus_dsrvl8.qual = type;
3357 dsr->argus_dsrvl8.len = 3;
3358 ((unsigned short *)(dsr + 1))[0] = psize->src.psizemin;
3359 ((unsigned short *)(dsr + 1))[1] = psize->src.psizemax;
3360 ((unsigned short *)(dsr + 1))[2] = psize->dst.psizemin;
3361 ((unsigned short *)(dsr + 1))[3] = psize->dst.psizemax;
3362 break;
3363
3364 case ARGUS_SRC_SHORT:
3365 dsr->argus_dsrvl8.qual = type;
3366 dsr->argus_dsrvl8.len = 2;
3367 ((unsigned short *)(dsr + 1))[0] = psize->src.psizemin;
3368 ((unsigned short *)(dsr + 1))[1] = psize->src.psizemax;
3369 break;
3370
3371 case ARGUS_DST_SHORT:
3372 dsr->argus_dsrvl8.qual = type;
3373 dsr->argus_dsrvl8.len = 2;
3374 ((unsigned short *)(dsr + 1))[0] = psize->dst.psizemin;
3375 ((unsigned short *)(dsr + 1))[1] = psize->dst.psizemax;
3376 break;
3377
3378 default:
3379 ArgusLog (LOG_ERR, "ArgusGenerateRecord: packet size type not defined");
3380 break;
3381 }
3382 dsr->argus_dsrvl8.qual = type;
3383 len = dsr->argus_dsrvl8.len;
3384 dsrptr += len;
3385 } else
3386 len = 0;
3387 break;
3388 }
3389
3390 case ARGUS_MPLS_INDEX: {
3391 struct ArgusMplsStruct *mpls = (struct ArgusMplsStruct *) dsr;
3392 struct ArgusMplsStruct *tmpls = (struct ArgusMplsStruct *) dsrptr;
3393 unsigned char subtype = mpls->hdr.subtype & ~(ARGUS_MPLS_SRC_LABEL | ARGUS_MPLS_DST_LABEL);
3394
3395 *dsrptr++ = *(unsigned int *)dsr;
3396 tmpls->hdr.argus_dsrvl8.len = 1;
3397
3398 if (((mpls->hdr.argus_dsrvl8.qual & 0xF0) >> 4) > 0) {
3399 subtype |= ARGUS_MPLS_SRC_LABEL;
3400 *dsrptr++ = mpls->slabel;
3401 tmpls->hdr.argus_dsrvl8.len++;
3402 }
3403 if ((mpls->hdr.argus_dsrvl8.qual & 0x0F) > 0) {
3404 subtype |= ARGUS_MPLS_DST_LABEL;
3405 *dsrptr++ = mpls->dlabel;
3406 tmpls->hdr.argus_dsrvl8.len++;
3407 }
3408 tmpls->hdr.subtype = subtype;
3409 len = tmpls->hdr.argus_dsrvl8.len;
3410 break;
3411 }
3412
3413 case ARGUS_JITTER_INDEX: {
3414 struct ArgusJitterStruct *jitter = (struct ArgusJitterStruct *) dsr;
3415 struct ArgusJitterStruct *tjit = (struct ArgusJitterStruct *) dsrptr;
3416 int size = sizeof(jitter->act.src)/4;
3417
3418 *dsrptr++ = *(unsigned int *)dsr;
3419 tjit->hdr.argus_dsrvl8.len = 1;
3420
3421 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_SRC_ACTIVE_JITTER) {
3422 unsigned int *tptr = (unsigned int *)&jitter->act.src;
3423 for (x = 0; x < size; x++)
3424 *dsrptr++ = *tptr++;
3425 tjit->hdr.argus_dsrvl8.len += size;
3426 }
3427 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_SRC_IDLE_JITTER) {
3428 unsigned int *tptr = (unsigned int *)&jitter->idle.src;
3429 for (x = 0; x < size; x++)
3430 *dsrptr++ = *tptr++;
3431 tjit->hdr.argus_dsrvl8.len += size;
3432 }
3433 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_DST_ACTIVE_JITTER) {
3434 unsigned int *tptr = (unsigned int *)&jitter->act.dst;
3435 for (x = 0; x < size; x++)
3436 *dsrptr++ = *tptr++;
3437 tjit->hdr.argus_dsrvl8.len += size;
3438 }
3439 if (jitter->hdr.argus_dsrvl8.qual & ARGUS_DST_IDLE_JITTER) {
3440 unsigned int *tptr = (unsigned int *)&jitter->idle.dst;
3441 for (x = 0; x < size; x++)
3442 *dsrptr++ = *tptr++;
3443 tjit->hdr.argus_dsrvl8.len += size;
3444 }
3445
3446 len = tjit->hdr.argus_dsrvl8.len;
3447 break;
3448 }
3449
3450 case ARGUS_IPATTR_INDEX: {
3451 struct ArgusIPAttrStruct *attr = (struct ArgusIPAttrStruct *) dsr;
3452 struct ArgusIPAttrStruct *tattr = (struct ArgusIPAttrStruct *) dsrptr;
3453
3454 *dsrptr++ = *(unsigned int *)dsr;
3455 tattr->hdr.argus_dsrvl8.len = 1;
3456
3457 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC) {
3458 *dsrptr++ = *(unsigned int *)&attr->src;
3459 tattr->hdr.argus_dsrvl8.len++;
3460 }
3461 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_SRC_OPTIONS) {
3462 *dsrptr++ = attr->src.options;
3463 tattr->hdr.argus_dsrvl8.len++;
3464 }
3465 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST) {
3466 *dsrptr++ = *(unsigned int *)&attr->dst;
3467 tattr->hdr.argus_dsrvl8.len++;
3468 }
3469 if (attr->hdr.argus_dsrvl8.qual & ARGUS_IPATTR_DST_OPTIONS) {
3470 *dsrptr++ = attr->dst.options;
3471 tattr->hdr.argus_dsrvl8.len++;
3472 }
3473 len = tattr->hdr.argus_dsrvl8.len;
3474 break;
3475 }
3476
3477 /* user capture data buffers are passed to the output
3478 model as (struct ArgusDataStruct *) buffers, not as
3479 pointers to sections of the canonical record.
3480 Seems wierd but is saves us a few copies */
3481
3482 case ARGUS_SRCUSERDATA_INDEX:
3483 case ARGUS_DSTUSERDATA_INDEX: {
3484 unsigned short *sptr;
3485 struct ArgusDataStruct *user = (struct ArgusDataStruct *) dsr;
3486 len = 2 + (user->count + 3)/4;
3487
3488 sptr = (unsigned short *)&user->hdr.argus_dsrvl8;
3489 *sptr = len;
3490
3491 for (x = 0; x < len; x++)
3492 *dsrptr++ = ((unsigned int *)user)[x];
3493
3494 break;
3495 }
3496 }
3497 dsrlen += len;
3498 }
3499 dsrindex &= ~ind;
3500 }
3501
3502 retn->hdr.len = dsrlen;
3503 break;
3504 }
3505 case ARGUS_MAR: {
3506 bcopy ((char *)&rec->canon, (char *) retn, rec->hdr.len * 4);
3507 retn->hdr = rec->hdr;
3508 if (state)
3509 retn->hdr.cause = (state & 0xF0) | (retn->hdr.cause & 0x0F);
3510 break;
3511 }
3512 }
3513
3514 } else {
3515 retn->hdr.type = ARGUS_MAR;
3516 retn->hdr.type |= ARGUS_VERSION;
3517 retn->hdr.cause = state & 0xF0;
3518 retn->hdr.len = 1;
3519 }
3520
3521 #ifdef ARGUSDEBUG
3522 ArgusDebug (8, "ArgusGenerateRecord (0x%x, %d) done\n", rec, state);
3523 #endif
3524 return (retn);
3525 }
3526
3527
3528 struct ArgusRecordStruct *ArgusCopyRecordStruct (struct ArgusRecordStruct *);
3529
3530 #define ARGUS_MAX_OS_STATUS 4204
3531
3532 struct ArgusRecordStruct *
ArgusCopyRecordStruct(struct ArgusRecordStruct * rec)3533 ArgusCopyRecordStruct (struct ArgusRecordStruct *rec)
3534 {
3535 struct ArgusRecordStruct *retn = NULL;
3536 int i;
3537
3538 if (rec) {
3539 switch (rec->hdr.type & 0xF0) {
3540 case ARGUS_EVENT: {
3541 if ((retn = (struct ArgusRecordStruct *) ArgusMallocListRecord (ARGUS_MAX_OS_STATUS)) != NULL)
3542 bcopy ((char *)rec, (char *)retn, ARGUS_MAX_OS_STATUS);
3543 break;
3544 }
3545
3546 case ARGUS_FAR: {
3547 if ((retn = (struct ArgusRecordStruct *) ArgusMallocListRecord (sizeof(*retn))) != NULL) {
3548 bcopy ((char *)&rec->hdr, (char *)&retn->hdr, sizeof (rec->hdr));
3549 bcopy ((char *)&rec->canon, (char *)&retn->canon, sizeof (rec->canon));
3550
3551 retn->status = rec->status;
3552 retn->trans = rec->trans;
3553 retn->timeout = rec->timeout;
3554
3555 if ((retn->dsrindex = rec->dsrindex)) {
3556 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
3557 if (rec->dsrs[i] != NULL) {
3558 switch (i) {
3559 case ARGUS_TRANSPORT_INDEX: retn->dsrs[i] = &retn->canon.trans.hdr; break;
3560 case ARGUS_TIME_INDEX: retn->dsrs[i] = &retn->canon.time.hdr; break;
3561 case ARGUS_FLOW_INDEX: retn->dsrs[i] = &retn->canon.flow.hdr; break;
3562 case ARGUS_METRIC_INDEX: retn->dsrs[i] = &retn->canon.metric.hdr; break;
3563 case ARGUS_NETWORK_INDEX: retn->dsrs[i] = &retn->canon.net.hdr; break;
3564 case ARGUS_IPATTR_INDEX: retn->dsrs[i] = &retn->canon.attr.hdr; break;
3565 case ARGUS_JITTER_INDEX: retn->dsrs[i] = &retn->canon.jitter.hdr; break;
3566 case ARGUS_ICMP_INDEX: retn->dsrs[i] = &retn->canon.icmp.hdr; break;
3567 case ARGUS_ENCAPS_INDEX: retn->dsrs[i] = &retn->canon.encaps.hdr; break;
3568 case ARGUS_PSIZE_INDEX: retn->dsrs[i] = &retn->canon.psize.hdr; break;
3569 case ARGUS_MAC_INDEX: retn->dsrs[i] = &retn->canon.mac.hdr; break;
3570 case ARGUS_VLAN_INDEX: retn->dsrs[i] = &retn->canon.vlan.hdr; break;
3571 case ARGUS_MPLS_INDEX: retn->dsrs[i] = &retn->canon.mpls.hdr; break;
3572
3573 case ARGUS_SRCUSERDATA_INDEX:
3574 case ARGUS_DSTUSERDATA_INDEX: {
3575 struct ArgusDataStruct *user = (struct ArgusDataStruct *) rec->dsrs[i];
3576 if (user->count > 0) {
3577 if ((retn->dsrs[i] = (void *) ArgusCalloc(1, (8 + user->size))) != NULL) {
3578 bcopy ((char *)rec->dsrs[i], (char *)retn->dsrs[i], 8 + user->count);
3579 } else {
3580 retn->dsrindex &= ~(0x01 << i);
3581 }
3582 break;
3583 }
3584 }
3585 }
3586
3587 } else {
3588 switch (i) {
3589 case ARGUS_SRCUSERDATA_INDEX:
3590 case ARGUS_DSTUSERDATA_INDEX:
3591 if (retn->dsrs[i] != NULL)
3592 ArgusFree(retn->dsrs[i]);
3593 break;
3594 }
3595 retn->dsrs[i] = NULL;
3596 retn->dsrindex &= ~(0x01 << i);
3597 }
3598 }
3599 }
3600
3601 retn->srate = rec->srate;
3602 retn->drate = rec->drate;
3603 retn->sload = rec->sload;
3604 retn->dload = rec->dload;
3605 retn->pcr = rec->pcr;
3606 retn->sploss = rec->sploss;
3607 retn->dploss = rec->dploss;
3608 }
3609 break;
3610 }
3611 }
3612 }
3613
3614 #ifdef ARGUSDEBUG
3615 ArgusDebug (8, "ArgusCopyRecordStruct (0x%x) done\n", rec);
3616 #endif
3617
3618 return (retn);
3619 }
3620
3621
3622 struct ArgusRecordStruct *
ArgusGenerateListRecord(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flow,unsigned char state)3623 ArgusGenerateListRecord (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flow, unsigned char state)
3624 {
3625 struct ArgusRecordStruct *retn = NULL;
3626 int dsrlen = 1, i;
3627
3628 if ((retn = (struct ArgusRecordStruct *) ArgusMallocListRecord (sizeof(*retn))) != NULL) {
3629 if (flow) {
3630 bcopy ((char *)&flow->canon, (char *)&retn->canon, sizeof (flow->canon));
3631 if ((retn->dsrindex = flow->dsrindex) != 0) {
3632 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
3633 if (flow->dsrs[i] != NULL) {
3634 switch (i) {
3635 case ARGUS_TRANSPORT_INDEX: retn->dsrs[i] = &retn->canon.trans.hdr; break;
3636 case ARGUS_TIME_INDEX: retn->dsrs[i] = &retn->canon.time.hdr; break;
3637 case ARGUS_ENCAPS_INDEX: retn->dsrs[i] = &retn->canon.encaps.hdr; break;
3638 case ARGUS_FLOW_INDEX: retn->dsrs[i] = &retn->canon.flow.hdr; break;
3639 case ARGUS_METRIC_INDEX: retn->dsrs[i] = &retn->canon.metric.hdr; break;
3640 case ARGUS_PSIZE_INDEX: retn->dsrs[i] = &retn->canon.psize.hdr; break;
3641 case ARGUS_IPATTR_INDEX: retn->dsrs[i] = &retn->canon.attr.hdr; break;
3642 case ARGUS_MAC_INDEX: retn->dsrs[i] = &retn->canon.mac.hdr; break;
3643 case ARGUS_ICMP_INDEX: retn->dsrs[i] = &retn->canon.icmp.hdr; break;
3644
3645 /* pass the user data buffer into the list record */
3646 case ARGUS_SRCUSERDATA_INDEX:
3647 case ARGUS_DSTUSERDATA_INDEX: {
3648 struct ArgusDataStruct *data = (struct ArgusDataStruct *) retn->dsrs[i];
3649 retn->dsrs[i] = flow->dsrs[i];
3650 flow->dsrs[i] = NULL;
3651 if (data != NULL) {
3652 ArgusFree(data);
3653 }
3654 break;
3655 }
3656
3657 case ARGUS_NETWORK_INDEX: {
3658 switch (retn->canon.net.hdr.subtype & 0x7F) {
3659 case ARGUS_TCP_STATUS:
3660 case ARGUS_TCP_PERF:
3661 ArgusTCPFlowRecord (&retn->canon.net, state);
3662 retn->dsrs[i] = &retn->canon.net.hdr;
3663 break;
3664
3665 case ARGUS_ESP_DSR:
3666 ArgusESPFlowRecord (&retn->canon.net, state);
3667 retn->dsrs[i] = &retn->canon.net.hdr;
3668 break;
3669
3670 default:
3671 retn->dsrs[i] = &retn->canon.net.hdr;
3672 break;
3673 }
3674 break;
3675 }
3676
3677 case ARGUS_MPLS_INDEX: retn->dsrs[i] = &retn->canon.mpls.hdr; break;
3678 case ARGUS_VLAN_INDEX: retn->dsrs[i] = &retn->canon.vlan.hdr; break;
3679
3680 case ARGUS_JITTER_INDEX: {
3681 struct ArgusJitterStruct *jitter = &retn->canon.jitter;
3682
3683 if ((flow->stime.act.n || flow->dtime.act.n) ||(flow->stime.idle.n || flow->dtime.idle.n)) {
3684
3685 jitter->hdr.argus_dsrvl8.qual = 0;
3686 jitter->hdr.argus_dsrvl8.len = 1;
3687
3688 if (flow->stime.act.n) {
3689 struct ArgusStatsObject *tjit = (struct ArgusStatsObject *) (&jitter->act.src);
3690 tjit->n = flow->stime.act.n;
3691 tjit->minval = flow->stime.act.minval;
3692 tjit->maxval = flow->stime.act.maxval;
3693 tjit->meanval = flow->stime.act.sum/flow->stime.act.n;
3694 tjit->stdev = (sqrt ((flow->stime.act.sumsqrd/flow->stime.act.n) -
3695 pow ((flow->stime.act.sum)/flow->stime.act.n, 2.0))) * 1;
3696
3697 jitter->hdr.argus_dsrvl8.qual |= ARGUS_SRC_ACTIVE_JITTER;
3698 jitter->hdr.argus_dsrvl8.len += sizeof(*tjit)/4;
3699 tjit++;
3700 }
3701
3702 if (flow->stime.idle.n) {
3703 struct ArgusStatsObject *tjit = (struct ArgusStatsObject *) (&jitter->idle.src);
3704 tjit->n = flow->stime.idle.n;
3705 tjit->minval = flow->stime.idle.minval;
3706 tjit->maxval = flow->stime.idle.maxval;
3707 tjit->meanval = flow->stime.idle.sum/flow->stime.idle.n;
3708 tjit->stdev = (sqrt ((flow->stime.idle.sumsqrd/flow->stime.idle.n) -
3709 pow ((flow->stime.idle.sum)/flow->stime.idle.n, 2.0))) * 1;
3710
3711 jitter->hdr.argus_dsrvl8.qual |= ARGUS_SRC_IDLE_JITTER;
3712 jitter->hdr.argus_dsrvl8.len += sizeof(*tjit)/4;
3713 tjit++;
3714 }
3715
3716 if (flow->dtime.act.n) {
3717 struct ArgusStatsObject *tjit = (struct ArgusStatsObject *) (&jitter->act.dst);
3718 tjit->n = flow->dtime.act.n;
3719 tjit->minval = flow->dtime.act.minval;
3720 tjit->maxval = flow->dtime.act.maxval;
3721 tjit->meanval = flow->dtime.act.sum/flow->dtime.act.n;
3722 tjit->stdev = (sqrt ((flow->dtime.act.sumsqrd/flow->dtime.act.n) -
3723 pow ((flow->dtime.act.sum)/flow->dtime.act.n, 2.0))) * 1;
3724
3725 jitter->hdr.argus_dsrvl8.qual |= ARGUS_DST_ACTIVE_JITTER;
3726 jitter->hdr.argus_dsrvl8.len += sizeof(*tjit)/4;
3727 tjit++;
3728 }
3729
3730 if (flow->dtime.idle.n) {
3731 struct ArgusStatsObject *tjit = (struct ArgusStatsObject *) (&jitter->idle.dst);
3732 tjit->n = flow->dtime.act.n;
3733 tjit->n = flow->dtime.idle.n;
3734 tjit->minval = flow->dtime.idle.minval;
3735 tjit->maxval = flow->dtime.idle.maxval;
3736 tjit->meanval = flow->dtime.idle.sum/flow->dtime.idle.n;
3737 tjit->stdev = (sqrt ((flow->dtime.idle.sumsqrd/flow->dtime.idle.n) -
3738 pow ((flow->dtime.idle.sum)/flow->dtime.idle.n, 2.0))) * 1;
3739
3740 jitter->hdr.argus_dsrvl8.qual |= ARGUS_DST_IDLE_JITTER;
3741 jitter->hdr.argus_dsrvl8.len += sizeof(*tjit)/4;
3742 tjit++;
3743 }
3744
3745 retn->dsrs[i] = (struct ArgusDSRHeader *)jitter;
3746
3747 } else {
3748 retn->dsrindex &= ~ARGUS_JITTER_INDEX;
3749 retn->dsrs[i] = NULL;
3750 }
3751
3752 break;
3753 }
3754
3755 case ARGUS_BEHAVIOR_INDEX: {
3756 struct ArgusBehaviorStruct *actor = &retn->canon.actor;
3757 retn->dsrs[i] = NULL;
3758 int value;
3759
3760 if ((value = getArgusKeystroke(model)) > 0) {
3761 actor->hdr.type = ARGUS_BEHAVIOR_DSR;
3762 actor->hdr.subtype = 0;
3763 actor->hdr.argus_dsrvl8.len = sizeof(*actor)/4;
3764 actor->keyStroke.src.n_strokes = flow->skey.n_strokes;
3765 actor->keyStroke.dst.n_strokes = 0;
3766
3767 if (flow->skey.n_pkts >= model->ArgusKeyStroke.n_min) {
3768 if ((value == ARGUS_SSH_KEYSTROKE) && (flow->status & ARGUS_SSH_MONITOR)) {
3769 actor->hdr.subtype = ARGUS_SSH_KEYSTROKE;
3770 retn->dsrs[i] = (struct ArgusDSRHeader *)actor;
3771 } else
3772 if (value == ARGUS_TCP_KEYSTROKE) {
3773 actor->hdr.subtype = ARGUS_TCP_KEYSTROKE;
3774 retn->dsrs[i] = (struct ArgusDSRHeader *)actor;
3775 }
3776 }
3777
3778 }
3779 if (retn->dsrs[i] == NULL) {
3780 actor->keyStroke.src.n_strokes = 0;
3781 actor->keyStroke.dst.n_strokes = 0;
3782 retn->dsrindex &= ~ARGUS_BEHAVIOR_INDEX;
3783 }
3784 break;
3785 }
3786 }
3787
3788 if (retn->dsrs[i]) {
3789 dsrlen += ((retn->dsrs[i]->type & 0x80) ? 1 :
3790 ((retn->dsrs[i]->type == ARGUS_DATA_DSR) ? retn->dsrs[i]->argus_dsrvl16.len :
3791 retn->dsrs[i]->argus_dsrvl8.len ));
3792 }
3793
3794 } else {
3795 switch (i) {
3796 case ARGUS_SRCUSERDATA_INDEX:
3797 case ARGUS_DSTUSERDATA_INDEX:
3798 if (retn->dsrs[i] != NULL)
3799 ArgusFree(retn->dsrs[i]);
3800 }
3801
3802 retn->dsrs[i] = NULL;
3803 retn->dsrindex &= ~(0x01 << i);
3804 }
3805 }
3806
3807 } else {
3808 if (retn->dsrs[ARGUS_SRCUSERDATA_INDEX] != NULL) {
3809 ArgusFree(retn->dsrs[ARGUS_SRCUSERDATA_INDEX]);
3810 retn->dsrs[ARGUS_SRCUSERDATA_INDEX] = NULL;
3811 retn->dsrindex &= ~(0x01 << ARGUS_SRCUSERDATA_INDEX);
3812 }
3813 if (retn->dsrs[ARGUS_DSTUSERDATA_INDEX] != NULL) {
3814 ArgusFree(retn->dsrs[ARGUS_DSTUSERDATA_INDEX]);
3815 retn->dsrs[ARGUS_DSTUSERDATA_INDEX] = NULL;
3816 retn->dsrindex &= ~(0x01 << ARGUS_DSTUSERDATA_INDEX);
3817 }
3818 }
3819
3820 retn->srate = ArgusFetchSrcRate(retn);
3821 retn->drate = ArgusFetchDstRate(retn);
3822 retn->sload = ArgusFetchSrcLoad(retn);
3823 retn->dload = ArgusFetchDstRate(retn);
3824 retn->pcr = ArgusFetchAppByteRatio(retn);
3825 retn->sploss = ArgusFetchPercentSrcLoss(retn);
3826 retn->dploss = ArgusFetchPercentDstLoss(retn);
3827
3828 } else {
3829 retn->dsrindex = 0;
3830 bzero ((char *)&retn->canon, sizeof(retn->canon));
3831 bzero ((char *)&retn->dsrs, sizeof(retn->dsrs));
3832 }
3833
3834 if (!(flow) && ((state == ARGUS_STOP) || (state == ARGUS_ERROR))) {
3835 retn->hdr.type = ARGUS_MAR;
3836 retn->status = 0;
3837 retn->trans = 0;
3838 retn->timeout = 0;
3839
3840 } else {
3841 retn->hdr.type = flow->canon.hdr.type | ARGUS_FAR;
3842 retn->status = flow->status;
3843 retn->trans = flow->trans;
3844 retn->timeout = flow->timeout;
3845 }
3846
3847 retn->hdr.type |= ARGUS_VERSION;
3848 retn->hdr.cause = state & 0xF0;
3849 retn->hdr.len = dsrlen;
3850
3851 } else {
3852 #ifdef ARGUSDEBUG
3853 ArgusDebug (3, "ArgusMallocListRecord (%d) returned NULL\n", sizeof(*retn));
3854 #endif
3855 }
3856
3857 #ifdef ARGUSDEBUG
3858 ArgusDebug (8, "ArgusGenerateListRecord (%p, %p, %d) returning %p\n", model, flow, state, retn);
3859 #endif
3860 return (retn);
3861 }
3862
3863
3864 void
ArgusSendFlowRecord(struct ArgusModelerStruct * model,struct ArgusFlowStruct * flow,unsigned char state)3865 ArgusSendFlowRecord (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flow, unsigned char state)
3866 {
3867 struct ArgusRecordStruct *argus;
3868 #ifdef ARGUSDEBUG
3869 int scheduled = 0;
3870 #endif
3871
3872 if (flow != NULL) {
3873 if (model->ArgusOutputList) {
3874 struct ArgusFlowStruct *frag;
3875 if ((frag = (struct ArgusFlowStruct *)flow->frag.start) != NULL) {
3876 do {
3877 ArgusUpdateParentFlow(model, frag);
3878 frag = (struct ArgusFlowStruct *)frag->qhdr.nxt;
3879 } while (frag != (struct ArgusFlowStruct *)flow->frag.start);
3880 }
3881
3882 if (flow->canon.metric.src.pkts || flow->canon.metric.dst.pkts) {
3883 if (flow->canon.trans.seqnum == 0) {
3884 if ((flow->canon.trans.seqnum = model->ArgusSeqNum++) == 0xFFFFFFFF)
3885 flow->canon.trans.seqnum = model->ArgusSeqNum++;
3886 }
3887
3888 if ((argus = ArgusGenerateListRecord (model, flow, state)) != NULL) {
3889 ArgusPushBackList (model->ArgusOutputList, (struct ArgusListRecord *) argus, ARGUS_LOCK);
3890 flow->status |= ARGUS_RECORD_WRITTEN;
3891 model->ArgusTotalSends++;
3892 #ifdef ARGUSDEBUG
3893 scheduled = 1;
3894 #endif
3895
3896 #if defined(ARGUS_THREADS)
3897 pthread_mutex_lock(&model->ArgusOutputList->lock);
3898 pthread_cond_signal(&model->ArgusOutputList->cond);
3899 pthread_mutex_unlock(&model->ArgusOutputList->lock);
3900 #endif
3901 }
3902
3903 #ifdef ARGUSDEBUG
3904 if (scheduled)
3905 ArgusDebug (9, "ArgusSendFlowRecord (%p, %p, %d) scheduled %p\n", model, flow, state, argus);
3906 else
3907 ArgusDebug (9, "ArgusSendFlowRecord (%p, %p, %d) done\n", model, flow, state);
3908 #endif
3909 } else {
3910 model->ArgusTotalBadSends++;
3911 }
3912
3913 } else {
3914 #ifdef ARGUSDEBUG
3915 ArgusDebug (3, "ArgusSendFlowRecord (%p, %p, %d) no model->ArgusOutputList\n", model, flow, state);
3916 #endif
3917 }
3918
3919 } else {
3920 #ifdef ARGUSDEBUG
3921 ArgusDebug (2, "ArgusSendFlowRecord (%p, %p, %d) no flow provided\n", model, flow, state);
3922 #endif
3923 }
3924 }
3925
3926
3927 void
ArgusModelerCleanUp(struct ArgusModelerStruct * model)3928 ArgusModelerCleanUp (struct ArgusModelerStruct *model)
3929 {
3930 struct ArgusQueueStruct *queue;
3931
3932 if ((model->ArgusTimeOutQueues != NULL) && (model->ArgusTimeOutQueues->count > 0)) {
3933 int i, cnt = model->ArgusTimeOutQueues->count;
3934
3935 for (i = 0; i < cnt; i++) {
3936 queue = (struct ArgusQueueStruct *)ArgusPopQueue (model->ArgusTimeOutQueues, ARGUS_LOCK);
3937 if (queue->count) {
3938 #ifdef ARGUSDEBUG
3939 ArgusDebug (9, "ArgusModelerCleanUp(%p) ArgusProcessQueue(%p) timeout queue with %d records\n", model, queue, queue->count);
3940 #endif
3941 ArgusProcessQueue (model, queue, ARGUS_SHUTDOWN);
3942 }
3943 ArgusDeleteQueue (queue);
3944 }
3945 ArgusDeleteQueue (model->ArgusTimeOutQueues);
3946 model->ArgusTimeOutQueues = NULL;
3947 }
3948
3949 if (model->ArgusStatusQueue) {
3950 queue = model->ArgusStatusQueue;
3951
3952 #ifdef ARGUSDEBUG
3953 ArgusDebug (8, "ArgusModelerCleanUp(%p) ArgusProcessQueue(%p) status queue with %d records %d sent\n", model, queue, queue->count, model->ArgusTotalSends);
3954 #endif
3955
3956 if (queue->count)
3957 ArgusProcessQueue (model, queue, ARGUS_SHUTDOWN);
3958
3959 ArgusDeleteQueue (queue);
3960 model->ArgusStatusQueue = NULL;
3961 }
3962
3963 #ifdef ARGUSDEBUG
3964 ArgusDebug (3, "ArgusModelerCleanUp (%p) returning\n", model);
3965 #endif
3966 }
3967
3968 int ArgusCmp(void *, void *, int);
3969
3970 int
ArgusCmp(void * p1,void * p2,int len)3971 ArgusCmp(void *p1, void *p2, int len)
3972 {
3973 unsigned int *c1 = p1, *c2 = p2;
3974 int retn = 0, i = 0;
3975
3976 for (; i < len; i++, c1++, c2++)
3977 if (*c1 != *c2)
3978 break;
3979
3980 if (i != len)
3981 retn = c1[i] - c2[i];
3982
3983 return(retn);
3984 }
3985
3986
3987 void *
ArgusCreateIPv6Flow(struct ArgusModelerStruct * model,struct ip6_hdr * ip)3988 ArgusCreateIPv6Flow (struct ArgusModelerStruct *model, struct ip6_hdr *ip)
3989 {
3990 void *retn = NULL;
3991 struct ArgusSystemFlow *tflow;
3992
3993 if ((ip != NULL) && STRUCTCAPTURED(model, *ip)) {
3994 int nxt, done = 0, i = 0;
3995 unsigned int *sp = (unsigned int*) &ip->ip6_src;
3996 unsigned int *dp = (unsigned int*) &ip->ip6_dst;
3997 unsigned short alen, sport = 0, dport = 0;
3998 unsigned int *rsp, *rdp;
3999 #ifdef _LITTLE_ENDIAN
4000 // unsigned plen;
4001 // plen = ntohs(ip->ip6_plen);
4002 #endif
4003
4004 tflow = model->ArgusThisFlow;
4005 rsp = (unsigned int *)&tflow->ipv6_flow.ip_src;
4006 rdp = (unsigned int *)&tflow->ipv6_flow.ip_dst;
4007
4008 tflow->ipv6_flow.flow = 0;
4009
4010 nxt = ip->ip6_nxt;
4011 model->ArgusThisIpHdr = ip;
4012
4013 alen = sizeof(ip->ip6_src)/sizeof(int);
4014 if (model->ArgusFlowType == ARGUS_BIDIRECTIONAL) {
4015 while ((i < alen) && (*dp == *sp)) { /* copy while they are equal */
4016 *rsp++ = *sp++; /* leave pointers where they are not */
4017 *rdp++ = *dp++;
4018 i++;
4019 }
4020 if (i < alen) {
4021 if (ntohl(*sp) < ntohl(*dp)) {
4022 unsigned int *tmp = rdp;
4023 rdp = rsp;
4024 rsp = tmp;
4025 model->state |= ARGUS_DIRECTION;
4026 }
4027 while (i < alen) {
4028 *rsp++ = *sp++;
4029 *rdp++ = *dp++;
4030 i++;
4031 }
4032 }
4033 } else {
4034 for (i = 0; i < alen; i++) {
4035 *rsp++ = *sp++;
4036 *rdp++ = *dp++;
4037 }
4038 }
4039
4040 model->ArgusThisIpv6Frag = NULL;
4041 model->ArgusThisLength -= sizeof(*ip);
4042 model->ArgusSnapLength -= sizeof(*ip);
4043
4044 model->ArgusThisUpHdr = (unsigned char *)(ip + 1);
4045 ip++;
4046
4047 while (!done) {
4048 switch (nxt) {
4049 case IPPROTO_FRAGMENT: {
4050 int offset = ((((struct ip6_hbh *)ip)->ip6h_len + 1) << 3);
4051 struct ip6_frag *tfrag = (struct ip6_frag *) ip;
4052
4053 model->ArgusThisIpv6Frag = tfrag;
4054 nxt = *(char *)ip;
4055
4056 if ((ntohs(tfrag->ip6f_offlg & IP6F_OFF_MASK)) != 0)
4057 done++;
4058
4059 ip = (struct ip6_hdr *)((char *)ip + offset);
4060 model->ArgusThisLength -= offset;
4061 model->ArgusSnapLength -= offset;
4062 model->ArgusThisUpHdr += offset;
4063 break;
4064 }
4065
4066 case IPPROTO_HOPOPTS:
4067 case IPPROTO_DSTOPTS:
4068 case IPPROTO_ROUTING: {
4069 int offset = ((((struct ip6_hbh *)ip)->ip6h_len + 1) << 3);
4070 nxt = *(char *)ip;
4071 ip = (struct ip6_hdr *)((char *)ip + offset);
4072 model->ArgusThisLength -= offset;
4073 model->ArgusSnapLength -= offset;
4074 model->ArgusThisUpHdr += offset;
4075 break;
4076 }
4077
4078 default:
4079 done++;
4080 break;
4081 }
4082 }
4083
4084 tflow->hdr.type = ARGUS_FLOW_DSR;
4085 retn = tflow;
4086
4087 if (model->ArgusFlowKey & ARGUS_FLOW_KEY_CLASSIC5TUPLE) {
4088 tflow->hdr.subtype = ARGUS_FLOW_CLASSIC5TUPLE;
4089 tflow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_IPV6;
4090 tflow->hdr.argus_dsrvl8.len = 11;
4091 tflow->ipv6_flow.ip_p = nxt;
4092
4093 if ((model->ArgusThisIpv6Frag) && ((ntohs(model->ArgusThisIpv6Frag->ip6f_offlg & IP6F_OFF_MASK)) != 0)) {
4094 tflow->fragv6_flow.ip_id = model->ArgusThisIpv6Frag->ip6f_ident;
4095 tflow->hdr.argus_dsrvl8.qual |= ARGUS_FRAGMENT;
4096 } else {
4097 if (nxt == IPPROTO_AH) {
4098 struct AHHeader *ah = (struct AHHeader *) model->ArgusThisUpHdr;
4099
4100 model->ArgusThisEncaps |= ARGUS_ENCAPS_AH;
4101
4102 if (STRUCTCAPTURED(model, *ah)) {
4103 nxt = ah->nxt;
4104 model->ArgusThisUpHdr = (unsigned char *)(ah + 1);
4105 tflow->ipv6_flow.ip_p = nxt;
4106 }
4107 }
4108
4109 switch (nxt) {
4110 case IPPROTO_TCP: {
4111 struct tcphdr *tp = (struct tcphdr *) model->ArgusThisUpHdr;
4112 if (model->state & ARGUS_DIRECTION) {
4113 dport = ntohs(tp->th_sport);
4114 sport = ntohs(tp->th_dport);
4115 } else {
4116 sport = ntohs(tp->th_sport);
4117 dport = ntohs(tp->th_dport);
4118 }
4119 tflow->ipv6_flow.sport = sport;
4120 tflow->ipv6_flow.dport = dport;
4121 break;
4122 }
4123
4124 case IPPROTO_UDP: {
4125 struct udphdr *up = (struct udphdr *) model->ArgusThisUpHdr;
4126 if (model->state & ARGUS_DIRECTION) {
4127 dport = ntohs(up->uh_sport);
4128 sport = ntohs(up->uh_dport);
4129 } else {
4130 sport = ntohs(up->uh_sport);
4131 dport = ntohs(up->uh_dport);
4132 }
4133 tflow->ipv6_flow.sport = sport;
4134 tflow->ipv6_flow.dport = dport;
4135 break;
4136 }
4137
4138 case IPPROTO_ESP:
4139 retn = ArgusCreateESPv6Flow(model, ip);
4140 break;
4141
4142 case IPPROTO_ICMPV6:
4143 retn = ArgusCreateICMPv6Flow(model, (struct icmp6_hdr *)model->ArgusThisUpHdr);
4144 break;
4145
4146 case IPPROTO_IGMP:
4147 retn = ArgusCreateIGMPv6Flow(model, (struct igmp *)model->ArgusThisUpHdr);
4148 break;
4149
4150 default:
4151 tflow->ipv6_flow.sport = sport;
4152 tflow->ipv6_flow.dport = dport;
4153 break;
4154 }
4155 }
4156
4157 } else {
4158 if (model->ArgusFlowKey & ARGUS_FLOW_KEY_LAYER_3_MATRIX) {
4159 tflow->hdr.subtype = ARGUS_FLOW_LAYER_3_MATRIX;
4160 tflow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_IPV6;
4161 tflow->hdr.argus_dsrvl8.len = 9;
4162 tflow->ipv6_flow.sport = 0;
4163 tflow->ipv6_flow.dport = 0;
4164 tflow->ipv6_flow.ip_p = 0;
4165 }
4166 }
4167 }
4168
4169 #ifdef ARGUSDEBUG
4170 ArgusDebug (9, "ArgusCreateIPv6Flow (0x%x, 0x%x) returning %d\n", model, ip, retn);
4171 #endif
4172
4173 return (retn);
4174 }
4175
4176
4177 void *
ArgusCreateIPv4Flow(struct ArgusModelerStruct * model,struct ip * ip)4178 ArgusCreateIPv4Flow (struct ArgusModelerStruct *model, struct ip *ip)
4179 {
4180 void *retn = model->ArgusThisFlow;
4181 unsigned char *nxtHdr = (unsigned char *)((char *)ip + (ip->ip_hl << 2));
4182 struct ip tipbuf, *tip = &tipbuf;
4183 arg_uint16 sport = 0, dport = 0;
4184 arg_uint8 proto, tp_p = 0;
4185 arg_uint32 len;
4186 int hlen, ArgusOptionLen;
4187
4188 if ((ip != NULL) && STRUCTCAPTURED(model, *ip)) {
4189 model->ArgusThisIpHdr = ip;
4190
4191 #ifdef _LITTLE_ENDIAN
4192 bzero(tip, sizeof(*tip));
4193 tip->ip_len = ntohs(ip->ip_len);
4194 tip->ip_id = ntohs(ip->ip_id);
4195 tip->ip_v = ip->ip_v;
4196 tip->ip_hl = ip->ip_hl;
4197 tip->ip_off = ntohs(ip->ip_off);
4198 tip->ip_src.s_addr = ntohl(ip->ip_src.s_addr);
4199 tip->ip_dst.s_addr = ntohl(ip->ip_dst.s_addr);
4200 #else
4201 tip = ip;
4202 #endif
4203
4204 hlen = tip->ip_hl << 2;
4205 len = (tip->ip_len - hlen);
4206
4207 model->ArgusOptionIndicator = '\0';
4208 if ((ArgusOptionLen = (hlen - sizeof (struct ip))) > 0)
4209 model->ArgusOptionIndicator = ArgusParseIPOptions ((unsigned char *) (ip + 1), ArgusOptionLen);
4210 else
4211 model->ArgusOptionIndicator = 0;
4212
4213 model->ArgusThisLength = len;
4214 model->ArgusSnapLength -= hlen;
4215
4216 if (model->ArgusFlowKey & ARGUS_FLOW_KEY_CLASSIC5TUPLE) {
4217 bzero ((char *)model->ArgusThisFlow, sizeof(*model->ArgusThisFlow));
4218 model->ArgusThisFlow->hdr.type = ARGUS_FLOW_DSR;
4219 model->ArgusThisFlow->hdr.subtype = ARGUS_FLOW_CLASSIC5TUPLE;
4220 model->ArgusThisFlow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_IPV4;
4221 model->ArgusThisFlow->hdr.argus_dsrvl8.len = 5;
4222
4223 proto = ip->ip_p;
4224
4225 if (!(tip->ip_off & 0x1fff)) {
4226 if (proto == IPPROTO_AH) {
4227 struct AHHeader *ah = (struct AHHeader *) nxtHdr;
4228
4229 model->ArgusThisEncaps |= ARGUS_ENCAPS_AH;
4230
4231 if (STRUCTCAPTURED(model, *ah)) {
4232 proto = ah->nxt;
4233 nxtHdr = (unsigned char *)(ah + 1);
4234 }
4235 }
4236
4237 model->ArgusThisUpHdr = nxtHdr;
4238
4239 switch (proto) {
4240 case IPPROTO_ESP:
4241 retn = ArgusCreateESPFlow (model, ip);
4242 return (retn);
4243
4244 case IPPROTO_ICMP:
4245 retn = ArgusCreateICMPFlow (model, ip);
4246 return (retn);
4247
4248 case IPPROTO_IGMP:
4249 retn = ArgusCreateIGMPFlow (model, ip);
4250 return (retn);
4251
4252 case IPPROTO_TCP: {
4253 model->ArgusThisFlow->ip_flow.smask = 0;
4254 model->ArgusThisFlow->ip_flow.dmask = 0;
4255 if (len >= sizeof (struct tcphdr)) {
4256 struct tcphdr *tp = (struct tcphdr *) nxtHdr;
4257 if (BYTESCAPTURED(model, *tp, 4)) {
4258 sport = ntohs(tp->th_sport);
4259 dport = ntohs(tp->th_dport);
4260 }
4261 }
4262 break;
4263 }
4264 case IPPROTO_UDP: {
4265 model->ArgusThisFlow->ip_flow.smask = 0;
4266 model->ArgusThisFlow->ip_flow.dmask = 0;
4267 if (len >= sizeof (struct udphdr)) {
4268 struct udphdr *up = (struct udphdr *) nxtHdr;
4269 if (BYTESCAPTURED(model, *up, 4)) {
4270 sport = ntohs(up->uh_sport);
4271 dport = ntohs(up->uh_dport);
4272 }
4273 if ((sport == 53) || (dport == 53)) {
4274 unsigned short pad = ntohs(*(u_int16_t *)(up + 1));
4275 bcopy(&pad, &model->ArgusThisFlow->ip_flow.smask, 2);
4276 }
4277 }
4278 break;
4279 }
4280
4281 default:
4282 break;
4283 }
4284
4285 if (model->ArgusFlowType == ARGUS_BIDIRECTIONAL)
4286 if ((tip->ip_src.s_addr > tip->ip_dst.s_addr) ||
4287 ((tip->ip_src.s_addr == tip->ip_dst.s_addr) &&
4288 sport > dport))
4289 model->state |= ARGUS_DIRECTION;
4290
4291 if (model->state & ARGUS_DIRECTION) {
4292 model->ArgusThisFlow->hdr.subtype |= ARGUS_REVERSE;
4293 model->ArgusThisFlow->ip_flow.ip_src = tip->ip_dst.s_addr;
4294 model->ArgusThisFlow->ip_flow.ip_dst = tip->ip_src.s_addr;
4295 model->ArgusThisFlow->ip_flow.sport = dport;
4296 model->ArgusThisFlow->ip_flow.dport = sport;
4297 } else {
4298 model->ArgusThisFlow->ip_flow.ip_src = tip->ip_src.s_addr;
4299 model->ArgusThisFlow->ip_flow.ip_dst = tip->ip_dst.s_addr;
4300 model->ArgusThisFlow->ip_flow.sport = sport;
4301 model->ArgusThisFlow->ip_flow.dport = dport;
4302 }
4303
4304 model->ArgusThisFlow->ip_flow.ip_p = proto;
4305 model->ArgusThisFlow->ip_flow.tp_p = tp_p;
4306
4307 } else {
4308 if (model->ArgusFlowType == ARGUS_BIDIRECTIONAL) {
4309 if (tip->ip_src.s_addr > tip->ip_dst.s_addr) {
4310 model->state |= ARGUS_DIRECTION;
4311 model->ArgusThisFlow->hdr.argus_dsrvl8.qual |= ARGUS_DIRECTION;
4312 model->ArgusThisFlow->hdr.subtype |= ARGUS_REVERSE;
4313 }
4314 }
4315
4316 model->ArgusThisFlow->hdr.argus_dsrvl8.qual |= ARGUS_FRAGMENT;
4317
4318 if (model->state & ARGUS_DIRECTION) {
4319 model->ArgusThisFlow->frag_flow.ip_dst = tip->ip_src.s_addr;
4320 model->ArgusThisFlow->frag_flow.ip_src = tip->ip_dst.s_addr;
4321 } else {
4322 model->ArgusThisFlow->frag_flow.ip_src = tip->ip_src.s_addr;
4323 model->ArgusThisFlow->frag_flow.ip_dst = tip->ip_dst.s_addr;
4324 }
4325 model->ArgusThisFlow->frag_flow.ip_p = proto;
4326 model->ArgusThisFlow->frag_flow.ip_id = tip->ip_id;
4327 }
4328
4329 } else {
4330 if (model->ArgusFlowKey & ARGUS_FLOW_KEY_LAYER_3_MATRIX) {
4331 model->ArgusThisFlow->hdr.type = ARGUS_FLOW_DSR;
4332 model->ArgusThisFlow->hdr.subtype = ARGUS_FLOW_LAYER_3_MATRIX;
4333 model->ArgusThisFlow->hdr.argus_dsrvl8.qual = ARGUS_TYPE_IPV4;
4334 model->ArgusThisFlow->hdr.argus_dsrvl8.len = 3;
4335
4336 switch (model->ArgusFlowType) {
4337 case ARGUS_UNIDIRECTIONAL:
4338 break;
4339 case ARGUS_BIDIRECTIONAL: {
4340 if (tip->ip_src.s_addr > tip->ip_dst.s_addr)
4341 model->state |= ARGUS_DIRECTION;
4342 break;
4343 }
4344 }
4345
4346 if (model->state & ARGUS_DIRECTION) {
4347 model->ArgusThisFlow->ip_flow.ip_src = tip->ip_dst.s_addr;
4348 model->ArgusThisFlow->ip_flow.ip_dst = tip->ip_src.s_addr;
4349 } else {
4350 model->ArgusThisFlow->ip_flow.ip_src = tip->ip_src.s_addr;
4351 model->ArgusThisFlow->ip_flow.ip_dst = tip->ip_dst.s_addr;
4352 }
4353 }
4354 }
4355 }
4356
4357 #ifdef ARGUSDEBUG
4358 ArgusDebug (9, "ArgusCreateIPv4Flow (0x%x, 0x%x) returning 0x%x\n", model, ip, retn);
4359 #endif
4360
4361 return (retn);
4362 }
4363
4364 #if !defined(IPOPT_RA)
4365 #define IPOPT_RA 148
4366 #endif
4367
4368 unsigned short
ArgusParseIPOptions(unsigned char * ptr,int len)4369 ArgusParseIPOptions (unsigned char *ptr, int len)
4370 {
4371 unsigned short retn = 0;
4372 int offset = 0;
4373
4374 for (; len > 0; ptr += offset, len -= offset) {
4375 switch (*ptr) {
4376 case IPOPT_EOL: break;
4377 case IPOPT_NOP: break;
4378 case IPOPT_RA: retn |= ARGUS_RTRALERT; break;
4379 case IPOPT_TS: retn |= ARGUS_TIMESTAMP; break;
4380 case IPOPT_RR: retn |= ARGUS_RECORDROUTE; break;
4381 case IPOPT_SECURITY: retn |= ARGUS_SECURITY; break;
4382 case IPOPT_LSRR: retn |= ARGUS_LSRCROUTE; break;
4383 case IPOPT_SSRR: retn |= ARGUS_SSRCROUTE; break;
4384 case IPOPT_SATID: retn |= ARGUS_SATID; break;
4385 default: break;
4386 }
4387
4388 if ((*ptr == IPOPT_EOL) || (*ptr == IPOPT_NOP))
4389 offset = 1;
4390 else {
4391 offset = ptr[1];
4392 if (!(offset && (offset <= len)))
4393 break;
4394 }
4395 }
4396
4397 return (retn);
4398 }
4399
4400 void
setArgusIpTimeout(struct ArgusModelerStruct * model,int value)4401 setArgusIpTimeout (struct ArgusModelerStruct *model, int value)
4402 {
4403 if (model != NULL) {
4404 model->ArgusIPTimeout = value;
4405 }
4406 }
4407
4408 void
setArgusTcpTimeout(struct ArgusModelerStruct * model,int value)4409 setArgusTcpTimeout (struct ArgusModelerStruct *model, int value)
4410 {
4411 if (model != NULL) {
4412 model->ArgusTCPTimeout = value;
4413 }
4414 }
4415
4416 void
setArgusIcmpTimeout(struct ArgusModelerStruct * model,int value)4417 setArgusIcmpTimeout (struct ArgusModelerStruct *model, int value)
4418 {
4419 if (model != NULL) {
4420 model->ArgusICMPTimeout = value;
4421 }
4422 }
4423
4424 void
setArgusIgmpTimeout(struct ArgusModelerStruct * model,int value)4425 setArgusIgmpTimeout (struct ArgusModelerStruct *model, int value)
4426 {
4427 if (model != NULL) {
4428 model->ArgusIGMPTimeout = value;
4429 }
4430 }
4431
4432 void
setArgusFragTimeout(struct ArgusModelerStruct * model,int value)4433 setArgusFragTimeout (struct ArgusModelerStruct *model, int value)
4434 {
4435 if (model != NULL) {
4436 model->ArgusFRAGTimeout = value;
4437 }
4438 }
4439
4440 void
setArgusArpTimeout(struct ArgusModelerStruct * model,int value)4441 setArgusArpTimeout (struct ArgusModelerStruct *model, int value)
4442 {
4443 if (model != NULL) {
4444 model->ArgusARPTimeout = value;
4445 }
4446 }
4447
4448 void
setArgusOtherTimeout(struct ArgusModelerStruct * model,int value)4449 setArgusOtherTimeout (struct ArgusModelerStruct *model, int value)
4450 {
4451 if (model != NULL) {
4452 model->ArgusOtherTimeout = value;
4453 }
4454 }
4455
4456 int
getArgusmflag(struct ArgusModelerStruct * model)4457 getArgusmflag (struct ArgusModelerStruct *model)
4458 {
4459 return(model->Argusmflag);
4460 }
4461
4462
4463 void
setArgusFlowType(struct ArgusModelerStruct * model,int value)4464 setArgusFlowType (struct ArgusModelerStruct *model, int value)
4465 {
4466 model->ArgusFlowType = value;
4467 }
4468
4469 void
setArgusFlowKey(struct ArgusModelerStruct * model,int value)4470 setArgusFlowKey (struct ArgusModelerStruct *model, int value)
4471 {
4472 model->ArgusFlowKey |= value;
4473 }
4474
4475 void
setArgusSynchronize(struct ArgusModelerStruct * model,int value)4476 setArgusSynchronize (struct ArgusModelerStruct *model, int value)
4477 {
4478 model->ArgusSelfSynchronize = value;
4479 }
4480
4481
4482 void
setArgusmflag(struct ArgusModelerStruct * model,int value)4483 setArgusmflag (struct ArgusModelerStruct *model, int value)
4484 {
4485 model->Argusmflag = value;
4486 }
4487
4488 int
getArgusGenerateTime(struct ArgusModelerStruct * model)4489 getArgusGenerateTime(struct ArgusModelerStruct *model)
4490 {
4491 return (model->ArgusGenerateTime);
4492 }
4493
4494 void
setArgusGenerateTime(struct ArgusModelerStruct * model,int value)4495 setArgusGenerateTime(struct ArgusModelerStruct *model, int value)
4496 {
4497 model->ArgusGenerateTime = value;
4498 }
4499
4500 int
getArgusGeneratePacketSize(struct ArgusModelerStruct * model)4501 getArgusGeneratePacketSize(struct ArgusModelerStruct *model)
4502 {
4503 return (model->ArgusGeneratePacketSize);
4504 }
4505
4506 void
setArgusGeneratePacketSize(struct ArgusModelerStruct * model,int value)4507 setArgusGeneratePacketSize(struct ArgusModelerStruct *model, int value)
4508 {
4509 model->ArgusGeneratePacketSize = value;
4510 }
4511
4512 int
getArgusKeystroke(struct ArgusModelerStruct * model)4513 getArgusKeystroke(struct ArgusModelerStruct *model)
4514 {
4515 return (model->ArgusKeyStroke.status);
4516 }
4517
4518 void
setArgusKeystroke(struct ArgusModelerStruct * model,int value)4519 setArgusKeystroke(struct ArgusModelerStruct *model, int value)
4520 {
4521 model->ArgusKeyStroke.status = value;
4522 }
4523
4524 #if !defined(HAVE_STRTOF) && !defined(CYGWIN)
4525 float strtof (char *, char **);
4526 #endif
4527
4528
4529 void
setArgusKeystrokeVariable(struct ArgusModelerStruct * model,char * kstok)4530 setArgusKeystrokeVariable(struct ArgusModelerStruct *model, char *kstok)
4531 {
4532 float fval = 0;
4533 long ival = 0;
4534 char *tptr;
4535
4536 if (!(strncasecmp(kstok, "DC_MIN=", 6))) {
4537 ival = strtol(&kstok[7], (char **)&tptr, 10);
4538 model->ArgusKeyStroke.dc_min = ival;
4539 } else
4540 if (!(strncasecmp(kstok, "DC_MAX=", 6))) {
4541 ival = strtol(&kstok[7], (char **)&tptr, 10);
4542 model->ArgusKeyStroke.dc_max = ival;
4543 } else
4544 if (!(strncasecmp(kstok, "GS_MAX=", 6))) {
4545 ival = strtol(&kstok[7], (char **)&tptr, 10);
4546 model->ArgusKeyStroke.gs_max = ival;
4547 } else
4548 if (!(strncasecmp(kstok, "DS_MIN=", 6))) {
4549 ival = strtol(&kstok[7], (char **)&tptr, 10);
4550 model->ArgusKeyStroke.ds_min = ival;
4551 } else
4552 if (!(strncasecmp(kstok, "DS_MAX=", 6))) {
4553 ival = strtol(&kstok[7], (char **)&tptr, 10);
4554 model->ArgusKeyStroke.ds_max = ival;
4555 } else
4556 if (!(strncasecmp(kstok, "IC_MIN=", 6))) {
4557 ival = strtol(&kstok[7], (char **)&tptr, 10);
4558 model->ArgusKeyStroke.ic_min = ival;
4559 } else
4560 if (!(strncasecmp(kstok, "LCS_MAX=", 7))) {
4561 ival = strtol(&kstok[8], (char **)&tptr, 10);
4562 model->ArgusKeyStroke.lcs_max = ival;
4563 } else
4564 if (!(strncasecmp(kstok, "GPC_MAX=", 7))) {
4565 ival = strtol(&kstok[8], (char **)&tptr, 10);
4566 model->ArgusKeyStroke.gpc_max = ival;
4567 } else
4568 if (!(strncasecmp(kstok, "ICR_MIN=", 7))) {
4569 fval = strtof(&kstok[8], (char **)&tptr);
4570 model->ArgusKeyStroke.icr_min = fval;
4571 } else
4572 if (!(strncasecmp(kstok, "ICR_MAX=", 7))) {
4573 fval = strtof(&kstok[8], (char **)&tptr);
4574 model->ArgusKeyStroke.icr_max = fval;
4575 }
4576
4577 }
4578
4579 int
getArgusTunnelDiscovery(struct ArgusModelerStruct * model)4580 getArgusTunnelDiscovery (struct ArgusModelerStruct *model)
4581 {
4582 return(model->ArgusTunnelDiscovery);
4583 }
4584
4585 void
setArgusTunnelDiscovery(struct ArgusModelerStruct * model,int value)4586 setArgusTunnelDiscovery (struct ArgusModelerStruct *model, int value)
4587 {
4588 model->ArgusTunnelDiscovery = value;
4589 }
4590
4591 int
getArgusTrackDuplicates(struct ArgusModelerStruct * model)4592 getArgusTrackDuplicates (struct ArgusModelerStruct *model)
4593 {
4594 return(model->ArgusTrackDuplicates);
4595 }
4596
4597 void
setArgusTrackDuplicates(struct ArgusModelerStruct * model,int value)4598 setArgusTrackDuplicates (struct ArgusModelerStruct *model, int value)
4599 {
4600 model->ArgusTrackDuplicates = value;
4601 }
4602
4603 int
getArgusUserDataLen(struct ArgusModelerStruct * model)4604 getArgusUserDataLen (struct ArgusModelerStruct *model)
4605 {
4606 return (model->ArgusUserDataLen);
4607 }
4608
4609 void
setArgusUserDataLen(struct ArgusModelerStruct * model,int value)4610 setArgusUserDataLen (struct ArgusModelerStruct *model, int value)
4611 {
4612 model->ArgusUserDataLen = value;
4613 }
4614
4615 int
getArgusMajorVersion(struct ArgusModelerStruct * model)4616 getArgusMajorVersion(struct ArgusModelerStruct *model) {
4617 return (model->ArgusMajorVersion);
4618 }
4619
4620 void
setArgusMajorVersion(struct ArgusModelerStruct * model,int value)4621 setArgusMajorVersion(struct ArgusModelerStruct *model, int value)
4622 {
4623 model->ArgusMajorVersion = value;
4624 }
4625
4626 int
getArgusMinorVersion(struct ArgusModelerStruct * model)4627 getArgusMinorVersion(struct ArgusModelerStruct *model) {
4628 return (model->ArgusMinorVersion);
4629 }
4630
4631 void
setArgusMinorVersion(struct ArgusModelerStruct * model,int value)4632 setArgusMinorVersion(struct ArgusModelerStruct *model, int value)
4633 {
4634 model->ArgusMinorVersion = value;
4635 }
4636
4637 struct timeval *
getArgusFarReportInterval(struct ArgusModelerStruct * model)4638 getArgusFarReportInterval(struct ArgusModelerStruct *model) {
4639 return (&model->ArgusFarReportInterval);
4640 }
4641
4642 unsigned int
getArgusLocalNet(struct ArgusModelerStruct * model)4643 getArgusLocalNet(struct ArgusModelerStruct *model) {
4644 return (model->ArgusLocalNet);
4645 }
4646
4647 unsigned int
getArgusNetMask(struct ArgusModelerStruct * model)4648 getArgusNetMask(struct ArgusModelerStruct *model) {
4649 return (model->ArgusNetMask);
4650 }
4651
4652 void
setArgusLocalNet(struct ArgusModelerStruct * model,unsigned int value)4653 setArgusLocalNet(struct ArgusModelerStruct *model, unsigned int value)
4654 {
4655 model->ArgusLocalNet = value;
4656 }
4657
4658 int
getArgusResponseStatus(struct ArgusModelerStruct * model)4659 getArgusResponseStatus(struct ArgusModelerStruct *model) {
4660 return (model->ArgusResponseStatus);
4661 }
4662
4663 void
setArgusResponseStatus(struct ArgusModelerStruct * model,int value)4664 setArgusResponseStatus(struct ArgusModelerStruct *model, int value)
4665 {
4666 model->ArgusResponseStatus = value;
4667 }
4668
4669 int
getArgusIpTimeout(struct ArgusModelerStruct * model)4670 getArgusIpTimeout(struct ArgusModelerStruct *model) {
4671 return (model->ArgusIPTimeout);
4672 }
4673
4674 int
getArgusTcpTimeout(struct ArgusModelerStruct * model)4675 getArgusTcpTimeout(struct ArgusModelerStruct *model) {
4676 return (model->ArgusTCPTimeout);
4677 }
4678
4679 int
getArgusIcmpTimeout(struct ArgusModelerStruct * model)4680 getArgusIcmpTimeout(struct ArgusModelerStruct *model) {
4681 return (model->ArgusICMPTimeout);
4682 }
4683
4684 int
getArgusIgmpTimeout(struct ArgusModelerStruct * model)4685 getArgusIgmpTimeout(struct ArgusModelerStruct *model) {
4686 return (model->ArgusIGMPTimeout);
4687 }
4688
4689 int
getArgusFragTimeout(struct ArgusModelerStruct * model)4690 getArgusFragTimeout(struct ArgusModelerStruct *model) {
4691 return (model->ArgusFRAGTimeout);
4692 }
4693
4694 int
getArgusArpTimeout(struct ArgusModelerStruct * model)4695 getArgusArpTimeout(struct ArgusModelerStruct *model) {
4696 return (model->ArgusFRAGTimeout);
4697 }
4698
4699 int
getArgusOtherTimeout(struct ArgusModelerStruct * model)4700 getArgusOtherTimeout(struct ArgusModelerStruct *model) {
4701 return (model->ArgusFRAGTimeout);
4702 }
4703
4704
4705
4706 struct timeval *
getArgusQueueInterval(struct ArgusModelerStruct * model)4707 getArgusQueueInterval(struct ArgusModelerStruct *model) {
4708 return (&model->ArgusQueueInterval);
4709 }
4710
4711 struct timeval *
getArgusListenInterval(struct ArgusModelerStruct * model)4712 getArgusListenInterval(struct ArgusModelerStruct *model) {
4713 return (&model->ArgusListenInterval);
4714 }
4715
4716
4717 #include <string.h>
4718 #include <ctype.h>
4719 #include <math.h>
4720
4721 void
setArgusFarReportInterval(struct ArgusModelerStruct * model,char * value)4722 setArgusFarReportInterval (struct ArgusModelerStruct *model, char *value)
4723 {
4724 float fvalue;
4725 char *ptr;
4726 int i = *value;
4727
4728 if (((ptr = strchr(value, '.')) != NULL) || isdigit(i)) {
4729 int ivalue = 0;
4730
4731 if (ptr != NULL) {
4732 fvalue = atof(value);
4733 model->ArgusFarReportInterval.tv_sec = floorf(fvalue);
4734 model->ArgusFarReportInterval.tv_usec = fabs(remainderf(fvalue, 1.0) * 1000000);
4735
4736 } else {
4737 if (isdigit(i)) {
4738 ivalue = atoi(value);
4739 model->ArgusFarReportInterval.tv_sec = ivalue;
4740 }
4741 }
4742 }
4743 }
4744
4745 int
getArgusAflag(struct ArgusModelerStruct * model)4746 getArgusAflag (struct ArgusModelerStruct *model)
4747 {
4748 return (model->ArgusAflag);
4749 }
4750
4751 void
setArgusAflag(struct ArgusModelerStruct * model,int value)4752 setArgusAflag(struct ArgusModelerStruct *model, int value)
4753 {
4754 model->ArgusAflag = value;
4755 }
4756
4757 int
getArgusTCPflag(struct ArgusModelerStruct * model)4758 getArgusTCPflag(struct ArgusModelerStruct *model) {
4759 return (model->ArgusTCPflag);
4760 }
4761
4762 void
setArgusTCPflag(struct ArgusModelerStruct * model,int value)4763 setArgusTCPflag(struct ArgusModelerStruct *model, int value)
4764 {
4765 model->ArgusTCPflag = value;
4766 }
4767
4768
4769 int
getArgusdflag(struct ArgusModelerStruct * model)4770 getArgusdflag(struct ArgusModelerStruct *model) {
4771 return (Argusdflag);
4772 }
4773
4774 void
setArgusdflag(struct ArgusModelerStruct * model,int value)4775 setArgusdflag(struct ArgusModelerStruct *model, int value)
4776 {
4777 if (Argusdflag && !(value)) {
4778 }
4779
4780 if (value) {
4781 }
4782
4783 Argusdflag = value;
4784 }
4785
4786 void
setArgusLink(struct ArgusModelerStruct * model,unsigned int value)4787 setArgusLink(struct ArgusModelerStruct *model, unsigned int value)
4788 {
4789 model->ArgusLink = value;
4790 }
4791
4792 void
setArgusNetMask(struct ArgusModelerStruct * model,unsigned int value)4793 setArgusNetMask(struct ArgusModelerStruct *model, unsigned int value)
4794 {
4795 model->ArgusNetMask = value;
4796 }
4797
4798 void
setArgusTimeReport(struct ArgusModelerStruct * model,int value)4799 setArgusTimeReport(struct ArgusModelerStruct *model, int value)
4800 {
4801 model->ArgusReportAllTime = value;
4802 }
4803
4804