⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flow-fanout.c

📁 netflow,抓包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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-fanout.c,v 1.39 2003/04/04 02:24:40 maf Exp $ */#include "ftconfig.h"#include <ftlib.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/uio.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <arpa/inet.h>#include <errno.h>#include <syslog.h>#include <signal.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <time.h>#if HAVE_STRINGS_H #include <strings.h>#endif#if HAVE_STRING_H  #include <string.h>#endif#include "ftbuild.h"#define FANOUT_PIDFILE    "/var/run/flow-fanout.pid"#define SELECT_TIMEOUT 5   /* 5 seconds */int debug;char *pidfile;void usage(void);struct peer {  int fd;  struct sockaddr_in loc_addr; /* us */  struct sockaddr_in rem_addr; /* them */  int port;  int ttl;};void fterr_exit_handler(int code);int sig_quit_flag, sig_hup_flag;void sig_quit(int), sig_hup(int);pid_t pid;u_int16 listen_port;void pdu_xmit(int npeers, int tx_delay, int src_ip_spoof, int hdr_len,  u_int32 *send_nobufs, struct ip *ip_hdr, struct udphdr *udp_hdr,  struct ftencode *fte, struct peer *peers, struct ftnet *ftnet);int main(int argc, char **argv){  struct sockaddr_in tmp_addr;#ifdef IP_ADD_MEMBERSHIP  struct ip_mreq mr;#ifdef IP_ADD_SOURCE_MEMBERSHIP  struct ip_mreq_source mrs;#endif#endif  struct timeval tv;  struct tm *tm;  time_t now, time_startup;  fd_set rfd;  struct ip *ip_hdr;  struct udphdr *udp_hdr;  struct ftpeeri ftpi;  struct ftpdu ftpdu;  struct ftver ftv;  struct ftnet ftnet;  struct ftchash *ftch;  struct ftchash_rec_exp ftch_recexp, *ftch_recexpp;  struct ftencode fte;  struct ftfil ftfil;  struct ftfil_def *ftfd;  struct fts3rec_offsets fo;  struct ftset ftset;  struct peer *peers;  struct ftipmask ftipmask;  u_int32 flows_corrupt, flows_lost, flows_reset, hash, privacy_mask;  u_int32 send_nobufs;  unsigned int v1, v2;  char fmt_src_ip[32], fmt_dst_ip[32], fmt_dst_port[32];  char xl_rec[FT_IO_MAXREC], *out_rec;  char *filter_fname, *filter_active;  int i, n, detach, one, ret, offset, hdr_len;  int npeers, tx_delay;  int stat_interval, stat_next, src_ip_spoof;  time_startup = time((time_t)0L);  /* init fterr */  fterr_setid(argv[0]);  fterr_setexit(fterr_exit_handler);  bzero(&ftpdu, sizeof ftpdu);  bzero(&ftv, sizeof ftv);  bzero(&ftnet, sizeof ftnet);  bzero(&ftch_recexp, sizeof ftch_recexp);  bzero(&tv, sizeof tv);  bzero(&ftfil, sizeof ftfil);  stat_interval = 0;  stat_next = -1;  src_ip_spoof = 0; /* no */  hdr_len = 0;  send_nobufs = 0;  filter_fname = FT_PATH_CFG_FILTER;  filter_active = (char*)0L;  ftfd = (struct ftfil_def*)0L;  /* pidfile */  pidfile = FANOUT_PIDFILE;  /* by default do not mask any src/dst ip addr bits */  privacy_mask = 0xFFFFFFFF;  /* defaults + default compression */  ftset_init(&ftset, Z_DEFAULT_COMPRESSION);  flows_corrupt = flows_lost = flows_reset = 0;  debug = 0;  tx_delay = 0;  detach = 1;  while ((i = getopt(argc, argv, "A:d:Df:F:hm:p:sS:V:x:")) != -1)    switch (i) {    case 'A': /* AS substitution */      ftset.as_sub = atoi(optarg);      break;    case 'd': /* debug */      debug = atoi(optarg);      break;    case 'D': /* detach */      detach = 0;      break;    case 'f': /* filter fname */      filter_fname = optarg;      break;      case 'F': /* filter active */      filter_active = optarg;      break;    case 'h': /* help */      usage();      exit (0);      break;    case 'm': /* privacy mask */      privacy_mask = scan_ip(optarg);      break;    case 'p': /* pidfile */      if ((optarg[0] == 0) || ((optarg[0] == '-') && (optarg[1] == 0)))        pidfile = (char*)0L;      else        pidfile = optarg;      break;    case 's': /* source ip preserve */      src_ip_spoof = 1;      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 '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 'x': /* transmit delay */      tx_delay = atoi(optarg);      break;    default:      usage();      exit (1);      break;    } /* switch */  /* initialize encode struct */  ftencode_init(&fte, (src_ip_spoof) ? FT_ENC_FLAGS_IPHDR : 0);  /* if src ip spoofing, initialize the IP/UDP header */  if (src_ip_spoof) {    ip_hdr = (struct ip*)&fte.buf;    udp_hdr = (struct udphdr*)((char*)&fte.buf + sizeof (*ip_hdr));    ip_hdr->ip_hl = 5;    ip_hdr->ip_v = 4;    ip_hdr->ip_p = 17; /* UDP */    hdr_len = FT_ENC_IPHDR_LEN;  }  /* initialize encoder version */  if (ftv.set)    bcopy(&ftv, &fte.ver, sizeof ftv);  /* allocate argc - optind peer entries */  npeers = argc - optind - 1;  if (npeers < 1)    fterr_errx(1, "Must define at least source and one destination.");  /* pre-scan so write_pidfile has the port */  ftpi = scan_peeri(argv[optind]);  listen_port = (ftpi.dst_port) ? ftpi.dst_port : FT_PORT;  if (mysignal(SIGQUIT, sig_quit) == SIG_ERR)    fterr_err(1, "signal(SIGQUIT)");  if (mysignal(SIGHUP, sig_hup) == SIG_ERR)    fterr_err(1, "signal(SIGHUP)");  /* daemonize */  if (detach) {      if ((pid = fork()) == -1) {      fterr_err(1, "fork()");    } else if (pid) {      if (pidfile)        write_pidfile(pid, pidfile, listen_port);      exit (0); /* parent */    }       chdir ("/");     umask(0022);    setsid();    for (n = 0; n < 16; ++n) /* XXX dynamically get NOFILE */      close (n);        /* enable syslog */    fterr_setsyslog(1, LOG_PID|LOG_NDELAY, LOG_LOCAL6);    /* disable stderr */    fterr_setfile(0, (void*)0L);  }  if (!(peers = (struct peer*)malloc(npeers * sizeof (struct peer))))    fterr_err(1, "malloc()");  /* zero out malloc'd memory */  bzero(peers, npeers*sizeof(struct peer));  /* pick off destinations, fill in peer entries */  for (i = optind+1, n = 0; i < argc; ++i, ++n) {    /* parse loc_ip/rem_ip/port/ttl */    ftpi = scan_peeri(argv[i]);    /* default UDP destination port is FT_PORT */    peers[n].rem_addr.sin_port = (ftpi.dst_port) ? htons(ftpi.dst_port)      : htons(FT_PORT);    peers[n].loc_addr.sin_family = AF_INET;    peers[n].rem_addr.sin_family = AF_INET;    peers[n].ttl = ftpi.ttl;    /* default ttl to 255 if this is unicast */    if (!(IN_CLASSD(ftpi.rem_ip)) && (!ftpi.ttl))      peers[n].ttl = 255;    /* reverse remote and local if multicast */    if ((n == 0) && (IN_CLASSD(ftpi.rem_ip))) {      peers[n].loc_addr.sin_addr.s_addr = htonl(ftpi.rem_ip);      peers[n].rem_addr.sin_addr.s_addr = htonl(ftpi.loc_ip);    } else {      peers[n].rem_addr.sin_addr.s_addr = htonl(ftpi.rem_ip);      peers[n].loc_addr.sin_addr.s_addr = htonl(ftpi.loc_ip);    }    /* if preserving source IP address then these are raw sockets */    if (src_ip_spoof) {      if ((peers[n].fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)        fterr_err(1, "socket()");/* see Stevens Unix Network Programming Volume 1 2nd edition page 657 */#ifdef IP_HDRINCL      one = 1;      if (setsockopt(peers[n].fd, IPPROTO_IP, IP_HDRINCL,        &one, sizeof(one)) < 0) {        fterr_err(1, "setsockopt(IP_HDRINCL)");      }#endif /* IP_HDRINCL */    } else { /* normal UDP */      if ((peers[n].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)        fterr_err(1, "socket()");    }    if (bigsockbuf(peers[n].fd, SO_SNDBUF, FT_SO_SND_BUFSIZE) < 0)      fterr_err(1, "bigsockbuf()");      #ifdef IP_ADD_MEMBERSHIP      /* multicast destination? */    if ((!src_ip_spoof) &&        (IN_CLASSD(ntohl(peers[n].rem_addr.sin_addr.s_addr)))) {         u_char ttl = peers[n].ttl;        /* set the ttl */      if (setsockopt(peers[n].fd, IPPROTO_IP, IP_MULTICAST_TTL,        (char*)&ttl, sizeof(ttl)) < 0) {        fterr_err(1, "setsockopt(IP_MULTICAST_TTL=%d)", ttl);      }    } /* multicast */     #endif /* IP_ADD_MEMBERSHIP */       if (!src_ip_spoof) {       if (bind(peers[n].fd, (struct sockaddr*)&peers[n].loc_addr,        sizeof(struct sockaddr)) < 0)        fterr_err(1, "bind(xmit)");    }    if (connect(peers[n].fd, (struct sockaddr*)&peers[n].rem_addr,      sizeof(struct sockaddr)) < 0)      fterr_err(1, "connect(xmit)");  } /* for each destination */  /* first arg is the listener, scan it and store away in ftnet */  ftpi = scan_peeri(argv[optind]);    ftnet.rem_ip = ftpi.rem_ip;  ftnet.loc_ip = ftpi.loc_ip;  /* default UDP listen port is FT_PORT */  ftnet.dst_port = (ftpi.dst_port) ? ftpi.dst_port : FT_PORT;    ftnet.loc_addr.sin_addr.s_addr = htonl(ftpi.loc_ip);  ftnet.loc_addr.sin_port = htons(ftnet.dst_port);  /* socket to receive flow pdu exports */  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()");  /*   * setup to receive flows   *//* 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -