static int open_socket(struct sigma_dut *dut, int port) { struct sockaddr_in addr; #ifndef __QNXNTO__ int val; #endif /* !__QNXNTO__ */ #ifdef __QNXNTO__ dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); #else /* __QNXNTO__ */ dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); #endif /* __QNXNTO__ */ if (dut->s < 0) { sigma_dut_print(dut, DUT_MSG_ERROR, "socket: %s", strerror(errno)); return -1; } #ifndef __QNXNTO__ val = 1; if (setsockopt(dut->s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) sigma_dut_print(dut, DUT_MSG_INFO, "setsockopt SO_REUSEADDR: " "%s", strerror(errno)); #endif /* !__QNXNTO__ */ #ifdef __linux__ val = 1; if (setsockopt(dut->s, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) < 0) sigma_dut_print(dut, DUT_MSG_INFO, "setsockopt TCP_NODELAY: " "%s", strerror(errno)); #endif /* __linux__ */ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (bind(dut->s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { sigma_dut_print(dut, DUT_MSG_ERROR, "bind: %s", strerror(errno)); goto fail; } if (listen(dut->s, 5) < 0) { sigma_dut_print(dut, DUT_MSG_ERROR, "listen: %s", strerror(errno)); goto fail; } return 0; fail: shutdown(dut->s, SHUT_RDWR); close(dut->s); dut->s = -1; return -1; }
static void process_conn(struct sigma_dut *dut, struct sigma_conn *conn) { ssize_t res; int i; sigma_dut_print( DUT_MSG_DEBUG, "Read from %s:%d", inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port)); res = recv(conn->s, conn->buf + conn->pos, MAX_CMD_LEN + 5 - conn->pos, 0); if (res < 0) { sigma_dut_print( DUT_MSG_INFO, "recv: %s", strerror(errno)); } if (res <= 0) { sigma_dut_print( DUT_MSG_DEBUG, "Close connection from " "%s:%d", inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port)); close(conn->s); conn->s = -1; return; } sigma_dut_print( DUT_MSG_DEBUG, "Received %d bytes", (int) res); for (;;) { for (i = conn->pos; i < conn->pos + res; i++) { if (conn->buf[i] == '\r' || conn->buf[i] == '\n') break; } if (i == conn->pos + res) { /* Full command not yet received */ conn->pos += res; if (conn->pos >= MAX_CMD_LEN + 5) { sigma_dut_print( DUT_MSG_INFO, "Too long " "command dropped"); conn->pos = 0; } break; } /* Full command received */ conn->buf[i++] = '\0'; process_cmd(dut, conn, conn->buf); if (i < conn->pos + res && (conn->buf[i] == '\r' || conn->buf[i] == '\n')) i++; memmove(conn->buf, &conn->buf[i], conn->pos + res - i); res = conn->pos + res - i; conn->pos = 0; } }
void send_resp(struct sigma_dut *dut, struct sigma_conn *conn, enum sigma_status status, char *buf) { struct msghdr msg; struct iovec iov[4]; size_t elems; sigma_dut_print(dut, DUT_MSG_INFO, "resp: status=%d buf=%s", status, buf ? buf : "N/A"); iov[0].iov_base = "status,"; iov[0].iov_len = 7; switch (status) { case SIGMA_RUNNING: iov[1].iov_base = "RUNNING,"; iov[1].iov_len = 8; break; case SIGMA_INVALID: iov[1].iov_base = "INVALID,"; iov[1].iov_len = 8; break; case SIGMA_ERROR: iov[1].iov_base = "ERROR,"; iov[1].iov_len = 6; break; case SIGMA_COMPLETE: iov[1].iov_base = "COMPLETE,"; iov[1].iov_len = 9; break; } if (status != SIGMA_RUNNING) { sigma_dut_summary(dut, "CAPI resp: status,%s%s", (char *) iov[1].iov_base, buf ? buf : ""); } if (buf) { iov[2].iov_base = buf; iov[2].iov_len = strlen(buf); iov[3].iov_base = "\r\n"; iov[3].iov_len = 2; elems = 4; } else { iov[1].iov_len--; iov[2].iov_base = "\r\n"; iov[2].iov_len = 2; elems = 3; } memset(&msg, 0, sizeof(msg)); msg.msg_iov = iov; msg.msg_iovlen = elems; if (sendmsg(conn->s, &msg, 0) < 0) sigma_dut_print(dut, DUT_MSG_INFO, "sendmsg: %s", strerror(errno)); }
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; }
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_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 open_socket(struct sigma_dut *dut, int port) { struct sockaddr_in addr; int val; dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (dut->s < 0) { sigma_dut_print( DUT_MSG_ERROR, "socket: %s", strerror(errno)); return -1; } val = 1; if (setsockopt(dut->s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) sigma_dut_print( DUT_MSG_INFO, "setsockopt SO_REUSEADDR: " "%s", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (bind(dut->s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { sigma_dut_print( DUT_MSG_ERROR, "bind: %s", strerror(errno)); goto fail; } if (listen(dut->s, 5) < 0) { sigma_dut_print( DUT_MSG_ERROR, "listen: %s", strerror(errno)); goto fail; } sigma_dut_print( DUT_MSG_INFO, "%s succeed", __func__); return 0; fail: close(dut->s); dut->s = -1; return -1; }
void sigma_dut_hexdump(int level, const char *title, const unsigned char *buf, size_t len, int show) { size_t i; //if (level < wpa_debug_level) // return; //wpa_debug_print_timestamp(); sigma_dut_print(DUT_MSG_DEBUG, "%s - hexdump(len=%lu): %s", title, (unsigned long)len, (show) ? (buf ? "......" : " [NULL]") : " [REMOVED]"); if (buf) { char line[82]; i = 0; while (i<len) { int j, next=0; for (j=0; j<27 && i<len; ++j, ++i) { next += sprintf(line+next, "%02X ", buf[i]); } sigma_dut_print(DUT_MSG_DEBUG, "%s %s", TAGS, line); } sigma_dut_print(DUT_MSG_DEBUG, "%s %s", TAGS, "--------------------------------------------------------------------------------"); } }
static int cmd_sta_atheros(struct sigma_dut *dut, struct sigma_conn *conn, struct sigma_cmd *cmd) { char buf[2048], *pos; int i; const char *intf, *c; char resp[200]; intf = get_param(cmd, "interface"); c = get_param(cmd, "cmd"); if (c == NULL) return -1; buf[0] = '\0'; if (strncmp(c, "ctrl=", 5) == 0) { size_t rlen; c += 5; if (wpa_command_resp(intf, c, buf, sizeof(buf)) < 0) return -2; rlen = strlen(buf); if (rlen > 0 && buf[rlen - 1] == '\n') buf[rlen - 1] = '\0'; } else if (strncmp(c, "timeout=", 8) == 0) { unsigned int timeout; timeout = atoi(c + 8); if (timeout == 0) return -1; dut->default_timeout = timeout; sigma_dut_print( DUT_MSG_INFO, "Set DUT default timeout " "to %u seconds", dut->default_timeout); snprintf(buf, sizeof(buf), "OK"); } else return -2; i = snprintf(resp, sizeof(resp), "resp,"); pos = buf; while (*pos && i + 1 < sizeof(resp)) { char c = *pos++; if (c == '\n' || c == '\r' || c == ',') c = '^'; resp[i++] = c; } resp[i] = '\0'; send_resp(dut, conn, SIGMA_COMPLETE, resp); 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_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; }
BOOL wfaDecodeTLV(BYTE *tlv_data, int tlv_len, WORD *ptag, int *pval_len, BYTE *pvalue) { wfaTLV *data = (wfaTLV *)tlv_data; if(pvalue == NULL) { sigma_dut_print(DUT_MSG_ERROR, "Parm buf invalid\n"); return FALSE; } *ptag = data->tag; *pval_len = data->len; if(tlv_len < *pval_len) return FALSE; if(*pval_len != 0 && *pval_len < MAX_PARMS_BUFF) { wMEMCPY(pvalue, tlv_data+4, *pval_len); } return TRUE; }
static int cmd_traffic_send_ping(struct sigma_dut *dut, struct sigma_conn *conn, struct sigma_cmd *cmd) { const char *dst, *val; int size, dur, pkts; int id; char resp[100]; float interval; double rate; FILE *f; char buf[100]; int type = 1; int dscp = 0, use_dscp = 0; char extra[100], int_arg[100], intf_arg[100]; val = get_param(cmd, "Type"); if (!val) val = get_param(cmd, "IPType"); if (val) type = atoi(val); if (type != 1 && type != 2) { send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported address type"); return 0; } dst = get_param(cmd, "destination"); if (dst == NULL || (type == 1 && !is_ip_addr(dst)) || (type == 2 && !is_ipv6_addr(dst))) return -1; val = get_param(cmd, "frameSize"); if (val == NULL) return -1; size = atoi(val); val = get_param(cmd, "frameRate"); if (val == NULL) return -1; rate = atof(val); if (rate <= 0) return -1; val = get_param(cmd, "duration"); if (val == NULL) return -1; dur = atoi(val); if (dur <= 0 || dur > 3600) dur = 3600; pkts = dur * rate; interval = (float) 1 / rate; if (interval > 100000) return -1; val = get_param(cmd, "DSCP"); if (val) { dscp = atoi(val); if (dscp < 0 || dscp > 63) { send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid DSCP value"); return 0; } use_dscp = 1; } id = dut->next_streamid++; snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id); unlink(buf); snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id); unlink(buf); sigma_dut_print(dut, DUT_MSG_DEBUG, "Send ping: pkts=%d interval=%f " "streamid=%d", pkts, interval, id); f = fopen(SIGMA_TMPDIR "/sigma_dut-ping.sh", "w"); if (f == NULL) return -2; extra[0] = '\0'; if (use_dscp) { snprintf(extra, sizeof(extra), " -Q 0x%02x", dscp << 2); } int_arg[0] = '\0'; if (rate != 1) snprintf(int_arg, sizeof(int_arg), " -i %f", interval); intf_arg[0] = '\0'; if (type == 2) snprintf(intf_arg, sizeof(intf_arg), " -I %s", get_station_ifname()); fprintf(f, "#!" SHELL "\n" "ping%s -c %d%s -s %d%s -q%s %s > " SIGMA_TMPDIR "/sigma_dut-ping.%d &\n" "echo $! > " SIGMA_TMPDIR "/sigma_dut-ping-pid.%d\n", type == 2 ? "6" : "", pkts, int_arg, size, extra, intf_arg, dst, id, id); fclose(f); if (chmod(SIGMA_TMPDIR "/sigma_dut-ping.sh", S_IRUSR | S_IWUSR | S_IXUSR) < 0) return -2; if (system(SIGMA_TMPDIR "/sigma_dut-ping.sh") != 0) { sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to start ping"); return -2; } unlink(SIGMA_TMPDIR "/sigma_dut-ping.sh"); snprintf(resp, sizeof(resp), "streamID,%d", id); send_resp(dut, conn, SIGMA_COMPLETE, resp); return 0; }
static int cmd_traffic_stop_ping(struct sigma_dut *dut, struct sigma_conn *conn, struct sigma_cmd *cmd) { const char *val; int id, pid; FILE *f; char buf[100]; int res_found = 0, sent = 0, received = 0; val = get_param(cmd, "streamID"); if (val == NULL) return -1; id = atoi(val); snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping-pid.%d", id); f = fopen(buf, "r"); if (f == NULL) { send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unknown streamID"); return 0; } if (fscanf(f, "%d", &pid) != 1 || pid <= 0) { sigma_dut_print(dut, DUT_MSG_ERROR, "No PID for ping process"); fclose(f); unlink(buf); return -2; } fclose(f); unlink(buf); sigma_dut_print(dut, DUT_MSG_DEBUG, "Ping process pid %d", pid); if (kill(pid, SIGINT) < 0 && errno != ESRCH) { sigma_dut_print(dut, DUT_MSG_DEBUG, "kill failed: %s", strerror(errno)); } usleep(250000); snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id); f = fopen(buf, "r"); if (f == NULL) { sigma_dut_print(dut, DUT_MSG_DEBUG, "No ping result file found"); send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0"); return 0; } while (fgets(buf, sizeof(buf), f)) { char *pos; pos = strstr(buf, " packets transmitted"); if (pos) { pos--; while (pos > buf && isdigit(pos[-1])) pos--; sent = atoi(pos); res_found = 1; } pos = strstr(buf, " packets received"); if (pos == NULL) pos = strstr(buf, " received"); if (pos) { pos--; while (pos > buf && isdigit(pos[-1])) pos--; received = atoi(pos); res_found = 1; } } fclose(f); snprintf(buf, sizeof(buf), SIGMA_TMPDIR "/sigma_dut-ping.%d", id); unlink(buf); if (!res_found) { sigma_dut_print(dut, DUT_MSG_DEBUG, "No ping results found"); send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0"); return 0; } snprintf(buf, sizeof(buf), "sent,%d,replies,%d", sent, received); send_resp(dut, conn, SIGMA_COMPLETE, buf); return 0; }
int cmd_traffic_send_ping(struct sigma_dut *dut, tgPingStart_t *staPing, dutCmdResponse_t *spresp) { const char *dst; int val, size, dur, pkts; int id; char resp[100]; float interval, rate; FILE *f; char buf[100]; dst = staPing->dipaddr; if (strcmp(dst, "") == 0 || !is_ip_addr(dst)) return -1; //val = get_param(cmd, "frameSize"); val = staPing->frameSize; if (val == 0) return -1; size = val; //atoi(val); val = staPing->frameRate; if (val == 0) return -1; rate = val; // atof(val); #if 0 if (rate < 1) { return -1; } #endif val = staPing->duration; if (val == 0) return -1; dur = val; // atoi(val); if (dur <= 0) dur = 3600; pkts = dur * rate; interval = (float) 1 / rate; id = dut->next_streamid++; snprintf(buf, sizeof(buf), "/tmp/sigma_dut-ping.%d", id); unlink(buf); snprintf(buf, sizeof(buf), "/tmp/sigma_dut-ping-pid.%d", id); unlink(buf); sigma_dut_print( DUT_MSG_DEBUG, "Send ping: pkts=%d interval=%f " "streamid=%d", pkts, interval, id); f = fopen("/tmp/sigma_dut-ping.sh", "w"); if (f == NULL) return -2; fprintf(f, "#!/bin/sh\n" "ping -c %d -i %f -s %d -q %s > /tmp/sigma_dut-ping.%d &\n" "echo $! > /tmp/sigma_dut-ping-pid.%d\n", pkts, interval, size, dst, id, id); fclose(f); if (chmod("/tmp/sigma_dut-ping.sh", S_IRUSR | S_IWUSR | S_IXUSR) < 0) return -2; if (system("/tmp/sigma_dut-ping.sh") != 0) { sigma_dut_print( DUT_MSG_ERROR, "Failed to start ping"); return -2; } unlink("/tmp/sigma_dut-ping.sh"); snprintf(resp, sizeof(resp), "streamID,%d", id); send_resp(dut, conn, SIGMA_COMPLETE, resp); return 0; }
static void run_loop(struct sigma_dut *dut) { struct sigma_conn conn[MAX_CONNECTIONS]; int i, res, maxfd, can_accept; fd_set rfds; for (i = 0; i < MAX_CONNECTIONS; i++) conn[i].s = -1; for (;;) { FD_ZERO(&rfds); maxfd = -1; can_accept = 0; for (i = 0; i < MAX_CONNECTIONS; i++) { if (conn[i].s >= 0) { FD_SET(conn[i].s, &rfds); if (conn[i].s > maxfd) maxfd = conn[i].s; } else can_accept = 1; } if (can_accept) { FD_SET(dut->s, &rfds); if (dut->s > maxfd) maxfd = dut->s; } sigma_dut_print( DUT_MSG_DEBUG, "Waiting for next " "command (can_accept=%d)", can_accept); res = select(maxfd + 1, &rfds, NULL, NULL, NULL); if (res < 0) { perror("select"); sleep(1); continue; } if (!res) { sigma_dut_print( DUT_MSG_DEBUG, "Nothing ready"); sleep(1); continue; } if (FD_ISSET(dut->s, &rfds)) { for (i = 0; i < MAX_CONNECTIONS; i++) { if (conn[i].s < 0) break; } conn[i].addrlen = sizeof(conn[i].addr); conn[i].s = accept(dut->s, (struct sockaddr *) &conn[i].addr, &conn[i].addrlen); if (conn[i].s < 0) { sigma_dut_print( DUT_MSG_INFO, "accept: %s", strerror(errno)); continue; } sigma_dut_print( DUT_MSG_DEBUG, "Connection %d from %s:%d", i, inet_ntoa(conn[i].addr.sin_addr), ntohs(conn[i].addr.sin_port)); conn[i].pos = 0; } for (i = 0; i < MAX_CONNECTIONS; i++) { //sigma_dut_print( DUT_MSG_DEBUG, "%s : idx : %d, s : %d\n", __func__, i, conn[i].s); if (conn[i].s < 0) continue; if (FD_ISSET(conn[i].s, &rfds)) #if 0 // by bbelief process_conn(dut, &conn[i]); #else process_conn2(dut, &conn[i]); #endif //sigma_dut_print( DUT_MSG_DEBUG, "##-7\n"); } //sigma_dut_print( DUT_MSG_DEBUG, "##-8\n"); } }
/* Full command received */ conn->buf[i++] = '\0'; process_cmd(dut, conn, conn->buf); if (i < conn->pos + res && (conn->buf[i] == '\r' || conn->buf[i] == '\n')) i++; memmove(conn->buf, &conn->buf[i], conn->pos + res - i); res = conn->pos + res - i; conn->pos = 0; } } // by bbelief extern xcCommandFuncPtr gWfaCmdFuncTbl[]; /* command process functions */ static void process_conn2(struct sigma_dut *dut, struct sigma_conn *conn) { int nbytes = 0, cmdLen = 0, respLen; unsigned char xcCmdBuf[WFA_BUFF_1K], parmsVal[MAX_PARMS_BUFF], respBuf[WFA_RESP_BUF_SZ]; unsigned short xcCmdTag; char gCmdStr[WFA_CMD_STR_SZ]; dutCmdResponse_t gGenericResp; ssize_t res; int i; sigma_dut_print( DUT_MSG_DEBUG, "Read from %s:%d", inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port)); res = recv(conn->s, conn->buf + conn->pos, MAX_CMD_LEN + 5 - conn->pos, 0); if (res < 0) { sigma_dut_print( DUT_MSG_INFO, "recv: %s", strerror(errno)); } if (res <= 0) { sigma_dut_print( DUT_MSG_DEBUG, "Close connection from " "%s:%d", inet_ntoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port)); close(conn->s); conn->s = -1; return; } sigma_dut_print( DUT_MSG_DEBUG, "Received %d bytes", (int) res); /////////////////////// nbytes = (int)res; memset(xcCmdBuf, 0, WFA_BUFF_1K); memcpy(xcCmdBuf, conn->buf + conn->pos, nbytes); //sigma_dut_hexdump(DUT_MSG_DEBUG, "sigma", xcCmdBuf , nbytes, 1); /* command received */ wfaDecodeTLV(xcCmdBuf, nbytes, &xcCmdTag, &cmdLen, parmsVal); memset(respBuf, 0, WFA_RESP_BUF_SZ); respLen = 0; //sigma_dut_print(DUT_MSG_DEBUG, "%s - 1 : cmdtag : %d, cmdlen : %d\n", __func__, xcCmdTag, cmdLen); /* reset two commond storages used by control functions */ memset(gCmdStr, 0, WFA_CMD_STR_SZ); memset(&gGenericResp, 0, sizeof(dutCmdResponse_t)); /* command process function defined in wfa_ca.c and wfa_tg.c */ if((xcCmdTag != 0 && xcCmdTag > WFA_STA_NEW_COMMANDS_START && xcCmdTag < WFA_STA_NEW_COMMANDS_END) && gWfaCmdFuncTbl[xcCmdTag - WFA_STA_NEW_COMMANDS_START + (WFA_STA_COMMANDS_END - 1)] != NULL) { sigma_dut_print(DUT_MSG_DEBUG, "%s - 2 : idx : %d\n", __func__, xcCmdTag - WFA_STA_NEW_COMMANDS_START + (WFA_STA_COMMANDS_END - 1)); /* since the new commands are expanded to new block */ gWfaCmdFuncTbl[xcCmdTag - WFA_STA_NEW_COMMANDS_START + (WFA_STA_COMMANDS_END - 1)](cmdLen, parmsVal, &respLen, (BYTE *)respBuf); } else if((xcCmdTag != 0 && xcCmdTag < WFA_STA_COMMANDS_END) && gWfaCmdFuncTbl[xcCmdTag] != NULL) { sigma_dut_print(DUT_MSG_DEBUG, "%s - 3 : idx : %d\n", __func__, xcCmdTag); /* commands in the old block */ gWfaCmdFuncTbl[xcCmdTag](cmdLen, parmsVal, &respLen, (BYTE *)respBuf); } else { // no command defined sigma_dut_print(DUT_MSG_DEBUG, "%s - 4 : idx : %d\n", __func__, 0); gWfaCmdFuncTbl[0](cmdLen, parmsVal, &respLen, (BYTE *)respBuf); } // gWfaCmdFuncTbl[xcCmdTag](cmdLen, parmsVal, &respLen, (BYTE *)respBuf); if(send(conn->s, (BYTE *)respBuf, respLen, 0) != respLen) { sigma_dut_print( DUT_MSG_INFO, "wfa-wfaCtrlSend Error\n"); } }
static void run_loop(struct sigma_dut *dut) { struct sigma_conn conn[MAX_CONNECTIONS]; int i, res, maxfd, can_accept; fd_set rfds; memset(&conn, 0, sizeof(conn)); for (i = 0; i < MAX_CONNECTIONS; i++) conn[i].s = -1; #ifdef __linux__ signal(SIGINT, handle_term); signal(SIGTERM, handle_term); signal(SIGPIPE, SIG_IGN); #endif /* __linux__ */ while (!stop_loop) { FD_ZERO(&rfds); maxfd = -1; can_accept = 0; for (i = 0; i < MAX_CONNECTIONS; i++) { if (conn[i].s >= 0) { FD_SET(conn[i].s, &rfds); if (conn[i].s > maxfd) maxfd = conn[i].s; } else if (!conn[i].waiting_completion) can_accept = 1; } if (can_accept) { FD_SET(dut->s, &rfds); if (dut->s > maxfd) maxfd = dut->s; } sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for next " "command (can_accept=%d)", can_accept); res = select(maxfd + 1, &rfds, NULL, NULL, NULL); if (res < 0) { perror("select"); if (!stop_loop) sleep(1); continue; } if (!res) { sigma_dut_print(dut, DUT_MSG_DEBUG, "Nothing ready"); sleep(1); continue; } if (FD_ISSET(dut->s, &rfds)) { for (i = 0; i < MAX_CONNECTIONS; i++) { if (conn[i].s < 0 && !conn[i].waiting_completion) break; } if (i == MAX_CONNECTIONS) { /* * This cannot really happen since can_accept * would not be set to one. */ sigma_dut_print(dut, DUT_MSG_DEBUG, "No room for new connection"); continue; } conn[i].addrlen = sizeof(conn[i].addr); conn[i].s = accept(dut->s, (struct sockaddr *) &conn[i].addr, &conn[i].addrlen); if (conn[i].s < 0) { sigma_dut_print(dut, DUT_MSG_INFO, "accept: %s", strerror(errno)); continue; } sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection %d from %s:%d", i, inet_ntoa(conn[i].addr.sin_addr), ntohs(conn[i].addr.sin_port)); conn[i].pos = 0; } for (i = 0; i < MAX_CONNECTIONS; i++) { if (conn[i].s < 0) continue; if (FD_ISSET(conn[i].s, &rfds)) process_conn(dut, &conn[i]); } } }
static void process_cmd(struct sigma_dut *dut, struct sigma_conn *conn, char *buf) { struct sigma_cmd_handler *h; struct sigma_cmd c; char *cmd, *pos, *pos2; int len; char txt[200]; int res; while (*buf == '\r' || *buf == '\n' || *buf == '\t' || *buf == ' ') buf++; len = strlen(buf); while (len > 0 && buf[len - 1] == ' ') { buf[len - 1] = '\0'; len--; } sigma_dut_print( DUT_MSG_INFO, "cmd: %s", buf); snprintf(txt, sizeof(txt), "NOTE CAPI:%s", buf); txt[sizeof(txt) - 1] = '\0'; wpa_command(get_main_ifname(), txt); memset(&c, 0, sizeof(c)); cmd = buf; pos = strchr(cmd, ','); if (pos) { *pos++ = '\0'; if (strcasecmp(cmd, "AccessPoint") == 0 || strcasecmp(cmd, "PowerSwitch") == 0) { pos2 = strchr(pos, ','); if (pos2 == NULL) goto invalid_params; c.params[c.count] = pos; c.values[c.count] = pos2; c.count++; pos = strchr(pos2, ','); if (pos) *pos++ = '\0'; } while (pos) { pos2 = strchr(pos, ','); if (pos2 == NULL) goto invalid_params; *pos2++ = '\0'; if (c.count == MAX_PARAMS) { sigma_dut_print( DUT_MSG_INFO, "Too many " "parameters"); goto invalid_params; } c.params[c.count] = pos; c.values[c.count] = pos2; c.count++; pos = strchr(pos2, ','); if (pos) *pos++ = '\0'; } } h = dut->cmds; while (h) { if (strcasecmp(cmd, h->cmd) == 0) break; h = h->next; } if (h == NULL) { sigma_dut_print( DUT_MSG_INFO, "Unknown command: '%s'", cmd); send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unknown command"); return; } if (h->validate && h->validate(&c) < 0) { invalid_params: sigma_dut_print( DUT_MSG_INFO, "Invalid parameters"); send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid " "parameters"); return; } send_resp(dut, conn, SIGMA_RUNNING, NULL); sigma_dut_print( DUT_MSG_INFO, "Run command: %s", cmd); res = h->process(dut, conn, &c); if (res == -2) send_resp(dut, conn, SIGMA_ERROR, NULL); else if (res == -1) send_resp(dut, conn, SIGMA_INVALID, NULL); else if (res == 1) send_resp(dut, conn, SIGMA_COMPLETE, NULL); }
int main(int argc, char *argv[]) { int c; int daemonize = 0; int port = SIGMA_DUT_PORT; char *local_cmd = NULL; #ifdef __QNXNTO__ char *env_str = NULL; char buf[20]; char *sigma_ctrl_sock = NULL; /* env used for QNX */ #endif /* __QNXNTO__ */ memset(&sigma_dut, 0, sizeof(sigma_dut)); sigma_dut.debug_level = DUT_MSG_INFO; sigma_dut.default_timeout = 120; sigma_dut.dialog_token = 0; set_defaults(&sigma_dut); for (;;) { c = getopt(argc, argv, "ab:Bc:C:dDE:e:fhH:i:Ik:l:L:m:M:np:qr:R:s:S:tT:uv:VWw:"); if (c < 0) break; switch (c) { case 'a': sigma_dut.ap_anqpserver = 1; break; case 'b': sigma_dut.bridge = optarg; break; case 'B': daemonize++; break; case 'C': sigma_cert_path = optarg; break; case 'd': if (sigma_dut.debug_level > 0) sigma_dut.debug_level--; break; #ifdef __QNXNTO__ case 'E': sigma_ctrl_sock = optarg; break; #endif /* __QNXNTO__ */ case 'D': sigma_dut.stdout_debug = 1; break; case 'e': sigma_dut.hostapd_entropy_log = optarg; break; case 'f': /* Disable writing stats */ sigma_dut.write_stats = 0; break; case 'H': sigma_dut.hostapd_debug_log = optarg; break; case 'I': print_license(); exit(0); break; case 'l': local_cmd = optarg; break; case 'L': sigma_dut.summary_log = optarg; break; case 'p': port = atoi(optarg); break; case 'q': sigma_dut.debug_level++; break; case 'r': if (strcmp(optarg, "HT40") == 0) { sigma_dut.default_ap_chwidth = AP_40; } else { printf("Unsupported -r value\n"); exit(1); } break; case 'R': { static int num_radio = 0; static char **radio_ptr = sigma_radio_ifname; num_radio++; if (num_radio > MAX_RADIO) { printf("Multiple radio support limit (%d) exceeded\n", MAX_RADIO); exit(1); } *radio_ptr++ = optarg; break; } case 's': sigma_dut.sniffer_ifname = optarg; break; case 't': sigma_dut.no_timestamps = 1; break; case 'T': sigma_dut.throughput_pktsize = atoi(optarg); if (sigma_dut.throughput_pktsize <= 0) { printf("Invalid -T value\n"); exit(0); } break; case 'm': sigma_dut.set_macaddr = optarg; break; case 'M': sigma_main_ifname = optarg; break; case 'n': sigma_dut.no_ip_addr_set = 1; break; case 'S': sigma_station_ifname = optarg; break; case 'w': sigma_hapd_ctrl = optarg; sigma_wpas_ctrl = optarg; break; case 'i': ap_inet_addr = optarg; break; case 'k': ap_inet_mask = optarg; break; case 'c': printf("%s", optarg); if (set_wifi_chip(optarg) < 0) sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, "WRONG CHIP TYPE: SAP will " "not load"); break; case 'v': sigma_dut.version = optarg; break; case 'V': printf("sigma_dut " SIGMA_DUT_VER "\n"); exit(0); break; case 'W': sigma_dut_print(&sigma_dut, DUT_MSG_INFO, "Running WMM-AC test suite"); sigma_wmm_ac = 1; break; case 'u': sigma_dut_print(&sigma_dut, DUT_MSG_INFO, "Use iface down/up in reset cmd"); sigma_dut.iface_down_on_reset = 1; break; case 'h': default: printf("usage: sigma_dut [-aBdfqDIntuVW] [-p<port>] " "[-s<sniffer>] [-m<set_maccaddr.sh>] \\\n" " [-M<main ifname>] [-R<radio ifname>] " "[-S<station ifname>] \\\n" " [-T<throughput pktsize>] \\\n" " [-w<wpa_supplicant/hostapd ctrl_iface " "dir>] \\\n" " [-H <hostapd log file>] \\\n" " [-C <certificate path>] \\\n" " [-v <version string>] \\\n" " [-L <summary log>] \\\n" " [-c <wifi chip type: WCN or ATHEROS or " "AR6003 or MAC80211 or QNXNTO or OPENWRT>] " "\\\n" " [-i <IP address of the AP>] \\\n" " [-k <subnet mask for the AP>] \\\n" " [-e <hostapd entropy file>] \\\n" " [-r <HT40>]\n"); printf("local command: sigma_dut [-p<port>] " "<-l<cmd>>\n"); exit(0); break; } } if (local_cmd) return run_local_cmd(port, local_cmd); if (wifi_chip_type == DRIVER_QNXNTO && (sigma_main_ifname == NULL || sigma_station_ifname == NULL)) { sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, "Interface should be provided for QNX driver check option M and S"); } sigma_dut_register_cmds(); #ifdef __QNXNTO__ /* Try to open socket in other env dev */ if (sigma_ctrl_sock) { env_str = getenv("SOCK"); if (env_str) { sigma_dut_print(&sigma_dut, DUT_MSG_INFO, "SOCK=%s", env_str); } snprintf(buf, sizeof(buf), "SOCK=%s", sigma_ctrl_sock); if (putenv(buf) != 0) { sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, "putenv() failed setting SOCK"); return EXIT_FAILURE; } } #endif /* __QNXNTO__ */ if (open_socket(&sigma_dut, port) < 0) return -1; #ifdef __QNXNTO__ /* restore back the SOCK */ if (sigma_ctrl_sock) { if (env_str) { snprintf(buf, sizeof(buf), "SOCK=%s", env_str); if (putenv(buf) != 0) { sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, "putenv() failed setting SOCK"); return EXIT_FAILURE; } } else { /* unset the env for sock */ unsetenv("SOCK"); } } #endif /* __QNXNTO__ */ if (daemonize) { if (daemon(0, 0) < 0) { perror("daemon"); exit(-1); } } else { #ifdef __linux__ setlinebuf(stdout); #endif /* __linux__ */ } run_loop(&sigma_dut); #ifdef CONFIG_SNIFFER sniffer_close(&sigma_dut); #endif /* CONFIG_SNIFFER */ close_socket(&sigma_dut); sigma_dut_unreg_cmds(&sigma_dut); return 0; }
void send_resp_debug(enum sigma_status status, char *buf) { sigma_dut_print( DUT_MSG_INFO, "resp: status=%d buf=%s", status, buf); }