pcap_dumper_t* createPcapFile(pcap_t* handle, FILE* f){
  pcap_dumper_t *dumpdesc= pcap_dump_fopen(handle,f);
  if(dumpdesc == NULL){
    printf("ERROR dump\n");
    exit(1);
  }
  return dumpdesc;
}
PacketFilter_PcapLogger::PacketFilter_PcapLogger(ConfigParser *cfg) {
    std::string filename = cfg->get("PacketFilter_PcapLogger::filename");
    pkt_count = 0;
    file = fopen(filename.c_str(), "w");
    pcap_file = pcap_open_dead(DLT_USB_LINUX, SNAP_LEN);
    if (pcap_file == NULL)
        fprintf(stderr, "Unable to open pcap file for output\n");
    pcap_writer = pcap_dump_fopen(pcap_file, file);
    pcap_dump_flush(pcap_writer);

    if (pcap_writer == NULL) {
        fprintf(stderr, "Unable to open pcap dumper for output\n");
        pcap_close(pcap_file);
    }
    pthread_mutex_init(&pcap_writer_mutex, NULL);
}
Ejemplo n.º 3
0
Archivo: pdump.c Proyecto: aissat/vde2
static int set_dumper(FILE *console) {
	int fd;
	FILE *fp;
	if ((fd = open(dumpfile, O_WRONLY | O_CREAT, 0600)) < 0) {
		printoutc(console, "%s() open(%s): %s", __FUNCTION__, dumpfile, strerror(errno));
		return -1;
	}
	if ((fp = fdopen(fd, "w")) == NULL) {
		printoutc(console, "%s() fdopen(): %s", __FUNCTION__, strerror(errno));
		return -1;
	}
	if ((dumper = pcap_dump_fopen(desc, fp)) == NULL) {
		printoutc(console, "%s() pcap_dump_fopen(): %s", __FUNCTION__, pcap_geterr(desc));
		return -1;
	}
	return 0;
}
void PCAPExporterPipe::startProcess()
{
	char errbuf[PCAP_ERRBUF_SIZE];
	close(fd[0]);
	close(fd[1]);

	if (pipe(fd)) {
		THROWEXCEPTION("pipe() command failed");
	}
	FILE *f = fdopen(fd[1], "w");
	if (! f) {
		THROWEXCEPTION("fdopen failed");
	}
	dumper = pcap_dump_fopen(dummy, f);
	if (!dumper) {
		THROWEXCEPTION("Could not open dump file: %s", errbuf);
	}
	fifoReaderPid = execCmd(fifoReaderCmd);
	msg(MSG_INFO, "Restarted process with fifoReaderCmd \'%s\' and fifoReaderPid = %d",
						fifoReaderCmd.c_str(), fifoReaderPid);
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
	const char *from_dev = NULL;			/* Capture from device */
	const char *from_file = NULL;			/* Read from pcap file */
	int from_stdin = 0;				/* Read from stdin */
	
	pcap_t *in;					/* PCAP input handle */
	
	int limit = -1;					/* How many packets to sniff */
	
	char errbuf[PCAP_ERRBUF_SIZE];			/* Error buffer */

	char *to_file = NULL;				/* PCAP output file */
	
	char *pcap_filter = NULL;			/* PCAP filter string */
	char *radius_filter = NULL;
	int port = 1812;
	
	struct bpf_program fp;				/* Holds compiled filter */
	bpf_u_int32 ip_mask = PCAP_NETMASK_UNKNOWN;	/* Device Subnet mask */
	bpf_u_int32 ip_addr = 0;			/* Device IP */
	
	char buffer[1024];

	int opt;
	FR_TOKEN parsecode;
	const char *radius_dir = RADIUS_DIR;
	
	fr_debug_flag = 2;
	log_dst = stdout;

	/*
	 *  Get options
	 */
	while ((opt = getopt(argc, argv, "c:d:Ff:hi:I:p:qr:s:Svw:xX")) != EOF) {
		switch (opt)
		{
		case 'c':
			limit = atoi(optarg);
			if (limit <= 0) {
				fprintf(stderr, "radsniff: Invalid number of packets \"%s\"\n", optarg);
				exit(1);
			}
			break;
		case 'd':
			radius_dir = optarg;
			break;
		case 'F':
			from_stdin = 1;
			to_stdout = 1;
			break;
		case 'f':
			pcap_filter = optarg;
			break;
		case 'h':
			usage(0);
			break;
		case 'i':
			from_dev = optarg;
			break;
		case 'I':
			from_file = optarg;
			break;
		case 'p':
			port = atoi(optarg);
			break;
		case 'q':
			if (fr_debug_flag > 0) {
				fr_debug_flag--;
			}
			break;
		case 'r':
			radius_filter = optarg;
			break;
		case 's':
			radius_secret = optarg;
			break;
		case 'S':
			do_sort = 1;
			break;
		case 'v':
			INFO(log_dst, "%s %s\n", radsniff_version, pcap_lib_version());
			exit(0);
			break;
		case 'w':
			to_file = optarg;
			break;
		case 'x':
		case 'X':
		  	fr_debug_flag++;
			break;
		default:
			usage(64);
		}
	}
	
	/* What's the point in specifying -F ?! */
	if (from_stdin && from_file && to_file) {
		usage(64);
	}
	
	/* Can't read from both... */
	if (from_file && from_dev) {
		usage(64);
	}
	
	/* Reading from file overrides stdin */
	if (from_stdin && (from_file || from_dev)) {
		from_stdin = 0;
	}
	
	/* Writing to file overrides stdout */
	if (to_file && to_stdout) {
		to_stdout = 0;
	}
	
	/*
	 *  If were writing pcap data stdout we *really* don't want to send
	 *  logging there as well.
	 */
 	log_dst = to_stdout ? stderr : stdout;

#if !defined(HAVE_PCAP_FOPEN_OFFLINE) || !defined(HAVE_PCAP_DUMP_FOPEN)
	if (from_stdin || to_stdout) {
		fprintf(stderr, "radsniff: PCAP streams not supported.\n");
		exit(64);
	}
#endif

	if (!pcap_filter) {
		pcap_filter = buffer;
		snprintf(buffer, sizeof(buffer), "udp port %d or %d or %d",
			 port, port + 1, 3799);
	}
	
	/*
	 *  There are times when we don't need the dictionaries.
	 */
	if (!to_stdout) {
		if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
			fr_perror("radsniff");
			exit(64);
		}
	}

	if (radius_filter) {
		parsecode = userparse(radius_filter, &filter_vps);
		if (parsecode == T_OP_INVALID) {
			fprintf(stderr, "radsniff: Invalid RADIUS filter \"%s\" (%s)\n", radius_filter, fr_strerror());
			exit(64);
		}
		
		if (!filter_vps) {
			fprintf(stderr, "radsniff: Empty RADIUS filter \"%s\"\n", radius_filter);
			exit(64);
		}

		filter_tree = rbtree_create((rbcmp) fr_packet_cmp, free, 0);
		if (!filter_tree) {
			fprintf(stderr, "radsniff: Failed creating filter tree\n");
			exit(1);
		}
	}

	/*
	 *  Setup the request tree
	 */
	request_tree = rbtree_create((rbcmp) fr_packet_cmp, free, 0);
	if (!request_tree) {
		fprintf(stderr, "radsniff: Failed creating request tree\n");
		exit(1);
	}

	/*
	 *  Allocate a null packet for decrypting attributes in CoA requests
	 */
	nullpacket = rad_alloc(NULL, 0);
	if (!nullpacket) {
		fprintf(stderr, "radsniff: Out of memory\n");
		exit(1);
	}

	/*
	 *  Get the default capture device
	 */
	if (!from_stdin && !from_file && !from_dev) {
		from_dev = pcap_lookupdev(errbuf);
		if (!from_dev) {
			fprintf(stderr, "radsniff: Failed discovering default interface (%s)\n", errbuf);
			exit(1);
		}

		INFO(log_dst, "Capturing from interface \"%s\"\n", from_dev);
	}
	
	/*
	 *  Print captures values which will be used
	 */
	if (fr_debug_flag > 2) {
				DEBUG1(log_dst, "Sniffing with options:\n");
		if (from_dev)	DEBUG1(log_dst, "  Device		   : [%s]\n", from_dev);
		if (limit > 0)	DEBUG1(log_dst, "  Capture limit (packets)  : [%d]\n", limit);
				DEBUG1(log_dst, "  PCAP filter	      : [%s]\n", pcap_filter);
				DEBUG1(log_dst, "  RADIUS secret	    : [%s]\n", radius_secret);
		if (filter_vps){DEBUG1(log_dst, "  RADIUS filter	    :\n");
			vp_printlist(log_dst, filter_vps);
		}
	}

	/*
	 *  Figure out whether were doing a reading from a file, doing a live
	 *  capture or reading from stdin.
	 */
	if (from_file) {
		in = pcap_open_offline(from_file, errbuf);
#ifdef HAVE_PCAP_FOPEN_OFFLINE
	} else if (from_stdin) {
		in = pcap_fopen_offline(stdin, errbuf);
#endif
	} else if (from_dev) {
		pcap_lookupnet(from_dev, &ip_addr, &ip_mask, errbuf);
		in = pcap_open_live(from_dev, 65536, 1, 1, errbuf);
	} else {
		fprintf(stderr, "radsniff: No capture devices available\n");
	}
	
	if (!in) {
		fprintf(stderr, "radsniff: Failed opening input (%s)\n", errbuf);
		exit(1);
	}

	if (to_file) {
		out = pcap_dump_open(in, to_file);
		if (!out) {
			fprintf(stderr, "radsniff: Failed opening output file (%s)\n", pcap_geterr(in));
			exit(1);
		}
#ifdef HAVE_PCAP_DUMP_FOPEN
	} else if (to_stdout) {
		out = pcap_dump_fopen(in, stdout);
		if (!out) {
			fprintf(stderr, "radsniff: Failed opening stdout (%s)\n", pcap_geterr(in));
			exit(1);
		}
#endif
	}

	/*
	 *  Apply the rules
	 */
	if (pcap_compile(in, &fp, pcap_filter, 0, ip_mask) < 0) {
		fprintf(stderr, "radsniff: Failed compiling PCAP filter (%s)\n", pcap_geterr(in));
		exit(1);
	}
	
	if (pcap_setfilter(in, &fp) < 0) {
		fprintf(stderr, "radsniff: Failed applying PCAP filter (%s)\n", pcap_geterr(in));
		exit(1);
	}

	/*
	 *  Enter the main capture loop...
	 */
	pcap_loop(in, limit, got_packet, NULL);
	
	/*
	 *  ...were done capturing.
	 */
	pcap_close(in);
	if (out) {
		pcap_dump_close(out);
	}
	
	if (filter_tree) {
		rbtree_free(filter_tree);
	}
	
	INFO(log_dst, "Done sniffing\n");
	
	return 0;
}
Ejemplo n.º 6
0
/** Open a PCAP handle abstraction
 *
 * This opens interfaces for capture or injection, or files/streams for reading/writing.
 * @param pcap created with fr_pcap_init.
 * @return 0 on success, -1 on error.
 */
