http://blog.csdn.net/NJZhuJinhua/archive/2010/04/11/5473970.aspx
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處。
hostapd 的main函數(shù)位于hostapd/hostapd.c中。
函數(shù)開(kāi)始是日志相關(guān)以及對(duì)命令行參數(shù)選項(xiàng)的處理。
- int main(int argc, char *argv[])
- {
- struct hapd_interfaces interfaces;
- int ret = 1, k;
- size_t i, j;
- int c, debug = 0, daemonize = 0, tnc = 0;
- char *pid_file = NULL;
- hostapd_logger_register_cb(hostapd_logger_cb);
- for (;;) {
- c = getopt(argc, argv, "BdhKP:tv");
- switch (c) {
- case 'h':
- usage();
- break;
- case 'd':
- debug++;
- if (wpa_debug_level > 0)
- wpa_debug_level--;
- break;
- case 'B':
- daemonize++;
- break;
- case 'K':
- wpa_debug_show_keys++;
- break;
- case 'P':
- os_free(pid_file);
- pid_file = os_rel2abs_path(optarg);
- break;
- case 't':
- wpa_debug_timestamp++;
- break;
- case 'v':
- show_version();
- exit(1);
- break;
- default:
- usage();
- break;
- }
后續(xù)不用代碼框了,csdn的博客中插入的代碼還不知道怎么修改,
h:調(diào)用usage()函數(shù),打印使用說(shuō)明
static void usage(void)
{
show_version();
fprintf(stderr,
"/n"
"usage: hostapd [-hdBKtv] [-P <PID file>] "
"<configuration file(s)>/n"
"/n"
"options:/n"
" -h show this usage/n"
" -d show more debug messages (-dd for even more)/n"
" -B run daemon in the background/n"
" -P PID file/n"
" -K include key data in debug messages/n"
" -t include timestamps in some debug messages/n"
" -v show hostapd version/n");
exit(1);
}
d:
case 'd':
debug++;
if (wpa_debug_level > 0)
wpa_debug_level--;
如果選項(xiàng)中每出現(xiàn)一個(gè)d則debug級(jí)別遞增,同時(shí)日志級(jí)別數(shù)字降低。
在src/utils/wpa_debug.c中有定義:
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
int wpa_debug_timestamp = 0;
這里enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR }; 其中MSG_INFO值為2,在該級(jí)別時(shí)正常情況下基本沒(méi)有日志輸出。
默認(rèn)級(jí)別就是MSG_INFO,因而要想獲得更多執(zhí)行流程中的輸出就需要增加debug級(jí)別。如果想把碼流及各radius屬性均打印出的話就將級(jí)別調(diào)為MSG_MSGDUMP=0吧。
【本系列分析中debug級(jí)別或日志級(jí)別越高指的是debug變量值越大,wpa_debug_level值越低。】
B:作為守護(hù)進(jìn)程運(yùn)行,
case 'B':
daemonize++;
break;
如果含有該選項(xiàng)則執(zhí)行os_daemonize(pid_file)
if (daemonize && os_daemonize(pid_file)) {
perror("daemon");
goto out;
}
在utils/os_win32.c中該函數(shù)未實(shí)現(xiàn)。
在utils/os_unix.c中定義為
int os_daemonize(const char *pid_file)
{
#ifdef __uClinux__
return -1;
#else /* __uClinux__ */
if (os_daemon(0, 0)) {
perror("daemon");
return -1;
}
if (pid_file) {
FILE *f = fopen(pid_file, "w");
if (f) {
fprintf(f, "%u/n", getpid());
fclose(f);
}
}
return -0;
#endif /* __uClinux__ */
}
其中os_daemon即為daemon系統(tǒng)調(diào)用。如果調(diào)用成功則獲取進(jìn)程id并寫入pid_file指定的文件中。
K:
case 'K':
wpa_debug_show_keys++;
break;
用于控制在調(diào)試時(shí)是否輸出密鑰相關(guān)key值。如需輸出密鑰還需要設(shè)置日志級(jí)別為MSG_DEBUG或以上
例如:
wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
challenge, len);
如果選項(xiàng)中沒(méi)有K顯式說(shuō)明,則即使日志級(jí)別為MSG_DEBUG或MSG_MSGDUMP也不會(huì)輸出的。
P:
case 'P':
os_free(pid_file);
pid_file = os_rel2abs_path(optarg);
break;
設(shè)定pid_file的值,os_rel2abs_path 將參數(shù)提供的相對(duì)路徑轉(zhuǎn)為絕對(duì)路徑。
t:
case 't':
wpa_debug_timestamp++;
break;
該項(xiàng)作用為在日志中包含時(shí)間戳信息。
wpa_debug_timestamp的定義參見(jiàn)選項(xiàng)d時(shí)的說(shuō)明,默認(rèn)值為0,即不包含。
帶時(shí)間戳效果為
1270995804.000000: EAP: EAP entering state RECEIVED
1270995804.000000: EAP: parseEapResp: rxResp=1 respId=77 respMethod=21 respVendor=0 respVendorMethod=0
1270995804.000000: EAP: EAP entering state INTEGRITY_CHECK
1270995804.000000: EAP: EAP entering state METHOD_RESPONSE
1270995804.000000: SSL: Received packet(len=176) - Flags 0x00
1270995804.000000: SSL: Received packet: Flags 0x0 Message Length 0
v
case 'v':
show_version();
exit(1);
break;
顯式版本號(hào)并退出。
static void show_version(void)
{
fprintf(stderr,
"hostapd v" VERSION_STR "/n"
"User space daemon for IEEE 802.11 AP management,/n"
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator/n"
"Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "
"and contributors/n");
}
#define VERSION_STR "0.6.10"
了解上述選項(xiàng)的設(shè)定,在隨后eap server的分離中可以直接設(shè)定時(shí)間戳,日志級(jí)別等。
下一節(jié)介紹hostapd啟動(dòng)時(shí)eap server相關(guān)的代碼。