tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: IEEE80211_IOC_STA_STATS broken?



David Young wrote:
If someone could tell me what I'm doing wrong or it's it's a
NetBSD-4.99.73 bug I'd appreciate it.
Apparently, i_data has to point at a STA's MAC address:

        error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN);
        if (error != 0)
                return error;
        ni = ieee80211_find_node(&ic->ic_sta, macaddr);
        if (ni == NULL)
                return EINVAL;          /* XXX */

Instead of EINVAL, it should return ENOENT, IMO.

Also, I suggest pointing i_data at an ieee80211req_sta_stats.

OK, it works a little better now.
It things it works, but from the looks of it the data returned is garbage. Attached is the program, here is the output.

$ ./x
ok
00:13:49:a0:1d:48
00:13:49:a0:1d:48
1024
SIOCG80211: Operation not permitted
$ sudo ./x
ok
00:13:49:a0:1d:48
00:13:49:a0:1d:48
1024
ok
00:00:00:00:00:00
0 0 0

The last 3 numbers are data length, frequency and rssi.
Questions

1) Why is superuser required to obtain such simple information such as rssi of the AP associated to? 2) What is going wrong? It's quite hard as I can find no sample code for this ioctl and I don't understand much kernel code.
3) Is there an easier way to do this?

This is purely to try and get the wavelan panel plugin on XFCE working with my iwi0 card.

Thanks

Roy
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <net/if.h>
#include <net/if_ether.h>
#include <net80211/ieee80211.h>
#include <net80211/ieee80211_ioctl.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(void) {
        struct ieee80211_bssid bssid;
        struct ieee80211req ireq;
        union {
                struct ieee80211req_sta_req req;
                char buf[1024];
        } u;
        struct ieee80211req_sta_info *si;
        int8_t noise;
        int level;
        struct ether_addr ea;
        int s = socket(AF_INET, SOCK_DGRAM, 0);

        bzero(&bssid, sizeof(bssid));
        strlcpy(bssid.i_name, "iwi0", sizeof(bssid.i_name));
        if (ioctl(s, SIOCG80211BSSID, &bssid) != 0) {
                perror("SIOCG80211BSSID");
                exit(-1);
        }
        printf("ok\n");
        memcpy(ea.ether_addr_octet, bssid.i_bssid, IEEE80211_ADDR_LEN);
        printf("%s\n", ether_ntoa(&ea));
        memset(&ireq, 0, sizeof(ireq));
        strlcpy(ireq.i_name, "iwi0", sizeof(ireq.i_name));
        memcpy(u.req.is_u.macaddr, bssid.i_bssid,sizeof(u.req.is_u.macaddr));
        //memset(u.req.is_u.macaddr, 0xff, sizeof(u.req.is_u.macaddr));
        memcpy(ea.ether_addr_octet, u.req.is_u.macaddr, 
sizeof(u.req.is_u.macaddr));
        printf("%s\n", ether_ntoa(&ea));
        ireq.i_type = IEEE80211_IOC_STA_INFO;
        ireq.i_data = (caddr_t)&u;
        ireq.i_len = sizeof(u);
        printf ("%d\n", ireq.i_len);
        if(ioctl(s, SIOCG80211, &ireq) != 0) {
                perror("SIOCG80211");
                exit(-1);
        }
        printf("ok\n");
        si = &u.req.info[0];
        memcpy(ea.ether_addr_octet, si->isi_macaddr, IEEE80211_ADDR_LEN);
        printf("%s\n", ether_ntoa(&ea));
        printf ("%d %d %d\n", ireq.i_len, si->isi_freq, si->isi_rssi);
        return 0;
}



Home | Main Index | Thread Index | Old Index