udhcp源码剖析(五)——DHCP客户端重要的数据结构和初始化配置

来源:互联网 发布:淘宝访客平均价值 编辑:程序博客网 时间:2024/06/04 17:43

数据结构

和服务器类似,客户端也维护着一个全局的数据结构client_config,用于所有的DHCP服务。

struct client_config_t client_config = {    /* Default options. */    abort_if_no_lease: 0,    foreground: 0,    quit_after_lease: 0,    background_if_no_lease: 0,    interface: "eth0",    pidfile: NULL,    script: DEFAULT_SCRIPT,    clientid: NULL,    hostname: NULL,    ifindex: 0,    arp: "\0\0\0\0\0\0",        /* appease gcc-3.0 */};

该结构在dhcpc.h中定义,并在dhcpc.c中设置默认值

struct client_config_t client_config = {    /* Default options. */    abort_if_no_lease: 0,    foreground: 0,    quit_after_lease: 0,    background_if_no_lease: 0,    interface: "eth0",    pidfile: NULL,    script: DEFAULT_SCRIPT,    clientid: NULL,    hostname: NULL,    ifindex: 0,    arp: "\0\0\0\0\0\0",        /* appease gcc-3.0 */};

其它全局变量

其余所需要的重要的全局变量都以简单数据结构给出,并没有专门设计复杂结构。

static int state;static unsigned long requested_ip; /* = 0,请求的IP */static unsigned long server_addr;       //服务器地址static unsigned long timeout;       //租约超时时刻    static int packet_num; /* = 0 */        //可认为是连续重复发送数据包的次数static int fd;                  //本地socket监听的fdstatic int signal_pipe[2];          //本地接收signal消息的pipe fd

udhcpc_main的初始化和配置

dhcpc的初始化和dhcpd类似,但是简化了很多操作,并且添加了对传入参数的解析和处理。

解析arg选项

对启动时传递的arg选项的解析,通过这些选项,DHCP可以选择多种模式运行,比如传递参数q,即设置quit_after_lease=1,客户端将在成功获得lease之后退出。

enum {        OPT_c = 1 << 0,        OPT_C = 1 << 1,        OPT_V = 1 << 2,        OPT_f = 1 << 3,        OPT_b = 1 << 4,        OPT_H = 1 << 5,        OPT_h = 1 << 6,        OPT_F = 1 << 7,        OPT_i = 1 << 8,        OPT_n = 1 << 9,        OPT_p = 1 << 10,        OPT_q = 1 << 11,        OPT_R = 1 << 12,        OPT_r = 1 << 13,        OPT_s = 1 << 14,        OPT_T = 1 << 15,        OPT_t = 1 << 16,        OPT_v = 1 << 17,        OPT_S = 1 << 18,    };#if ENABLE_GETOPT_LONG    static const char udhcpc_longopts[] ALIGN1 =        "clientid\0"      Required_argument "c"        "clientid-none\0" No_argument       "C"        "vendorclass\0"   Required_argument "V"        "foreground\0"    No_argument       "f"        "background\0"    No_argument       "b"        "hostname\0"      Required_argument "H"        "hostname\0"      Required_argument "h"        "fqdn\0"          Required_argument "F"        "interface\0"     Required_argument "i"        "now\0"           No_argument       "n"        "pidfile\0"       Required_argument "p"        "quit\0"          No_argument       "q"        "release\0"       No_argument       "R"        "request\0"       Required_argument "r"        "script\0"        Required_argument "s"        "timeout\0"       Required_argument "T"        "version\0"       No_argument       "v"        "retries\0"       Required_argument "t"        "syslog\0"        No_argument       "S"        ;#endif    /* Default options. */    client_config.interface = "eth0";    client_config.script = DEFAULT_SCRIPT;    client_config.retries = 3;    client_config.timeout = 3;    /* Parse command line */    opt_complementary = "c--C:C--c" // mutually exclusive                        ":hH:Hh"; // -h and -H are the same#if ENABLE_GETOPT_LONG    applet_long_options = udhcpc_longopts;#endif    opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vS",        &str_c, &str_V, &str_h, &str_h, &str_F,        &client_config.interface, &client_config.pidfile, &str_r,        &client_config.script, &str_T, &str_t        );    if (opt & OPT_c)        client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0);    //if (opt & OPT_C)    if (opt & OPT_V)        client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);    if (opt & OPT_f)        client_config.foreground = 1;    if (opt & OPT_b)        client_config.background_if_no_lease = 1;    if (opt & OPT_h)        client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);    if (opt & OPT_F) {        client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);        /* Flags: 0000NEOS        S: 1 => Client requests Server to update A RR in DNS as well as PTR        O: 1 => Server indicates to client that DNS has been updated regardless        E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"        N: 1 => Client requests Server to not update DNS        */        client_config.fqdn[OPT_DATA + 0] = 0x1;        /* client_config.fqdn[OPT_DATA + 1] = 0; - redundant */        /* client_config.fqdn[OPT_DATA + 2] = 0; - redundant */    }    // if (opt & OPT_i) client_config.interface = ...    if (opt & OPT_n)        client_config.abort_if_no_lease = 1;    // if (opt & OPT_p) client_config.pidfile = ...    if (opt & OPT_q)        client_config.quit_after_lease = 1;    if (opt & OPT_R)        client_config.release_on_quit = 1;    if (opt & OPT_r)        requested_ip = inet_addr(str_r);    // if (opt & OPT_s) client_config.script = ...    if (opt & OPT_T)        client_config.timeout = xatoi_u(str_T);    if (opt & OPT_t)        client_config.retries = xatoi_u(str_t);    if (opt & OPT_v) {        printf("version %s\n", BB_VER);        return 0;    }    if (opt & OPT_S) {        openlog(applet_name, LOG_PID, LOG_LOCAL0);        logmode |= LOGMODE_SYSLOG;    }

