4 * Jean II - HPLB 97->99 - HPL 99->00
6 * Main code for "iwconfig". This is the generic tool for most
8 * You need to link this code against "iwlib.c" and "-lm".
10 * This file is released under the GPL license.
11 * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
14 #include "iwlib.h" /* Header */
16 /**************************** CONSTANTS ****************************/
18 static const char * argtype[] = {
19 " ", "byte", "char", "", "int ", "float" };
21 /************************* MISC SUBROUTINES **************************/
23 /*------------------------------------------------------------------*/
30 fprintf(stderr, "Usage: iwpriv interface [private-command [private-arguments]]\n");
31 fprintf(stderr, " interface [roam {on|off}]\n");
32 fprintf(stderr, " interface [port {ad-hoc|managed|N}]\n");
35 /************************ GENERIC FUNCTIONS *************************/
37 /*------------------------------------------------------------------*/
39 * Print on the screen in a neat fashion all the info we have collected
43 print_priv_info(int skfd,
52 /* Avoid "Unused parameter" warning */
53 args = args; count = count;
55 /* Read the private ioctls */
56 n = iw_get_priv_info(skfd, ifname, priv);
61 /* Could skip this message ? */
62 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
67 printf("%-8.8s Available private ioctl :\n", ifname);
69 for(k = 0; k < n; k++)
70 printf(" %s (%X) : set %3d %s & get %3d %s\n",
71 priv[k].name, priv[k].cmd,
72 priv[k].set_args & IW_PRIV_SIZE_MASK,
73 argtype[(priv[k].set_args & IW_PRIV_TYPE_MASK) >> 12],
74 priv[k].get_args & IW_PRIV_SIZE_MASK,
75 argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);
81 /************************* SETTING ROUTINES **************************/
83 /*------------------------------------------------------------------*/
85 * Execute a private command on the interface
88 set_private(int skfd, /* Socket */
89 char * args[], /* Command line args */
90 int count, /* Args count */
91 char * ifname) /* Dev name */
95 int i = 0; /* Start with first arg */
101 /* Read the private ioctls */
102 number = iw_get_priv_info(skfd, ifname, priv);
107 /* Could skip this message ? */
108 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
113 /* Search the correct ioctl */
115 while((++k < number) && strcmp(priv[k].name, args[i]));
117 /* If not found... */
120 fprintf(stderr, "Invalid command : %s\n", args[i]);
127 /* If we have to set some data */
128 if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
129 (priv[k].set_args & IW_PRIV_SIZE_MASK))
131 switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
133 case IW_PRIV_TYPE_BYTE:
134 /* Number of args to fetch */
135 wrq.u.data.length = count - 1;
136 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
137 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
140 for(; i < wrq.u.data.length + 1; i++) {
141 sscanf(args[i], "%d", &temp);
142 buffer[i - 1] = (char) temp;
146 case IW_PRIV_TYPE_INT:
147 /* Number of args to fetch */
148 wrq.u.data.length = count - 1;
149 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
150 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
153 for(; i < wrq.u.data.length + 1; i++)
154 sscanf(args[i], "%d", ((u_int *) buffer) + i - 1);
157 case IW_PRIV_TYPE_CHAR:
160 /* Size of the string to fetch */
161 wrq.u.data.length = strlen(args[i]) + 1;
162 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
163 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
166 memcpy(buffer, args[i], wrq.u.data.length);
167 buffer[sizeof(buffer) - 1] = '\0';
172 wrq.u.data.length = 1;
178 fprintf(stderr, "Not yet implemented...\n");
182 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
183 (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
185 printf("The command %s need exactly %d argument...\n",
186 priv[k].name, priv[k].set_args & IW_PRIV_SIZE_MASK);
189 } /* if args to set */
192 wrq.u.data.length = 0L;
195 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
197 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
198 (iw_byte_size(priv[k].set_args) < IFNAMSIZ))
199 memcpy(wrq.u.name, buffer, IFNAMSIZ);
202 wrq.u.data.pointer = (caddr_t) buffer;
203 wrq.u.data.flags = 0;
206 /* Perform the private ioctl */
207 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
209 fprintf(stderr, "Interface doesn't accept private ioctl...\n");
210 fprintf(stderr, "%X: %s\n", priv[k].cmd, strerror(errno));
214 /* If we have to get some data */
215 if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
216 (priv[k].get_args & IW_PRIV_SIZE_MASK))
219 int n = 0; /* number of args */
221 printf("%-8.8s %s:", ifname, priv[k].name);
223 if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
224 (iw_byte_size(priv[k].get_args) < IFNAMSIZ))
226 memcpy(buffer, wrq.u.name, IFNAMSIZ);
227 n = priv[k].get_args & IW_PRIV_SIZE_MASK;
230 n = wrq.u.data.length;
232 switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
234 case IW_PRIV_TYPE_BYTE:
236 for(j = 0; j < n; j++)
237 printf("%d ", buffer[j]);
241 case IW_PRIV_TYPE_INT:
243 for(j = 0; j < n; j++)
244 printf("%d ", ((u_int *) buffer)[j]);
248 case IW_PRIV_TYPE_CHAR:
250 buffer[wrq.u.data.length - 1] = '\0';
251 printf("%s\n", buffer);
255 fprintf(stderr, "Not yet implemented...\n");
258 } /* if args to set */
263 /********************** PRIVATE IOCTLS MANIPS ***********************/
265 * Convenient access to some private ioctls of some devices
268 /*------------------------------------------------------------------*/
270 * Set roaming mode on and off
271 * Found in wavelan_cs driver
274 set_roaming(int skfd, /* Socket */
275 char * args[], /* Command line args */
276 int count, /* Args count */
277 char * ifname) /* Dev name */
281 int i = 0; /* Start with first arg */
285 char RoamState; /* buffer to hold new roam state */
286 char ChangeRoamState=0; /* whether or not we are going to
287 change roam states */
289 /* Read the private ioctls */
290 number = iw_get_priv_info(skfd, ifname, priv);
295 /* Could skip this message ? */
296 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
307 if(!strcasecmp(args[i], "on"))
309 printf("%-8.8s enable roaming\n", ifname);
312 fprintf(stderr, "This device doesn't support roaming\n");
319 if(!strcasecmp(args[i], "off"))
322 printf("%-8.8s disable roaming\n", ifname);
325 fprintf(stderr, "This device doesn't support roaming\n");
340 while((++k < number) && strcmp(priv[k].name, "setroam"));
343 fprintf(stderr, "This device doesn't support roaming\n");
346 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
350 memcpy(wrq.u.name, &buffer, IFNAMSIZ);
352 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
354 fprintf(stderr, "Roaming support is broken.\n");
362 /*------------------------------------------------------------------*/
364 * Get and set the port type
365 * Found in wavelan2_cs and wvlan_cs drivers
368 port_type(int skfd, /* Socket */
369 char * args[], /* Command line args */
370 int count, /* Args count */
371 char * ifname) /* Dev name */
374 int i = 0; /* Start with first arg */
379 char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
381 /* Read the private ioctls */
382 number = iw_get_priv_info(skfd, ifname, priv);
387 /* Could skip this message ? */
388 fprintf(stderr, "%-8.8s no private ioctls.\n\n", ifname);
395 /* So, we just want to see the current value... */
397 while((++k < number) && strcmp(priv[k].name, "gport_type") &&
398 strcmp(priv[k].name, "get_port"));
401 fprintf(stderr, "This device doesn't support getting port type\n");
404 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
407 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
409 fprintf(stderr, "Port type support is broken.\n");
415 printf("%-8.8s Current port mode is %s <port type is %d>.\n\n",
416 ifname, modes[(int) ptype], ptype);
430 while((k < 4) && strncasecmp(args[i], modes[k], 2))
435 /* ...or as an integer */
436 if(sscanf(args[i], "%d", (int *) &ptype) != 1)
443 while((++k < number) && strcmp(priv[k].name, "sport_type") &&
444 strcmp(priv[k].name, "set_port"));
447 fprintf(stderr, "This device doesn't support setting port type\n");
450 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
452 *(wrq.u.name) = ptype;
454 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
456 fprintf(stderr, "Invalid port type (or setting not allowed)\n");
463 /******************************* MAIN ********************************/
465 /*------------------------------------------------------------------*/
473 int skfd; /* generic raw socket desc. */
476 /* Create a channel to the NET kernel. */
477 if((skfd = iw_sockets_open()) < 0)
483 /* No argument : show the list of all device + info */
485 iw_enum_devices(skfd, &print_priv_info, NULL, 0);
487 /* Special cases take one... */
489 if((!strncmp(argv[1], "-h", 9)) ||
490 (!strcmp(argv[1], "--help")))
493 /* The device name must be the first argument */
494 /* Name only : show for that device only */
496 print_priv_info(skfd, argv[1], NULL, 0);
498 /* Special cases take two... */
500 if(!strncmp(argv[2], "roam", 4))
501 goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);
504 if(!strncmp(argv[2], "port", 4))
505 goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);
507 /* Otherwise, it's a private ioctl */
508 goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);
510 /* Close the socket. */