1 /*
2  * Copyright (c) 2001 Mark Fullmer and The Ohio State University
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $Id: flow-capture.c,v 1.78 2004/01/05 17:56:50 maf Exp $
27  */
28 
29 #include "ftconfig.h"
30 #include <ftlib.h>
31 
32 #include <sys/time.h>
33 #include <sys/types.h>
34 #include <sys/uio.h>
35 #include <sys/socket.h>
36 #include <sys/param.h>
37 #include <sys/stat.h>
38 #include <sys/wait.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <unistd.h>
44 #include <signal.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <time.h>
48 #include <syslog.h>
49 
50 #if HAVE_STRINGS_H
51  #include <strings.h>
52 #endif
53 
54 #if HAVE_STRING_H
55   #include <string.h>
56 #endif
57 
58 #ifdef HAVE_LIBWRAP
59 #include <tcpd.h>
60 #endif /* HAVE_LIBWRAP */
61 
62 void fterr_exit_handler(int code);
63 
64 #define CAPTURE_PIDFILE    "/var/run/flow-capture.pid"
65 
66 #define SELECT_TIMEOUT 1   /* 1 second */
67 
68 struct client_rec {
69   int fd;
70   struct sockaddr_in addr;
71   int flags;
72   time_t conn_time;
73   struct ftio ftio;
74   FT_LIST_ENTRY (client_rec) chain;
75 };
76 
77 struct client {
78   FT_LIST_HEAD(clienth, client_rec) list;
79   struct sockaddr_in addr;
80   int fd;
81   int enabled; /* listen socket enabled? */
82   int max; /* max connections */
83   int active; /* active connections */
84 #ifdef HAVE_LIBWRAP
85   struct request_info tcpd;
86 #endif /* HAVE_LIBWRAP */
87 };
88 
89 struct rotate {
90   double next;    /* time of next rotation */
91   int    cur;     /* current rotation # */
92   int    n;       /* number per day */
93 };
94 
95 struct file {
96   int fd;                   /* file descriptor */
97   char name[MAXPATHLEN+1];  /* name */
98   char nname[MAXPATHLEN+1]; /* new name */
99   time_t time;
100   struct ftver ftv;
101   off_t nbytes;
102   uint32_t hdr_nflows;
103   uint32_t hdr_flows_corrupt;
104   uint32_t hdr_flows_lost;
105   uint32_t hdr_flows_reset;
106 };
107 
108 int debug;
109 int sig_pipe_flag, sig_quit_flag, sig_hup_flag, sig_chld_flag, sig_term_flag;
110 int reload_flag;
111 void sig_pipe(int);
112 void sig_quit(int);
113 void sig_hup(int);
114 void sig_chld(int);
115 void sig_term(int);
116 pid_t pid;
117 char *pidfile;
118 struct ftnet ftnet;
119 
120 void usage(void);
121 int calc_rotate (int next, double *trotate, int *cur);
122 double doubletime(void);
123 
main(argc,argv)124 int main(argc, argv)
125 int argc;
126 char **argv;
127 {
128 #ifdef IP_ADD_MEMBERSHIP
129   struct ip_mreq mr;
130 #ifdef IP_ADD_SOURCE_MEMBERSHIP
131   struct ip_mreq_source mrs;
132 #endif
133 #endif
134   fd_set rfd;
135   struct sockaddr_in tmp_addr;
136   struct timeval tv;
137   struct tm *tm;
138   struct ftset ftset;
139   struct ftfile_entries fte;
140   struct client client;
141   struct ftio ftio;
142   struct ftpdu ftpdu;
143   struct ftpeeri ftpi;
144   struct ftver ftv;
145   struct ftchash *ftch;
146   struct ftchash_rec_exp ftch_recexp, *ftch_recexpp;
147   struct rotate rot;
148   struct file cap_file;
149   struct fttag fttag;
150   struct ftfil ftfil;
151   struct ftxlate ftxlate;
152   struct fttag_def *ftd;
153   struct ftfil_def *ftfd;
154   struct ftvar ftvar;
155   struct ftxlate_def *ftxd;
156   struct fts3rec_offsets fo;
157   struct client_rec *client_rec, *client_rec2;
158   pid_t child_pid;
159   time_t tt_now, time_startup;
160   double now;
161   char work_dir[MAXPATHLEN+1], post_rotate_exec[MAXPATHLEN+1];
162   int i, n, tmp_len, enable_unlink, offset, detach, nest, one, max_fd;
163   unsigned int v1, v2;
164   uint32_t hash;
165   char fmt_src_ip[32], fmt_dst_ip[32], fmt_dst_port[32];
166   char xl_rec[FT_IO_MAXREC], *out_rec;
167   const char *tag_fname, *tag_active;
168   const char *filter_fname, *filter_active;
169   const char *xlate_fname, *xlate_active;
170   int stat_interval, stat_next, child_status;
171   int v_flag;
172   int preserve_umask;
173 #ifdef IP_RECVDSTADDR
174 #ifdef CMSG_DATA
175   struct cmsghdr *cmsg;
176 #endif
177 #endif
178 
179   time_startup = time(NULL);
180 
181   bzero (&rot, sizeof rot);
182   bzero (&cap_file, sizeof cap_file);
183   bzero (&ftnet, sizeof ftnet);
184   bzero (&tv, sizeof tv);
185   bzero (&work_dir, sizeof work_dir);
186   bzero (&post_rotate_exec, sizeof post_rotate_exec);
187   bzero (&fte, sizeof fte);
188   bzero (&client, sizeof client);
189   bzero (&ftpdu, sizeof ftpdu);
190   bzero (&ftv, sizeof ftv);
191   bzero (&fttag, sizeof fttag);
192   bzero (&ftfil, sizeof ftfil);
193   bzero (&ftxlate, sizeof ftxlate);
194   bzero (&ftvar, sizeof ftvar);
195 
196   FT_LIST_INIT(&client.list);
197   stat_interval = 0;
198   stat_next = -1;
199   v_flag = 0;
200   reload_flag = 1;
201   preserve_umask = 0;
202 
203   tag_fname = FT_PATH_CFG_TAG;
204   tag_active = (char*)0L;
205 
206   filter_fname = FT_PATH_CFG_FILTER;
207   filter_active = (char*)0L;
208 
209   xlate_fname = FT_PATH_CFG_XLATE;
210   xlate_active = (char*)0L;
211 
212   ftfd = (struct ftfil_def*)0L;
213   ftd = (struct fttag_def*)0L;
214   ftxd = (struct ftxlate_def*)0L;
215 
216   /* init fterr */
217   fterr_setid(argv[0]);
218   fterr_setexit(fterr_exit_handler);
219 
220   /* init var binding */
221   if (ftvar_new(&ftvar) < 0)
222     fterr_errx(1, "ftvar_new(): failed");
223 
224   /* defaults + default compression */
225   ftset_init(&ftset, Z_DEFAULT_COMPRESSION);
226 
227   /* default timeout waiting for an active fd */
228   tv.tv_sec = SELECT_TIMEOUT;
229 
230   /* listen for PDU's */
231   ftnet.loc_addr.sin_family = AF_INET;
232   ftnet.loc_addr.sin_addr.s_addr = htonl(INADDR_ANY);
233   ftnet.loc_addr.sin_port = htons(FT_PORT);
234 
235   /* listen for clients */
236   client.addr.sin_family = AF_INET;
237   client.addr.sin_addr.s_addr = htonl(INADDR_ANY);
238   client.addr.sin_port = htons(FT_PORT);
239 
240   /* default detach from parent */
241   detach = 1;
242 
243   /* default 95 rotations per day, or every 15 minutes */
244   rot.n = 95;
245 
246   /* no files initially open */
247   cap_file.fd = -1;
248 
249   /* year/month/day nesting */
250   nest = 3;
251 
252   /* pidfile */
253   pidfile = CAPTURE_PIDFILE;
254 
255   while ((i = getopt(argc, argv,
256     "b:c:C:d:De:E:f:F:hn:N:p:S:t:T:uv:V:w:x:X:z:R:")) != -1)
257 
258     switch (i) {
259 
260     case 'b': /* output byte order */
261       if (!strcasecmp(optarg, "little"))
262         ftset.byte_order = FT_HEADER_LITTLE_ENDIAN;
263       else if (!strcasecmp(optarg, "big"))
264         ftset.byte_order = FT_HEADER_BIG_ENDIAN;
265       else
266         fterr_errx(1, "expecting \"big\" or \"little\" at -b");
267       break;
268 
269     case 'c': /* client enable */
270       client.max = atoi(optarg);
271       break;
272 
273     case 'C': /* comment field */
274       ftset.comments = optarg;
275       break;
276 
277     case 'D': /* daemonize */
278       detach = 0;
279       pidfile = (char*)0L;
280       break;
281 
282     case 'e': /* expire */
283       fte.max_files = atoi(optarg);
284       if (fte.max_files)
285         fte.expiring = 1;
286       break;
287 
288     case 'E': /* expire bytes */
289       if ((fte.max_bytes = scan_size(optarg)) == -1)
290         fterr_errx(1, "scan_size(): failed");
291       if (fte.max_bytes)
292         fte.expiring = 1;
293       break;
294 
295     case 'f': /* filter fname */
296       filter_fname = optarg;
297       break;
298 
299     case 'F': /* filter active */
300       filter_active = optarg;
301       break;
302 
303     case 'd': /* debug */
304       debug = atoi(optarg);
305       break;
306 
307     case 'h': /* help */
308       usage();
309       exit (0);
310       break;
311 
312     case 'n': /* # rotations / day */
313       rot.n = atoi(optarg);
314       /* no more than 1 rotation per minute */
315       if (rot.n > (1440-1))
316         fterr_errx(1, "rotations limited to every 1 minute");
317       break;
318 
319     case 'N': /* nesting level */
320       nest = atoi(optarg);
321       if ((nest < -3) || (nest > 3))
322         fterr_errx(1, "-3 <= nesting level <= 3");
323       break;
324 
325     case 'p': /* pidfile */
326       if ((optarg[0] == 0) || ((optarg[0] == '-') && (optarg[1] == 0)))
327         pidfile = (char*)0L;
328       else
329         pidfile = optarg;
330       break;
331 
332     case 'R': /* Post rotate exec */
333       if (strlen(optarg) > MAXPATHLEN)
334         fterr_errx(1, "Post rotate argument too long");
335       strcpy(post_rotate_exec,optarg);
336       break;
337 
338     case 'S': /* stat interval */
339       stat_interval = atoi(optarg);
340       if ((stat_interval < 0) || (stat_interval > 60))
341         fterr_errx(1, "Stat interval must be between 0 and 60.");
342       break;
343 
344     case 't': /* tag filename */
345       tag_fname = optarg;
346       break;
347 
348     case 'T': /* active tags */
349       tag_active = optarg;
350       /* required for fttag_eval() */
351       ftv.s_version = FT_IO_SVERSION;
352       ftv.d_version = 1005;
353       ftv.set = 1;
354       break;
355 
356     case 'u': /* preserve inherited umask */
357       preserve_umask = 1;
358       break;
359 
360     case 'v': /* variable */
361       if (ftvar_pset(&ftvar, optarg) < 0)
362         fterr_errx(1, "ftvar_pset(%s): failed", optarg);
363       break;
364 
365     case 'V': /* PDU version */
366       v_flag = 1;
367       n = sscanf(optarg, "%u.%u", &v1, &v2);
368       if (n == 1) {
369         ftv.s_version = FT_IO_SVERSION;
370         ftv.d_version = v1;
371         ftv.set = 1;
372       } else if (n == 2) {
373         ftv.s_version = FT_IO_SVERSION;
374         ftv.d_version = v1;
375         ftv.agg_method = v2;
376         ftv.agg_version = 2;
377         ftv.set = 1;
378       } else {
379         fterr_errx(1, "Version scan failed");
380       }
381       break;
382 
383     case 'w': /* working directory */
384       if (strlen(optarg) > (MAXPATHLEN))
385         fterr_errx(1, "Pathname too long");
386       strcpy(work_dir, optarg);
387       break;
388 
389     case 'x': /* xlate file name */
390       xlate_fname = optarg;
391       break;
392 
393     case 'X': /* xlate definition name */
394       xlate_active = optarg;
395       break;
396 
397     case 'z': /* compress level */
398       ftset.z_level = atoi(optarg);
399       if ((ftset.z_level < 0) || (ftset.z_level > 9))
400         fterr_errx(1, "Compression level must be between 0 and 9");
401       break;
402 
403     default:
404       usage();
405       exit (1);
406       break;
407 
408     } /* switch */
409 
410   /* disable pidfile if not forking */
411   if (!detach)
412     pidfile = (char*)0L;
413 
414   if ((argc - optind) != 1)
415     fterr_errx(1, "Specify localip/remoteip/port.");
416 
417   /* tagging forces v1005 */
418   if (v_flag && tag_active && (ftv.d_version != 1005))
419     fterr_errx(1, "Must be v1005 with tagging.");
420 
421   if (!work_dir[0])
422     fterr_errx(1, "Specify workdir with -w.");
423 
424   ftpi = scan_peeri(argv[optind]);
425 
426   ftnet.rem_ip = ftpi.rem_ip;
427   ftnet.loc_ip = ftpi.loc_ip;
428 
429   if (ftpi.dst_port)
430     ftnet.dst_port = ftpi.dst_port;
431   else
432     ftnet.dst_port = FT_PORT;
433 
434   ftnet.loc_addr.sin_addr.s_addr = htonl(ftpi.loc_ip);
435   ftnet.loc_addr.sin_port = htons(ftnet.dst_port);
436   client.addr.sin_port = htons(ftnet.dst_port);
437 
438   /* if debugging is enabled do not unlink any files when aging */
439   if (debug)
440     enable_unlink = 0;
441   else
442     enable_unlink = 1;
443 
444   /* daemonize */
445   if (detach) {
446     if ((pid = fork()) == -1) {
447       fterr_err(1, "fork()");
448     } else if (pid) {
449          exit (0); /* parent */
450     }
451 
452     if (!preserve_umask)
453       umask(0022);
454 
455     setsid();
456 
457     for (n = 0; n < 16; ++n)
458       close (n);
459 
460     /* enable syslog */
461     fterr_setsyslog(1, LOG_PID|LOG_NDELAY, LOG_LOCAL6);
462 
463     /* disable stderr */
464     fterr_setfile(0, (void*)0L);
465 
466   }
467 
468   /*
469    * configure signal handlers
470    */
471 
472   if (mysignal(SIGPIPE, sig_pipe) == SIG_ERR)
473     fterr_err(1, "signal(SIGPIPE)");
474 
475   if (mysignal(SIGHUP, sig_hup) == SIG_ERR)
476     fterr_err(1, "signal(SIGHUP)");
477 
478   if (mysignal(SIGQUIT, sig_quit) == SIG_ERR)
479     fterr_err(1, "signal(SIGQUIT)");
480 
481   if (mysignal(SIGTERM, sig_term) == SIG_ERR)
482     fterr_err(1, "signal(SIGTERM)");
483 
484   if (mysignal(SIGCHLD, sig_chld) == SIG_ERR)
485     fterr_err(1, "signal(SIGCHLD)");
486 
487   /* sandbox */
488   if (chdir(work_dir) == -1)
489     fterr_err(1, "chdir(%s)", work_dir);
490 
491   /*
492    * load directory entries into the file ager
493    */
494   if (fte.expiring)
495     if (ftfile_loaddir(&fte, ".", FT_FILE_SORT|FT_FILE_INIT|FT_FILE_CHECKNAMES))
496       fterr_errx(1, "ftfile_scandir(): failed");
497 
498   /* debugging gets a dump of the ager */
499   if (debug)
500     ftfile_dump(&fte);
501 
502   /* run the ager once now */
503   if (fte.expiring)
504     if (ftfile_expire(&fte, enable_unlink, (uint32_t)0))
505       fterr_errx(1, "ftfile_export(): failed");
506 
507   /* get hostname */
508   if (gethostname((char*)&ftset.hnbuf, FT_HOSTNAME_LEN-1) == -1)
509     fterr_err(1, "gethostname()");
510 
511   /* ensure null terminated */
512   ftset.hnbuf[FT_HOSTNAME_LEN-1] = 0;
513 
514   /* socket to receive flow pdu exports */
515   if ((ftnet.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
516     fterr_err(1, "socket()");
517 
518   if (bigsockbuf(ftnet.fd, SO_RCVBUF, FT_SO_RCV_BUFSIZE) < 0)
519     fterr_err(1, "bigsockbuf()");
520 
521 /* multicast capable? */
522 #ifdef IP_ADD_MEMBERSHIP
523 
524   if (IN_CLASSD(ftpi.rem_ip)) {
525 
526     /* source is the first arg now */
527     ftnet.rem_ip = ftpi.loc_ip;
528     ftnet.loc_ip = ftpi.rem_ip;
529 
530     /* socket API usually requires INADDR_ANY
531      * and s/g/port identifier does not have a source interface field
532      * to use here
533      */
534     bzero(&tmp_addr, sizeof tmp_addr);
535     tmp_addr.sin_family = AF_INET;
536     tmp_addr.sin_port = htons(ftnet.dst_port);
537 
538     one = 1;
539 
540     /* Multicast streams may have multiple receivers */
541     if (setsockopt(ftnet.fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
542       sizeof(one)) < 0)
543       fterr_err(1, "setsockopt(SO_REUSEADDR)");
544 
545     if (bind(ftnet.fd, (struct sockaddr*)&tmp_addr,
546       sizeof(struct sockaddr)) < 0)
547       fterr_err(1, "bind(%s)", inet_ntoa(tmp_addr.sin_addr));
548 
549 #ifdef IP_ADD_SOURCE_MEMBERSHIP
550 
551     /* ssm address? */
552     if (IN_CLASSD_SSM(ftpi.rem_ip)) {
553 
554       mrs.imr_sourceaddr.s_addr = htonl(ftpi.loc_ip);
555       mrs.imr_multiaddr.s_addr = htonl(ftpi.rem_ip);
556       mrs.imr_interface.s_addr = INADDR_ANY;
557 
558       if (setsockopt(ftnet.fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
559         (char*)&mrs, sizeof(mrs)) < 0)
560         fterr_err(1, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)");
561 
562     }
563 
564     goto mcast_done;
565 #endif /* IP_ADD_SOURCE_MEMBERSHIP */
566 
567     mr.imr_multiaddr.s_addr = htonl(ftpi.rem_ip);
568     mr.imr_interface.s_addr = INADDR_ANY;
569 
570     if (setsockopt(ftnet.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
571       (char *)&mr, sizeof(mr)) < 0)
572       fterr_err(1, "setsockopt(IP_ADD_MEMBERSHIP)");
573 
574 
575   } else { /* is a multicast group */
576 
577     /* unicast bind -- multicast support */
578     if (bind(ftnet.fd, (struct sockaddr*)&ftnet.loc_addr,
579       sizeof(ftnet.loc_addr)) < 0)
580       fterr_err(1, "bind(%s)", inet_ntoa(ftnet.loc_addr.sin_addr));
581 
582   } /* not multicast group */
583 
584 #ifdef IP_ADD_SOURCE_MEMBERSHIP
585 mcast_done:
586 #endif /* IP_ADD_SOURCE_MEMBERSHIP */
587 
588 #else /* IP_ADD_MEMBERSHIP */
589 
590   /* unicast bind -- no multicast support */
591   if (bind(ftnet.fd, (struct sockaddr*)&ftnet.loc_addr,
592     sizeof(ftnet.loc_addr)) < 0)
593     fterr_err(1, "bind(%s)", inet_ntoa(ftnet.loc_addr.sin_addr)));
594 
595 #endif /* IP_ADD_MEMBERSHIP */
596 
597 #ifdef IP_RECVDSTADDR
598   one = 1;
599   /* return the destination IP address */
600   if (setsockopt(ftnet.fd, IPPROTO_IP, IP_RECVDSTADDR, (char *)&one,
601     sizeof(one)) < 0)
602     fterr_err(1, "setsockopt(IP_RECVDSTADDR)");
603 #else
604 #ifdef IP_PKTINFO
605   one = 1;
606   /* return the destination IP address */
607   if (setsockopt(ftnet.fd, IPPROTO_IP, IP_PKTINFO, (char *)&one,
608     sizeof(one)) < 0)
609     fterr_err(1, "setsockopt(IP_PKTINFO)");
610 #endif /* else */
611 #endif /* IP_RECVDSTADDR */
612 
613   /* init hash table for demuxing exporters */
614   if (!(ftch = ftchash_new(256, sizeof (struct ftchash_rec_exp), 12, 1)))
615     fterr_errx(1, "ftchash_new(): failed");
616 
617   /* If we bind to the socket we are running and can write the pidfile */
618   if (pidfile)
619        write_pidfile(getpid(), pidfile, ftnet.dst_port);
620 
621   /* init msg block */
622   ftnet.iov[0].iov_len = sizeof ftpdu.buf;
623   ftnet.iov[0].iov_base = (char*)&ftpdu.buf;
624   ftnet.msg.msg_iov = (struct iovec*)&ftnet.iov;
625   ftnet.msg.msg_iovlen = 1;
626   ftnet.msg.msg_name = &ftnet.rem_addr;
627   ftnet.msg.msg_namelen = sizeof ftnet.rem_addr;
628   ftnet.msg.msg_control = &ftnet.msgip;
629 
630 #ifdef CMSG_DATA
631   ftnet.msg.msg_controllen = CMSG_LEN(sizeof(struct sockaddr_storage));
632 #else
633   ftnet.msg.msg_controllen = sizeof ftnet.msgip;
634 #endif
635 
636   while (1) {
637 
638     FD_ZERO (&rfd);
639     FD_SET (ftnet.fd, &rfd);
640 
641     if (client.enabled && client.max) {
642       FD_SET (client.fd, &rfd);
643       max_fd = (client.fd > ftnet.fd) ? client.fd : ftnet.fd;
644     } else {
645       max_fd = ftnet.fd;
646     }
647 
648     if (select (max_fd+1, &rfd, (fd_set *)0, (fd_set *)0, &tv) < 0)  {
649       if (errno == EINTR) {
650         FD_ZERO (&rfd);
651       } else {
652         fterr_err(1, "select()");
653       }
654     }
655 
656     bzero (&tv, sizeof tv);
657     tv.tv_sec = SELECT_TIMEOUT;
658 
659     tt_now = now = doubletime();
660 
661     /* new TCP client connection ? */
662     if ((client.max) && (FD_ISSET(client.fd, &rfd))) {
663 
664       /* too many clients? */
665       if (client.active >= client.max) {
666         /* bye */
667         i = accept(client.fd, (struct sockaddr*)&tmp_addr,
668           (socklen_t*)&tmp_len);
669         close(i);
670         fterr_warnx("Maximum clients exceeded, rejecting connection from %s",
671         inet_ntoa(tmp_addr.sin_addr));
672         goto skip_client;
673       }
674 
675       /* allocate a new client record, fail gracefully */
676       if (!(client_rec = (struct client_rec*)malloc(sizeof *client_rec))) {
677         fterr_warn("malloc()");
678         /* bye */
679         tmp_len = sizeof (struct sockaddr_in);
680         i = accept(client.fd, (struct sockaddr*)&client_rec->addr,
681           (socklen_t*)&tmp_len);
682         close(i);
683         goto skip_client;
684       }
685 
686       bzero(client_rec, sizeof *client_rec);
687 
688       /* link in the new record */
689       FT_LIST_INSERT_HEAD(&client.list, client_rec, chain);
690 
691       tmp_len = sizeof (struct sockaddr_in);
692       /* accept() the connection */
693       if ((client_rec->fd = accept(client.fd,
694         (struct sockaddr*)&client_rec->addr, (socklen_t*)&tmp_len)) < 0) {
695         fterr_warn("accept()");
696         FT_LIST_REMOVE(client_rec, chain);
697         free(client_rec);
698         goto skip_client;
699       }
700 
701 #ifdef HAVE_LIBWRAP
702 
703       request_init(&client.tcpd, RQ_DAEMON, "flow-capture-client", RQ_FILE,
704         client_rec->fd, NULL);
705 
706       fromhost(&client.tcpd);
707 
708       if (!hosts_access(&client.tcpd)) {
709 
710         fterr_warnx("client %s refused by libwrap",
711           inet_ntoa(client_rec->addr.sin_addr));
712 
713         close(client_rec->fd);
714 
715         FT_LIST_REMOVE(client_rec, chain);
716         free(client_rec);
717 
718         goto skip_client;
719 
720       }
721 
722 #endif /* HAVE_LIBWRAP */
723 
724       if (bigsockbuf(client_rec->fd, SO_SNDBUF, FT_SO_SND_BUFSIZE) < 0)
725         fterr_warn("bigsockbuf()");
726 
727       /* log it */
728       client_rec->conn_time = tt_now;
729       fterr_info("client connect: ip=%s time=%lu",
730         inet_ntoa(client_rec->addr.sin_addr),
731         (unsigned long)client_rec->conn_time);
732 
733       /* ftio_init the stream */
734       if (ftio_init(&client_rec->ftio, client_rec->fd,
735         FT_IO_FLAG_NO_SWAP | FT_IO_FLAG_WRITE) < 0) {
736         fterr_warnx("ftio_init(): failed for client");
737         close(client_rec->fd);
738         FT_LIST_REMOVE(client_rec, chain);
739         free(client_rec);
740         goto skip_client;
741       }
742 
743       /* set the version information in the io stream */
744       if (ftio_set_ver(&client_rec->ftio, &ftv) < 0)
745         fterr_errx(1, "ftio_set_ver(): failed");
746 
747       ftio_set_comment(&client_rec->ftio, ftset.comments);
748       ftio_set_cap_hostname(&client_rec->ftio, ftset.hnbuf);
749       ftio_set_byte_order(&client_rec->ftio, ftset.byte_order);
750       ftio_set_cap_time(&client_rec->ftio, cap_file.time, 0);
751       ftio_set_debug(&client_rec->ftio, debug);
752 
753       /* header first */
754       if ((n = ftio_write_header(&client_rec->ftio)) < 0) {
755         fterr_warnx("ftio_write_header(): failed for client");
756         ftio_close(&client_rec->ftio);
757         FT_LIST_REMOVE(client_rec, chain);
758         free(client_rec);
759         goto skip_client;
760       }
761 
762       ++client.active;
763 
764     } /* new TCP client */
765 
766 skip_client:
767 
768     /* stake the zombies */
769 
770     if (sig_chld_flag) {
771 
772       /* not again */
773       sig_chld_flag = 0;
774 
775       while (1) {
776 
777         child_pid = wait3(&child_status, WNOHANG, 0);
778 
779         /* no more dead children? */
780         if (!child_pid)
781           break;
782 
783         /* no more dead children? */
784         if ((child_pid == -1) && (errno == ECHILD))
785           break;
786 
787         if (WIFEXITED(child_status)) {
788 
789           if (WEXITSTATUS(child_status))
790             fterr_warnx("Child %d exit_status=%d", (int)child_pid,
791               WEXITSTATUS(child_status));
792 
793         } else if (WIFSIGNALED(child_status)) {
794 
795           fterr_warnx("Child %d signal=%d", (int)child_pid,
796             WTERMSIG(child_status));
797 
798         } else {
799 
800           fterr_warnx("PID %d exited status=%d", (int)child_pid,
801             child_status);
802 
803         }
804 
805       } /* buffy */
806 
807     } /* sig_chld_flag */
808 
809     if (stat_interval) {
810 
811       tm = localtime (&tt_now);
812 
813       /*
814        * note there is an obscure race condition here if this
815        * code is not reached at least every stat_interval*60 seconds
816        * where up to 1 hour of STAT lines would not show up.
817        * This is highly unlikely and not handled.
818        */
819 
820       if ((tm->tm_min == stat_next) || (stat_next == -1)) {
821 
822         ftchash_first(ftch);
823 
824         while ((ftch_recexpp = ftchash_foreach(ftch))) {
825 
826           fmt_ipv4(fmt_src_ip, ftch_recexpp->src_ip, FMT_JUST_LEFT);
827           fmt_ipv4(fmt_dst_ip, ftch_recexpp->dst_ip, FMT_JUST_LEFT);
828 
829           fterr_info(
830             "STAT: now=%lu startup=%lu src_ip=%s dst_ip=%s d_ver=%d pkts=%lu flows=%lu lost=%lu reset=%lu filter_drops=%lu",
831             (unsigned long)tt_now, (unsigned long)time_startup,
832             fmt_src_ip, fmt_dst_ip,
833             ftch_recexpp->d_version, (u_long)ftch_recexpp->packets,
834             (u_long)ftch_recexpp->flows, (u_long)ftch_recexpp->lost,
835             (u_long)ftch_recexpp->reset, (u_long)ftch_recexpp->filtered_flows);
836 
837         }
838 
839         stat_next = (tm->tm_min + (stat_interval - tm->tm_min % stat_interval))
840           % 60;
841 
842       }
843 
844     } /* stat_inverval */
845 
846     /* flag for work later on */
847     ftpdu.ftd.count = 0;
848 
849     /* PDU ready */
850     if (FD_ISSET(ftnet.fd, &rfd)) {
851 
852 restart_recvmsg:
853 
854       if ((ftpdu.bused = recvmsg(ftnet.fd,
855         (struct msghdr*)&ftnet.msg, 0)) < 0) {
856 
857         if (errno == EAGAIN)
858           goto restart_recvmsg;
859 
860         fterr_err(1, "recvmsg()");
861 
862       }
863 
864 #ifdef IP_RECVDSTADDR
865       /* got destination IP back? */
866 #ifdef CMSG_DATA
867       for (cmsg = CMSG_FIRSTHDR(&ftnet.msg); cmsg != NULL;
868           cmsg = CMSG_NXTHDR(&ftnet.msg, cmsg)) {
869               if (cmsg->cmsg_level == IPPROTO_IP &&
870                   cmsg->cmsg_type == IP_RECVDSTADDR) {
871                       memcpy(&ftnet.loc_addr.sin_addr.s_addr,
872                           CMSG_DATA(cmsg), sizeof(struct in_addr));
873                       break;
874               }
875       }
876 #else
877       if ((ftnet.msgip.hdr.cmsg_level == IPPROTO_IP) &&
878           (ftnet.msgip.hdr.cmsg_type == IP_RECVDSTADDR)) {
879           ftnet.loc_addr.sin_addr.s_addr = ftnet.msgip.ip.s_addr;
880       } else {
881         ftnet.loc_addr.sin_addr.s_addr = 0;
882       }
883 #endif /* CMSG_DATA */
884 #else
885 #ifdef IP_PKTINFO
886       if ((ftnet.msgip.hdr.cmsg_level == IPPROTO_IP) &&
887           (ftnet.msgip.hdr.cmsg_type == IP_PKTINFO)) {
888           ftnet.loc_addr.sin_addr.s_addr = ftnet.msgip.pktinfo.ipi_addr.s_addr;
889       } else {
890         ftnet.loc_addr.sin_addr.s_addr = 0;
891       }
892 #else
893       ftnet.loc_addr.sin_addr.s_addr = 0;
894 #endif
895 #endif /* IP_RECVDSTADDR */
896 
897       /* fill in hash key */
898       ftch_recexp.src_ip = htonl(ftnet.rem_addr.sin_addr.s_addr);
899       ftch_recexp.dst_ip = htonl(ftnet.loc_addr.sin_addr.s_addr);
900       ftch_recexp.dst_port = ftnet.dst_port;
901 
902       /* verify integrity, get version */
903       if (ftpdu_verify(&ftpdu) < 0) {
904         fmt_ipv4(fmt_src_ip, ftch_recexp.src_ip, FMT_JUST_LEFT);
905         fterr_warnx("ftpdu_verify(): src_ip=%s failed.", fmt_src_ip);
906         ++cap_file.hdr_flows_corrupt;
907         goto skip_pdu_decode;
908       }
909 
910       /* rest of hash key */
911       ftch_recexp.d_version = ftpdu.ftv.d_version;
912 
913       /* if exporter src IP has been configured then make sure it matches */
914       if (ftnet.rem_ip && (ftnet.rem_ip != ftch_recexp.src_ip)) {
915         fmt_ipv4(fmt_src_ip, ftch_recexp.src_ip, FMT_JUST_LEFT);
916         fterr_warnx("Unexpected PDU: src_ip=%s not configured", fmt_src_ip);
917         ++cap_file.hdr_flows_corrupt;
918         goto skip_pdu_decode;
919       }
920 
921       /* first flow or no configured destination version? */
922       if (!ftv.set) {
923 
924         /* copy to compare next time */
925         bcopy(&ftpdu.ftv, &ftv, sizeof ftv);
926 
927         /* flag struct as configured */
928         ftv.set = 1;
929 
930       } else {
931 
932         /* translation to/from v8 not possible */
933         if (((ftv.d_version == 8) && (ftpdu.ftv.d_version != 8)) ||
934             ((ftv.d_version != 8) && (ftpdu.ftv.d_version == 8))) {
935           fmt_ipv4(fmt_src_ip, ftch_recexp.dst_ip, FMT_JUST_LEFT);
936           fterr_warnx("Unexpected PDU: src_ip=%s no v8 translation",
937             fmt_src_ip);
938           cap_file.hdr_flows_corrupt ++;
939           goto skip_pdu_decode;
940         }
941 
942         /* translation among v8 aggregation methods not possible */
943         if ((ftv.d_version == 8) && ((ftv.agg_method != ftpdu.ftv.agg_method)
944           || (ftv.agg_version != ftpdu.ftv.agg_version))) {
945           fmt_ipv4(fmt_src_ip, ftch_recexp.dst_ip, FMT_JUST_LEFT);
946           fterr_warnx(
947             "Unexpected PDU: src_ip=%s multi v8 oagg=%d agg=%d over=%d ver=%d",
948             fmt_src_ip, (int)ftv.agg_method, (int)ftpdu.ftv.agg_method,
949             (int)ftv.agg_version, (int)ftpdu.ftv.agg_version);
950           cap_file.hdr_flows_corrupt ++;
951           goto skip_pdu_decode;
952         }
953       } /* version processing */
954 
955       /* compute 8 bit hash */
956       hash = (ftch_recexp.src_ip & 0xFF);
957       hash ^= (ftch_recexp.src_ip>>24);
958       hash ^= (ftch_recexp.dst_ip & 0xFF);
959       hash ^= (ftch_recexp.dst_ip>>24);
960       hash ^= (ftch_recexp.d_version & 0xFF);
961 
962       /* get/create hash table entry */
963       if (!(ftch_recexpp = ftchash_update(ftch, &ftch_recexp, hash)))
964         fterr_errx(1, "ftch_update(): failed");
965 
966       /* if the packet count is 0, then this is a new entry */
967       if (ftch_recexpp->packets == 0) {
968 
969         fmt_ipv4(fmt_src_ip, ftch_recexp.src_ip, FMT_JUST_LEFT);
970         fmt_ipv4(fmt_dst_ip, ftch_recexp.dst_ip, FMT_JUST_LEFT);
971         fterr_info("New exporter: time=%lu src_ip=%s dst_ip=%s d_version=%d",
972           (u_long)tt_now, fmt_src_ip, fmt_dst_ip, (int)ftpdu.ftv.d_version);
973 
974         /* set translation function */
975         if (ftch_recexp.d_version != ftv.d_version)
976           ftch_recexpp->xlate = ftrec_xlate_func(&ftpdu.ftv, &ftv);
977 
978       }
979 
980       /* verify sequence number */
981       if (ftpdu_check_seq(&ftpdu, &(ftch_recexpp->ftseq)) < 0) {
982         fmt_ipv4(fmt_src_ip, ftch_recexp.src_ip, FMT_JUST_LEFT);
983         fmt_ipv4(fmt_dst_ip, ftch_recexp.dst_ip, FMT_JUST_LEFT);
984         fmt_uint16(fmt_dst_port, ftch_recexp.dst_port, FMT_JUST_LEFT);
985         fterr_warnx(
986           "ftpdu_seq_check(): src_ip=%s dst_ip=%s d_version=%d expecting=%lu received=%lu lost=%lu",
987           fmt_src_ip, fmt_dst_ip, (int)ftpdu.ftv.d_version,
988           (u_long)ftch_recexpp->ftseq.seq_exp,
989           (u_long)ftch_recexpp->ftseq.seq_rcv,
990           (u_long)ftch_recexpp->ftseq.seq_lost);
991 
992         /* only count these lost if "lost" is a reasonable number */
993         if (ftch_recexpp->ftseq.seq_lost < FT_SEQ_RESET) {
994           cap_file.hdr_flows_lost += ftch_recexpp->ftseq.seq_lost;
995           ftch_recexpp->lost += ftch_recexpp->ftseq.seq_lost;
996         } else {
997           cap_file.hdr_flows_reset ++;
998           ftch_recexpp->reset ++;
999         }
1000       }
1001 
1002       /* decode the pdu */
1003       ftpdu.ftd.byte_order = ftset.byte_order;
1004       ftpdu.ftd.exporter_ip = ftch_recexp.src_ip;
1005       n = fts3rec_pdu_decode(&ftpdu);
1006 
1007       /* update the exporter stats */
1008       ftch_recexpp->packets ++;
1009       ftch_recexpp->flows += n;
1010 
1011     } /* PDU on receive buffer */
1012 
1013 skip_pdu_decode:
1014 
1015     /* no current file and pdu version has been set -> create file */
1016     if ((cap_file.fd == -1) && (ftv.d_version)) {
1017 
1018       /* calculate the current rotation and next rotate time */
1019       if (calc_rotate(rot.n, &rot.next, &rot.cur) == -1)
1020         fterr_errx(1, "calc_rotate(): failed");
1021 
1022       /* remember when file was created */
1023       cap_file.time = (uint32_t)tt_now;
1024 
1025       /* remember the version encoded in the filename */
1026       bcopy(&ftv, &cap_file.ftv, sizeof cap_file.ftv);
1027 
1028       /* construct the capture file name */
1029       ftfile_pathname(cap_file.name, MAXPATHLEN, nest, cap_file.ftv, 0,
1030         cap_file.time);
1031 
1032       /* create directory path for file */
1033       if (ftfile_mkpath(cap_file.time, nest) < 0)
1034         fterr_err(1, "ftfile_mkpath(%s)", cap_file.name);
1035 
1036       /* create/open the capture file */
1037       if ((cap_file.fd = open(cap_file.name, O_WRONLY|O_CREAT|O_TRUNC, 0644))
1038         == -1)
1039         fterr_err(1, "open(%s)", cap_file.name);
1040 
1041       /* initialize the IO stream */
1042       if (ftio_init(&ftio, cap_file.fd, FT_IO_FLAG_NO_SWAP | FT_IO_FLAG_WRITE |
1043         ((ftset.z_level) ? FT_IO_FLAG_ZINIT : 0) ) < 0)
1044         fterr_errx(1, "ftio_init(): failed");
1045 
1046       /* set the version information in the io stream */
1047       if (ftio_set_ver(&ftio, &ftv) < 0)
1048         fterr_errx(1, "ftio_set_ver(): failed");
1049 
1050       /* need offsets for filter later */
1051       fts3rec_compute_offsets(&fo, &ftv);
1052 
1053       ftio_set_comment(&ftio, ftset.comments);
1054       ftio_set_cap_hostname(&ftio, ftset.hnbuf);
1055       ftio_set_byte_order(&ftio, ftset.byte_order);
1056       ftio_set_z_level(&ftio, ftset.z_level);
1057       ftio_set_cap_time(&ftio, cap_file.time, 0);
1058       ftio_set_debug(&ftio, debug);
1059       ftio_set_corrupt(&ftio, cap_file.hdr_flows_corrupt);
1060       ftio_set_lost(&ftio, cap_file.hdr_flows_lost);
1061       ftio_set_reset(&ftio, cap_file.hdr_flows_reset);
1062       ftio_set_flows_count(&ftio, cap_file.hdr_nflows);
1063 
1064 /*      ftio_map_load(&ftio, FT_MAP_FILE, ftnet.rem_ip); */
1065 
1066       /* header first */
1067       if ((n = ftio_write_header(&ftio)) < 0)
1068         fterr_errx(1, "ftio_write_header(): failed");
1069       else
1070         cap_file.nbytes = n;
1071 
1072     } /* create capture file and init new io stream */
1073 
1074     /* load filters and tags? */
1075     if (reload_flag && ftv.set) {
1076 
1077       /* load tags */
1078       if (tag_active) {
1079 
1080         /* not first time through, then free previous tags */
1081         if (ftd) {
1082           fttag_free(&fttag);
1083           fterr_info("Reloading tags.");
1084         }
1085 
1086         if (fttag_load(&fttag, &ftvar, tag_fname) < 0)
1087           fterr_errx(1, "fttag_load(): failed");
1088 
1089         if (!(ftd = fttag_def_find(&fttag, tag_active)))
1090           fterr_errx(1, "fttag_load(): failed");
1091 
1092       } /* tag_active */
1093 
1094       /* load filters */
1095       if (filter_active) {
1096 
1097         /* not first time through, then free previous filters */
1098         if (ftfd) {
1099           ftfil_free(&ftfil);
1100           fterr_info("Reloading filters.");
1101         }
1102 
1103         if (ftfil_load(&ftfil, &ftvar, filter_fname))
1104           fterr_errx(1, "ftfil_load(%s): failed", filter_fname);
1105 
1106         if (!(ftfd = ftfil_def_find(&ftfil, filter_active)))
1107           fterr_errx(1, "ftfil_def_find(%s): failed", filter_active);
1108 
1109         if (ftfil_def_test_xfields(ftfd, ftrec_xfield(&ftv)))
1110           fterr_errx(1, "Filter references a field not in flow.");
1111 
1112       } /* filter_active */
1113 
1114       /* load translations */
1115       if (xlate_active) {
1116 
1117         /* not first time through, then free previous translations */
1118         if (ftxd) {
1119           ftxlate_free(&ftxlate);
1120           fterr_info("Reloading translations.");
1121         }
1122 
1123         if (ftxlate_load(&ftxlate, &ftvar, xlate_fname))
1124           fterr_errx(1, "ftxlate_load(%s): failed", xlate_fname);
1125 
1126         if (!(ftxd = ftxlate_def_find(&ftxlate, xlate_active)))
1127           fterr_errx(1, "ftlate_def_find(%s): failed", xlate_active);
1128 
1129         if (ftxlate_def_test_xfields(ftxd, ftrec_xfield(&ftv)))
1130           fterr_errx(1, "Xlate references a field not in flow.");
1131 
1132       } /* xlate_active */
1133 
1134       reload_flag = 0;
1135 
1136     } /* reload_flag */
1137 
1138     /* if the decode buffer has entries write them out */
1139     for (i = 0, offset = 0; i < ftpdu.ftd.count;
1140       ++i, offset += ftpdu.ftd.rec_size) {
1141 
1142       /* translate version? */
1143       if (ftch_recexpp->xlate) {
1144 
1145         ftch_recexpp->xlate(ftpdu.ftd.buf+offset, &xl_rec);
1146 
1147         out_rec = (char*)&xl_rec;
1148 
1149         /* tagging? */
1150         if (tag_active)
1151           fttag_def_eval(ftd, (struct fts3rec_v1005*)out_rec);
1152 
1153       } else {
1154 
1155         out_rec = (char*)ftpdu.ftd.buf+offset;
1156 
1157       }
1158 
1159       /* filter? */
1160       if (ftfd)
1161         if (ftfil_def_eval(ftfd, out_rec, &fo) == FT_FIL_MODE_DENY) {
1162           ++ftch_recexpp->filtered_flows;
1163           continue;
1164         }
1165 
1166       /* xlate? */
1167       if (ftxd)
1168         if (ftxlate_def_eval(ftxd, out_rec, &fo) != 0)
1169           fterr_errx(1, "ftxlate_def_eval(): failed.");
1170 
1171       /* update # of flows stored in capture file */
1172       cap_file.hdr_nflows ++;
1173 
1174       if ((n = ftio_write(&ftio, out_rec)) < 0)
1175         fterr_errx(1, "ftio_write(): failed");
1176 
1177       /* write to clients */
1178       FT_LIST_FOREACH(client_rec, &client.list, chain) {
1179 
1180         if ((n = ftio_write(&client_rec->ftio, out_rec)) < 0) {
1181 
1182           fterr_info("Killed client: ip=%s, dtime=%lu",
1183             inet_ntoa(client_rec->addr.sin_addr),
1184             (unsigned long)tt_now - client_rec->conn_time);
1185 
1186           ftio_close(&client_rec->ftio);
1187           client_rec2 = client_rec;
1188           client_rec = client_rec->chain.le_next;
1189           FT_LIST_REMOVE(client_rec2, chain);
1190           free(client_rec2);
1191           --client.active;
1192 
1193           if (!client_rec)
1194             break;
1195 
1196         } /* ftio_write */
1197 
1198       } /* foreach client */
1199 
1200       /* update # of bytes stored in capture file */
1201       cap_file.nbytes += n;
1202 
1203     } /* foreach entry in decode buffer */
1204 
1205     /*
1206      * time for a new file ?
1207      */
1208     if ((now > rot.next) || sig_term_flag || sig_quit_flag || sig_hup_flag) {
1209 
1210       if (sig_hup_flag)
1211         fterr_info("SIGHUP");
1212 
1213       sig_hup_flag = 0; /* re-arm */
1214 
1215       if (cap_file.fd != -1) {
1216 
1217         ftio_set_cap_time(&ftio, cap_file.time, (uint32_t)tt_now);
1218         ftio_set_corrupt(&ftio, cap_file.hdr_flows_corrupt);
1219         ftio_set_lost(&ftio, cap_file.hdr_flows_lost);
1220         ftio_set_reset(&ftio, cap_file.hdr_flows_reset);
1221         ftio_set_flows_count(&ftio, cap_file.hdr_nflows);
1222 
1223         /* re-write header first */
1224         if (ftio_write_header(&ftio) < 0)
1225           fterr_errx(1, "ftio_write_header(): failed");
1226 
1227         if ((n = ftio_close(&ftio)) < 0)
1228           fterr_errx(1, "ftio_close(): failed");
1229 
1230         cap_file.nbytes += n;
1231 
1232         /* construct final version of capture filename */
1233         ftfile_pathname(cap_file.nname, MAXPATHLEN, nest, cap_file.ftv, 1,
1234           cap_file.time);
1235 
1236         /* rename working to final */
1237         if (rename(cap_file.name, cap_file.nname) == -1)
1238           fterr_err(1, "rename(%s,%s)", cap_file.name, cap_file.nname);
1239 
1240         /* add it to the ager */
1241         if (fte.expiring)
1242           if (ftfile_add_tail(&fte, cap_file.nname, cap_file.nbytes,
1243             cap_file.time))
1244             fterr_errx(1, "ftfile_add_tail(%s): failed", cap_file.name);
1245 
1246         /* debugging gets a dump of the ager */
1247         if (debug)
1248           ftfile_dump(&fte);
1249 
1250 	/* Do the post rotate exec */
1251         if (post_rotate_exec[0]) {
1252 
1253           if ((n = fork()) == -1) {
1254 
1255             fterr_err(1, "fork()");
1256 
1257           } else if (!n) { /* child */
1258 
1259             n = execl(post_rotate_exec, post_rotate_exec, cap_file.nname,
1260                 NULL);
1261 
1262             if (n == -1)
1263               fterr_err(1, "exec(%s)", post_rotate_exec);
1264 
1265             _exit(0);
1266           } /* child */
1267         } /* post rotate exec */
1268 
1269 	/* reset */
1270         bzero(&cap_file, sizeof cap_file);
1271 
1272         /* invalidate file descriptor */
1273         cap_file.fd = -1;
1274 
1275         /* had enough */
1276         if (sig_quit_flag || sig_term_flag)
1277           goto main_exit;
1278       } /* file open */
1279 
1280     } /* time for new file */
1281 
1282     /* also need to check sig_quit if no file has been processed yet */
1283     if (sig_quit_flag || sig_term_flag)
1284       goto main_exit;
1285 
1286   /*
1287    * If client attachments are enabled, and the flow version has been
1288    * determined setup a listener, but only once.
1289    */
1290   if (ftv.set && client.max && !client.enabled) {
1291 
1292     /* socket for listen */
1293     if ((client.fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
1294       fterr_err(1, "socket()");
1295 
1296     one = 1;
1297 
1298     if (setsockopt(client.fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one,
1299       sizeof (one)))
1300       fterr_err(1, "setsockopt(SO_REUSEADDR)");
1301 
1302     if (bind(client.fd, (struct sockaddr*)&client.addr, sizeof (client.addr))
1303       < 0)
1304       fterr_err(1, "bind(%s)", inet_ntoa(client.addr.sin_addr));
1305 
1306     /* listen for new TCP connections */
1307     if (listen(client.fd, 5) < 0)
1308       fterr_err(1, "listen()");
1309 
1310     /* non blocking */
1311     if (fcntl(client.fd, F_SETFL, O_NONBLOCK) < 0)
1312       fterr_err(1, "fcntl()");
1313 
1314     client.enabled = 1;
1315 
1316   } /* clients enabled */
1317 
1318 
1319     if (!(cap_file.hdr_nflows % 1001)) {
1320 
1321       if (fte.expiring)
1322         if (ftfile_expire(&fte, enable_unlink, cap_file.nbytes))
1323           fterr_errx(1, "ftfile_expire(): failed");
1324 
1325     } /* ager run? */
1326 
1327   } /* while 1 */
1328 
1329 main_exit:
1330 
1331   if (pidfile)
1332     unlink_pidfile(pid, pidfile, ftnet.dst_port);
1333 
1334   if (sig_quit_flag)
1335     fterr_info("SIGQUIT");
1336 
1337   if (sig_term_flag)
1338     fterr_info("SIGTERM");
1339 
1340   /* free storage allocated to file entries */
1341   if (fte.expiring)
1342     ftfile_free(&fte);
1343 
1344   return 0;
1345 
1346 } /* main */
1347 
sig_pipe(int signo)1348 void sig_pipe(int signo)
1349 {
1350   sig_pipe_flag = 1;
1351 }
1352 
sig_hup(int signo)1353 void sig_hup(int signo)
1354 {
1355   sig_hup_flag = 1;
1356   reload_flag = 1;
1357 }
1358 
sig_quit(int signo)1359 void sig_quit(int signo)
1360 {
1361   sig_quit_flag = 1;
1362 }
1363 
sig_term(int signo)1364 void sig_term(int signo)
1365 {
1366   sig_term_flag = 1;
1367 }
1368 
sig_chld(int signo)1369 void sig_chld(int signo)
1370 {
1371   sig_chld_flag = 1;
1372 }
1373 
1374 /* doubletime - like time(2), but returns a double (with fractional seconds)
1375  * This was inspired by the Time::HiRes perl module.  E.g.:
1376  *    $ perl -MTime::HiRes -le 'print scalar Time::HiRes::time'
1377  * See "perl/CPAN/authors/id/D/DE/DEWEG/Time-HiRes-01.20.tar.gz".
1378  * - Dave Plonka <plonka@doit.wisc.edu>
1379  */
doubletime(void)1380 double doubletime(void) {
1381    double now;
1382    struct timeval tv_now;
1383    if (-1 == gettimeofday(&tv_now, (struct timezone *)0))
1384       return -1;
1385    now = tv_now.tv_sec + (tv_now.tv_usec / 1000000.0);
1386    return now;
1387 }
1388 
calc_rotate(int next,double * trotate,int * cur)1389 int calc_rotate (int next, double *trotate, int *cur)
1390 {
1391   double now;       /* current time */
1392   time_t tt_now;    /* current time */
1393   double irotate;   /* interval of next in seconds */
1394   time_t morning;   /* start of the day */
1395   struct tm *tm1;
1396 
1397   irotate = 86400. / (next+1);
1398 
1399   *cur = 0;
1400 
1401   if (-1 == (tt_now = now = doubletime()))
1402     return -1;
1403 
1404   /* calculate start of the day */
1405   if (!(tm1 = localtime (&tt_now)))
1406      return -1;
1407 
1408   tm1->tm_sec = 0;
1409   tm1->tm_min = 0;
1410   tm1->tm_hour = 0;
1411 
1412   if ((morning = mktime(tm1)) == -1)
1413     return -1;
1414 
1415   if (next)
1416     *trotate = morning + irotate;
1417   else
1418     *trotate = morning + 86400.;
1419 
1420   while (now > *trotate) {
1421 
1422     ++ *cur;
1423     *trotate += irotate;
1424 
1425   }
1426 
1427   return 0;
1428 
1429 } /* calc_rotate */
1430 
fterr_exit_handler(int code)1431 void fterr_exit_handler(int code)
1432 {
1433   if (pid && pidfile)
1434     unlink_pidfile(pid, pidfile, ftnet.dst_port);
1435   exit (code);
1436 } /* fterr_exit_handler */
1437 
usage(void)1438 void usage(void) {
1439 
1440   fprintf(stderr, "Usage: flow-capture [-hu] [-b big|little]\n");
1441   fprintf(stderr, "       [-C comment] [-c flow_clients] [-d debug_level] [-D daemonize]\n");
1442   fprintf(stderr, "       [-e expire_count] [-E expire_size[bKMG]] [-n rotations]\n");
1443   fprintf(stderr, "       [-N nesting_level] [-p pidfile ] [-R rotate_program]\n");
1444   fprintf(stderr, "       [-S stat_interval] [-t tag_fname] [-T tag_active] [-V pdu_version]\n");
1445   fprintf(stderr, "       [-z z_level] [-x xlate_fname] [-X xlate_active]\n");
1446   fprintf(stderr, "       -w workdir localip/remoteip/port\n");
1447   fprintf(stderr, "Signals:\n");
1448   fprintf(stderr, "   SIGHUP  - close and rotate current file\n");
1449   fprintf(stderr, "   SIGQUIT - close current file and exit\n");
1450 
1451 } /* usage */
1452 
1453