IP 카메라에서 WiFi 기능을 위해 필요한 파일 시스템에 포함된 파일들을 정리하여 기술한다.
'현재(2013/6/28) 시점을 기준으로 한다.'

그것들은 어디에 있나?

크게 두 군데로 나뉘어 있다.

WiFi 관련 커널 모듈 파일(.ko)과 WiFi 인터페이스 전용 DHCP client application 이 있다.

파일명 설명
cfg80211.ko WiFi 관련 커널 모듈 파일
lib80211_crypt_ccmp.ko WiFi 관련 커널 모듈 파일
lib80211_crypt_tkip.ko WiFi 관련 커널 모듈 파일
lib80211_crypt_wep.ko WiFi 관련 커널 모듈 파일
mac80211.ko WiFi 관련 커널 모듈 파일
wifi-dhcpcd –WiFi 전용 DHCP 클라이언트 프로그램으로서, 이런식으로 실행한다(./wifi-dhcpcd -d eth1 &)–
load_module.sh 부팅 시, 자동으로 커널 모듈을 로딩하는 파일
파일명 설명
udhcpc 기존의 wifi-dhcpcd 버그(killall 할 때, 해당 인터페이스가 down 됨)로 인해 대체하여 사용함(udhcpc -i eth0)
파일명 설명
default.script udhcpc 를 실행했을 때, 자동으로 읽어들이는 스크립트 파일. 실제로 sample.bound 파일을 실행한다
sample.bound IP 및 DNS 를 설정하는 역할을 하는 스크립트 파일

WiFi API 와 관련한 모든 파일들이 있다.

파일명 설명
bcm 무선카메라 WiFi 관련 파일들
realtek 지능형 카메라 WiFi 관련 파일들
dns-va.conf 지능형 카메라에서 soft ap 모드로 동작시, DHCP server 가 실행하기 위해 참조하는 설정 파일
dns.conf 무선 카메라에서 soft ap 모드로 동작시, DHCP server 가 실행하기 위해 참조하는 설정 파일
dnsmasq DHCP server 로 만들어주는 프로그램으로서, 이런식으로 실행한다(./dnsmasq -C ../dns.conf -d &)

무선 카메라(BCM43362)와 관련한 파일들이 있다.

파일명 설명
NVRAM_20130221.txt WiFi 드라이버 세팅값으로서, NVRAM 과 마찬가지 역할을 한다
bcm43362_softap.bin WiFi SOC 에 실제로 올라가는 펌웨어로서 성능에 영향을 주는 요인 중 하나다
dhd.ko WiFi 드라이버 커널 모듈 파일
factory_mode.sh Factory 모드(즉, soft ap 모드로 동작할 때)에서 실행되는 스크립트 파일
insmod.sh 드라이버 모듈 및 펌웨어, 설정 파일을 로딩하는 스크립트 파일
normal_mode.sh 일반 모드(즉, station 모드로 동작할 때)에서 실행되는 스크립트 파일
softap-open soft ap 동작시, 인증을 암호없음으로 설정하는 스크립트 파일
softap-wpa2 soft ap 동작시, 인증을 wpa2(암호 : 87654321) 로 설정하는 스크립트 파일
supplicant wpa_supplicant 관련 파일들이 들어있는 디렉토리
wlarm wl 실행파일과 동일. 소스코드가 없어 BCM 으로부터 바이너리만 받아 사용
wps-none.sh WPS 연결 시, AP 의 인증이 암호없음 일때, 실행되는 스크립트 파일
wps-wpa.sh WPS 연결 시, AP 의 인증의 WPA/WPA2 일때, 실행되는 스크립트 파일

wpa_supplicant 관련 파일들이 들어있다.

