[Dhcp-agent-commits] dhcp-agent THANKS,1.7,1.8 TODO,1.20,1.21 acinclude.m4,1.6,1.7 aclocal.m4,1.6,1.
Status: Alpha
Brought to you by:
actmodern
Update of /cvsroot/dhcp-agent/dhcp-agent In directory usw-pr-cvs1:/tmp/cvs-serv11220 Modified Files: THANKS TODO acinclude.m4 aclocal.m4 configure.in dhcp-agent.h dhcp-client.c dhcp-interface.c Log Message: revamped dhcp-client.c to be able to retrieve interfaces automatically; changed message in kill(0,pid) test; added more to dhcp-interface.c; added more to TODO list; Index: THANKS =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/THANKS,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** THANKS 6 Jun 2002 23:59:00 -0000 1.7 --- THANKS 11 Jun 2002 01:50:27 -0000 1.8 *************** *** 16,19 **** -- Bill Traynor for Solaris x86. ! -- Brian J. Kifiak for OpenBSD help/testing and helpful suggestions. ! --- 16,18 ---- -- Bill Traynor for Solaris x86. ! -- Brian J. Kifiak for assisting in development. Index: TODO =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/TODO,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** TODO 6 Jun 2002 03:25:04 -0000 1.20 --- TODO 11 Jun 2002 01:50:27 -0000 1.21 *************** *** 6,15 **** extend over 255 octets) major todos: ! -- make dhcpclient relay agent friendly. -- write dhcpserver -- write dhcpstat -- write dhcpdiscover other todo: --- 6,24 ---- extend over 255 octets) + probably many more to come once the rest of the todos are + complete. currently the client seems to be behaving properly. + major todos: ! -- make dhcpclient relay agent friendly ! -- check rfcs for any catch 22s -- write dhcpserver + -- need a seperate machine to do proper testing. -- write dhcpstat + a command line utility to perform pretty output on + the dhcp client's cache and status. -- write dhcpdiscover + a scanner to output information on servers/relay agents + responding other todo: *************** *** 21,36 **** -- check for duplicates in configure.in and compress them (for example -I and -L flags should not be repeated.) -- add cleanup handlers to down routes, interfaces, etc. ! -- good idea to add config file handlers in sysconf array so ! config files can be handled. instead of doing it explicitly. ! -- proper error handling in packet objects. possibly generic codes with ! an error buff (?). -- add a isascii() and a strcasecmp() for portability - -- redo dhcp-client-conf to be better. -- dhcp_option should be called dhcp_option_t -- rawnet_is_valid needs more checks. -- client_discover_offer() should update its timeout when receiving unwanted packets. -- implement decline, and inform in the client. -- add check in validate_to_string for conformity with DHCP RFC on character set. --- 30,75 ---- -- check for duplicates in configure.in and compress them (for example -I and -L flags should not be repeated.) + -- add cleanup handlers to down routes, interfaces, etc. ! dhcp-sysconf needs to be redone to allow the following: ! ! * configure an option for the system. ! * register a routine to be run after the initial ! configuration is done -- ! useful for copying files around or delaying ! a certain setting till an earlier one is complete. ! * clean up the option for the system. ! useful for deleting or removing settings ! which are persistant (config files no longer valid) ! ! * add ability to run external program with option string ! passed to it via exec() ! ! * add special minimalist shell which has few and well defined ! metacharacters called dhcpsysconf. and allow system configuration ! to be done through it. ! -- add a isascii() and a strcasecmp() for portability -- dhcp_option should be called dhcp_option_t -- rawnet_is_valid needs more checks. + + * actually this needs to be reviewed more carefully. + we're currently using a lot of validity checks + in many places which is good, but they should all be + complete in their own domain. these domains need to be + defined. + -- client_discover_offer() should update its timeout when receiving unwanted packets. + + the rawnet_transact() routine should be replaced with something + that is more flexible in timing out while not even considering + invalid packets. Mayhaps reading the next packet could be done + with a high level filter. + -- implement decline, and inform in the client. + + as per RFC2131 + -- add check in validate_to_string for conformity with DHCP RFC on character set. *************** *** 41,48 **** -- be nice to servers. sort the list according to option tag value. the highest value first seems about right. - -- current rule is to malloc to keep local copies in each - data structure/module. this isn't too effecient. - clean up in areas where it seems prudent. or come up - with guidelines we can stick to. -- rawnet and the dhcp client control are foobared by a fake mac address. check, fix, clean. --- 80,83 ---- Index: acinclude.m4 =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/acinclude.m4,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** acinclude.m4 10 Jun 2002 23:15:20 -0000 1.6 --- acinclude.m4 11 Jun 2002 01:50:27 -0000 1.7 *************** *** 156,160 **** AC_DEFUN(AC_WF_CHECK_KILL_SIGNAL_DETECT, ! [AC_MSG_CHECKING(if kill can be used to detect a process that can be signaled) AC_TRY_RUN([ /* Check the behaviour of kill(pid, 0). --- 156,160 ---- AC_DEFUN(AC_WF_CHECK_KILL_SIGNAL_DETECT, ! [AC_MSG_CHECKING('if kill(0, pid) can be used to detect a process) AC_TRY_RUN([ /* Check the behaviour of kill(pid, 0). Index: aclocal.m4 =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/aclocal.m4,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** aclocal.m4 10 Jun 2002 23:15:20 -0000 1.6 --- aclocal.m4 11 Jun 2002 01:50:27 -0000 1.7 *************** *** 1,5 **** ! dnl aclocal.m4 generated automatically by aclocal 1.4-p5 ! dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, --- 1,5 ---- ! dnl aclocal.m4 generated automatically by aclocal 1.4-p4 ! dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, *************** *** 168,172 **** AC_DEFUN(AC_WF_CHECK_KILL_SIGNAL_DETECT, ! [AC_MSG_CHECKING(if kill can be used to detect a process that can be signaled) AC_TRY_RUN([ /* Check the behaviour of kill(pid, 0). --- 168,172 ---- AC_DEFUN(AC_WF_CHECK_KILL_SIGNAL_DETECT, ! [AC_MSG_CHECKING('if kill(0, pid) can be used to detect a process) AC_TRY_RUN([ /* Check the behaviour of kill(pid, 0). *************** *** 225,229 **** dnl AM_INIT_AUTOMAKE(package,version, [no-define]) ! AC_DEFUN([AM_INIT_AUTOMAKE], [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] --- 225,229 ---- dnl AM_INIT_AUTOMAKE(package,version, [no-define]) ! AC_DEFUN(AM_INIT_AUTOMAKE, [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] *************** *** 253,257 **** # ! AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case --- 253,257 ---- # ! AC_DEFUN(AM_SANITY_CHECK, [AC_MSG_CHECKING([whether build environment is sane]) # Just in case *************** *** 294,298 **** dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. ! AC_DEFUN([AM_MISSING_PROG], [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if --- 294,298 ---- dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. ! AC_DEFUN(AM_MISSING_PROG, [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if *************** *** 310,314 **** # Like AC_CONFIG_HEADER, but automatically create stamp file. ! AC_DEFUN([AM_CONFIG_HEADER], [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) --- 310,314 ---- # Like AC_CONFIG_HEADER, but automatically create stamp file. ! AC_DEFUN(AM_CONFIG_HEADER, [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) Index: configure.in =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/configure.in,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** configure.in 10 Jun 2002 23:15:20 -0000 1.19 --- configure.in 11 Jun 2002 01:50:27 -0000 1.20 *************** *** 47,51 **** AC_SUBST(DHCP_SNPRINTF) ! dnl check if kill(pid, 0) can be used to detect a process we can signal AC_WF_CHECK_KILL_SIGNAL_DETECT --- 47,51 ---- AC_SUBST(DHCP_SNPRINTF) ! dnl check if kill(pid, 0) can be used to detect a process AC_WF_CHECK_KILL_SIGNAL_DETECT Index: dhcp-agent.h =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/dhcp-agent.h,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** dhcp-agent.h 8 Jun 2002 17:35:02 -0000 1.53 --- dhcp-agent.h 11 Jun 2002 01:50:27 -0000 1.54 *************** *** 820,824 **** extern void destroy_interface_control(interface_control_t *ic); extern int interface_get_ip_addr(interface_control_t *ic, uint32_t *addr); ! extern list_t *interface_get_available(void); /* client states */ --- 820,825 ---- extern void destroy_interface_control(interface_control_t *ic); extern int interface_get_ip_addr(interface_control_t *ic, uint32_t *addr); ! extern list_t *interface_get_active_interfaces(void); ! extern list_t *interface_get_inactive_interfaces(void); /* client states */ Index: dhcp-client.c =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/dhcp-client.c,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** dhcp-client.c 8 Jun 2002 06:00:32 -0000 1.24 --- dhcp-client.c 11 Jun 2002 01:50:27 -0000 1.25 *************** *** 28,31 **** --- 28,82 ---- #include <dhcp-files.h> + /* client command codes: index to command array */ + + #define DO_VERSION 0 + #define DO_KILL 1 + #define DO_WAKE 2 + #define DO_CLEAR 3 + #define DO_CLIENT 4 + + const char *command_string[] = { + "version", "kill", + "wake", "clear", "client" + }; + + typedef void (*client_command)(char *interface); + typedef char *(*interface_lister)(void); + + /* 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); + + /* 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. */ + }; + + /* 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. */ + }; + + /* global vars affecting other code. */ int interactive = 1; /* by default we begin interactive (messages on stdout/stderr). */ char *work_dir = CLIENT_WORK_DIR; /* our default working directory */ *************** *** 35,38 **** --- 86,97 ---- #endif /* HAVE_PROGNAME */ + /* local vars for dhcpclient. */ + 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. */ + /* read up on our global conf. */ static void read_global_conf(const char *interface) *************** *** 47,50 **** --- 106,131 ---- } + /* 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_DISCOVER_OFFER; + } else /* if not empty we assume we can request the options. */ + return STATE_REQUEST_ACK; + } + + /* print usage info. */ + static void usage(char *s) + { + printf("usage: %s [-cavkw] [-d directory] [-i interface name] [ -m mac address ]\n", s); + exit(0); + } + + /* print out version information and exit. */ + static void do_version(char *interface) + { + info_message("%s version: %s\n", getprogname(), VERSION); + } + /* do a graceful shutdown. */ static void do_shutdown(dhcp_client_control_t *dc) *************** *** 61,90 **** } ! /* ! * Our initialize client state function. ! * We can be in two states. ! * ! * The discover/offer state, or we can ! * be in the request state where we ! * already have a configuration. ! * ! * We always ask for configuration info on ! * startup so we can't begin in any other ! * state except these two. ! */ ! static int initialize_client_state(dhcp_client_control_t *dc) { ! if(client_cache_is_empty(dc->cache)) { ! return STATE_DISCOVER_OFFER; ! } else /* if not empty we assume we can request the options. */ ! return STATE_REQUEST_ACK; } ! /* print usage info. */ ! static void usage(char *s) { ! printf("usage: %s [-cavkw] [-d directory] [-i interface name] [ -m mac address ]\n", s); ! exit(0); } --- 142,197 ---- } ! /* check for existing client. */ ! static int client_process_exists(char *interface) ! { ! pid_t pid; ! if(!get_pid_file(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 { ! delete_pid_file(interface); ! return 0; ! } ! #endif ! ! } ! ! static char *interface_get_proc(int active) { ! char *first_interface; ! list_t *interface_list; ! ! if(active) ! interface_list = interface_get_active_interfaces(); ! else ! interface_list = interface_get_inactive_interfaces(); ! ! if(interface_list == NULL) ! return NULL; ! ! first_interface = strdup(interface_list->data); ! purge_list(interface_list, NULL); ! return first_interface; } ! static char *interface_get_active(void) { ! return(interface_get_proc(1)); ! } ! ! static char *interface_get_inactive(void) ! { ! return(interface_get_proc(0)); } *************** *** 156,161 **** pid_t pid; if(get_pid_file(interface, &pid)) { ! error_message("could not get dhcpclient PID."); error_message("maybe it's not running?"); return; --- 263,270 ---- pid_t pid; + info_message("killing %s running on interface: %s", getprogname(), interface); + if(get_pid_file(interface, &pid)) { ! error_message("could not get %s PID.", getprogname()); error_message("maybe it's not running?"); return; *************** *** 163,167 **** if(kill(pid, SIGTERM) < 0) { ! error_message("could not send signal to dhcpclient process."); error_message("maybe it's not running?"); return; --- 272,276 ---- if(kill(pid, SIGTERM) < 0) { ! error_message("could not send signal to %s process.", getprogname()); error_message("maybe it's not running?"); return; *************** *** 178,182 **** if(get_pid_file(interface, &pid)) { ! error_message("could not get dhcpclient PID."); error_message("maybe it's not running?"); return; --- 287,291 ---- if(get_pid_file(interface, &pid)) { ! error_message("could not get %s PID.", getprogname()); error_message("maybe it's not running?"); return; *************** *** 184,188 **** if(kill(pid, SIGALRM) < 0) { ! error_message("could not send signal to dhcpclient process."); error_message("maybe it's not running?"); return; --- 293,297 ---- if(kill(pid, SIGALRM) < 0) { ! error_message("could not send signal to %s process.", getprogname()); error_message("maybe it's not running?"); return; *************** *** 202,207 **** /* A race condition exists between the discover and request state. * And we can't hup the client and tell it the cache has been deleted. */ ! error_message("dhcpclient already running."); ! error_message("i won't delete cache until it's shutdown."); return; } --- 311,316 ---- /* A race condition exists between the discover and request state. * And we can't hup the client and tell it the cache has been deleted. */ ! error_message("%s already running.", getprogname()); ! error_message("I won't delete cache until it's shutdown."); return; } *************** *** 227,324 **** } ! /* check for existing client. */ ! static int client_process_exists(char *interface) ! { ! pid_t pid; ! ! if(!get_pid_file(interface, &pid) && ! !kill(pid, 0)) { /* FIXME: add test to make sure 0 works. */ ! return 1; ! } else { ! delete_pid_file(interface); ! return 0; ! } ! } ! ! int main(int argc, char *argv[]) { - int c; - dhcp_client_control_t *dc; - char *interface = "eth0"; - int state; - unsigned char want_background = 1; - char *fake_hw_addr = NULL; - int promiscuous = 0; - - #if !defined(HAVE_PROGNAME) - __progname = argv[0]; - #endif /* HAVE_PROGNAME */ - - while((c = getopt(argc, argv, "gcdavi:m:kwh:l:")) != -1) { - - switch(c) { - - case 'v': - printf("%s version: %s\n", getprogname(), VERSION); - exit(0); - - case 'd': - work_dir = strdup(optarg); - break; - - case 'a': - want_background = 0; - break; - - case 'i': - printf("%s\n",optarg); - interface = strdup(optarg); - break; - - case 'm': - fake_hw_addr = strdup(optarg); - break; - - case 'k': /* kill client. */ - chdir(work_dir); - do_kill_client(interface); - exit(0); - - case 'w': /* wake client. */ - chdir(work_dir); - do_wake_client(interface); - exit(0); - - case 'c': - chdir(work_dir); - do_clear_cache(interface); - exit(0); - - case 'l': - - if(set_verbosity_level(atoi(optarg))) { - error_message("illegal verbosity level: %s", optarg); - exit(1); - } - - break; - - case 'p': - - promiscuous = 1; - break; - - case 'h': /* fall through. */ - default: - usage(argv[0]); - break; - } - } - - info_message("(C) 2001 Thamer Al-Harbash <tm...@wh...>"); - info_message("See LICENSE file for details."); - info_message(" "); - info_message("starting for interface %s", interface); - /* Switch into our work directory */ --- 336,341 ---- } ! static void do_change_work_dir(void) { /* Switch into our work directory */ *************** *** 340,343 **** --- 357,370 ---- } + return; + } + + static void do_client(char *interface) + { + dhcp_client_control_t *dc; + int state; + + info_message("starting for interface %s", interface); + /* We need to read our global configuration right after we change to work directory. */ read_global_conf(interface); *************** *** 418,419 **** --- 445,534 ---- exit(0); /* should never get here. */ } + + int main(int argc, char *argv[]) + { + int c, command_code = DO_CLIENT; + + #if !defined(HAVE_PROGNAME) + __progname = argv[0]; + #endif /* HAVE_PROGNAME */ + + info_message("(C) 2001 Thamer Al-Harbash <tm...@wh...>"); + info_message("See LICENSE file for details."); + info_message(" "); + + while((c = getopt(argc, argv, "gcdavi:m:kwh:l:")) != -1) { + + switch(c) { + + /* check for command codes. */ + case 'v': /* print version. */ + command_code = DO_VERSION; + break; + + case 'k': /* kill client. */ + command_code = DO_KILL; + break; + + case 'w': /* wake client. */ + command_code = DO_WAKE; + break; + + case 'c': /* clear up cache. */ + command_code = DO_CLEAR; + break; + + case 'd': + work_dir = strdup(optarg); + break; + + /* setup options. */ + + case 'a': + want_background = 0; + break; + + case 'i': + interface = strdup(optarg); + break; + + case 'm': + fake_hw_addr = strdup(optarg); + break; + + case 'l': + + if(set_verbosity_level(atoi(optarg))) { + error_message("illegal verbosity level: %s", optarg); + exit(1); + } + + break; + + case 'p': + promiscuous = 1; + break; + + case 'h': /* fall through. */ + default: + usage(argv[0]); + break; + } + } + + do_change_work_dir(); + + if(interface == NULL) /* get interface if not specified. */ + interface = get_interface[command_code](); + + if(interface == NULL) {/* if we were unable to attain an interface. */ + error_message("unable to retrieve suitable interface"); + error_message("for this operation: %s", command_string[command_code]); + exit(1); /* can't use fatal_error for multiline error message. */ + /* fixme: this stupidity will go with exception stack. */ + } + + commands[command_code](interface); + exit(0); + } + Index: dhcp-interface.c =================================================================== RCS file: /cvsroot/dhcp-agent/dhcp-agent/dhcp-interface.c,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** dhcp-interface.c 8 Jun 2002 17:35:02 -0000 1.16 --- dhcp-interface.c 11 Jun 2002 01:50:28 -0000 1.17 *************** *** 143,162 **** } ! /* utility to get interface list and place it in a list. */ ! ! static int list_available_interfaces(const struct intf_entry *entry, void *arg) { - list_t **p_list; /* pointer to linked list. */ - list_t *head; /* head of linked list. */ - char *intf_name = NULL; - - p_list = arg; - head = *p_list; - - /* - * Check the interface type is ethernet, - * is down OR has no IP address assigned to it. - * If it passes then add the name to the list. - */ if(entry->intf_type == INTF_TYPE_ETH) { --- 143,150 ---- } ! /* utility check function for looping on interface list. ! * check whether is down or does not have an IP assigned to it. */ ! static int check_interface_down(const struct intf_entry *entry) { if(entry->intf_type == INTF_TYPE_ETH) { *************** *** 165,185 **** || (entry->intf_addr.addr_type == ADDR_TYPE_NONE)) /* or true if no address set. */ ! intf_name = strdup(entry->intf_name); } ! if(intf_name != NULL) ! head = add_to_end_of_list(head, intf_name); ! *p_list = head; return 0; } ! list_t *interface_get_available(void) { intf_t *interfaces; ! list_t *interface_list; ! list_t **p_list = xmalloc(sizeof(list_t *)); ! *p_list = NULL; interfaces = intf_open(); --- 153,206 ---- || (entry->intf_addr.addr_type == ADDR_TYPE_NONE)) /* or true if no address set. */ ! return 1; } ! return 0; ! } ! /* utility check function for looping on interface list. ! * check whether is down or does not have an IP assigned to it. */ ! static int check_interface_up(const struct intf_entry *entry) ! { ! ! if(entry->intf_type == INTF_TYPE_ETH && ! (entry->intf_flags&INTF_FLAG_UP)) ! return 1; return 0; } ! /* utility to get interface list and place it in a list. */ ! static int list_interfaces(const struct intf_entry *entry, void *arg) ! { ! list_t *interfaces; ! int (*check)(const struct intf_entry *entry); ! char *intf_name = NULL; ! ! interfaces = arg; ! check = interfaces->data; /* first is always the routine to ! check routine. */ ! ! /* Check the interface type is ethernet, ! * is down OR has no IP address assigned to it. ! * If it passes then add the name to the list. ! */ ! ! if(check(entry)) { ! intf_name = strdup(entry->intf_name); ! interfaces = add_to_end_of_list(interfaces, intf_name); ! } ! ! return 0; ! } ! ! static list_t *interfaces_get_proc(int (*check)(const struct intf_entry *entry)) { intf_t *interfaces; ! list_t *interface_list = NULL; ! list_t *returned_list; ! ! /* add check as first datum. */ ! interface_list = add_to_end_of_list(interface_list, check); interfaces = intf_open(); *************** *** 188,202 **** error_message("dhcp-interface: interfaces_get_available: could not obtain interface handle: %s\n", strerror(errno)); /* yes it's too long -- need exception stack. */ ! xfree(p_list); intf_close(interfaces); return NULL; } ! intf_loop(interfaces, list_available_interfaces, p_list); - interface_list = *p_list; - xfree(p_list); intf_close(interfaces); ! return interface_list; } --- 209,236 ---- error_message("dhcp-interface: interfaces_get_available: could not obtain interface handle: %s\n", strerror(errno)); /* yes it's too long -- need exception stack. */ ! xfree(interface_list); /* fixme: this isn't really ! * good. we should have a way to destroy a list but not its ! * datums if we want to. */ intf_close(interfaces); return NULL; } ! intf_loop(interfaces, list_interfaces, interface_list); intf_close(interfaces); ! returned_list = interface_list->next; ! xfree(interface_list); ! ! return returned_list; ! } ! ! list_t *interface_get_active_interfaces(void) ! { ! return(interfaces_get_proc(check_interface_up)); ! } ! ! list_t *interface_get_inactive_interfaces(void) ! { ! return(interfaces_get_proc(check_interface_down)); } |