1/* 2 * Copyright (c) 2007-2008 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16/* */ 17/* Module Name : apdbg.c */ 18/* */ 19/* Abstract */ 20/* Debug tools */ 21/* */ 22/* NOTES */ 23/* None */ 24/* */ 25/************************************************************************/ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <unistd.h> 30#include <string.h> 31#include <errno.h> 32#include <ctype.h> 33#include <sys/types.h> 34#include <sys/socket.h> 35#include <sys/ioctl.h> 36#include <net/if.h> 37#include <netinet/in.h> 38 39#include <linux/sockios.h> 40 41#define ZM_IOCTL_REG_READ 0x01 42#define ZM_IOCTL_REG_WRITE 0x02 43#define ZM_IOCTL_MEM_DUMP 0x03 44#define ZM_IOCTL_REG_DUMP 0x05 45#define ZM_IOCTL_TXD_DUMP 0x06 46#define ZM_IOCTL_RXD_DUMP 0x07 47#define ZM_IOCTL_MEM_READ 0x0B 48#define ZM_IOCTL_MEM_WRITE 0x0C 49#define ZM_IOCTL_DMA_TEST 0x10 50#define ZM_IOCTL_REG_TEST 0x11 51#define ZM_IOCTL_TEST 0x80 52#define ZM_IOCTL_TALLY 0x81 /* CWYang(+) */ 53#define ZM_IOCTL_RTS 0xA0 54#define ZM_IOCTL_MIX_MODE 0xA1 55#define ZM_IOCTL_FRAG 0xA2 56#define ZM_IOCTL_SCAN 0xA3 57#define ZM_IOCTL_KEY 0xA4 58#define ZM_IOCTL_RATE 0xA5 59#define ZM_IOCTL_ENCRYPTION_MODE 0xA6 60#define ZM_IOCTL_GET_TXCNT 0xA7 61#define ZM_IOCTL_GET_DEAGG_CNT 0xA8 62#define ZM_IOCTL_DURATION_MODE 0xA9 63#define ZM_IOCTL_SET_AES_KEY 0xAA 64#define ZM_IOCTL_SET_AES_MODE 0xAB 65#define ZM_IOCTL_SIGNAL_STRENGTH 0xAC /* CWYang(+) */ 66#define ZM_IOCTL_SIGNAL_QUALITY 0xAD /* CWYang(+) */ 67#define ZM_IOCTL_SET_PIBSS_MODE 0xAE 68#define ZDAPIOCTL SIOCDEVPRIVATE 69 70struct zdap_ioctl { 71 unsigned short cmd; /* Command to run */ 72 unsigned int addr; /* Length of the data buffer */ 73 unsigned int value; /* Pointer to the data buffer */ 74 unsigned char data[0x100]; 75}; 76 77/* Declaration of macro and function for handling WEP Keys */ 78 79 80char *prgname; 81 82int set_ioctl(int sock, struct ifreq *req) 83{ 84 if (ioctl(sock, ZDAPIOCTL, req) < 0) { 85 fprintf(stderr, "%s: ioctl(SIOCGIFMAP): %s\n", 86 prgname, strerror(errno)); 87 return -1; 88 } 89 90 return 0; 91} 92 93 94int read_reg(int sock, struct ifreq *req) 95{ 96 struct zdap_ioctl *zdreq = NULL; 97 98 if (!set_ioctl(sock, req)) 99 return -1; 100 101 /* 102 * zdreq = (struct zdap_ioctl *)req->ifr_data; 103 * printf( "reg = %4x, value = %4x\n", zdreq->addr, zdreq->value); 104 */ 105 106 return 0; 107} 108 109 110int read_mem(int sock, struct ifreq *req) 111{ 112 struct zdap_ioctl *zdreq = NULL; 113 int i; 114 115 if (!set_ioctl(sock, req)) 116 return -1; 117 118 /* 119 * zdreq = (struct zdap_ioctl *)req->ifr_data; 120 * printf("dump mem from %x, length = %x\n", zdreq->addr, zdreq->value); 121 * 122 * for (i=0; i<zdreq->value; i++) { 123 * printf("%02x", zdreq->data[i]); 124 * printf(" "); 125 * 126 * if ((i>0) && ((i+1)%16 == 0)) 127 * printf("\n"); 128 * } 129 */ 130 131 return 0; 132} 133 134 135int main(int argc, char **argv) 136{ 137 int sock; 138 int addr, value; 139 struct ifreq req; 140 char *action = NULL; 141 struct zdap_ioctl zdreq; 142 143 prgname = argv[0]; 144 145 if (argc < 3) { 146 fprintf(stderr, "%s: usage is \"%s <ifname> <operation>" 147 "[<address>] [<value>]\"\n", prgname, prgname); 148 fprintf(stderr, "valid operation : read, write, mem, reg,\n"); 149 fprintf(stderr, " : txd, rxd, rmem, wmem\n"); 150 fprintf(stderr, " : dmat, regt, test\n"); 151 152 fprintf(stderr, " scan, Channel Scan\n"); 153 fprintf(stderr, " rts <decimal>, Set RTS Threshold\n"); 154 fprintf(stderr, " frag <decimal>, Set Fragment" 155 " Threshold\n"); 156 fprintf(stderr, " rate <0-28>, 0:AUTO, 1-4:CCK," 157 " 5-12:OFDM, 13-28:HT\n"); 158 fprintf(stderr, " TBD mix <0 or 1>, Set 1 to enable" 159 " mixed mode\n"); 160 fprintf(stderr, " enc, <0-3>, 0=>OPEN, 1=>WEP64, " 161 "2=>WEP128, 3=>WEP256\n"); 162 fprintf(stderr, " skey <key>, Set WEP key\n"); 163 fprintf(stderr, " txcnt, Get TxQ Cnt\n"); 164 fprintf(stderr, " dagcnt, Get Deaggregate Cnt\n"); 165 fprintf(stderr, " durmode <mode>, Set Duration Mode " 166 "0=>HW, 1=>SW\n"); 167 fprintf(stderr, " aeskey <user> <key>\n"); 168 fprintf(stderr, " aesmode <mode>\n"); 169 fprintf(stderr, " wlanmode <0,1> 0:Station mode, " 170 "1:PIBSS mode\n"); 171 fprintf(stderr, " tal <0,1>, Get Current Tally Info, " 172 "0=>read, 1=>read and reset\n"); 173 174 exit(1); 175 } 176 177 strcpy(req.ifr_name, argv[1]); 178 zdreq.addr = 0; 179 zdreq.value = 0; 180 181 /* a silly raw socket just for ioctl()ling it */ 182 sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 183 if (sock < 0) { 184 fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno)); 185 exit(1); 186 } 187 188 if (argc >= 4) 189 sscanf(argv[3], "%x", &addr); 190 191 if (argc >= 5) 192 sscanf(argv[4], "%x", &value); 193 194 zdreq.addr = addr; 195 zdreq.value = value; 196 197 if (!strcmp(argv[2], "read")) 198 zdreq.cmd = ZM_IOCTL_REG_READ; 199 else if (!strcmp(argv[2], "mem")) 200 zdreq.cmd = ZM_IOCTL_MEM_DUMP; 201 else if (!strcmp(argv[2], "write")) 202 zdreq.cmd = ZM_IOCTL_REG_WRITE; 203 else if (!strcmp(argv[2], "reg")) 204 zdreq.cmd = ZM_IOCTL_REG_DUMP; 205 else if (!strcmp(argv[2], "txd")) 206 zdreq.cmd = ZM_IOCTL_TXD_DUMP; 207 else if (!strcmp(argv[2], "rxd")) 208 zdreq.cmd = ZM_IOCTL_RXD_DUMP; 209 else if (!strcmp(argv[2], "rmem")) 210 zdreq.cmd = ZM_IOCTL_MEM_READ; 211 else if (!strcmp(argv[2], "wmem")) 212 zdreq.cmd = ZM_IOCTL_MEM_WRITE; 213 else if (!strcmp(argv[2], "dmat")) 214 zdreq.cmd = ZM_IOCTL_DMA_TEST; 215 else if (!strcmp(argv[2], "regt")) 216 zdreq.cmd = ZM_IOCTL_REG_TEST; 217 else if (!strcmp(argv[2], "test")) 218 zdreq.cmd = ZM_IOCTL_TEST; 219 else if (!strcmp(argv[2], "tal")) { 220 sscanf(argv[3], "%d", &addr); 221 zdreq.addr = addr; 222 zdreq.cmd = ZM_IOCTL_TALLY; 223 } else if (!strcmp(argv[2], "rts")) { 224 sscanf(argv[3], "%d", &addr); 225 zdreq.addr = addr; 226 zdreq.cmd = ZM_IOCTL_RTS; 227 } else if (!strcmp(argv[2], "mix")) { 228 zdreq.cmd = ZM_IOCTL_MIX_MODE; 229 } else if (!strcmp(argv[2], "frag")) { 230 sscanf(argv[3], "%d", &addr); 231 zdreq.addr = addr; 232 zdreq.cmd = ZM_IOCTL_FRAG; 233 } else if (!strcmp(argv[2], "scan")) { 234 zdreq.cmd = ZM_IOCTL_SCAN; 235 } else if (!strcmp(argv[2], "skey")) { 236 zdreq.cmd = ZM_IOCTL_KEY; 237 238 if (argc >= 4) { 239 unsigned char temp[29]; 240 int i; 241 int keyLen; 242 int encType; 243 244 keyLen = strlen(argv[3]); 245 246 if (keyLen == 10) 247 sscanf(argv[3], "%02x%02x%02x%02x%02x", 248 &temp[0], &temp[1], &temp[2], &temp[3], 249 &temp[4]); 250 else if (keyLen == 26) 251 sscanf(argv[3], "%02x%02x%02x%02x%02x%02x" 252 "%02x%02x%02x%02x%02x%02x%02x", 253 &temp[0], &temp[1], &temp[2], &temp[3], 254 &temp[4], &temp[5], &temp[6], &temp[7], 255 &temp[8], &temp[9], &temp[10], 256 &temp[11], &temp[12]); 257 else if (keyLen == 58) 258 sscanf(argv[3], "%02x%02x%02x%02x%02x%02x" 259 "%02x%02x%02x%02x%02x%02x%02x%02x%02x" 260 "%02x%02x%02x%02x%02x%02x%02x%02x%02x" 261 "%02x%02x%02x%02x%02x", 262 &temp[0], &temp[1], &temp[2], &temp[3], 263 &temp[4], &temp[5], &temp[6], &temp[7], 264 &temp[8], &temp[9], &temp[10], 265 &temp[11], &temp[12], &temp[13], 266 &temp[14], &temp[15], &temp[16], 267 &temp[17], &temp[18], &temp[19], 268 &temp[20], &temp[21], &temp[22], 269 &temp[23], &temp[24], &temp[25], 270 &temp[26], &temp[27], &temp[28]); 271 else { 272 fprintf(stderr, "Invalid key length\n"); 273 exit(1); 274 } 275 zdreq.addr = keyLen/2; 276 277 for (i = 0; i < zdreq.addr; i++) 278 zdreq.data[i] = temp[i]; 279 } else { 280 printf("Error : Key required!\n"); 281 } 282 } else if (!strcmp(argv[2], "rate")) { 283 sscanf(argv[3], "%d", &addr); 284 285 if (addr > 28) { 286 fprintf(stderr, "Invalid rate, range:0~28\n"); 287 exit(1); 288 } 289 zdreq.addr = addr; 290 zdreq.cmd = ZM_IOCTL_RATE; 291 } else if (!strcmp(argv[2], "enc")) { 292 sscanf(argv[3], "%d", &addr); 293 294 if (addr > 3) { 295 fprintf(stderr, "Invalid encryption mode, range:0~3\n"); 296 exit(1); 297 } 298 299 if (addr == 2) 300 addr = 5; 301 else if (addr == 3) 302 addr = 6; 303 304 zdreq.addr = addr; 305 zdreq.cmd = ZM_IOCTL_ENCRYPTION_MODE; 306 } else if (!strcmp(argv[2], "txcnt")) { 307 zdreq.cmd = ZM_IOCTL_GET_TXCNT; 308 } else if (!strcmp(argv[2], "dagcnt")) { 309 sscanf(argv[3], "%d", &addr); 310 311 if (addr != 0 && addr != 1) { 312 fprintf(stderr, "The value should be 0 or 1\n"); 313 exit(0); 314 } 315 316 zdreq.addr = addr; 317 zdreq.cmd = ZM_IOCTL_GET_DEAGG_CNT; 318 } else if (!strcmp(argv[2], "durmode")) { 319 sscanf(argv[3], "%d", &addr); 320 321 if (addr != 0 && addr != 1) { 322 fprintf(stderr, "The Duration mode should be 0 or 1\n"); 323 exit(0); 324 } 325 326 zdreq.addr = addr; 327 zdreq.cmd = ZM_IOCTL_DURATION_MODE; 328 } else if (!strcmp(argv[2], "aeskey")) { 329 unsigned char temp[16]; 330 int i; 331 332 sscanf(argv[3], "%d", &addr); 333 334 sscanf(argv[4], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" 335 "%02x%02x%02x%02x%02x%02x", &temp[0], &temp[1], 336 &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], 337 &temp[7], &temp[8], &temp[9], &temp[10], &temp[11], 338 &temp[12], &temp[13], &temp[14], &temp[15]); 339 340 for (i = 0; i < 16; i++) 341 zdreq.data[i] = temp[i]; 342 343 zdreq.addr = addr; 344 zdreq.cmd = ZM_IOCTL_SET_AES_KEY; 345 } else if (!strcmp(argv[2], "aesmode")) { 346 sscanf(argv[3], "%d", &addr); 347 348 zdreq.addr = addr; 349 zdreq.cmd = ZM_IOCTL_SET_AES_MODE; 350 } else if (!strcmp(argv[2], "wlanmode")) { 351 sscanf(argv[3], "%d", &addr); 352 353 zdreq.addr = addr; 354 zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE; 355 } else { 356 fprintf(stderr, "error action\n"); 357 exit(1); 358 } 359 360 req.ifr_data = (char *)&zdreq; 361 set_ioctl(sock, &req); 362 363fail: 364 exit(0); 365} 366