파일명 설명
ap_scan –AP 에 접속된 이후에도, 일정시간 마다 스캔을 하기위해 실행되는 스크립트, AP 접속 후 10 초후에 AP 스캔을 한다(삭제 예정)–
disconn 강제로 접속된 AP 연결을 끊을 때, 실행되는 스크립트. (./wpa_cli -i eth1 -p /var/run/wpa_supplicant disable_network 0)
open –인증이 암호없음 인 AP 에 접속할 때, 실행되는 스크립트. SSID 를 인자로 받아 사용한다(삭제 예정)–
w-none 인증이 암호없음 인 AP 에 접속할 때, 실행되는 스크립트. SSID 를 인자로 받아 사용한다
open-wps WPS 로 접속시, AP 의 인증이 암호없음 일때, 실행되는 스크립트. SSID 를 인자로 받아 사용한다. wpsenr 에 의해 실행된다
pbc wpa_supplicant 로 WPS PBC 로 접속할 때, 실행되는 스크립트. 현재 구동되지 않아 사용안함
pin wpa_supplicant 로 WPS PIN 로 접속할 때, 실행되는 스크립트. 현재 구동되지 않아 사용안함
save wpa_supplicant 에서 현재 접속 정도를 저장할 때, 실행하는 스크립트. 현재 사용하지 않음
–scan_parse– –scan 결과를 parsing 하는 테스트 프로그램. 삭제예정–
status –wpa_supplicant 에서 현재 상태를 확인할 때 사용하는 스크립트 파일. 삭제예정–
supplicant_bcm.sh wpa_supplicant 를 실행하는 스크립트. 주기적으로 스캔을 실행하기 위해 wpa_supplicant 실행 후, 1초 후에 스캔 실행함
wpa.conf wpa_supplicant 가 실행될 때, 참조하는 환경 설정 파일
wpa_cli wpa_supplicant 에 명령을 내리기 위해 사용하는 프로그램
wpa_passphrase wpa_supplicant 에서 접속시 암호화를 위해 사용하는 프로그램. 평소에 사용할 일 없음
wpa_supplicant wpa_supplicant 실행 파일
wpa_tkip_aes –wpa_supplicant 에서 AP 의 인증이 WPA/WPA2 일 때 사용하는 스크립트 파일(삭제예정)–
wpa_tkip_aes-wps WPS 사용시, AP 의 인증이 WPA/WPA2 일 때 사용하는 스크립트 파일
w-wep-open-hex OPEN(개방) 모드에서 비밀번호가 숫자일 때 사용하는 스크립트 파일
w-wep-open-string OPEN(개방) 모드에서 비밀번호가 문자일 때 사용하는 스크립트 파일
w-wep-shared-hex SHARED(공유) 모드에서 비밀번호가 숫자일 때 사용하는 스크립트 파일
w-wep-shared-string SHARED(공유) 모드에서 비밀번호가 문자일 때 사용하는 스크립트 파일
w-wpa WPA/WPA2 모드 일때 사용하는 스크립트 파일

지능형 카메라(Realtek8189)와 관련한 파일들이 있다.

파일명 설명
8192cu.ko WiFi 드라이버 커널 모듈 파일
factory_mode.sh soft ap 모드로 동작 할때, 실행되는 스트립트 파일
hostapd soft ap 모드로 실행하게 만들어주는 프로그램. 이렇게 사용한다(/hostapd ./hostapd.conf.bak)
hostapd.conf hostapd 가 실행할 때, 참조하는 설정 파일. 인증은 암호없음으로 설정
hostapd.conf.bak hostapd 가 실행할 때, 참조하는 설정 파일. 인증은 WPA2 로 설정
hostapd_rtl hostapd 를 실제 실행하게 하는 스크립트 파일. WiFi 인터페이스의 MAC 주소를 이용해서 SSID 를 설정하도록 설정 파일에 추가함
insmod.sh WiFi 드라이버를 로딩하는 스크립트

어떻게 생성하나?

파일시스템에 들어있는 파일 가운데, 바이너리 파일을 사용하는 경우가 몇 있다. 이 문서에서 설명할 프로그램들의 소스코드는 /home/wjkim/wifi 디렉토리 아래에 있다.

–DHCP client 로 만들어주는 프로그램이다. 기존에 유선 네트워크 인터페이스용으로 사용되고 있었으며, 무선 네트워크 인터페이스용으로 복사하여 이름만 바꿨다. 따라서 이름이 다른 두개의 바이너리 파일은 동일하다고 봐도 무방하다.–
–이 프로그램은 데몬의 형태로 실행되며, 백그라운드로 dhcp request 를 계속 보내다가, IP 를 할당받으면 IP 를 설정한다. 그 이후로도 프로세스는 실행되면서, dhcp request 를 보낸다.–

