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 "iwcommon.c" and "-lm".
10 * This file is released under the GPL license.
13 #include "iwlib.h" /* Header */
15 /************************* MISC SUBROUTINES **************************/
17 /*------------------------------------------------------------------*/
24 fprintf(stderr, "Usage: iwpriv interface [private-command [private-arguments]]\n");
25 fprintf(stderr, " interface [roam {on|off}]\n");
26 fprintf(stderr, " interface [port {ad-hoc|managed|N}]\n");
29 /************************ GENERIC FUNCTIONS *************************/
31 /*------------------------------------------------------------------*/
33 * Print on the screen in a neat fashion all the info we have collected
37 print_priv_info(int skfd,
43 char * argtype[] = { " ", "byte", "char", "", "int ", "float" };
45 /* Read the private ioctls */
46 n = iw_get_priv_info(skfd, ifname, priv);
51 /* Could skip this message ? */
52 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
57 printf("%-8.8s Available private ioctl :\n", ifname);
59 for(k = 0; k < n; k++)
60 printf(" %s (%X) : set %3d %s & get %3d %s\n",
61 priv[k].name, priv[k].cmd,
62 priv[k].set_args & IW_PRIV_SIZE_MASK,
63 argtype[(priv[k].set_args & IW_PRIV_TYPE_MASK) >> 12],
64 priv[k].get_args & IW_PRIV_SIZE_MASK,
65 argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);
70 /*------------------------------------------------------------------*/
72 * Get info on all devices and print it on the screen
75 print_priv_devices(int skfd)
82 /* Get list of active devices */
83 ifc.ifc_len = sizeof(buff);
85 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
87 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
93 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
94 print_priv_info(skfd, ifr->ifr_name);
97 /************************* SETTING ROUTINES **************************/
99 /*------------------------------------------------------------------*/
101 * Execute a private command on the interface
104 set_private(int skfd, /* Socket */
105 char * args[], /* Command line args */
106 int count, /* Args count */
107 char * ifname) /* Dev name */
111 int i = 0; /* Start with first arg */
116 /* Read the private ioctls */
117 number = iw_get_priv_info(skfd, ifname, priv);
122 /* Could skip this message ? */
123 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
128 /* Search the correct ioctl */
130 while((++k < number) && strcmp(priv[k].name, args[i]));
132 /* If not found... */
135 fprintf(stderr, "Invalid command : %s\n", args[i]);
142 /* If we have to set some data */
143 if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
144 (priv[k].set_args & IW_PRIV_SIZE_MASK))
146 switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
148 case IW_PRIV_TYPE_BYTE:
149 /* Number of args to fetch */
150 wrq.u.data.length = count - 1;
151 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
152 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
155 for(; i < wrq.u.data.length + 1; i++)
156 sscanf(args[i], "%d", (int *)(buffer + i - 1));
159 case IW_PRIV_TYPE_INT:
160 /* Number of args to fetch */
161 wrq.u.data.length = count - 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 for(; i < wrq.u.data.length + 1; i++)
167 sscanf(args[i], "%d", ((u_int *) buffer) + i - 1);
170 case IW_PRIV_TYPE_CHAR:
173 /* Size of the string to fetch */
174 wrq.u.data.length = strlen(args[i]) + 1;
175 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
176 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
179 memcpy(buffer, args[i], wrq.u.data.length);
180 buffer[sizeof(buffer) - 1] = '\0';
185 wrq.u.data.length = 1;
191 fprintf(stderr, "Not yet implemented...\n");
195 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
196 (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
198 printf("The command %s need exactly %d argument...\n",
199 priv[k].name, priv[k].set_args & IW_PRIV_SIZE_MASK);
202 } /* if args to set */
205 wrq.u.data.length = 0L;
208 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
210 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
211 (iw_byte_size(priv[k].set_args) < IFNAMSIZ))
212 memcpy(wrq.u.name, buffer, IFNAMSIZ);
215 wrq.u.data.pointer = (caddr_t) buffer;
216 wrq.u.data.flags = 0;
219 /* Perform the private ioctl */
220 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
222 fprintf(stderr, "Interface doesn't accept private ioctl...\n");
223 fprintf(stderr, "%X: %s\n", priv[k].cmd, strerror(errno));
227 /* If we have to get some data */
228 if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
229 (priv[k].get_args & IW_PRIV_SIZE_MASK))
232 int n = 0; /* number of args */
234 printf("%-8.8s %s:", ifname, priv[k].name);
236 if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
237 (iw_byte_size(priv[k].get_args) < IFNAMSIZ))
239 memcpy(buffer, wrq.u.name, IFNAMSIZ);
240 n = priv[k].get_args & IW_PRIV_SIZE_MASK;
243 n = wrq.u.data.length;
245 switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
247 case IW_PRIV_TYPE_BYTE:
249 for(j = 0; j < n; j++)
250 printf("%d ", buffer[j]);
254 case IW_PRIV_TYPE_INT:
256 for(j = 0; j < n; j++)
257 printf("%d ", ((u_int *) buffer)[j]);
261 case IW_PRIV_TYPE_CHAR:
263 buffer[wrq.u.data.length - 1] = '\0';
264 printf("%s\n", buffer);
268 fprintf(stderr, "Not yet implemented...\n");
271 } /* if args to set */
276 /********************** PRIVATE IOCTLS MANIPS ***********************/
278 * Convenient access to some private ioctls of some devices
281 /*------------------------------------------------------------------*/
283 * Set roaming mode on and off
284 * Found in wavelan_cs driver
287 set_roaming(int skfd, /* Socket */
288 char * args[], /* Command line args */
289 int count, /* Args count */
290 char * ifname) /* Dev name */
294 int i = 0; /* Start with first arg */
298 char RoamState; /* buffer to hold new roam state */
299 char ChangeRoamState=0; /* whether or not we are going to
300 change roam states */
302 /* Read the private ioctls */
303 number = iw_get_priv_info(skfd, ifname, priv);
308 /* Could skip this message ? */
309 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
320 if(!strcasecmp(args[i], "on"))
322 printf("%-8.8s enable roaming\n", ifname);
325 fprintf(stderr, "This device doesn't support roaming\n");
332 if(!strcasecmp(args[i], "off"))
335 printf("%-8.8s disable roaming\n", ifname);
338 fprintf(stderr, "This device doesn't support roaming\n");
353 while((++k < number) && strcmp(priv[k].name, "setroam"));
356 fprintf(stderr, "This device doesn't support roaming\n");
359 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
363 memcpy(wrq.u.name, &buffer, IFNAMSIZ);
365 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
367 fprintf(stderr, "Roaming support is broken.\n");
375 /*------------------------------------------------------------------*/
377 * Get and set the port type
378 * Found in wavelan2_cs and wvlan_cs drivers
381 port_type(int skfd, /* Socket */
382 char * args[], /* Command line args */
383 int count, /* Args count */
384 char * ifname) /* Dev name */
387 int i = 0; /* Start with first arg */
392 char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
394 /* Read the private ioctls */
395 number = iw_get_priv_info(skfd, ifname, priv);
400 /* Could skip this message ? */
401 fprintf(stderr, "%-8.8s no private ioctls.\n\n", ifname);
408 /* So, we just want to see the current value... */
410 while((++k < number) && strcmp(priv[k].name, "gport_type") &&
411 strcmp(priv[k].name, "get_port"));
414 fprintf(stderr, "This device doesn't support getting port type\n");
417 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
420 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
422 fprintf(stderr, "Port type support is broken.\n");
428 printf("%-8.8s Current port mode is %s <port type is %d>.\n\n",
429 ifname, modes[(int) ptype], ptype);
443 while((k < 4) && strncasecmp(args[i], modes[k], 2))
448 /* ...or as an integer */
449 if(sscanf(args[i], "%d", (int *) &ptype) != 1)
456 while((++k < number) && strcmp(priv[k].name, "sport_type") &&
457 strcmp(priv[k].name, "set_port"));
460 fprintf(stderr, "This device doesn't support setting port type\n");
463 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
465 *(wrq.u.name) = ptype;
467 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
469 fprintf(stderr, "Invalid port type (or setting not allowed)\n");
476 /******************************* MAIN ********************************/
478 /*------------------------------------------------------------------*/
486 int skfd = -1; /* generic raw socket desc. */
489 /* Create a channel to the NET kernel. */
490 if((skfd = iw_sockets_open()) < 0)
496 /* No argument : show the list of all device + info */
499 print_priv_devices(skfd);
504 /* Special cases take one... */
506 if((!strncmp(argv[1], "-h", 9)) ||
507 (!strcmp(argv[1], "--help")))
514 /* The device name must be the first argument */
515 /* Name only : show for that device only */
518 print_priv_info(skfd, argv[1]);
523 /* Special cases take two... */
525 if(!strncmp(argv[2], "roam", 4))
527 goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);
533 if(!strncmp(argv[2], "port", 4))
535 goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);
540 /* Otherwise, it's a private ioctl */
541 goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);
543 /* Close the socket. */