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, ð_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 + -
显示快捷键?