6 * Just print the ESSID or NWID...
8 * This file is released under the GPL license.
9 * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
12 #include "iwlib.h" /* Header */
16 #define FORMAT_DEFAULT 0 /* Nice looking display for the user */
17 #define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
18 #define WTYPE_ESSID 0 /* Display ESSID or NWID */
19 #define WTYPE_AP 1 /* Display AP/Cell Address */
22 * Note on Pcmcia Schemes :
23 * ----------------------
24 * The purpose of this tool is to use the ESSID discovery mechanism
25 * to select the appropriate Pcmcia Scheme. The card tell us which
26 * ESSID it has found, and we can then select the appropriate Pcmcia
27 * Scheme for this ESSID (Wireless config (encrypt keys) and IP config).
28 * The way to do it is as follows :
29 * cardctl scheme "essidany"
31 * $scheme = iwgetid --scheme
32 * cardctl scheme $scheme
33 * Of course, you need to add a scheme called "essidany" with the
39 * This can also be integrated int he Pcmcia scripts.
40 * Some drivers don't activate the card up to "ifconfig up".
41 * Therefore, they wont scan ESSID up to this point, so we can't
42 * read it reliably in Pcmcia scripts.
43 * I guess the proper way to write the network script is as follows :
44 * if($scheme == "iwgetid") {
45 * iwconfig $name essid any
46 * iwconfig $name nwid any
49 * $scheme = iwgetid $name --scheme
53 * This is pseudo code, but you get an idea...
54 * The "ifconfig up" activate the card.
55 * The "delay" is necessary to let time for the card scan the
56 * frequencies and associate with the AP.
57 * The "ifconfig down" is necessary to allow the driver to optimise
58 * the wireless parameters setting (minimise number of card resets).
60 * Another cute idea is to have a list of Pcmcia Schemes to try
61 * and to keep the first one that associate (AP address != 0). This
62 * would be necessary for closed networks and cards that can't
68 /*************************** SUBROUTINES ***************************/
70 * Just for the heck of it, let's try to not link with iwlib.
71 * This will keep the binary small and tiny...
74 /*------------------------------------------------------------------*/
77 * Depending on the protocol present, open the right socket. The socket
78 * will allow us to talk to the driver.
83 int ipx_sock = -1; /* IPX socket */
84 int ax25_sock = -1; /* AX.25 socket */
85 int inet_sock = -1; /* INET socket */
86 int ddp_sock = -1; /* Appletalk DDP socket */
89 * Now pick any (exisiting) useful socket family for generic queries
90 * Note : don't open all the socket, only returns when one matches,
91 * all protocols might not be valid.
92 * Workaround by Jim Kaba <jkaba@sarnoff.com>
93 * Note : in 99% of the case, we will just open the inet_sock.
94 * The remaining 1% case are not fully correct...
96 inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
99 ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
102 ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
105 ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
107 * If this is -1 we have no known network layers and its time to jump.
112 /*------------------------------------------------------------------*/
114 * Display an Ethernet address in readable format.
117 iw_ether_ntop(const struct ether_addr* eth, char* buf)
119 sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
120 eth->ether_addr_octet[0], eth->ether_addr_octet[1],
121 eth->ether_addr_octet[2], eth->ether_addr_octet[3],
122 eth->ether_addr_octet[4], eth->ether_addr_octet[5]);
125 /************************ DISPLAY ESSID/NWID ************************/
127 /*------------------------------------------------------------------*/
129 * Display the ESSID if possible
132 print_essid(int skfd,
137 char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID */
138 char pessid[IW_ESSID_MAX_SIZE + 1]; /* Pcmcia format */
143 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
144 wrq.u.essid.pointer = (caddr_t) essid;
145 wrq.u.essid.length = 0;
146 wrq.u.essid.flags = 0;
147 if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
153 /* Strip all white space and stuff */
155 for(i = 0; i < strlen(essid); i++)
156 if(isalnum(essid[i]))
157 pessid[j++] = essid[i];
159 if((j == 0) || (j > 32))
161 printf("%s\n", pessid);
164 printf("%-8.8s ESSID:\"%s\"\n", ifname, essid);
171 /*------------------------------------------------------------------*/
173 * Display the NWID if possible
183 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
184 if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
190 /* Prefix with nwid to avoid name space collisions */
191 printf("nwid%X\n", wrq.u.nwid.value);
194 printf("%-8.8s NWID:%X\n", ifname, wrq.u.nwid.value);
201 /**************************** AP ADDRESS ****************************/
203 /*------------------------------------------------------------------*/
205 * Display the AP Address if possible
216 strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
217 if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)
221 iw_ether_ntop((const struct ether_addr *) wrq.u.ap_addr.sa_data, buffer);
225 /* I think ':' are not problematic, because Pcmcia scripts
226 * seem to handle them properly... */
227 printf("%s\n", buffer);
230 printf("%-8.8s Access Point: %s\n", ifname, buffer);
237 /******************************* MAIN ********************************/
239 /*------------------------------------------------------------------*/
241 * Check options and call the proper handler
244 print_one_device(int skfd,
252 if(wtype == WTYPE_AP)
254 /* Try to print an AP */
255 ret = print_ap(skfd, ifname, format);
259 /* Try to print an ESSID */
260 ret = print_essid(skfd, ifname, format);
264 /* Try to print a nwid */
265 ret = print_nwid(skfd, ifname, format);
271 /*------------------------------------------------------------------*/
273 * Try the various devices until one return something we can use
276 scan_devices(int skfd,
285 /* Get list of active devices */
286 ifc.ifc_len = sizeof(buff);
288 if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
290 perror("SIOCGIFCONF");
295 /* Print the first match */
296 for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
298 if(print_one_device(skfd, format, wtype, ifr->ifr_name) >= 0)
304 /*------------------------------------------------------------------*/
311 fputs("Usage iwgetid [OPTIONS] [ifname]\n"
313 " -a,--ap Print the access point address\n"
314 " -h,--help Print this message\n"
315 " -s,--scheme Format the output as a PCMCIA scheme identifier\n",
316 status ? stderr : stdout);
320 static const struct option long_opts[] = {
321 { "ap", no_argument, NULL, 'a' },
322 { "help", no_argument, NULL, 'h' },
323 { "scheme", no_argument, NULL, 's' },
327 /*------------------------------------------------------------------*/
335 int skfd; /* generic raw socket desc. */
336 int format = FORMAT_DEFAULT;
337 int wtype = WTYPE_ESSID;
341 /* Check command line arguments */
342 while((opt = getopt_long(argc, argv, "ahs", long_opts, NULL)) > 0)
347 /* User wants AP/Cell Address */
356 /* User wants a Scheme format */
357 format = FORMAT_SCHEME;
365 if(optind + 1 < argc) {
366 fputs("Too many arguments.\n", stderr);
370 /* Create a channel to the NET kernel. */
371 if((skfd = iw_sockets_open()) < 0)
377 /* Check if first argument is a device name */
380 /* Yes : query only this device */
381 ret = print_one_device(skfd, format, wtype, argv[optind]);
385 /* No : query all devices and print first found */
386 ret = scan_devices(skfd, format, wtype);