一、无线信息传递——user space下的hostapd

本文介绍了用户空间程序hostapd的作用,它作为AP和认证服务器,实现802.11接入管理、认证等功能。详细讲解了hostapd的网络接口和BSS初始化,信号传递机制,以及管理帧处理回调,揭示了如何将配置信息传递给底层并处理来自kernel space的消息。
摘要由CSDN通过智能技术生成

系列说明

  大致简单了解了无线通信在底层的组成,接收和发送之后,接下来希望能更系统地对信息从user space至kernel space,至kernel对信息的使用,发送和接收等一系列步骤进行总结说明。以便后续将wifi的ssid,密码,加密方式等需要的信息填充入beacon帧中进行发送端组包,接收端解包的处理。
  这一章先从user space层的hostapd开始说起,主要目的在于了解hostapd是怎么将hostapd.conf配置文件下的配置内容传递给底层,让底层根据这些信息做相应处理的。
  以下链接是对我了解hostapd过程中起到很大帮助的网址链接:
hostapd源代码分析(一):网络接口和BSS的初始化
hostapd源代码分析(二):hostapd的工作机制
hostapd源代码分析(三):管理帧的收发和处理
wifi相关知识点网址链接
  该篇主要对:hostapd作用,hostapd网络接口和BSS初始化,hostapd信息传输机制,socket注册回调。三个模块进行说明。

一、hostapd作用

  hostapd 是一个用户态用于AP和认证服务器的守护进程。它实现了IEEE 802.11相关的接入管理,IEEE 802.1X/WPA/WPA2/EAP 认证, RADIUS客户端,EAP服务器和RADIUS 认证服务器。Linux下支持的驱动有:Host AP,madwifi,基于mac80211的驱动。
  从上面的一段话中可以了解到,hostapd仅是用于当设备处于ap模式时,进行设备底层的初始化,对需要连接该热点的设备认证及管理。并没有参与相关底层协议帧的组合和发送。

二、hostapd的网络接口和BSS初始化

2.1、简要说明

  在该模块中,hostapd主要进行网络接口及网络网卡的初始化。初始化相应的接收回调函数,网卡相关执行信息的设置以及创建与kernel space层的socket句柄。

2.2、hostapd初始化

  了解hostapd初始化之前首先了解以下两个结构体,因为这两个结构体在hostapd中使用的次数最多,也就是扮演的角色最关键。

/*--------------hostapd中两个关键的结构体----------*/
/**
 * struct hostapd_iface - hostapd per-interface data structure
 */
struct hostapd_iface {
        struct hostapd_config *conf: 保存对网络接口的配置(从配置文件hostapd.conf中加载)
        sizt_t num_bss: 此接口下辖的BSS 个数
        struct hostapd_data **bss:BSS 列表,描述各BSS 的配置
     。。。
}; 

/**
 * struct hostapd_data - hostapd per-BSS data structure
 */
struct hostapd_data {
        struct hostapd_bss_config *conf:保存BSS 的配置信息(从配置文件hostapd.conf 中加载)
        u8 own_addr[ETH_ALEN]:表示此BSS 的BSSID (ETH_ALEN 为6,u8 其实是unsigned char)
        struct wpa_driver_ops *driver:指向一组驱动程序接口,用来和内核交互。(这里是用的nl80211)
        。。。
};

//!!!以上结构体中写出的是最主要的结构体变量,其他的结构体变量暂时不需要重点了解。

  接下来观察main函数中的几个重要的初始化。将以main中接口为入口进行展开说明。

