diff --git a/config.c b/config.c index 06aac8c..05be7fc 100644 --- a/config.c +++ b/config.c @@ -26,11 +26,11 @@ static void configure_daemon_log_param(int daemon_mode) { g_prog_config.run_in_background = 0; set_log_destination(LOG_TO_CONSOLE); break; - case 1: case 2: g_prog_config.run_in_background = 1; set_log_destination(LOG_TO_CONSOLE); break; + case 1: case 3: g_prog_config.run_in_background = 1; set_log_file_path(g_prog_config.logfile); @@ -78,6 +78,41 @@ RESULT parse_cmdline_conf_file(int argc, char* argv[]) { return SUCCESS; } +#define _STR(x) #x +#define STR(x) _STR(x) +static void print_cmdline_help() { + PR_RAW( + "\t--help, -h\t显示本帮助\n" + "\t--kill, -k [1]\t终止其他实例并退出。加任意非 0 参数表示终止其他实例后继续进行认证\n" + "\t--save, -w\t保存本次认证所用参数\n" + "\t--username, -u <...>\t用户名\n" + "\t--password, -p <...>\t密码\n" + "\t--nic, -n <...>\t\t要使用的网络界面名\n" + "\t--stage-timeout, -t \t单个认证阶段的超时时间 [默认" STR(DEFAULT_STAGE_TIMEOUT) "]\n" + "\t--wait-after-fail, -r \t认证失败后重新认证前的等待时间(注意当服务器要求重新认证时将直接开始认证)[默认" STR(DEFAULT_WAIT_AFTER_FAIL_SECS) "]\n" + "\t--max-fail, -l \t最大允许认证失败次数 [默认" STR(DEFAULT_MAX_FAILURES) "]\n" + "\t--no-auto-reauth, -x\t认证掉线后不允许自动重连 [默认" STR(DEFAULT_RESTART_ON_LOGOFF) "]\n" + "\t--daemonize, -b <0-3>\t后台运行方式: [默认0]\n" + "\t\t\t\t0 = 不后台\n" + "\t\t\t\t1 = 后台运行,输出到当前控制台\n" + "\t\t\t\t2 = 同3,为保持兼容性而设\n" + "\t\t\t\t3 = 后台运行,输出到日志文件\n" + "\t--run-on-success, -c <...>\t认证完成后运行此命令 [默认无]\n" + "\t--dhcp-script <...>\t\t同上\n" + "\t--proxy-lan-iface, -z <...>\t代理认证时的 LAN 网络界面名 [默认无]\n" + "\t--auth-round, -j \t需要认证的次数 [默认1]\n" + "\t--max-retries \t最大超时重试的次数 [默认3]\n" + "\t--pid-file <...>\tPID 文件路径,设为none可禁用 [默认" DEFAULT_PIDFILE "]\n" + "\t--conf-file <...>\t配置文件路径 [默认" DEFAULT_CONFFILE "]\n" + "\t--if-impl <...>\t\t选择此网络操作抽象模块 [默认" DEFAULT_IF_IMPL "]\n" + "\t--pkt-plugin <...>\t启用此名称的数据包修改器 [默认无]\n" + "\t--module <...>\t\t同上\n" + ); + + packet_plugin_print_cmdline_help(); + exit(EXIT_SUCCESS); +} + RESULT parse_cmdline_opts(int argc, char* argv[]) { int opt = 0; int longIndex = 0; @@ -91,16 +126,15 @@ RESULT parse_cmdline_opts(int argc, char* argv[]) { { "username", required_argument, NULL, 'u' }, { "password", required_argument, NULL, 'p' }, { "nic", required_argument, NULL, 'n' }, - { "auth-timeout", required_argument, NULL, 't' }, + { "stage-timeout", required_argument, NULL, 't' }, { "wait-after-fail", required_argument, NULL, 'r' }, { "max-fail", required_argument, NULL, 'l' }, - { "no-auto-reauth", required_argument, NULL, 'x' }, + { "no-auto-reauth", no_argument, NULL, 'x' }, { "daemonize", required_argument, NULL, 'b' }, { "run-on-success", required_argument, NULL, 'c' }, /* They are */ { "dhcp-script", required_argument, NULL, 'c' }, /* both 'c' */ { "proxy-lan-iface", required_argument, NULL, 'z' }, { "auth-round", required_argument, NULL, 'j' }, - { "decode-config", required_argument, NULL, 'q' }, { "max-retries", required_argument, NULL, 0}, { "pid-file", required_argument, NULL, 0}, { "if-impl", required_argument, NULL, 0}, @@ -117,7 +151,8 @@ RESULT parse_cmdline_opts(int argc, char* argv[]) { while (opt != -1) { switch (opt) { case 'h': - //print_help(argv[0]); /* 调用本函数将退出程序 */ + print_cmdline_help(); /* 调用本函数将退出程序 */ + break; case 'k': if (optarg == NULL) g_prog_config.kill_type = KILL_ONLY; /* 结束其他实例并退出 */ @@ -137,7 +172,7 @@ RESULT parse_cmdline_opts(int argc, char* argv[]) { COPY_N_ARG_TO(g_prog_config.ifname, IFNAMSIZ); break; case 't': - g_prog_config.stage_timeout = atoi(optarg); /* 此处不设置限制,但原始的代码中有最大99秒的限制 */ + g_prog_config.stage_timeout = atoi(optarg); /* 此处不设置限制,但原始的代码中有最大99秒的限制 */ //TODO break; case 'r': g_prog_config.wait_after_fail_secs = atoi(optarg); /* 同上 */ @@ -146,7 +181,7 @@ RESULT parse_cmdline_opts(int argc, char* argv[]) { g_prog_config.max_failures = atoi(optarg); break; case 'x': - g_prog_config.restart_on_logoff = atoi(optarg); + g_prog_config.restart_on_logoff = 1; break; case 'b': daemon_mode = atoi(optarg) % 4; diff --git a/eap_state_machine.c b/eap_state_machine.c index 52b2d11..18f1dbf 100644 --- a/eap_state_machine.c +++ b/eap_state_machine.c @@ -213,6 +213,7 @@ static RESULT state_mach_process_failure(ETH_EAP_FRAME* frame) { } void eap_state_machine_recv_handler(ETH_EAP_FRAME* frame) { + /* Keep a copy of the frame, since if_impl may not hold it */ if (PRIV->last_recv_frame != NULL) { free_frame(&PRIV->last_recv_frame); } @@ -246,7 +247,7 @@ void eap_state_machine_recv_handler(ETH_EAP_FRAME* frame) { break; } } - packet_plugin_on_frame_received(frame); + packet_plugin_on_frame_received(PRIV->last_recv_frame); } static void state_watchdog(void* frame) { @@ -255,6 +256,7 @@ static void state_watchdog(void* frame) { } static RESULT trans_to_preparing(ETH_EAP_FRAME* frame) { + PR_INFO("MiniEAP " VERSION "已启动"); IF_IMPL* _if_impl = get_if_impl(); RESULT ret = switch_to_state(EAP_STATE_START_SENT, frame); _if_impl->start_capture(_if_impl); // Blocking... diff --git a/include/config.h b/include/config.h index ea8df58..11063f9 100644 --- a/include/config.h +++ b/include/config.h @@ -97,7 +97,7 @@ typedef struct _prog_config { * and timed access control. */ int restart_on_logoff; - #define DEFAULT_RESTART_ON_LOGOFF FALSE + #define DEFAULT_RESTART_ON_LOGOFF TRUE /* * Wait seconds after failure before next try. diff --git a/include/logging.h b/include/logging.h index 7fbe69c..195398f 100644 --- a/include/logging.h +++ b/include/logging.h @@ -33,6 +33,9 @@ #define PR_DBG(...) \ print_log("D", FUNC_NAME, __VA_ARGS__); +#define PR_RAW(...) \ + print_log_raw(__VA_ARGS__) + typedef enum _LOG_DESTINATION { LOG_TO_FILE, LOG_TO_CONSOLE diff --git a/include/minieap_common.h b/include/minieap_common.h index 20dd64d..a9418d2 100644 --- a/include/minieap_common.h +++ b/include/minieap_common.h @@ -1,6 +1,8 @@ #ifndef _MINIEAP_MINIEAP_COMMON_H #define _MINIEAP_MINIEAP_COMMON_H +#define VERSION "0.91" + typedef enum _function_result { SUCCESS = 0, FAILURE = -1 diff --git a/include/packet_plugin.h b/include/packet_plugin.h index b4d5d3e..4d78cfb 100644 --- a/include/packet_plugin.h +++ b/include/packet_plugin.h @@ -10,7 +10,7 @@ typedef struct _packet_plugin { * Can be used to free memory. */ void (*destroy)(struct _packet_plugin* this); - + /* * Called by main program when command line options are available. * Can be used to initialize custom options. @@ -18,7 +18,7 @@ typedef struct _packet_plugin { * Return: if there is any error during the process (malformed value, etc) */ RESULT (*process_cmdline_opts)(struct _packet_plugin* this, int argc, char* argv[]); - + /* * Called by main program when it knows the config file path. * Can be used to read from config file. @@ -30,26 +30,31 @@ typedef struct _packet_plugin { * Return: if there is any error during the process (malformed value, etc) */ RESULT (*process_config_file)(struct _packet_plugin* this, const char* filepath); - + /* * Validate the parameters (from config file or overriden by cmdline) * * Return: if all mandatory params are valid/not null */ RESULT (*validate_params)(struct _packet_plugin* this); - + + /* + * Print credit / version info + */ + void (*print_banner)(struct _packet_plugin* this); + /* * Load the defaults * * Return: if all mandatory params are valid/not null */ void (*load_default_params)(struct _packet_plugin* this); - + /* * Called by main program when printing help for command line options. */ void (*print_cmdline_help)(struct _packet_plugin* this); - + /* * Called by main program when the main program finishes filling * the standard ethernet and EAP(OL) fields in a ready-to-send frame. @@ -66,24 +71,29 @@ typedef struct _packet_plugin { * Return: if the frame is processed successfully */ RESULT (*on_frame_received)(struct _packet_plugin* this, ETH_EAP_FRAME* frame); - + /* * Sets the round number we are currently in. * This is useful in double authentication, where frames in round 1 and round 2 * require different fields. */ void (*set_auth_round)(struct _packet_plugin* this, int round); - + /* * Plugin name, to be selected by user */ char* name; - + /* * Description, displayed to user */ char* description; - + + /* + * Version string, displayed to user + */ + char* version; + /* * Packet plugin internal use */ @@ -100,6 +110,7 @@ RESULT select_packet_plugin(const char* name); void packet_plugin_destroy(); RESULT packet_plugin_process_cmdline_opts(int argc, char* argv[]); RESULT packet_plugin_validate_params(); +void packet_plugin_print_banner(); void packet_plugin_load_default_params(); RESULT packet_plugin_process_config_file(char* filepath); void packet_plugin_print_cmdline_help(); diff --git a/minieap.c b/minieap.c index 2b17c42..62c6bcc 100644 --- a/minieap.c +++ b/minieap.c @@ -81,6 +81,9 @@ static int init_cfg(int argc, char* argv[]) { init_if_impl_list(); init_packet_plugin_list(); + PR_RAW("MiniEAP " VERSION "\n" + "Hamster Tian, 2016\n\n"); + load_default_params(); if (IS_FAIL(init_program_config(argc, argv))) { PR_ERR("参数初始化错误"); @@ -94,6 +97,7 @@ static int init_cfg(int argc, char* argv[]) { return FAILURE; } + packet_plugin_print_banner(); packet_plugin_load_default_params(); if (IS_FAIL(init_plugin_config(argc, argv))) { PR_ERR("插件初始化错误"); diff --git a/packet_plugin/packet_plugin.c b/packet_plugin/packet_plugin.c index cb610bb..5393de7 100644 --- a/packet_plugin/packet_plugin.c +++ b/packet_plugin/packet_plugin.c @@ -26,7 +26,8 @@ int init_packet_plugin_list() { int i = 0; for (; i < sizeof(list) / sizeof(PACKET_PLUGIN*); ++i) { PACKET_PLUGIN* (*func)() = list[i]; - insert_data(&g_packet_plugin_list, func()); + PACKET_PLUGIN* instance = func(); + insert_data(&g_packet_plugin_list, instance); } return i; } @@ -150,3 +151,12 @@ void packet_plugin_set_auth_round(int round) { PLUGIN->set_auth_round(PLUGIN, round); } while ((plugin_info = plugin_info->next)); } + +void packet_plugin_print_banner() { + LIST_ELEMENT *plugin_info = g_active_packet_plugin_list; + if (g_active_packet_plugin_list == NULL) return; + do { + CHK_FUNC(PLUGIN->print_banner); + PLUGIN->print_banner(PLUGIN); + } while ((plugin_info = plugin_info->next)); +} diff --git a/packet_plugin/rjv3/packet_plugin_rjv3.c b/packet_plugin/rjv3/packet_plugin_rjv3.c index ce780cb..b2cf362 100644 --- a/packet_plugin/rjv3/packet_plugin_rjv3.c +++ b/packet_plugin/rjv3/packet_plugin_rjv3.c @@ -222,6 +222,12 @@ RESULT rjv3_process_config_file(struct _packet_plugin* this, const char* filepat return SUCCESS; // TODO } +static void packet_plugin_rjv3_print_banner() { + PR_INFO("\nRJv3 for MiniEAP " VERSION "\n" + "V3 校验算法来自 hyrathb@GitHub\n" + "Hamster Tian, 2016\n\n"); +} + PACKET_PLUGIN* packet_plugin_rjv3_new() { PACKET_PLUGIN* this = (PACKET_PLUGIN*)malloc(sizeof(PACKET_PLUGIN)); if (this < 0) { @@ -240,8 +246,10 @@ PACKET_PLUGIN* packet_plugin_rjv3_new() { this->name = "rjv3"; this->description = "来自 hyrathb@GitHub 的 Ruijie V3 验证算法"; + this->version = PACKET_PLUGIN_RJV3_VER_STR; this->destroy = rjv3_destroy; this->process_cmdline_opts = rjv3_process_cmdline_opts; + this->print_banner = packet_plugin_rjv3_print_banner; this->load_default_params = rjv3_load_default_params; this->print_cmdline_help = rjv3_print_cmdline_help; this->prepare_frame = rjv3_prepare_frame; diff --git a/packet_plugin/rjv3/packet_plugin_rjv3.h b/packet_plugin/rjv3/packet_plugin_rjv3.h index e1e1cfb..44f15ad 100644 --- a/packet_plugin/rjv3/packet_plugin_rjv3.h +++ b/packet_plugin/rjv3/packet_plugin_rjv3.h @@ -3,6 +3,8 @@ #include "packet_plugin.h" +#define PACKET_PLUGIN_RJV3_VER_STR "0.90" + #define DEFAULT_HEARTBEAT_INTERVAL 60 #define DEFAULT_SERVICE_NAME "internet" #define DEFAULT_VER_STR "RG-SU For Linux V1.0"