6 * Main code for "iwconfig". This is the generic tool for most
8 * You need to link this code against "iwcommon.c" and "-lm".
11 #include "iwcommon.h" /* Header */
13 /************************* MISC SUBROUTINES **************************/
15 /*------------------------------------------------------------------*/
22 fprintf(stderr, "Usage: iwpriv interface [private-command [private-arguments]]\n");
23 fprintf(stderr, " interface [roam {on|off}]\n");
24 fprintf(stderr, " interface [port {ad-hoc|managed|N}]\n");
28 /************************ GENERIC FUNCTIONS *************************/
30 /*------------------------------------------------------------------*/
32 * Print on the screen in a neat fashion all the info we have collected
36 print_priv_info(int skfd,
42 char * argtype[] = { " ", "byte", "char", "", "int", "float" };
44 /* Read the private ioctls */
45 n = get_priv_info(skfd, ifname, priv);
50 /* Could skip this message ? */
51 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
56 printf("%-8.8s Available private ioctl :\n", ifname);
58 for(k = 0; k < n; k++)
59 printf(" %s (%X) : set %3d %s & get %3d %s\n",
60 priv[k].name, priv[k].cmd,
61 priv[k].set_args & IW_PRIV_SIZE_MASK,
62 argtype[(priv[k].set_args & IW_PRIV_TYPE_MASK) >> 12],
63 priv[k].get_args & IW_PRIV_SIZE_MASK,
64 argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);
69 /*------------------------------------------------------------------*/
71 * Get info on all devices and print it on the screen
74 print_priv_devices(int skfd)
81 /* Get list of active devices */
82 ifc.ifc_len = sizeof(buff);
84 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
86 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
92 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
93 print_priv_info(skfd, ifr->ifr_name);
96 /************************* SETTING ROUTINES **************************/
98 /*------------------------------------------------------------------*/
100 * Execute a private command on the interface
103 set_private(int skfd, /* Socket */
104 char * args[], /* Command line args */
105 int count, /* Args count */
106 char * ifname) /* Dev name */
110 int i = 0; /* Start with first arg */
115 /* Read the private ioctls */
116 number = get_priv_info(skfd, ifname, priv);
121 /* Could skip this message ? */
122 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
127 /* Search the correct ioctl */
129 while((++k < number) && strcmp(priv[k].name, args[i]));
131 /* If not found... */
134 fprintf(stderr, "Invalid command : %s\n", args[i]);
141 /* If we have to set some data */
142 if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
143 (priv[k].set_args & IW_PRIV_SIZE_MASK))
145 switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
147 case IW_PRIV_TYPE_BYTE:
148 /* Number of args to fetch */
149 wrq.u.data.length = count - 1;
150 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
151 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
154 for(; i < wrq.u.data.length + 1; i++)
155 sscanf(args[i], "%d", (int *)(buffer + i - 1));
158 case IW_PRIV_TYPE_INT:
159 /* Number of args to fetch */
160 wrq.u.data.length = count - 1;
161 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
162 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
165 for(; i < wrq.u.data.length + 1; i++)
166 sscanf(args[i], "%d", ((u_int *) buffer) + i - 1);
169 case IW_PRIV_TYPE_CHAR:
172 /* Size of the string to fetch */
173 wrq.u.data.length = strlen(args[i]) + 1;
174 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
175 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
178 memcpy(buffer, args[i], wrq.u.data.length);
179 buffer[sizeof(buffer) - 1] = '\0';
184 wrq.u.data.length = 1;
190 fprintf(stderr, "Not yet implemented...\n");
194 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
195 (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
197 printf("The command %s need exactly %d argument...\n",
198 priv[k].name, priv[k].set_args & IW_PRIV_SIZE_MASK);
201 } /* if args to set */
204 wrq.u.data.length = 0L;
207 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
209 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
210 (byte_size(priv[k].set_args) < IFNAMSIZ))
211 memcpy(wrq.u.name, buffer, IFNAMSIZ);
214 wrq.u.data.pointer = (caddr_t) buffer;
215 wrq.u.data.flags = 0;
218 /* Perform the private ioctl */
219 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
221 fprintf(stderr, "Interface doesn't accept private ioctl...\n");
222 fprintf(stderr, "%X: %s\n", priv[k].cmd, strerror(errno));
226 /* If we have to get some data */
227 if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
228 (priv[k].get_args & IW_PRIV_SIZE_MASK))
231 int n = 0; /* number of args */
233 printf("%-8.8s %s:", ifname, priv[k].name);
235 if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
236 (byte_size(priv[k].get_args) < IFNAMSIZ))
238 memcpy(buffer, wrq.u.name, IFNAMSIZ);
239 n = priv[k].get_args & IW_PRIV_SIZE_MASK;
242 n = wrq.u.data.length;
244 switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
246 case IW_PRIV_TYPE_BYTE:
248 for(j = 0; j < n; j++)
249 printf("%d ", buffer[j]);
253 case IW_PRIV_TYPE_INT:
255 for(j = 0; j < n; j++)
256 printf("%d ", ((u_int *) buffer)[i]);
260 case IW_PRIV_TYPE_CHAR:
262 buffer[wrq.u.data.length - 1] = '\0';
263 printf("%s\n", buffer);
267 fprintf(stderr, "Not yet implemented...\n");
270 } /* if args to set */
275 /********************** PRIVATE IOCTLS MANIPS ***********************/
277 * Convenient access to some private ioctls of some devices
280 /*------------------------------------------------------------------*/
282 * Set roaming mode on and off
283 * Found in wavelan_cs driver
286 set_roaming(int skfd, /* Socket */
287 char * args[], /* Command line args */
288 int count, /* Args count */
289 char * ifname) /* Dev name */
293 int i = 0; /* Start with first arg */
297 char RoamState; /* buffer to hold new roam state */
298 char ChangeRoamState=0; /* whether or not we are going to
299 change roam states */
301 /* Read the private ioctls */
302 number = get_priv_info(skfd, ifname, priv);
307 /* Could skip this message ? */
308 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
316 if(!strcasecmp(args[i], "on"))
318 printf("%-8.8s enable roaming\n", ifname);
321 fprintf(stderr, "This device doesn't support roaming\n");
328 if(!strcasecmp(args[i], "off"))
331 printf("%-8.8s disable roaming\n", ifname);
334 fprintf(stderr, "This device doesn't support roaming\n");
349 while((++k < number) && strcmp(priv[k].name, "setroam"));
352 fprintf(stderr, "This device doesn't support roaming\n");
355 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
359 memcpy(wrq.u.name, &buffer, IFNAMSIZ);
361 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
363 fprintf(stderr, "Roaming support is broken.\n");
372 /*------------------------------------------------------------------*/
374 * Get and set the port type
375 * Found in wavelan2_cs and wvlan_cs drivers
378 port_type(int skfd, /* Socket */
379 char * args[], /* Command line args */
380 int count, /* Args count */
381 char * ifname) /* Dev name */
384 int i = 0; /* Start with first arg */
389 char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
391 /* Read the private ioctls */
392 number = get_priv_info(skfd, ifname, priv);
397 /* Could skip this message ? */
398 fprintf(stderr, "%-8.8s no private ioctls.\n\n", ifname);
405 /* So, we just want to see the current value... */
407 while((++k < number) && strcmp(priv[k].name, "gport_type") &&
408 strcmp(priv[k].name, "get_port"));
411 fprintf(stderr, "This device doesn't support getting port type\n");
414 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
417 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
419 fprintf(stderr, "Port type support is broken.\n");
425 printf("%-8.8s Current port mode is %s <port type is %d>.\n\n",
426 ifname, modes[(int) ptype], ptype);
437 while((k < 4) && strncasecmp(args[i], modes[k], 2))
442 /* ...or as an integer */
443 if(sscanf(args[i], "%d", (int *) &ptype) != 1)
447 while((++k < number) && strcmp(priv[k].name, "sport_type") &&
448 strcmp(priv[k].name, "set_port"));
451 fprintf(stderr, "This device doesn't support setting port type\n");
454 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
456 *(wrq.u.name) = ptype;
458 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
460 fprintf(stderr, "Invalid port type (or setting not allowed)\n");
468 /******************************* MAIN ********************************/
470 /*------------------------------------------------------------------*/
478 int skfd = -1; /* generic raw socket desc. */
481 /* Create a channel to the NET kernel. */
482 if((skfd = sockets_open()) < 0)
488 /* No argument : show the list of all device + info */
491 print_priv_devices(skfd);
496 /* Special cases take one... */
498 if((!strncmp(argv[1], "-h", 9)) ||
499 (!strcmp(argv[1], "--help")))
506 /* The device name must be the first argument */
507 /* Name only : show for that device only */
510 print_priv_info(skfd, argv[1]);
515 /* Special cases take two... */
517 if(!strncmp(argv[2], "roam", 4))
519 goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);
525 if(!strncmp(argv[2], "port", 4))
527 goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);
532 /* Otherwise, it's a private ioctl */
533 goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);
535 /* Close the socket. */