/*----------------hostapd的main函数------------------*/
int main(int argc, char** argv)
{
    ...

    if (hostapd_global_init(&interfaces, entropy_file)) //global的初始化
        return -1;

    /* Initialize interfaces */     
    for (i = 0; i < interfaces.count; i++) 
    {
        interfaces.iface[i] = hostapd_interface_init(&interfaces,   //对每个网络接口(物理网卡)初始化
            argv[optind + i],
            debug); 
        if (!interfaces.iface[i])
            goto out;
    }

    if (hostapd_global_run(&interfaces, daemonize, pid_file))       //下一模块再进行说明
       goto out;
    ...

}   
/*----------------hostapd_global_init函数---------------*/
//global 初始化接口
static int hostapd_global_init(struct hapd_interfaces *interfaces,
          const char *entropy_file)
{
    int i;
    os_memset(&global, 0, sizeof(global));
    hostapd_logger_register_cb(hostapd_logger_cb);
    if (eap_server_register_methods()) {                    //初始化认证服务器算法
        wpa_printf(MSG_ERROR, "Failed to register EAP methods");
        return -1;
    }
    if (eloop_init()) {                             //eloop初始化 主要为初始化eloop_data结构体
        wpa_printf(MSG_ERROR, "Failed to initialize event loop");
        return -1;
    }
    random_init(entropy_file);
    eloop_register_signal_terminate(handle_term, interfaces);       //相关信号处理回调初始化
    for (i = 0; wpa_drivers[i]; i++)
        global.drv_count++;
    if (global.drv_count == 0) {
        wpa_printf(MSG_ERROR, "No drivers enabled");
        return -1;
    }
    global.drv_priv = os_calloc(global.drv_count, sizeof(void *));      //申请driver驱动私有数据空间
    if (global.drv_priv == NULL)
        return -1;
    return 0;
} 
/*-------------hostapd_interface_init函数--------------*/
//hostapd_interface_init:网卡初始化
static struct hostapd_iface *
hostapd_interface_init(struct hapd_interfaces *interfaces,
         const char *config_fname, int debug)
{
    struct hostapd_iface *iface;
    int k;
    wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
    iface = hostapd_init(config_fname);             //用于初始化网卡,iface为hostapd_init的(struct hostapd_iface结构体)返回值
    if (!iface)
        return NULL;
    iface->interfaces = interfaces;
    for (k = 0; k < debug; k++) {
        if (iface->bss[0]->conf->logger_stdout_level > 0)
            iface->bss[0]->conf->logger_stdout_level--;
    }
    if (iface->conf->bss[0].iface[0] != 0 ||
        hostapd_drv_none(iface->bss[0])) 
    {
        if (hostapd_driver_init(iface) ||           //初始化网络驱动
            hostapd_setup_interface(iface)) {       //设置网络接口
            hostapd_interface_deinit_free(iface);
            return NULL;
        }
    }
    return iface;
}
/*---------------hostapd_init函数----------------*/
/**
 * hostapd_init - Allocate and initialize per-interface data
 * @config_file: Path to the configuration file
 * Returns: Pointer to the allocated interface data or %NULL on failure
 *
 * This function is used to allocate main data structures for per-interface
 * data. The allocated data buffer will be freed by calling
 * hostapd_cleanup_iface().
 */
static struct hostapd_iface * hostapd_init(const char *config_file)
{
    struct hostapd_iface *hapd_iface = NULL;
    struct hostapd_config *conf = NULL;
    struct hostapd_data *hapd;
    size_t i;
    hapd_iface = os_zalloc(sizeof(*hapd_iface));
    if (hapd_iface == NULL)
        goto fail;
    hapd_iface->config_fname = os_strdup(config_file);
    if (hapd_iface->config_fname == NULL)
        goto fail;
    conf = hostapd_config_read(hapd_iface->config_fname);       //用于读取配置文件中的配置信息,一般的配置文件名(hostapd.conf)
    if (conf == NULL)
        goto fail;
    hapd_iface->conf = conf;
    hapd_iface->num_bss = conf->num_bss;                //从配置中获取BSS的个数      
    hapd_iface->bss = os_calloc(conf->num_bss,          //分配BSS列表空间
            sizeof(struct hostapd_data *));
    if (hapd_iface->bss == NULL)
        goto fail;
    for (i = 0; i < conf->num_bss; i++) {
        hapd = hapd_iface->bss[i] =
            hostapd_alloc_bss_data(hapd_iface, conf,    //初始化每个BSS数据结构
            &conf->bss[i]);
        if (hapd == NULL)
            goto fail;
        hapd->msg_ctx = hapd;
        hapd->setup_complete_cb = hostapd_setup_complete_cb;
    }
    return hapd_iface;
fail:
    if (conf)
        hostapd_config_free(conf);
    if (hapd_iface) {
        os_free(hapd_iface->config_fname);
        os_free(hapd_iface->bss);
        os_free(hapd_iface);
    }
    return NULL;
}

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值