int fr_pcap_open(fr_pcap_t *pcap)
{
	switch (pcap->type) {
	case PCAP_INTERFACE_OUT:
	case PCAP_INTERFACE_IN:
	{
#if defined(HAVE_PCAP_CREATE) && defined(HAVE_PCAP_ACTIVATE)
		pcap->handle = pcap_create(pcap->name, pcap->errbuf);
		if (!pcap->handle) {
			fr_strerror_printf("%s", pcap->errbuf);
			return -1;
		}
		if (pcap_set_snaplen(pcap->handle, SNAPLEN) != 0) {
		create_error:
			fr_strerror_printf("%s", pcap_geterr(pcap->handle));
			pcap_close(pcap->handle);
			pcap->handle = NULL;
			return -1;
		}
		if (pcap_set_timeout(pcap->handle, PCAP_NONBLOCK_TIMEOUT) != 0) {
			goto create_error;
		}
		if (pcap_set_promisc(pcap->handle, pcap->promiscuous) != 0) {
			goto create_error;
		}

		if (pcap_set_buffer_size(pcap->handle, SNAPLEN *
					 (pcap->buffer_pkts ? pcap->buffer_pkts : PCAP_BUFFER_DEFAULT)) != 0) {
			goto create_error;
		}
		if (pcap_activate(pcap->handle) != 0) {
			goto create_error;
		}
#else
		/*
		 *	Alternative functions for libpcap < 1.0
		 */
		pcap->handle = pcap_open_live(pcap->name, SNAPLEN, pcap->promiscuous, PCAP_NONBLOCK_TIMEOUT,
					      pcap->errbuf);
		if (!pcap->handle) {
			fr_strerror_printf("%s", pcap->errbuf);
			return -1;
		}
#endif
		/*
		 *	Despite accepting an errbuff, pcap_setnonblock doesn't seem to write
		 *	error message there in newer versions.
		 */
		if (pcap_setnonblock(pcap->handle, true, pcap->errbuf) != 0) {
			fr_strerror_printf("%s", *pcap->errbuf != '\0' ?
					   pcap->errbuf : pcap_geterr(pcap->handle));
			pcap_close(pcap->handle);
			pcap->handle = NULL;
			return -1;
		}

		pcap->fd = pcap_get_selectable_fd(pcap->handle);
		pcap->link_layer = pcap_datalink(pcap->handle);
#ifndef __linux__
		{
			int value = 1;
			if (ioctl(pcap->fd, BIOCIMMEDIATE, &value) < 0) {
				fr_strerror_printf("Failed setting BIOCIMMEDIATE: %s", fr_syserror(errno));
			}
		}
#endif
	}
		break;

	case PCAP_FILE_IN:
		pcap->handle = pcap_open_offline(pcap->name, pcap->errbuf);
		if (!pcap->handle) {
			fr_strerror_printf("%s", pcap->errbuf);

			return -1;
		}
		pcap->fd = pcap_get_selectable_fd(pcap->handle);
		pcap->link_layer = pcap_datalink(pcap->handle);
		break;

	case PCAP_FILE_OUT:
		if (pcap->link_layer < 0) {
			pcap->link_layer = DLT_EN10MB;
		}
		pcap->handle = pcap_open_dead(pcap->link_layer, SNAPLEN);
		if (!pcap->handle) {
			fr_strerror_printf("Unknown error occurred opening dead PCAP handle");

			return -1;
		}
		pcap->dumper = pcap_dump_open(pcap->handle, pcap->name);
		if (!pcap->dumper) {
			fr_strerror_printf("%s", pcap_geterr(pcap->handle));

			return -1;
		}
		break;

#ifdef HAVE_PCAP_FOPEN_OFFLINE
	case PCAP_STDIO_IN:
		pcap->handle = pcap_fopen_offline(stdin, pcap->errbuf);
		if (!pcap->handle) {
			fr_strerror_printf("%s", pcap->errbuf);

			return -1;
		}
		pcap->fd = pcap_get_selectable_fd(pcap->handle);
		pcap->link_layer = pcap_datalink(pcap->handle);
		break;
#else
	case PCAP_STDIO_IN:
		fr_strerror_printf("This version of libpcap does not support reading pcap data from streams");

		return -1;
#endif
#ifdef HAVE_PCAP_DUMP_FOPEN
	case PCAP_STDIO_OUT:
		pcap->handle = pcap_open_dead(DLT_EN10MB, SNAPLEN);
		pcap->dumper = pcap_dump_fopen(pcap->handle, stdout);
		if (!pcap->dumper) {
			fr_strerror_printf("%s", pcap_geterr(pcap->handle));

			return -1;
		}
		break;
#else
	case PCAP_STDIO_OUT:
		fr_strerror_printf("This version of libpcap does not support writing pcap data to streams");

		return -1;
#endif
	case PCAP_INVALID:
	default:
		fr_assert(0);
		fr_strerror_printf("Bad handle type (%i)", pcap->type);
		return -1;
	}

	return 0;
}
Ejemplo n.º 7
0
/**
 * init our tcpdump handle using the given pcap handle
 * Basically, this starts up tcpdump as a child and communicates
 * to it via a pair of sockets (stdout/stdin)
 */
