Subject: kern/15328: wiconfig -D doesn't work if interface isn't up
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lha@stacken.kth.se>
List: netbsd-bugs
Date: 01/22/2002 02:44:32
>Number:         15328
>Category:       kern
>Synopsis:       wiconfig -D doesn't work if interface isn't up
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 21 17:46:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Love
>Release:        NetBSD 1.5ZA
>Organization:
	Stacken Computer Club
>Environment:
System: NetBSD nutcracker.stacken.kth.se 1.5ZA NetBSD 1.5ZA (NUTCRACKER) #91: Tue Jan 22 01:33:43 CET 2002 root@nutcracker.stacken.kth.se:/usr/src/sys/arch/i386/compile/NUTCRACKER i386
Architecture: i386
Machine: i386
>Description:
	
	If the interface isn't up. this is simple to fix in wiconfig, just up
	the interface if its down and down it when scanning is done.

	Also wiconfig failes to fflush stdout, and scanning... appears
after
	scanning is done.

>How-To-Repeat:

: root@nutcracker ; wiconfig wi0 -D
wiconfig: ioctl: Invalid argument
scanning .............: root@nutcracker ; 
: root@nutcracker ; ifconfig wi0 up
: root@nutcracker ; wiconfig wi0 -D
scanning .....
AP Information
ap[0]:
        netname (SSID):                 [ RadioLAN ]
        BSSID:                          [ 00:02:2d:0d:5a:8e ]
        Channel:                        [ 1 ]
        Quality/Signal/Noise [signal]:  [ 30 / 83 / 53 ]
                                [dBm]:  [ 30 / -66 / -96 ]
        BSS Beacon Interval [Kusec]:    [ 100 ]
        Capinfo:                        [ ESS WEP ]
: root@nutcracker ; ifconfig wi0 down


Apply patch

: root@nutcracker ; ifconfig wi0 | grep MU
wi0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
: root@nutcracker ; wiconfig wi0 -D
scanning .....
AP Information
ap[0]:
        netname (SSID):                 [ RadioLAN ]
        BSSID:                          [ 00:02:2d:0d:5a:8e ]
        Channel:                        [ 1 ]
        Quality/Signal/Noise [signal]:  [ 28 / 83 / 55 ]
                                [dBm]:  [ 28 / -66 / -94 ]
        BSS Beacon Interval [Kusec]:    [ 100 ]
        Capinfo:                        [ ESS WEP ]
: root@nutcracker ; ifconfig wi0 | grep MU
wi0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> mtu 1500




>Fix:

Index: wiconfig.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/wiconfig/wiconfig.8,v
retrieving revision 1.19
diff -w -u -r1.19 wiconfig.8
--- wiconfig.8  2002/01/21 11:35:06     1.19
+++ wiconfig.8  2002/01/22 01:41:08
@@ -140,8 +140,6 @@
 .It Fl D
 This forces the driver to initiate one round of access point scanning.
 All of Access points found are displayed.
-This mode does not work unless the driver has been initialized; i.e., an IP
-address must be assigned first.
 .It Fl e Ar 0|1
 Enable or disable WEP encryption.  Permitted values are
 .Ar 0
Index: wiconfig.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/wiconfig/wiconfig.c,v
retrieving revision 1.16
diff -w -u -r1.16 wiconfig.c
--- wiconfig.c  2002/01/21 12:59:50     1.16
+++ wiconfig.c  2002/01/22 01:41:09
@@ -109,6 +109,8 @@
 static void wi_setkeys         __P((char *, char *, int));
 static void wi_printkeys       __P((struct wi_req *));
 static void wi_dumpstats       __P((char *));
+static int  get_if_flags       __P((int, const char *));
+static int  set_if_flags       __P((int, const char *, int));
 static void usage              __P((void));
 static struct wi_table *
        wi_optlookup __P((struct wi_table *, int));
@@ -116,6 +118,38 @@
 static void wi_str2key         __P((char *, struct wi_key *));
 int main __P((int argc, char **argv));
 
+static int get_if_flags(s, name)
+       int                     s;
+       const char              *name;
+{
+       struct ifreq ifreq;
+       int flags;
+       
+       strncpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
+       if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifreq) == -1)
+               err(1, "SIOCGIFFLAGS");
+       flags = ifreq.ifr_flags;
+
+       return flags;
+}
+
+static int set_if_flags(s, name, flags)
+       int                     s;
+       const char              *name;
+       int                     flags;
+{
+       struct ifreq ifreq;
+       
+       ifreq.ifr_flags = flags;
+       strncpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
+       if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifreq) == -1)
+               err(1, "SIOCSIFFLAGS");
+
+       return 0;
+}
+
+
+
 static void wi_apscan(iface)
        char                    *iface;
 {
@@ -124,11 +158,22 @@
        int                     s;
        int                     naps, rate;
        int                     retries = 10;
+       int                     flags;
        struct wi_apinfo        *w;
        int                     i, j;
 
        if (iface == NULL)
                errx(1, "must specify interface name");
+
+
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       if (s == -1)
+               err(1, "socket");
+
+       flags = get_if_flags(s, iface);
+       if ((flags & IFF_UP) == 0)
+               flags = set_if_flags(s, iface, flags | IFF_UP);
+
        memset((char *)&wreq, 0, sizeof(wreq));
 
        wreq.wi_type = WI_RID_SCAN_APS;
@@ -154,12 +199,8 @@
         strcpy(ifr.ifr_name, iface);
         ifr.ifr_data = (caddr_t)&wreq;
 
-       s = socket(AF_INET, SOCK_DGRAM, 0);
-
-       if (s == -1)
-               err(1, "socket");
-
        printf("scanning ...");
+       fflush(stdout);
        while (ioctl(s, SIOCGWAVELAN, &ifr) == -1) {
                retries--;
                if (retries >= 0) {
@@ -170,10 +211,10 @@
                errno = 0;
        }
 
-       close(s);
        if (errno) {
+               set_if_flags(s, iface, flags);
+               close(s);
                err(1, "ioctl");
-               exit(1);
        }
        printf("\nAP Information\n");
 
@@ -232,6 +273,9 @@
                }
                if (rate) printf("\tDataRate [Mbps]:\t\t[ %d ]\n", rate);
        }
+
+       set_if_flags(s, iface, flags);
+       close(s);
 }
 
 static void wi_getval(iface, wreq)



>Release-Note:
>Audit-Trail:
>Unformatted: