6 * Just print the ESSID or NWID...
8 * This file is released under the GPL license.
9 * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
12 #include "iwlib-private.h" /* Private header */
17 * Note on Pcmcia Schemes :
18 * ----------------------
19 * The purpose of this tool is to use the ESSID discovery mechanism
20 * to select the appropriate Pcmcia Scheme. The card tell us which
21 * ESSID it has found, and we can then select the appropriate Pcmcia
22 * Scheme for this ESSID (Wireless config (encrypt keys) and IP config).
23 * The way to do it is as follows :
24 * cardctl scheme "essidany"
26 * $scheme = iwgetid --scheme
27 * cardctl scheme $scheme
28 * Of course, you need to add a scheme called "essidany" with the
34 * This can also be integrated int he Pcmcia scripts.
35 * Some drivers don't activate the card up to "ifconfig up".
36 * Therefore, they wont scan ESSID up to this point, so we can't
37 * read it reliably in Pcmcia scripts.
38 * I guess the proper way to write the network script is as follows :
39 * if($scheme == "iwgetid") {
40 * iwconfig $name essid any
41 * iwconfig $name nwid any
44 * $scheme = iwgetid $name --scheme
48 * This is pseudo code, but you get an idea...
49 * The "ifconfig up" activate the card.
50 * The "delay" is necessary to let time for the card scan the
51 * frequencies and associate with the AP.
52 * The "ifconfig down" is necessary to allow the driver to optimise
53 * the wireless parameters setting (minimise number of card resets).
55 * Another cute idea is to have a list of Pcmcia Schemes to try
56 * and to keep the first one that associate (AP address != 0). This
57 * would be necessary for closed networks and cards that can't
63 /**************************** CONSTANTS ****************************/
65 #define FORMAT_DEFAULT 0 /* Nice looking display for the user */
66 #define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
67 #define FORMAT_RAW 2 /* Raw value, for shell scripts */
68 #define WTYPE_ESSID 0 /* Display ESSID or NWID */
69 #define WTYPE_AP 1 /* Display AP/Cell Address */
70 #define WTYPE_FREQ 2 /* Display frequency/channel */
71 #define WTYPE_CHANNEL 3 /* Display channel (converted from freq) */
72 #define WTYPE_MODE 4 /* Display mode */
73 #define WTYPE_PROTO 5 /* Display protocol name */
75 /************************ DISPLAY ESSID/NWID ************************/
77 /*------------------------------------------------------------------*/
79 * Display the ESSID if possible
87 char essid[IW_ESSID_MAX_SIZE + 2]; /* ESSID */
88 char pessid[4 * IW_ESSID_MAX_SIZE + 1]; /* Printable format */
92 /* Make sure ESSID is always NULL terminated */
93 memset(essid, 0, sizeof(essid));
96 wrq.u.essid.pointer = (caddr_t) essid;
97 wrq.u.essid.length = IW_ESSID_MAX_SIZE + 2;
98 wrq.u.essid.flags = 0;
99 if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) < 0)
105 /* Strip all white space and stuff */
107 for(i = 0; i < wrq.u.essid.length; i++)
108 if(isalnum(essid[i]))
109 pessid[j++] = essid[i];
111 if((j == 0) || (j > 32))
113 printf("%s\n", pessid);
116 printf("%s\n", essid);
119 iw_essid_escape(pessid, essid, wrq.u.essid.length);
120 printf("%-8.16s ESSID:\"%s\"\n", ifname, pessid);
127 /*------------------------------------------------------------------*/
129 * Display the NWID if possible
139 if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) < 0)
145 /* Prefix with nwid to avoid name space collisions */
146 printf("nwid%X\n", wrq.u.nwid.value);
149 printf("%X\n", wrq.u.nwid.value);
152 printf("%-8.16s NWID:%X\n", ifname, wrq.u.nwid.value);
159 /**************************** AP ADDRESS ****************************/
161 /*------------------------------------------------------------------*/
163 * Display the AP Address if possible
174 if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) < 0)
178 iw_ether_ntop((const struct ether_addr *) wrq.u.ap_addr.sa_data, buffer);
182 /* I think ':' are not problematic, because Pcmcia scripts
183 * seem to handle them properly... */
185 printf("%s\n", buffer);
188 printf("%-8.16s Access Point/Cell: %s\n", ifname, buffer);
195 /****************************** OTHER ******************************/
197 /*------------------------------------------------------------------*/
199 * Display the frequency (or channel) if possible
210 /* Get frequency / channel */
211 if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
215 freq = iw_freq2float(&(wrq.u.freq));
219 /* Prefix with freq to avoid name space collisions */
220 printf("freq%g\n", freq);
223 printf("%g\n", freq);
226 iw_print_freq(buffer, sizeof(buffer), freq, -1, wrq.u.freq.flags);
227 printf("%-8.16s %s\n", ifname, buffer);
234 /*------------------------------------------------------------------*/
236 * Display the channel (converted from frequency) if possible
239 print_channel(int skfd,
244 struct iw_range range;
248 /* Get frequency / channel */
249 if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
252 /* Convert to channel */
253 if(iw_get_range_info(skfd, ifname, &range) < 0)
255 freq = iw_freq2float(&(wrq.u.freq));
257 channel = (int) freq;
260 channel = iw_freq_to_channel(freq, &range);
269 /* Prefix with freq to avoid name space collisions */
270 printf("channel%d\n", channel);
273 printf("%d\n", channel);
276 printf("%-8.16s Channel:%d\n", ifname, channel);
283 /*------------------------------------------------------------------*/
285 * Display the mode if possible
294 /* Get frequency / channel */
295 if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) < 0)
297 if(wrq.u.mode >= IW_NUM_OPER_MODE)
304 /* Strip all white space and stuff */
305 if(wrq.u.mode == IW_MODE_ADHOC)
308 printf("%s\n", iw_operation_mode[wrq.u.mode]);
311 printf("%d\n", wrq.u.mode);
314 printf("%-8.16s Mode:%s\n", ifname, iw_operation_mode[wrq.u.mode]);
321 /*------------------------------------------------------------------*/
323 * Display the ESSID if possible
326 print_protocol(int skfd,
331 char proto[IFNAMSIZ + 1]; /* Protocol */
332 char pproto[IFNAMSIZ + 1]; /* Pcmcia format */
336 /* Get Protocol name */
337 if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
339 strncpy(proto, wrq.u.name, IFNAMSIZ);
340 proto[IFNAMSIZ] = '\0';
345 /* Strip all white space and stuff */
347 for(i = 0; i < strlen(proto); i++)
348 if(isalnum(proto[i]))
349 pproto[j++] = proto[i];
351 if((j == 0) || (j > 32))
353 printf("%s\n", pproto);
356 printf("%s\n", proto);
359 printf("%-8.16s Protocol Name:\"%s\"\n", ifname, proto);
366 /******************************* MAIN ********************************/
368 /*------------------------------------------------------------------*/
370 * Check options and call the proper handler
373 print_one_device(int skfd,
384 /* Try to print an AP */
385 ret = print_ap(skfd, ifname, format);
389 /* Try to print channel */
390 ret = print_channel(skfd, ifname, format);
394 /* Try to print frequency */
395 ret = print_freq(skfd, ifname, format);
399 /* Try to print the mode */
400 ret = print_mode(skfd, ifname, format);
404 /* Try to print the protocol */
405 ret = print_protocol(skfd, ifname, format);
409 /* Try to print an ESSID */
410 ret = print_essid(skfd, ifname, format);
413 /* Try to print a nwid */
414 ret = print_nwid(skfd, ifname, format);
421 /*------------------------------------------------------------------*/
423 * Try the various devices until one return something we can use
425 * Note : we can't use iw_enum_devices() because we want a different
427 * 1) Stop at the first valid wireless device
428 * 2) Only go through active devices
431 scan_devices(int skfd,
440 /* Get list of active devices */
441 ifc.ifc_len = sizeof(buff);
443 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
445 perror("SIOCGIFCONF");
450 /* Print the first match */
451 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
453 if(print_one_device(skfd, format, wtype, ifr->ifr_name) >= 0)
459 /*------------------------------------------------------------------*/
466 fputs("Usage iwgetid [OPTIONS] [ifname]\n"
468 " -a,--ap Print the access point address\n"
469 " -c,--channel Print the current channel\n"
470 " -f,--freq Print the current frequency\n"
471 " -m,--mode Print the current mode\n"
472 " -p,--protocol Print the protocol name\n"
473 " -r,--raw Format the output as raw value for shell scripts\n"
474 " -s,--scheme Format the output as a PCMCIA scheme identifier\n"
475 " -h,--help Print this message\n",
476 status ? stderr : stdout);
480 static const struct option long_opts[] = {
481 { "ap", no_argument, NULL, 'a' },
482 { "channel", no_argument, NULL, 'c' },
483 { "freq", no_argument, NULL, 'f' },
484 { "mode", no_argument, NULL, 'm' },
485 { "protocol", no_argument, NULL, 'p' },
486 { "help", no_argument, NULL, 'h' },
487 { "raw", no_argument, NULL, 'r' },
488 { "scheme", no_argument, NULL, 's' },
492 /*------------------------------------------------------------------*/
500 int skfd; /* generic raw socket desc. */
501 int format = FORMAT_DEFAULT;
502 int wtype = WTYPE_ESSID;
506 /* Check command line arguments */
507 while((opt = getopt_long(argc, argv, "acfhmprs", long_opts, NULL)) > 0)
512 /* User wants AP/Cell Address */
517 /* User wants channel only */
518 wtype = WTYPE_CHANNEL;
522 /* User wants frequency/channel */
527 /* User wants the mode */
532 /* User wants the protocol */
541 /* User wants a Raw format */
546 /* User wants a Scheme format */
547 format = FORMAT_SCHEME;
555 if(optind + 1 < argc) {
556 fputs("Too many arguments.\n", stderr);
560 /* Create a channel to the NET kernel. */
561 if((skfd = iw_sockets_open()) < 0)
567 /* Check if first argument is a device name */
570 /* Yes : query only this device */
571 ret = print_one_device(skfd, format, wtype, argv[optind]);
575 /* No : query all devices and print first found */
576 ret = scan_devices(skfd, format, wtype);
580 iw_sockets_close(skfd);