# ./dhcpcd -h
DHCP Client Daemon v.1.3.22-pl4
Copyright (C) 1996 - 1997 Yoichi Hariguchi <yoichi@fore.com>
Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
Location: http://www.phystech.com/download/
Usage: dhcpcd [-dknrBCDHNRSTY] [-l leasetime] [-h hostname] [-t timeout]
       [-i vendorClassID] [-I ClientID] [-c filename] [-s [ipaddr]]
       [-w windowsize] [-G [gateway]] [interface]
root@IPCAM:/opt/ipnc# 

busybox 에 기본적으로 포함되어 있는 dhcp client 프로그램으로서, 실행방법은 다음과 같다.

#udhcpc -i eth1

타겟을 DHCP server 로 만들어주는 프로그램이다. 오픈소스이며, dnsmasq-2.65.tar.gz 을 사용했다. Makefile 파일을 수정하여 크로스컴파일하면, dnsmasq 바이너리 파일을 얻을 수 있다.
수정사항을 반영하여 dnsmasq-2.65-wjkim.tar 을 만들었다. 차후에는 이 파일을 사용하면 된다.
이것 말고도 설정 파일이 필요한데, 다음과 같이 작성하면 된다. 여기서는 파일명을 dns.conf 로 했다.

dhcp-authoritative
dhcp-range=10.10.10.11,10.10.10.100,12h
dhcp-leasefile=/var/lib/misc/dnsmasq.leases
pid-file=/var/lib/misc/dnsmasq.pid
dhcp-option=3,10.10.10.1
user=root                 // 실행 권한
interface=wl0.1           // DHCP 서버로 동작시킬 인터페이스 명을 적어준다

이외 자세한 설명은 다른 문서를 참조한다.

BCM 드라이버에서 wpa_supplicant 상의 WPS 가 제대로 동작되지 않는 문제로 인해, BCM 전용 WPS 프로그램을 빌드해서 사용해야 한다. 파일은 falcon_rel_5_90_188_59_0507-real-final.tar.gz 을 사용한다. 빌드 방법은 다음과 같다.

#/home/wjkim/wifi/falcon_rel_5_90_188_59_0507/falcon_rel_5_90_188_59
#./bfd-app-wps.sh

에러없이 빌드가 완료되면, 2.6.37 디렉토리 아래에 wpsenr 바이너리가 생성되어 있다. 사용방법은 다음과 같다.

#./wpsenr -if eth1 -pb &

원래 릴리즈 받은 소스코드에서 내가 추가한 파일은 'falcon_rel_5_90_188_59_0507/falcon_rel_5_90_188_59/src/wps/linux/enr/wps_enr.c' 파일이다.

AP 스캔 및 접속 등의 거의 모든 WIFI 동작을 관리하는 프로그램으로 오픈소스다. v2.0 을 사용한다. wpa_supplicant-2.0-wjkim.tar 파일을 사용했다. 빌드 방법은 다음과 같다.

#cd wpa_supplicant-2.0/wpa_supplicant
#make

성공적으로 빌드되면 wpa_supplicant, wpa_cli, wpa_passphrase 가 생성된다. 원래 소스코드에서 수정한 부분은 'wpa_supplicant/ctrl_iface.c' 파일이다.

본래의 오픈소스 코드에서 몇가지 이슈들로 인해 코드를 수정했다.

주기적으로 Scan 을 하기 위해 빌드시 해당 옵션을 활성화한다. 아래는 .config 파일이다.

# Autoscan
# This can be used to enable automatic scan support in wpa_supplicant.
# See wpa_supplicant.conf for more information on autoscan usage.
#
# Enabling directly a module will enable autoscan support.
# For exponential module:
CONFIG_AUTOSCAN_EXPONENTIAL=y
# For periodic module:
#CONFIG_AUTOSCAN_PERIODIC=y

scan.c 파일을 다음과 같이 수정한다.

void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
{
    wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
//  eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);    주석 처리
}

wpa_supplicant 는 일부 Hide SSID 까지도 스캔하여 결과를 보여준다. 이때 SSID 는 '\x00' 으로 시작한다. 이를 필터링 하기 위해 ctrl_iface.c 파일을 다음과 같이 수정했다.

