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.h" /* 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 + 1]; /* ESSID */
88 char pessid[IW_ESSID_MAX_SIZE + 1]; /* Pcmcia 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 + 1;
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 < strlen(essid); 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 printf("%-8.16s ESSID:\"%s\"\n", ifname, essid);
126 /*------------------------------------------------------------------*/
128 * Display the NWID if possible
138 if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) < 0)
144 /* Prefix with nwid to avoid name space collisions */
145 printf("nwid%X\n", wrq.u.nwid.value);
148 printf("%X\n", wrq.u.nwid.value);
151 printf("%-8.16s NWID:%X\n", ifname, wrq.u.nwid.value);
158 /**************************** AP ADDRESS ****************************/
160 /*------------------------------------------------------------------*/
162 * Display the AP Address if possible
173 if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) < 0)
177 iw_ether_ntop((const struct ether_addr *) wrq.u.ap_addr.sa_data, buffer);
181 /* I think ':' are not problematic, because Pcmcia scripts
182 * seem to handle them properly... */
184 printf("%s\n", buffer);
187 printf("%-8.16s Access Point/Cell: %s\n", ifname, buffer);
194 /****************************** OTHER ******************************/
196 /*------------------------------------------------------------------*/
198 * Display the frequency (or channel) if possible
209 /* Get frequency / channel */
210 if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
214 freq = iw_freq2float(&(wrq.u.freq));
218 /* Prefix with freq to avoid name space collisions */
219 printf("freq%g\n", freq);
222 printf("%g\n", freq);
225 iw_print_freq(buffer, sizeof(buffer), freq, -1, wrq.u.freq.flags);
226 printf("%-8.16s %s\n", ifname, buffer);
233 /*------------------------------------------------------------------*/
235 * Display the channel (converted from frequency) if possible
238 print_channel(int skfd,
243 struct iw_range range;
247 /* Get frequency / channel */
248 if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
251 /* Convert to channel */
252 if(iw_get_range_info(skfd, ifname, &range) < 0)
254 freq = iw_freq2float(&(wrq.u.freq));
256 channel = (int) freq;
259 channel = iw_freq_to_channel(freq, &range);
268 /* Prefix with freq to avoid name space collisions */
269 printf("channel%d\n", channel);
272 printf("%d\n", channel);
275 printf("%-8.16s Channel:%d\n", ifname, channel);
282 /*------------------------------------------------------------------*/
284 * Display the mode if possible
293 /* Get frequency / channel */
294 if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) < 0)
296 if(wrq.u.mode >= IW_NUM_OPER_MODE)
303 /* Strip all white space and stuff */
304 if(wrq.u.mode == IW_MODE_ADHOC)
307 printf("%s\n", iw_operation_mode[wrq.u.mode]);
310 printf("%d\n", wrq.u.mode);
313 printf("%-8.16s Mode:%s\n", ifname, iw_operation_mode[wrq.u.mode]);
320 /*------------------------------------------------------------------*/
322 * Display the ESSID if possible
325 print_protocol(int skfd,
330 char proto[IFNAMSIZ + 1]; /* Protocol */
331 char pproto[IFNAMSIZ + 1]; /* Pcmcia format */
335 /* Get Protocol name */
336 if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
338 strncpy(proto, wrq.u.name, IFNAMSIZ);
339 proto[IFNAMSIZ] = '\0';
344 /* Strip all white space and stuff */
346 for(i = 0; i < strlen(proto); i++)
347 if(isalnum(proto[i]))
348 pproto[j++] = proto[i];
350 if((j == 0) || (j > 32))
352 printf("%s\n", pproto);
355 printf("%s\n", proto);
358 printf("%-8.16s Protocol Name:\"%s\"\n", ifname, proto);
365 /******************************* MAIN ********************************/
367 /*------------------------------------------------------------------*/
369 * Check options and call the proper handler
372 print_one_device(int skfd,
383 /* Try to print an AP */
384 ret = print_ap(skfd, ifname, format);
388 /* Try to print channel */
389 ret = print_channel(skfd, ifname, format);
393 /* Try to print frequency */
394 ret = print_freq(skfd, ifname, format);
398 /* Try to print the mode */
399 ret = print_mode(skfd, ifname, format);
403 /* Try to print the protocol */
404 ret = print_protocol(skfd, ifname, format);
408 /* Try to print an ESSID */
409 ret = print_essid(skfd, ifname, format);
412 /* Try to print a nwid */
413 ret = print_nwid(skfd, ifname, format);
420 /*------------------------------------------------------------------*/
422 * Try the various devices until one return something we can use
424 * Note : we can't use iw_enum_devices() because we want a different
426 * 1) Stop at the first valid wireless device
427 * 2) Only go through active devices
430 scan_devices(int skfd,
439 /* Get list of active devices */
440 ifc.ifc_len = sizeof(buff);
442 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
444 perror("SIOCGIFCONF");
449 /* Print the first match */
450 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
452 if(print_one_device(skfd, format, wtype, ifr->ifr_name) >= 0)
458 /*------------------------------------------------------------------*/
465 fputs("Usage iwgetid [OPTIONS] [ifname]\n"
467 " -a,--ap Print the access point address\n"
468 " -c,--channel Print the current channel\n"
469 " -f,--freq Print the current frequency\n"
470 " -m,--mode Print the current mode\n"
471 " -p,--protocol Print the protocol name\n"
472 " -r,--raw Format the output as raw value for shell scripts\n"
473 " -s,--scheme Format the output as a PCMCIA scheme identifier\n"
474 " -h,--help Print this message\n",
475 status ? stderr : stdout);
479 static const struct option long_opts[] = {
480 { "ap", no_argument, NULL, 'a' },
481 { "channel", no_argument, NULL, 'c' },
482 { "freq", no_argument, NULL, 'f' },
483 { "mode", no_argument, NULL, 'm' },
484 { "protocol", no_argument, NULL, 'p' },
485 { "help", no_argument, NULL, 'h' },
486 { "raw", no_argument, NULL, 'r' },
487 { "scheme", no_argument, NULL, 's' },
491 /*------------------------------------------------------------------*/
499 int skfd; /* generic raw socket desc. */
500 int format = FORMAT_DEFAULT;
501 int wtype = WTYPE_ESSID;
505 /* Check command line arguments */
506 while((opt = getopt_long(argc, argv, "acfhmprs", long_opts, NULL)) > 0)
511 /* User wants AP/Cell Address */
516 /* User wants channel only */
517 wtype = WTYPE_CHANNEL;
521 /* User wants frequency/channel */
526 /* User wants the mode */
531 /* User wants the protocol */
540 /* User wants a Raw format */
545 /* User wants a Scheme format */
546 format = FORMAT_SCHEME;
554 if(optind + 1 < argc) {
555 fputs("Too many arguments.\n", stderr);
559 /* Create a channel to the NET kernel. */
560 if((skfd = iw_sockets_open()) < 0)
566 /* Check if first argument is a device name */
569 /* Yes : query only this device */
570 ret = print_one_device(skfd, format, wtype, argv[optind]);
574 /* No : query all devices and print first found */
575 ret = scan_devices(skfd, format, wtype);
579 iw_sockets_close(skfd);