blob: 89ff57474368606dbc639e9f35bd2dc715dd017a [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (sniffer)
3 * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
Jouni Malinen69b367b2019-02-19 12:34:58 +02004 * Copyright (c) 2019, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005 * All Rights Reserved.
6 * Licensed under the Clear BSD license. See README for more details.
7 */
8
9#include "sigma_dut.h"
10#include <signal.h>
11#include <sys/stat.h>
12#include <sys/wait.h>
13
14
15static void capture_process(const char *ifname, const char *filename)
16{
17 char *env[] = { NULL };
18 char *argv[] = { "sigma_dut[capture]", "-i", strdup(ifname),
19 "-w", strdup(filename), NULL };
20 execve("/usr/bin/dumpcap", argv, env);
21 perror("execve");
22 exit(EXIT_FAILURE);
23}
24
25
Jouni Malinen69b367b2019-02-19 12:34:58 +020026static enum sigma_cmd_result cmd_sniffer_control_start(struct sigma_dut *dut,
27 struct sigma_conn *conn,
28 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020029{
30 const char *filename = get_param(cmd, "filename");
Jouni Malinen69b367b2019-02-19 12:34:58 +020031 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020032 pid_t pid;
33
34 if (dut->sniffer_pid) {
35 sigma_dut_print(dut, DUT_MSG_INFO, "Sniffer was already capturing - restart based on new parameters");
36 sniffer_close(dut);
37 }
38
39 if (filename == NULL) {
40 send_resp(dut, conn, SIGMA_ERROR,
41 "errorCode,Missing filename argument");
Jouni Malinen69b367b2019-02-19 12:34:58 +020042 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020043 }
44 if (strchr(filename, '/')) {
45 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
Jouni Malinen69b367b2019-02-19 12:34:58 +020046 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020047 }
48
49 res = cmd_wlantest_set_channel(dut, conn, cmd);
Jouni Malinen69b367b2019-02-19 12:34:58 +020050 if (res != SUCCESS_SEND_STATUS)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020051 return res;
52
53 mkdir("Captures", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
54
55 sigma_dut_print(dut, DUT_MSG_INFO, "Starting sniffer process");
56 snprintf(dut->sniffer_filename, sizeof(dut->sniffer_filename),
57 "Captures/%s", filename);
58 pid = fork();
59 if (pid < 0) {
60 send_resp(dut, conn, SIGMA_ERROR,
61 "errorCode,Failed to fork sniffer process");
Jouni Malinen69b367b2019-02-19 12:34:58 +020062 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020063 }
64
65 if (pid == 0) {
66 capture_process(dut->sniffer_ifname, dut->sniffer_filename);
Jouni Malinen69b367b2019-02-19 12:34:58 +020067 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020068 }
69
70 dut->sniffer_pid = pid;
71
Jouni Malinen69b367b2019-02-19 12:34:58 +020072 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020073}
74
75
76void sniffer_close(struct sigma_dut *dut)
77{
78 if (!dut->sniffer_pid)
79 return;
80
81 if (kill(dut->sniffer_pid, SIGTERM) < 0) {
82 printf("Failed to kill sniffer process: %s\n", strerror(errno));
83 dut->sniffer_pid = 0;
84 return;
85 }
86 waitpid(dut->sniffer_pid, NULL, 0);
87
88 if (dut->sniffer_filename[0]) {
89 chmod(dut->sniffer_filename,
90 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
91 dut->sniffer_filename[0] = '\0';
92 }
93
94 dut->sniffer_pid = 0;
95}
96
97
Jouni Malinen69b367b2019-02-19 12:34:58 +020098static enum sigma_cmd_result cmd_sniffer_control_stop(struct sigma_dut *dut,
99 struct sigma_conn *conn,
100 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200101{
102 if (!dut->sniffer_pid) {
103 send_resp(dut, conn, SIGMA_ERROR,
104 "errorCode,Sniffer was not capturing");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200105 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200106 }
107
108 sniffer_close(dut);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200109 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200110}
111
112
Jouni Malinen69b367b2019-02-19 12:34:58 +0200113static enum sigma_cmd_result
114cmd_sniffer_control_field_check(struct sigma_dut *dut, struct sigma_conn *conn,
115 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200116{
117 const char *filename = get_param(cmd, "filename");
118 const char *framename = get_param(cmd, "framename");
119 const char *srcmac = get_param(cmd, "srcmac");
120 const char *wsc_state = get_param(cmd, "WSC_State");
121 const char *pvb_bit = get_param(cmd, "pvb_bit");
122 const char *moredata_bit = get_param(cmd, "MoreData_bit");
123 const char *eosp_bit = get_param(cmd, "EOSP_bit");
124 char buf[2000], *pos;
125 FILE *f;
126
127 if (filename == NULL || srcmac == NULL)
Jouni Malinen69b367b2019-02-19 12:34:58 +0200128 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200129
130 if (strchr(filename, '/')) {
131 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200132 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200133 }
134
135 if (!file_exists("sniffer-control-field-check.py")) {
136 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-field-check.py not found");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200137 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200138 }
139
140 snprintf(buf, sizeof(buf),
141 "./sniffer-control-field-check.py FileName=Captures/%s SrcMac=%s%s%s%s%s%s%s%s%s%s%s",
142 filename, srcmac,
143 framename ? " FrameName=" : "", framename ? framename : "",
144 wsc_state ? " WSC_State=" : "", wsc_state ? wsc_state : "",
145 moredata_bit ? " MoreData_bit=" : "",
146 moredata_bit ? moredata_bit : "",
147 eosp_bit ? " EOSP_bit=" : "", eosp_bit ? eosp_bit : "",
148 pvb_bit ? " pvb_bit=" : "", pvb_bit ? pvb_bit : "");
149 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
150 f = popen(buf, "r");
151 if (f == NULL) {
152 send_resp(dut, conn, SIGMA_ERROR,
153 "errorCode,Failed to run sniffer helper");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200154 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200155 }
156
157 if (!fgets(buf, sizeof(buf), f)) {
158 pclose(f);
159 send_resp(dut, conn, SIGMA_ERROR,
160 "errorCode,Failed extract response from sniffer helper");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200161 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200162 }
163 pos = strchr(buf, '\n');
164 if (pos)
165 *pos = '\0';
166
167 pclose(f);
168
169 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200170 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200171}
172
173
Jouni Malinen69b367b2019-02-19 12:34:58 +0200174static enum sigma_cmd_result cmd_sniffer_get_info(struct sigma_dut *dut,
175 struct sigma_conn *conn,
176 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200177{
178 char buf[200];
179
180 snprintf(buf, sizeof(buf), "WfaSnifferVersion,SigmaSniffer-foo,SnifferSTA,foo,DeviceSwInfo,foo,WiresharkVersion,foo");
181 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200182 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200183}
184
185
Jouni Malinen69b367b2019-02-19 12:34:58 +0200186static enum sigma_cmd_result
187cmd_sniffer_control_filter_capture(struct sigma_dut *dut,
188 struct sigma_conn *conn,
189 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200190{
191 const char *infile = get_param(cmd, "InFile");
192 const char *outfile = get_param(cmd, "OutFile");
193 const char *srcmac = get_param(cmd, "SrcMac");
194 const char *framename = get_param(cmd, "FrameName");
195 const char *nframes = get_param(cmd, "Nframes");
196 const char *hasfield = get_param(cmd, "HasField");
197 const char *datalen = get_param(cmd, "Datalen");
198 char buf[500], *pos;
199 FILE *f;
200
201 if (infile == NULL || outfile == NULL || srcmac == NULL ||
202 nframes == NULL)
Jouni Malinen69b367b2019-02-19 12:34:58 +0200203 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200204
205 if (strchr(infile, '/') || strchr(outfile, '/'))
Jouni Malinen69b367b2019-02-19 12:34:58 +0200206 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200207
208 if (!file_exists("sniffer-control-filter-capture.py")) {
209 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-filter-capture.py not found");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200210 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200211 }
212
213 snprintf(buf, sizeof(buf),
214 "./sniffer-control-filter-capture.py InFile=Captures/%s OutFile=Captures/%s SrcMac=%s%s%s Nframes=%s%s%s%s%s",
215 infile, outfile, srcmac,
216 framename ? " FrameName=" : "", framename ? framename : "",
217 nframes,
218 hasfield ? " HasField=" : "", hasfield ? hasfield : "",
219 datalen ? " Datalen=" : "", datalen ? datalen : "");
220 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
221 f = popen(buf, "r");
222 if (f == NULL) {
223 send_resp(dut, conn, SIGMA_ERROR,
224 "errorCode,Failed to run sniffer helper");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200225 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200226 }
227
228 if (!fgets(buf, sizeof(buf), f)) {
229 pclose(f);
230 send_resp(dut, conn, SIGMA_ERROR,
231 "errorCode,Failed extract response from sniffer helper");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200232 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200233 }
234 pos = strchr(buf, '\n');
235 if (pos)
236 *pos = '\0';
237
238 pclose(f);
239
240 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200241 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200242}
243
244
Jouni Malinen69b367b2019-02-19 12:34:58 +0200245static enum sigma_cmd_result
246cmd_sniffer_get_field_value(struct sigma_dut *dut, struct sigma_conn *conn,
247 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200248{
249 const char *infile = get_param(cmd, "FileName");
250 const char *srcmac = get_param(cmd, "SrcMac");
251 const char *framename = get_param(cmd, "FrameName");
252 const char *fieldname = get_param(cmd, "FieldName");
253 char buf[500], *pos;
254 FILE *f;
255
256 if (infile == NULL || srcmac == NULL || framename == NULL ||
257 fieldname == NULL)
Jouni Malinen69b367b2019-02-19 12:34:58 +0200258 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200259
260 if (!file_exists("sniffer-get-field-value.py")) {
261 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-get-field-value.py not found");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200262 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200263 }
264
265 snprintf(buf, sizeof(buf),
266 "./sniffer-get-field-value.py FileName=Captures/%s SrcMac=%s FrameName=%s FieldName=%s",
267 infile, srcmac, framename, fieldname);
268 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
269 f = popen(buf, "r");
270 if (f == NULL) {
271 send_resp(dut, conn, SIGMA_ERROR,
272 "errorCode,Failed to run sniffer helper");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200273 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200274 }
275
276 if (!fgets(buf, sizeof(buf), f)) {
277 pclose(f);
278 send_resp(dut, conn, SIGMA_ERROR,
279 "errorCode,Failed extract response from sniffer helper");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200280 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200281 }
282 pos = strchr(buf, '\n');
283 if (pos)
284 *pos = '\0';
285
286 pclose(f);
287
288 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200289 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200290}
291
292
Jouni Malinen69b367b2019-02-19 12:34:58 +0200293static enum sigma_cmd_result
294cmd_sniffer_check_p2p_noa_duration(struct sigma_dut *dut,
295 struct sigma_conn *conn,
296 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200297{
298 FILE *f;
299 char buf[200], *pos;
300 const char *infile = get_param(cmd, "FileName");
301 const char *bssid = get_param(cmd, "bssid");
302 const char *srcmac = get_param(cmd, "srcmac");
303 const char *destmac = get_param(cmd, "destmac");
304
305 if (infile == NULL || bssid == NULL || srcmac == NULL ||
306 destmac == NULL)
Jouni Malinen69b367b2019-02-19 12:34:58 +0200307 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200308
309 if (!file_exists("sniffer-check-p2p-noa-duration.py")) {
310 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-check-p2p-noa-duration.py not found");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200311 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200312 }
313
314 snprintf(buf, sizeof(buf),
315 "./sniffer-check-p2p-noa-duration.py Captures/%s %s %s %s",
316 infile, bssid, srcmac, destmac);
317 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
318 f = popen(buf, "r");
319 if (f == NULL) {
320 send_resp(dut, conn, SIGMA_ERROR,
321 "errorCode,Failed to run sniffer check");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200322 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200323 }
324
325 if (!fgets(buf, sizeof(buf), f)) {
326 pclose(f);
327 send_resp(dut, conn, SIGMA_ERROR,
328 "errorCode,Failed extract response from sniffer check");
Jouni Malinen69b367b2019-02-19 12:34:58 +0200329 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200330 }
331 pos = strchr(buf, '\n');
332 if (pos)
333 *pos = '\0';
334
335 pclose(f);
336
337 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200338 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200339}
340
341
Jouni Malinen69b367b2019-02-19 12:34:58 +0200342static enum sigma_cmd_result
343cmd_sniffer_check_p2p_opps_client(struct sigma_dut *dut,
344 struct sigma_conn *conn,
345 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200346{
347 char buf[200];
348
349 /* TODO */
350 snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
351 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200352 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200353}
354
355
Jouni Malinen69b367b2019-02-19 12:34:58 +0200356static enum sigma_cmd_result
357cmd_sniffer_check_frame_field(struct sigma_dut *dut,
358 struct sigma_conn *conn,
359 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200360{
361 char buf[200];
362
363 /* TODO */
364 snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
365 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinen69b367b2019-02-19 12:34:58 +0200366 return STATUS_SENT;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200367}
368
369
370void sniffer_register_cmds(void)
371{
372 sigma_dut_reg_cmd("sniffer_control_start", NULL,
373 cmd_sniffer_control_start);
374 sigma_dut_reg_cmd("sniffer_control_stop", NULL,
375 cmd_sniffer_control_stop);
376 sigma_dut_reg_cmd("sniffer_control_field_check", NULL,
377 cmd_sniffer_control_field_check);
378 sigma_dut_reg_cmd("sniffer_get_info", NULL, cmd_sniffer_get_info);
379 sigma_dut_reg_cmd("sniffer_control_filter_capture", NULL,
380 cmd_sniffer_control_filter_capture);
381 sigma_dut_reg_cmd("wfa_sniffer_control_filter_capture", NULL,
382 cmd_sniffer_control_filter_capture);
383 sigma_dut_reg_cmd("sniffer_get_field_value", NULL,
384 cmd_sniffer_get_field_value);
385 sigma_dut_reg_cmd("sniffer_check_p2p_NoA_duration", NULL,
386 cmd_sniffer_check_p2p_noa_duration);
387 sigma_dut_reg_cmd("sniffer_check_p2p_opps_client", NULL,
388 cmd_sniffer_check_p2p_opps_client);
389 sigma_dut_reg_cmd("sniffer_check_frame_field", NULL,
390 cmd_sniffer_check_frame_field);
391}