1 --- apps/cflowd/cflowd.cc_dwm Sat Oct 16 05:45:45 1999
2 +++ apps/cflowd/cflowd.cc Thu Apr 20 22:15:03 2000
4 //===========================================================================
7 +#include <errno.h> /* errno, EINTR */
8 +#include <fcntl.h> /* fcntl, open, O_CREAT, O_WRONLY, O_TRUNC, O_RDWR */
9 +#include <math.h> /* log */
10 +#include <signal.h> /* signal, SIGCHLD, SIGTERM, SIGPIPE, SIGTTOU, SIG_IGN */
11 +#include <stddef.h> /* NULL */
12 +#include <stdio.h> /* rename, EOF, fprintf, stderr */
13 +#include <stdlib.h> /* exit, strtoul */
14 +#include <string.h> /* memset, strcpy, strlen, memcpy */
15 +#include <sys/termios.h> /* termios */
16 +#include <sys/wait.h> /* wait, waitpid, WNOHANG */
17 +#include <time.h> /* time, time_t, difftime, strftime, localtime, tm, gmtime */
18 +#include <unistd.h> /* unlink, close, fork, write, read, setpgid, getpid */
19 +static time_t mutt_local_tz (time_t t);
21 #include <sys/types.h>
22 -#include <sys/wait.h>
23 #include <sys/ioctl.h>
26 #ifdef HAVE_SYS_FILIO_H
28 #include <sys/filio.h>
34 +#include <strstream.h>
36 #include "CflowdConfig.hh"
37 #include "CflowdConfigLex.hh"
38 #include "CflowdTableRequest.hh"
40 static int g_tableSockFd = -1;
41 static CflowdPacketQueue g_packetQueue;
42 bool g_cflowdDebug = false;
43 +static time_t g_logtimeout = (time_t) -1;
44 +static int g_logfd = -1;
45 +static int g_skip_output_if = -1;
46 +static int g_retain_multicast = 0; // boolean
47 +static unsigned long g_multimask = inet_addr("240.0.0.0");
48 +static unsigned long g_multinet = inet_addr("224.0.0.0");
49 Signal g_sigChld(SIGCHLD);
50 Signal g_sigTerm(SIGTERM);
53 int numPackets, numFlows;
55 CflowdCiscoMap::iterator ciscoMapIter;
59 uint16_t exportVersion;
63 numFlows = flowArrNum;
66 + if ((time_t)-1 != g_logtimeout) {
68 + if (-1 == g_logfd || difftime(now, then) > g_logtimeout) {
69 + string current, previous;
71 + // remember when we rename(2)d the previous log file:
74 + // generate the current timestamp with trailing "hours east" of UTC:
75 + static char date[sizeof "YYYYMMDD_HH:MI:SS+0000"];
76 + strftime(date, sizeof date, "%Y%m%d_%H:%M:%S", localtime(&now));
77 + time_t tz = mutt_local_tz(now);
78 + tz /= 60; // convert to minutes
79 + sprintf(date+sizeof "YYYYMMDD_HH:MI:SS" - sizeof "", "%+03d%02d",
80 + (int)tz/60, (int)abs(tz)%60);
82 + current = g_cflowdConfig.FlowDirectory();
83 + current += "/flows.current";
85 + previous = g_cflowdConfig.FlowDirectory();
86 + previous += "/flows.";
89 + if (-1 != g_logfd) { // rename current log file to previous:
91 + if (-1 == rename(current.c_str(), previous.c_str())) {
92 + syslog(LOG_ERR,"[E] rename(\"%s\", \"%s\"): %m {%s:%d}",
93 + current.c_str(), previous.c_str(),
94 + __FILE__, __LINE__);
98 + // open a new current log file:
99 + g_logfd = open(current.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
100 + if (-1 == g_logfd) {
102 + "[E] open(\"%s\", O_CREAT | O_WRONLY | O_TRUNC): %m {%s:%d}",
103 + current.c_str(), __FILE__, __LINE__);
108 for (flowNum = 0; flowNum < numFlows; flowNum++) {
109 ciscoMapIter = g_cflowdConfig.CiscoMap().find(flows[flowNum].Router());
110 if (ciscoMapIter != g_cflowdConfig.CiscoMap().end()) {
111 ((*ciscoMapIter).second)->AddFlow(flows[flowNum]);
113 + // if (the output interface is the one we were asked to skip &&
114 + // (we weren't asked to retain multicast flows ||
115 + // this isn't a multicast flow))
116 + if (g_skip_output_if == flows[flowNum].OutputIfIndex() &&
117 + (!g_retain_multicast ||
118 + (g_multimask & flows[flowNum].DstIpAddr()) != g_multinet)) {
122 + if (-1 != g_logfd) flows[flowNum].Write(g_logfd);
126 @@ -851,11 +926,39 @@
128 char *configFilename = NULL;
130 - while ((optChar = getopt(argc,argv,"D")) != EOF) {
131 + while ((optChar = getopt(argc,argv,"Ds:O:m")) != EOF) {
134 g_cflowdDebug = true;
139 + g_logtimeout = strtoul(optarg, &unconv, 10);
140 + if ('\0' != *unconv) {
141 + fprintf(stderr, "usage cflowd [ -s logtimeout_seconds [ -O skip_output_if [-m] ] ]\n");
149 + g_skip_output_if = strtoul(optarg, &unconv, 10);
150 + if ('\0' != *unconv) {
151 + fprintf(stderr, "usage cflowd [ -s logtimeout_seconds [ -O skip_output_if [-m] ] ]\n");
156 + case 'm': // retain multicast traffic even if we're skipping output_if 0
157 + // (Multicast flows always show the output_if as 0.)
158 + if (-1 == g_skip_output_if) {
159 + fprintf(stderr, "usage cflowd [ -s logtimeout_seconds [ -O skip_output_if [-m] ] ]\n");
162 + g_retain_multicast = 1;
175 + * Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>
177 + * This program is free software; you can redistribute it and/or modify
178 + * it under the terms of the GNU General Public License as published by
179 + * the Free Software Foundation; either version 2 of the License, or
180 + * (at your option) any later version.
182 + * This program is distributed in the hope that it will be useful,
183 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
184 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
185 + * GNU General Public License for more details.
187 + * You should have received a copy of the GNU General Public License
188 + * along with this program; if not, write to the Free Software
189 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
192 +/* returns the seconds east of UTC given `g' and its corresponding gmtime()
194 +static time_t compute_tz (time_t g, struct tm *utc)
196 + struct tm *lt = localtime (&g);
200 + t = (((lt->tm_hour - utc->tm_hour) * 60) + (lt->tm_min - utc->tm_min)) * 60;
202 + if ((yday = (lt->tm_yday - utc->tm_yday)))
204 + /* This code is optimized to negative timezones (West of Greenwich) */
205 + if (yday == -1 || /* UTC passed midnight before localtime */
206 + yday > 1) /* UTC passed new year before localtime */
215 +/* Returns the local timezone in seconds east of UTC for the time t,
216 + * or for the current time if t is zero.
218 +static time_t mutt_local_tz (time_t t)
226 + /* need to make a copy because gmtime/localtime return a pointer to
227 + static memory (grr!) */
228 + memcpy (&utc, ptm, sizeof (utc));
229 + return (compute_tz (t, &utc));