OSDN Git Service

v10
[android-x86/external-wireless-tools.git] / wireless_tools / iwpriv.c
1 /*
2  * Warning : this program need wireless extensions...
3  */
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <sys/ioctl.h>
7 #include <linux/netdevice.h>
8 #include <linux/if.h>
9 #include <linux/if_arp.h>
10 #include <linux/if_ether.h>
11 #include <linux/ipx.h>
12 #include <linux/wireless.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <ctype.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20
21 int skfd = -1;                          /* generic raw socket desc.     */
22 int ipx_sock = -1;                      /* IPX socket                   */
23 int ax25_sock = -1;                     /* AX.25 socket                 */
24 int inet_sock = -1;                     /* INET socket                  */
25 int ddp_sock = -1;                      /* Appletalk DDP socket         */
26
27 static int sockets_open()
28 {
29         inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
30         ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
31         ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
32         ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
33         /*
34          *      Now pick any (exisiting) useful socket family for generic queries
35          */
36         if(inet_sock!=-1)
37                 return inet_sock;
38         if(ipx_sock!=-1)
39                 return ipx_sock;
40         if(ax25_sock!=-1)
41                 return ax25_sock;
42         /*
43          *      If this is -1 we have no known network layers and its time to jump.
44          */
45          
46         return ddp_sock;
47 }
48
49 int
50 byte_size(args)
51 {
52   int   ret = args & IW_PRIV_SIZE_MASK;
53
54   if(((args & IW_PRIV_TYPE_MASK) == IW_PRIV_TYPE_INT) ||
55      ((args & IW_PRIV_TYPE_MASK) == IW_PRIV_TYPE_FLOAT))
56     ret <<= 2;
57
58   if((args & IW_PRIV_TYPE_MASK) == IW_PRIV_TYPE_NONE)
59     return 0;
60
61   return ret;
62 }
63
64 int
65 main(int        argc,
66      char **    argv)
67 {
68   struct iwreq          wrq;
69   char *                ifname = argv[1];
70   struct iw_priv_args   priv[16];
71   int                   k;
72
73   if(argc < 2)
74     exit(0);
75
76   /* Create a channel to the NET kernel. */
77   if((skfd = sockets_open()) < 0)
78     {
79       perror("socket");
80       exit(-1);
81     }
82
83   strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
84   wrq.u.data.pointer = (caddr_t) priv;
85   wrq.u.data.length = 0;
86   wrq.u.data.flags = 0;
87   if(ioctl(skfd, SIOCGIWPRIV, &wrq) < 0)
88     {
89       fprintf(stderr, "Interface doesn't provide private interface info...\n");
90       fprintf(stderr, "SIOCGIWPRIV: %s\n", strerror(errno));
91       return(-1);
92     }
93
94   /* If no args... */
95   if(argc < 3)
96     {
97       char *    argtype[] = { "    ", "byte", "char", "", "int", "float" };
98
99       printf("Available private ioctl :\n");
100       for(k = 0; k < wrq.u.data.length; k++)
101         printf("%s (%lX) : set %3d %s & get %3d %s\n",
102                priv[k].name, priv[k].cmd,
103                priv[k].set_args & IW_PRIV_SIZE_MASK,
104                argtype[(priv[k].set_args & IW_PRIV_TYPE_MASK) >> 12],
105                priv[k].get_args & IW_PRIV_SIZE_MASK,
106                argtype[(priv[k].get_args & IW_PRIV_TYPE_MASK) >> 12]);
107     }
108   else
109     {
110       u_char    buffer[1024];
111
112       /* Seach the correct ioctl */
113       k = -1;
114       while((++k < wrq.u.data.length) && strcmp(priv[k].name, argv[2]))
115         ;
116       /* If not found... */
117       if(k == wrq.u.data.length)
118         fprintf(stderr, "Invalid argument : %s\n", argv[2]);
119
120       /* If we have to set some data */
121       if((priv[k].set_args & IW_PRIV_TYPE_MASK) &&
122          (priv[k].set_args & IW_PRIV_SIZE_MASK))
123         {
124           int   i;
125
126           /* Warning : we may have no args to set... */
127
128           switch(priv[k].set_args & IW_PRIV_TYPE_MASK)
129             {
130             case IW_PRIV_TYPE_BYTE:
131               /* Number of args to fetch */
132               wrq.u.data.length = argc - 3;
133               if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
134                 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
135
136               /* Fetch args */
137               for(i = 0; i < wrq.u.data.length; i++)
138                 sscanf(argv[i + 3], "%d", buffer + i);
139               break;
140
141             case IW_PRIV_TYPE_INT:
142               /* Number of args to fetch */
143               wrq.u.data.length = argc - 3;
144               if(wrq.u.data.length > (priv[k].set_args & IW_PRIV_SIZE_MASK))
145                 wrq.u.data.length = priv[k].set_args & IW_PRIV_SIZE_MASK;
146
147               /* Fetch args */
148               for(i = 0; i < wrq.u.data.length; i++)
149                 sscanf(argv[i + 3], "%d", ((u_int *) buffer) + i);
150               break;
151
152             default:
153               fprintf(stderr, "Not yet implemented...\n");
154               return(-1);
155             }
156
157           if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
158              (wrq.u.data.length != (priv[k].set_args & IW_PRIV_SIZE_MASK)))
159             {
160               printf("The command %s need exactly %d argument...\n",
161                      priv[k].name, priv[k].set_args & IW_PRIV_SIZE_MASK);
162               return(-1);
163             }
164         }       /* if args to set */
165       else
166         {
167           wrq.u.data.length = 0L;
168         }
169
170       strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
171
172       if((priv[k].set_args & IW_PRIV_SIZE_FIXED) &&
173          (byte_size(priv[k].set_args) < IFNAMSIZ))
174         memcpy(wrq.u.name, buffer, IFNAMSIZ);
175       else
176         {
177           wrq.u.data.pointer = (caddr_t) buffer;
178           wrq.u.data.flags = 0;
179         }
180
181       if(ioctl(skfd, priv[k].cmd, &wrq) < 0)
182         {
183           fprintf(stderr, "Interface doesn't accept private ioctl...\n");
184           fprintf(stderr, "%X: %s\n", priv[k].cmd, strerror(errno));
185           return(-1);
186         }
187
188       /* If we have to get some data */
189       if((priv[k].get_args & IW_PRIV_TYPE_MASK) &&
190          (priv[k].get_args & IW_PRIV_SIZE_MASK))
191         {
192           int   i;
193           int   n;              /* number of args */
194
195           if((priv[k].get_args & IW_PRIV_SIZE_FIXED) &&
196              (byte_size(priv[k].get_args) < IFNAMSIZ))
197             {
198               memcpy(buffer, wrq.u.name, IFNAMSIZ);
199               n = priv[k].get_args & IW_PRIV_SIZE_MASK;
200             }
201           else
202             n = wrq.u.data.length;
203
204           switch(priv[k].get_args & IW_PRIV_TYPE_MASK)
205             {
206             case IW_PRIV_TYPE_BYTE:
207               /* Display args */
208               for(i = 0; i < n; i++)
209                 printf("%d  ", buffer[i]);
210               printf("\n");
211               break;
212
213             case IW_PRIV_TYPE_INT:
214               /* Display args */
215               for(i = 0; i < n; i++)
216                 printf("%d  ", ((u_int *) buffer)[i]);
217               printf("\n");
218               break;
219
220             default:
221               fprintf(stderr, "Not yet implemented...\n");
222               return(-1);
223             }
224
225         }       /* if args to set */
226
227     }   /* if ioctl list else ioctl exec */
228
229   /* Close the socket. */
230   close(skfd);
231
232   return(1);
233 }