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); }
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); }
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; }
/** 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; }
/** * 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; }
/* * 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); }
/** 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; }