hostapd的radius/eap server代码分析(1)-main
NJZhuJinhua@csdn Apr.10,2010
http://blog.csdn.net/NJZhuJinhua/archive/2010/04/11/5473970.aspx
欢迎转载,转载请注明出处。
hostapd 的main函数位于hostapd/hostapd.c中。
函数开始是日志相关以及对命令行参数选项的处理。
- 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;
- }
后续不用代码框了,csdn的博客中插入的代码还不知道怎么修改,
h:调用usage()函数,打印使用说明
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--;
如果选项中每出现一个d则debug级别递增,同时日志级别数字降低。
在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,在该级别时正常情况下基本没有日志输出。
默认级别就是MSG_INFO,因而要想获得更多执行流程中的输出就需要增加debug级别。如果想把码流及各radius属性均打印出的话就将级别调为MSG_MSGDUMP=0吧。
【本系列分析中debug级别或日志级别越高指的是debug变量值越大,wpa_debug_level值越低。】
B:作为守护进程运行,
case 'B':
daemonize++;
break;
如果含有该选项则执行os_daemonize(pid_file)
if (daemonize && os_daemonize(pid_file)) {
perror("daemon");
goto out;
}
在utils/os_win32.c中该函数未实现。
在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系统调用。如果调用成功则获取进程id并写入pid_file指定的文件中。
K:
case 'K':
wpa_debug_show_keys++;
break;
用于控制在调试时是否输出密钥相关key值。如需输出密钥还需要设置日志级别为MSG_DEBUG或以上
例如:
wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
challenge, len);
如果选项中没有K显式说明,则即使日志级别为MSG_DEBUG或MSG_MSGDUMP也不会输出的。
P:
case 'P':
os_free(pid_file);
pid_file = os_rel2abs_path(optarg);
break;
设定pid_file的值,os_rel2abs_path 将参数提供的相对路径转为绝对路径。
t:
case 't':
wpa_debug_timestamp++;
break;
该项作用为在日志中包含时间戳信息。
wpa_debug_timestamp的定义参见选项d时的说明,默认值为0,即不包含。
带时间戳效果为
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;
显式版本号并退出。
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"
了解上述选项的设定,在随后eap server的分离中可以直接设定时间戳,日志级别等。
下一节介绍hostapd启动时eap server相关的代码。