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 *)&ether_type)[0] = ((unsigned char *)&llc->ethertype)[0];
1080                ((unsigned char *)&ether_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 *)&ether_type)[0] = ((unsigned char *)&llc->ethertype)[0];
1196             ((unsigned char *)&ether_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