⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp-client-states.c

📁 this is sample about DHCP-agent
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-client-states.c,v 1.44 2003/06/28 17:50:06 actmodern Exp $ *  * Copyright 2002 Thamer Alharbash <tmh@whitefang.com> *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *  * These are the individual client state functions,  * along with their utility routines. *  */#define MODULE_NAME "dhcp-client-states"#include "dhcp-local.h"#include "dhcp-limits.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"#include "dhcp-option.h"#include "dhcp-options-strings.h"#include "dhcp-client-conf.h"#include "dhcp-client-cache.h"#include "dhcp-client.h"#include "dhcp-sysconf.h"/*************************** * option list generation  * ***************************//* create DISCOVER and REQUEST option list. */static list_t *client_build_option_list(dhcp_client_control_t *dc){    list_t *options;    dhcp_opt_t *option;    char *hostname_tmp;    const char *hostname;    uint16_t max_message_opt_data = MAX_MESSAGE_SIZE;    options = list_create();    option = dhcp_opt_create_from_internal_data(TAG_DHCP_MAX_DHCP_SIZE, &max_message_opt_data,                                                 sizeof(max_message_opt_data));    list_add(options, option);    /* client_id */    option = dhcp_opt_create_from_internal_data(TAG_DHCP_CLIENT_ID, dc->client_id, (ETH_ADDR_LEN + 1));    list_add(options, option);    /* class_id */    option = dhcp_opt_create_from_internal_data(TAG_DHCP_VENDOR_CLASS_ID, dc->class_id, (strlen(dc->class_id) + 1));    list_add(options, option);    /* hostname if available */    hostname = client_conf_get_hostname(dc->conf);    if(hostname != NULL) {        /* if we have one set it. */        /* can't pass const char pointer so copy to char pointer.         * FIXME: audit types and fix any const propogation         * problems like these properly. */        hostname_tmp = xstrdup(hostname);        option = dhcp_opt_create_from_internal_data(TAG_DHCP_HOST_NAME, hostname_tmp, (strlen(hostname_tmp) + 1));        xfree(hostname_tmp);        list_add(options, option);    }    return options;}/* create DHCP DISCOVER option list. */static list_t *client_build_discover_option_list(dhcp_client_control_t *dc){    list_t *options;    list_t *requested_options;    dhcp_opt_t *option;    options = list_create();    option = dhcp_opt_create_parameter_request_list(client_conf_get_request_opt_bit_array(dc->conf));    if(option == NULL) {        WARN_MESSAGE("sending without parameter request list");    } else {        list_add(options, option);    }    /* dhcp message type. */    option = dhcp_opt_create_message_type(DHCP_DISCOVER_TM);    list_add(options, option);    requested_options = client_build_option_list(dc);    list_join(options, requested_options); /* this destroys requested_options */    return options;}/* create DHCP REQUEST option list. */static list_t *client_build_request_option_list(dhcp_client_control_t *dc){    list_t *options;    list_t *requested_options;    dhcp_opt_t *option;    options = list_create();    /* dhcp message type. */    option = dhcp_opt_create_message_type(DHCP_REQUEST_TM);    list_add(options, option);    requested_options = client_build_option_list(dc);    list_join(options, requested_options); /* this destroys requested_options */    return options;}/* create DHCP RELEASE option list. */static list_t *client_build_release_option_list(dhcp_client_control_t *dc){    list_t *options;    dhcp_opt_t *option;    options = list_create();    /* client_id: RFC2131 says we MAY */    option = dhcp_opt_create_from_internal_data(TAG_DHCP_CLIENT_ID, dc->client_id, (ETH_ADDR_LEN + 1));    list_add(options, option);    /* dhcp message type. */    option = dhcp_opt_create_message_type(DHCP_RELEASE_TM);    list_add(options, option);    return options;}static list_t *client_build_decline_option_list(dhcp_client_control_t *dc, ip_addr_t ip_address){    list_t *options;    dhcp_opt_t *option;    options = list_create();    /* client_id: RFC2131 says we MAY */    option = dhcp_opt_create_from_internal_data(TAG_DHCP_CLIENT_ID, dc->client_id, (ETH_ADDR_LEN + 1));    list_add(options, option);    /* requested ip address: RFC2131 MUST. */    option = dhcp_opt_create_from_internal_data(TAG_DHCP_REQUESTED_IP_ADDRESS, &ip_address, IP_ADDR_LEN);    list_add(options, option);    /* dhcp message type. */    option = dhcp_opt_create_message_type(DHCP_DECLINE_TM);    list_add(options, option);    return options;}/* create DHCP RENEW option list. */static list_t *client_build_renew_option_list(dhcp_client_control_t *dc){    list_t *options;    dhcp_opt_t *option;    options = list_create();    /* dhcp message type. */    option = dhcp_opt_create_message_type(DHCP_REQUEST_TM);    list_add(options, option);    /* client_id */    option = dhcp_opt_create_from_internal_data(TAG_DHCP_CLIENT_ID, dc->client_id, (ETH_ADDR_LEN + 1));    list_add(options, option);    return options;}/* create DHCP REBIND option list. */static list_t *client_build_rebind_option_list(dhcp_client_control_t *dc){    /* just call renew_option_list since it's the same. */    return (client_build_renew_option_list(dc));}/************* * ARP/UNARP * *************//*  * Use this to send out a broadcast reply claiming that we own the * IP. To prevent a poisoned cache we use the actual interface hw * addr as opposed to any fake one we may have been passed. *  */static int client_broadcast_arp_reply(dhcp_client_control_t *dc, ip_addr_t client_ip_addr){    eth_addr_t client_hw_addr;    client_ip_addr = rawnet_get_ip_addr(dc->rawnet);    rawnet_get_real_hw_addr(dc->rawnet, &client_hw_addr);    build_arp_reply_broadcast(dc->rawnet, client_ip_addr, client_hw_addr);    if(rawnet_send_packet(dc->rawnet) < 0) {        ERROR_MESSAGE("could not transmit arp reply.");        return -1;    }    return 0;}/* UNARP (rfc 1868). This makes us more network friendly. */static int client_broadcast_unarp(dhcp_client_control_t *dc){    ip_addr_t client_ip_addr;    eth_addr_t client_hw_addr;    client_ip_addr = rawnet_get_ip_addr(dc->rawnet);    rawnet_get_real_hw_addr(dc->rawnet, &client_hw_addr);    build_unarp(dc->rawnet, client_ip_addr, client_hw_addr);    if(rawnet_send_packet(dc->rawnet) < 0) {        ERROR_MESSAGE("could not transmit unarp.");        return -1;    }    return 0;}/*************************** * utility routines        * ***************************//* update secs field. can be called from rawnet_packet_transact */static void client_update_packet(void *arg){    dhcp_client_control_t *dc = arg;    dhcp_client_update_secs(dc);    rawnet_dhcp_update(dc->rawnet, (uint16_t)dc->secs); /* FIXME: this may be an integer overflow. */    return;}/* setup our timers. */static void client_setup_timers(dhcp_client_control_t *dc){    list_t *timer_options;    timer_options = client_cache_load_timer_options(dc->cache, 0);    if(list_get_len(timer_options) == 0) {        FATAL_MESSAGE("no timers to setup. we should have least one: lease time");        exit(1);    }    do_sysconf_setup_timers(timer_options, dc);    dhcp_opt_destroy_option_list(timer_options);    return;}static time_t compensate_timeout_with_timer(dhcp_client_control_t *dc){    uint32_t next_timer;    time_t timeout;    /* we realize time_t may not be uint32_t, however we're only     * going to set the max timeout if it is lower so this is     * safe. we shouldn't overflow. */    next_timer = timer_peek_next_timer(dc->context->timer);    if(next_timer < RECOMMENDED_MAX_SECS_WAIT) {        if(next_timer != 0)            timeout = next_timer / 2;        else            timeout = next_timer;    } else {        timeout = RECOMMENDED_MAX_SECS_WAIT;    }   return timeout;}/* make a new copy without options which are meant for protocol purposes only. */static list_t *client_remove_protocol_only_options(list_t *options){    dhcp_opt_t *option, *option_copy;    list_t *non_protocol_opts;    non_protocol_opts = list_create();    list_rewind(options);    while((option = list_next(options)) != NULL) {        switch(dhcp_opt_get_tag(option)) {        case TAG_DHCP_MAX_DHCP_SIZE:        case TAG_DHCP_MESSAGE_TYPE:        case TAG_DHCP_OVERLOAD:            break;        default:            option_copy = dhcp_option_copy(option);            list_add(non_protocol_opts, option_copy);            break;        }    }    return non_protocol_opts;}/* utility routine that should zap our configuration and leave us * with an interface with no real address on it. */static void client_unconfigure(dhcp_client_control_t *dc){    list_t *options;    ip_addr_t ip_addr;    /* load our cache and call sysconf with DO_SHUTDOWN to     * unconfigure us. */    options = client_cache_load_options(dc->cache, 0);    do_sysconf(options, dc, STATE_SHUTDOWN);    dhcp_opt_destroy_option_list(options);    ip_addr = rawnet_get_ip_addr(dc->rawnet);    /* check if we have a real address or not. */    if(ip_addr != 0) {        /* call UNARP first. */        client_broadcast_unarp(dc);        /* zap our ip address. */        rawnet_interface_up(dc->rawnet, 0, 0, CLIENT_DEFAULT_MTU, 1);    }    /* we're done. */    return;}/* this is called from setup: we should have a lease in our cache. */static int client_configure(dhcp_client_control_t *dc){    list_t *options;    ip_addr_t interface_ip;    ip_addr_t *passed_ip = NULL;    eth_addr_t eth_addr;    dhcp_opt_t *option;    INFO_MESSAGE("performing system configuration");    options = client_cache_load_options(dc->cache, 0);    if(list_get_len(options) == 0) {        ERROR_MESSAGE("received empty configuration cache! cannot configure host");        return STATE_FATAL_ERROR;    }    /* Check if the address we've been assigned is in use.  only     * check if our interface address does not match the address     * in our lease cache.*/    interface_ip = rawnet_get_ip_addr(dc->rawnet);    list_rewind(options);    while((option = list_next(options)) != NULL) {        if(dhcp_opt_get_tag(option) == TAG_DHCP_REQUESTED_IP_ADDRESS) {            passed_ip = dhcp_opt_get_host_data(option);            break;        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -