📄 dhcp-client.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-client.c,v 1.36 2003/07/08 07:01:41 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"#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-guile.h"/* forward declarations of do_ routines. */static void do_version(char *interface);static void do_kill_client(char *interface);static void do_wake_client(char *interface);static void do_clear_cache(char *interface);static void do_client(char *interface);static void do_status(char *interface);/* command to string table. */const char *command_string[] = { "version", "kill", "wake", "clear", "do client"};/* table of functions indexed by command codes. */client_command commands[] = { do_version, /* print out version information. */ do_kill_client, /* kill client. */ do_wake_client, /* wake client. */ do_clear_cache, /* clear cache. */ do_client, /* initialize and run client. */ do_status, /* get status info. */};/* forward declaration for interface routines. */static char *interface_get_active(void);static char *interface_get_inactive(void);/* Our get interface sister routine. Different command codes will want to select interface on different criteria. We use this to manage it. */interface_lister get_interface[] = { NULL, /* version output needs nothing. */ interface_get_active, /* kill client. */ interface_get_active, /* wake client. */ interface_get_active, /* clear cache. */ interface_get_inactive, /* run client. */ interface_get_active, /* get status. */};/* client state dispatch: index constants in dhcp-client.h */client_state client_states[] = { client_init, client_init_reboot, client_requesting, client_renewing, client_rebinding, client_setup, client_bound, client_inform, client_shutdown, client_release, client_decline,};/* global vars affecting other code. */char *work_dir = DHCPLOCALSTATE_CLIENTDIR; /* our default working directory */#if !defined(HAVE_PROGNAME)const char *__progname;#endif /* HAVE_PROGNAME *//* local vars for dhcp-client. */static char *interface = NULL; /* the interface we're concerned with. */static unsigned char want_background = 1; /* whether we should go into the background. */static char *fake_hw_addr = NULL; /* if using fake hardware address set here. */static int promiscuous = 0; /* whether or not we're running in promiscious mode. *//* Utility routines. *//* initialize state per contents of cache. */static int initialize_client_state(dhcp_client_control_t *dc){ if(client_cache_is_empty(dc->cache)) { return STATE_INIT; } else /* if not empty we assume we can request the options. */ return STATE_INIT_REBOOT;}/* print usage info. */static void usage(char *s){ printf("usage: %s [-scpavkwt] [-l verbosity level] [-d directory]\n", s); printf("usage: %-*s [-i interface name] [ -m mac address ]\n", strlen(s), " "); exit(0);}/* print out version information and exit. */static void do_version(char *interface){ INFO_MESSAGE("%s version: %s\n", getprogname(), VERSION);}/* check for existing client. */static int client_process_exists(char *interface){ pid_t pid; if(file_get_pid(interface, &pid)) return 0; /* no pid file -- therefore no process. */#if !defined(KILL_SIGNAL_DETECT) /* if we can't detect it assume it is up since the PID file exists :| * issue warning though. */ WARN_MESSAGE("%s PID file exists please delete and kill process.", getprogname()); return 0;#else if(!kill(pid, 0)) return 1; else { file_delete_pid(interface); return 0; }#endif}/* wrapper around interface retrieval routines. *//* get active or inactive interfaces. */static char *interface_get_proc(int active){ char *first_interface; list_t *interface_list; if(active) interface_list = rawnet_list_active_interfaces(); else interface_list = rawnet_list_inactive_interfaces(); if(list_get_len(interface_list) == 0) { list_destroy(interface_list, xfree); return NULL; } first_interface = xstrdup(list_first(interface_list)); list_destroy(interface_list, xfree); return first_interface;}/* get interface which is active. */static char *interface_get_active(void){ return (interface_get_proc(1));}/* get interface which is inactive. */static char *interface_get_inactive(void){ return (interface_get_proc(0));}/* main loop: if only_setup is called we exit after setup -- * this is useful for running through the loop only long * enough to setup the interface. */static int do_client_dhcp_loop(int only_setup, dhcp_client_control_t *dc, int state){ while(1) { /* In between states we're clean. * * If we get interrupted inside a state * we still should be clean, but we don't * want to shutdown if we can help it. * * Handle any interrupts here. */ while(check_for_interrupts()) { switch (got_interrupt_type()) { case INTERRUPT_NONE: /* no more interrupts. we're done. */ break; case INTERRUPT_TERM: state = STATE_SHUTDOWN; break; case INTERRUPT_HUP: /* re-read configuration. */ INFO_MESSAGE("re-reading configuration"); if(client_conf_reread(dc->conf)) { WARN_MESSAGE("could not read configuration. using previous configuration."); } break; case INTERRUPT_ALARM: /* if alarm then check for timer type so we can set our state accordingly. */ switch (timer_get_current_id(dc->context->timer)) { case TIMER_RENEW: state = STATE_RENEW; break; case TIMER_IP_LEASE: state = STATE_INIT; break; case TIMER_REBIND: state = STATE_REBIND; break; default: FATAL_MESSAGE("invalid timer type caught. this is a bug. report me."); } break; default: FATAL_MESSAGE("invalid interrupt type caught. this is a bug. report me."); } } /* if we're only running to be setup, * return here. */ if((state == STATE_BOUND) && only_setup) { return state; } if(state == STATE_USER_INTERRUPT || state == STATE_NO_LEASES || state == STATE_FATAL_ERROR) state = STATE_SHUTDOWN; state = client_states[state] (dc); } return STATE_FATAL_ERROR; /* we should never get here, but if we do it's bad :) */}/* kill a running client. */static void do_kill_client(char *interface){ pid_t pid; INFO_MESSAGE("killing %s running on interface: %s", getprogname(), interface); if(file_get_pid(interface, &pid)) { ERROR_MESSAGE("could not get PID for client %s. maybe it's not running?", interface); return; } if(kill(pid, SIGTERM) < 0) { ERROR_MESSAGE("coud not send signal to client on interface: %s. maybe it's not running?", interface); return; } INFO_MESSAGE("killed client on pid: %u", pid); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -