/* * 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 #include #include 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); }