#define HIDE_WILDCARD_SSID  "\x00"                        // 추가
#define HIDE_WILDCARD_SSID_LEN  4                         // 추가
...
/* Format one result on one text line into a buffer. */
static int wpa_supplicant_ctrl_iface_scan_result(
    struct wpa_supplicant *wpa_s,
    const struct wpa_bss *bss, char *buf, size_t buflen)
{
    char *pos, *end;
    int ret;
    const u8 *ie, *ie2, *p2p;
 
    p2p = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
    if (p2p && bss->ssid_len == P2P_WILDCARD_SSID_LEN &&
        os_memcmp(bss->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) ==
        0)
        return 0; /* Do not show P2P listen discovery results here */
 
    if (os_memcmp(bss->ssid, HIDE_WILDCARD_SSID, HIDE_WILDCARD_SSID_LEN) == 0)                // 추가
        return 0; /* Do not show P2P listen discovery results here */                                                 // 추가
 
    pos = buf;
    end = buf + buflen;
 
    ret = os_snprintf(pos, end - pos, "%s",
              wpa_ssid_txt(bss->ssid, bss->ssid_len));
    if (ret < 0 || ret >= end - pos)
        return -1;
    pos += ret;
 
    ret = os_snprintf(pos, end - pos, "\t%d\t",
              bss->level);
    if (ret < 0 || ret >= end - pos)
        return -1;
    pos += ret;
    ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
    if (ie)
        pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
    ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    if (ie2)
        pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
    pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
    if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
        ret = os_snprintf(pos, end - pos, "[WEP]");
        if (ret < 0 || ret >= end - pos)
            return -1;
        pos += ret;
    }
    if (bss->caps & IEEE80211_CAP_IBSS) {
        ret = os_snprintf(pos, end - pos, "[IBSS]");
        if (ret < 0 || ret >= end - pos)
            return -1;
        pos += ret;
    }
    if (bss->caps & IEEE80211_CAP_ESS) {
        ret = os_snprintf(pos, end - pos, "[ESS]");
        if (ret < 0 || ret >= end - pos)
            return -1;
        pos += ret;
    }
    if (p2p) {
        ret = os_snprintf(pos, end - pos, "[P2P]");
        if (ret < 0 || ret >= end - pos)
            return -1;
        pos += ret;
    }
#ifdef CONFIG_HS20
    if (wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE) && ie2) {
        ret = os_snprintf(pos, end - pos, "[HS20]");
        if (ret < 0 || ret >= end - pos)
            return -1;
        pos += ret;
    }
#endif /* CONFIG_HS20 */
/*
    ret = os_snprintf(pos, end - pos, "\t%s",
              wpa_ssid_txt(bss->ssid, bss->ssid_len));
    if (ret < 0 || ret >= end - pos)
        return -1;
    pos += ret;
*/
    ret = os_snprintf(pos, end - pos, "\n");
    if (ret < 0 || ret >= end - pos)
        return -1;
    pos += ret;
 
    return pos - buf;
}

Application 쪽에 스캔 결과를 보내주기 위해 데이터 포맷을 수정했다. ctrl_iface.c 파일이다.

static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
                        const char *params,
                        char *buf, size_t buflen)       // - wjkim
{
    char *pos, *end, tmp[30];
    int res, verbose, wps, ret;
 
    verbose = os_strcmp(params, "-VERBOSE") == 0;
    wps = os_strcmp(params, "-WPS") == 0;
    pos = buf;
    end = buf + buflen;
 
    ret = os_snprintf(pos, end - pos, "%s\n",
              wpa_supplicant_state_txt(wpa_s->wpa_state));      // - wjkim
    if (ret < 0 || ret >= end - pos)
        return pos - buf;
    pos += ret;
 
 
    if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
        struct wpa_ssid *ssid = wpa_s->current_ssid;
/*      ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
                  MAC2STR(wpa_s->bssid));
        if (ret < 0 || ret >= end - pos)
            return pos - buf;
        pos += ret;
*/
 
 
        if (ssid) {
            u8 *_ssid = ssid->ssid;
            size_t ssid_len = ssid->ssid_len;
            u8 ssid_buf[MAX_SSID_LEN];
            if (ssid_len == 0) {
                int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
                if (_res < 0)   
                    ssid_len = 0;
                else
                    ssid_len = _res;
                _ssid = ssid_buf;
            }
            ret = os_snprintf(pos, end - pos, "%s\n",            // - wjkim
                      wpa_ssid_txt(_ssid, ssid_len));
            if (ret < 0 || ret >= end - pos)
                return pos - buf;
            pos += ret;
 
        if (ret < 0 || ret >= end - pos)
                return pos - buf;
            pos += ret;
        }
 
#ifdef CONFIG_AP
        if (wpa_s->ap_iface) {
            pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
                                end - pos,
                                verbose);
        } else
