blob: 72d0e59812307b984478fb88cc5cc176c6af094f [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.
4 * All Rights Reserved.
5 * Licensed under the Clear BSD license. See README for more details.
6 */
7
8#include "sigma_dut.h"
9#include <signal.h>
10#include <sys/stat.h>
11#include <sys/wait.h>
12
13
14static void capture_process(const char *ifname, const char *filename)
15{
16 char *env[] = { NULL };
17 char *argv[] = { "sigma_dut[capture]", "-i", strdup(ifname),
18 "-w", strdup(filename), NULL };
19 execve("/usr/bin/dumpcap", argv, env);
20 perror("execve");
21 exit(EXIT_FAILURE);
22}
23
24
25static int cmd_sniffer_control_start(struct sigma_dut *dut,
26 struct sigma_conn *conn,
27 struct sigma_cmd *cmd)
28{
29 const char *filename = get_param(cmd, "filename");
30 int res;
31 pid_t pid;
32
33 if (dut->sniffer_pid) {
34 sigma_dut_print(dut, DUT_MSG_INFO, "Sniffer was already capturing - restart based on new parameters");
35 sniffer_close(dut);
36 }
37
38 if (filename == NULL) {
39 send_resp(dut, conn, SIGMA_ERROR,
40 "errorCode,Missing filename argument");
41 return 0;
42 }
43 if (strchr(filename, '/')) {
44 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
45 return 0;
46 }
47
48 res = cmd_wlantest_set_channel(dut, conn, cmd);
49 if (res != 1)
50 return res;
51
52 mkdir("Captures", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
53
54 sigma_dut_print(dut, DUT_MSG_INFO, "Starting sniffer process");
55 snprintf(dut->sniffer_filename, sizeof(dut->sniffer_filename),
56 "Captures/%s", filename);
57 pid = fork();
58 if (pid < 0) {
59 send_resp(dut, conn, SIGMA_ERROR,
60 "errorCode,Failed to fork sniffer process");
61 return 0;
62 }
63
64 if (pid == 0) {
65 capture_process(dut->sniffer_ifname, dut->sniffer_filename);
66 return 0;
67 }
68
69 dut->sniffer_pid = pid;
70
71 return 1;
72}
73
74
75void sniffer_close(struct sigma_dut *dut)
76{
77 if (!dut->sniffer_pid)
78 return;
79
80 if (kill(dut->sniffer_pid, SIGTERM) < 0) {
81 printf("Failed to kill sniffer process: %s\n", strerror(errno));
82 dut->sniffer_pid = 0;
83 return;
84 }
85 waitpid(dut->sniffer_pid, NULL, 0);
86
87 if (dut->sniffer_filename[0]) {
88 chmod(dut->sniffer_filename,
89 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
90 dut->sniffer_filename[0] = '\0';
91 }
92
93 dut->sniffer_pid = 0;
94}
95
96
97static int cmd_sniffer_control_stop(struct sigma_dut *dut,
98 struct sigma_conn *conn,
99 struct sigma_cmd *cmd)
100{
101 if (!dut->sniffer_pid) {
102 send_resp(dut, conn, SIGMA_ERROR,
103 "errorCode,Sniffer was not capturing");
104 return 0;
105 }
106
107 sniffer_close(dut);
108 return 1;
109}
110
111
112static int cmd_sniffer_control_field_check(struct sigma_dut *dut,
113 struct sigma_conn *conn,
114 struct sigma_cmd *cmd)
115{
116 const char *filename = get_param(cmd, "filename");
117 const char *framename = get_param(cmd, "framename");
118 const char *srcmac = get_param(cmd, "srcmac");
119 const char *wsc_state = get_param(cmd, "WSC_State");
120 const char *pvb_bit = get_param(cmd, "pvb_bit");
121 const char *moredata_bit = get_param(cmd, "MoreData_bit");
122 const char *eosp_bit = get_param(cmd, "EOSP_bit");
123 char buf[2000], *pos;
124 FILE *f;
125
126 if (filename == NULL || srcmac == NULL)
127 return -1;
128
129 if (strchr(filename, '/')) {
130 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
131 return 0;
132 }
133
134 if (!file_exists("sniffer-control-field-check.py")) {
135 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-field-check.py not found");
136 return 0;
137 }
138
139 snprintf(buf, sizeof(buf),
140 "./sniffer-control-field-check.py FileName=Captures/%s SrcMac=%s%s%s%s%s%s%s%s%s%s%s",
141 filename, srcmac,
142 framename ? " FrameName=" : "", framename ? framename : "",
143 wsc_state ? " WSC_State=" : "", wsc_state ? wsc_state : "",
144 moredata_bit ? " MoreData_bit=" : "",
145 moredata_bit ? moredata_bit : "",
146 eosp_bit ? " EOSP_bit=" : "", eosp_bit ? eosp_bit : "",
147 pvb_bit ? " pvb_bit=" : "", pvb_bit ? pvb_bit : "");
148 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
149 f = popen(buf, "r");
150 if (f == NULL) {
151 send_resp(dut, conn, SIGMA_ERROR,
152 "errorCode,Failed to run sniffer helper");
153 return 0;
154 }
155
156 if (!fgets(buf, sizeof(buf), f)) {
157 pclose(f);
158 send_resp(dut, conn, SIGMA_ERROR,
159 "errorCode,Failed extract response from sniffer helper");
160 return 0;
161 }
162 pos = strchr(buf, '\n');
163 if (pos)
164 *pos = '\0';
165
166 pclose(f);
167
168 send_resp(dut, conn, SIGMA_COMPLETE, buf);
169 return 0;
170}
171
172
173static int cmd_sniffer_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
174 struct sigma_cmd *cmd)
175{
176 char buf[200];
177
178 snprintf(buf, sizeof(buf), "WfaSnifferVersion,SigmaSniffer-foo,SnifferSTA,foo,DeviceSwInfo,foo,WiresharkVersion,foo");
179 send_resp(dut, conn, SIGMA_COMPLETE, buf);
180 return 0;
181}
182
183
184static int cmd_sniffer_control_filter_capture(struct sigma_dut *dut,
185 struct sigma_conn *conn,
186 struct sigma_cmd *cmd)
187{
188 const char *infile = get_param(cmd, "InFile");
189 const char *outfile = get_param(cmd, "OutFile");
190 const char *srcmac = get_param(cmd, "SrcMac");
191 const char *framename = get_param(cmd, "FrameName");
192 const char *nframes = get_param(cmd, "Nframes");
193 const char *hasfield = get_param(cmd, "HasField");
194 const char *datalen = get_param(cmd, "Datalen");
195 char buf[500], *pos;
196 FILE *f;
197
198 if (infile == NULL || outfile == NULL || srcmac == NULL ||
199 nframes == NULL)
200 return -1;
201
202 if (strchr(infile, '/') || strchr(outfile, '/'))
203 return -1;
204
205 if (!file_exists("sniffer-control-filter-capture.py")) {
206 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-filter-capture.py not found");
207 return 0;
208 }
209
210 snprintf(buf, sizeof(buf),
211 "./sniffer-control-filter-capture.py InFile=Captures/%s OutFile=Captures/%s SrcMac=%s%s%s Nframes=%s%s%s%s%s",
212 infile, outfile, srcmac,
213 framename ? " FrameName=" : "", framename ? framename : "",
214 nframes,
215 hasfield ? " HasField=" : "", hasfield ? hasfield : "",
216 datalen ? " Datalen=" : "", datalen ? datalen : "");
217 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
218 f = popen(buf, "r");
219 if (f == NULL) {
220 send_resp(dut, conn, SIGMA_ERROR,
221 "errorCode,Failed to run sniffer helper");
222 return 0;
223 }
224
225 if (!fgets(buf, sizeof(buf), f)) {
226 pclose(f);
227 send_resp(dut, conn, SIGMA_ERROR,
228 "errorCode,Failed extract response from sniffer helper");
229 return 0;
230 }
231 pos = strchr(buf, '\n');
232 if (pos)
233 *pos = '\0';
234
235 pclose(f);
236
237 send_resp(dut, conn, SIGMA_COMPLETE, buf);
238 return 0;
239}
240
241
242static int cmd_sniffer_get_field_value(struct sigma_dut *dut,
243 struct sigma_conn *conn,
244 struct sigma_cmd *cmd)
245{
246 const char *infile = get_param(cmd, "FileName");
247 const char *srcmac = get_param(cmd, "SrcMac");
248 const char *framename = get_param(cmd, "FrameName");
249 const char *fieldname = get_param(cmd, "FieldName");
250 char buf[500], *pos;
251 FILE *f;
252
253 if (infile == NULL || srcmac == NULL || framename == NULL ||
254 fieldname == NULL)
255 return -1;
256
257 if (!file_exists("sniffer-get-field-value.py")) {
258 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-get-field-value.py not found");
259 return 0;
260 }
261
262 snprintf(buf, sizeof(buf),
263 "./sniffer-get-field-value.py FileName=Captures/%s SrcMac=%s FrameName=%s FieldName=%s",
264 infile, srcmac, framename, fieldname);
265 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
266 f = popen(buf, "r");
267 if (f == NULL) {
268 send_resp(dut, conn, SIGMA_ERROR,
269 "errorCode,Failed to run sniffer helper");
270 return 0;
271 }
272
273 if (!fgets(buf, sizeof(buf), f)) {
274 pclose(f);
275 send_resp(dut, conn, SIGMA_ERROR,
276 "errorCode,Failed extract response from sniffer helper");
277 return 0;
278 }
279 pos = strchr(buf, '\n');
280 if (pos)
281 *pos = '\0';
282
283 pclose(f);
284
285 send_resp(dut, conn, SIGMA_COMPLETE, buf);
286 return 0;
287}
288
289
290static int cmd_sniffer_check_p2p_noa_duration(struct sigma_dut *dut,
291 struct sigma_conn *conn,
292 struct sigma_cmd *cmd)
293{
294 FILE *f;
295 char buf[200], *pos;
296 const char *infile = get_param(cmd, "FileName");
297 const char *bssid = get_param(cmd, "bssid");
298 const char *srcmac = get_param(cmd, "srcmac");
299 const char *destmac = get_param(cmd, "destmac");
300
301 if (infile == NULL || bssid == NULL || srcmac == NULL ||
302 destmac == NULL)
303 return -1;
304
305 if (!file_exists("sniffer-check-p2p-noa-duration.py")) {
306 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-check-p2p-noa-duration.py not found");
307 return 0;
308 }
309
310 snprintf(buf, sizeof(buf),
311 "./sniffer-check-p2p-noa-duration.py Captures/%s %s %s %s",
312 infile, bssid, srcmac, destmac);
313 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
314 f = popen(buf, "r");
315 if (f == NULL) {
316 send_resp(dut, conn, SIGMA_ERROR,
317 "errorCode,Failed to run sniffer check");
318 return 0;
319 }
320
321 if (!fgets(buf, sizeof(buf), f)) {
322 pclose(f);
323 send_resp(dut, conn, SIGMA_ERROR,
324 "errorCode,Failed extract response from sniffer check");
325 return 0;
326 }
327 pos = strchr(buf, '\n');
328 if (pos)
329 *pos = '\0';
330
331 pclose(f);
332
333 send_resp(dut, conn, SIGMA_COMPLETE, buf);
334 return 0;
335}
336
337
338static int cmd_sniffer_check_p2p_opps_client(struct sigma_dut *dut,
339 struct sigma_conn *conn,
340 struct sigma_cmd *cmd)
341{
342 char buf[200];
343
344 /* TODO */
345 snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
346 send_resp(dut, conn, SIGMA_COMPLETE, buf);
347 return 0;
348}
349
350
351static int cmd_sniffer_check_frame_field(struct sigma_dut *dut,
352 struct sigma_conn *conn,
353 struct sigma_cmd *cmd)
354{
355 char buf[200];
356
357 /* TODO */
358 snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
359 send_resp(dut, conn, SIGMA_COMPLETE, buf);
360 return 0;
361}
362
363
364void sniffer_register_cmds(void)
365{
366 sigma_dut_reg_cmd("sniffer_control_start", NULL,
367 cmd_sniffer_control_start);
368 sigma_dut_reg_cmd("sniffer_control_stop", NULL,
369 cmd_sniffer_control_stop);
370 sigma_dut_reg_cmd("sniffer_control_field_check", NULL,
371 cmd_sniffer_control_field_check);
372 sigma_dut_reg_cmd("sniffer_get_info", NULL, cmd_sniffer_get_info);
373 sigma_dut_reg_cmd("sniffer_control_filter_capture", NULL,
374 cmd_sniffer_control_filter_capture);
375 sigma_dut_reg_cmd("wfa_sniffer_control_filter_capture", NULL,
376 cmd_sniffer_control_filter_capture);
377 sigma_dut_reg_cmd("sniffer_get_field_value", NULL,
378 cmd_sniffer_get_field_value);
379 sigma_dut_reg_cmd("sniffer_check_p2p_NoA_duration", NULL,
380 cmd_sniffer_check_p2p_noa_duration);
381 sigma_dut_reg_cmd("sniffer_check_p2p_opps_client", NULL,
382 cmd_sniffer_check_p2p_opps_client);
383 sigma_dut_reg_cmd("sniffer_check_frame_field", NULL,
384 cmd_sniffer_check_frame_field);
385}