wifidog中的wdctl命令

37 篇文章 3 订阅
20 篇文章 0 订阅

新的wifidog源码增加了wdctl的命令,看了一下,是一个很好命令行的模板。收藏!
wdctl.h文件

#ifndef _WDCTL_H_
#define _WDCTL_H_

#define DEFAULT_SOCK    "/tmp/wdctl.sock"

#define WDCTL_UNDEF     0
#define WDCTL_STATUS        1
#define WDCTL_STOP      2
#define WDCTL_KILL      3
#define WDCTL_RESTART   4

typedef struct {
    char *socket;
    int command;
    char *param;
} s_config;
#endif

wdctl.c文件:

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <syslog.h>
#include <errno.h>

#include "wdctl.h"

static s_config config;      //定义配置,是在wdctl.h中重新定义的s_config,而不是wifidog的config

static void usage(void);
static void init_config(void);
static void parse_commandline(int, char **);
static int connect_to_server(const char *);
static size_t send_request(int, const char *);
static void wdctl_status(void);
static void wdctl_stop(void);
static void wdctl_reset(void);
static void wdctl_restart(void);

/** @internal
 * @brief Print usage
 *
 * Prints usage, called when wdctl is run with -h or with an unknown option
 * usage函数,打印options和commands功用
 */
static void
usage(void)
{
    fprintf(stdout, "Usage: wdctl [options] command [arguments]\n");
    fprintf(stdout, "\n");
    fprintf(stdout, "options:\n");
    fprintf(stdout, "  -s <path>         Path to the socket\n");
    fprintf(stdout, "  -h                Print usage\n");
    fprintf(stdout, "\n");
    fprintf(stdout, "commands:\n");
    fprintf(stdout, "  reset [mac|ip]    Reset the specified mac or ip connection\n");
    fprintf(stdout, "  status            Obtain the status of wifidog\n");
    fprintf(stdout, "  stop              Stop the running wifidog\n");
    fprintf(stdout, "  restart           Re-start the running wifidog (without disconnecting active users!)\n");
    fprintf(stdout, "\n");
}

/** @internal
 *
 * Init default values in config struct
 * 初始化config  
 */
static void
init_config(void)
{

    config.socket = strdup(DEFAULT_SOCK); //初始化值 "/tmp/wdctl.sock"
    config.command = WDCTL_UNDEF;        //初始化值 0
}

/** @internal
 *
 * Uses getopt() to parse the command line and set configuration values
 * s使用getopt定义命令行
 */
void
parse_commandline(int argc, char **argv)
{
    extern int optind;
    int c;

    while (-1 != (c = getopt(argc, argv, "s:h"))) {
        switch (c) {
        case 'h':
            usage();
            exit(1);
            break;

        case 's':
            if (optarg) {
                free(config.socket);       // strdup初始化的值,这里释放后重新定义
                config.socket = strdup(optarg);
            }
            break;

        default:
            usage();
            exit(1);
            break;
        }
    }

    if ((argc - optind) <= 0) {          //命令行参数数目不对时打印usage
        usage();
        exit(1);
    }

    if (strcmp(*(argv + optind), "status") == 0) {    //command的值为 status 
        config.command = WDCTL_STATUS;
    } else if (strcmp(*(argv + optind), "stop") == 0) {   //command的值为 stop 
        config.command = WDCTL_STOP;
    } else if (strcmp(*(argv + optind), "reset") == 0) {     //command的值为 reset
        config.command = WDCTL_KILL;
        if ((argc - (optind + 1)) <= 0) {                 // conmmand值为 reset事 需要增加参数IP 或者MAC
            fprintf(stderr, "wdctl: Error: You must specify an IP " "or a Mac address to reset\n");
            usage();
            exit(1);
        } 
        config.param = strdup(*(argv + optind + 1));    //将config的param复制
    } else if (strcmp(*(argv + optind), "restart") == 0) {      // command的值为 restart 
        config.command = WDCTL_RESTART;
    } else {
        fprintf(stderr, "wdctl: Error: Invalid command \"%s\"\n", *(argv + optind));
        usage();
        exit(1);
    }
}

/*建立socket , 并建立网络连接*/
static int
connect_to_server(const char *sock_name)
{
    int sock;
    struct sockaddr_un sa_un;

    /* Connect to socket */
    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock < 0) {
        fprintf(stderr, "wdctl: could not get socket (Error: %s)\n", strerror(errno));
        exit(1);
    }
    memset(&sa_un, 0, sizeof(sa_un));
    sa_un.sun_family = AF_UNIX;
    strncpy(sa_un.sun_path, sock_name, (sizeof(sa_un.sun_path) - 1));

    if (connect(sock, (struct sockaddr *)&sa_un, strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) {
        fprintf(stderr, "wdctl: wifidog probably not started (Error: %s)\n", strerror(errno));
        exit(1);
    }

    return sock;
}

/*向对象终端发送写请求request,返回发送数据的大小*/
static size_t
send_request(int sock, const char *request)
{
    size_t len;
    ssize_t written;

    len = 0;
    while (len != strlen(request)) {
        written = write(sock, (request + len), strlen(request) - len);
        if (written == -1) {
            fprintf(stderr, "Write to wifidog failed: %s\n", strerror(errno));
            exit(1);
        }
        len += (size_t) written;
    }

    return len;
}

