📄 flow-receive.c
字号:
/* * Copyright (c) 2001 Mark Fullmer and The Ohio State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: flow-receive.c,v 1.51 2003/04/02 18:03:02 maf Exp $ */#include "ftconfig.h"#include <ftlib.h>#include <sys/time.h>#include <sys/types.h>#include <sys/uio.h>#include <sys/socket.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <time.h>#include <fcntl.h>#if HAVE_STRINGS_H #include <strings.h>#endif#if HAVE_STRING_H #include <string.h>#endif#include "ftbuild.h"int debug;int done;void usage(void);void sig_quit(int);#define SELECT_TIMEOUT 1 /* 1 second */int main(int argc, char **argv){#ifdef IP_ADD_MEMBERSHIP struct sockaddr_in tmp_addr; struct ip_mreq mr;#ifdef IP_ADD_SOURCE_MEMBERSHIP struct ip_mreq_source mrs;#endif#endif struct timeval tv; struct tm *tm; struct stat stat_buf; struct ftio ftio; struct ftset ftset; struct ftpdu ftpdu; struct ftnet ftnet; struct ftpeeri ftpi; struct ftver ftv; struct ftipmask ftipmask; struct ftchash *ftch; struct ftchash_rec_exp ftch_recexp, *ftch_recexpp; struct fttag fttag; struct ftfil ftfil; struct fttag_def *ftd; struct ftfil_def *ftfd; struct fts3rec_offsets fo; time_t now, time_startup; int i, n, offset, out_fd, out_fd_plain, one; unsigned int v1, v2; fd_set rfd; char *out_fname; u_int32 filtered_flows, nflows, time_start, time_end; u_int32 flows_corrupt, flows_lost, flows_reset; u_int32 privacy_mask, hash; char fmt_src_ip[32], fmt_dst_ip[32], fmt_dst_port[32]; char xl_rec[FT_IO_MAXREC], *out_rec; char *tag_fname, *tag_active; char *filter_fname, *filter_active; int stat_interval, stat_next; time_startup = time((time_t)0L); privacy_mask = 0xFFFFFFFF; out_fname = (char*)0L; filtered_flows = nflows = 0; out_fd_plain = 0; out_fd = -1; ftset.z_level = 0; done = 0; bzero(&tv, sizeof tv); bzero(&ftnet, sizeof ftnet); bzero(&ftv, sizeof ftv); bzero(&ftpdu, sizeof ftpdu); bzero(&ftch_recexp, sizeof ftch_recexp); bzero(&fttag, sizeof fttag); bzero(&ftfil, sizeof ftfil); flows_corrupt = flows_lost = flows_reset = 0; stat_interval = 0; stat_next = -1; tag_fname = FT_PATH_CFG_TAG; tag_active = (char*)0L; filter_fname = FT_PATH_CFG_FILTER; filter_active = (char*)0L; ftfd = (struct ftfil_def*)0L; ftd = (struct fttag_def*)0L; /* init fterr */ fterr_setid(argv[0]); /* defaults + no compression */ ftset_init(&ftset, 0); /* listen for PDU's */ ftnet.loc_addr.sin_family = AF_INET; ftnet.loc_addr.sin_addr.s_addr = htonl(INADDR_ANY); ftnet.loc_addr.sin_port = htons(FT_PORT); while ((i = getopt(argc, argv, "A:b:C:d:f:F:h?m:o:S:t:T:V:z:")) != -1) switch (i) { case 'A': /* AS substitution */ ftset.as_sub = atoi(optarg); break; case 'b': /* output byte order */ if (!strcasecmp(optarg, "little")) ftset.byte_order = FT_HEADER_LITTLE_ENDIAN; else if (!strcasecmp(optarg, "big")) ftset.byte_order = FT_HEADER_BIG_ENDIAN; else fterr_errx(1, "expecting \"big\" or \"little\""); break; case 'C': /* comment field */ ftset.comments = optarg; break; case 'd': /* debug */ debug = atoi(optarg); break; case 'f': /* filter fname */ filter_fname = optarg; break; case 'F': /* filter active */ filter_active = optarg; break; case 'h': /* help */ case '?': usage(); exit (0); break; case 'm': /* privacy mask */ privacy_mask = scan_ip(optarg); break; case 'o': /* output filename */ out_fname = optarg; break; case 'S': /* stat interval */ stat_interval = atoi(optarg); if ((stat_interval < 0) || (stat_interval > 60)) fterr_errx(1, "Stat interval must be between 0 and 60."); break; case 't': /* tag filename */ tag_fname = optarg; break; case 'T': /* active tag */ tag_active = optarg; break; case 'V': /* PDU version */ n = sscanf(optarg, "%u.%u", &v1, &v2); if (n == 1) { ftv.s_version = FT_IO_SVERSION; ftv.d_version = v1; ftv.set = 1; } else if (n == 2) { ftv.s_version = FT_IO_SVERSION; ftv.d_version = v1; ftv.agg_method = v2; ftv.agg_version = 2; ftv.set = 1; } else fterr_errx(1, "Version scan failed"); break; case 'z': /* compress level */ ftset.z_level = atoi(optarg); if ((ftset.z_level < 0) || (ftset.z_level > 9)) fterr_errx(1, "Compression level must be between 0 and 9"); break; default: usage(); exit (1); break; } /* switch */ /* load tags */ if (tag_active) { if (ftv.set) fterr_errx(1, "-V not supported with tagging."); if (fttag_load(&fttag, tag_fname) < 0) fterr_errx(1, "fttag_load(%s): failed", tag_fname); if (!(ftd = fttag_def_find(&fttag, tag_active))) fterr_errx(1, "fttag_def_find(%s): failed", tag_active); /* required for fttag_eval() */ ftv.s_version = FT_IO_SVERSION; ftv.d_version = 1005; ftv.set = 1; } /* tag_active */ /* load filters */ if (filter_active) { if (ftfil_load(&ftfil, filter_fname)) fterr_errx(1, "ftfil_load(%s): failed", filter_fname); if (!(ftfd = ftfil_def_find(&ftfil, filter_active))) fterr_errx(1, "ftfil_def_find(%s): failed", filter_active); } /* filter_active */ /* setup for ftrec_mask_ip */ if (privacy_mask != 0xFFFFFFFF) ftrec_compute_mask(&ftipmask, privacy_mask, privacy_mask, ftset.byte_order); /* number of unprocessed options */ n = argc - optind; /* loc_ip/rem_ip/port */ if (n == 1) { ftpi = scan_peeri(argv[optind]); ftnet.rem_ip = ftpi.rem_ip; ftnet.loc_ip = ftpi.loc_ip; if (ftpi.dst_port) ftnet.dst_port = ftpi.dst_port; else ftnet.dst_port = FT_PORT; ftnet.loc_addr.sin_addr.s_addr = htonl(ftpi.loc_ip); ftnet.loc_addr.sin_port = htons(ftnet.dst_port); } else if (n == 0) { /* defaults */ } else { fterr_errx(1, "Illegal option: %s", argv[optind+1]); } /* * configure signal handlers */ if (mysignal(SIGQUIT, sig_quit) == SIG_ERR) fterr_err(1, "signal(SIGQUIT)"); if (mysignal(SIGHUP, sig_quit) == SIG_ERR) fterr_err(1, "signal(SIGHUP)"); if (mysignal(SIGINT, sig_quit) == SIG_ERR) fterr_err(1, "signal(SIGINT)"); if (mysignal(SIGTERM, sig_quit) == SIG_ERR) fterr_err(1, "signal(SIGTERM)"); /* get hostname */ if (gethostname((char*)&ftset.hnbuf, (int)FT_HOSTNAME_LEN-1) == -1) fterr_err(1, "gethostname()"); ftset.hnbuf[FT_HOSTNAME_LEN-1] = 0; if ((ftnet.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) fterr_err(1, "socket()"); if (bigsockbuf(ftnet.fd, SO_RCVBUF, FT_SO_RCV_BUFSIZE) < 0) fterr_err(1, "bigsockbuf()");/* multicast capable? */#ifdef IP_ADD_MEMBERSHIP if (IN_CLASSD(ftpi.rem_ip)) { /* source is the first arg now */ ftnet.rem_ip = ftpi.loc_ip; ftnet.loc_ip = ftpi.rem_ip; /* socket API usually requires INADDR_ANY * and s/g/port identifier does not have a source interface field * to use here */ bzero(&tmp_addr, sizeof tmp_addr); tmp_addr.sin_family = AF_INET; tmp_addr.sin_port = htons(ftnet.dst_port); one = 1; /* Multicast streams may have multiple receivers */ if (setsockopt(ftnet.fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) fterr_err(1, "setsockopt(SO_REUSEADDR)"); if (bind(ftnet.fd, (struct sockaddr*)&tmp_addr, sizeof(struct sockaddr)) < 0) fterr_err(1, "bind(mcast-rcv)");#ifdef IP_ADD_SOURCE_MEMBERSHIP /* ssm address? */ if (IN_CLASSD_SSM(ftpi.rem_ip)) { mrs.imr_sourceaddr.s_addr = htonl(ftpi.loc_ip); mrs.imr_multiaddr.s_addr = htonl(ftpi.rem_ip); mrs.imr_interface.s_addr = INADDR_ANY; if (setsockopt(ftnet.fd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char*)&mrs, sizeof(mrs)) < 0) fterr_err(1, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)"); } goto mcast_done;#endif /* IP_ADD_SOURCE_MEMBERSHIP */ mr.imr_multiaddr.s_addr = htonl(ftpi.rem_ip); mr.imr_interface.s_addr = INADDR_ANY; if (setsockopt(ftnet.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mr, sizeof(mr)) < 0) fterr_err(1, "setsockopt(IP_ADD_MEMBERSHIP)"); } else { /* is a multicast group */ /* unicast bind -- multicast support */ if (bind(ftnet.fd, (struct sockaddr*)&ftnet.loc_addr, sizeof(ftnet.loc_addr)) < 0) fterr_err(1, "bind()"); } /* not multicast group */#ifdef IP_ADD_SOURCE_MEMBERSHIPmcast_done:#endif /* IP_ADD_SOURCE_MEMBERSHIP */#else /* IP_ADD_MEMBERSHIP */ /* unicast bind -- no multicast support */ if (bind(ftnet.fd, (struct sockaddr*)&ftnet.loc_addr, sizeof(ftnet.loc_addr)) < 0) fterr_err(1, "bind()");#endif /* IP_ADD_MEMBERSHIP */#ifdef IP_RECVDSTADDR one = 1; /* return the destination IP address */ if (setsockopt(ftnet.fd, IPPROTO_IP, IP_RECVDSTADDR, (char *)&one, sizeof(one)) < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -