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 /************************* MISC SUBROUTINES **************************/
18 /*------------------------------------------------------------------*/
25 fprintf(stderr, "Usage: iwpriv interface [private-command [private-arguments]]\n");
26 fprintf(stderr, " interface [roam {on|off}]\n");
27 fprintf(stderr, " interface [port {ad-hoc|managed|N}]\n");
30 /************************ GENERIC FUNCTIONS *************************/
32 /*------------------------------------------------------------------*/
34 * Print on the screen in a neat fashion all the info we have collected
38 print_priv_info(int skfd,
44 char * argtype[] = { " ", "byte", "char", "", "int ", "float" };
46 /* Read the private ioctls */
47 n = iw_get_priv_info(skfd, ifname, priv);
52 /* Could skip this message ? */
53 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
58 printf("%-8.8s Available private ioctl :\n", ifname);
60 for(k = 0; k < n; k++)
61 printf(" %s (%X) : set %3d %s & get %3d %s\n",
62 priv[k].name, priv[k].cmd,
63 priv[k].set_args & IW_PRIV_SIZE_MASK,
64 argtype[(priv[k].set_args & IW_PRIV_TYPE_MASK) >> 12],
65 priv[k].get_args & IW_PRIV_SIZE_MASK,
66 argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);
71 /*------------------------------------------------------------------*/
73 * Get info on all devices and print it on the screen
76 print_priv_devices(int skfd)
83 /* Get list of active devices */
84 ifc.ifc_len = sizeof(buff);
86 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
88 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
94 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
95 print_priv_info(skfd, ifr->ifr_name);
98 /************************* SETTING ROUTINES **************************/
100 /*------------------------------------------------------------------*/
102 * Execute a private command on the interface
105 set_private(int skfd, /* Socket */
106 char * args[], /* Command line args */
107 int count, /* Args count */
108 char * ifname) /* Dev name */
112 int i = 0; /* Start with first arg */
118 /* Read the private ioctls */
119 number = iw_get_priv_info(skfd, ifname, priv);
124 /* Could skip this message ? */
125 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
130 /* Search the correct ioctl */
132 while((++k < number) && strcmp(priv[k].name, args[i]));
134 /* If not found... */
137 fprintf(stderr, "Invalid command : %s\n", args[i]);
144 /* If we have to set some data */
145 if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
146 (priv[k].set_args & IW_PRIV_SIZE_MASK))
148 switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
150 case IW_PRIV_TYPE_BYTE:
151 /* Number of args to fetch */
152 wrq.u.data.length = count - 1;
153 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
154 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
157 for(; i < wrq.u.data.length + 1; i++) {
158 sscanf(args[i], "%d", &temp);
159 buffer[i - 1] = (char) temp;
163 case IW_PRIV_TYPE_INT:
164 /* Number of args to fetch */
165 wrq.u.data.length = count - 1;
166 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
167 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
170 for(; i < wrq.u.data.length + 1; i++)
171 sscanf(args[i], "%d", ((u_int *) buffer) + i - 1);
174 case IW_PRIV_TYPE_CHAR:
177 /* Size of the string to fetch */
178 wrq.u.data.length = strlen(args[i]) + 1;
179 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
180 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
183 memcpy(buffer, args[i], wrq.u.data.length);
184 buffer[sizeof(buffer) - 1] = '\0';
189 wrq.u.data.length = 1;
195 fprintf(stderr, "Not yet implemented...\n");
199 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
200 (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
202 printf("The command %s need exactly %d argument...\n",
203 priv[k].name, priv[k].set_args & IW_PRIV_SIZE_MASK);
206 } /* if args to set */
209 wrq.u.data.length = 0L;
212 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
214 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
215 (iw_byte_size(priv[k].set_args) < IFNAMSIZ))
216 memcpy(wrq.u.name, buffer, IFNAMSIZ);
219 wrq.u.data.pointer = (caddr_t) buffer;
220 wrq.u.data.flags = 0;
223 /* Perform the private ioctl */
224 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
226 fprintf(stderr, "Interface doesn't accept private ioctl...\n");
227 fprintf(stderr, "%X: %s\n", priv[k].cmd, strerror(errno));
231 /* If we have to get some data */
232 if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
233 (priv[k].get_args & IW_PRIV_SIZE_MASK))
236 int n = 0; /* number of args */
238 printf("%-8.8s %s:", ifname, priv[k].name);
240 if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
241 (iw_byte_size(priv[k].get_args) < IFNAMSIZ))
243 memcpy(buffer, wrq.u.name, IFNAMSIZ);
244 n = priv[k].get_args & IW_PRIV_SIZE_MASK;
247 n = wrq.u.data.length;
249 switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
251 case IW_PRIV_TYPE_BYTE:
253 for(j = 0; j < n; j++)
254 printf("%d ", buffer[j]);
258 case IW_PRIV_TYPE_INT:
260 for(j = 0; j < n; j++)
261 printf("%d ", ((u_int *) buffer)[j]);
265 case IW_PRIV_TYPE_CHAR:
267 buffer[wrq.u.data.length - 1] = '\0';
268 printf("%s\n", buffer);
272 fprintf(stderr, "Not yet implemented...\n");
275 } /* if args to set */
280 /********************** PRIVATE IOCTLS MANIPS ***********************/
282 * Convenient access to some private ioctls of some devices
285 /*------------------------------------------------------------------*/
287 * Set roaming mode on and off
288 * Found in wavelan_cs driver
291 set_roaming(int skfd, /* Socket */
292 char * args[], /* Command line args */
293 int count, /* Args count */
294 char * ifname) /* Dev name */
298 int i = 0; /* Start with first arg */
302 char RoamState; /* buffer to hold new roam state */
303 char ChangeRoamState=0; /* whether or not we are going to
304 change roam states */
306 /* Read the private ioctls */
307 number = iw_get_priv_info(skfd, ifname, priv);
312 /* Could skip this message ? */
313 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
324 if(!strcasecmp(args[i], "on"))
326 printf("%-8.8s enable roaming\n", ifname);
329 fprintf(stderr, "This device doesn't support roaming\n");
336 if(!strcasecmp(args[i], "off"))
339 printf("%-8.8s disable roaming\n", ifname);
342 fprintf(stderr, "This device doesn't support roaming\n");
357 while((++k < number) && strcmp(priv[k].name, "setroam"));
360 fprintf(stderr, "This device doesn't support roaming\n");
363 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
367 memcpy(wrq.u.name, &buffer, IFNAMSIZ);
369 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
371 fprintf(stderr, "Roaming support is broken.\n");
379 /*------------------------------------------------------------------*/
381 * Get and set the port type
382 * Found in wavelan2_cs and wvlan_cs drivers
385 port_type(int skfd, /* Socket */
386 char * args[], /* Command line args */
387 int count, /* Args count */
388 char * ifname) /* Dev name */
391 int i = 0; /* Start with first arg */
396 char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
398 /* Read the private ioctls */
399 number = iw_get_priv_info(skfd, ifname, priv);
404 /* Could skip this message ? */
405 fprintf(stderr, "%-8.8s no private ioctls.\n\n", ifname);
412 /* So, we just want to see the current value... */
414 while((++k < number) && strcmp(priv[k].name, "gport_type") &&
415 strcmp(priv[k].name, "get_port"));
418 fprintf(stderr, "This device doesn't support getting port type\n");
421 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
424 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
426 fprintf(stderr, "Port type support is broken.\n");
432 printf("%-8.8s Current port mode is %s <port type is %d>.\n\n",
433 ifname, modes[(int) ptype], ptype);
447 while((k < 4) && strncasecmp(args[i], modes[k], 2))
452 /* ...or as an integer */
453 if(sscanf(args[i], "%d", (int *) &ptype) != 1)
460 while((++k < number) && strcmp(priv[k].name, "sport_type") &&
461 strcmp(priv[k].name, "set_port"));
464 fprintf(stderr, "This device doesn't support setting port type\n");
467 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
469 *(wrq.u.name) = ptype;
471 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
473 fprintf(stderr, "Invalid port type (or setting not allowed)\n");
480 /******************************* MAIN ********************************/
482 /*------------------------------------------------------------------*/
490 int skfd = -1; /* generic raw socket desc. */
493 /* Create a channel to the NET kernel. */
494 if((skfd = iw_sockets_open()) < 0)
500 /* No argument : show the list of all device + info */
503 print_priv_devices(skfd);
508 /* Special cases take one... */
510 if((!strncmp(argv[1], "-h", 9)) ||
511 (!strcmp(argv[1], "--help")))
518 /* The device name must be the first argument */
519 /* Name only : show for that device only */
522 print_priv_info(skfd, argv[1]);
527 /* Special cases take two... */
529 if(!strncmp(argv[2], "roam", 4))
531 goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);
537 if(!strncmp(argv[2], "port", 4))
539 goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);
544 /* Otherwise, it's a private ioctl */
545 goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);
547 /* Close the socket. */