int
tcpdump_open(tcpdump_t *tcpdump, pcap_t *pcap)
{
    assert(tcpdump);
    assert(pcap);

    if (tcpdump->pid != 0) {
        warn("tcpdump process already running");
        return FALSE;
    }

    /* is tcpdump executable? */
    if (! can_exec(TCPDUMP_BINARY)) {
        errx(-1, "Unable to execute tcpdump binary: %s", TCPDUMP_BINARY);
    }

#ifdef DEBUG
     strlcpy(tcpdump->debugfile, TCPDUMP_DEBUG, sizeof(tcpdump->debugfile));
     if (debug >= 5) {
         dbgx(5, "Opening tcpdump debug file: %s", tcpdump->debugfile);

         if ((tcpdump->debugfd = open(tcpdump->debugfile, O_WRONLY|O_CREAT|O_TRUNC, 
                S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) == -1) {
            errx(-1, "Error opening tcpdump debug file: %s\n%s", tcpdump->debugfile, strerror(errno));
        }
    }
#endif

    /* copy over the args */
    dbg(2, "Prepping tcpdump options...");
    tcpdump_fill_in_options(tcpdump->args);

    dbg(2, "Starting tcpdump...");

    /* create our pipe to send packet data to tcpdump via */
    if (pipe(tcpdump->pipes[PARENT_READ_PIPE]) < 0 ||
            pipe(tcpdump->pipes[PARENT_WRITE_PIPE]) < 0)
        errx(-1, "Unable to create pipe: %s", strerror(errno));

    if ((tcpdump->pid = fork() ) < 0)
        errx(-1, "Fork failed: %s", strerror(errno));

    dbgx(2, "tcpdump pid: %d", tcpdump->pid);

    if (tcpdump->pid > 0) {
        /* parent - we're still in tcpreplay */

        /* close fds not required by parent */
        dbgx(2, "[parent] closing child read/write fd %d/%d", CHILD_READ_FD,
                CHILD_WRITE_FD);
        close(CHILD_READ_FD);
        close(CHILD_WRITE_FD);
        CHILD_READ_FD = 0;
        CHILD_WRITE_FD = 0;

        /* send the pcap file header to tcpdump */
        FILE *writer = fdopen(PARENT_WRITE_FD, "w");
        if ((pcap_dump_fopen(pcap, writer)) == NULL) {
            warnx("[parent] pcap_dump_fopen(): %s", pcap_geterr(pcap));
            return FALSE;
        }

        pcap_dump_flush((pcap_dumper_t*)writer);

        if (fcntl(PARENT_WRITE_FD, F_SETFL, O_NONBLOCK) < 0)
            warnx("[parent] Unable to fcntl write pipe:\n%s", strerror(errno));

        if (fcntl(PARENT_READ_FD, F_SETFL, O_NONBLOCK) < 0)
            warnx("[parent] Unable to fnctl read pip:\n%s", strerror(errno));
    } else {
        dbg(2, "[child] started the kid");

        /* we're in the child process - run "tcpdump  <options> -r -" */
        if (dup2(CHILD_READ_FD, STDIN_FILENO) != STDIN_FILENO) {
            errx(-1, "[child] Unable to duplicate socket to stdin: %s",
                                strerror(errno));
        }

        if (dup2(CHILD_WRITE_FD, STDOUT_FILENO) != STDOUT_FILENO) {
            errx(-1, "[child] Unable to duplicate socket to stdout: %s",
                                strerror(errno));
        }

        /*
         * Close sockets not required by child. The exec'ed program must
         * not know that they ever existed.
         */
        dbgx(2, "[child] closing in fds %d/%d/%d/%d", CHILD_READ_FD,
                CHILD_WRITE_FD, PARENT_READ_FD, PARENT_WRITE_FD);
        close(CHILD_READ_FD);
        close(CHILD_WRITE_FD);
        close(PARENT_READ_FD);
        close(PARENT_WRITE_FD);

        /* exec tcpdump */
        dbg(2, "[child] Exec'ing tcpdump...");
        if (execv(TCPDUMP_BINARY, options_vec) < 0)
            errx(-1, "Unable to exec tcpdump: %s", strerror(errno));

        dbg(2, "[child] tcpdump done!");
    }

    return TRUE;
}
Ejemplo n.º 8
0
Archivo: gulp.c Proyecto: edemir/gulp
/*
 * This thread reads stdin or the network and appends to the ring buffer
 */
void *Reader(void *arg)
    {
#ifndef JUSTCOPY
    char errbuf[PCAP_ERRBUF_SIZE];	/* error buffer */
    struct bpf_program fp;		/* compiled filter program */
    bpf_u_int32 mask;			/* subnet mask */
    bpf_u_int32 net;			/* ip */
    int num_packets = -1;		/* number of packets to capture */
#endif
#ifdef CPU_SET
    int rtid = gettid();		/* reader thread id */
    cpu_set_t csmask;
    CPU_ZERO(&csmask);
    CPU_SET(READER_CPU, &csmask);
    if (my_sched_setaffinity(rtid, sizeof(cpu_set_t), &csmask) != 0) {
        fprintf(stderr, "%s: Reader could not set cpu affinity: %s\n",
	    progname, strerror(errno));
        }
    if (setpriority(PRIO_PROCESS, rtid, READ_PRIO) != 0) {
	fprintf(stderr, "%s: Reader could not set scheduling priority: %s\n",
	    progname, strerror(errno));
	}
#else
    replace with equivalent code for your OS or delete and run less optimally
#endif

#ifdef USE_SIGNAL
    signal(SIGINT, cleanup);
    signal(SIGPIPE, cleanup);
#else
    struct sigaction sa;
    sa.sa_handler = cleanup;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;			/* allow signal to abort pcap read */
    
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);
#endif /* USE_SIGNAL */

    if (just_copy) {
	static char rbuf[MAXPKT];
	int c;
	reader_ready = 1;
	while (!eof && (c = read(0, rbuf, MAXPKT)) != 0) {
	    if (c > 0) append(rbuf, c, 1);
	    }
	}
#ifndef JUSTCOPY
    else {

    /*
     * get network number and mask associated with capture device
     * (needed to compile a bpf expression).
     */
    if (strcmp(dev,"-") && pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
	fprintf(stderr, "%s: Couldn't get netmask for dev %s: %s\n",
	    progname, dev, errbuf);
	net = 0;
	mask = 0;
    }

    /* open capture device */
    if (!strcmp(dev, "-")) {
	handle = pcap_open_offline(dev, errbuf);
#ifndef RHEL3
	int sfd = -2;
	if (handle) sfd = pcap_get_selectable_fd(handle);
	if (sfd >= 0 && lseek(sfd, 0, SEEK_CUR) >= 0) {
	    warn_buf_full = 0;		/* input is a file, don't warn */
	    }
#endif /* RHEL3 */
	}
    else
{
	//handle = pcap_open_live(dev, d_snap_len, 1, 0, errbuf);
          // handle = pcap_open_live(dev, d_snap_len, 1, 0, errbuf);
          handle = pcap_create (dev, errbuf);
          if (handle == NULL)
            {
              fprintf (stderr, "%s: Couldn't open device %s: %s\n",
                       progname, dev, errbuf);
              exit (EXIT_FAILURE);
            }
          if (pcap_set_buffer_size (handle, 200 * 1024 * 1024) != 0)
            {
              fprintf (stderr, " Couldn't set buffer\n");
              exit (EXIT_FAILURE);
            }
          if (pcap_set_snaplen (handle, d_snap_len) < 0)
            {
              fprintf (stderr, "Couldn't set snap len\n");
              exit (EXIT_FAILURE);
            }
          if (pcap_set_promisc (handle, 1) < 0)
            {
              fprintf (stderr, "Couldn't set promisc \n");
              exit (EXIT_FAILURE);
            }
          if (pcap_set_timeout (handle, 0) < 0)
            {
              fprintf (stderr, "Couldn't set timeout\n");
              exit (EXIT_FAILURE);
            }
          if (pcap_activate (handle) < 0)
            {
              fprintf (stderr, "Couldn't activate\n");
              exit (EXIT_FAILURE);
            }
}
    if (handle == NULL) {
	fprintf(stderr, "%s: Couldn't open device %s: %s\n",
	    progname, dev, errbuf);
	exit(EXIT_FAILURE);
    }

    reader_ready = 1;

    /* make sure we're capturing on an Ethernet device */
    if (pcap_datalink(handle) != DLT_EN10MB) {
	fprintf(stderr, "%s: %s is not an Ethernet\n", progname, dev);
	exit(EXIT_FAILURE);
    }

    /* compile the filter expression */
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
	fprintf(stderr, "%s: Couldn't parse filter %s: %s\n",
	    progname, filter_exp, pcap_geterr(handle));
	exit(EXIT_FAILURE);
    }

    /* apply the compiled filter */
    if (pcap_setfilter(handle, &fp) == -1) {
	fprintf(stderr, "%s: Couldn't install filter %s: %s\n",
	    progname, filter_exp, pcap_geterr(handle));
	exit(EXIT_FAILURE);
    }

    /*
     * emit pcap file header
     */

#ifndef RHEL3
    char tmpstr[] = "/tmp/gulp_hdr.XXXXXX";
    int tmpfd = mkstemp(tmpstr);
    if (tmpfd >= 0) {
	pcap_dumper_t *dump = pcap_dump_fopen(handle, fdopen(tmpfd,"w"));
	if (dump) pcap_dump_close(dump);
	tmpfd = open(tmpstr, O_RDONLY);	/* get pcap to create a header */
	if (tmpfd >= 0) read(tmpfd, (char *)&fh, sizeof(fh));
	if (tmpfd >= 0) close(tmpfd);
	unlink(tmpstr);
	fh.snaplen = snap_len;		/* snaplen after any decapsulation */
	}
#endif /* RHEL3 */
    if (fh.magic != 0xa1b2c3d4) {	/* if the above failed, do this */
	fprintf(stderr, "%s: using canned pcap header\n", progname);
	fh.magic = 0xa1b2c3d4;
	fh.version_major = 2;
	fh.version_minor = 4;
	fh.thiszone = 0;
	fh.sigfigs = 0;
	fh.snaplen = snap_len;
	fh.linktype = 1;
	}

    append((char *)&fh, sizeof(fh), 0);

    /* now we can set our callback function */
    pcap_loop(handle, num_packets, got_packet, NULL);

    fprintf(stderr, "\n%d packets captured\n", captured);
    if (ignored > 0) {
	fprintf(stderr, "%d packets ignored (too small to decapsulate)\n",
	    ignored);
	}
    if (got_stats) {
	(void)fprintf(stderr, "%d packets received by filter\n", pcs.ps_recv);
	(void)fprintf(stderr, "%d packets dropped by kernel\n", pcs.ps_drop);

	/*
	 * if packets dropped, check/warn if pcap socket buffer is too small
	 */
	if (pcs.ps_drop > 0) {
	    procf = fopen(RMEM_DEF, "r");
	    if (procf) {fscanf(procf, "%d", &rmem_def); fclose(procf);}
	    procf = fopen(RMEM_MAX, "r");
	    if (procf) {fscanf(procf, "%d", &rmem_max); fclose(procf);}
	    if (rmem_def < RMEM_SUG || rmem_max < RMEM_SUG) {
		fprintf(stderr, "\nNote %s may drop fewer packets "
		    "if you increase:\n  %s and\n  %s\nto %d or more\n\n",
		    progname, RMEM_MAX, RMEM_DEF, RMEM_SUG);
		}
	    }
	}
    if (check_block) {
	if (would_block)
	    fprintf(stderr, "select reports writes would have blocked\n");
	else
	    fprintf(stderr, "select reports writes would not have blocked\n");
	}
    /* cleanup */
    pcap_freecode(&fp);
#ifndef RHEL3
    pcap_close(handle);
#endif /* RHEL3 */

    }
