OSDN Git Service

v22
[android-x86/external-wireless-tools.git] / wireless_tools / iwgetid.c
1 /*
2  *      Wireless Tools
3  *
4  *              Jean II - HPL '01
5  *
6  * Just print the ESSID or NWID...
7  *
8  * This file is released under the GPL license.
9  */
10
11 #include "iwlib.h"              /* Header */
12
13 #define FORMAT_DEFAULT  0       /* Nice looking display for the user */
14 #define FORMAT_SCHEME   1       /* To be used as a Pcmcia Scheme */
15
16 /*
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"
25  *                      delay 100
26  *                      $scheme = iwgetid --scheme
27  *                      cardctl scheme $scheme
28  *      Of course, you need to add a scheme called "essidany" with the
29  * following setting :
30  *                      essidany,*,*,*)
31  *                              ESSID="any"
32  *                              IPADDR="10.0.0.1"
33  *
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
42  *                              ifconfig $name up
43  *                              delay 100
44  *                              $scheme = iwgetid $name --scheme
45  *                              ifconfig $name down
46  *                      }
47  *
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).
54  *
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
58  * discover essid...
59  *
60  * Jean II - 29/3/01
61  */
62
63 /************************ DISPLAY ESSID/NWID ************************/
64
65 /*------------------------------------------------------------------*/
66 /*
67  * Display the ESSID if possible
68  */
69 static int
70 print_essid(int         skfd,
71             char *      ifname,
72             int         format)
73 {
74   struct iwreq          wrq;
75   char                  essid[IW_ESSID_MAX_SIZE + 1];   /* ESSID */
76   char                  pessid[IW_ESSID_MAX_SIZE + 1];  /* Pcmcia format */
77   int           i;
78   int           j;
79
80   /* Get ESSID */
81   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
82   wrq.u.essid.pointer = (caddr_t) essid;
83   wrq.u.essid.length = 0;
84   wrq.u.essid.flags = 0;
85   if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
86     return(-1);
87
88   switch(format)
89     {
90     case FORMAT_SCHEME:
91       /* Stip all white space and stuff */
92       j = 0;
93       for(i = 0; i < strlen(essid); i++)
94         if(isalnum(essid[i]))
95           pessid[j++] = essid[i];
96       pessid[j] = '\0';
97       if((j == 0) || (j > 32))
98         return(-2);
99       printf("%s\n", pessid);
100       fflush(stdout);
101       break;
102     default:
103       printf("%-8.8s  ESSID:\"%s\"\n", ifname, essid);
104       break;
105     }
106
107   return(0);
108 }
109
110 /*------------------------------------------------------------------*/
111 /*
112  * Display the NWID if possible
113  */
114 static int
115 print_nwid(int          skfd,
116            char *       ifname,
117            int          format)
118 {
119   struct iwreq          wrq;
120
121   /* Get network ID */
122   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
123   if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
124     return(-1);
125
126   switch(format)
127     {
128     case FORMAT_SCHEME:
129       /* Prefix with nwid to avoid name space collisions */
130       printf("nwid%X\n", wrq.u.nwid.value);
131       fflush(stdout);
132       break;
133     default:
134       printf("%-8.8s  NWID:%X\n", ifname, wrq.u.nwid.value);
135       break;
136     }
137
138   return(0);
139 }
140
141 /*------------------------------------------------------------------*/
142 /*
143  * Try the various devices until one return something we can use
144  */
145 static int
146 scan_devices(int                skfd,
147              int                format)
148 {
149   char          buff[1024];
150   struct ifconf ifc;
151   struct ifreq *ifr;
152   int           i;
153   int           ret;
154
155   /* Get list of active devices */
156   ifc.ifc_len = sizeof(buff);
157   ifc.ifc_buf = buff;
158   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
159     {
160       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
161       return(-1);
162     }
163   ifr = ifc.ifc_req;
164
165   /* Print the first match */
166   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
167     {
168       /* Try to print an ESSID */
169       ret = print_essid(skfd, ifr->ifr_name, format);
170       if(ret == 0)
171         return(0);      /* Success */
172
173       /* Try to print a nwid */
174       ret = print_nwid(skfd, ifr->ifr_name, format);
175       if(ret == 0)
176         return(0);      /* Success */
177     }
178   return(-1);
179 }
180
181 /*************************** SUBROUTINES ***************************/
182
183 /*------------------------------------------------------------------*/
184 /*
185  * Display an Ethernet address in readable format.
186  */
187 char *
188 pr_ether(char *         buffer,
189          unsigned char *ptr)
190 {
191   sprintf(buffer, "%02X:%02X:%02X:%02X:%02X:%02X",
192           (ptr[0] & 0xFF), (ptr[1] & 0xFF), (ptr[2] & 0xFF),
193           (ptr[3] & 0xFF), (ptr[4] & 0xFF), (ptr[5] & 0xFF)
194   );
195   return(buffer);
196 }
197
198 /*------------------------------------------------------------------*/
199 /*
200  * Open a socket.
201  * Depending on the protocol present, open the right socket. The socket
202  * will allow us to talk to the driver.
203  */
204 int
205 sockets_open(void)
206 {
207         int ipx_sock = -1;              /* IPX socket                   */
208         int ax25_sock = -1;             /* AX.25 socket                 */
209         int inet_sock = -1;             /* INET socket                  */
210         int ddp_sock = -1;              /* Appletalk DDP socket         */
211
212         inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
213         ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
214         ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
215         ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
216         /*
217          * Now pick any (exisiting) useful socket family for generic queries
218          */
219         if(inet_sock!=-1)
220                 return inet_sock;
221         if(ipx_sock!=-1)
222                 return ipx_sock;
223         if(ax25_sock!=-1)
224                 return ax25_sock;
225         /*
226          * If this is -1 we have no known network layers and its time to jump.
227          */
228          
229         return ddp_sock;
230 }
231
232 /**************************** AP ADDRESS ****************************/
233
234 /*------------------------------------------------------------------*/
235 /*
236  * Display the NWID if possible
237  */
238 static int
239 print_ap(int            skfd,
240          char *         ifname,
241          int            format)
242 {
243   struct iwreq          wrq;
244   char                  buffer[64];
245
246   /* Get network ID */
247   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
248   if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)
249     return(-1);
250
251   /* Print */
252   printf("%-8.8s  Access Point: %s\n", ifname,
253          pr_ether(buffer, wrq.u.ap_addr.sa_data));
254
255   return(0);
256 }
257
258 /*------------------------------------------------------------------*/
259 /*
260  * Try the various devices until one return something we can use
261  */
262 static inline int
263 scan_ap(int             skfd,
264         int             format)
265 {
266   char          buff[1024];
267   struct ifconf ifc;
268   struct ifreq *ifr;
269   int           i;
270   int           ret;
271
272   /* Get list of active devices */
273   ifc.ifc_len = sizeof(buff);
274   ifc.ifc_buf = buff;
275   if(ioctl(skfd, SIOCGIFCONF, &ifc) < 0)
276     {
277       fprintf(stderr, "SIOCGIFCONF: %s\n", strerror(errno));
278       return(-1);
279     }
280   ifr = ifc.ifc_req;
281
282   /* Print the first match */
283   for(i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
284     {
285       /* Try to print an ESSID */
286       ret = print_ap(skfd, ifr->ifr_name, format);
287       if(ret == 0)
288         return(0);      /* Success */
289     }
290   return(-1);
291 }
292
293 /******************************* MAIN ********************************/
294
295 /*------------------------------------------------------------------*/
296 /*
297  * The main !
298  */
299 int
300 main(int        argc,
301      char **    argv)
302 {
303   int   skfd = -1;              /* generic raw socket desc.     */
304   int   format = FORMAT_DEFAULT;
305   int   ret = -1;
306
307   /* Create a channel to the NET kernel. */
308   if((skfd = sockets_open()) < 0)
309     {
310       perror("socket");
311       return(-1);
312     }
313
314   /* No argument */
315   if(argc == 1)
316     {
317       /* Look on all devices */
318       ret = scan_devices(skfd, format);
319       close(skfd);
320       return(ret);
321     }
322
323   /* Only ask for first AP address */
324   if((!strcmp(argv[1], "--ap")) || (!strcmp(argv[1], "-a")))
325     {
326       /* Look on all devices */
327       ret = scan_ap(skfd, format);
328       close(skfd);
329       return(ret);
330     }
331
332   /* Only the format, no interface name */
333   if((!strncmp(argv[1], "--scheme", 4)) || (!strcmp(argv[1], "-s")))
334     {
335       /* Look on all devices */
336       format = FORMAT_SCHEME;
337       ret = scan_devices(skfd, format);
338       close(skfd);
339       return(ret);
340     }
341
342   /* Help */
343   if((argc > 3) ||
344      (!strncmp(argv[1], "-h", 9)) || (!strcmp(argv[1], "--help")))
345     {
346       fprintf(stderr, "Usage: iwgetid [interface]\n");
347       fprintf(stderr, "               [interface] --scheme\n");
348       return(-1);
349     }
350
351   /* If at least a device name */
352   if(argc > 1)
353     {
354       /* Check extra format argument */
355       if(argc > 2)
356         {
357           /* Only ask for first AP address */
358           if((!strcmp(argv[2], "--ap")) || (!strcmp(argv[2], "-a")))
359             {
360               ret = print_ap(skfd, argv[1], format);
361               close(skfd);
362               return(ret);
363             }
364
365           /* Want scheme format */
366           if((!strncmp(argv[2], "--scheme", 4)) || (!strcmp(argv[2], "-s")))
367             format = FORMAT_SCHEME;
368         }
369
370       /* Try to print an ESSID */
371       ret = print_essid(skfd, argv[1], format);
372
373       if(ret == -1)
374         {
375           /* Try to print a nwid */
376           ret = print_nwid(skfd, argv[1], format);
377         }
378     }
379
380   /* Close the socket. */
381   close(skfd);
382
383   return(ret);
384 }