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
    评论
1、因手头有一个7620N芯片的大功率无线路由器(万兴达WR5508商用路由),由于要使用无线广告营销功能,但在网上搜寻了很久,都没找到合适的固件。 2、可能有人会说支持7620方案的广告营销固件多的是,但这款路由器是大功率的,500mW,刷了海蜘蛛、RippleOS以及其他有wifidog功能的固件,无线超过3-5米就没有信号了。只有刷了openwrt和PandoraBox固件,无线信号超级强大,达到26db。 3、因此,只能使用openwrt和PandoraBox固件,查询了多种方法,都是需要对固件进行编译的,由于小弟不懂编程,只有通过网友们的安装配置经验进行参考,在刷好的固件基础上安装wifidog和Luci界面的配置,如果哪位高手能将Luci-wifidog源码打包成ipk安装包,小弟万分感谢!此方法仅供想玩wifidog的朋友参考,编程高手勿拍砖就行了! 方法: 1、安装wifidog(前提是路由器必须接入互联网) [root@PandoraBox:/root]#opkg update [root@PandoraBox:/root]#opkg install wifidog [root@PandoraBox:/root]#/etc/init.d/wifidog enable [root@PandoraBox:/root]#/etc/init.d/wifidog start 备注:安装wifidog可能需要依赖包 libc iptables-mod-extra iptables-mod-ipopt iptables-mod-nat-extra libpthread 2、安装配置luci-wifidog(luci-wifidog源码是在网上找的,别人已经设置好了的,如果不喜欢,自行到官网下) (1)使用winscp把源码controller文件夹下的内容复制到/usr/lib/lua/luci里目录的controller下,model放到model下 (2)源码root文件夹下的内容复制到root/etc下各自相应的目录下 (3)源码ipkg文件夹下的内容复制到/usr/lib/opkg目录下 (4)源码makefile文件复制到/etc下并给xxx权限 (5)最后重启路由器。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值