/*发送status, 网络读status并打印,以下函数类同*/
static void
wdctl_status(void)
{
    int sock;
    char buffer[4096];
    char request[16];
    ssize_t len;

    sock = connect_to_server(config.socket);

    strncpy(request, "status\r\n\r\n", 15);

    send_request(sock, request);

    // -1: need some space for \0!
    while ((len = read(sock, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[len] = '\0';
        fprintf(stdout, "%s", buffer);
    }

    shutdown(sock, 2);
    close(sock);
}

static void
wdctl_stop(void)
{
    int sock;
    char buffer[4096];
    char request[16];
    ssize_t len;

    sock = connect_to_server(config.socket);

    strncpy(request, "stop\r\n\r\n", 15);

    send_request(sock, request);

    while ((len = read(sock, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[len] = '\0';
        fprintf(stdout, "%s", buffer);
    }

    shutdown(sock, 2);
    close(sock);
}

void
wdctl_reset(void)
{
    int sock;
    char buffer[4096];
    char request[64];
    size_t len;
    ssize_t rlen;

    sock = connect_to_server(config.socket);

    strncpy(request, "reset ", 64);
    strncat(request, config.param, (64 - strlen(request) - 1));
    strncat(request, "\r\n\r\n", (64 - strlen(request) - 1));

    send_request(sock, request);

    len = 0;
    memset(buffer, 0, sizeof(buffer));
    while ((len < sizeof(buffer)) && ((rlen = read(sock, (buffer + len), (sizeof(buffer) - len))) > 0)) {
        len += (size_t) rlen;
    }

    if (strcmp(buffer, "Yes") == 0) {
        fprintf(stdout, "Connection %s successfully reset.\n", config.param);
    } else if (strcmp(buffer, "No") == 0) {
        fprintf(stdout, "Connection %s was not active.\n", config.param);
    } else {
        fprintf(stderr, "wdctl: Error: WiFiDog sent an abnormal " "reply.\n");
    }

    shutdown(sock, 2);
    close(sock);
}

static void
wdctl_restart(void)
{
    int sock;
    char buffer[4096];
    char request[16];
    ssize_t len;

    sock = connect_to_server(config.socket);

    strncpy(request, "restart\r\n\r\n", 15);

    send_request(sock, request);

    while ((len = read(sock, buffer, sizeof(buffer) - 1)) > 0) {
        buffer[len] = '\0';
        fprintf(stdout, "%s", buffer);
    }

    shutdown(sock, 2);
    close(sock);
}

/*主函数,初始化config,对照commanline输入的命令行的值,根据命令值选择对应的执行函数*/
int
main(int argc, char **argv)
{

    /* Init configuration */
    init_config();
    parse_commandline(argc, argv);

    switch (config.command) {
    case WDCTL_STATUS:
        wdctl_status();
        break;

    case WDCTL_STOP:
        wdctl_stop();
        break;

    case WDCTL_KILL:
        wdctl_reset();
        break;

    case WDCTL_RESTART:
        wdctl_restart();
        break;

    default:
        /* XXX NEVER REACHED */
        fprintf(stderr, "Oops\n");
        exit(1);
        break;
    }
    exit(0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安装和配置wifidog的步骤如下: 1.首先在OpenWRT路由器上安装wifidog,可以通过以下命令进行安装: ```shell opkg update opkg install wifidog ``` 2.安装完成后,需要进行配置。首先需要编辑wifidog的配置文件`/etc/config/wifidog`,可以使用vi或nano等编辑器进行编辑。在配置文件,需要设置以下几个参数: - `interface`: 设置wifidog所监听的网络接口,一般为无线接口,例如`wlan0`。 - `gateway_interface`: 设置wifidog所使用的网关接口,一般为有线接口,例如`eth0`。 - `auth_server`: 设置wifidog所连接的认证服务器的地址和端口号,例如`http://authserver.com:8080/wifidog/auth`。 - `auth_server_port`: 设置wifidog所连接的认证服务器的端口号,例如`8080`。 - `auth_server_path`: 设置wifidog所连接的认证服务器的路径,例如`/wifidog/auth`。 - `gateway_interface_ip`: 设置wifidog所使用的网关接口的IP地址,例如`192.168.1.1`。 - `check_interval`: 设置wifidog检查客户端是否在线的时间间隔,单位为秒,例如`30`。 3.配置完成后,需要启动wifidog服务。可以使用以下命令启动wifidog: ```shell /etc/init.d/wifidog start ``` 4.启动wifidog后,需要在防火墙添加相应的规则,以允许wifidog正常工作。可以使用以下命令添加规则: ```shell iptables -I zone_wan_input -p tcp --dport 80 -j ACCEPT iptables -I zone_wan_input -p udp --dport 53 -j ACCEPT iptables -I zone_wan_forward -p tcp --dport 80 -j ACCEPT iptables -I zone_wan_forward -p udp --dport 53 -j ACCEPT ``` 5.配置完成后,可以通过以下命令查看wifidog的状态: ```shell /etc/init.d/wifidog status ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值