2 * wifidump is an extcap tool used to capture Wi-Fi frames using a remote ssh host
4 * Adapted from sshdump.
6 * Copyright 2022, Adrian Granados <adrian@intuitibits.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
16 #define WS_LOG_DOMAIN "wifidump"
18 #include <extcap/extcap-base.h>
19 #include <extcap/ssh-base.h>
20 #include <wsutil/interface.h>
21 #include <wsutil/file_util.h>
22 #include <wsutil/strtoi.h>
23 #include <wsutil/filesystem.h>
24 #include <wsutil/privileges.h>
25 #include <wsutil/please_report_bug.h>
26 #include <wsutil/wslog.h>
34 static char* wifidump_extcap_interface
;
35 #define DEFAULT_WIFIDUMP_EXTCAP_INTERFACE "wifidump"
37 #define WIFIDUMP_VERSION_MAJOR "1"
38 #define WIFIDUMP_VERSION_MINOR "0"
39 #define WIFIDUMP_VERSION_RELEASE "0"
41 #define SSH_READ_BLOCK_SIZE 256
44 EXTCAP_BASE_OPTIONS_ENUM
,
52 OPT_REMOTE_CHANNEL_FREQUENCY
,
53 OPT_REMOTE_CHANNEL_WIDTH
,
56 OPT_SSHKEY_PASSPHRASE
,
62 static const struct ws_option longopts
[] = {
64 { "help", ws_no_argument
, NULL
, OPT_HELP
},
65 { "version", ws_no_argument
, NULL
, OPT_VERSION
},
66 SSH_BASE_PACKET_OPTIONS
,
67 { "remote-channel-frequency", ws_required_argument
, NULL
, OPT_REMOTE_CHANNEL_FREQUENCY
},
68 { "remote-channel-width", ws_required_argument
, NULL
, OPT_REMOTE_CHANNEL_WIDTH
},
72 static const char * remote_capture_functions
=
74 "function iface_down {\n"
76 " sudo ip link set $iface down > /dev/null 2>&1\n"
79 "function iface_up {\n"
81 " sudo ip link set $iface up > /dev/null 2>&1\n"
84 "function iface_monitor {\n"
86 " sudo iw dev $iface set monitor control otherbss > /dev/null 2>&1 ||\n"
87 " sudo iw dev $iface set type monitor control otherbss > /dev/null 2>&1\n"
90 "function iface_scan {\n"
92 " iface_down $iface &&\n"
93 " sudo iw dev $iface set type managed > /dev/null 2>&1 &&\n"
94 " iface_up $iface &&\n"
95 " sudo iw dev $iface scan > /dev/null 2>&1\n"
98 "function iface_config {\n"
101 " local ch_width=$3\n"
102 " local center_freq=$4\n"
103 " if [ $freq -eq $center_freq ]; then\n"
104 " sudo iw dev $1 set freq $freq $ch_width 2>&1\n"
106 " sudo iw dev $1 set freq $freq $ch_width $center_freq 2>&1\n"
110 "function iface_start {\n"
113 " local filter=\"${@:3}\"\n"
114 " if [ $count -gt 0 ]; then\n"
115 " sudo tcpdump -i $iface -U -w - -c $count $filter\n"
117 " sudo tcpdump -i $iface -U -w - $filter\n"
121 "function capture_generic {\n"
124 " local ch_width=$3\n"
125 " local center_freq=$4\n"
127 " local filter=\"${@:6}\"\n"
128 " if ! { iwconfig $iface | grep Monitor > /dev/null 2>&1; }; then\n"
129 " iface_down $iface &&\n"
130 " iface_monitor $iface &&\n"
133 " iface_monitor $iface\n"
135 " iface_config $iface $freq $ch_width $center_freq &&\n"
136 " iface_start $iface $count $filter\n"
139 "function capture_iwlwifi {\n"
142 " local ch_width=$3\n"
143 " local center_freq=$4\n"
145 " local filter=\"${@:6}\"\n"
146 " INDEX=`sudo iw dev $iface info | grep wiphy | grep -Eo '[0-9]+'`\n"
147 " sudo iw phy phy${INDEX} channels | grep $freq | grep -i disabled > /dev/null 2>&1 &&\n"
148 " iface_scan $iface\n"
150 " sudo iw $iface interface add $MON type monitor flags none > /dev/null 2>&1\n"
151 " iface_up $MON &&\n"
152 " iface_down $iface &&\n"
153 " iface_config $MON $freq $ch_width $center_freq &&\n"
154 " iface_start $MON $count $filter\n"
157 "function capture {\n"
160 " local ch_width=$3\n"
161 " local center_freq=$4\n"
163 " local filter=\"${@:6}\"\n"
164 " if [ \"$iface\" == \"auto\" ]; then\n"
165 " iface=`sudo iw dev | grep -i interface | awk '{ print $2 }' | sort | head -n 1`\n"
167 " local driver=`/usr/sbin/ethtool -i $iface | grep driver | awk '{ print $2 }'`\n"
168 " if [ $driver = \"iwlwifi\" ]; then\n"
169 " capture_iwlwifi $iface $freq $ch_width $center_freq $count $filter\n"
171 " capture_generic $iface $freq $ch_width $center_freq $count $filter\n"
176 static unsigned int wifi_freqs_2dot4_5ghz
[] = {
177 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462,
179 5180, 5200, 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580,
180 5600, 5620, 5640, 5660, 5680, 5700, 5720, 5745, 5765, 5785, 5805, 5825,
184 static unsigned int freq_to_channel(unsigned int freq_mhz
) {
185 if (freq_mhz
== 2484)
187 else if (freq_mhz
>= 2412 && freq_mhz
<= 2484)
188 return ((freq_mhz
- 2412) / 5) + 1;
189 else if (freq_mhz
>= 5160 && freq_mhz
<= 5885)
190 return ((freq_mhz
- 5180) / 5) + 36;
191 else if (freq_mhz
>= 5955 && freq_mhz
<= 7115)
192 return ((freq_mhz
- 5955) / 5) + 1;
197 static const char *freq_to_band(unsigned int freq_mhz
)
199 if (freq_mhz
>= 2412 && freq_mhz
<= 2484)
201 else if (freq_mhz
>= 5160 && freq_mhz
<= 5885)
203 else if (freq_mhz
>= 5955 && freq_mhz
<= 7115)
209 static unsigned int center_freq(unsigned int freq_mhz
, unsigned int ch_width_mhz
) {
211 unsigned int start_freq
;
213 if (ch_width_mhz
== 20) {
216 else if (ch_width_mhz
== 40) {
217 if (freq_mhz
>= 5180 && freq_mhz
<= 5720) {
218 for (start_freq
= 5180; start_freq
<= 5700; start_freq
+= ch_width_mhz
) {
219 if (freq_mhz
>= start_freq
&& freq_mhz
<= (start_freq
+ 20))
220 return ((start_freq
* 2) + 20) / 2;
223 else if (freq_mhz
>= 5745 && freq_mhz
<= 5765)
225 else if (freq_mhz
>= 5785 && freq_mhz
<= 5805)
227 else if (freq_mhz
>= 5955 && freq_mhz
<= 7095) {
228 for (start_freq
= 5955; start_freq
<= 7075; start_freq
+= ch_width_mhz
) {
229 if (freq_mhz
>= start_freq
&& freq_mhz
<= (start_freq
+ 20))
230 return ((start_freq
* 2) + 20) / 2;
234 else if (ch_width_mhz
== 80) {
235 if (freq_mhz
>= 5180 && freq_mhz
<= 5660) {
236 for (start_freq
= 5180; start_freq
<= 5660; start_freq
+= ch_width_mhz
) {
237 if (freq_mhz
>= start_freq
&& freq_mhz
<= (start_freq
+ 60))
238 return ((start_freq
* 2) + 60) / 2;
241 else if (freq_mhz
>= 5745 && freq_mhz
<= 5805)
243 else if (freq_mhz
>= 5955 && freq_mhz
<= 7055) {
244 for (start_freq
= 5955; start_freq
<= 6995; start_freq
+= ch_width_mhz
) {
245 if (freq_mhz
>= start_freq
&& freq_mhz
<= (start_freq
+ 60))
246 return ((start_freq
* 2) + 60) / 2;
250 else if (ch_width_mhz
== 160) {
251 if (freq_mhz
>= 5180 && freq_mhz
<= 5640) {
252 for (start_freq
= 5180; start_freq
<= 5500; start_freq
+= ch_width_mhz
) {
253 if (freq_mhz
>= start_freq
&& freq_mhz
<= (start_freq
+ 140))
254 return ((start_freq
* 2) + 140) / 2;
257 else if (freq_mhz
>= 5955 && freq_mhz
<= 7055) {
258 for (start_freq
= 5955; start_freq
<= 6915; start_freq
+= ch_width_mhz
) {
259 if (freq_mhz
>= start_freq
&& freq_mhz
<= (start_freq
+ 140))
260 return ((start_freq
* 2) + 140) / 2;
268 static int ssh_loop_read(ssh_channel channel
, FILE* fp
)
271 int ret
= EXIT_SUCCESS
;
272 char buffer
[SSH_READ_BLOCK_SIZE
];
274 /* read from stdin until data are available */
275 while (ssh_channel_is_open(channel
) && !ssh_channel_is_eof(channel
)) {
276 nbytes
= ssh_channel_read(channel
, buffer
, SSH_READ_BLOCK_SIZE
, 0);
278 ws_warning("Error reading from channel");
284 if (fwrite(buffer
, 1, nbytes
, fp
) != (unsigned)nbytes
) {
285 ws_warning("Error writing to fifo");
292 /* read loop finished... maybe something wrong happened. Read from stderr */
293 while (ssh_channel_is_open(channel
) && !ssh_channel_is_eof(channel
)) {
294 nbytes
= ssh_channel_read(channel
, buffer
, SSH_READ_BLOCK_SIZE
, 1);
296 ws_warning("Error reading from channel");
299 if (fwrite(buffer
, 1, nbytes
, stderr
) != (unsigned)nbytes
) {
300 ws_warning("Error writing to stderr");
306 if (ssh_channel_send_eof(channel
) != SSH_OK
) {
307 ws_warning("Error sending EOF in ssh channel");
313 static ssh_channel
run_ssh_command(ssh_session sshs
, const char* capture_functions
,
314 const char* iface
, const uint16_t channel_frequency
, const uint16_t channel_width
,
315 const uint16_t center_frequency
, const char* cfilter
, const uint32_t count
)
319 char* quoted_iface
= NULL
;
320 char* quoted_filter
= NULL
;
321 char* count_str
= NULL
;
322 unsigned int remote_port
= 22;
324 channel
= ssh_channel_new(sshs
);
326 ws_warning("Can't create channel");
330 if (ssh_channel_open_session(channel
) != SSH_OK
) {
331 ws_warning("Can't open session");
332 ssh_channel_free(channel
);
336 ssh_options_get_port(sshs
, &remote_port
);
338 quoted_iface
= iface
? g_shell_quote(iface
) : NULL
;
339 quoted_filter
= g_shell_quote(cfilter
? cfilter
: "");
340 cmdline
= ws_strdup_printf("%s capture %s %u %u %u %u %s",
342 quoted_iface
? quoted_iface
: "auto",
349 ws_debug("Running: %s", cmdline
);
350 if (ssh_channel_request_exec(channel
, cmdline
) != SSH_OK
) {
351 ws_warning("Can't request exec");
352 ssh_channel_close(channel
);
353 ssh_channel_free(channel
);
357 g_free(quoted_iface
);
358 g_free(quoted_filter
);
365 static int ssh_open_remote_connection(const ssh_params_t
* params
, const char* capture_functions
,
366 const char* iface
, const uint16_t channel_frequency
, const uint16_t channel_width
,
367 const uint16_t center_frequency
, const char* cfilter
, const uint32_t count
, const char* fifo
)
369 ssh_session sshs
= NULL
;
370 ssh_channel channel
= NULL
;
372 int ret
= EXIT_FAILURE
;
373 char* err_info
= NULL
;
375 if (g_strcmp0(fifo
, "-")) {
376 /* Open or create the output file */
377 fp
= fopen(fifo
, "wb");
379 ws_warning("Error creating output file: %s (%s)", fifo
, g_strerror(errno
));
384 sshs
= create_ssh_connection(params
, &err_info
);
387 ws_warning("Error creating connection.");
391 channel
= run_ssh_command(sshs
, capture_functions
, iface
, channel_frequency
,
392 channel_width
, center_frequency
, cfilter
, count
);
395 ws_warning("Can't run ssh command.");
399 /* read from channel and write into fp */
400 if (ssh_loop_read(channel
, fp
) != EXIT_SUCCESS
) {
401 ws_warning("Error in read loop.");
409 ws_warning("%s", err_info
);
412 /* clean up and exit */
413 ssh_cleanup(&sshs
, &channel
);
415 if (g_strcmp0(fifo
, "-"))
420 static int list_config(char *interface
)
426 ws_warning("ERROR: No interface specified.");
430 if (g_strcmp0(interface
, wifidump_extcap_interface
)) {
431 ws_warning("ERROR: interface must be %s", wifidump_extcap_interface
);
436 printf("arg {number=%u}{call=--remote-host}{display=Remote SSH server address}"
437 "{type=string}{tooltip=The remote SSH host. It can be both "
438 "an IP address or a hostname}{required=true}{group=Server}\n", inc
++);
439 printf("arg {number=%u}{call=--remote-port}{display=Remote SSH server port}"
440 "{type=unsigned}{tooltip=The remote SSH host port (1-65535)}"
441 "{range=1,65535}{group=Server}\n", inc
++);
443 // Authentication tab
444 printf("arg {number=%u}{call=--remote-username}{display=Remote SSH server username}"
445 "{type=string}{tooltip=The remote SSH username. If not provided, "
446 "the current user will be used}{group=Authentication}\n", inc
++);
447 printf("arg {number=%u}{call=--remote-password}{display=Remote SSH server password}"
448 "{type=password}{tooltip=The SSH password, used when other methods (SSH agent "
449 "or key files) are unavailable.}{group=Authentication}\n", inc
++);
450 printf("arg {number=%u}{call=--sshkey}{display=Path to SSH private key}"
451 "{type=fileselect}{tooltip=The path on the local filesystem of the private ssh key}"
452 "{mustexist=true}{group=Authentication}\n", inc
++);
453 printf("arg {number=%u}{call=--sshkey-passphrase}{display=SSH key passphrase}"
454 "{type=password}{tooltip=Passphrase to unlock the SSH private key}{group=Authentication}\n",
456 printf("arg {number=%u}{call=--ssh-sha1}{display=Support SHA-1 keys (deprecated)}"
457 "{type=boolflag}{tooltip=Support keys and key exchange algorithms using SHA-1 (deprecated)}{group=Authentication}"
462 printf("arg {number=%u}{call=--remote-interface}{display=Remote interface}"
463 "{type=string}{tooltip=The remote network interface used to capture"
464 "}{default=auto}{group=Capture}\n", inc
++);
465 printf("arg {number=%u}{call=--remote-channel-frequency}{display=Remote channel}"
466 "{type=selector}{tooltip=The remote channel used to capture}{group=Capture}\n", inc
);
468 unsigned int freq
= 0;
469 for (i
= 0; (freq
= wifi_freqs_2dot4_5ghz
[i
]); i
++) {
470 printf("value {arg=%u}{value=%u}{display=%s, Channel %u}\n", inc
, freq
, freq_to_band(freq
), freq_to_channel(freq
));
473 for (freq
= 5955, psc
= 3; freq
<= 7115; freq
+= 20, psc
++) {
474 printf("value {arg=%u}{value=%u}{display=%s, Channel %u%s}\n", inc
, freq
,
475 freq_to_band(freq
), freq_to_channel(freq
), (psc
% 4 == 0) ? " (PSC)" : "");
479 printf("arg {number=%u}{call=--remote-channel-width}{display=Remote channel width}"
480 "{type=selector}{tooltip=The remote channel width used to capture}"
481 "{group=Capture}\n", inc
);
482 printf("value {arg=%u}{value=20}{display=20 MHz}\n", inc
);
483 printf("value {arg=%u}{value=40}{display=40 MHz}\n", inc
);
484 printf("value {arg=%u}{value=80}{display=80 MHz}\n", inc
);
485 printf("value {arg=%u}{value=160}{display=160 MHz}\n", inc
);
488 printf("arg {number=%u}{call=--remote-filter}{display=Remote capture filter}{type=string}"
489 "{tooltip=The remote capture filter}{group=Capture}\n", inc
++);
490 printf("arg {number=%u}{call=--remote-count}{display=Frames to capture}"
491 "{type=unsigned}{tooltip=The number of remote frames to capture.}"
492 "{group=Capture}\n", inc
++);
494 extcap_config_debug(&inc
);
499 static char* concat_filters(const char* extcap_filter
, const char* remote_filter
)
501 if (!extcap_filter
&& remote_filter
)
502 return g_strdup(remote_filter
);
504 if (!remote_filter
&& extcap_filter
)
505 return g_strdup(extcap_filter
);
507 if (!remote_filter
&& !extcap_filter
)
510 return ws_strdup_printf("(%s) and (%s)", extcap_filter
, remote_filter
);
513 int main(int argc
, char *argv
[])
518 ssh_params_t
* ssh_params
= ssh_params_new();
519 char* remote_interface
= NULL
;
520 uint16_t remote_channel_frequency
= 0;
521 uint16_t remote_channel_width
= 0;
522 uint16_t remote_center_frequency
= 0;
523 char* remote_filter
= NULL
;
525 int ret
= EXIT_FAILURE
;
526 extcap_parameters
* extcap_conf
= g_new0(extcap_parameters
, 1);
528 char* help_header
= NULL
;
529 char* interface_description
= g_strdup("Wi-Fi remote capture");
531 /* Set the program name. */
532 g_set_prgname("wifidump");
534 /* Initialize log handler early so we can have proper logging during startup. */
537 wifidump_extcap_interface
= g_path_get_basename(argv
[0]);
538 if (g_str_has_suffix(wifidump_extcap_interface
, ".exe")) {
539 wifidump_extcap_interface
[strlen(wifidump_extcap_interface
) - 4] = '\0';
543 * Get credential information for later use.
545 init_process_policies();
548 * Attempt to get the pathname of the directory containing the
551 err_msg
= configuration_init(argv
[0]);
552 if (err_msg
!= NULL
) {
553 ws_warning("Can't get pathname of directory containing the extcap program: %s.",
558 help_url
= data_file_url("wifidump.html");
559 extcap_base_set_util_info(extcap_conf
, argv
[0], WIFIDUMP_VERSION_MAJOR
, WIFIDUMP_VERSION_MINOR
,
560 WIFIDUMP_VERSION_RELEASE
, help_url
);
562 add_libssh_info(extcap_conf
);
563 if (g_strcmp0(wifidump_extcap_interface
, DEFAULT_WIFIDUMP_EXTCAP_INTERFACE
)) {
564 char* temp
= interface_description
;
565 interface_description
= ws_strdup_printf("%s, custom version", interface_description
);
568 extcap_base_register_interface(extcap_conf
, wifidump_extcap_interface
, interface_description
, 147, "Remote capture dependent DLT");
569 g_free(interface_description
);
571 help_header
= ws_strdup_printf(
572 " %s --extcap-interfaces\n"
573 " %s --extcap-interface=%s --extcap-dlts\n"
574 " %s --extcap-interface=%s --extcap-config\n"
575 " %s --extcap-interface=%s --remote-host myhost --remote-port 22222 "
576 "--remote-username myuser --remote-interface wlan0 --remote-channel-frequency 5180 "
577 "--remote-channel-width 40 --fifo=FILENAME --capture\n", argv
[0], argv
[0], wifidump_extcap_interface
, argv
[0],
578 wifidump_extcap_interface
, argv
[0], wifidump_extcap_interface
);
579 extcap_help_add_header(extcap_conf
, help_header
);
581 extcap_help_add_option(extcap_conf
, "--help", "print this help");
582 extcap_help_add_option(extcap_conf
, "--version", "print the version");
583 extcap_help_add_option(extcap_conf
, "--remote-host <host>", "the remote SSH host");
584 extcap_help_add_option(extcap_conf
, "--remote-port <port>", "the remote SSH port");
585 extcap_help_add_option(extcap_conf
, "--remote-username <username>", "the remote SSH username");
586 extcap_help_add_option(extcap_conf
, "--remote-password <password>", "the remote SSH password. If not specified, ssh-agent and ssh-key are used");
587 extcap_help_add_option(extcap_conf
, "--sshkey <public key path>", "the path of the ssh key");
588 extcap_help_add_option(extcap_conf
, "--sshkey-passphrase <public key passphrase>", "the passphrase to unlock public ssh");
589 extcap_help_add_option(extcap_conf
, "--ssh-sha1", "support keys and key exchange using SHA-1 (deprecated)");
590 extcap_help_add_option(extcap_conf
, "--remote-interface <iface>", "the remote capture interface");
591 extcap_help_add_option(extcap_conf
, "--remote-channel-frequency <channel_frequency>", "the remote channel frequency in MHz");
592 extcap_help_add_option(extcap_conf
, "--remote-channel-width <channel_width>", "the remote channel width in MHz");
593 extcap_help_add_option(extcap_conf
, "--remote-filter <filter>", "a filter for remote capture");
594 extcap_help_add_option(extcap_conf
, "--remote-count <count>", "the number of frames to capture");
600 extcap_help_print(extcap_conf
);
604 while ((result
= ws_getopt_long(argc
, argv
, ":", longopts
, &option_idx
)) != -1) {
609 extcap_help_print(extcap_conf
);
614 extcap_version_print(extcap_conf
);
618 case OPT_REMOTE_HOST
:
619 g_free(ssh_params
->host
);
620 ssh_params
->host
= g_strdup(ws_optarg
);
623 case OPT_REMOTE_PORT
:
624 if (!ws_strtou16(ws_optarg
, NULL
, &ssh_params
->port
) || ssh_params
->port
== 0) {
625 ws_warning("Invalid port: %s", ws_optarg
);
630 case OPT_REMOTE_USERNAME
:
631 g_free(ssh_params
->username
);
632 ssh_params
->username
= g_strdup(ws_optarg
);
635 case OPT_REMOTE_PASSWORD
:
636 g_free(ssh_params
->password
);
637 ssh_params
->password
= g_strdup(ws_optarg
);
638 memset(ws_optarg
, 'X', strlen(ws_optarg
));
642 g_free(ssh_params
->sshkey_path
);
643 ssh_params
->sshkey_path
= g_strdup(ws_optarg
);
646 case OPT_SSHKEY_PASSPHRASE
:
647 g_free(ssh_params
->sshkey_passphrase
);
648 ssh_params
->sshkey_passphrase
= g_strdup(ws_optarg
);
649 memset(ws_optarg
, 'X', strlen(ws_optarg
));
653 ssh_params
->ssh_sha1
= true;
656 case OPT_REMOTE_INTERFACE
:
657 g_free(remote_interface
);
658 remote_interface
= g_strdup(ws_optarg
);
661 case OPT_REMOTE_CHANNEL_FREQUENCY
:
662 if (!ws_strtou16(ws_optarg
, NULL
, &remote_channel_frequency
)) {
663 ws_warning("Invalid channel frequency: %s", ws_optarg
);
668 case OPT_REMOTE_CHANNEL_WIDTH
:
669 if (!ws_strtou16(ws_optarg
, NULL
, &remote_channel_width
)) {
670 ws_warning("Invalid channel width: %s", ws_optarg
);
675 case OPT_REMOTE_FILTER
:
676 g_free(remote_filter
);
677 remote_filter
= g_strdup(ws_optarg
);
680 case OPT_REMOTE_COUNT
:
681 if (!ws_strtou32(ws_optarg
, NULL
, &count
)) {
682 ws_warning("Invalid value for count: %s", ws_optarg
);
688 /* missing option argument */
689 ws_warning("Option '%s' requires an argument", argv
[ws_optind
- 1]);
693 if (!extcap_base_parse_options(extcap_conf
, result
- EXTCAP_OPT_LIST_INTERFACES
, ws_optarg
)) {
694 ws_warning("Invalid option: %s", argv
[ws_optind
- 1]);
700 extcap_cmdline_debug(argv
, argc
);
702 if (extcap_base_handle_interface(extcap_conf
)) {
707 if (extcap_conf
->show_config
) {
708 ret
= list_config(extcap_conf
->interface
);
712 err_msg
= ws_init_sockets();
713 if (err_msg
!= NULL
) {
714 ws_warning("ERROR: %s", err_msg
);
716 ws_warning("%s", please_report_bug());
720 if (extcap_conf
->capture
) {
723 if (!ssh_params
->host
) {
724 ws_warning("Missing parameter: --remote-host");
727 remote_center_frequency
= center_freq(remote_channel_frequency
, remote_channel_width
);
728 filter
= concat_filters(extcap_conf
->capture_filter
, remote_filter
);
729 ssh_params_set_log_level(ssh_params
, extcap_conf
->debug
);
730 ret
= ssh_open_remote_connection(ssh_params
, remote_capture_functions
,
731 remote_interface
, remote_channel_frequency
, remote_channel_width
, remote_center_frequency
,
732 filter
, count
, extcap_conf
->fifo
);
735 ws_debug("You should not come here... maybe some parameter missing?");
741 ssh_params_free(ssh_params
);
742 g_free(remote_interface
);
743 g_free(remote_filter
);
744 extcap_base_cleanup(&extcap_conf
);
749 * Editor modelines - https://www.wireshark.org/tools/modelines.html
754 * indent-tabs-mode: t
757 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
758 * :indentSize=8:tabSize=8:noTabs=false: