1 /*
2 * Argus Software. Argus files - Utilities
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 */
21
22 /*
23 * $Id: //depot/argus/argus/argus/ArgusUtil.c#88 $
24 * $DateTime: 2015/08/06 16:35:55 $
25 * $Change: 3044 $
26 */
27
28 /* ArgusUtil.c */
29
30 #ifdef HAVE_CONFIG_H
31 #include "argus_config.h"
32 #endif
33
34 #define _GNU_SOURCE
35
36 #if !defined(ArgusUtil)
37 #define ArgusUtil
38 #endif
39
40 #include <stdlib.h>
41 #include <inttypes.h>
42 #include <stdio.h>
43 #include <math.h>
44
45 #if defined(HAVE_SYS_VFS_H)
46 #include <sys/vfs.h>
47 #else
48 #include <sys/param.h>
49 #include <sys/mount.h>
50 #endif
51
52
53 #if defined(ARGUS_THREADS)
54 #include <pthread.h>
55 #endif
56
57 #if defined(ARGUS_SASL)
58 #include <sasl/sasl.h>
59 #endif
60
61 #define Argus_Parser
62
63 #include <argus_compat.h>
64 #include <argus_parser.h>
65
66 #include <ArgusModeler.h>
67 #include <argus_dscodepoints.h>
68 #include <argus_encapsulations.h>
69
70
71 long long
ArgusTimeDiff(struct timeval * start,struct timeval * stop)72 ArgusTimeDiff (struct timeval *start, struct timeval *stop)
73 {
74 long long retn, stime, etime;
75
76 stime = (start->tv_sec * 1000000LL) + start->tv_usec;
77 etime = (stop->tv_sec * 1000000LL) + stop->tv_usec;
78
79 retn = stime - etime;
80 return (retn);
81 }
82
83 unsigned long long
ArgusAbsTimeDiff(struct timeval * start,struct timeval * stop)84 ArgusAbsTimeDiff (struct timeval *start, struct timeval *stop)
85 {
86 unsigned long long retn = 0;
87 struct timeval *t1 = start, *t2 = stop;
88
89 if ((stop->tv_sec < start->tv_sec) || ((stop->tv_sec == start->tv_sec) &&
90 (stop->tv_usec < start->tv_usec))) {
91 t2 = start;
92 t1 = stop;
93 }
94
95 retn = ((t2->tv_sec * 1000000LL) + t2->tv_usec) -
96 ((t1->tv_sec * 1000000LL) + t1->tv_usec);
97
98 return (retn);
99 }
100
101
102 struct ArgusListStruct *
ArgusNewList()103 ArgusNewList ()
104 {
105 struct ArgusListStruct *retn = NULL;
106
107 if ((retn = (struct ArgusListStruct *) ArgusCalloc (1, sizeof (struct ArgusListStruct))) != NULL) {
108 retn->start = NULL;
109 retn->count = 0;
110 #if defined(ARGUS_THREADS)
111 pthread_mutex_init(&retn->lock, NULL);
112 pthread_cond_init(&retn->cond, NULL);
113 #endif
114 }
115
116 #ifdef ARGUSDEBUG
117 ArgusDebug (4, "ArgusNewList () returning %p\n", retn);
118 #endif
119 return (retn);
120 }
121
122 void
ArgusDeleteList(struct ArgusListStruct * list,int type)123 ArgusDeleteList (struct ArgusListStruct *list, int type)
124 {
125 if (list) {
126 #ifdef ARGUSDEBUG
127 ArgusDebug (4, "ArgusDeleteList (%p, %d) %d items on list\n", list, type, list->count);
128 #endif
129 while (list->start) {
130 struct ArgusListRecord *retn = ArgusPopFrontList(list, ARGUS_LOCK);
131 switch (type) {
132 case ARGUS_RFILE_LIST: {
133 struct ArgusRfileStruct *rfile = (struct ArgusRfileStruct *) retn;
134 if (rfile->name != NULL)
135 free(rfile->name);
136 ArgusFree(retn);
137 break;
138 }
139
140 case ARGUS_WFILE_LIST: {
141 struct ArgusWfileStruct *wfile = (struct ArgusWfileStruct *) retn;
142 if (wfile->filename != NULL)
143 free(wfile->filename);
144 if (wfile->filter != NULL)
145 free(wfile->filter);
146 ArgusFree(retn);
147 break;
148 }
149
150 case ARGUS_DEVICE_LIST: {
151 struct ArgusDeviceStruct *device = (struct ArgusDeviceStruct *) retn;
152 if (device->name != NULL)
153 free(device->name);
154 ArgusFree(retn);
155 break;
156 }
157
158 case ARGUS_OUTPUT_LIST:
159 ArgusFreeListRecord(retn);
160 break;
161
162 case ARGUS_EVENT_LIST: {
163 struct ArgusListObjectStruct *lobj = (struct ArgusListObjectStruct *) retn;
164 if (lobj->obj != NULL) {
165 ArgusFree(lobj);
166 }
167 ArgusFree(retn);
168 break;
169 }
170
171 case ARGUS_BIND_ADDR_LIST: {
172 struct ArgusBindAddrStruct *baddr = (struct ArgusBindAddrStruct *) retn;
173 if (baddr->addr != NULL) {
174 free(baddr->addr);
175 }
176 ArgusFree(retn);
177 break;
178 }
179 }
180 }
181 #if defined(ARGUS_THREADS)
182 pthread_cond_destroy(&list->cond);
183 pthread_mutex_destroy(&list->lock);
184 #endif
185 ArgusFree (list);
186 }
187
188 #ifdef ARGUSDEBUG
189 ArgusDebug (4, "ArgusDeleteList (%p, %d) returning\n", list, type);
190 #endif
191 }
192
193 int
ArgusListEmpty(struct ArgusListStruct * list)194 ArgusListEmpty (struct ArgusListStruct *list)
195 {
196 return (list->count == 0);
197 }
198
199 int
ArgusGetListCount(struct ArgusListStruct * list)200 ArgusGetListCount(struct ArgusListStruct *list)
201 {
202 return (list->count);
203 }
204
205
206 int
ArgusPushFrontList(struct ArgusListStruct * list,struct ArgusListRecord * rec,int lstat)207 ArgusPushFrontList(struct ArgusListStruct *list, struct ArgusListRecord *rec, int lstat)
208 {
209 int retn = 0;
210
211 if (list && rec) {
212 #if defined(ARGUS_THREADS)
213 if (lstat)
214 pthread_mutex_lock(&list->lock);
215 #endif
216 if (list->start) {
217 rec->nxt = list->start;
218 } else {
219 rec->nxt = NULL;
220 }
221 list->start = (struct ArgusListObjectStruct *) rec;
222 if (list->end == NULL)
223 list->end = (struct ArgusListObjectStruct *) rec;
224 list->count++;
225 list->pushed++;
226 #if defined(ARGUS_THREADS)
227 if (lstat)
228 pthread_mutex_unlock(&list->lock);
229 #endif
230 retn++;
231 }
232
233 #ifdef ARGUSDEBUG
234 ArgusDebug (6, "ArgusPushFrontList (%p, %p, %d) returning %p\n", list, rec, lstat);
235 #endif
236
237 return (retn);
238 }
239
240 int
ArgusPushBackList(struct ArgusListStruct * list,struct ArgusListRecord * rec,int lstat)241 ArgusPushBackList(struct ArgusListStruct *list, struct ArgusListRecord *rec, int lstat)
242 {
243 int retn = 0;
244
245 if (list && rec) {
246 rec->nxt = NULL;
247
248 #if defined(ARGUS_THREADS)
249 if (lstat)
250 pthread_mutex_lock(&list->lock);
251 #endif
252 if (list->end) {
253 list->end->nxt = (struct ArgusListObjectStruct *) rec;
254 } else {
255 list->start = (struct ArgusListObjectStruct *) rec;
256 }
257 list->end = (struct ArgusListObjectStruct *) rec;
258 list->count++;
259 list->pushed++;
260 #if defined(ARGUS_THREADS)
261 if (lstat)
262 pthread_mutex_unlock(&list->lock);
263 #endif
264 retn++;
265 }
266
267 #ifdef ARGUSDEBUG
268 ArgusDebug (6, "ArgusPushBackList (%p, %p, %d) returning %d\n", list, rec, lstat, retn);
269 #endif
270
271 return (retn);
272 }
273
274
275 void
ArgusLoadList(struct ArgusListStruct * l1,struct ArgusListStruct * l2)276 ArgusLoadList(struct ArgusListStruct *l1, struct ArgusListStruct *l2)
277 {
278 if (l1 && l2) {
279 int count;
280 #if defined(ARGUS_THREADS)
281 pthread_mutex_lock(&l1->lock);
282 pthread_mutex_lock(&l2->lock);
283 #endif
284 count = l1->count;
285
286 if (l2->start == NULL)
287 l2->start = l1->start;
288 else
289 l2->end->nxt = l1->start;
290
291 l2->end = l1->end;
292 l2->count += count;
293
294 l1->start = NULL;
295 l1->end = NULL;
296 l1->loaded += count;
297 l1->count = 0;
298
299 #if defined(ARGUS_THREADS)
300 pthread_mutex_unlock(&l2->lock);
301 pthread_mutex_unlock(&l1->lock);
302 #endif
303
304 #ifdef ARGUSDEBUG
305 ArgusDebug (5, "ArgusLoadList (%p, %p) load %d objects\n", l1, l2, count);
306 #endif
307 }
308 }
309
310
311 struct ArgusListRecord *
ArgusPopFrontList(struct ArgusListStruct * list,int lstat)312 ArgusPopFrontList(struct ArgusListStruct *list, int lstat)
313 {
314 struct ArgusListRecord *retn = NULL;
315
316 #if defined(ARGUS_THREADS)
317 if (lstat)
318 pthread_mutex_lock(&list->lock);
319 #endif
320 if ((retn = (struct ArgusListRecord *) list->start)) {
321 list->start = retn->nxt;
322 list->count--;
323 list->popped++;
324 if (list->start == NULL) {
325 list->end = NULL;
326 if (list->count != 0)
327 ArgusLog (LOG_ERR, "ArgusPopFrontList(%p, %d) list empty count is %d\n", list, lstat, list->count);
328 }
329 }
330 #if defined(ARGUS_THREADS)
331 if (lstat)
332 pthread_mutex_unlock(&list->lock);
333 #endif
334
335 #ifdef ARGUSDEBUG
336 ArgusDebug (9, "ArgusPopFrontList (%p) returning\n", retn);
337 #endif
338
339 return (retn);
340 }
341
342
343 struct ArgusQueueStruct *
ArgusNewQueue()344 ArgusNewQueue ()
345 {
346 struct ArgusQueueStruct *retn = NULL;
347
348 if ((retn = (struct ArgusQueueStruct *) ArgusCalloc (1, sizeof (struct ArgusQueueStruct))) != NULL) {
349 retn->count = 0;
350 #if defined(ARGUS_THREADS)
351 pthread_mutex_init(&retn->lock, NULL);
352 #endif
353 retn->start = NULL;
354 retn->end = NULL;
355 }
356
357 #ifdef ARGUSDEBUG
358 ArgusDebug (4, "ArgusNewQueue () returning %p\n", retn);
359 #endif
360
361 return (retn);
362 }
363
364 void
ArgusDeleteQueue(struct ArgusQueueStruct * queue)365 ArgusDeleteQueue (struct ArgusQueueStruct *queue)
366 {
367 struct ArgusQueueHeader *obj = NULL;
368
369 if (queue != NULL) {
370 #if defined(ARGUS_THREADS)
371 pthread_mutex_lock(&queue->lock);
372 #endif
373
374 #ifdef ARGUSDEBUG
375 if (queue->count > 0)
376 ArgusDebug (1, "ArgusDeleteQueue (%p) contains %d items\n", queue, queue->count);
377 #endif
378 while ((obj = ArgusPopQueue(queue, ARGUS_LOCK)))
379 ArgusFree(obj);
380
381 if (queue->array != NULL) {
382 ArgusFree(queue->array);
383 queue->array = NULL;
384 }
385
386 #if defined(ARGUS_THREADS)
387 pthread_mutex_unlock(&queue->lock);
388 #endif
389
390 #if defined(ARGUS_THREADS)
391 pthread_mutex_destroy(&queue->lock);
392 #endif
393 ArgusFree(queue);
394 }
395
396 #ifdef ARGUSDEBUG
397 ArgusDebug (4, "ArgusDeleteQueue (%p) returning\n", queue);
398 #endif
399 }
400
401
402
403 int
ArgusGetQueueCount(struct ArgusQueueStruct * queue)404 ArgusGetQueueCount(struct ArgusQueueStruct *queue)
405 {
406
407 #ifdef ARGUSDEBUG
408 ArgusDebug (10, "ArgusGetQueueCount (%p) returning %d\n", queue, queue->count);
409 #endif
410
411 return (queue->count);
412 }
413
414
415 void
ArgusPushQueue(struct ArgusQueueStruct * queue,struct ArgusQueueHeader * obj,int type)416 ArgusPushQueue(struct ArgusQueueStruct *queue, struct ArgusQueueHeader *obj, int type)
417 {
418 #if defined(ARGUS_THREADS)
419 if (type == ARGUS_LOCK)
420 pthread_mutex_lock(&queue->lock);
421 #endif
422 if ((ArgusAddToQueue (queue, obj, ARGUS_NOLOCK)) > 0) {
423 queue->start = queue->start->prv;
424 queue->end = queue->start->prv;
425 }
426
427 #if defined(ARGUS_THREADS)
428 if (type == ARGUS_LOCK)
429 pthread_mutex_unlock(&queue->lock);
430 #endif
431
432 #ifdef ARGUSDEBUG
433 ArgusDebug (10, "ArgusPushQueue (%p, %p) returning\n", queue, obj);
434 #endif
435 }
436
437
438 int
ArgusAddToQueue(struct ArgusQueueStruct * queue,struct ArgusQueueHeader * obj,int type)439 ArgusAddToQueue(struct ArgusQueueStruct *queue, struct ArgusQueueHeader *obj, int type)
440 {
441 int retn = 0;
442
443 if (queue && obj) {
444 if (obj->queue == NULL) {
445 #if defined(ARGUS_THREADS)
446 if (type == ARGUS_LOCK)
447 pthread_mutex_lock(&queue->lock);
448 #endif
449 if (queue->start != NULL) {
450 obj->prv = queue->start->prv;
451 queue->start->prv = obj;
452 obj->nxt = queue->start;
453 obj->prv->nxt = obj;
454 } else {
455 queue->start = obj;
456 obj->nxt = obj;
457 obj->prv = obj;
458 }
459 queue->end = obj;
460 queue->count++;
461 #if defined(ARGUS_THREADS)
462 if (type == ARGUS_LOCK)
463 pthread_mutex_unlock(&queue->lock);
464 #endif
465 obj->queue = queue;
466
467 if (ArgusSourceTask->ArgusReadingOffLine)
468 obj->qtime = ArgusModel->ArgusGlobalTime;
469 else
470 gettimeofday(&obj->qtime, 0L);
471 retn = 1;
472
473 } else
474 ArgusLog (LOG_ERR, "ArgusAddToQueue (%p, %p) obj in queue %p\n", queue, obj, obj->queue);
475 } else
476 ArgusLog (LOG_ERR, "ArgusAddToQueue (%p, %p) parameter error\n", queue, obj);
477
478 #ifdef ARGUSDEBUG
479 ArgusDebug (10, "ArgusAddToQueue (%p, %p) returning %d\n", queue, obj, retn);
480 #endif
481
482 return (retn);
483 }
484
485
486 struct ArgusQueueHeader *
ArgusPopQueue(struct ArgusQueueStruct * queue,int type)487 ArgusPopQueue (struct ArgusQueueStruct *queue, int type)
488 {
489 struct ArgusQueueHeader *retn = NULL;
490 struct ArgusQueueHeader *obj = NULL;
491
492 if (queue && queue->count) {
493 #if defined(ARGUS_THREADS)
494 if (type == ARGUS_LOCK)
495 pthread_mutex_lock(&queue->lock);
496 #endif
497 if ((obj = (struct ArgusQueueHeader *) queue->start) != NULL) {
498 queue->count--;
499
500 if (queue->count) {
501 if (queue->start == obj)
502 queue->start = obj->nxt;
503
504 obj->prv->nxt = obj->nxt;
505 obj->nxt->prv = obj->prv;
506
507 queue->end = queue->start->prv;
508
509 } else {
510 queue->start = NULL;
511 queue->end = NULL;
512 }
513 }
514 #if defined(ARGUS_THREADS)
515 if (type == ARGUS_LOCK)
516 pthread_mutex_unlock(&queue->lock);
517 #endif
518
519 if (obj != NULL) {
520 obj->prv = NULL;
521 obj->nxt = NULL;
522 obj->queue = NULL;
523 retn = obj;
524 }
525 }
526
527 #ifdef ARGUSDEBUG
528 ArgusDebug (10, "ArgusPopQueue (%p) returning %p\n", queue, retn);
529 #endif
530
531 return(retn);
532 }
533
534 struct ArgusQueueHeader *
ArgusPopBackQueue(struct ArgusQueueStruct * queue,int type)535 ArgusPopBackQueue (struct ArgusQueueStruct *queue, int type)
536 {
537 struct ArgusQueueHeader *retn = NULL;
538 struct ArgusQueueHeader *obj = NULL;
539
540 if (queue && queue->count) {
541 #if defined(ARGUS_THREADS)
542 if (type == ARGUS_LOCK)
543 pthread_mutex_lock(&queue->lock);
544 #endif
545 if ((obj = (struct ArgusQueueHeader *) queue->end) != NULL) {
546 queue->count--;
547
548 if (queue->count) {
549 if (queue->start == obj)
550 queue->start = obj->nxt;
551
552 obj->prv->nxt = obj->nxt;
553 obj->nxt->prv = obj->prv;
554
555 queue->end = queue->start->prv;
556
557 } else {
558 queue->start = NULL;
559 queue->end = NULL;
560 }
561 }
562 #if defined(ARGUS_THREADS)
563 if (type == ARGUS_LOCK)
564 pthread_mutex_unlock(&queue->lock);
565 #endif
566
567 if (obj != NULL) {
568 obj->prv = NULL;
569 obj->nxt = NULL;
570 obj->queue = NULL;
571 retn = obj;
572 }
573 }
574
575 #ifdef ARGUSDEBUG
576 ArgusDebug (10, "ArgusPopBackQueue (%p) returning %p\n", queue, retn);
577 #endif
578
579 return(retn);
580 }
581
582
583 struct ArgusQueueHeader *
ArgusRemoveFromQueue(struct ArgusQueueStruct * queue,struct ArgusQueueHeader * obj,int type)584 ArgusRemoveFromQueue(struct ArgusQueueStruct *queue, struct ArgusQueueHeader *obj, int type)
585 {
586 struct ArgusQueueHeader *retn = NULL;
587
588 if ((queue != NULL) && (obj != NULL)) {
589 #if defined(ARGUS_THREADS)
590 if (type == ARGUS_LOCK)
591 pthread_mutex_lock(&queue->lock);
592 #endif
593 if (obj->queue == queue) {
594 if (queue->count) {
595 queue->count--;
596
597 if (queue->count) {
598 if (queue->start == obj)
599 queue->start = obj->nxt;
600
601 obj->prv->nxt = obj->nxt;
602 obj->nxt->prv = obj->prv;
603
604 queue->end = queue->start->prv;
605
606 } else {
607 queue->start = NULL;
608 queue->end = NULL;
609 }
610 }
611 obj->prv = NULL;
612 obj->nxt = NULL;
613 obj->queue = NULL;
614 retn = obj;
615 }
616
617 #if defined(ARGUS_THREADS)
618 if (type == ARGUS_LOCK)
619 pthread_mutex_unlock(&queue->lock);
620 #endif
621 }
622
623 #ifdef ARGUSDEBUG
624 ArgusDebug (10, "ArgusRemoveFromQueue (%p, %p) returning %p\n", queue, obj, obj);
625 #endif
626
627 return (retn);
628 }
629
630 #include <stdio.h>
631 #include <errno.h>
632
633
634 void
ArgusProcessQueue(struct ArgusModelerStruct * model,struct ArgusQueueStruct * queue,int status)635 ArgusProcessQueue(struct ArgusModelerStruct *model, struct ArgusQueueStruct *queue, int status)
636 {
637 struct ArgusFlowStruct *obj = NULL;
638
639 switch (status) {
640 case ARGUS_STOP:
641 case ARGUS_SHUTDOWN:
642 #ifdef ARGUSDEBUG
643 ArgusDebug (3, "ArgusProcessQueue (%p, %d) Shuting Down with %d records\n", queue, status, queue->count);
644 #endif
645 while (queue->count) {
646 if ((obj = (struct ArgusFlowStruct *) ArgusPopBackQueue(queue, ARGUS_LOCK)) != NULL) {
647 if (!(obj->status & ARGUS_RECORD_WRITTEN))
648 ArgusSendFlowRecord(model, obj, status);
649 ArgusDeleteObject (obj);
650 }
651 }
652 break;
653 }
654
655 #ifdef ARGUSDEBUG
656 ArgusDebug (8, "ArgusProcessQueue (%p, %d) returning\n", queue, status);
657 #endif
658 }
659
660
661 int
ArgusCheckTimeout(struct ArgusModelerStruct * model,struct timeval * ts,struct timeval * timeout)662 ArgusCheckTimeout(struct ArgusModelerStruct *model, struct timeval *ts, struct timeval *timeout)
663 {
664 long long diff = 0, tdiff = 0;
665 int retn;
666
667 if (timeout->tv_sec < 0) // if timeout is set to less that zero, then we never timeout.
668 retn = 0;
669 else {
670 if ((timeout->tv_sec > 0) || (timeout->tv_usec > 0)) {
671 diff = ArgusTimeDiff (&model->ArgusGlobalTime, ts);
672 tdiff = (timeout->tv_sec * 1000000LL + timeout->tv_usec);
673
674 if (diff >= tdiff)
675 retn = 1;
676 else
677 retn = 0;
678 } else
679 retn = 1;
680 }
681
682 #ifdef ARGUSDEBUG
683 ArgusDebug (11, "ArgusCheckTimeout (%p, %d.%06d, %d.%06d) diff %f returning %d\n", model, ts->tv_sec, ts->tv_usec,
684 timeout->tv_sec, timeout->tv_usec, (diff / 1000000.0), retn);
685 #endif
686
687 return (retn);
688 }
689
690
691
692 void
ArgusDeleteObject(struct ArgusFlowStruct * obj)693 ArgusDeleteObject(struct ArgusFlowStruct *obj)
694 {
695 if (obj) {
696 struct ArgusHashTableHeader *htblhdr;
697 struct ArgusNetworkStruct *net = NULL;
698 struct ArgusQueueStruct *queue;
699
700 if ((queue = obj->qhdr.queue) != NULL) {
701 if (ArgusRemoveFromQueue (queue, &obj->qhdr, ARGUS_LOCK)) {
702 obj->qhdr.queue = NULL;
703 } else
704 ArgusLog (LOG_ERR, "ArgusDeleteObject: race condition on queue %p\n", queue);
705 }
706
707 if ((htblhdr = obj->htblhdr) != NULL) {
708 ArgusRemoveHashEntry(htblhdr);
709 obj->htblhdr = NULL;
710 }
711
712 if ((net = (struct ArgusNetworkStruct *) obj->dsrs[ARGUS_FRAG_INDEX]) != NULL) {
713 if (net->hdr.subtype == ARGUS_NETWORK_SUBTYPE_FRAG) {
714 struct ArgusFragObject *frag = &net->net_union.frag;
715 struct ArgusFragOffsetStruct *fragOffset = frag->offsets.nxt;
716
717 while ((fragOffset = frag->offsets.nxt) != NULL) {
718 frag->offsets.nxt = fragOffset->nxt;
719 free(fragOffset);
720 }
721 net->hdr.type = 0;
722 }
723 }
724
725 if (obj->dsrs[ARGUS_SRCUSERDATA_INDEX] != NULL) {
726 ArgusFree(obj->dsrs[ARGUS_SRCUSERDATA_INDEX]);
727 obj->dsrs[ARGUS_SRCUSERDATA_INDEX] = NULL;
728 }
729
730 if (obj->dsrs[ARGUS_DSTUSERDATA_INDEX] != NULL) {
731 ArgusFree(obj->dsrs[ARGUS_DSTUSERDATA_INDEX]);
732 obj->dsrs[ARGUS_DSTUSERDATA_INDEX] = NULL;
733 }
734
735 if (obj->frag.start != NULL) {
736 struct ArgusFlowStruct *frag;
737
738 while ((frag = (void *) ArgusPopQueue(&obj->frag, ARGUS_LOCK))) {
739 ArgusSendFlowRecord(ArgusModel, frag, ARGUS_TIMEOUT);
740 ArgusDeleteObject(frag);
741 }
742 }
743
744 ArgusFree(obj);
745 ArgusModel->ArgusTotalClosedFlows++;
746 }
747
748 #ifdef ARGUSDEBUG
749 ArgusDebug (4, "ArgusDeleteObject (%p) returning\n", obj);
750 #endif
751 }
752
753
754 int
ArgusUpdateTime(struct ArgusModelerStruct * model)755 ArgusUpdateTime (struct ArgusModelerStruct *model)
756 {
757 long long ival = model->ival;
758 long long diff;
759 int retn = 0;
760
761 if (model->ArgusUpdateTimer.tv_sec == 0)
762 model->ArgusUpdateTimer = model->ArgusGlobalTime;
763
764 diff = ArgusTimeDiff(&model->ArgusGlobalTime, &model->ArgusUpdateTimer);
765
766 if (diff >= 0) {
767 retn = 1;
768
769 if (diff > ival)
770 model->ArgusUpdateTimer = model->ArgusGlobalTime;
771
772 model->ArgusUpdateTimer.tv_sec += model->ArgusUpdateInterval.tv_sec;
773 model->ArgusUpdateTimer.tv_usec += model->ArgusUpdateInterval.tv_usec;
774
775 while (model->ArgusUpdateTimer.tv_usec >= 1000000) {
776 model->ArgusUpdateTimer.tv_sec++;
777 model->ArgusUpdateTimer.tv_usec -= 1000000;
778 }
779
780 } else {
781
782 if (ArgusSourceTask != NULL) {
783 if (!(ArgusSourceTask->ArgusReadingOffLine)) {
784 if (llabs(diff) > (ival * 2)) {
785
786 // something is wrong, so try to figure out if ArgusGlobalTime needs to be adjusted.
787 // Must be kernel time bug, so try to reset the ArgusUpdateTimer, and declare
788 // that the timer has popped. Redefine global timer if needed.
789
790 unsigned long long tdiff;
791 struct timeval now;
792
793 retn = 1;
794
795 gettimeofday(&now, 0L);
796 tdiff = ArgusAbsTimeDiff(&now, &model->ArgusGlobalTime);
797
798 if (tdiff > (ival * 2))
799 model->ArgusGlobalTime = now;
800
801 model->ArgusUpdateTimer = model->ArgusGlobalTime;
802
803 model->ArgusUpdateTimer.tv_sec += model->ArgusUpdateInterval.tv_sec;
804 model->ArgusUpdateTimer.tv_usec += model->ArgusUpdateInterval.tv_usec;
805
806 while (model->ArgusUpdateTimer.tv_usec >= 1000000) {
807 model->ArgusUpdateTimer.tv_sec++;
808 model->ArgusUpdateTimer.tv_usec -= 1000000;
809 }
810 }
811 }
812 }
813 }
814
815 #ifdef ARGUSDEBUG
816 if (retn) {
817 ArgusDebug (8, "ArgusUpdateTime (%p) global time %d.%06d update %d.%06d returning %d\n",
818 model, model->ArgusGlobalTime.tv_sec, model->ArgusGlobalTime.tv_usec,
819 model->ArgusUpdateTimer.tv_sec, model->ArgusUpdateTimer.tv_usec, retn);
820 } else
821 ArgusDebug (8, "ArgusUpdateTime (%p) not time\n", model);
822 #endif
823
824 return (retn);
825 }
826
827 struct ArgusHashStats {
828 int n, max;
829 };
830
831 struct ArgusHashTable *ArgusNewHashTable (size_t, int);
832 struct ArgusHashStats *ArgusHashTableStats = NULL;
833 int ArgusHashTableMax = 0;
834 void ArgusEmptyHashTable (struct ArgusHashTable *);
835 void ArgusDeleteHashTable (struct ArgusHashTable *);
836
837 struct ArgusHashTable *
ArgusNewHashTable(size_t size,int status)838 ArgusNewHashTable (size_t size, int status)
839 {
840 struct ArgusHashTable *retn = NULL;
841
842 if ((retn = (struct ArgusHashTable *) ArgusCalloc (1, sizeof(*retn))) == NULL)
843 ArgusLog (LOG_ERR, "ArgusNewHashTable: ArgusCalloc(1, %d) error %s\n", size, strerror(errno));
844
845 if ((retn->array = (struct ArgusHashTableHeader **) ArgusCalloc (size,
846 sizeof (struct ArgusHashTableHeader *))) == NULL)
847 ArgusLog (LOG_ERR, "RaMergeQueue: ArgusCalloc error %s\n", strerror(errno));
848
849 retn->size = size;
850 #if defined(ARGUS_HASH_DEBUG)
851 if ((retn->status = status) == ARGUSHASHTABLETRACK) {
852 if (ArgusHashTableStats == NULL) {
853 if ((ArgusHashTableStats = (struct ArgusHashStats *) ArgusCalloc (size, sizeof(struct ArgusHashStats))) == NULL)
854 ArgusLog (LOG_ERR, "ArgusHashTableStats: ArgusCalloc(%d, %d) error %s\n",
855 size, sizeof(struct ArgusStatsObject), strerror(errno));
856 }
857 }
858 #endif
859 #if defined(ARGUS_THREADS)
860 pthread_mutex_init(&retn->lock, NULL);
861 #endif
862
863 #ifdef ARGUSDEBUG
864 ArgusDebug (4, "ArgusNewHashTable (%d) returning %p\n", size, retn);
865 #endif
866
867 return (retn);
868 }
869
870 void
ArgusDeleteHashTable(struct ArgusHashTable * htbl)871 ArgusDeleteHashTable (struct ArgusHashTable *htbl)
872 {
873
874 if (htbl != NULL) {
875 ArgusEmptyHashTable (htbl);
876
877 if (htbl->array != NULL)
878 ArgusFree(htbl->array);
879
880 ArgusFree(htbl);
881 }
882
883 #ifdef ARGUSDEBUG
884 ArgusDebug (4, "ArgusDeleteHashTable (%p)\n", htbl);
885 #endif
886 }
887
888 void
ArgusEmptyHashTable(struct ArgusHashTable * htbl)889 ArgusEmptyHashTable (struct ArgusHashTable *htbl)
890 {
891 struct ArgusHashTableHeader *htblhdr = NULL, *tmp;
892 int i, count = 0, bins = 0;
893
894 #if defined(ARGUS_THREADS)
895 pthread_mutex_lock(&htbl->lock);
896 #endif
897 for (i = 0; i < htbl->size; i++) {
898 if ((htblhdr = htbl->array[i]) != NULL) {
899 htblhdr->prv->nxt = NULL;
900 while ((tmp = htblhdr) != NULL) {
901 htblhdr = htblhdr->nxt;
902 ArgusFree (tmp);
903 htbl->items--;
904 count++;
905 }
906 htbl->array[i] = NULL;
907 htbl->bins--;
908 bins++;
909 }
910 }
911
912
913 #if defined(ARGUS_THREADS)
914 pthread_mutex_unlock(&htbl->lock);
915 #endif
916
917 #ifdef ARGUSDEBUG
918 ArgusDebug (6, "ArgusEmptyHashTable (%p) cleared %d bins %d items\n", htbl, bins, count);
919 #endif
920 }
921
922
923 int
ArgusCreateFlowKey(struct ArgusModelerStruct * model,struct ArgusSystemFlow * flow,struct ArgusHashStruct * hstruct)924 ArgusCreateFlowKey (struct ArgusModelerStruct *model, struct ArgusSystemFlow *flow, struct ArgusHashStruct *hstruct)
925 {
926 unsigned int *ptr = (unsigned int *)&flow->flow_un;
927 unsigned int *key = (unsigned int *) hstruct->key;
928 int retn = 0, i, len = flow->hdr.argus_dsrvl8.len - 1;
929
930 memset (hstruct, 0, sizeof(*hstruct));
931
932 if (len > 0) {
933 for (i = 0; i < len; i++)
934 *key++ = *ptr++;
935
936 hstruct->len = len;
937
938 if (model->ArgusFlowKey & ARGUS_FLOW_KEY_VLAN) {
939 *key++ = model->ArgusThisPacket8021QEncaps & 0x0FFF;
940 hstruct->len++;
941 }
942
943 if (model->ArgusFlowKey & (ARGUS_FLOW_KEY_LOCAL_MPLS | ARGUS_FLOW_KEY_COMPLETE_MPLS)) {
944 *key++ = model->ArgusThisMplsLabel;
945 hstruct->len++;
946 }
947
948 if (model->ArgusFlowKey & (ARGUS_FLOW_KEY_LAYER_2 | ARGUS_FLOW_KEY_LAYER_2_MATRIX)) {
949 struct ether_header *ep = model->ArgusThisEpHdr;
950 if (ep) {
951 int klen = (sizeof(*ep) + (sizeof(*key) - 1)) / sizeof(*key);
952 if (model->state & ARGUS_DIRECTION) {
953 #ifndef ETH_ALEN
954 #define ETH_ALEN 6
955 #endif
956 char *kptr = (char *) key;
957 bcopy ((char *)&ep->ether_shost, kptr, ETH_ALEN); kptr += ETH_ALEN;
958 bcopy ((char *)&ep->ether_dhost, kptr, ETH_ALEN); kptr += ETH_ALEN;
959 bcopy ((char *)&ep->ether_type, kptr, sizeof(ep->ether_type));
960
961 } else
962 bcopy (ep, key, sizeof(*ep));
963
964 key += klen;
965 hstruct->len += klen;
966 }
967 }
968
969 ptr = hstruct->key;
970
971 for (i = 0; i < hstruct->len; i++)
972 hstruct->hash ^= *ptr++;
973
974 hstruct->hash ^= hstruct->hash >> 16;
975 hstruct->hash ^= hstruct->hash >> 8;
976 }
977
978 return (retn);
979 }
980
981
982 struct ArgusFlowStruct *
ArgusFindFlow(struct ArgusModelerStruct * model,struct ArgusHashStruct * hstruct)983 ArgusFindFlow (struct ArgusModelerStruct *model, struct ArgusHashStruct *hstruct)
984 {
985 struct ArgusFlowStruct *retn = NULL;
986 struct ArgusHashTableHeader *hashEntry = NULL, *target, *head;
987 struct ArgusHashTable *table = model->ArgusHashTable;
988
989 if (table && hstruct) {
990 unsigned int hash = hstruct->hash;
991 unsigned int ind = (hash % (table->size - 1)), i;
992
993 if ((target = table->array[ind]) != NULL) {
994 unsigned int *ptr3 = hstruct->key;
995 int len = hstruct->len;
996 head = target;
997
998 do {
999 if ((target->hstruct.hash == hash) && (target->hstruct.len == hstruct->len)) {
1000 unsigned int *ptr1 = target->hstruct.key;
1001 unsigned int *ptr2 = ptr3;
1002
1003 if (len > 0) {
1004 for (i = 0; i < len; i++)
1005 if (*ptr1++ != *ptr2++)
1006 break;
1007 if (i == len) {
1008 hashEntry = target;
1009 break;
1010 }
1011
1012 } else
1013 hashEntry = target;
1014 }
1015
1016 target = target->nxt;
1017
1018 } while (target && (target != head) && (hashEntry == NULL));
1019
1020 if (hashEntry != NULL) {
1021 if (hashEntry != head)
1022 table->array[ind] = hashEntry;
1023 retn = hashEntry->object;
1024 }
1025 }
1026 }
1027
1028 #ifdef ARGUSDEBUG
1029 ArgusDebug (8, "ArgusFindFlow () returning %p\n", retn);
1030 #endif
1031
1032 return (retn);
1033 }
1034
1035 #define ARGUS_HASH_DEBUG 1
1036
1037 struct ArgusHashTableHeader *
ArgusAddHashEntry(struct ArgusHashTable * table,struct ArgusFlowStruct * flow,struct ArgusHashStruct * hstruct)1038 ArgusAddHashEntry (struct ArgusHashTable *table, struct ArgusFlowStruct *flow, struct ArgusHashStruct *hstruct)
1039 {
1040 struct ArgusHashTableHeader *retn = NULL, *start = NULL;
1041
1042 if (table != NULL) {
1043 unsigned int hash = hstruct->hash;
1044 int ind;
1045
1046 retn = &flow->htblbuf;
1047 memcpy(&retn->hstruct, hstruct, sizeof(*hstruct));
1048 retn->object = flow;
1049
1050 ind = (hash % (table->size - 1));
1051
1052 if ((start = table->array[ind]) != NULL) {
1053 retn->nxt = start;
1054 retn->prv = start->prv;
1055 retn->prv->nxt = retn;
1056 retn->nxt->prv = retn;
1057 } else {
1058 retn->prv = retn;
1059 retn->nxt = retn;
1060 table->bins++;
1061 }
1062 table->items++;
1063
1064 table->array[ind] = retn;
1065 retn->htbl = table;
1066 #if defined(ARGUS_HASH_DEBUG)
1067 if (table->status & ARGUSHASHTABLETRACK) {
1068 ArgusHashTableStats[ind].n++;
1069 if (ArgusHashTableStats[ind].max < ArgusHashTableStats[ind].n)
1070 ArgusHashTableStats[ind].max = ArgusHashTableStats[ind].n;
1071
1072 if (ArgusHashTableMax < ArgusHashTableStats[ind].n)
1073 ArgusHashTableMax = ArgusHashTableStats[ind].n;
1074 }
1075 #endif
1076 }
1077
1078 #ifdef ARGUSDEBUG
1079 ArgusDebug (6, "ArgusAddHashEntry (%p) returning %p\n", flow, retn);
1080 #endif
1081
1082 return (retn);
1083 }
1084
1085
1086 void
ArgusRemoveHashEntry(struct ArgusHashTableHeader * htblhdr)1087 ArgusRemoveHashEntry (struct ArgusHashTableHeader *htblhdr)
1088 {
1089 if (htblhdr != NULL) {
1090 unsigned int hash = htblhdr->hstruct.hash;
1091 struct ArgusHashTable *table = htblhdr->htbl;
1092
1093 if (table != NULL) {
1094 int ind = (hash % (table->size - 1));
1095
1096 htblhdr->prv->nxt = htblhdr->nxt;
1097 htblhdr->nxt->prv = htblhdr->prv;
1098
1099 if (htblhdr == table->array[ind]) {
1100 if (htblhdr == htblhdr->nxt) {
1101 table->array[ind] = NULL;
1102 table->bins--;
1103 } else
1104 table->array[ind] = htblhdr->nxt;
1105 }
1106
1107 table->items--;
1108
1109 #if defined(ARGUS_HASH_DEBUG)
1110 if (table->status & ARGUSHASHTABLETRACK)
1111 ArgusHashTableStats[ind].n--;
1112 #endif
1113 }
1114 }
1115
1116 #ifdef ARGUSDEBUG
1117 ArgusDebug (6, "ArgusRemoveHashEntry (%p) returning\n", htblhdr);
1118 #endif
1119 }
1120
1121
1122 void ArgusZeroRecord (struct ArgusFlowStruct *);
1123
1124 void
ArgusZeroRecord(struct ArgusFlowStruct * flow)1125 ArgusZeroRecord (struct ArgusFlowStruct *flow)
1126 {
1127 int i;
1128
1129 flow->status &= ~ARGUS_RECORD_WRITTEN;
1130 flow->status &= ~0xF0;
1131
1132 for (i = 0; i < ARGUSMAXDSRTYPE; i++) {
1133 if (flow->dsrs[i] != NULL) {
1134 switch (i) {
1135 default:
1136 flow->dsrs[i] = NULL;
1137 break;
1138
1139 case ARGUS_FLOW_INDEX: {
1140 struct ArgusFlow *tflow = (struct ArgusFlow *)flow->dsrs[i];
1141 tflow->hdr.argus_dsrvl8.qual &= ~ARGUS_FRAGMENT;
1142 break;
1143 }
1144
1145 case ARGUS_TRANSPORT_INDEX:
1146 case ARGUS_MAC_INDEX:
1147 break;
1148
1149 case ARGUS_JITTER_INDEX: {
1150 struct ArgusJitterStruct *jit = (void *)flow->dsrs[i];
1151 bzero ((char *)&jit->act, sizeof(struct ArgusJitterObject));
1152 bzero ((char *)&jit->idle, sizeof(struct ArgusJitterObject));
1153 jit->act.src.minval = -1.0;
1154 jit->idle.src.minval = -1.0;
1155 jit->act.dst.minval = -1.0;
1156 jit->idle.dst.minval = -1.0;
1157 break;
1158 }
1159
1160 case ARGUS_IPATTR_INDEX: {
1161 struct ArgusIPAttrStruct *attr = (void *)flow->dsrs[i];
1162 attr->hdr.argus_dsrvl8.qual &= ~(ARGUS_IPATTR_SRC_FRAGMENTS | ARGUS_IPATTR_DST_FRAGMENTS);
1163 attr->src.status = 0; attr->src.options = 0;
1164 attr->dst.status = 0; attr->dst.options = 0;
1165 break;
1166 }
1167
1168 case ARGUS_TIME_INDEX: {
1169 struct ArgusTimeObject *tim = (void *)flow->dsrs[i];
1170 bzero(&tim->src, sizeof(*tim) - 4);
1171 break;
1172 }
1173
1174 case ARGUS_METRIC_INDEX: {
1175 struct ArgusMetricStruct *metric = (void *) flow->dsrs[i];
1176 bzero((&metric->hdr + 1), sizeof(*metric) - 4);
1177 break;
1178 }
1179
1180 case ARGUS_NETWORK_INDEX: {
1181 struct ArgusNetworkStruct *net = NULL;
1182 if ((net = (struct ArgusNetworkStruct *) flow->dsrs[ARGUS_NETWORK_INDEX]) != NULL) {
1183
1184 switch (net->hdr.type) {
1185 case ARGUS_NETWORK_DSR: {
1186 switch (net->hdr.subtype) {
1187 case ARGUS_NETWORK_SUBTYPE_FRAG: {
1188 struct ArgusFragObject *frag = &net->net_union.frag;
1189 struct ArgusFragOffsetStruct *fragOffset = frag->offsets.nxt;
1190
1191 while ((fragOffset = frag->offsets.nxt) != NULL) {
1192 frag->offsets.nxt = fragOffset->nxt;
1193 free(fragOffset);
1194 }
1195 bzero((char *)frag, sizeof(struct ArgusFragObject));
1196 break;
1197 }
1198
1199 case ARGUS_TCP_INIT:
1200 case ARGUS_TCP_STATUS:
1201 case ARGUS_TCP_PERF: {
1202 struct ArgusTCPObject *tcp = &net->net_union.tcp;
1203 tcp->src.status &= ~(ARGUS_RESET|ARGUS_PKTS_RETRANS|ARGUS_WINDOW_SHUT|ARGUS_OUTOFORDER|ARGUS_ECN_CONGESTED);
1204 tcp->dst.status &= ~(ARGUS_RESET|ARGUS_PKTS_RETRANS|ARGUS_WINDOW_SHUT|ARGUS_OUTOFORDER|ARGUS_ECN_CONGESTED);
1205 tcp->src.retrans = 0;
1206 tcp->dst.retrans = 0;
1207 tcp->src.flags = 0;
1208 tcp->dst.flags = 0;
1209 tcp->src.bytes = 0;
1210 tcp->dst.bytes = 0;
1211 tcp->src.winbytes = 0;
1212 tcp->dst.winbytes = 0;
1213 tcp->src.ackbytes = 0;
1214 tcp->dst.ackbytes = 0;
1215 tcp->src.seqbase = tcp->src.seq;
1216 tcp->dst.seqbase = tcp->dst.seq;
1217 break;
1218 }
1219
1220 case ARGUS_RTP_FLOW: {
1221 struct ArgusRTPObject *rtp = &net->net_union.rtp;
1222 rtp->sdrop = 0;
1223 rtp->ddrop = 0;
1224 break;
1225 }
1226
1227 case ARGUS_ESP_DSR: {
1228 struct ArgusESPObject *esp = &net->net_union.esp;
1229 esp->status = 0;
1230 esp->lostseq = 0;
1231 break;
1232 }
1233 }
1234 break;
1235 }
1236 }
1237
1238 net->hdr.argus_dsrvl8.qual = 0;
1239 }
1240 break;
1241 }
1242
1243 case ARGUS_SRCUSERDATA_INDEX:
1244 case ARGUS_DSTUSERDATA_INDEX: {
1245 struct ArgusDataStruct *user = (struct ArgusDataStruct *) flow->dsrs[i];
1246 user->count = 0;
1247 memset (user->array, 0, user->size);
1248 break;
1249 }
1250 }
1251 }
1252 }
1253
1254 memset(&flow->stime.act, 0, sizeof(flow->stime.act));
1255 memset(&flow->stime.idle, 0, sizeof(flow->stime.idle));
1256 memset(&flow->dtime.act, 0, sizeof(flow->dtime.act));
1257 memset(&flow->dtime.idle, 0, sizeof(flow->dtime.idle));
1258
1259 flow->stime.act.minval = 0xffffffff;
1260 flow->stime.idle.minval = 0xffffffff;
1261 flow->dtime.act.minval = 0xffffffff;
1262 flow->dtime.idle.minval = 0xffffffff;
1263
1264 flow->sipid = 0;
1265 flow->dipid = 0;
1266 flow->skey.n_strokes = 0;
1267
1268 #ifdef ARGUSDEBUG
1269 ArgusDebug (8, "ArgusZeroRecord (%p) returning\n", flow);
1270 #endif
1271 }
1272
1273 /*
1274 struct ArgusSocketStruct {
1275 struct ArgusListStruct *ArgusSocketList;
1276 int fd, status, cnt, expectedSize, errornum;
1277 int ArgusLastRecord, ArgusReadState;
1278 struct timeval lastwrite;
1279 struct ArgusRecordStruct *rec;
1280 int length, writen;
1281 struct sockaddr sock;
1282 char *filename;
1283 void *obj;
1284 unsigned char *ptr, buf[ARGUS_MAXRECORD];
1285 };
1286 */
1287
1288 struct ArgusSocketStruct *
ArgusNewSocket(int fd)1289 ArgusNewSocket (int fd)
1290 {
1291 struct ArgusSocketStruct *retn = NULL;
1292 int flags;
1293
1294 if ((retn = ((struct ArgusSocketStruct *) ArgusCalloc (1, sizeof (struct ArgusSocketStruct)))) != NULL) {
1295 if ((retn->ArgusSocketList = ArgusNewList()) != NULL) {
1296 retn->fd = fd;
1297 flags = fcntl (fd, F_GETFL, 0);
1298 flags |= O_NONBLOCK;
1299 fcntl (fd, F_SETFL, flags);
1300 } else
1301 ArgusLog(LOG_ERR, "ArgusNewSocket: ArgusNewList failed %s", strerror(errno));
1302 } else
1303 ArgusLog(LOG_ERR, "ArgusNewSocket: ArgusCalloc failed %s", strerror(errno));
1304
1305 #ifdef ARGUSDEBUG
1306 ArgusDebug (2, "ArgusNewSocket (%d) returning %p\n", fd, retn);
1307 #endif
1308
1309 return (retn);
1310 }
1311
1312 void
ArgusDeleteSocket(struct ArgusOutputStruct * output,struct ArgusClientData * client)1313 ArgusDeleteSocket (struct ArgusOutputStruct *output, struct ArgusClientData *client)
1314 {
1315 struct ArgusSocketStruct *asock = client->sock;
1316
1317 if (asock != NULL) {
1318 struct ArgusListStruct *list = asock->ArgusSocketList;
1319
1320 while (!(ArgusListEmpty (list)))
1321 if (ArgusWriteOutSocket(output, client) < 0)
1322 break;
1323
1324 #ifdef ARGUSDEBUG
1325 if (!(ArgusListEmpty (list)))
1326 ArgusDebug(2, "ArgusDeleteSocket: list not empty");
1327 #endif
1328 ArgusDeleteList(asock->ArgusSocketList, ARGUS_OUTPUT_LIST);
1329
1330 close(asock->fd);
1331 asock->fd = -1;
1332
1333 if (asock->filename) {
1334 free(asock->filename);
1335 asock->filename = NULL;
1336 }
1337
1338 ArgusFree (asock);
1339 client->sock = NULL;
1340 client->fd = -1;
1341 }
1342
1343 #ifdef ARGUSDEBUG
1344 ArgusDebug (2, "ArgusDeleteSocket (%p) returning\n", asock);
1345 #endif
1346 }
1347
1348
1349 void
ArgusSetChroot(char * dir)1350 ArgusSetChroot(char *dir)
1351 {
1352 if (chdir(dir) < 0)
1353 ArgusLog(LOG_ERR, "ArgusSetChroot: failed to chdir to \"%s\": %s", dir, strerror(errno));
1354
1355 if (chroot(dir) < 0)
1356 ArgusLog(LOG_ERR, "ArgusSetChroot: failed to chroot to \"%s\": %s", dir, strerror(errno));
1357
1358 if (chdir("/") < 0)
1359 ArgusLog(LOG_ERR, "ArgusSetChroot: failed to chdir to \"/\" after chroot: %s", dir, strerror(errno));
1360
1361 #ifdef ARGUSDEBUG
1362 ArgusDebug (2, "ArgusSetChroot (%s) returning\n", dir);
1363 #endif
1364 }
1365
1366
1367 #include <sys/stat.h>
1368 #include <fcntl.h>
1369
1370 #define ARGUS_MAXERROR 200000
1371 #define ARGUS_MAXWRITENUM 10000
1372
1373 int ArgusMaxListLength = 100000;
1374 int ArgusCloseFile = 0;
1375
1376
1377 extern struct ArgusRecord *ArgusGenerateInitialMar (struct ArgusOutputStruct *);
1378
1379 int
ArgusWriteSocket(struct ArgusOutputStruct * output,struct ArgusClientData * client,struct ArgusRecordStruct * rec)1380 ArgusWriteSocket (struct ArgusOutputStruct *output, struct ArgusClientData *client, struct ArgusRecordStruct *rec)
1381 {
1382 struct ArgusSocketStruct *asock = client->sock;
1383 struct ArgusListStruct *list = asock->ArgusSocketList;
1384 struct stat statbuf;
1385 int retn = 0, ocnt;
1386
1387 #if defined(HAVE_SOLARIS)
1388 struct statvfs statfsbuf;
1389 #else
1390 struct statfs statfsbuf;
1391 #endif
1392
1393 if (ArgusListEmpty (list) && (asock->rec == NULL)) {
1394 #ifdef ARGUSDEBUG
1395 if (asock->writen || asock->length)
1396 ArgusDebug (6, "ArgusWriteSocket: asock stats error %d %d\n", asock->writen, asock->length);
1397 #endif
1398 if (client->host == NULL) {
1399 if (!(output->ArgusWriteStdOut) && (asock->filename)) {
1400 if (asock->lastwrite.tv_sec < output->ArgusModel->ArgusGlobalTime.tv_sec) {
1401 if (((stat (asock->filename, &statbuf)) < 0) || (ArgusCloseFile)) {
1402 if (asock->fd != -1)
1403 close(asock->fd);
1404 if ((asock->fd = open (asock->filename, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0x1a4)) < 0)
1405 ArgusLog (LOG_ERR, "ArgusWriteSocket: open(%s, flags, 0x1a4) failed %s\n",
1406 asock->filename, strerror(errno));
1407 #ifdef ARGUSDEBUG
1408 ArgusDebug (2, "ArgusWriteSocket: created outfile %s\n", asock->filename);
1409 #endif
1410 }
1411
1412 #if defined(HAVE_SOLARIS)
1413 retn = statvfs (asock->filename, &statfsbuf);
1414 #else
1415 retn = statfs (asock->filename, &statfsbuf);
1416 #endif
1417
1418 if (retn == 0) {
1419 if (statfsbuf.f_bfree > 100) {
1420 if ((stat (asock->filename, &statbuf)) == 0) {
1421 if (statbuf.st_size == 0) {
1422 if (output->ArgusInitMar != NULL)
1423 ArgusFree(output->ArgusInitMar);
1424 output->ArgusInitMar = ArgusGenerateInitialMar(output);
1425 ocnt = ntohs(output->ArgusInitMar->hdr.len) * 4;
1426 #ifdef ARGUSDEBUG
1427 ArgusDebug (6, "ArgusWriteSocket: write initial mar (%d, %p, %d)\n",
1428 asock->fd, output->ArgusInitMar, ocnt);
1429 #endif
1430 if (((retn = write (asock->fd, output->ArgusInitMar, ocnt))) < ocnt)
1431 ArgusLog (LOG_ERR, "ArgusWriteSocket: write %s failed %s\n", asock->filename, strerror(errno));
1432 ArgusFree(output->ArgusInitMar);
1433 output->ArgusInitMar = NULL;
1434 }
1435 }
1436
1437 } else {
1438 close(asock->fd);
1439 asock->fd = -1;
1440 }
1441 }
1442 asock->lastwrite = output->ArgusModel->ArgusGlobalTime;
1443 }
1444 }
1445 }
1446
1447 if (asock->fd != -1) {
1448 if (ArgusGenerateRecord (output->ArgusModel, rec, 0, (struct ArgusRecord *)&asock->buf)) {
1449 int cnt = ((struct ArgusRecord *)&asock->buf)->hdr.len * 4;
1450 #if defined(_LITTLE_ENDIAN)
1451 ArgusHtoN((struct ArgusRecord *)&asock->buf);
1452 #endif
1453 #ifdef ARGUS_SASL
1454 if (client->sasl_conn) {
1455 unsigned int outputlen = 0;
1456 const char *output = NULL;
1457 const int *ssfp;
1458 int result;
1459
1460 if ((result = sasl_getprop(client->sasl_conn, SASL_SSF, (const void **) &ssfp)) != SASL_OK)
1461 ArgusLog (LOG_ERR, "sasl_getprop: error %s\n", sasl_errdetail(client->sasl_conn));
1462
1463 if (ssfp && (*ssfp > 0)) {
1464 #ifdef ARGUSDEBUG
1465 ArgusDebug (6, "ArgusHandleClientData: sasl_encode(%p, %p, %d, %p, %p)\n",
1466 client->sasl_conn, rec, cnt, &output, &outputlen);
1467 #endif
1468 if ((retn = sasl_encode(client->sasl_conn, (const char *) asock->buf, (unsigned int) cnt,
1469 &output, &outputlen)) == SASL_OK) {
1470 #ifdef ARGUSDEBUG
1471 ArgusDebug (6, "ArgusHandleClientData: sasl_encode returned %d bytes\n", outputlen);
1472 #endif
1473 if (outputlen < ARGUS_MAXRECORD) {
1474 bcopy(output, asock->buf, outputlen);
1475 cnt = outputlen;
1476 } else
1477 ArgusLog (LOG_ERR, "sasl_encode: returned too many bytes %d\n", outputlen);
1478
1479 } else
1480 ArgusLog (LOG_ERR, "sasl_encode: failed returned %d\n", retn);
1481 }
1482 }
1483 #endif
1484
1485 #ifdef ARGUSDEBUG
1486 ArgusDebug (4, "ArgusWriteSocket: write record (%d, %p, %d)\n", asock->fd, &asock->buf, cnt);
1487 #endif
1488 if (client->host != NULL) {
1489 retn = sendto (asock->fd, &asock->buf, cnt, 0, client->host->ai_addr, client->host->ai_addrlen);
1490 #ifdef ARGUSDEBUG
1491 ArgusDebug (6, "ArgusWriteSocket: sendto (%d, %p, %d, ...) %d\n", asock->fd, &asock->buf, cnt, retn);
1492 #endif
1493 } else {
1494 retn = write (asock->fd, &asock->buf, cnt);
1495 #ifdef ARGUSDEBUG
1496 ArgusDebug (6, "ArgusWriteSocket: write (%d, %p, %d, ...) %d\n", asock->fd, &asock->buf, cnt, retn);
1497 #endif
1498 }
1499 if (retn >= 0) {
1500 asock->status |= ARGUS_WAS_FUNCTIONAL;
1501 asock->errornum = 0;
1502 if (retn != cnt) {
1503 #ifdef ARGUSDEBUG
1504 ArgusDebug (6, "ArgusWriteSocket: write returned %d, scheduled record\n", retn);
1505 #endif
1506 asock->writen = retn;
1507 asock->length = cnt;
1508 asock->rec = ArgusCopyRecordStruct(rec);
1509 } else {
1510 asock->writen = 0;
1511 asock->length = 0;
1512 #ifdef ARGUSDEBUG
1513 ArgusDebug (6, "ArgusWriteSocket: write successful %d\n", retn);
1514 #endif
1515 }
1516
1517 } else {
1518 #ifdef ARGUSDEBUG
1519 ArgusDebug (6, "ArgusWriteSocket: write returned %d, errno %d\n", retn, errno);
1520 #endif
1521 asock->writen = 0;
1522 asock->length = cnt;
1523 asock->rec = ArgusCopyRecordStruct(rec);
1524
1525 switch (errno) {
1526 case ENOSPC:
1527 if (asock->filename != NULL) {
1528 close(asock->fd);
1529 asock->fd = -1;
1530 asock->rec = NULL;
1531 asock->writen = 0;
1532 asock->length = 0;
1533 ArgusFreeListRecord(rec);
1534 while ((rec = (struct ArgusRecordStruct *) ArgusPopFrontList(list, ARGUS_LOCK)) != NULL)
1535 ArgusFreeListRecord(rec);
1536 }
1537 break;
1538
1539 case EAGAIN:
1540 case EINTR:
1541 retn = 0;
1542 break;
1543
1544 case EPIPE: {
1545 if (!(asock->status & ARGUS_WAS_FUNCTIONAL)) {
1546 retn = 0;
1547 }
1548 break;
1549 }
1550
1551 default:
1552 break;
1553 }
1554 }
1555
1556 } else {
1557 #ifdef ARGUSDEBUG
1558 ArgusDebug (6, "ArgusWriteSocket: ArgusGenerateRecord returned zero\n");
1559 #endif
1560 }
1561 }
1562
1563 } else {
1564 if (list->count >= ArgusMaxListLength) {
1565 if (ArgusWriteOutSocket(output, client) < 0) {
1566 #if defined(ARGUS_THREADS)
1567 pthread_mutex_lock(&list->lock);
1568 #endif
1569 if (list->count >= ArgusMaxListLength) {
1570 struct ArgusRecordStruct *trec;
1571 int i;
1572 #define ARGUS_MAX_TOSS_RECORD 64
1573 ArgusLog (LOG_WARNING, "ArgusWriteSocket: ArgusWriteOutSocket tossing records\n");
1574
1575 for (i = 0; i < ARGUS_MAX_TOSS_RECORD; i++)
1576 if ((trec = (struct ArgusRecordStruct *) ArgusPopFrontList(list, ARGUS_NOLOCK)) != NULL)
1577 ArgusFreeListRecord(trec);
1578 }
1579 #if defined(ARGUS_THREADS)
1580 pthread_mutex_unlock(&list->lock);
1581 #endif
1582 }
1583 }
1584
1585 if (asock->rec == NULL)
1586 asock->rec = (struct ArgusRecordStruct *) ArgusPopFrontList(list, ARGUS_LOCK);
1587
1588 #ifdef ARGUSDEBUG
1589 ArgusDebug (6, "ArgusWriteSocket (%p, %p, %p) schedule record\n", output, asock, rec);
1590 #endif
1591 ArgusPushBackList (list, (struct ArgusListRecord *) ArgusCopyRecordStruct(rec), ARGUS_LOCK);
1592 retn = 0;
1593 }
1594
1595 #ifdef ARGUSDEBUG
1596 ArgusDebug (6, "ArgusWriteSocket (%p, %p, %p) returning %d\n", output, asock, rec, retn);
1597 #endif
1598
1599 return (retn);
1600 }
1601
1602
1603
1604 #define ARGUS_LISTREPORTLEN 50000
1605 #define ARGUS_LISTREPORTTIME 30
1606
1607 int
ArgusWriteOutSocket(struct ArgusOutputStruct * output,struct ArgusClientData * client)1608 ArgusWriteOutSocket (struct ArgusOutputStruct *output, struct ArgusClientData *client)
1609 {
1610 struct ArgusSocketStruct *asock = client->sock;
1611 struct ArgusListStruct *list = NULL;
1612 struct ArgusRecordStruct *rec = NULL;
1613 int retn = 0, count = 1, len, ocnt;
1614 struct stat statbuf;
1615 unsigned char *ptr;
1616
1617 if ((list = asock->ArgusSocketList) != NULL) {
1618 if ((count = ArgusGetListCount(list)) > 0) {
1619 if (count > ARGUS_MAXWRITENUM)
1620 count = ARGUS_MAXWRITENUM;
1621
1622 if (count == 1)
1623 count = 2;
1624
1625 #if defined(ARGUS_THREADS)
1626 pthread_mutex_lock(&list->lock);
1627 #endif
1628 while ((asock->fd != -1 ) && count--) {
1629 if ((rec = asock->rec) != NULL) {
1630 ptr = (unsigned char *)&asock->buf;
1631 if (!(asock->writen)) {
1632 if (!(output->ArgusWriteStdOut) && (asock->filename)) {
1633 if (asock->lastwrite.tv_sec < output->ArgusModel->ArgusGlobalTime.tv_sec) {
1634 if (((stat (asock->filename, &statbuf)) < 0) || (ArgusCloseFile)) {
1635 close(asock->fd);
1636 if ((asock->fd = open (asock->filename, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0x1a4)) < 0)
1637 ArgusLog (LOG_ERR, "ArgusWriteSocket: open(%s, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0x1a4) failed %s\n",
1638 asock->filename, strerror(errno));
1639 #ifdef ARGUSDEBUG
1640 ArgusDebug (2, "ArgusWriteOutSocket: created outfile %s\n", asock->filename);
1641 #endif
1642 }
1643
1644 if ((stat (asock->filename, &statbuf)) == 0) {
1645 if (statbuf.st_size == 0) {
1646 if (output->ArgusInitMar != NULL)
1647 ArgusFree(output->ArgusInitMar);
1648 output->ArgusInitMar = ArgusGenerateInitialMar(output);
1649 ocnt = sizeof(struct ArgusRecord);
1650 if (((retn = write (asock->fd, output->ArgusInitMar, ocnt))) < ocnt)
1651 ArgusLog (LOG_ERR, "ArgusWriteSocket: write %s failed %s\n", asock->filename, strerror(errno));
1652 ArgusFree(output->ArgusInitMar);
1653 output->ArgusInitMar = NULL;
1654
1655 }
1656 }
1657 asock->lastwrite = output->ArgusModel->ArgusGlobalTime;
1658 }
1659 }
1660 }
1661
1662 if ((asock->writen < asock->length) && ( asock->writen >= 0)) {
1663 len = asock->length - asock->writen;
1664
1665 if (client->host != NULL) {
1666 retn = sendto (asock->fd, (unsigned char *)&ptr[asock->writen], len, 0, client->host->ai_addr, client->host->ai_addrlen);
1667 #ifdef ARGUSDEBUG
1668 ArgusDebug (3, "ArgusWriteSocket: sendto (%d, %p, %d, ...) %d\n", asock->fd, &asock->buf, len, retn);
1669 #endif
1670 } else {
1671 retn = write(asock->fd, (unsigned char *)&ptr[asock->writen], len);
1672 #ifdef ARGUSDEBUG
1673 ArgusDebug (3, "ArgusWriteSocket: write (%d, %p, %d, ...) %d\n", asock->fd, &asock->buf, len, retn);
1674 #endif
1675 }
1676
1677 if (retn >= 0) {
1678 asock->errornum = 0;
1679 asock->writen += retn;
1680
1681 } else {
1682 switch (errno) {
1683 case ENOSPC: {
1684 if (asock->filename != NULL) {
1685 close(asock->fd);
1686 asock->fd = -1;
1687 asock->rec = NULL;
1688 asock->writen = 0;
1689 asock->length = 0;
1690 ArgusFreeListRecord(rec);
1691 while ((rec = (struct ArgusRecordStruct *) ArgusPopFrontList(list, ARGUS_NOLOCK)) != NULL)
1692 ArgusFreeListRecord(rec);
1693 }
1694 break;
1695 }
1696
1697 case EAGAIN:
1698 case EINTR: {
1699 if (!(output->ArgusWriteStdOut) && (asock->filename == NULL)) {
1700 if (asock->errornum++ < ARGUS_MAXERROR) {
1701 retn = 0;
1702 } else {
1703 }
1704
1705 } else {
1706 retn = 0;
1707 }
1708 break;
1709 }
1710
1711 case EPIPE:
1712 break;
1713
1714 default:
1715 if (asock->errornum++ == 0)
1716 ArgusLog (LOG_WARNING, "ArgusWriteOutSocket: write() %s\n", strerror(errno));
1717 break;
1718 }
1719 }
1720 }
1721
1722 if (asock->writen >= asock->length) {
1723 gettimeofday(&list->outputTime, 0L);
1724 ArgusFreeListRecord(rec);
1725
1726 #ifdef ARGUSDEBUG
1727 ArgusDebug (6, "ArgusWriteOutSocket: rec %p complete, %d count\n", rec, count);
1728 #endif
1729 asock->rec = NULL;
1730 asock->writen = 0;
1731 asock->length = 0;
1732
1733 if ((rec = (struct ArgusRecordStruct *) ArgusPopFrontList(list, ARGUS_NOLOCK)) != NULL) {
1734 if (ArgusGenerateRecord (output->ArgusModel, rec, 0, (struct ArgusRecord *)&asock->buf)) {
1735 int cnt = ((struct ArgusRecord *)&asock->buf)->hdr.len * 4;
1736 #if defined(_LITTLE_ENDIAN)
1737 ArgusHtoN((struct ArgusRecord *)&asock->buf);
1738 #endif
1739 #ifdef ARGUS_SASL
1740 if (client->sasl_conn) {
1741 unsigned int outputlen = 0;
1742 const char *output = NULL;
1743 #ifdef ARGUSDEBUG
1744 ArgusDebug (3, "ArgusHandleClientData: sasl_encode(%p, %p, %d, %p, %p)\n",
1745 client->sasl_conn, rec, cnt, &output, &outputlen);
1746 #endif
1747 if ((retn = sasl_encode(client->sasl_conn, (const char *) asock->buf, (unsigned int) cnt,
1748 &output, &outputlen)) == SASL_OK) {
1749 #ifdef ARGUSDEBUG
1750 ArgusDebug (3, "ArgusWriteOutSocket: sasl_encode returned %d bytes\n", outputlen);
1751 #endif
1752 if (outputlen < ARGUS_MAXRECORD) {
1753 bcopy(output, asock->buf, outputlen);
1754 cnt = outputlen;
1755
1756 } else
1757 ArgusLog (LOG_ERR, "sasl_encode: returned too many bytes %d\n", outputlen);
1758
1759 } else
1760 ArgusLog (LOG_ERR, "sasl_encode: failed returned %d\n", retn);
1761 }
1762 #endif
1763 asock->writen = 0;
1764 asock->length = cnt;
1765 asock->rec = rec;
1766 #ifdef ARGUSDEBUG
1767 ArgusDebug (6, "ArgusWriteOutSocket: posted record %p", rec);
1768 #endif
1769
1770 } else {
1771 #ifdef ARGUSDEBUG
1772 ArgusDebug (6, "ArgusWriteOutSocket: ArgusGenerateRecord error! deleting record");
1773 #endif
1774 ArgusFreeListRecord(rec);
1775 }
1776 } else {
1777 #ifdef ARGUSDEBUG
1778 ArgusDebug (3, "ArgusWriteOutSocket: list %p is now empty", list);
1779 #endif
1780 }
1781
1782 } else {
1783 #ifdef ARGUSDEBUG
1784 ArgusDebug (6, "ArgusWriteOutSocket: still work to be done for %p, len %d writen %d", rec, asock->length, asock->writen);
1785 #endif
1786 break;
1787 }
1788
1789 } else {
1790 #ifdef ARGUSDEBUG
1791 ArgusDebug (6, "ArgusWriteOutSocket: nothing to be done for %p, len %d writen %d", rec, asock->length, asock->writen);
1792 #endif
1793 }
1794 }
1795
1796 #if defined(ARGUS_THREADS)
1797 pthread_mutex_unlock(&list->lock);
1798 #endif
1799
1800 #ifdef ARGUSDEBUG
1801 ArgusDebug (9, "ArgusWriteOutSocket(%p): queue empty\n", asock);
1802 #endif
1803
1804 if (asock->errornum >= ARGUS_MAXERROR) {
1805 ArgusLog (LOG_WARNING, "ArgusWriteOutSocket(%p) maximum errors exceeded %d\n", asock, asock->errornum);
1806 retn = -1;
1807 }
1808
1809 if ((count = ArgusGetListCount(list)) > ArgusMaxListLength) {
1810 ArgusLog (LOG_WARNING, "ArgusWriteOutSocket(%p) max queue exceeded %d\n", asock, count);
1811 retn = -1;
1812 }
1813
1814 #ifdef ARGUSDEBUG
1815 if (list) {
1816 ArgusDebug (6, "ArgusWriteOutSocket (%p) %d records waiting. returning %d\n", asock, count, retn);
1817 } else {
1818 ArgusDebug (6, "ArgusWriteOutSocket (%p) no list. returning %d\n", asock, count, retn);
1819 }
1820 #endif
1821 }
1822
1823 } else {
1824 #ifdef ARGUSDEBUG
1825 ArgusDebug (6, "ArgusWriteOutSocket (%p, %p) no list returning %d\n", output, client, retn);
1826 #endif
1827 }
1828
1829 #ifdef ARGUSDEBUG
1830 ArgusDebug (6, "ArgusWriteOutSocket (%p, %p) returning %d\n", output, client, retn);
1831 #endif
1832
1833 return retn;
1834 }
1835
1836
1837 #if !defined(ArgusAddrtoName)
1838 #define ArgusAddrtoName
1839 #endif
1840
1841 #include <sys/socket.h>
1842 #include <signal.h>
1843 #include <netdb.h>
1844
1845 #include <argus_namedb.h>
1846
1847 #ifdef ETHER_SERVICE
1848 struct ether_addr;
1849
1850 #ifdef HAVE_ETHER_HOSTTON
1851 /*
1852 * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
1853 * ether_hostton()?
1854 */
1855 #ifdef HAVE_NETINET_IF_ETHER_H
1856 struct mbuf; /* Squelch compiler warnings on some platforms for */
1857 struct rtentry; /* declarations in <net/if.h> */
1858 #include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
1859 #include <netinet/if_ether.h>
1860 #endif /* HAVE_NETINET_IF_ETHER_H */
1861 #ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
1862 #include <netinet/ether.h>
1863 #endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
1864 #endif /* HAVE_ETHER_HOSTTON */
1865 #endif
1866
1867 /*
1868 * hash tables for whatever-to-name translations
1869
1870 #define HASHNAMESIZE 4096
1871
1872 struct h6namemem {
1873 struct in6_addr addr;
1874 char *name;
1875 struct h6namemem *nxt;
1876 };
1877
1878 struct hnamemem {
1879 u_int addr;
1880 char *name;
1881 struct hnamemem *nxt;
1882 };
1883
1884 struct h6namemem h6nametable[HASHNAMESIZE];
1885 struct hnamemem hnametable[HASHNAMESIZE];
1886 struct hnamemem tporttable[HASHNAMESIZE];
1887 struct hnamemem uporttable[HASHNAMESIZE];
1888 struct hnamemem eprototable[HASHNAMESIZE];
1889 struct hnamemem nnametable[HASHNAMESIZE];
1890 struct hnamemem llcsaptable[HASHNAMESIZE];
1891
1892 struct enamemem {
1893 u_short e_addr0;
1894 u_short e_addr1;
1895 u_short e_addr2;
1896 char *e_name;
1897 u_char *e_nsap;
1898 struct enamemem *e_nxt;
1899 };
1900
1901 struct enamemem enametable[HASHNAMESIZE];
1902 struct enamemem nsaptable[HASHNAMESIZE];
1903
1904 struct protoidmem {
1905 u_int p_oui;
1906 arg_uint16 p_proto;
1907 char *p_name;
1908 struct protoidmem *p_nxt;
1909 };
1910
1911 struct protoidmem protoidtable[HASHNAMESIZE];
1912 */
1913
1914 /*
1915 * A faster replacement for inet_ntoa().
1916 */
1917 char *
intoa(u_int addr)1918 intoa(u_int addr)
1919 {
1920 char *cp;
1921 u_int byte;
1922 int n;
1923 static char buf[sizeof(".xxx.xxx.xxx.xxx")];
1924 /*
1925 addr = htonl(addr);
1926 */
1927 cp = &buf[sizeof buf];
1928 *--cp = '\0';
1929
1930 n = 4;
1931 do {
1932 byte = addr & 0xff;
1933 *--cp = byte % 10 + '0';
1934 byte /= 10;
1935 if (byte > 0) {
1936 *--cp = byte % 10 + '0';
1937 byte /= 10;
1938 if (byte > 0)
1939 *--cp = byte + '0';
1940 }
1941 *--cp = '.';
1942 addr >>= 8;
1943 } while (--n > 0);
1944
1945 return cp + 1;
1946 }
1947
1948 /*
1949 * Return a name for the IP address pointed to by ap. This address
1950 * is assumed to be in network byte order.
1951 */
1952 char *
ArgusGetName(struct ArgusParserStruct * parser,u_char * ap)1953 ArgusGetName(struct ArgusParserStruct *parser, u_char *ap)
1954 {
1955 static struct hnamemem *p; /* static for longjmp() */
1956 u_int addr;
1957
1958 #if !defined(TCPDUMP_ALIGN)
1959 addr = *(const u_int *)ap;
1960 #else
1961 /*
1962 * Deal with alignment.
1963 */
1964 switch ((int)ap & 3) {
1965
1966 case 0:
1967 addr = *(u_int *)ap;
1968 break;
1969
1970 case 2:
1971 addr = ((u_int)*(u_short *)ap << 16) |
1972 (u_int)*(u_short *)(ap + 2);
1973 break;
1974
1975 default:
1976 addr = ((u_int)ap[3] << 24) |
1977 ((u_int)ap[2] << 16) |
1978 ((u_int)ap[1] << 8) |
1979 (u_int)ap[0];
1980 break;
1981 }
1982 #endif
1983 p = &parser->hnametable[addr % (HASHNAMESIZE-1)];
1984 for (; p->nxt; p = p->nxt) {
1985 if (p->addr == addr)
1986 if (p->name != NULL)
1987 return (p->name);
1988 }
1989 p->addr = addr;
1990 p->nxt = (struct hnamemem *)calloc(1, sizeof (*p));
1991
1992 return (intoa(addr));
1993 }
1994
1995
1996 #include <sys/socket.h>
1997 #include <arpa/inet.h>
1998
1999 #if !defined(INET6_ADDRSTRLEN)
2000 #define INET6_ADDRSTRLEN 46
2001 #endif
2002
2003 #if !defined(AF_INET6)
2004 #define AF_INET6 23
2005 #endif
2006
2007 char *
ArgusGetV6Name(struct ArgusParserStruct * parser,u_char * ap)2008 ArgusGetV6Name(struct ArgusParserStruct *parser, u_char *ap)
2009 {
2010 struct in6_addr addr;
2011 char ntop_buf[INET6_ADDRSTRLEN];
2012 struct h6namemem *p; /* static for longjmp() */
2013 const char *cp;
2014
2015 memcpy(&addr, ap, sizeof(addr));
2016
2017 p = &parser->h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
2018 for (; p->nxt; p = p->nxt) {
2019 if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
2020 return (p->name);
2021 }
2022 p->addr = addr;
2023 p->nxt = (struct h6namemem *)calloc(1, sizeof (*p));
2024
2025 if ((cp = inet_ntop(AF_INET6, (const void *) &addr, ntop_buf, sizeof(ntop_buf))) != NULL)
2026 p->name = strdup(cp);
2027
2028 return (p->name);
2029 }
2030
2031 struct timeval *
RaMinTime(struct timeval * s1,struct timeval * s2)2032 RaMinTime (struct timeval *s1, struct timeval *s2)
2033 {
2034 struct timeval *retn = s2;
2035
2036 if ((s1->tv_sec < s2->tv_sec) || ((s1->tv_sec == s2->tv_sec) && (s1->tv_usec < s2->tv_usec)))
2037 retn = s1;
2038
2039 return (retn);
2040 }
2041
2042
2043 struct timeval *
RaMaxTime(struct timeval * s1,struct timeval * s2)2044 RaMaxTime (struct timeval *s1, struct timeval *s2)
2045 {
2046 struct timeval *retn = s2;
2047
2048 if ((s1->tv_sec > s2->tv_sec) || ((s1->tv_sec == s2->tv_sec) && (s1->tv_usec > s2->tv_usec)))
2049 retn = s1;
2050
2051 return (retn);
2052 }
2053
2054
2055 float
RaDeltaFloatTime(struct timeval * s1,struct timeval * s2)2056 RaDeltaFloatTime (struct timeval *s1, struct timeval *s2)
2057 {
2058 float retn = 0.0;
2059
2060 if (s1 && s2) {
2061 double v1 = (s1->tv_sec * 1.0) + (s1->tv_usec / 1000000.0);
2062 double v2 = (s2->tv_sec * 1.0) + (s2->tv_usec / 1000000.0);
2063
2064 retn = v1 - v2;
2065 }
2066
2067 return (retn);
2068 }
2069
2070 int
RaDiffTime(struct timeval * s1,struct timeval * s2,struct timeval * diff)2071 RaDiffTime (struct timeval *s1, struct timeval *s2, struct timeval *diff)
2072 {
2073 int retn = 0;
2074
2075 if (s1 && s2 && diff) {
2076 bzero ((char *)diff, sizeof(*diff));
2077
2078 double v1 = (s1->tv_sec * 1.0) + (s1->tv_usec / 1000000.0);
2079 double v2 = (s2->tv_sec * 1.0) + (s2->tv_usec / 1000000.0);
2080 double f, i;
2081
2082 v1 -= v2;
2083
2084 f = modf(v1, &i);
2085
2086 diff->tv_sec = i;
2087 diff->tv_usec = f * 1000000;
2088
2089 retn = 1;
2090 }
2091
2092 return (retn);
2093 }
2094
2095
2096 long long ArgusDiffTime (struct ArgusTime *, struct ArgusTime *, struct timeval *);
2097
2098 long long
ArgusDiffTime(struct ArgusTime * s1,struct ArgusTime * s2,struct timeval * diff)2099 ArgusDiffTime (struct ArgusTime *s1, struct ArgusTime *s2, struct timeval *diff)
2100 {
2101 long long v1 = 0, v2 = 0;
2102
2103 if (s1 && s2 && diff) {
2104 v1 = (s1->tv_sec * 1000000LL) + s1->tv_usec;
2105 v2 = (s2->tv_sec * 1000000LL) + s2->tv_usec;
2106
2107 v1 -= v2;
2108
2109 diff->tv_sec = v1 / 1000000;
2110 diff->tv_usec = v1 % 1000000;
2111 }
2112
2113 return (v1);
2114 }
2115
2116
2117 float
RaGetFloatDuration(struct ArgusRecordStruct * argus)2118 RaGetFloatDuration (struct ArgusRecordStruct *argus)
2119 {
2120 float retn = 0;
2121 int sec = 0, usec = 0;
2122
2123 if (argus->hdr.type & ARGUS_MAR) {
2124 struct ArgusRecord *rec = (struct ArgusRecord *) &argus->canon;
2125
2126 sec = rec->argus_mar.now.tv_sec - rec->argus_mar.startime.tv_sec;
2127 usec = rec->argus_mar.now.tv_usec - rec->argus_mar.startime.tv_usec;
2128
2129 } else {
2130 struct ArgusTimeObject *dtime = &argus->canon.time;
2131 struct timeval *stime = NULL, *ltime = NULL;
2132 struct timeval srctime, dsttime;
2133 unsigned int subtype = dtime->hdr.subtype & (ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START |
2134 ARGUS_TIME_SRC_END | ARGUS_TIME_DST_END);
2135 if (subtype) {
2136 switch (subtype) {
2137 case ARGUS_TIME_SRC_START | ARGUS_TIME_DST_START |
2138 ARGUS_TIME_SRC_END | ARGUS_TIME_DST_END: {
2139
2140 srctime.tv_sec = dtime->src.start.tv_sec;
2141 srctime.tv_usec = dtime->src.start.tv_usec;
2142 dsttime.tv_sec = dtime->dst.start.tv_sec;
2143 dsttime.tv_usec = dtime->dst.start.tv_usec;
2144
2145 stime = RaMinTime(&srctime, &dsttime);
2146
2147 srctime.tv_sec = dtime->src.end.tv_sec;
2148 srctime.tv_usec = dtime->src.end.tv_usec;
2149 dsttime.tv_sec = dtime->dst.end.tv_sec;
2150 dsttime.tv_usec = dtime->dst.end.tv_usec;
2151
2152 ltime = RaMaxTime(&srctime, &dsttime);
2153 break;
2154 }
2155
2156 case ARGUS_TIME_SRC_START:
2157 case ARGUS_TIME_SRC_START | ARGUS_TIME_SRC_END: {
2158
2159 srctime.tv_sec = dtime->src.start.tv_sec;
2160 srctime.tv_usec = dtime->src.start.tv_usec;
2161 dsttime.tv_sec = dtime->src.end.tv_sec;
2162 dsttime.tv_usec = dtime->src.end.tv_usec;
2163
2164 stime = &srctime;
2165 ltime = &dsttime;
2166 break;
2167 }
2168
2169 case ARGUS_TIME_DST_START:
2170 case ARGUS_TIME_DST_START | ARGUS_TIME_DST_END: {
2171 srctime.tv_sec = dtime->dst.start.tv_sec;
2172 srctime.tv_usec = dtime->dst.start.tv_usec;
2173 dsttime.tv_sec = dtime->dst.end.tv_sec;
2174 dsttime.tv_usec = dtime->dst.end.tv_usec;
2175
2176 stime = &srctime;
2177 ltime = &dsttime;
2178 break;
2179 }
2180
2181 case ARGUS_TIME_SRC_START | ARGUS_TIME_DST_END: {
2182 srctime.tv_sec = dtime->src.start.tv_sec;
2183 srctime.tv_usec = dtime->src.start.tv_usec;
2184 dsttime.tv_sec = dtime->dst.end.tv_sec;
2185 dsttime.tv_usec = dtime->dst.end.tv_usec;
2186
2187 stime = &srctime;
2188 ltime = &dsttime;
2189 break;
2190 }
2191
2192 default:
2193 break;
2194 }
2195
2196 } else {
2197 srctime.tv_sec = dtime->src.start.tv_sec;
2198 srctime.tv_usec = dtime->src.start.tv_usec;
2199 dsttime.tv_sec = dtime->src.end.tv_sec;
2200 dsttime.tv_usec = dtime->src.end.tv_usec;
2201
2202 stime = &srctime;
2203 ltime = &dsttime;
2204 }
2205
2206
2207 if (stime && ltime) {
2208 sec = ltime->tv_sec - stime->tv_sec;
2209 usec = ltime->tv_usec - stime->tv_usec;
2210 }
2211 }
2212
2213 retn = (sec * 1.0) + usec/1000000.0;
2214 return (retn);
2215 }
2216
2217
2218 float
RaGetFloatSrcDuration(struct ArgusRecordStruct * argus)2219 RaGetFloatSrcDuration (struct ArgusRecordStruct *argus)
2220 {
2221 float retn = 0.0;
2222 int sec = 0, usec = 0;
2223
2224 if (argus->hdr.type & ARGUS_MAR) {
2225
2226 } else {
2227 struct ArgusTimeObject *dtime = &argus->canon.time;
2228 struct ArgusTime *stime = &dtime->src.start;
2229 struct ArgusTime *ltime = &dtime->src.end;
2230
2231 sec = ltime->tv_sec - stime->tv_sec;
2232 usec = ltime->tv_usec - stime->tv_usec;
2233 retn = (sec * 1.0) + usec/1000000.0;
2234 }
2235
2236 return (retn);
2237 }
2238
2239
2240 float
RaGetFloatDstDuration(struct ArgusRecordStruct * argus)2241 RaGetFloatDstDuration (struct ArgusRecordStruct *argus)
2242 {
2243 float retn = 0.0;
2244 int sec = 0, usec = 0;
2245
2246 if (argus->hdr.type & ARGUS_MAR) {
2247
2248 } else {
2249 struct ArgusTimeObject *dtime = &argus->canon.time;
2250 struct ArgusTime *stime = &dtime->dst.start;
2251 struct ArgusTime *ltime = &dtime->dst.end;
2252
2253 sec = ltime->tv_sec - stime->tv_sec;
2254 usec = ltime->tv_usec - stime->tv_usec;
2255 retn = (sec * 1.0) + usec/1000000.0;
2256 }
2257
2258 return (retn);
2259 }
2260
2261
2262 double
ArgusFetchDuration(struct ArgusRecordStruct * ns)2263 ArgusFetchDuration (struct ArgusRecordStruct *ns)
2264 {
2265 double retn = RaGetFloatDuration(ns);
2266 return (retn);
2267 }
2268
2269 double
ArgusFetchSrcDuration(struct ArgusRecordStruct * ns)2270 ArgusFetchSrcDuration (struct ArgusRecordStruct *ns)
2271 {
2272 double retn = RaGetFloatSrcDuration(ns);
2273 return (retn);
2274 }
2275
2276 double
ArgusFetchDstDuration(struct ArgusRecordStruct * ns)2277 ArgusFetchDstDuration (struct ArgusRecordStruct *ns)
2278 {
2279 double retn = RaGetFloatDstDuration(ns);
2280 return (retn);
2281 }
2282
2283
2284 double
ArgusFetchSrcLoad(struct ArgusRecordStruct * ns)2285 ArgusFetchSrcLoad (struct ArgusRecordStruct *ns)
2286 {
2287 struct ArgusMetricStruct *m1 = NULL;
2288 float dur = 0.0;
2289 long long cnt1;
2290 double retn = 0.0;
2291
2292 dur = ArgusFetchSrcDuration(ns);
2293
2294 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL) {
2295 cnt1 = m1->src.pkts;
2296 } else {
2297 cnt1 = 0;
2298 }
2299
2300 if (dur > 0.0)
2301 retn = (cnt1 * 1.0)/dur;
2302
2303 return (retn);
2304 }
2305
2306 double
ArgusFetchDstLoad(struct ArgusRecordStruct * ns)2307 ArgusFetchDstLoad (struct ArgusRecordStruct *ns)
2308 {
2309 struct ArgusMetricStruct *m1 = NULL;
2310 struct timeval ts1buf, *ts1 = &ts1buf;
2311 struct timeval t1buf, *t1d = &t1buf;
2312 long long cnt1 = 0;
2313 float d1 = 0.0;
2314 double retn = 0;
2315
2316 ts1->tv_sec = ns->canon.time.src.start.tv_sec;
2317 ts1->tv_usec = ns->canon.time.src.start.tv_usec;
2318
2319 t1d->tv_sec = ns->canon.time.src.end.tv_sec;
2320 t1d->tv_usec = ns->canon.time.src.end.tv_usec;
2321
2322 t1d->tv_sec -= ts1->tv_sec; t1d->tv_usec -= ts1->tv_usec;
2323 if (t1d->tv_usec < 0) {t1d->tv_sec--; t1d->tv_usec += 1000000;}
2324 d1 = ((t1d->tv_sec * 1.0) + (t1d->tv_usec/1000000.0));
2325
2326 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
2327 cnt1 = m1->dst.pkts;
2328
2329 if (d1 > 0.0)
2330 retn = (cnt1 * 1.0)/d1;
2331
2332 return (retn);
2333 }
2334
2335
2336 double
ArgusFetchLoad(struct ArgusRecordStruct * ns)2337 ArgusFetchLoad (struct ArgusRecordStruct *ns)
2338 {
2339 struct ArgusMetricStruct *m1 = NULL;
2340 struct timeval ts1buf, *ts1 = &ts1buf;
2341 struct timeval t1buf, *t1d = &t1buf;
2342 long long cnt1 = 0;
2343 float d1 = 0.0;
2344 double retn = 0;
2345
2346 ts1->tv_sec = ns->canon.time.src.start.tv_sec;
2347 ts1->tv_usec = ns->canon.time.src.start.tv_usec;
2348
2349 t1d->tv_sec = ns->canon.time.src.end.tv_sec;
2350 t1d->tv_usec = ns->canon.time.src.end.tv_usec;
2351
2352 t1d->tv_sec -= ts1->tv_sec; t1d->tv_usec -= ts1->tv_usec;
2353 if (t1d->tv_usec < 0) {t1d->tv_sec--; t1d->tv_usec += 1000000;}
2354 d1 = ((t1d->tv_sec * 1.0) + (t1d->tv_usec/1000000.0));
2355
2356 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
2357 cnt1 = m1->src.pkts + m1->dst.pkts;
2358
2359 if ((cnt1 > 0) && (d1 > 0.0))
2360 retn = (cnt1 * 1.0)/d1;
2361
2362 return (retn);
2363 }
2364
2365
2366 double
ArgusFetchLoss(struct ArgusRecordStruct * ns)2367 ArgusFetchLoss (struct ArgusRecordStruct *ns)
2368 {
2369 double retn = 0.0;
2370
2371 if (ns) {
2372 if (ns->hdr.type & ARGUS_MAR) {
2373 } else {
2374 struct ArgusFlow *flow = (struct ArgusFlow *)&ns->canon.flow;
2375 switch (flow->hdr.subtype & 0x3F) {
2376 case ARGUS_FLOW_CLASSIC5TUPLE: {
2377 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
2378 case ARGUS_TYPE_IPV4: {
2379 switch (ns->canon.flow.ip_flow.ip_p) {
2380 case IPPROTO_UDP: {
2381 if (ns->canon.net.hdr.subtype == ARGUS_RTP_FLOW) {
2382 struct ArgusRTPObject *rtp = (void *)&ns->canon.net.net_union.rtp;
2383 retn = (rtp->sdrop + rtp->ddrop) * 1.0;
2384 }
2385 break;
2386 }
2387
2388 case IPPROTO_ICMP: {
2389 break;
2390 }
2391 case IPPROTO_TCP: {
2392 struct ArgusTCPObject *tcp = (void *)&ns->canon.net.net_union.tcp;
2393
2394 if ((tcp != NULL) && (tcp->state != 0)) {
2395 if (ns->canon.metric.src.pkts)
2396 retn = (tcp->src.retrans + tcp->dst.retrans) * 1.0;
2397 }
2398 break;
2399 }
2400 case IPPROTO_ESP: {
2401 struct ArgusESPObject *esp = (void *)&ns->canon.net.net_union.esp;
2402 if (esp != NULL) {
2403 if (ns->canon.metric.src.pkts)
2404 retn = esp->lostseq * 1.0;
2405 }
2406 break;
2407 }
2408 }
2409 break;
2410 }
2411
2412 case ARGUS_TYPE_IPV6: {
2413 switch (flow->ipv6_flow.ip_p) {
2414 case IPPROTO_UDP: {
2415 if (ns->canon.net.hdr.subtype == ARGUS_RTP_FLOW) {
2416 struct ArgusRTPObject *rtp = (void *)&ns->canon.net.net_union.rtp;
2417 retn = (rtp->sdrop + rtp->ddrop) * 1.0;
2418 }
2419 break;
2420 }
2421
2422 case IPPROTO_ICMP: {
2423 break;
2424 }
2425
2426 case IPPROTO_TCP: {
2427 struct ArgusTCPObject *tcp = (void *)&ns->canon.net.net_union.tcp;
2428
2429 if ((tcp != NULL) && (tcp->state != 0)) {
2430 if (ns->canon.metric.src.pkts)
2431 retn = (tcp->src.retrans + tcp->dst.retrans) * 1.0;
2432 }
2433 break;
2434 }
2435 }
2436 }
2437 }
2438 break;
2439 }
2440 }
2441 }
2442 }
2443
2444 return (retn);
2445 }
2446
2447
2448 double
ArgusFetchSrcLoss(struct ArgusRecordStruct * ns)2449 ArgusFetchSrcLoss (struct ArgusRecordStruct *ns)
2450 {
2451 double retn = 0.0;
2452
2453 if (ns) {
2454 if (ns->hdr.type & ARGUS_MAR) {
2455 } else {
2456 struct ArgusFlow *flow = (struct ArgusFlow *)&ns->canon.flow;
2457 switch (flow->hdr.subtype & 0x3F) {
2458 case ARGUS_FLOW_CLASSIC5TUPLE: {
2459 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
2460 case ARGUS_TYPE_IPV4: {
2461 switch (ns->canon.flow.ip_flow.ip_p) {
2462 case IPPROTO_UDP: {
2463 if (ns->canon.net.hdr.subtype == ARGUS_RTP_FLOW) {
2464 struct ArgusRTPObject *rtp = (void *)&ns->canon.net.net_union.rtp;
2465 retn = rtp->sdrop * 1.0;
2466 }
2467 break;
2468 }
2469
2470 case IPPROTO_ICMP: {
2471 break;
2472 }
2473 case IPPROTO_TCP: {
2474 struct ArgusTCPObject *tcp = (void *)&ns->canon.net.net_union.tcp;
2475
2476 if ((tcp != NULL) && (tcp->state != 0)) {
2477 if (ns->canon.metric.src.pkts)
2478 retn = tcp->src.retrans * 1.0;
2479 }
2480 break;
2481 }
2482 case IPPROTO_ESP: {
2483 struct ArgusESPObject *esp = (void *)&ns->canon.net.net_union.esp;
2484 if (esp != NULL) {
2485 if (ns->canon.metric.src.pkts)
2486 retn = esp->lostseq * 1.0;
2487 }
2488 break;
2489 }
2490 }
2491 break;
2492 }
2493
2494 case ARGUS_TYPE_IPV6: {
2495 switch (flow->ipv6_flow.ip_p) {
2496 case IPPROTO_UDP: {
2497 if (ns->canon.net.hdr.subtype == ARGUS_RTP_FLOW) {
2498 struct ArgusRTPObject *rtp = (void *)&ns->canon.net.net_union.rtp;
2499 retn = rtp->sdrop * 1.0;
2500 }
2501 break;
2502 }
2503
2504 case IPPROTO_ICMP: {
2505 break;
2506 }
2507
2508 case IPPROTO_TCP: {
2509 struct ArgusTCPObject *tcp = (void *)&ns->canon.net.net_union.tcp;
2510
2511 if ((tcp != NULL) && (tcp->state != 0)) {
2512 if (ns->canon.metric.src.pkts)
2513 retn = tcp->src.retrans * 1.0;
2514 }
2515 break;
2516 }
2517 }
2518 }
2519 }
2520 break;
2521 }
2522 }
2523 }
2524 }
2525
2526 return (retn);
2527 }
2528
2529 double
ArgusFetchDstLoss(struct ArgusRecordStruct * ns)2530 ArgusFetchDstLoss (struct ArgusRecordStruct *ns)
2531 {
2532 double retn = 0.0;
2533
2534 if (ns) {
2535 if (ns->hdr.type & ARGUS_MAR) {
2536 } else {
2537 struct ArgusFlow *flow = (struct ArgusFlow *)&ns->canon.flow;
2538 switch (flow->hdr.subtype & 0x3F) {
2539 case ARGUS_FLOW_CLASSIC5TUPLE: {
2540 switch ((flow->hdr.argus_dsrvl8.qual & 0x1F)) {
2541 case ARGUS_TYPE_IPV4: {
2542 switch (ns->canon.flow.ip_flow.ip_p) {
2543 case IPPROTO_UDP: {
2544 if (ns->canon.net.hdr.subtype == ARGUS_RTP_FLOW) {
2545 struct ArgusRTPObject *rtp = (void *)&ns->canon.net.net_union.rtp;
2546 retn = rtp->ddrop * 1.0;
2547 }
2548 }
2549
2550 case IPPROTO_ICMP: {
2551 break;
2552 }
2553 case IPPROTO_TCP: {
2554 struct ArgusTCPObject *tcp = (void *)&ns->canon.net.net_union.tcp;
2555
2556 if ((tcp != NULL) && (tcp->state != 0)) {
2557 if (ns->canon.metric.dst.pkts)
2558 retn = tcp->dst.retrans * 1.0;
2559 }
2560 break;
2561 }
2562 case IPPROTO_ESP: {
2563 struct ArgusESPObject *esp = (void *)&ns->canon.net.net_union.esp;
2564 if (esp != NULL) {
2565 if (ns->canon.metric.dst.pkts)
2566 retn = esp->lostseq * 1.0;
2567 }
2568 }
2569 }
2570 break;
2571 }
2572
2573 case ARGUS_TYPE_IPV6: {
2574 switch (flow->ipv6_flow.ip_p) {
2575 case IPPROTO_UDP: {
2576 if (ns->canon.net.hdr.subtype == ARGUS_RTP_FLOW) {
2577 struct ArgusRTPObject *rtp = (void *)&ns->canon.net.net_union.rtp;
2578 retn = rtp->ddrop * 1.0;
2579 }
2580 break;
2581 }
2582
2583 case IPPROTO_ICMP: {
2584 break;
2585 }
2586
2587 case IPPROTO_TCP: {
2588 struct ArgusTCPObject *tcp = (void *)&ns->canon.net.net_union.tcp;
2589
2590 if ((tcp != NULL) && (tcp->state != 0)) {
2591 if (ns->canon.metric.dst.pkts)
2592 retn = tcp->dst.retrans * 1.0;
2593 }
2594 break;
2595 }
2596 }
2597 }
2598 }
2599 break;
2600 }
2601 }
2602 }
2603 }
2604
2605 return (retn);
2606 }
2607
2608
2609 double
ArgusFetchPercentLoss(struct ArgusRecordStruct * ns)2610 ArgusFetchPercentLoss (struct ArgusRecordStruct *ns)
2611 {
2612 double retn = 0.0;
2613 int pkts = 0;
2614
2615 if (ns) {
2616 retn = ArgusFetchLoss(ns);
2617 pkts = ns->canon.metric.src.pkts + ns->canon.metric.dst.pkts;
2618 if (pkts > 0) {
2619 retn = (retn * 100.0)/((pkts * 1.0 )+ retn);
2620 } else
2621 retn = 0.0;
2622 }
2623
2624 return (retn);
2625 }
2626
2627 double
ArgusFetchPercentSrcLoss(struct ArgusRecordStruct * ns)2628 ArgusFetchPercentSrcLoss (struct ArgusRecordStruct *ns)
2629 {
2630 double retn = 0.0;
2631 int pkts = 0;
2632
2633 if (ns) {
2634 retn = ArgusFetchSrcLoss(ns);
2635 pkts = ns->canon.metric.src.pkts;
2636 if (pkts > 0) {
2637 retn = (retn * 100.0)/((pkts * 1.0) + retn);
2638 } else
2639 retn = 0.0;
2640 }
2641
2642 return (retn);
2643 }
2644
2645 double
ArgusFetchPercentDstLoss(struct ArgusRecordStruct * ns)2646 ArgusFetchPercentDstLoss (struct ArgusRecordStruct *ns)
2647 {
2648 double retn = 0.0;
2649 int pkts = 0;
2650
2651 if (ns) {
2652 retn = ArgusFetchDstLoss(ns);
2653 pkts = ns->canon.metric.dst.pkts;
2654 if (pkts > 0) {
2655 retn = (retn * 100.0)/((pkts * 1.0) + retn);
2656 } else
2657 retn = 0.0;
2658 }
2659
2660 return (retn);
2661 }
2662
2663
2664 double
ArgusFetchSrcRate(struct ArgusRecordStruct * ns)2665 ArgusFetchSrcRate (struct ArgusRecordStruct *ns)
2666 {
2667 struct ArgusMetricStruct *m1 = NULL;
2668 struct timeval ts1buf, *ts1 = &ts1buf;
2669 struct timeval t1buf, *t1d = &t1buf;
2670 long long cnt1 = 0;
2671 float d1, r1 = 0.0;
2672 double retn = 0;
2673
2674 ts1->tv_sec = ns->canon.time.src.start.tv_sec;
2675 ts1->tv_usec = ns->canon.time.src.start.tv_usec;
2676
2677 t1d->tv_sec = ns->canon.time.src.end.tv_sec;
2678 t1d->tv_usec = ns->canon.time.src.end.tv_usec;
2679
2680 t1d->tv_sec -= ts1->tv_sec; t1d->tv_usec -= ts1->tv_usec;
2681 if (t1d->tv_usec < 0) {t1d->tv_sec--; t1d->tv_usec += 1000000;}
2682 d1 = ((t1d->tv_sec * 1.0) + (t1d->tv_usec/1000000.0));
2683
2684 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
2685 cnt1 = m1->src.bytes * 8;
2686
2687 if ((cnt1 > 0) && (d1 > 0.0))
2688 r1 = (cnt1 * 1.0)/d1;
2689
2690 retn = r1;
2691 return (retn);
2692 }
2693
2694 double
ArgusFetchDstRate(struct ArgusRecordStruct * ns)2695 ArgusFetchDstRate (struct ArgusRecordStruct *ns)
2696 {
2697 struct ArgusMetricStruct *m1 = NULL;
2698 struct timeval ts1buf, *ts1 = &ts1buf;
2699 struct timeval t1buf, *t1d = &t1buf;
2700 float d1, r1 = 0.0;
2701 long long cnt1 = 0;
2702 double retn = 0;
2703
2704 ts1->tv_sec = ns->canon.time.src.start.tv_sec;
2705 ts1->tv_usec = ns->canon.time.src.start.tv_usec;
2706
2707 t1d->tv_sec = ns->canon.time.src.end.tv_sec;
2708 t1d->tv_usec = ns->canon.time.src.end.tv_usec;
2709
2710 t1d->tv_sec -= ts1->tv_sec; t1d->tv_usec -= ts1->tv_usec;
2711 if (t1d->tv_usec < 0) {t1d->tv_sec--; t1d->tv_usec += 1000000;}
2712 d1 = ((t1d->tv_sec * 1.0) + (t1d->tv_usec/1000000.0));
2713
2714 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
2715 cnt1 = m1->dst.bytes * 8;
2716
2717 if ((cnt1 > 0) && (d1 > 0.0))
2718 r1 = (cnt1 * 1.0)/d1;
2719
2720 retn = r1;
2721 return (retn);
2722 }
2723
2724 double
ArgusFetchRate(struct ArgusRecordStruct * ns)2725 ArgusFetchRate (struct ArgusRecordStruct *ns)
2726 {
2727 struct ArgusMetricStruct *m1 = NULL;
2728 struct timeval ts1buf, *ts1 = &ts1buf;
2729 struct timeval t1buf, *t1d = &t1buf;
2730 long long cnt1 = 0;
2731 float d1, r1 = 0.0;
2732 double retn = 0;
2733
2734 ts1->tv_sec = ns->canon.time.src.start.tv_sec;
2735 ts1->tv_usec = ns->canon.time.src.start.tv_usec;
2736
2737 t1d->tv_sec = ns->canon.time.src.end.tv_sec;
2738 t1d->tv_usec = ns->canon.time.src.end.tv_usec;
2739
2740 t1d->tv_sec -= ts1->tv_sec; t1d->tv_usec -= ts1->tv_usec;
2741 if (t1d->tv_usec < 0) {t1d->tv_sec--; t1d->tv_usec += 1000000;}
2742 d1 = ((t1d->tv_sec * 1.0) + (t1d->tv_usec/1000000.0));
2743
2744 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL)
2745 cnt1 = (m1->src.bytes + m1->dst.bytes) * 8;
2746
2747 if ((cnt1 > 0) && (d1 > 0.0))
2748 r1 = (cnt1 * 1.0)/d1;
2749
2750 retn = r1;
2751 return (retn);
2752 }
2753
2754 double
ArgusFetchAppByteRatio(struct ArgusRecordStruct * ns)2755 ArgusFetchAppByteRatio (struct ArgusRecordStruct *ns)
2756 {
2757 struct ArgusMetricStruct *m1 = NULL;
2758 double retn = 0.0;
2759
2760 if ((m1 = (struct ArgusMetricStruct *) ns->dsrs[ARGUS_METRIC_INDEX]) != NULL) {
2761 double nvalue = (m1->src.appbytes - m1->dst.appbytes) * 1.0;
2762 double dvalue = (m1->src.appbytes + m1->dst.appbytes) * 1.0;
2763
2764 if (dvalue > 0)
2765 retn = nvalue / dvalue;
2766 else
2767 retn = -0.0;
2768 }
2769 return (retn);
2770 }
2771