wifi @android:wpa_wlan0,android-wifi模块篇之wpa_suppliact解析(上)

以下分析基于 wpa_supplicant 0.5.11

版本

1、wpa_supplicant简介

wpa_supplicant is an implementation of the WPA Supplicant

component,

i.e., the part that runs in the client stations. It implements WPA

key

negotiation with a WPA Authenticator and EAP authentication

with

Authentication Server. In addition, it controls the roaming and

IEEE

802.11 authentication/association of the wlan driver.

wpa_supplicant is designed to

be a "daemon" program that runs in the

background and acts as the backend component controlling the

wireless

connection. wpa_supplicant supports separate frontend programs and

an

example text-based frontend, wpa_cli, is included with

wpa_supplicant.

Following steps are used when

associating with an AP using WPA:

-

wpa_supplicant requests the kernel driver to scan neighboring

BSSes

-

wpa_supplicant selects a BSS based on its configuration

-

wpa_supplicant requests the kernel driver to associate with the

chosen BSS

- If

WPA-EAP: integrated IEEE 802.1X Supplicant completes EAP

authentication with the authentication server

(proxied by theAuthenticator in the AP)

- If

WPA-EAP: master key is received from the IEEE 802.1X

Supplicant

- If

WPA-PSK: wpa_supplicant uses PSK as the master session key

-

wpa_supplicant completes WPA 4-Way Handshake and Group Key

Handshake

with the Authenticator (AP)

-

wpa_supplicant configures encryption keys for unicast and

broadcast

- normal

data packets can be transmitted and received

2、启动命令

You will need to make a configuration file, e.g.,

/etc/wpa_supplicant.conf, with network configuration for the

networks

you are going to use. Configuration file section below

includes

explanation fo the configuration file format and includes

various

examples. Once the configuration is ready, you can test whether

the

configuration work by first running wpa_supplicant with

following

command to start it on foreground with debugging enabled:

wpa_supplicant

-iwlan0 -c/etc/wpa_supplicant.conf -d

Assuming everything goes

fine, you can start using following command

to start wpa_supplicant on background without debugging:

wpa_supplicant -iwlan0

-c/etc/wpa_supplicant.conf -B

Please note that if you

included more than one driver interface in the

build time configuration (.config), you may need to specify

which

interface to use by including -D

name> option on the command

line. See following section for more details on command line

options

for wpa_supplicant.

Command line options

--------------------

usage:

wpa_supplicant [-BddfhKLqqtuvwW]

[-P]

[-g] \

-i

-c

[-C]

[-D]

[-p] \

