pcap_t * pcap_open_live_extended(const char *source, int snaplen, int promisc, int to_ms, int rfmon, char *errbuf) { pcap_t *p; int status; p = pcap_create(source, errbuf); if (p == NULL) return (NULL); status = pcap_set_snaplen(p, snaplen); if (status < 0) goto fail; status = pcap_set_promisc(p, promisc); if (status < 0) goto fail; status = pcap_set_timeout(p, to_ms); if (status < 0) goto fail; if(pcap_can_set_rfmon(p) == 1) { status = pcap_set_rfmon(p, rfmon); if (status < 0) goto fail; } status = pcap_activate(p); if (status < 0) goto fail; return (p); fail: snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, pcap_geterr(p)); pcap_close(p); return (NULL); }
/* * Class: disy_jnipcap_Pcap * Method: canSetRfmon * Signature: (J)I */ JNIEXPORT jint JNICALL Java_disy_jnipcap_Pcap_canSetRfmon (JNIEnv *env, jclass jcls, jlong jptr) { pcap_t *p = (pcap_t *) jptr; if (p == NULL) return -1; return (jint) pcap_can_set_rfmon (p); }
void Sniffer::set_rfmon(bool rfmon_enabled) { #ifndef _WIN32 if (pcap_can_set_rfmon(get_pcap_handle()) == 1) { if (pcap_set_rfmon(get_pcap_handle(), rfmon_enabled)) { throw pcap_error(pcap_geterr(get_pcap_handle())); } } #endif }
static int epcap_open(EPCAP_STATE *ep) { char errbuf[PCAP_ERRBUF_SIZE]; if (ep->file) { PCAP_ERRBUF(ep->p = pcap_open_offline(ep->file, errbuf)); } else { if (ep->dev == NULL) PCAP_ERRBUF(ep->dev = pcap_lookupdev(errbuf)); #ifdef HAVE_PCAP_CREATE PCAP_ERRBUF(ep->p = pcap_create(ep->dev, errbuf)); (void)pcap_set_snaplen(ep->p, ep->snaplen); (void)pcap_set_promisc(ep->p, ep->opt & EPCAP_OPT_PROMISC); (void)pcap_set_timeout(ep->p, ep->timeout); if (ep->bufsz > 0) (void)pcap_set_buffer_size(ep->p, ep->bufsz); switch (pcap_activate(ep->p)) { case 0: break; case PCAP_WARNING: case PCAP_ERROR: case PCAP_WARNING_PROMISC_NOTSUP: case PCAP_ERROR_NO_SUCH_DEVICE: case PCAP_ERROR_PERM_DENIED: pcap_perror(ep->p, "pcap_activate: "); exit(EXIT_FAILURE); default: exit(EXIT_FAILURE); } #else PCAP_ERRBUF(ep->p = pcap_open_live(ep->dev, ep->snaplen, ep->opt & EPCAP_OPT_PROMISC, ep->timeout, errbuf)); #endif /* monitor mode */ #ifdef PCAP_ERROR_RFMON_NOTSUP if (pcap_can_set_rfmon(ep->p) == 1) (void)pcap_set_rfmon(ep->p, ep->opt & EPCAP_OPT_RFMON); #endif } ep->datalink = pcap_datalink(ep->p); return 0; }
static bool check_rfmon(const char *dev) { char junk[PCAP_ERRBUF_SIZE]; pcap_t *handle; handle = pcap_create(dev, junk); if(!handle) goto fail; if(pcap_can_set_rfmon(handle) != 1) goto fail; pcap_close(handle); return true; fail: pcap_close(handle); return false; }
int epcap_open(EPCAP_STATE *ep) { char errbuf[PCAP_ERRBUF_SIZE]; if (ep->file) { PCAP_ERRBUF(ep->p = pcap_open_offline(ep->file, errbuf)); } else { if (ep->dev == NULL) PCAP_ERRBUF(ep->dev = pcap_lookupdev(errbuf)); PCAP_ERRBUF(ep->p = pcap_open_live(ep->dev, ep->snaplen, ep->promisc, ep->timeout, errbuf)); /* monitor mode */ if (pcap_can_set_rfmon(ep->p) == 1) (void)pcap_set_rfmon(ep->p, ep->rfmon); } return (0); }
inline bool can_set_monitor_mode(pcap_t *source) { const auto result = pcap_can_set_rfmon(source); switch (result) { case 0: return false; case 1: return true; case PCAP_ERROR_NO_SUCH_DEVICE: throw error{"Capture source does not exist\n" + error_string(source)}; case PCAP_ERROR_PERM_DENIED: throw error{ "Insufficient permissions to check whether monitor mode " "could be supported\n" + error_string(source)}; case PCAP_ERROR_ACTIVATED: throw already_activated_error{source}; case PCAP_ERROR: throw error{"pcap_can_set_rfmon error\n" + error_string(source)}; default: throw error{"pcap_can_set_rfmon unknown error\n" + error_string(source)}; } }
int main (int argc, char *argv[]) { char *iface; pcap_t *pcap_res; int exitno, isrfmon; char errbuf[PCAP_ERRBUF_SIZE]; exitno = EXIT_SUCCESS; pcap_res = NULL; if ( argc < 2 ){ fprintf (stdout, "Usage: %s <INTERFACE>\n\nCheck if an INTERFACE supports a monitor mode (rfmon).\n", argv[0]); exitno = 2; goto cleanup; } iface = argv[1]; pcap_res = pcap_create (iface, errbuf); if ( pcap_res == NULL ){ fprintf (stderr, "%s: cannot open interface for a packet capture: %s\n", argv[0], errbuf); exitno = 2; goto cleanup; } isrfmon = pcap_can_set_rfmon (pcap_res); if ( isrfmon == 0 ){ fprintf (stderr, "not supported\n"); exitno = 1; goto cleanup; } else if ( isrfmon == 1 ){ // Attempt to activate a packet capture // ... } else { fprintf (stderr, "%s: cannot obtain information about rfmon support: %s\n", argv[0], pcap_geterr (pcap_res)); exitno = 2; goto cleanup; } isrfmon = pcap_set_rfmon (pcap_res, 1); if ( isrfmon != 0 ){ fprintf (stderr, "%s: cannot set an interface to monitor mode: %s\n", argv[0], pcap_geterr (pcap_res)); exitno = 2; goto cleanup; } isrfmon = pcap_activate (pcap_res); if ( isrfmon == PCAP_ERROR_RFMON_NOTSUP ){ fprintf (stderr, "not supported\n"); exitno = 1; } else if ( isrfmon == 0 ){ fprintf (stderr, "supported\n"); exitno = 0; } else { fprintf (stderr, "%s: cannot activate a packet capture: %s\n", argv[0], pcap_geterr (pcap_res)); exitno = 2; } cleanup: if ( pcap_res != NULL ) pcap_close (pcap_res); return exitno; }
void capture_init(char *interface) { char device[20]; //char device[]="wlan0"; strcpy(device,interface); char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ unsigned char dev_macAddress[17]; char *filter_exp; unsigned char *dev; filter_exp= (char *)malloc (200); int check_monitor_mode; // strcat(filter_exp,"ether src "); //char filter_exp[] = "ether src 00:1e:2a:52:ec:9c"; /* filter expression [3] */ struct bpf_program fp; /* compiled filter program (expression) */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ // int num_packets = 1000; /* number of packets to capture */ int num_packets = 0; /* INFINITY */ int data_linkValue; //print_app_banner(); dev =(unsigned char *)device; /* if (mkfifo(INCOME_PIPE, 0777) !=0 ) { PRINT_DEBUG("MKFIFO Failed \n"); exit(EXIT_FAILURE); } */ /* has to run without return check to work as blocking call */ /** It blocks until the other communication side opens the pipe */ income_pipe_fd = open(INCOME_PIPE, O_WRONLY); if (income_pipe_fd == -1) { PRINT_DEBUG("Income Pipe failure \n"); exit(EXIT_FAILURE); } /* Build the filter expression based on the mac address of the passed * device name */ //getDevice_MACAddress(dev_macAddress,dev); //strcat(filter_exp,dev_macAddress); //strcat(filter_exp," not arp and not tcp"); //strcat(filter_exp," and udp and"); strcat(filter_exp,"dst host 127.0.0.1"); /* get network number and mask associated with capture device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* print capture info */ printf("Device: %s\n", dev); printf("Number of packets: %d\n", num_packets); printf("Filter expression: %s\n", filter_exp); /* open capture device */ capture_handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf); if (capture_handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); exit(EXIT_FAILURE); } /* make sure we're capturing on an Ethernet device [2] */ data_linkValue = pcap_datalink(capture_handle); if (data_linkValue != DLT_EN10MB) { fprintf(stderr, "%s is not an Ethernet\n", dev); exit(EXIT_FAILURE); } printf("Datalink layer Description: %s \n",pcap_datalink_val_to_description(data_linkValue)); /* compile the filter expression */ if (pcap_compile(capture_handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(capture_handle)); exit(EXIT_FAILURE); } /* apply the compiled filter */ if (pcap_setfilter(capture_handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(capture_handle)); exit(EXIT_FAILURE); } check_monitor_mode = pcap_can_set_rfmon(capture_handle); if (check_monitor_mode ) {PRINT_DEBUG("\n Monitor mode can be set\n"); } else if (check_monitor_mode ==0 ) { PRINT_DEBUG("\n Monitor mode could not be set\n"); } else PRINT_DEBUG("\n check_monior_mode value is %d \n",check_monitor_mode); /* now we can set our callback function */ pcap_loop(capture_handle, num_packets, got_packet,(u_char *) NULL); /* cleanup */ pcap_freecode(&fp); free(filter_exp); } // end of capture_init
static ERL_NIF_TERM nif_pcap_open_live(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary device = {0}; int snaplen = 0; int promisc = 0; int to_ms = 0; int buffer_size = 0; int rfmon = 0; char errbuf[PCAP_ERRBUF_SIZE] = {0}; EWPCAP_STATE *ep = NULL; ERL_NIF_TERM res = {0}; ERL_NIF_TERM ref = {0}; if (!enif_inspect_iolist_as_binary(env, argv[0], &device)) return enif_make_badarg(env); if (!enif_get_int(env, argv[1], &snaplen)) return enif_make_badarg(env); if (!enif_get_int(env, argv[2], &promisc)) return enif_make_badarg(env); if (!enif_get_int(env, argv[3], &to_ms)) return enif_make_badarg(env); if (!enif_get_int(env, argv[4], &buffer_size)) return enif_make_badarg(env); if (!enif_get_int(env, argv[5], &rfmon)) return enif_make_badarg(env); /* NULL terminate the device name */ if (device.size > 0) { if (!enif_realloc_binary(&device, device.size+1)) return enif_make_tuple2(env, atom_error, atom_enomem); device.data[device.size-1] = '\0'; } ep = enif_alloc_resource(EWPCAP_RESOURCE, sizeof(EWPCAP_STATE)); if (ep == NULL) return enif_make_tuple2(env, atom_error, atom_enomem); /* "any" is a Linux only virtual dev */ ep->p = pcap_create((device.size == 0 ? "any" : (char *)device.data), errbuf); if (ep->p == NULL) return enif_make_tuple2(env, atom_error, enif_make_string(env, errbuf, ERL_NIF_LATIN1)); /* Set the snaplen */ (void)pcap_set_snaplen(ep->p, snaplen); /* Set promiscuous mode */ (void)pcap_set_promisc(ep->p, promisc); /* Set timeout */ (void)pcap_set_timeout(ep->p, to_ms); /* Set buffer size */ if (buffer_size > 0) (void)pcap_set_buffer_size(ep->p, buffer_size); /* Set monitor mode */ if (pcap_can_set_rfmon(ep->p) == 1) (void)pcap_set_rfmon(ep->p, rfmon); /* Return failure on error and warnings */ if (pcap_activate(ep->p) != 0) { pcap_close(ep->p); return enif_make_tuple2(env, atom_error, enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1)); } ep->datalink = pcap_datalink(ep->p); (void)enif_self(env, &ep->pid); ep->term_env = enif_alloc_env(); if (ep->term_env == NULL) { pcap_close(ep->p); return enif_make_tuple2(env, atom_error, atom_enomem); } ep->ref = enif_make_ref(ep->term_env); ref = enif_make_copy(env, ep->ref); res = enif_make_resource(env, ep); enif_release_resource(ep); return enif_make_tuple2(env, atom_ok, enif_make_tuple3(env, atom_ewpcap_resource, ref, res)); }
int main(int argc, char **argv) { /* default values for command line arguments (see also static variables) */ const char *if_name = PCAPPRINT_DEF_IFNAME; int snaplen = PCAPPRINT_DEF_SNAPLEN; const char *dlt_name = PCAPPRINT_DEF_DLTNAME; int num_pkts = -1; const char *pcap_filename = NULL; const char *bpf_expr = NULL; int rfmon = 0; /* process command line options */ const char *usage = "usage: pcap-print [options]\n"; int c; while ((c = getopt(argc, argv, ":1234ab:c:dfhi:mNqr:s:tVy:")) != -1) { switch (c) { case '1': case '2': case '3': case '4': enabled_layers[c-'0'-1]++; break; case 'a': /* arbitrary "big" number */ enabled_layers[0] = 100; enabled_layers[1] = 100; enabled_layers[2] = 100; enabled_layers[3] = 100; break; case 'b': bpf_expr = optarg; break; case 'c': num_pkts = atoi(optarg); break; case 'd': tsfmt = TS_CTIME; break; case 'f': print_fcs = 1; break; case 'h': printf(usage); printf( " -1 print data-link header (e.g. Ethernet)\n" " -2 print network header (e.g. IP)\n" " -3 print transport header (e.g. TCP)\n" " -4 print application header (e.g. HTTP)\n" " -a print ALL headers, with maximum verbosity\n" " -b specify a BPF filter\n" " -c print only first N packets\n" " -d print absolute timestamp in date format\n" " -f print FCS for MAC headers\n" " -h print usage information and quit\n" " -i network interface on which to capture packets" " (default: %s)\n" " -m set rfmon mode on interface\n" " -N number packets as they are printed\n" " -q suppress printing of packet-parsing errors\n" " -r read from pcap file instead of live capture\n" " -s capture size in bytes (default: %d)\n" " -t print absolute timestamp\n" " -V print pcap version and quit\n" " -y datalink type for capturing interface (default: %s)\n", PCAPPRINT_DEF_IFNAME, PCAPPRINT_DEF_SNAPLEN, PCAPPRINT_DEF_DLTNAME); exit(0); break; case 'i': if_name = optarg; break; case 'm': rfmon = 1; break; case 'N': use_numbering = 1; break; case 'q': quiet = 1; break; case 'r': pcap_filename = optarg; break; case 's': snaplen = (int)strtol(optarg, (char **)NULL, 10); break; case 't': tsfmt = TS_ABS; break; case 'V': printf("%s\n", pcap_lib_version()); exit(0); break; case 'y': dlt_name = optarg; break; case ':': errx(1, "option -%c requires an operand", optopt); break; case '?': errx(1, "unrecognized option: -%c", optopt); break; default: /* unhandled option indicates programming error */ assert(0); } } /* if no layers we specified, use defaults (hard-coded) */ if (! (enabled_layers[0] || enabled_layers[1] || enabled_layers[2] || enabled_layers[3])) { enabled_layers[1] = 1; enabled_layers[2] = 1; } /* create pcap handle (either from file or from live capture) */ char ebuf[PCAP_ERRBUF_SIZE]; *ebuf = '\0'; /* used only if a BPF program (filter) is specified */ bpf_u_int32 netnum = 0, netmask = 0; if (pcap_filename != NULL) { /* "capture" from file */ if (strcmp(if_name, PCAPPRINT_DEF_IFNAME) != 0) warnx("warning: -i option ignored when -f option is present"); if (snaplen != PCAPPRINT_DEF_SNAPLEN) warnx("warning: -s option ignored when -f option is present"); if (strcmp(dlt_name, PCAPPRINT_DEF_DLTNAME) != 0) warnx("warning: -y option ignored when -f option is present"); pcap_h = pcap_open_offline(pcap_filename, ebuf); if (pcap_h == NULL) errx(1, "pcap_open_offline: %s", ebuf); else if (*ebuf) warnx("pcap_open_offline: %s", ebuf); /* read dlt from file */ dlt = pcap_datalink(pcap_h); } else { /* live capture */ dlt = pcap_datalink_name_to_val(dlt_name); if (dlt < 0) err(1, "invalid data link type %s", dlt_name); pcap_h = pcap_create(if_name, ebuf); if (pcap_h == NULL) errx(1, "pcap_create: %s", ebuf); if (pcap_set_snaplen(pcap_h, snaplen) != 0) errx(1, "pcap_set_snaplen: %s", pcap_geterr(pcap_h)); if (pcap_set_promisc(pcap_h, 1) != 0) errx(1, "pcap_set_promisc: %s", pcap_geterr(pcap_h)); if (rfmon) { if (pcap_can_set_rfmon(pcap_h) == 0) errx(1, "cannot set rfmon mode on device %s", if_name); if (pcap_set_rfmon(pcap_h, 1) != 0) errx(1, "pcap_set_rfmon: %s", pcap_geterr(pcap_h)); } if (pcap_set_buffer_size(pcap_h, PCAPPRINT_BPF_BUFSIZE) != 0) errx(1, "pcap_set_buffer_size: %s", pcap_geterr(pcap_h)); if (pcap_set_timeout(pcap_h, PCAPPRINT_READ_TIMEOUT) != 0) errx(1, "pcap_set_timeout: %s", pcap_geterr(pcap_h)); if (pcap_lookupnet(if_name, &netnum, &netmask, ebuf) == -1) errx(1, "pcap_lookupnet: %s", ebuf); if (pcap_activate(pcap_h) != 0) errx(1, "pcap_activate: %s", pcap_geterr(pcap_h)); /* * the following calls must be done AFTER pcap_activate(): * pcap_setfilter * pcap_setdirection * pcap_set_datalink * pcap_getnonblock * pcap_setnonblock * pcap_stats * all reads/writes */ if (pcap_set_datalink(pcap_h, dlt) == -1) errx(1, "pcap_set_datalink: %s", pcap_geterr(pcap_h)); int r, yes = 1; int pcap_fd = pcap_get_selectable_fd(pcap_h); if ((r = ioctl(pcap_fd, BIOCIMMEDIATE, &yes)) == -1) err(1, "BIOCIMMEDIATE"); else if (r != 0) warnx("BIOCIMMEDIATE returned %d", r); /* set up signal handlers */ if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, signal_handler); if (signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, signal_handler); } /* apply BPF filter (if one was specified) */ if (bpf_expr != NULL) { struct bpf_program bpf; if (pcap_compile(pcap_h, &bpf, bpf_expr, 1 /*optimize*/, netmask) == -1) errx(1, "pcap_compile: %s", pcap_geterr(pcap_h)); if (pcap_setfilter(pcap_h, &bpf) == -1) errx(1, "pcap_setfilter: %s", pcap_geterr(pcap_h)); } /* start reading packets */ if (pcap_loop(pcap_h, num_pkts, handle_packet, NULL) == -1) errx(1, "pcap_loop: %s", pcap_geterr(pcap_h)); if (pcap_filename == NULL) { /* if live capture.. */ printf("%u packets captured\n", pkt_count); struct pcap_stat stats; if (pcap_stats(pcap_h, &stats) != 0) { warnx("pcap_stats: %s", pcap_geterr(pcap_h)); } else { printf("%u packets received by filter\n" "%u packets dropped by kernel\n", stats.ps_recv, stats.ps_drop); } } pcap_close(pcap_h); return 0; }