Import the initial version of sigma_dut open source project
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
diff --git a/sniffer.c b/sniffer.c
new file mode 100644
index 0000000..72d0e59
--- /dev/null
+++ b/sniffer.c
@@ -0,0 +1,385 @@
+/*
+ * Sigma Control API DUT (sniffer)
+ * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
+ * All Rights Reserved.
+ * Licensed under the Clear BSD license. See README for more details.
+ */
+
+#include "sigma_dut.h"
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+
+static void capture_process(const char *ifname, const char *filename)
+{
+ char *env[] = { NULL };
+ char *argv[] = { "sigma_dut[capture]", "-i", strdup(ifname),
+ "-w", strdup(filename), NULL };
+ execve("/usr/bin/dumpcap", argv, env);
+ perror("execve");
+ exit(EXIT_FAILURE);
+}
+
+
+static int cmd_sniffer_control_start(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ const char *filename = get_param(cmd, "filename");
+ int res;
+ pid_t pid;
+
+ if (dut->sniffer_pid) {
+ sigma_dut_print(dut, DUT_MSG_INFO, "Sniffer was already capturing - restart based on new parameters");
+ sniffer_close(dut);
+ }
+
+ if (filename == NULL) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Missing filename argument");
+ return 0;
+ }
+ if (strchr(filename, '/')) {
+ send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
+ return 0;
+ }
+
+ res = cmd_wlantest_set_channel(dut, conn, cmd);
+ if (res != 1)
+ return res;
+
+ mkdir("Captures", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+
+ sigma_dut_print(dut, DUT_MSG_INFO, "Starting sniffer process");
+ snprintf(dut->sniffer_filename, sizeof(dut->sniffer_filename),
+ "Captures/%s", filename);
+ pid = fork();
+ if (pid < 0) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed to fork sniffer process");
+ return 0;
+ }
+
+ if (pid == 0) {
+ capture_process(dut->sniffer_ifname, dut->sniffer_filename);
+ return 0;
+ }
+
+ dut->sniffer_pid = pid;
+
+ return 1;
+}
+
+
+void sniffer_close(struct sigma_dut *dut)
+{
+ if (!dut->sniffer_pid)
+ return;
+
+ if (kill(dut->sniffer_pid, SIGTERM) < 0) {
+ printf("Failed to kill sniffer process: %s\n", strerror(errno));
+ dut->sniffer_pid = 0;
+ return;
+ }
+ waitpid(dut->sniffer_pid, NULL, 0);
+
+ if (dut->sniffer_filename[0]) {
+ chmod(dut->sniffer_filename,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ dut->sniffer_filename[0] = '\0';
+ }
+
+ dut->sniffer_pid = 0;
+}
+
+
+static int cmd_sniffer_control_stop(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ if (!dut->sniffer_pid) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Sniffer was not capturing");
+ return 0;
+ }
+
+ sniffer_close(dut);
+ return 1;
+}
+
+
+static int cmd_sniffer_control_field_check(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ const char *filename = get_param(cmd, "filename");
+ const char *framename = get_param(cmd, "framename");
+ const char *srcmac = get_param(cmd, "srcmac");
+ const char *wsc_state = get_param(cmd, "WSC_State");
+ const char *pvb_bit = get_param(cmd, "pvb_bit");
+ const char *moredata_bit = get_param(cmd, "MoreData_bit");
+ const char *eosp_bit = get_param(cmd, "EOSP_bit");
+ char buf[2000], *pos;
+ FILE *f;
+
+ if (filename == NULL || srcmac == NULL)
+ return -1;
+
+ if (strchr(filename, '/')) {
+ send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
+ return 0;
+ }
+
+ if (!file_exists("sniffer-control-field-check.py")) {
+ send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-field-check.py not found");
+ return 0;
+ }
+
+ snprintf(buf, sizeof(buf),
+ "./sniffer-control-field-check.py FileName=Captures/%s SrcMac=%s%s%s%s%s%s%s%s%s%s%s",
+ filename, srcmac,
+ framename ? " FrameName=" : "", framename ? framename : "",
+ wsc_state ? " WSC_State=" : "", wsc_state ? wsc_state : "",
+ moredata_bit ? " MoreData_bit=" : "",
+ moredata_bit ? moredata_bit : "",
+ eosp_bit ? " EOSP_bit=" : "", eosp_bit ? eosp_bit : "",
+ pvb_bit ? " pvb_bit=" : "", pvb_bit ? pvb_bit : "");
+ sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
+ f = popen(buf, "r");
+ if (f == NULL) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed to run sniffer helper");
+ return 0;
+ }
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ pclose(f);
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed extract response from sniffer helper");
+ return 0;
+ }
+ pos = strchr(buf, '\n');
+ if (pos)
+ *pos = '\0';
+
+ pclose(f);
+
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+static int cmd_sniffer_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ char buf[200];
+
+ snprintf(buf, sizeof(buf), "WfaSnifferVersion,SigmaSniffer-foo,SnifferSTA,foo,DeviceSwInfo,foo,WiresharkVersion,foo");
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+static int cmd_sniffer_control_filter_capture(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ const char *infile = get_param(cmd, "InFile");
+ const char *outfile = get_param(cmd, "OutFile");
+ const char *srcmac = get_param(cmd, "SrcMac");
+ const char *framename = get_param(cmd, "FrameName");
+ const char *nframes = get_param(cmd, "Nframes");
+ const char *hasfield = get_param(cmd, "HasField");
+ const char *datalen = get_param(cmd, "Datalen");
+ char buf[500], *pos;
+ FILE *f;
+
+ if (infile == NULL || outfile == NULL || srcmac == NULL ||
+ nframes == NULL)
+ return -1;
+
+ if (strchr(infile, '/') || strchr(outfile, '/'))
+ return -1;
+
+ if (!file_exists("sniffer-control-filter-capture.py")) {
+ send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-filter-capture.py not found");
+ return 0;
+ }
+
+ snprintf(buf, sizeof(buf),
+ "./sniffer-control-filter-capture.py InFile=Captures/%s OutFile=Captures/%s SrcMac=%s%s%s Nframes=%s%s%s%s%s",
+ infile, outfile, srcmac,
+ framename ? " FrameName=" : "", framename ? framename : "",
+ nframes,
+ hasfield ? " HasField=" : "", hasfield ? hasfield : "",
+ datalen ? " Datalen=" : "", datalen ? datalen : "");
+ sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
+ f = popen(buf, "r");
+ if (f == NULL) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed to run sniffer helper");
+ return 0;
+ }
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ pclose(f);
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed extract response from sniffer helper");
+ return 0;
+ }
+ pos = strchr(buf, '\n');
+ if (pos)
+ *pos = '\0';
+
+ pclose(f);
+
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+static int cmd_sniffer_get_field_value(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ const char *infile = get_param(cmd, "FileName");
+ const char *srcmac = get_param(cmd, "SrcMac");
+ const char *framename = get_param(cmd, "FrameName");
+ const char *fieldname = get_param(cmd, "FieldName");
+ char buf[500], *pos;
+ FILE *f;
+
+ if (infile == NULL || srcmac == NULL || framename == NULL ||
+ fieldname == NULL)
+ return -1;
+
+ if (!file_exists("sniffer-get-field-value.py")) {
+ send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-get-field-value.py not found");
+ return 0;
+ }
+
+ snprintf(buf, sizeof(buf),
+ "./sniffer-get-field-value.py FileName=Captures/%s SrcMac=%s FrameName=%s FieldName=%s",
+ infile, srcmac, framename, fieldname);
+ sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
+ f = popen(buf, "r");
+ if (f == NULL) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed to run sniffer helper");
+ return 0;
+ }
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ pclose(f);
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed extract response from sniffer helper");
+ return 0;
+ }
+ pos = strchr(buf, '\n');
+ if (pos)
+ *pos = '\0';
+
+ pclose(f);
+
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+static int cmd_sniffer_check_p2p_noa_duration(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ FILE *f;
+ char buf[200], *pos;
+ const char *infile = get_param(cmd, "FileName");
+ const char *bssid = get_param(cmd, "bssid");
+ const char *srcmac = get_param(cmd, "srcmac");
+ const char *destmac = get_param(cmd, "destmac");
+
+ if (infile == NULL || bssid == NULL || srcmac == NULL ||
+ destmac == NULL)
+ return -1;
+
+ if (!file_exists("sniffer-check-p2p-noa-duration.py")) {
+ send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-check-p2p-noa-duration.py not found");
+ return 0;
+ }
+
+ snprintf(buf, sizeof(buf),
+ "./sniffer-check-p2p-noa-duration.py Captures/%s %s %s %s",
+ infile, bssid, srcmac, destmac);
+ sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
+ f = popen(buf, "r");
+ if (f == NULL) {
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed to run sniffer check");
+ return 0;
+ }
+
+ if (!fgets(buf, sizeof(buf), f)) {
+ pclose(f);
+ send_resp(dut, conn, SIGMA_ERROR,
+ "errorCode,Failed extract response from sniffer check");
+ return 0;
+ }
+ pos = strchr(buf, '\n');
+ if (pos)
+ *pos = '\0';
+
+ pclose(f);
+
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+static int cmd_sniffer_check_p2p_opps_client(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ char buf[200];
+
+ /* TODO */
+ snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+static int cmd_sniffer_check_frame_field(struct sigma_dut *dut,
+ struct sigma_conn *conn,
+ struct sigma_cmd *cmd)
+{
+ char buf[200];
+
+ /* TODO */
+ snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
+ send_resp(dut, conn, SIGMA_COMPLETE, buf);
+ return 0;
+}
+
+
+void sniffer_register_cmds(void)
+{
+ sigma_dut_reg_cmd("sniffer_control_start", NULL,
+ cmd_sniffer_control_start);
+ sigma_dut_reg_cmd("sniffer_control_stop", NULL,
+ cmd_sniffer_control_stop);
+ sigma_dut_reg_cmd("sniffer_control_field_check", NULL,
+ cmd_sniffer_control_field_check);
+ sigma_dut_reg_cmd("sniffer_get_info", NULL, cmd_sniffer_get_info);
+ sigma_dut_reg_cmd("sniffer_control_filter_capture", NULL,
+ cmd_sniffer_control_filter_capture);
+ sigma_dut_reg_cmd("wfa_sniffer_control_filter_capture", NULL,
+ cmd_sniffer_control_filter_capture);
+ sigma_dut_reg_cmd("sniffer_get_field_value", NULL,
+ cmd_sniffer_get_field_value);
+ sigma_dut_reg_cmd("sniffer_check_p2p_NoA_duration", NULL,
+ cmd_sniffer_check_p2p_noa_duration);
+ sigma_dut_reg_cmd("sniffer_check_p2p_opps_client", NULL,
+ cmd_sniffer_check_p2p_opps_client);
+ sigma_dut_reg_cmd("sniffer_check_frame_field", NULL,
+ cmd_sniffer_check_frame_field);
+}