[-b [-N

-i

-c

[-C]

[-D] \

[-p]

[-b] ...]

options:

-b = optional bridge interface name

-B = run daemon in the background

-c = Configuration file

-C = ctrl_interface parameter (only used if -c

is not)

-i = interface name

-d = increase debugging verbosity (-dd even

more)

-D = driver name

-f = Log output to default log location

(normally /tmp)

-g = global ctrl_interface

-K = include keys (passwords, etc.) in debug

output

-t = include timestamp in debug messages

-h = show this help text

-L = show license (GPL and BSD)

-p = driver parameters

-P = PID file

-q = decrease debugging verbosity (-qq even

less)

-v = show version

-w = wait for interface to be added, if

needed

-W = wait for a control interface monitor before

starting

-N = start describing new interface

drivers:

hostap = Host AP driver (Intersil Prism2/2.5/3)

[default]

(this can also be used with Linuxant DriverLoader)

hermes = Agere Systems Inc. driver

(Hermes-I/Hermes-II)

madwifi = MADWIFI 802.11 support (Atheros,

etc.)

atmel = ATMEL AT76C5XXx (USB, PCMCIA)

wext = Linux wireless extensions

(generic)

ndiswrapper = Linux ndiswrapper

broadcom = Broadcom wl.o driver

ipw = Intel ipw2100/2200 driver (old; use wext

with Linux 2.6.13 or newer)

wired = wpa_supplicant wired Ethernet

driver

bsd = BSD 802.11 support (Atheros, etc.)

ndis = Windows NDIS driver

In most common cases, wpa_supplicant is started with

wpa_supplicant -Bw -c/etc/wpa_supplicant.conf -iwlan0

This makes the process fork

into background and wait for the wlan0

interface if it is not available at startup time.

The easiest way to debug

problems, and to get debug log for bug

reports, is to start wpa_supplicant on foreground with

debugging

enabled:

wpa_supplicant

-c/etc/wpa_supplicant.conf -iwlan0 -d

wpa_supplicant can control

multiple interfaces (radios) either by

running one process for each interface separately or by running

just

one process and list of options at command line. Each interface

is

separated with -N argument. As an example, following command

would

start wpa_supplicant for two interfaces:

wpa_supplicant \

-c wpa1.conf

-i wlan0 -D hostap -N \

-c wpa2.conf

-i ath0 -D madwifi

If the interface is added in

a Linux bridge (e.g., br0), the bridge

interface needs to be configured to wpa_supplicant in addition to

the

main interface:

wpa_supplicant

-cw.conf -Dmadwifi -iath0 -bbr0

3、结构体介绍

struct wpa_interfacestruct wpa_paramsstruct wpa_global

struct

wpa_interface - Parameters for

wpa_supplicant_add_iface().

struct

wpa_global - Internal, global data for all %wpa_supplicant

interfaces.

This structure is initialized by

calling wpa_supplicant_init() when

starting %wpa_supplicant.

struct

wpa_params - Parameters

for wpa_supplicant_init().

wpa_params主要记录一些与网卡本身没关的参数设置,而wpa_interface对应网络接口,

因为wpa_supplicant支持多个网络接口,所以可能有多个wpa_interface结构体,可以通过命令行

指定不同的接口,wpa_supplicant在main函数开始的地方会进行遍历!(参考代码main.c)

struct wpa_global{

structwpa_supplicant

*ifaces;

structwpa_params

params;

struct ctrl_iface_global_priv

*ctrl_iface;

struct ctrl_iface_dbus_priv

*dbus_ctrl_iface;

};

struct wpa_supplicant - Internal data

for wpa_supplicant interface.

每个网络接口都有一个对应的wpa_supplicant数据结构,该指针指向最近加入的一个,在wpa_supplicant数据结构中有指针指向next

struct ctrl_iface_global_priv

- Global control interface

struct ctrl_iface_dbus_priv - DBUS

control interface

4、理解main.c

在这个函数中,主要做了四件事。

a. android平台进程wpa_supplicant权限及结构体初始化,解析命令行参数

b. 调用wpa_supplicant_init()函数,主要初始化struct

wpa_global *global这个局部结构体同时传递给static struct  eloop_data eloop这个全局结构体并返回这个局部结构体(详解见下)

c. for循环中调用wpa_supplicant_add_iface()函数,注册可能有的一个或多个网卡接口

d. 调用wpa_supplicant_run()函数,这其中如果失败将会走到out或者是通过goto跳转到out.

下面详细介绍这四个过程:

4.1 初步初始化及解析命令行参数

最开始调用了os_program_init函数,来给wpa_supplicant进程分配权限,这里的进程一般是在init.rc中有个

service,然后通过在wifi.c中的函数由UI

settings设置通过jni调用下来从而会把service调用起来!跟踪这个函数到达了os_unix.c,见到了我们熟悉的setuid函数给它

设为AID_WIFI(user / group).

然后下面初始化两大结构体wpa_params和wpa_interface,再然后就开始解析命令行的参数了,这里不再详述了

4.2wpa_supplicant_init(¶ms)

我们先看下这个函数的说明:

这个函数先分配了struct wpa_global

*global这个局部指向结构体指针的内存空间,然后通过传递的params参数填充global指向的结构体中内嵌的structwpa_params对象,紧接着把global这个指针传递给static

struct eloop_data

eloop这个全局结构体对象!

下面分别调用global->ctrl_iface =

wpa_supplicant_global_ctrl_iface_init(global);

对于第一个接口的初始化,实际上通过socket进行了内部进程间通信,如下

priv->sock =

android_get_control_socket(global->params.ctrl_interface);

priv->sock =

socket(PF_UNIX, SOCK_DGRAM, 0);

下面bind或者connect,错误基本上也是goto到fail.到这里控制接口初始化结束.

下面初始化第二个接口dbus

global->dbus_ctrl_iface

=wpa_supplicant_dbus_ctrl_iface_init(global); /

*初始化dbus控制接口ctrl_iface_dbus.c */

再下面调用wpa_supplicant_daemon(global->params.pid_file));

再调用os_daemonize函数写pid(os_unix.c)

,最后返回局部变量global,到此初始化过程结束了!

你可能感兴趣的:(wifi)