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 "iwcommon.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");
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 = 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 */
117 /* Read the private ioctls */
118 number = get_priv_info(skfd, ifname, priv);
123 /* Could skip this message ? */
124 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
129 /* Search the correct ioctl */
131 while((++k < number) && strcmp(priv[k].name, args[i]));
133 /* If not found... */
136 fprintf(stderr, "Invalid command : %s\n", args[i]);
143 /* If we have to set some data */
144 if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
145 (priv[k].set_args & IW_PRIV_SIZE_MASK))
147 switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
149 case IW_PRIV_TYPE_BYTE:
150 /* Number of args to fetch */
151 wrq.u.data.length = count - 1;
152 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
153 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
156 for(; i < wrq.u.data.length + 1; i++)
157 sscanf(args[i], "%d", (int *)(buffer + i - 1));
160 case IW_PRIV_TYPE_INT:
161 /* Number of args to fetch */
162 wrq.u.data.length = count - 1;
163 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
164 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
167 for(; i < wrq.u.data.length + 1; i++)
168 sscanf(args[i], "%d", ((u_int *) buffer) + i - 1);
171 case IW_PRIV_TYPE_CHAR:
174 /* Size of the string to fetch */
175 wrq.u.data.length = strlen(args[i]) + 1;
176 if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
177 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
180 memcpy(buffer, args[i], wrq.u.data.length);
181 buffer[sizeof(buffer) - 1] = '\0';
186 wrq.u.data.length = 1;
192 fprintf(stderr, "Not yet implemented...\n");
196 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
197 (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
199 printf("The command %s need exactly %d argument...\n",
200 priv[k].name, priv[k].set_args & IW_PRIV_SIZE_MASK);
203 } /* if args to set */
206 wrq.u.data.length = 0L;
209 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
211 if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
212 (byte_size(priv[k].set_args) < IFNAMSIZ))
213 memcpy(wrq.u.name, buffer, IFNAMSIZ);
216 wrq.u.data.pointer = (caddr_t) buffer;
217 wrq.u.data.flags = 0;
220 /* Perform the private ioctl */
221 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
223 fprintf(stderr, "Interface doesn't accept private ioctl...\n");
224 fprintf(stderr, "%X: %s\n", priv[k].cmd, strerror(errno));
228 /* If we have to get some data */
229 if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
230 (priv[k].get_args & IW_PRIV_SIZE_MASK))
233 int n = 0; /* number of args */
235 printf("%-8.8s %s:", ifname, priv[k].name);
237 if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
238 (byte_size(priv[k].get_args) < IFNAMSIZ))
240 memcpy(buffer, wrq.u.name, IFNAMSIZ);
241 n = priv[k].get_args & IW_PRIV_SIZE_MASK;
244 n = wrq.u.data.length;
246 switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
248 case IW_PRIV_TYPE_BYTE:
250 for(j = 0; j < n; j++)
251 printf("%d ", buffer[j]);
255 case IW_PRIV_TYPE_INT:
257 for(j = 0; j < n; j++)
258 printf("%d ", ((u_int *) buffer)[j]);
262 case IW_PRIV_TYPE_CHAR:
264 buffer[wrq.u.data.length - 1] = '\0';
265 printf("%s\n", buffer);
269 fprintf(stderr, "Not yet implemented...\n");
272 } /* if args to set */
277 /********************** PRIVATE IOCTLS MANIPS ***********************/
279 * Convenient access to some private ioctls of some devices
282 /*------------------------------------------------------------------*/
284 * Set roaming mode on and off
285 * Found in wavelan_cs driver
288 set_roaming(int skfd, /* Socket */
289 char * args[], /* Command line args */
290 int count, /* Args count */
291 char * ifname) /* Dev name */
295 int i = 0; /* Start with first arg */
299 char RoamState; /* buffer to hold new roam state */
300 char ChangeRoamState=0; /* whether or not we are going to
301 change roam states */
303 /* Read the private ioctls */
304 number = get_priv_info(skfd, ifname, priv);
309 /* Could skip this message ? */
310 fprintf(stderr, "%-8.8s no private ioctls.\n\n",
318 if(!strcasecmp(args[i], "on"))
320 printf("%-8.8s enable roaming\n", ifname);
323 fprintf(stderr, "This device doesn't support roaming\n");
330 if(!strcasecmp(args[i], "off"))
333 printf("%-8.8s disable roaming\n", ifname);
336 fprintf(stderr, "This device doesn't support roaming\n");
351 while((++k < number) && strcmp(priv[k].name, "setroam"));
354 fprintf(stderr, "This device doesn't support roaming\n");
357 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
361 memcpy(wrq.u.name, &buffer, IFNAMSIZ);
363 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
365 fprintf(stderr, "Roaming support is broken.\n");
374 /*------------------------------------------------------------------*/
376 * Get and set the port type
377 * Found in wavelan2_cs and wvlan_cs drivers
380 port_type(int skfd, /* Socket */
381 char * args[], /* Command line args */
382 int count, /* Args count */
383 char * ifname) /* Dev name */
386 int i = 0; /* Start with first arg */
391 char * modes[] = { "invalid", "managed (BSS)", "reserved", "ad-hoc" };
393 /* Read the private ioctls */
394 number = get_priv_info(skfd, ifname, priv);
399 /* Could skip this message ? */
400 fprintf(stderr, "%-8.8s no private ioctls.\n\n", ifname);
407 /* So, we just want to see the current value... */
409 while((++k < number) && strcmp(priv[k].name, "gport_type") &&
410 strcmp(priv[k].name, "get_port"));
413 fprintf(stderr, "This device doesn't support getting port type\n");
416 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
419 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
421 fprintf(stderr, "Port type support is broken.\n");
427 printf("%-8.8s Current port mode is %s <port type is %d>.\n\n",
428 ifname, modes[(int) ptype], ptype);
439 while((k < 4) && strncasecmp(args[i], modes[k], 2))
444 /* ...or as an integer */
445 if(sscanf(args[i], "%d", (int *) &ptype) != 1)
449 while((++k < number) && strcmp(priv[k].name, "sport_type") &&
450 strcmp(priv[k].name, "set_port"));
453 fprintf(stderr, "This device doesn't support setting port type\n");
456 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
458 *(wrq.u.name) = ptype;
460 if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
462 fprintf(stderr, "Invalid port type (or setting not allowed)\n");
470 /******************************* MAIN ********************************/
472 /*------------------------------------------------------------------*/
480 int skfd = -1; /* generic raw socket desc. */
483 /* Create a channel to the NET kernel. */
484 if((skfd = sockets_open()) < 0)
490 /* No argument : show the list of all device + info */
493 print_priv_devices(skfd);
498 /* Special cases take one... */
500 if((!strncmp(argv[1], "-h", 9)) ||
501 (!strcmp(argv[1], "--help")))
508 /* The device name must be the first argument */
509 /* Name only : show for that device only */
512 print_priv_info(skfd, argv[1]);
517 /* Special cases take two... */
519 if(!strncmp(argv[2], "roam", 4))
521 goterr = set_roaming(skfd, argv + 3, argc - 3, argv[1]);
527 if(!strncmp(argv[2], "port", 4))
529 goterr = port_type(skfd, argv + 3, argc - 3, argv[1]);
534 /* Otherwise, it's a private ioctl */
535 goterr = set_private(skfd, argv + 2, argc - 2, argv[1]);
537 /* Close the socket. */