dhcp-client-control.c

来自「this is sample about DHCP-agent」· C语言 代码 · 共 333 行

C
333
字号
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-client-control.c,v 1.19 2003/06/25 03:08:32 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. */#define MODULE_NAME "dhcp-client-control"#include "dhcp-local.h"#include "dhcp-limits.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"#include "dhcp-client-conf.h"#include "dhcp-cache-entry.h"#include "dhcp-client-cache.h"#include "dhcp-client.h"#include "dhcp-client-conf.h"/* Utility routines to update counters and time stamps. *//* Update seconds field for dhcp discover packets. */void dhcp_client_update_secs(dhcp_client_control_t *dc){    dc->secs = (time(NULL) - dc->started);    return;}/* reset started field for when we revert back to discover again. */void dhcp_client_reset_secs(dhcp_client_control_t *dc){    dc->started = time(NULL);    return;}/* dhcp set lease time to be infinite. */void dhcp_client_lease_time_is_infinite(dhcp_client_control_t *dc){    dc->lease_time_is_infinite = 1;}/* dhcp set lease time to be finite. */void dhcp_client_lease_time_is_finite(dhcp_client_control_t *dc){    dc->lease_time_is_infinite = 0;}/* create client id from a string in the format of xx:xx:xx:xx:xx:xx */static unsigned char *create_fake_client_id(unsigned char *mac_string){    unsigned char *s;    unsigned char mac_add[ETH_ADDR_LEN];    s = xmalloc(1 + ETH_ADDR_LEN);    *s = DLT_EN10MB;    s++;    if(hex_string_to_value(mac_string, mac_add)) {        ERROR_MESSAGE("malformed mac string %s", mac_string);        return NULL;    }    memcpy(s, mac_add, ETH_ADDR_LEN);    s--;    return s;}/* create a proper client id from the interface address passed. */static unsigned char *create_client_id(eth_addr_t interface_address){    unsigned char *s;    s = xmalloc(1 + ETH_ADDR_LEN);    *s = DLT_EN10MB;    s++;    memcpy(s, interface_address.data, ETH_ADDR_LEN);    s--;    return s;}/* dummy routine. we use this to manipulate conf/cache. */dhcp_client_control_t *dhcp_client_control_create_dummy(char *interface){    dhcp_client_control_t *dc;    dc = xmalloc(sizeof(dhcp_client_control_t));    memset(dc, 0, sizeof(dhcp_client_control_t));    dc->interface = xstrdup(interface);    return dc;}void dhcp_client_update_xid(dhcp_client_control_t *dc){    dc->xid = dhcp_gen_xid();    return;}/* create client control object */dhcp_client_control_t *dhcp_client_control_create(char *interface, int promiscuous, int clear_interface){    dhcp_client_control_t *dc;    int dport, sport;    stringbuffer_t *filter;    eth_addr_t interface_addr;#ifdef HAVE_UNAME    struct utsname utsname;    stringbuffer_t *sb;#endif                          /* HAVE_UNAME */    dc = xcalloc(sizeof(dhcp_client_control_t));    dc->state = 0;    dc->interface = xstrdup(interface);    dc->cache = client_cache_create(dc->interface);    dc->conf = create_client_conf(dc->interface);    if(dc->conf == NULL) {        ERROR_MESSAGE("while reading client conf.");        dhcp_client_control_destroy(dc);        return NULL;    }    /* Get port numbers from services db. */    dport = rawnet_port_for_service("bootps", "udp");    sport = rawnet_port_for_service("bootpc", "udp");    dport = ntohs(dport);    sport = ntohs(sport);    if(dport == -1 || sport == -1) {        WARN_MESSAGE            ("could not lookup dhcp services in service db (%s) will use reasonable defaults.");        sport = BOOTP_CLIENT;        dport = BOOTP_SERVER;    }    /* Create filter. */    filter = stringbuffer_create();    stringbuffer_aprintf(filter, "arp or icmp or (udp and src port %d)",                         dport);    if((dc->rawnet =        rawnet_create(interface, stringbuffer_getstring(filter), client_conf_get_default_mtu(dc->conf), sport, dport,                      promiscuous, clear_interface)) == NULL) {        ERROR_MESSAGE("could not acquire rawnet handler.");        dhcp_client_control_destroy(dc);        return NULL;    }    stringbuffer_destroy(filter);    /* Additional fields. */    /* server port. */    dc->server_port = dport; /* demoting an integer to an unsigned short *                              * -- should be fine for our purposes.      */    /* xid setting */    dhcp_client_update_xid(dc);    /* secs settings. */    dhcp_client_reset_secs(dc);    dhcp_client_update_secs(dc);#ifdef HAVE_UNAME    sb = stringbuffer_create();    uname(&utsname);    stringbuffer_aprintf(sb, "%s %s %s %s", utsname.sysname, utsname.nodename, utsname.release, utsname.version,                         utsname.machine);    dc->class_id = xstrdup(stringbuffer_getstring(sb));    stringbuffer_destroy(sb);#else                           /* HAVE_UNAME */    dc->class_id = xstrdup("Unknown");#endif                          /* HAVE_UNAME */    if(rawnet_get_hw_addr(dc->rawnet, &interface_addr)) {        ERROR_MESSAGE("could not acquire interface address.");        return NULL;    }    dc->client_id = create_client_id(interface_addr);    dc->lease_time_is_infinite = 0; /* reset lease time infinite bit. */    /* create state context */    dc->context = dhcp_client_control_context_create();    return dc;}/* use fake address in 0x:0x:0x:0x:0x we need to notify rawnet about this. * achtung: all packets _except_ dhcp packets will still use the real hardware address. */void dhcp_client_control_use_fake_hw_addr(dhcp_client_control_t *dc, char *fake_hw_addr){    char *new_client_id = create_fake_client_id(fake_hw_addr);    if(dc->client_id != NULL)        xfree(dc->client_id);    dc->client_id = new_client_id;    rawnet_use_fake_hw_addr(dc->rawnet, fake_hw_addr);    return;}/* destructor. */void dhcp_client_control_destroy(dhcp_client_control_t *dc){    if(dc->rawnet)        rawnet_destroy(dc->rawnet);    if(dc->cache)        client_cache_destroy(dc->cache);    if(dc->conf)        client_conf_destroy(dc->conf);    if(dc->interface)        xfree(dc->interface);    if(dc->class_id)        xfree(dc->class_id);    if(dc->client_id)        xfree(dc->client_id);    xfree(dc);}/* Context information.  This serves one purpose. It lets us * destroy the control, recreate it and copy back information we * cannot cache anywhere. */dhcp_client_control_context_t *dhcp_client_control_context_create(void){    dhcp_client_control_context_t *context = xcalloc(sizeof(dhcp_client_control_context_t));    context->timer = create_timer();    return context;}void dhcp_client_control_destroy_context(dhcp_client_control_context_t *context){    if(context->timer)        destroy_timer(context->timer);    xfree(context);    return;}dhcp_client_control_context_t *dhcp_client_control_copy_context(dhcp_client_control_t *dc){    dhcp_client_control_context_t *context;    context = dhcp_client_control_context_create();    /* copy individual fields over. */    memcpy(&context->sip_addr, &dc->context->sip_addr, IP_ADDR_LEN);    memcpy(&context->shw_addr, &dc->context->shw_addr, ETH_ADDR_LEN);    /* copy over the timer. */    context->timer = timer_copy(dc->context->timer);    return context;}void dhcp_client_control_set_context(dhcp_client_control_t *dc, dhcp_client_control_context_t *context){    dhcp_client_control_destroy_context(dc->context);    dc->context = context;    return;}/* set the server address. */void dhcp_client_set_server_ip_address(dhcp_client_control_t *dc, ip_addr_t ip_addr){    memcpy(&dc->context->sip_addr, &ip_addr, sizeof(ip_addr_t));    return;}void dhcp_client_set_server_hw_address(dhcp_client_control_t *dc, eth_addr_t eth_addr){    memcpy(&dc->context->shw_addr, &eth_addr, sizeof(eth_addr_t));    return;}/* get the server address. */ip_addr_t dhcp_client_get_server_ip_address(dhcp_client_control_t *dc){    return dc->context->sip_addr;}eth_addr_t dhcp_client_get_server_hw_address(dhcp_client_control_t *dc){    return dc->context->shw_addr;}

⌨️ 快捷键说明

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