#endif /* JUSTCOPY */
    fprintf(stderr, "ring buffer use: %.1lf%% of %d MB\n",
       	100.0*(double)maxbuffered/(double)(ringsize), ringsize/1024/1024);

    eof = 1;
    fflush(stderr);
    pthread_exit(NULL);
    }
Ejemplo n.º 9
0
/** Open a PCAP handle abstraction
 *
 * This opens interfaces for capture or injection, or files/streams for reading/writing.
 * @param pcap created with fr_pcap_init.
 * @return 0 on success, -1 on error.
 */
int fr_pcap_open(fr_pcap_t *pcap)
{
	switch (pcap->type) {
		case PCAP_INTERFACE_OUT:
		case PCAP_INTERFACE_IN:
			pcap->handle = pcap_open_live(pcap->name, SNAPLEN, true, PCAP_NONBLOCK_TIMEOUT,
						      pcap->errbuf);
			if (!pcap->handle) {
				fr_strerror_printf("%s", pcap->errbuf);

				return -1;
			}

			pcap->fd = pcap_get_selectable_fd(pcap->handle);

#ifndef __linux__
			{
				int value = 1;
				if (ioctl(pcap->fd, BIOCIMMEDIATE, &value) < 0) {
					fr_strerror_printf("Failed setting BIOCIMMEDIATE: %s", fr_syserror(errno));
				}
			}
#endif

			break;
		case PCAP_FILE_IN:
			pcap->handle = pcap_open_offline(pcap->name, pcap->errbuf);
			if (!pcap->handle) {
				fr_strerror_printf("%s", pcap->errbuf);

				return -1;
			}
			break;
		case PCAP_FILE_OUT:
			pcap->handle = pcap_open_dead(DLT_EN10MB, SNAPLEN);
			pcap->dumper = pcap_dump_open(pcap->handle, pcap->name);
			if (!pcap->dumper) {
				fr_strerror_printf("%s", pcap->errbuf);

				return -1;
			}
			break;
#ifdef HAVE_PCAP_FOPEN_OFFLINE
		case PCAP_STDIO_IN:
			pcap->handle = pcap_fopen_offline(stdin, pcap->errbuf);
			if (!pcap->handle) {
				fr_strerror_printf("%s", pcap->errbuf);

				return -1;
			}
			break;
#else
		case PCAP_STDIO_IN:
			fr_strerror_printf("This version of libpcap does not support reading pcap data from streams");

			return -1;
#endif
#ifdef HAVE_PCAP_DUMP_FOPEN
		case PCAP_STDIO_OUT:
			pcap->handle = pcap_open_dead(DLT_EN10MB, SNAPLEN);
			pcap->dumper = pcap_dump_fopen(pcap->handle, stdout);
			if (!pcap->dumper) {
				fr_strerror_printf("%s", pcap_geterr(pcap->handle));

				return -1;
			}
			break;
#else
		case PCAP_STDIO_OUT:
			fr_strerror_printf("This version of libpcap does not support writing pcap data to streams");

			return -1;
#endif
		case PCAP_INVALID:
		default:
			fr_assert(0);
			return -1;
	}

	return 0;
}