#endif /* CONFIG_AP */
        pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
    }
/*
    ret = os_snprintf(pos, end - pos, "%s\n",
              wpa_supplicant_state_txt(wpa_s->wpa_state));
    if (ret < 0 || ret >= end - pos)
        return pos - buf;
    pos += ret;
*/
/*
    if (wpa_s->l2 &&
        l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
        ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
        if (ret < 0 || ret >= end - pos)
            return pos - buf;
        pos += ret;
    }
*/
#ifdef CONFIG_P2P
    if (wpa_s->global->p2p) {
        ret = os_snprintf(pos, end - pos, "p2p_device_address=" MACSTR
                  "\n", MAC2STR(wpa_s->global->p2p_dev_addr));
        if (ret < 0 || ret >= end - pos) 
            return pos - buf; 
        pos += ret; 
    }    
#endif /* CONFIG_P2P */
/*
    ret = os_snprintf(pos, end - pos, "address=" MACSTR "\n",
              MAC2STR(wpa_s->own_addr));
    if (ret < 0 || ret >= end - pos)
        return pos - buf;
    pos += ret;
*/
#ifdef CONFIG_HS20
    if (wpa_s->current_bss &&
        wpa_bss_get_vendor_ie(wpa_s->current_bss, HS20_IE_VENDOR_TYPE) &&
        wpa_s->wpa_proto == WPA_PROTO_RSN &&
        wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
        ret = os_snprintf(pos, end - pos, "hs20=1\n");
        if (ret < 0 || ret >= end - pos) 
            return pos - buf; 
        pos += ret; 
    }    
 
    if (wpa_s->current_ssid) {
        struct wpa_cred *cred;
        char *type;
 
        for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
            if (wpa_s->current_ssid->parent_cred != cred)
                continue;
            if (!cred->domain)
                continue;
 
            ret = os_snprintf(pos, end - pos, "home_sp=%s\n",
                      cred->domain);
            if (ret < 0 || ret >= end - pos) 
                return pos - buf; 
            pos += ret; 
 
            if (wpa_s->current_bss == NULL ||
                wpa_s->current_bss->anqp == NULL)
                res = -1;
            else 
                res = interworking_home_sp_cred(
                    wpa_s, cred,
                    wpa_s->current_bss->anqp->domain_name);
            if (res > 0) 
                type = "home";
            else if (res == 0)
                type = "roaming";
            else 
                type = "unknown";
 
            ret = os_snprintf(pos, end - pos, "sp_type=%s\n", type);
            if (ret < 0 || ret >= end - pos) 
                return pos - buf; 
            pos += ret; 
 
            break;
        }
    }    
#endif /* CONFIG_HS20 */
    if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
        wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
        res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos, 
                      verbose);
        if (res >= 0)
            pos += res; 
    }    
 
    res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
    if (res >= 0)
        pos += res; 
 
    return pos - buf; 
}
...
...
...
static int wpa_supplicant_ctrl_iface_scan_results(
    struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
{
    char *pos, *end;
    struct wpa_bss *bss;
    int ret;
 
    pos = buf;
    end = buf + buflen;
//  ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
//            "flags / ssid\n");    - wjkim
//  if (ret < 0 || ret >= end - pos)
//      return pos - buf;
//  pos += ret;
 
    dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
        ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
                                end - pos);
        if (ret < 0 || ret >= end - pos)
            return pos - buf;
        pos += ret;
    }
 
    return pos - buf;
}

soft ap 모드로 동작하게 해주는 프로그램으로서, 오픈소스다. 최신 버전이 v2.0 이지만, realtek 에서 가이드 했던, v0.8.x 를 사용했다. 파일은 wpa_supplicant_hostapd-0.8-wjkim.tar 이다.
빌드방법은 아래와 같다.

#cd wpa_supplicant_hostapd-0.8/hostapd
#make

참고로 최신버전 역시 사용할 수 있다. hostapd-2.0-wjkim.tar 파일을 사용하면 된다. 필드 방법은 다음과 같다.

#cd hostapd-2.0/src
#make
#cd ../..
#cd hostapd-2.0/hostapd
#make
ctrl_interface=/var/run/wpa_supplicant
update_config=1
ap_scan=0
eapol_version=1

