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

📄 flow-send.c

📁 netflow,抓包
💻 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-send.c,v 1.26 2003/04/04 02:24:40 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 <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <stdlib.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;void usage(void);void pdu_xmit(int tx_delay, int src_ip_spoof, int hdr_len,  struct ip *ip_hdr, struct udphdr *udp_hdr,  int sock, struct ftencode *fte, struct ftpeeri *ftpi);int main(int argc, char **argv){  struct sockaddr_in loc_addr, rem_addr;  struct ip *ip_hdr;  struct udphdr *udp_hdr;  struct ftio ftio;  struct ftprof ftp;  struct ftver ftv, ftv2;  struct ftencode fte;  struct ftpeeri ftpi;  struct ftipmask ftipmask;  void (*xlate)(void *in_rec, void *out_rec);  char xl_rec[FT_IO_MAXREC], *out_rec;  u_int32 privacy_mask;  unsigned int v1, v2, one;  int i, n, ret, tx_delay, udp_sock;  int src_ip_spoof, hdr_len;  void *rec;  /* init fterr */  fterr_setid(argv[0]);  tx_delay = 1;  bzero(&loc_addr, sizeof (struct sockaddr_in));  bzero(&rem_addr, sizeof (struct sockaddr_in));  bzero(&ftv, sizeof ftv);  privacy_mask = 0xFFFFFFFF;  src_ip_spoof = 0; /* no */  /* profile */  ftprof_start (&ftp);  while ((i = getopt(argc, argv, "d:h?m:sV:x:")) != -1)    switch (i) {    case 'd': /* debug */      debug = atoi(optarg);      break;    case 'h': /* help */    case '?':      usage();      exit (0);      break;    case 'm': /* privacy mask */      privacy_mask = scan_ip(optarg);      break;    case 's': /* source ip preserve */      src_ip_spoof = 1;      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': /* transmitter delay */      tx_delay = atoi(optarg);      break;    default:      usage();      exit (1);      break;    } /* switch */  /* expect IP address/port option */  if ((argc - optind) != 1) {    usage();    exit (1);  }  /* get localip/rem_ip/port/ttl */  ftpi = scan_peeri(argv[optind]);  /* default ttl to 255 if this is unicast */  if (!(IN_CLASSD(ftpi.rem_ip)) && (!ftpi.ttl))    ftpi.ttl = 255;  rem_addr.sin_addr.s_addr = htonl(ftpi.rem_ip);  rem_addr.sin_family = AF_INET;   if (ftpi.dst_port)     rem_addr.sin_port = htons(ftpi.dst_port);  else    rem_addr.sin_port = htons(FT_PORT);  loc_addr.sin_addr.s_addr = htonl(ftpi.loc_ip);  loc_addr.sin_family = AF_INET;    /* if preserving source IP address then these are raw sockets */    if (src_ip_spoof) {          if ((udp_sock = 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(udp_sock, IPPROTO_IP, IP_HDRINCL,        &one, sizeof(one)) < 0) {        fterr_err(1, "setsockopt(IP_HDRINCL)");      }#endif /* IP_HDRINCL */  } else {    /* normal UDP */    if ((udp_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)      fterr_err(1, "socket()");  }  if (bigsockbuf(udp_sock, SO_SNDBUF, FT_SO_SND_BUFSIZE) < 0)    fterr_err(1, "bigsockbuf()");#ifdef IP_ADD_MEMBERSHIP  /* multicast destination? */  if ((!src_ip_spoof) &&     (IN_CLASSD(ntohl(rem_addr.sin_addr.s_addr)))) {     u_char ttl = ftpi.ttl;    /* set the ttl */    if (setsockopt(udp_sock, IPPROTO_IP, IP_MULTICAST_TTL,      (char*)&ttl, sizeof(ttl)) < 0) {      fterr_err(1, "setsockopt(IP_MULTICAST_TTL=%d)", ttl);    }  } /* mcast */#endif /* IP_ADD_MEMBERSHIP */  if (!src_ip_spoof) {    if (bind(udp_sock, (struct sockaddr*)&loc_addr, sizeof loc_addr) < 0)      fterr_err(1, "bind()");  }      if (connect(udp_sock, (struct sockaddr*)&rem_addr, sizeof rem_addr) < 0)    fterr_err(1, "connect()");  /* read from stdin */  if (ftio_init(&ftio, 0, FT_IO_FLAG_READ) < 0)    fterr_errx(1, "ftio_init(): failed");  /* 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;  }  /* copy version from io stream */  ftio_get_ver(&ftio, &ftv2);  if (ftv.set)    bcopy(&ftv, &fte.ver, sizeof ftv);  else    bcopy(&ftv2, &fte.ver, sizeof ftv2);  /* translation? */  if (fte.ver.d_version != ftv2.d_version) {    if (!(xlate = ftrec_xlate_func(&ftv2, &fte.ver)))      fterr_errx(1, "ftrec_xlate_func(): failed");  } else {    xlate = (void*)0L;  }  /* setup for ftrec_mask_ip */  if (privacy_mask != 0xFFFFFFFF)    ftrec_compute_mask(&ftipmask, privacy_mask, privacy_mask,      ftio.fth.byte_order);  while ((rec = ftio_read(&ftio))) {    /* simple privacy */    if (privacy_mask != 0xFFFFFFFF)         ftrec_mask_ip(rec, &fte.ver, &ftipmask);    /* translate? */    if (xlate) {      xlate(rec, &xl_rec);      out_rec = (char*)&xl_rec;    } else {      out_rec = rec;    }retry:    ret = fts3rec_pdu_encode(&fte, out_rec);/*   ret == 0 then send and clear out buffer *   ret > 0 then encode another *   ret < 0 then this encoding failed, send and clear out buffer*/    if (ret <= 0) {      pdu_xmit(tx_delay, src_ip_spoof, hdr_len, ip_hdr, udp_hdr, udp_sock,        &fte, &ftpi);      /* if ret < 0 then the current record was not encoded */      if (ret < 0)        goto retry;    }  }  /* any left over? */  if (fte.buf_size) {    pdu_xmit(tx_delay, src_ip_spoof, hdr_len, ip_hdr, udp_hdr, udp_sock,      &fte, &ftpi);  } /* fte.buf_size */    if (debug > 0) {    ftprof_end(&ftp, ftio_get_rec_total(&ftio));    ftprof_print(&ftp, argv[0], stderr);  }  return ret;} /* main */void pdu_xmit(int tx_delay, int src_ip_spoof, int hdr_len,  struct ip *ip_hdr, struct udphdr *udp_hdr,  int sock, struct ftencode *fte, struct ftpeeri *ftpi){  int sum;  /* convert pdu to network byte order */#if BYTE_ORDER == LITTLE_ENDIAN  ftpdu_swap(fte->buf_enc, BYTE_ORDER);#endif /* BYTE_ORDER == LITTLE_ENDIAN */  /* do this once */  ftencode_sum_data(fte);  if (src_ip_spoof) {/* see Stevens Unix Network Programming Volume 1 2nd edition page 657 *//* conditional from <simon@limmat.switch.ch> rawsend.c */#if defined (__linux__) || (defined (__OpenBSD__) && (OpenBSD > 199702))    ip_hdr->ip_len = htons(FT_ENC_IPHDR_LEN+fte->buf_size);#else    ip_hdr->ip_len = FT_ENC_IPHDR_LEN+fte->buf_size;#endif    ip_hdr->ip_ttl = ftpi->ttl;    ip_hdr->ip_src.s_addr = htonl(ftpi->loc_ip);    ip_hdr->ip_dst.s_addr = htonl(ftpi->rem_ip);    udp_hdr->uh_sport = htons(7999);    udp_hdr->uh_dport = htons(ftpi->dst_port);    udp_hdr->uh_ulen = htons(fte->buf_size+8);    udp_hdr->uh_sum = 0;    sum = fte->d_sum;    sum += udp_cksum(ip_hdr, udp_hdr, fte->buf_size+8);    sum = (sum >> 16) + (sum & 0xffff);    sum += (sum >> 16);    udp_hdr->uh_sum = ~sum;  } again:   if (send(sock, (char*)&fte->buf, fte->buf_size+hdr_len, 0) < 0) {    /* always complete a send, drop flows in the kernel on receive if       overloaded */    if (errno == ENOBUFS) {      usleep(1);      goto again;    }    if (errno != ECONNREFUSED)      fterr_warn("send()");  }  if (tx_delay)    usleep((unsigned)tx_delay);  /* reset encode buffer */  ftencode_reset(fte);} /* pdu_xmit */void usage(void) {  fprintf(stderr, "Usage: flow-send [-h] [-d debug_level] [-x xmit_delay] [-V pdu_version]\n");  fprintf(stderr, "       localip/remoteip/port\n");  fprintf(stderr, "\n%s version %s: built by %s\n", PACKAGE, VERSION, FT_PROG_BUILD);} /* usage */

⌨️ 快捷键说明

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