读取接口信息和设置信号处理器

这一步和服务器的基本一致,注意这里的不同是对clientid的初始化,以及run_script。

    if (read_interface(client_config.interface, &client_config.ifindex,               NULL, client_config.arp))        return 1;    /* Make sure fd 0,1,2 are open */    bb_sanitize_stdio();    /* Equivalent of doing a fflush after every \n */    setlinebuf(stdout);    /* Create pidfile */    write_pidfile(client_config.pidfile);    /* if (!..) bb_perror_msg("cannot create pidfile %s", pidfile); */    /* Goes to stdout and possibly syslog */    bb_info_msg("%s (v%s) started", applet_name, BB_VER);    /* if not set, and not suppressed, setup the default client ID */    if (!client_config.clientid && !(opt & OPT_C)) {        client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);        client_config.clientid[OPT_DATA] = 1;        memcpy(client_config.clientid + OPT_DATA+1, client_config.arp, 6);    }    if (!client_config.vendorclass)        client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, "udhcp "BB_VER, 0);    /* setup the signal pipe */    udhcp_sp_setup();    state = INIT_SELECTING;    udhcp_run_script(NULL, "deconfig");    change_mode(LISTEN_RAW);    tv.tv_sec = 0;    goto jump_in;
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 北京公租房太小怎么办 申请公租房太小怎么办 房东电费收贵了怎么办 申请公租房工资超了怎么办 重庆公租房工资超了怎么办 公租房申请父母房子贷款怎么办 公产房父母去世办公证怎么办 动迁过程中承租人去世了怎么办 公租房的房间带阳台怎么办 公租房合同到期没有社保怎么办 租房合同没有到期违约了怎么办 租房户到期不搬怎么办 公租房摇号摇到了又怎么办 公租房被清退会怎么办 公租房摇不到号怎么办 公租房到期不搬怎么办 租房到期租客不搬怎么办 房产证面积与实际不符怎么办 社保晚交了1天怎么办 个人社保忘交了怎么办 个人社保晚交了怎么办 医保晚交了几天怎么办 辞职后转为灵活就业养老怎么办 公司名称变更提取不了公积金怎么办 五险合一软件已经减员怎么办 法人社保不在投标单位怎么办 换工作单位后社保怎么办 在北京孩子没有一老一小怎么办 深户小孩怎么办社保卡 社保卡没办下来去医院住院怎么办 老年社保卡丢了怎么办 外墙掉瓷砖伤车伤人怎么办 医保卡姓名弄错了怎么办 走工伤和走社保怎么办 公司在朝阳社保在海淀怎么办 公司没缴纳个税怎么办 报个税工资报少了怎么办 医院预约单丢了怎么办 肛瘘手术后太疼怎么办 低位保肛手术后吻合口瘘怎么办 做完痔疮手术后大便困难怎么办