먼저 wpa_supplicant 시작 시 접속하도록 conf 파일을 이용한 방법이다.

ctrl_interface=/var/run/wpa_supplicant
update_config=1
ap_scan=0
eapol_version=1
 
network={
eapol_flags=0
key_mgmt=IEEE8021X
eap=TLS
identity="testing"
ca_cert="/home/fat81/certs/ca.pem"
client_cert="/home/fat81/certs/client.pem"
private_key="/home/fat81/certs/client.p12"
private_key_passwd="whatever"
}

다음은 wpa_cli 를 이용한 방법이다.

#!/bin/sh
 
wpa_cli -p /var/run/wpa_supplicant remove_network 0
wpa_cli -p /var/run/wpa_supplicant ap_scan 0
wpa_cli -p /var/run/wpa_supplicant add_network
wpa_cli -p /var/run/wpa_supplicant set_network 0 eapol_flags 0
wpa_cli -p /var/run/wpa_supplicant set_network 0 key_mgmt IEEE8021X
wpa_cli -p /var/run/wpa_supplicant set_network 0 eap TLS 
wpa_cli -p /var/run/wpa_supplicant set_network 0 identity '"testing"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 ca_cert '"/home/fat81/certs/ca.pem"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 client_cert '"/home/fat81/certs/client.pem"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 private_key '"/home/fat81/certs/client.p12"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 private_key_passwd '"whatever"'
wpa_cli -p /var/run/wpa_supplicant select_network 0

아래는 인자값을 입력받도록 수정한 것이다.

#!/bin/sh
 
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant remove_network 0
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant ap_scan 0
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant add_network
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 eapol_flags 0
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 key_mgmt IEEE8021X
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 eap TLS 
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 identity \"$1\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 ca_cert \"$2\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 client_cert \"$3\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 private_key \"$4\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 private_key_passwd \"$5\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant select_network 0

실행방법은 아래와 같다.

#./xxx testing /srv/wifi/bcm/supplicant/ca.pem /srv/wifi/bcm/supplicant/client.pem /srv/wifi/bcm/supplicant/client.p12 whatever
ctrl_interface=/var/run/wpa_supplicant

먼저 wpa_supplicant 가 시작할 때 자동으로 접속하도록 conf 파일의 예제다.

ctrl_interface=/var/run/wpa_supplicant
 
network={
    ssid="WIFI_DEV3"
    scan_ssid=1
    key_mgmt=WPA-EAP
    eap=PEAP
    identity="testing"
    password="password"
    phase1="peaplabel=0"
    phase2="auth=MSCHAPV2"
}

아래는 wpa_cli 명령어를 사용한 경우다.

wpa_cli -p /var/run/wpa_supplicant remove_network 0
wpa_cli -p /var/run/wpa_supplicant ap_scan 1
wpa_cli -p /var/run/wpa_supplicant add_network
wpa_cli -p /var/run/wpa_supplicant set_network 0 ssid '"WIFI_DEV3"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 scan_ssid 1 
wpa_cli -p /var/run/wpa_supplicant set_network 0 key_mgmt WPA-EAP
wpa_cli -p /var/run/wpa_supplicant set_network 0 eap PEAP
wpa_cli -p /var/run/wpa_supplicant set_network 0 identity '"testing"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 password '"password"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 phase1 '"peaplabel=0"'
wpa_cli -p /var/run/wpa_supplicant set_network 0 phase2 '"auth=MSCHAPV2"'
wpa_cli -p /var/run/wpa_supplicant select_network 0

다음은 인자를 입력받도록 수정한 것이다.

#!/bin/sh
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant remove_network 0
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant ap_scan 1
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant add_network
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 ssid \"$1\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 scan_ssid 1 
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 key_mgmt $2
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 eap PEAP
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 identity \"$3\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 password \"$4\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 phase1 '"peaplabel=0"'
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant set_network 0 phase2 \"auth=$5\"
/root/wpa_supplicant-2.0/wpa_supplicant/wpa_cli -p /var/run/wpa_supplicant select_network 0

실행방법은 다음과 같다.

#./zzz WIFI_DEV3 WPA-EAP testing password MSCHAPV2
  • computer/itx/wifi_관련_파일시스템_파일.txt
  • Last modified: 3 years ago
  • by likewind