android wifi-wpa_supplicant_源码分析(一)

9 篇文章 0 订阅
5 篇文章 1 订阅

wpa_supplicant 是一个开源软件项目,它实现了 Station 对无线网络进行管理和控制的功能。
一、main函数分析
    (/external/wpa_supplicant_8/wpa_supplicant/main.c)
    int main(int argc, char *argv[])
    {
        int c, i;
        struct wpa_interface *ifaces, *iface;
        int iface_count, exitcode = -1;
        struct wpa_params params;
        struct wpa_global *global;
    
        //Android 平台中, 下面这个函数的实现在 os_unix.c 中。 Android 对其做了一些修改,主要是权限方面的设置防止某些情况下被破解者利
        用权限漏洞以获取 root 权限
        if (os_program_init())
            return -1;
    
        os_memset(&params, 0, sizeof(params));
        params.wpa_debug_level = MSG_INFO;
    
        iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
        if (ifaces == NULL)
            return -1;
        iface_count = 1;
    
        wpa_supplicant_fd_workaround(1);    //输入输出重定向到 /dev/null 设备
    
        for (;;) {    //参数解析
            c = getopt(argc, argv,
                   "b:Bc:C:D:de:f:g:G:hi:I:KLm:No:O:p:P:qsTtuvW");
            if (c < 0)
                break;
            switch (c) {
            case 'b':
                iface->bridge_ifname = optarg;
                break;
            case 'B':
                params.daemonize++;
                break;
            case 'c':
                //指定配置文件名。注意,该参数赋值给了 wpa_interface 中的变量
                iface->confname = optarg;
                break;
            case 'C':
                iface->ctrl_interface = optarg;
                break;
            case 'D':
                //指定 driver 名称
                iface->driver = optarg;
                break;
            case 'd':
    #ifdef CONFIG_NO_STDOUT_DEBUG
                printf("Debugging disabled with "
                       "CONFIG_NO_STDOUT_DEBUG=y build time "
                       "option.\n");
                goto out;
    #else /* CONFIG_NO_STDOUT_DEBUG */
                params.wpa_debug_level--;
                break;
    #endif /* CONFIG_NO_STDOUT_DEBUG */
            case 'e':
                //指定初始随机数文件,用于后续随机数的生成
                params.entropy_file = optarg;
                break;
    #ifdef CONFIG_DEBUG_FILE
            case 'f':
                params.wpa_debug_file_path = optarg;
                break;
    #endif /* CONFIG_DEBUG_FILE */
            case 'g':
                params.ctrl_interface = optarg;
                break;
            case 'G':
                params.ctrl_interface_group = optarg;
                break;
            case 'h':
                usage();
                exitcode = 0;
                goto out;
            case 'i':
                //指定网络设备接口名
                iface->ifname = optarg;
                break;
            case 'I':
                iface->confanother = optarg;
                break;
            case 'K':
                params.wpa_debug_show_keys++;
                break;
            case 'L':
                license();
                exitcode = 0;
                goto out;
    #ifdef CONFIG_P2P
            case 'm':
                iface->conf_p2p_dev = optarg;
                break;
    #endif /* CONFIG_P2P */
            case 'o':
                params.override_driver = optarg;
                break;
            case 'O':
                params.override_ctrl_interface = optarg;
                break;
            case 'p':
                iface->driver_param = optarg;
                break;
            case 'P':
                os_free(params.pid_file);
                params.pid_file = os_rel2abs_path(optarg);
                break;
            case 'q':
                params.wpa_debug_level++;
                break;
    #ifdef CONFIG_DEBUG_SYSLOG
            case 's':
                params.wpa_debug_syslog++;
                break;
    #endif /* CONFIG_DEBUG_SYSLOG */
    #ifdef CONFIG_DEBUG_LINUX_TRACING
            case 'T':
                params.wpa_debug_tracing++;
                break;
    #endif /* CONFIG_DEBUG_LINUX_TRACING */
            case 't':
                params.wpa_debug_timestamp++;
                break;
    #ifdef CONFIG_DBUS
            case 'u':
                params.dbus_ctrl_interface = 1;
                break;
    #endif /* CONFIG_DBUS */
            case 'v':
                printf("%s\n", wpa_supplicant_version);
                exitcode = 0;
                goto out;
            case 'W':
                params.wait_for_monitor++;
                break;
            case 'N':
                iface_count++;
                iface = os_realloc_array(ifaces, iface_count,
                             sizeof(struct wpa_interface));
                if (iface == NULL)
                    goto out;
                ifaces = iface;
                iface = &ifaces[iface_count - 1];
                os_memset(iface, 0, sizeof(*iface));
                break;
            default:
                usage();
                exitcode = 0;
                goto out;
            }
        }
    
        exitcode = 0;
        //关键函数:根据传入的参数,创建并初始化一个 wpa_global 对象
        global = wpa_supplicant_init(¶ms);
        if (global == NULL) {
            wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
            exitcode = -1;
            goto out;
        } else {
            wpa_printf(MSG_INFO, "Successfully initialized "
                   "wpa_supplicant");
        }
    
        for (i = 0; exitcode == 0 && i < iface_count; i++) {
            struct wpa_supplicant *wpa_s;
    
            if ((ifaces[i].confname == NULL &&
                 ifaces[i].ctrl_interface == NULL) ||
                ifaces[i].ifname == NULL) {
                if (iface_count == 1 && (params.ctrl_interface ||
                             params.dbus_ctrl_interface))
                    break;
                usage();
                exitcode = -1;
                break;
            }
            //WPAS 支持操作多个无线网络设备,此处需将它们一一添加到WPAS中
            //WPAS 内部将初始化这些设备
            wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]);
            if (wpa_s == NULL) {
                exitcode = -1;
                break;
            }
    #ifdef CONFIG_P2P
            if (wpa_s->global->p2p == NULL &&
                (wpa_s->drv_flags &
                 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
                wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) <
                0)
                exitcode = -1;
    #endif /* CONFIG_P2P */
        }
    
        //Android 平台中, wpa_supplicant 通过 select 或 epoll 方式实现多路 I/O 复用。
        if (exitcode == 0)
            exitcode = wpa_supplicant_run(global);
    
        wpa_supplicant_deinit(global);
    
    out:
        wpa_supplicant_fd_workaround(0);
        os_free(ifaces);
        os_free(params.pid_file);
    
        os_program_deinit();
    
        return exitcode;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值