2 * Hack my way... Jean II
5 #include <sys/socket.h>
7 #include <linux/netdevice.h>
9 #include <linux/if_arp.h>
10 #include <linux/if_ether.h>
11 #include <linux/ipx.h>
12 #include <linux/wireless.h>
21 /* Some usefull constants */
26 typedef struct iw_statistics iwstats;
27 typedef struct iw_range iwrange;
29 /* Structure for storing all wireless information for each device */
32 char dev[IFNAMSIZ]; /* Interface name (device) */
33 char name[12]; /* Wireless name */
36 u_long nwid; /* Network ID */
38 u_long freq; /* Frequency/channel */
47 int skfd = -1; /* generic raw socket desc. */
48 int ipx_sock = -1; /* IPX socket */
49 int ax25_sock = -1; /* AX.25 socket */
50 int inet_sock = -1; /* INET socket */
51 int ddp_sock = -1; /* Appletalk DDP socket */
57 fprintf(stderr, "Usage: iwconfig interface\n");
58 fprintf(stderr, " [nwid NN]\n");
59 fprintf(stderr, " [freq N.NN (add k, M or G) ]\n");
60 fprintf(stderr, " [channel N]\n");
66 print_info(struct wireless_info * info)
68 /* Display device name */
69 printf("%-8.8s ", info->dev);
71 /* Display wireless name */
72 printf("%s ", info->name);
74 /* Display Network ID */
77 printf("NWID:%lX ", info->nwid);
81 /* Display frequency / channel */
84 printf("Channel:%g ", (double) info->freq);
87 printf("Frequency:%gGHz ", info->freq / GIGA);
90 printf("Frequency:%gMHz ", info->freq / MEGA);
92 printf("Frequency:%gkHz ", info->freq / KILO);
99 printf(" Link quality:%d/%d Signal level:%d/%d Noise level:%d/%d\n",
100 info->stats.qual.qual, info->range.max_qual.qual,
101 info->stats.qual.level, info->range.max_qual.level,
102 info->stats.qual.noise, info->range.max_qual.noise);
104 printf(" Link quality:%d Signal level:%d Noise level:%d\n",
105 info->stats.qual.qual,
106 info->stats.qual.level,
107 info->stats.qual.noise);
109 printf(" Rx invalid nwid:%d invalid crypt:%d invalid misc:%d\n",
110 info->stats.discard.nwid,
111 info->stats.discard.crypt,
112 info->stats.discard.misc);
118 static int if_getstats(char *ifname, iwstats * stats)
120 FILE *f=fopen("/proc/net/wireless","r");
125 while(fgets(buf,255,f))
128 while(*bp&&isspace(*bp))
130 if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':')
134 bp = strtok(bp, " .");
135 sscanf(bp, "%X", &stats->status);
136 bp = strtok(NULL, " .");
137 sscanf(bp, "%d", &stats->qual.qual);
138 bp = strtok(NULL, " .");
139 sscanf(bp, "%d", &stats->qual.level);
140 bp = strtok(NULL, " .");
141 sscanf(bp, "%d", &stats->qual.noise);
142 bp = strtok(NULL, " .");
143 sscanf(bp, "%d", &stats->discard.nwid);
144 bp = strtok(NULL, " .");
145 sscanf(bp, "%d", &stats->discard.crypt);
146 bp = strtok(NULL, " .");
147 sscanf(bp, "%d", &stats->discard.misc);
156 /* Get wireless informations & config from the device driver */
158 get_info(char * ifname,
159 struct wireless_info * info)
163 memset((char *) info, 0, sizeof(struct wireless_info));
165 /* Get device name */
166 strcpy(info->dev, ifname);
168 /* Get wireless name */
169 strcpy(wrq.ifr_name, ifname);
170 if(ioctl(skfd, SIOCGIWNAME, &wrq) < 0)
171 /* If no wireless name : no wireless extensions */
174 strcpy(info->name, wrq.u.name);
177 strcpy(wrq.ifr_name, ifname);
178 if(ioctl(skfd, SIOCGIWNWID, &wrq) >= 0)
181 info->nwid_on = wrq.u.nwid.on;
182 info->nwid = wrq.u.nwid.nwid;
185 /* Get frequency / channel */
186 strcpy(wrq.ifr_name, ifname);
187 if(ioctl(skfd, SIOCGIWFREQ, &wrq) >= 0)
190 info->freq = wrq.u.freq;
194 if(if_getstats(ifname, &(info->stats)) == 0)
200 strcpy(wrq.ifr_name, ifname);
201 wrq.u.data.pointer = (caddr_t) &(info->range);
202 wrq.u.data.length = 0;
203 wrq.u.data.flags = 0;
204 if(ioctl(skfd, SIOCGIWRANGE, &wrq) >= 0)
214 set_info(char * args[], /* Command line args */
215 int count, /* Args count */
216 char * ifname) /* Dev name */
222 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
224 /* The other args on the line specify options to be set... */
225 for(i = 0; i < count; i++)
228 if(!strcmp(args[i], "nwid"))
232 if(!strcasecmp(args[i], "off"))
235 if(sscanf(args[i], "%lX", &(wrq.u.nwid.nwid)) != 1)
240 if(ioctl(skfd, SIOCSIWNWID, &wrq) < 0)
242 fprintf(stderr, "SIOCSIWNWID: %s\n", strerror(errno));
248 /* Set frequency / channel */
249 if((!strncmp(args[i], "freq", 4)) ||
250 (!strcmp(args[i], "channel")))
254 struct iw_range range;
257 wrq.u.data.pointer = (caddr_t) ⦥
258 wrq.u.data.length = 0;
259 wrq.u.data.flags = 0;
260 if(ioctl(skfd, SIOCGIWRANGE, &wrq) < 0)
262 fprintf(stderr, "SIOCGIWRANGE: %s\n", strerror(errno));
266 printf("%d channels ; available frequencies :",
268 for(k = 0; k < range.num_frequency; k++)
269 if(range.freq[k] > GIGA)
270 printf(" %gGHz ", range.freq[k] / GIGA);
272 if(range.freq[k] > MEGA)
273 printf(" %gMHz ", range.freq[k] / MEGA);
275 printf(" %gkHz ", range.freq[k] / KILO);
277 return; /* no more arg */
280 if(sscanf(args[i], "%g", &(wrq.u.freq)) != 1)
282 if(index(args[i], 'G')) wrq.u.freq *= GIGA;
283 if(index(args[i], 'M')) wrq.u.freq *= MEGA;
284 if(index(args[i], 'k')) wrq.u.freq *= KILO;
286 if(ioctl(skfd, SIOCSIWFREQ, &wrq) < 0)
288 fprintf(stderr, "SIOCSIWFREQ: %s\n", strerror(errno));
294 /* Here we have an unrecognised arg... */
295 fprintf(stderr, "Invalid argument : %s\n", args[i]);
298 } /* for(index ... */
303 print_devices(char *ifname)
306 struct wireless_info info;
311 if(ifname == (char *)NULL)
313 ifc.ifc_len = sizeof(buff);
315 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
317 fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
322 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
324 if(get_info(ifr->ifr_name, &info) < 0)
326 /* Could skip this message ? */
327 fprintf(stderr, "%-8.8s no wireless extensions.\n\n",
337 if(get_info(ifname, &info) < 0)
339 fprintf(stderr, "%s: no wireless extensions.\n",
349 static int sockets_open()
351 inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
352 ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
353 ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
354 ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
356 * Now pick any (exisiting) useful socket family for generic queries
365 * If this is -1 we have no known network layers and its time to jump.
377 /* Create a channel to the NET kernel. */
378 if((skfd = sockets_open()) < 0)
384 /* No argument : show the list of all device + info */
387 print_devices((char *)NULL);
392 /* The device name must be the first argument */
395 print_devices(argv[1]);
400 /* The other args on the line specify options to be set... */
401 goterr = set_info(argv + 2, argc - 2, argv[1]);
403 /* Close the socket. */