Search code examples
kernelwifiioctlnetlinkiwconfig

configure network device with wireless extensions


I need to configure a network device in C on a linux host for an application. I read up on netlink, libnl and nl80211 which goes through cfg80211 and mac80211. I found out later that the driver for the device I am using does not support the mac80211 interface so I am unable to use netlink library to configure the device. My only option left is through wireless extensions using ioctl. So I have been reading the source code for iwconfig (iw uses netlink while iwconfig uses wext).

So for example, say I am trying to set the channel on a 80211 adapter. The wireless extension ioctl command is SIOCSIWFREQ (as per iwconfig and my device's driver). By what I have read, you open up a socket and use ioctl with a 'ifreq' structure to configure the network adapter (see 'man netdevice').

The thing is, iwconfigure defines its own 'ifreq' structure called 'iwreq' which looks totally different (see iwconfig source, there is a comment that says this iwreq structure is the same as the ifreq struct).

The ifreq structure doesnt even look like it has a field to set the channel.

So my question, where in the kernel is this 'ifreq' struct received and processed. Where can I find documentation on the interface (the fields in the struct).

All the IOCTLS commands are defined in /usr/inlcude/linux/wireless.h

Thank you!

Here is the ifreq:

struct ifreq {
    char ifr_name[IFNAMSIZ]; /* Interface name */
    union {
        struct sockaddr ifr_addr;
        struct sockaddr ifr_dstaddr;
        struct sockaddr ifr_broadaddr;
        struct sockaddr ifr_netmask;
        struct sockaddr ifr_hwaddr;
        short           ifr_flags;
        int             ifr_ifindex;
        int             ifr_metric;
        int             ifr_mtu;
        struct ifmap    ifr_map;
        char            ifr_slave[IFNAMSIZ];
        char            ifr_newname[IFNAMSIZ];
        char           *ifr_data;
    };
};

and here is iwreq (from wireless.h in wireless-tools from HP)

union   iwreq_data
{   
    /* Config - generic */
    char        name[IFNAMSIZ];
    /* Name : used to verify the presence of  wireless extensions.
    * Name of the protocol/provider... */

    struct iw_point essid;      /* Extended network name */
    struct iw_param nwid;       /* network id (or domain - the cell) */
    struct iw_freq  freq;       /* frequency or channel :
                                 * 0-1000 = channel
                                 * > 1000 = frequency in Hz */

    struct iw_param sens;       /* signal level threshold */
    struct iw_param bitrate;    /* default bit rate */
    struct iw_param txpower;    /* default transmit power */
    struct iw_param rts;        /* RTS threshold threshold */
    struct iw_param frag;       /* Fragmentation threshold */
    __u32       mode;       /* Operation mode */
    struct iw_param retry;      /* Retry limits & lifetime */

    struct iw_point encoding;   /* Encoding stuff : tokens */
    struct iw_param power;      /* PM duration/timeout */
    struct iw_quality qual;     /* Quality part of statistics */

    struct sockaddr ap_addr;    /* Access point address */
    struct sockaddr addr;       /* Destination address (hw/mac) */

    struct iw_param param;      /* Other small parameters */
    struct iw_point data;       /* Other large parameters */
};

struct  iwreq
{
    union
    {
      char    ifrn_name[IFNAMSIZ];    /* if name, e.g. "eth0" */
    } ifr_ifrn;

    /* Data part (defined just above) */
    union   iwreq_data  u;
};

It's easy to tell how you would use iwreq to configure the channel, the freq field, but where is the standard in the ifreq structure?


Solution

  • the struct iwreq is found in linux/wireless.h you can simply include it and use the 'iwreq' struct.