root/trunk/iwcontrol.c

Revision 162, 19.0 kB (checked in by dragorn, 6 months ago)

Allow channels in MHz

Line 
1/*
2    This file is part of lorcon
3
4    lorcon is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    lorcon is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with lorcon; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18    Copyright (c) 2005 dragorn and Joshua Wright
19*/
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#ifdef HAVE_LINUX_WIRELESS
26
27#include <math.h>
28
29#include "iwcontrol.h"
30#include "tx80211.h"
31
32#ifndef rintf
33#define rintf(x) (float) rint((double) (x))
34#endif
35
36float iwfreq2float(struct iwreq *inreq)
37{
38        return ((float)inreq->u.freq.m) * pow(10, inreq->u.freq.e);
39}
40
41void iwfloat2freq(double in_val, struct iw_freq *out_freq)
42{
43        out_freq->e = (short)(floor(log10(in_val)));
44        if (out_freq->e > 8) {
45                out_freq->m =
46                    ((long)(floor(in_val / pow(10, out_freq->e - 6)))) * 100;
47                out_freq->e -= 8;
48        } else {
49                out_freq->m = (uint32_t) in_val;
50                out_freq->e = 0;
51        }
52}
53
54int floatchan2int(float in_chan)
55{
56        int mod_chan = (int)rintf(in_chan / 1000000);
57        int x = 0;
58        /* 80211b frequencies to channels */
59        int IEEE80211Freq[] = {
60                2412, 2417, 2422, 2427, 2432,
61                2437, 2442, 2447, 2452, 2457,
62                2462, 2467, 2472, 2484,
63                5180, 5200, 5210, 5220, 5240,
64                5250, 5260, 5280, 5290, 5300,
65                5320, 5745, 5760, 5765, 5785,
66                5800, 5805, 5825,
67                -1
68        };
69
70        int IEEE80211Ch[] = {
71                1, 2, 3, 4, 5,
72                6, 7, 8, 9, 10,
73                11, 12, 13, 14,
74                36, 40, 42, 44, 48,
75                50, 52, 56, 58, 60,
76                64, 149, 152, 153, 157,
77                160, 161, 165
78        };
79
80        while (IEEE80211Freq[x] != -1) {
81                if (IEEE80211Freq[x] == mod_chan) {
82                        return IEEE80211Ch[x];
83                }
84                x++;
85        }
86
87        return 0;
88}
89
90int iwconfig_set_ssid(const char *in_dev, char *errstr, char *in_essid)
91{
92        struct iwreq wrq;
93        int skfd;
94        char essid[IW_ESSID_MAX_SIZE + 1];
95
96        if (in_essid == NULL) {
97                essid[0] = '\0';
98        } else {
99                /* Trim transparently */
100                snprintf(essid, IW_ESSID_MAX_SIZE + 1, "%s", in_essid);
101        }
102
103        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
104                snprintf(errstr, TX80211_STATUS_MAX,
105                         "Failed to create ioctl socket to set SSID on %s: %s",
106                         in_dev, strerror(errno));
107                return -1;
108        }
109
110        /* Zero the ssid */
111        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
112        wrq.u.essid.pointer = (caddr_t) essid;
113        wrq.u.essid.length = strlen(essid) + 1;
114        wrq.u.essid.flags = 1;
115
116        if (ioctl(skfd, SIOCSIWESSID, &wrq) < 0) {
117                snprintf(errstr, TX80211_STATUS_MAX,
118                         "Failed to set SSID on %s: %s", in_dev,
119                         strerror(errno));
120                close(skfd);
121                return -1;
122        }
123
124        close(skfd);
125        return 0;
126}
127
128int iwconfig_get_ssid(const char *in_dev, char *errstr, char *in_essid)
129{
130        struct iwreq wrq;
131        int skfd;
132        char essid[IW_ESSID_MAX_SIZE + 1];
133
134        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
135                snprintf(errstr, TX80211_STATUS_MAX,
136                         "Failed to create socket to fetch SSID on %s: %s",
137                         in_dev, strerror(errno));
138                return -1;
139        }
140
141        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
142        wrq.u.essid.pointer = (caddr_t) essid;
143        wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
144        wrq.u.essid.flags = 0;
145
146        if (ioctl(skfd, SIOCGIWESSID, &wrq) < 0) {
147                snprintf(errstr, TX80211_STATUS_MAX,
148                         "Failed to fetch SSID from %s: %s", in_dev,
149                         strerror(errno));
150                close(skfd);
151                return -1;
152        }
153
154        snprintf(in_essid, min(IW_ESSID_MAX_SIZE, wrq.u.essid.length) + 1, "%s",
155                 (char *)wrq.u.essid.pointer);
156
157        close(skfd);
158        return 0;
159}
160
161int iwconfig_get_name(const char *in_dev, char *errstr, char *in_name)
162{
163        struct iwreq wrq;
164        int skfd;
165
166        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
167                snprintf(errstr, TX80211_STATUS_MAX,
168                         "Failed to create socket to get name on %s: %s",
169                         in_dev, strerror(errno));
170                return -1;
171        }
172
173        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
174
175        if (ioctl(skfd, SIOCGIWNAME, &wrq) < 0) {
176                snprintf(errstr, TX80211_STATUS_MAX,
177                         "Failed to get name on %s :%s", in_dev,
178                         strerror(errno));
179                close(skfd);
180                return -1;
181        }
182
183        snprintf(in_name, IFNAMSIZ, "%s", wrq.u.name);
184
185        close(skfd);
186        return 0;
187}
188
189/*
190 * Set a private ioctl that takes 1 or 2 integer parameters
191 * A return of -2 means no privctl found that matches, so that the caller
192 * can return a more detailed failure message
193 * Code largely taken from wireless_tools
194 */
195int iwconfig_set_intpriv(const char *in_dev, const char *privcmd,
196                         int val1, int val2, char *errstr)
197{
198        struct iwreq wrq;
199        int skfd;
200        struct iw_priv_args priv[IW_MAX_PRIV_DEF];
201        u_char buffer[4096];
202        int subcmd = 0;
203        int offset = 0;
204
205        memset(priv, 0, sizeof(priv));
206
207        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
208                snprintf(errstr, TX80211_STATUS_MAX,
209                         "Failed to create socket to set private ioctl "
210                         "on %s: %s", in_dev, strerror(errno));
211                return -1;
212        }
213
214        memset(&wrq, 0, sizeof(struct iwreq));
215        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
216
217        wrq.u.data.pointer = (caddr_t) priv;
218        wrq.u.data.length = IW_MAX_PRIV_DEF;
219        wrq.u.data.flags = 0;
220
221        if (ioctl(skfd, SIOCGIWPRIV, &wrq) < 0) {
222                snprintf(errstr, TX80211_STATUS_MAX,
223                         "Failed to retrieve list of private ioctls on %s: %s",
224                         in_dev, strerror(errno));
225                close(skfd);
226                return -1;
227        }
228
229        int pn = -1;
230        while ((++pn < wrq.u.data.length) && strcmp(priv[pn].name, privcmd)) ;
231
232        if (pn == wrq.u.data.length) {
233                snprintf(errstr, TX80211_STATUS_MAX,
234                         "Unable to find private ioctl '%s' on %s", 
235                         privcmd, in_dev);
236                close(skfd);
237                return -2;
238        }
239
240        /* Find subcmds, as if this isn't ugly enough already */
241        if (priv[pn].cmd < SIOCDEVPRIVATE) {
242                int j = -1;
243
244                while ((++j < wrq.u.data.length)
245                       && ((priv[j].name[0] != '\0')
246                           || (priv[j].set_args != priv[pn].set_args)
247                           || (priv[j].get_args != priv[pn].get_args))) ;
248
249                if (j == wrq.u.data.length) {
250                        snprintf(errstr, TX80211_STATUS_MAX,
251                                 "Unable to find subioctl '%s' on %s", 
252                                 privcmd, in_dev);
253                        close(skfd);
254                        return -2;
255                }
256
257                subcmd = priv[pn].cmd;
258                offset = sizeof(uint32_t);
259                pn = j;
260        }
261
262        /* Make sure its an iwpriv we can set */
263        if ((priv[pn].set_args & IW_PRIV_TYPE_MASK) == 0 ||
264            (priv[pn].set_args & IW_PRIV_SIZE_MASK) == 0) {
265                snprintf(errstr, TX80211_STATUS_MAX,
266                         "Unable to set values for private ioctl '%s' on %s",
267                         privcmd, in_dev);
268                close(skfd);
269                return -1;
270        }
271
272        if ((priv[pn].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) {
273                snprintf(errstr, TX80211_STATUS_MAX,
274                         "'%s' on %s does not accept integer parameters.",
275                         privcmd, in_dev);
276                close(skfd);
277                return -1;
278        }
279
280        /* Find out how many arguments it takes and die if we can't handle it */
281        int nargs = (priv[pn].set_args & IW_PRIV_SIZE_MASK);
282        if (nargs > 2) {
283                snprintf(errstr, TX80211_STATUS_MAX,
284                         "Private ioctl '%s' on %s expects more than "
285                         "2 arguments.", privcmd, in_dev);
286                close(skfd);
287                return -1;
288        }
289
290        /* Build the set request */
291        memset(&wrq, 0, sizeof(struct iwreq));
292        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
293
294        /* Assign the arguments */
295        wrq.u.data.length = nargs;
296        ((__s32 *) buffer)[0] = (__s32) val1;
297        if (nargs > 1) {
298                ((__s32 *) buffer)[1] = (__s32) val2;
299        }
300
301        /* This is terrible!
302         * This is also simplified from what iwpriv.c does, because we don't
303         * need to worry about get-no-set ioctls
304         */
305        if ((priv[pn].set_args & IW_PRIV_SIZE_FIXED) &&
306            ((sizeof(uint32_t) * nargs) + offset <= IFNAMSIZ)) {
307                if (offset)
308                        wrq.u.mode = subcmd;
309                memcpy(wrq.u.name + offset, buffer, IFNAMSIZ - offset);
310        } else {
311                wrq.u.data.pointer = (caddr_t) buffer;
312                wrq.u.data.flags = 0;
313        }
314
315        /* Actually do it. */
316        if (ioctl(skfd, priv[pn].cmd, &wrq) < 0) {
317                snprintf(errstr, TX80211_STATUS_MAX,
318                         "Failed to set private ioctl '%s' on %s: %s", privcmd,
319                         in_dev, strerror(errno));
320                close(skfd);
321                return -1;
322        }
323
324        close(skfd);
325        return 0;
326}
327
328int iwconfig_get_intpriv(const char *in_dev, const char *privcmd,
329                         int *val, char *errstr)
330{
331        struct iwreq wrq;
332        int skfd;
333        struct iw_priv_args priv[IW_MAX_PRIV_DEF];
334        u_char buffer[4096];
335        int subcmd = 0;
336        int offset = 0;
337
338        memset(priv, 0, sizeof(priv));
339
340        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
341                snprintf(errstr, TX80211_STATUS_MAX,
342                         "Failed to create socket to fetch private ioctl "
343                         "on %s: %s", in_dev, strerror(errno));
344                return -1;
345        }
346
347        memset(&wrq, 0, sizeof(struct iwreq));
348        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
349
350        wrq.u.data.pointer = (caddr_t) priv;
351        wrq.u.data.length = IW_MAX_PRIV_DEF;
352        wrq.u.data.flags = 0;
353
354        if (ioctl(skfd, SIOCGIWPRIV, &wrq) < 0) {
355                snprintf(errstr, TX80211_STATUS_MAX,
356                         "Failed to retrieve list of private ioctls on %s: %s",
357                         in_dev, strerror(errno));
358                close(skfd);
359                return -1;
360        }
361
362        int pn = -1;
363        while ((++pn < wrq.u.data.length) && strcmp(priv[pn].name, privcmd)) ;
364
365        if (pn == wrq.u.data.length) {
366                snprintf(errstr, TX80211_STATUS_MAX,
367                         "Unable to find private ioctl '%s' on %s", privcmd,
368                         in_dev);
369                close(skfd);
370                return -2;
371        }
372
373        /* Find subcmds, as if this isn't ugly enough already */
374        if (priv[pn].cmd < SIOCDEVPRIVATE) {
375                int j = -1;
376
377                while ((++j < wrq.u.data.length)
378                       && ((priv[j].name[0] != '\0')
379                           || (priv[j].set_args != priv[pn].set_args)
380                           || (priv[j].get_args != priv[pn].get_args))) ;
381
382                if (j == wrq.u.data.length) {
383                        snprintf(errstr, TX80211_STATUS_MAX,
384                                 "Unable to find subioctl '%s' on %s", privcmd,
385                                 in_dev);
386                        close(skfd);
387                        return -2;
388                }
389
390                subcmd = priv[pn].cmd;
391                offset = sizeof(uint32_t);
392                pn = j;
393        }
394
395        /* Make sure its an iwpriv we can set */
396        if ((priv[pn].get_args & IW_PRIV_TYPE_MASK) == 0 ||
397            (priv[pn].get_args & IW_PRIV_SIZE_MASK) == 0) {
398                snprintf(errstr, TX80211_STATUS_MAX,
399                         "Unable to get values for private ioctl '%s' on %s",
400                         privcmd, in_dev);
401                close(skfd);
402                return -1;
403        }
404
405        if ((priv[pn].get_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_INT) {
406                snprintf(errstr, TX80211_STATUS_MAX,
407                         "Private ioctl '%s' on %s does not return "
408                         "integer parameters.", privcmd, in_dev);
409                close(skfd);
410                return -1;
411        }
412
413        /* Find out how many arguments it takes and die if we can't handle it */
414        int nargs = (priv[pn].get_args & IW_PRIV_SIZE_MASK);
415        if (nargs > 1) {
416                snprintf(errstr, TX80211_STATUS_MAX,
417                         "Private ioctl '%s' on %s returns more than 1 "
418                         "parameter and we can't handle that at the moment.",
419                         privcmd, in_dev);
420                close(skfd);
421                return -1;
422        }
423
424        /* Build the get request */
425        memset(&wrq, 0, sizeof(struct iwreq));
426        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
427
428        /* Assign the arguments */
429        wrq.u.data.length = 0L;
430
431        /* This is terrible!
432         * Simplified (again) from iwpriv, since we split the command into
433         * a set and a get instead of combining the cases
434         */
435        if ((priv[pn].get_args & IW_PRIV_SIZE_FIXED) &&
436            ((sizeof(uint32_t) * nargs) + offset <= IFNAMSIZ)) {
437                /* Second case : no SET args, GET args fit within wrq */
438                if (offset)
439                        wrq.u.mode = subcmd;
440        } else {
441                wrq.u.data.pointer = (caddr_t) buffer;
442                wrq.u.data.flags = 0;
443        }
444
445        /* Actually do it. */
446        if (ioctl(skfd, priv[pn].cmd, &wrq) < 0) {
447                snprintf(errstr, TX80211_STATUS_MAX,
448                         "Failed to call get private ioctl '%s' on %s: %s",
449                         privcmd, in_dev, strerror(errno));
450                close(skfd);
451                return -1;
452        }
453
454        /* Where do we get the data from? */
455        if ((priv[pn].get_args & IW_PRIV_SIZE_FIXED) &&
456            ((sizeof(uint32_t) * nargs) + offset <= IFNAMSIZ))
457                memcpy(buffer, wrq.u.name, IFNAMSIZ);
458
459        /* Return the value of the ioctl */
460        (*val) = ((__s32 *) buffer)[0];
461
462        close(skfd);
463        return 0;
464}
465
466/*
467 * Set a character-based private ioctl
468 */
469int iwconfig_set_charpriv(const char *in_dev, const char *privcmd,
470                         char *val, char *errstr)
471{
472        struct iwreq wrq;
473        int skfd;
474        struct iw_priv_args priv[IW_MAX_PRIV_DEF];
475        int subcmd = 0;
476        int offset = 0;
477
478        memset(priv, 0, sizeof(priv));
479
480        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
481                snprintf(errstr, TX80211_STATUS_MAX,
482                         "Failed to create socket to set private ioctl "
483                         "on %s: %s", in_dev, strerror(errno));
484                return -1;
485        }
486
487        memset(&wrq, 0, sizeof(struct iwreq));
488        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
489
490        wrq.u.data.pointer = (caddr_t) priv;
491        wrq.u.data.length = IW_MAX_PRIV_DEF;
492        wrq.u.data.flags = 0;
493
494        if (ioctl(skfd, SIOCGIWPRIV, &wrq) < 0) {
495                snprintf(errstr, TX80211_STATUS_MAX,
496                         "Failed to retrieve list of private ioctls on %s: %s",
497                         in_dev, strerror(errno));
498                close(skfd);
499                return -1;
500        }
501
502        int pn = -1;
503        while ((++pn < wrq.u.data.length) && strcmp(priv[pn].name, privcmd)) ;
504
505        if (pn == wrq.u.data.length) {
506                snprintf(errstr, TX80211_STATUS_MAX,
507                         "Unable to find private ioctl '%s' on %s", 
508                         privcmd, in_dev);
509                close(skfd);
510                return -2;
511        }
512
513        /* Find subcmds, as if this isn't ugly enough already */
514        if (priv[pn].cmd < SIOCDEVPRIVATE) {
515                int j = -1;
516
517                while ((++j < wrq.u.data.length)
518                       && ((priv[j].name[0] != '\0')
519                           || (priv[j].set_args != priv[pn].set_args)
520                           || (priv[j].get_args != priv[pn].get_args))) ;
521
522                if (j == wrq.u.data.length) {
523                        snprintf(errstr, TX80211_STATUS_MAX,
524                                 "Unable to find subioctl '%s' on %s", 
525                                 privcmd, in_dev);
526                        close(skfd);
527                        return -2;
528                }
529
530                subcmd = priv[pn].cmd;
531                offset = sizeof(uint32_t);
532                pn = j;
533        }
534
535        /* Make sure its an iwpriv we can set */
536        if ((priv[pn].set_args & IW_PRIV_TYPE_MASK) == 0 ||
537            (priv[pn].set_args & IW_PRIV_SIZE_MASK) == 0) {
538                snprintf(errstr, TX80211_STATUS_MAX,
539                         "Unable to set values for private ioctl '%s' on %s",
540                         privcmd, in_dev);
541                close(skfd);
542                return -1;
543        }
544
545        if ((priv[pn].set_args & IW_PRIV_TYPE_MASK) != IW_PRIV_TYPE_CHAR) {
546                snprintf(errstr, TX80211_STATUS_MAX,
547                         "'%s' on %s does not accept char parameters.",
548                         privcmd, in_dev);
549                close(skfd);
550                return -1;
551        }
552
553        /* Find out how many arguments it takes and die if we can't handle it */
554#if 0
555        int nargs = (priv[pn].set_args & IW_PRIV_SIZE_MASK);
556        if (nargs > 1) {
557                snprintf(errstr, TX80211_STATUS_MAX,
558                         "Private ioctl '%s' on %s expects more than 1 arguments.", privcmd, in_dev);
559                close(skfd);
560                return -1;
561        }
562#endif
563
564        /* Build the set request */
565        memset(&wrq, 0, sizeof(struct iwreq));
566        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
567
568        /* Assign the arguments */
569        wrq.u.data.length = strlen(val) + 1;
570
571        /* This is terrible!
572         * This is also simplified from what iwpriv.c does, because we don't
573         * need to worry about get-no-set ioctls
574         */
575        if ((priv[pn].set_args & IW_PRIV_SIZE_FIXED) &&
576            ((sizeof(char) * strlen(val) + 1) + offset <= IFNAMSIZ)) {
577                if (offset)
578                        wrq.u.mode = subcmd;
579                memcpy(wrq.u.name + offset, val, IFNAMSIZ - offset);
580        } else {
581                wrq.u.data.pointer = (caddr_t) val;
582                wrq.u.data.flags = 0;
583        }
584
585        /* Actually do it. */
586        if (ioctl(skfd, priv[pn].cmd, &wrq) < 0) {
587                snprintf(errstr, TX80211_STATUS_MAX,
588                         "Failed to set private ioctl '%s' on %s: %s", privcmd,
589                         in_dev, strerror(errno));
590                close(skfd);
591                return -1;
592        }
593
594        close(skfd);
595        return 0;
596}
597
598int iwconfig_get_levels(const char *in_dev, char *in_err, int *level,
599                        int *noise)
600{
601        struct iwreq wrq;
602        struct iw_range range;
603        struct iw_statistics stats;
604        char buffer[sizeof(struct iw_range) * 2];
605        int skfd;
606
607        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
608                snprintf(in_err, TX80211_STATUS_MAX,
609                         "Failed to create AF_INET DGRAM socket %d:%s", errno,
610                         strerror(errno));
611                return -1;
612        }
613
614        /* Fetch the range */
615        memset(buffer, 0, sizeof(struct iw_range) * 2);
616        memset(&wrq, 0, sizeof(struct iwreq));
617        wrq.u.data.pointer = (caddr_t) buffer;
618        wrq.u.data.length = sizeof(buffer);
619        wrq.u.data.flags = 0;
620        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
621
622        if (ioctl(skfd, SIOCGIWRANGE, &wrq) < 0) {
623                snprintf(in_err, TX80211_STATUS_MAX,
624                         "Failed to fetch signal range, %s", strerror(errno));
625                close(skfd);
626                return -1;
627        }
628
629        /* Pull it out */
630        memcpy((char *)&range, buffer, sizeof(struct iw_range));
631
632        /* Fetch the stats */
633        wrq.u.data.pointer = (caddr_t) & stats;
634        wrq.u.data.length = 0;
635        wrq.u.data.flags = 1;   /* Clear updated flag */
636        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
637
638        if (ioctl(skfd, SIOCGIWSTATS, &wrq) < 0) {
639                snprintf(in_err, TX80211_STATUS_MAX,
640                         "Failed to fetch signal stats, %s", strerror(errno));
641                close(skfd);
642                return -1;
643        }
644
645        /*
646           if (stats.qual.level <= range.max_qual.level) {
647           *level = 0;
648           *noise = 0;
649           close(skfd);
650           return 0;
651           }
652         */
653
654        *level = stats.qual.level - 0x100;
655        *noise = stats.qual.noise - 0x100;
656
657        close(skfd);
658
659        return 0;
660}
661
662int iwconfig_get_channel(const char *in_dev, char *in_err)
663{
664        struct iwreq wrq;
665        int skfd;
666
667        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
668                snprintf(in_err, TX80211_STATUS_MAX,
669                         "Failed to create AF_INET DGRAM socket %d:%s", errno,
670                         strerror(errno));
671                return -1;
672        }
673
674        memset(&wrq, 0, sizeof(struct iwreq));
675        strncpy(wrq.ifr_name, in_dev, IFNAMSIZ);
676
677        if (ioctl(skfd, SIOCGIWFREQ, &wrq) < 0) {
678                snprintf(in_err, TX80211_STATUS_MAX,
679                         "channel get ioctl failed %d:%s", errno,
680                         strerror(errno));
681                close(skfd);
682                return -1;
683        }
684
685        close(skfd);
686        return (floatchan2int(iwfreq2float(&wrq)));
687}
688
689int iwconfig_set_channel(const char *in_dev, char *in_err, int in_ch)
690{
691        struct iwreq wrq;
692        int skfd;
693
694        if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
695                snprintf(in_err, TX80211_STATUS_MAX,
696                         "Failed to create AF_INET DGRAM socket %d:%s", errno,
697                         strerror(errno));
698                return -1;
699        }
700        /* Set a channel */
701        memset(&wrq, 0, sizeof(struct iwreq));
702