/** * Parse a link-type argument of the form "encap:<pcap dlt>" or * "proto:<proto name>". "Pcap dlt" must be a name conforming to * pcap_datalink_name_to_val() or an integer. "Proto name" must be * a protocol name, e.g. "http". */ static gboolean set_link_type(const char *lt_arg) { char *spec_ptr = strchr(lt_arg, ':'); char *p; int dlt_val; long val; dissector_handle_t dhandle; GString *pref_str; if (!spec_ptr) return FALSE; spec_ptr++; if (strncmp(lt_arg, "encap:", strlen("encap:")) == 0) { dlt_val = linktype_name_to_val(spec_ptr); if (dlt_val == -1) { errno = 0; val = strtol(spec_ptr, &p, 10); if (p == spec_ptr || *p != '\0' || errno != 0 || val > INT_MAX) { return FALSE; } dlt_val = (int)val; } encap = wtap_pcap_encap_to_wtap_encap(dlt_val); if (encap == WTAP_ENCAP_UNKNOWN) { return FALSE; } return TRUE; } else if (strncmp(lt_arg, "proto:", strlen("proto:")) == 0) { dhandle = find_dissector(spec_ptr); if (dhandle) { encap = WTAP_ENCAP_USER0; pref_str = g_string_new("uat:user_dlts:"); /* This must match the format used in the user_dlts file */ g_string_append_printf(pref_str, "\"User 0 (DLT=147)\",\"%s\",\"0\",\"\",\"0\",\"\"", spec_ptr); if (prefs_set_pref(pref_str->str) != PREFS_SET_OK) { g_string_free(pref_str, TRUE); return FALSE; } g_string_free(pref_str, TRUE); return TRUE; } } return FALSE; }
int capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture) { int status, snaplen; switch(opt) { case 'a': /* autostop criteria */ if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p); return 1; } break; #ifdef HAVE_PCAP_REMOTE case 'A': if (get_auth_arguments(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg_str_p); return 1; } break; #endif case 'b': /* Ringbuffer option */ capture_opts->multi_files_on = TRUE; if (get_ring_arguments(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg_str_p); return 1; } break; #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) case 'B': /* Buffer size */ if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.buffer_size = get_positive_int(optarg_str_p, "buffer size"); g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.buffer_size = get_positive_int(optarg_str_p, "buffer size"); } break; #endif case 'c': /* Capture n packets */ capture_opts->has_autostop_packets = TRUE; capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count"); break; case 'f': /* capture filter */ if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); g_free(interface_opts.cfilter); interface_opts.cfilter = g_strdup(optarg_str_p); g_array_append_val(capture_opts->ifaces, interface_opts); } else { g_free(capture_opts->default_options.cfilter); capture_opts->default_options.cfilter = g_strdup(optarg_str_p); } break; case 'H': /* Hide capture info dialog box */ capture_opts->show_info = FALSE; break; case 'i': /* Use interface x */ status = capture_opts_add_iface_opt(capture_opts, optarg_str_p); if (status != 0) { return status; } break; #ifdef HAVE_PCAP_CREATE case 'I': /* Capture in monitor mode */ if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.monitor_mode = TRUE; g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.monitor_mode = TRUE; } break; #endif case 'k': /* Start capture immediately */ *start_capture = TRUE; break; /*case 'l':*/ /* Automatic scrolling in live capture mode */ #ifdef HAVE_PCAP_SETSAMPLING case 'm': if (get_sampling_arguments(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg_str_p); return 1; } break; #endif case 'n': /* Use pcapng format */ capture_opts->use_pcapng = TRUE; break; case 'p': /* Don't capture in promiscuous mode */ if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.promisc_mode = FALSE; g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.promisc_mode = FALSE; } break; case 'P': /* Use pcap format */ capture_opts->use_pcapng = FALSE; break; #ifdef HAVE_PCAP_REMOTE case 'r': if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.nocap_rpcap = FALSE; g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.nocap_rpcap = FALSE; } break; #endif case 's': /* Set the snapshot (capture) length */ snaplen = get_natural_int(optarg_str_p, "snapshot length"); /* * Make a snapshot length of 0 equivalent to the maximum packet * length, mirroring what tcpdump does. */ if (snaplen == 0) snaplen = WTAP_MAX_PACKET_SIZE; if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.has_snaplen = TRUE; interface_opts.snaplen = snaplen; g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.snaplen = snaplen; capture_opts->default_options.has_snaplen = TRUE; } break; case 'S': /* "Real-Time" mode: used for following file ala tail -f */ capture_opts->real_time_mode = TRUE; break; #ifdef HAVE_PCAP_REMOTE case 'u': if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.datatx_udp = TRUE; g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.datatx_udp = TRUE; } break; #endif case 'w': /* Write to capture file x */ capture_opts->saving_to_file = TRUE; g_free(capture_opts->save_file); capture_opts->save_file = g_strdup(optarg_str_p); status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe); return status; case 'g': /* enable group read access on the capture file(s) */ capture_opts->group_read_access = TRUE; break; case 'y': /* Set the pcap data link type */ if (capture_opts->ifaces->len > 0) { interface_options interface_opts; interface_opts = g_array_index(capture_opts->ifaces, interface_options, capture_opts->ifaces->len - 1); capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, capture_opts->ifaces->len - 1); interface_opts.linktype = linktype_name_to_val(optarg_str_p); if (interface_opts.linktype == -1) { cmdarg_err("The specified data link type \"%s\" isn't valid", optarg_str_p); return 1; } g_array_append_val(capture_opts->ifaces, interface_opts); } else { capture_opts->default_options.linktype = linktype_name_to_val(optarg_str_p); if (capture_opts->default_options.linktype == -1) { cmdarg_err("The specified data link type \"%s\" isn't valid", optarg_str_p); return 1; } } break; default: /* the caller is responsible to send us only the right opt's */ g_assert_not_reached(); } return 0; }
int capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_str_p, gboolean *start_capture) { int status; switch(opt) { case 'a': /* autostop criteria */ if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p); return 1; } break; #ifdef HAVE_PCAP_REMOTE case 'A': if (get_auth_arguments(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -A arg \"%s\"", optarg_str_p); return 1; } break; #endif case 'b': /* Ringbuffer option */ capture_opts->multi_files_on = TRUE; if (get_ring_arguments(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg_str_p); return 1; } break; #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) case 'B': /* Buffer size */ capture_opts->buffer_size = get_positive_int(optarg_str_p, "buffer size"); break; #endif case 'c': /* Capture n packets */ capture_opts->has_autostop_packets = TRUE; capture_opts->autostop_packets = get_positive_int(optarg_str_p, "packet count"); break; case 'f': /* capture filter */ if (capture_opts->has_cfilter) { cmdarg_err("More than one -f argument specified"); return 1; } capture_opts->has_cfilter = TRUE; g_free(capture_opts->cfilter); capture_opts->cfilter = g_strdup(optarg_str_p); break; case 'H': /* Hide capture info dialog box */ capture_opts->show_info = FALSE; break; case 'i': /* Use interface x */ status = capture_opts_add_iface_opt(capture_opts, optarg_str_p); if(status != 0) { return status; } break; #ifdef HAVE_PCAP_CREATE case 'I': /* Capture in monitor mode */ capture_opts->monitor_mode = TRUE; break; #endif case 'k': /* Start capture immediately */ *start_capture = TRUE; break; /*case 'l':*/ /* Automatic scrolling in live capture mode */ #ifdef HAVE_PCAP_SETSAMPLING case 'm': if (get_sampling_arguments(capture_opts, optarg_str_p) == FALSE) { cmdarg_err("Invalid or unknown -m arg \"%s\"", optarg_str_p); return 1; } break; #endif case 'n': /* Use pcapng format */ capture_opts->use_pcapng = TRUE; break; case 'p': /* Don't capture in promiscuous mode */ capture_opts->promisc_mode = FALSE; break; case 'Q': /* Quit after capture (just capture to file) */ capture_opts->quit_after_cap = TRUE; *start_capture = TRUE; /*** -Q implies -k !! ***/ break; #ifdef HAVE_PCAP_REMOTE case 'r': capture_opts->nocap_rpcap = FALSE; break; #endif case 's': /* Set the snapshot (capture) length */ capture_opts->has_snaplen = TRUE; capture_opts->snaplen = get_natural_int(optarg_str_p, "snapshot length"); /* * Make a snapshot length of 0 equivalent to the maximum packet * length, mirroring what tcpdump does. */ if (capture_opts->snaplen == 0) capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; break; case 'S': /* "Real-Time" mode: used for following file ala tail -f */ capture_opts->real_time_mode = TRUE; break; #ifdef HAVE_PCAP_REMOTE case 'u': capture_opts->datatx_udp = TRUE; break; #endif case 'w': /* Write to capture file x */ capture_opts->saving_to_file = TRUE; g_free(capture_opts->save_file); #if defined _WIN32 && GLIB_CHECK_VERSION(2,6,0) /* since GLib 2.6, we need to convert filenames to utf8 for Win32 */ capture_opts->save_file = g_locale_to_utf8(optarg_str_p, -1, NULL, NULL, NULL); #else capture_opts->save_file = g_strdup(optarg_str_p); #endif status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe); return status; case 'y': /* Set the pcap data link type */ capture_opts->linktype = linktype_name_to_val(optarg_str_p); if (capture_opts->linktype == -1) { cmdarg_err("The specified data link type \"%s\" isn't valid", optarg_str_p); return 1; } break; default: /* the caller is responsible to send us only the right opt's */ g_assert_not_reached(); } return 0; }