📄 dhcp-client-guile.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-client-guile.c,v 1.11 2003/06/28 17:40:10 actmodern Exp $ * * Copyright 2002 Thamer Alharbash * * 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. * * Glue between dhcp-client and guile. * * Everything to do with guile should go here. * */#include "dhcp-local.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-client-guile.h"#include "dhcp-interface.h"#include "dhcp-limits.h"static scm_t_bits client_control_tag;/* * * * * * * * * * * * * * * * * * * * * * * * * utility routines guile doesn't provide but * * really should :| * * * * * * * * * * * * * * * * * * * * * * * * */static char *x_scm_symbol2newstr(SCM symbol){ size_t len; char *newstr; len = SCM_SYMBOL_LENGTH(symbol); newstr = xmalloc((len + 1) * sizeof(char)); memcpy(newstr, SCM_SYMBOL_CHARS(symbol), len); newstr[len] = 0; return newstr;}static char *x_scm_string2newstr(SCM string){ size_t len; char *newstr; len = SCM_STRING_LENGTH(string); newstr = xmalloc((len + 1) * sizeof(char)); memcpy(newstr, SCM_STRING_CHARS(string), len); newstr[len] = 0; return newstr;}/* * * * * * * * * * * * * * * * * * * * * * * * list conversions. we need to do a few * * of these to support some of the internal * * routines. * * * * * * * * * * * * * * * * * * * * * * * */static list_t *guile_address_list_to_internal_list(SCM scm_address_list){ char *address_string; int list_length, i; SCM scm_list_length; SCM scm_address_string; ip_addr_t *ip_address; list_t *address_list; SCM_ASSERT(SCM_CONSP(scm_address_list), scm_address_list, SCM_ARG1, "guile_address_list_to_internal_list"); scm_list_length = scm_length(scm_address_list); list_length = scm_num2int(scm_list_length, SCM_ARG1, "guile_address_list_to_internal_list"); address_list = list_create(); for(i = 0;i < list_length;i++) { scm_address_string = scm_list_ref(scm_address_list, SCM_MAKINUM(i)); address_string = x_scm_string2newstr(scm_address_string); ip_address = string_ip_to_ip_addr(address_string); list_add_to_end(address_list, ip_address); xfree(address_string); } return address_list;}/* take a latency list: a list of integer latency values followed * by an address, and convert it to a numeric value for integers, * and a string value for the address. */static SCM internal_latency_list_to_guile_latency_list(list_t *latency_list){ int *latency; ip_addr_t *address; char *address_string; SCM scm_inum_latency; SCM scm_address_string; SCM scm_latency_list = SCM_EOL; SCM scm_latency_address_pair = SCM_EOL; list_rewind(latency_list); while((latency = list_next(latency_list)) != NULL) { scm_inum_latency = SCM_MAKINUM(*latency); address = list_next(latency_list); /* this should always return a value. */ address_string = ip_addr_to_string(*address); scm_address_string = scm_makfrom0str(address_string); scm_latency_address_pair = scm_cons(scm_address_string, scm_latency_address_pair); scm_latency_address_pair = scm_cons(scm_inum_latency, scm_latency_address_pair); scm_latency_list = scm_cons(scm_latency_address_pair, scm_latency_list); scm_latency_address_pair = SCM_EOL; xfree(address_string); } return scm_latency_list;}/* * * * * * * * * * * * * * * * * * * * * guile interface to utility routines * * * * * * * * * * * * * * * * * * * * *//* find out if we should configure an option as per a user's request. */static SCM dhcp_scm_configurep(SCM scm_dc, SCM scm_option){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; uint8_t *configure_opts; char *opt_sym_name; char *opt_proper_name; dhcp_opt_tag_t tag; SCM return_bool = SCM_BOOL_F; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-configure?"); SCM_ASSERT(SCM_SYMBOLP(scm_option), scm_option, SCM_ARG2, "client-configure?"); client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; configure_opts = client_conf_get_opt_configure_bit_array(dc->conf, dhcp_client_get_server_ip_address(dc), dhcp_client_get_server_hw_address(dc)); if(configure_opts == NULL) return SCM_BOOL_T; opt_sym_name = x_scm_symbol2newstr(scm_option); if(!strncmp("dhcp-", opt_sym_name, strlen("dhcp-"))) { opt_proper_name = opt_sym_name + 5; for(tag = 0; tag < MAX_OPTIONS_HANDLED; tag++) { if(!strcmp(dhcp_option_conf_string_get(tag), opt_proper_name)) { return_bool = SCM_BOOL_T; break; } } } xfree(opt_sym_name); return return_bool;}/* get the default mtu */static SCM dhcp_scm_get_default_mtu(SCM scm_dc){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; SCM mtu; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-get-default-mtu"); client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; mtu = SCM_MAKINUM(client_conf_get_default_mtu(dc->conf)); return mtu;}/* get the default subnet mask. */static SCM dhcp_scm_get_default_subnet_mask(SCM scm_dc){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; SCM subnet_mask; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-get-default-subnet-mask"); client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; /* fixme: implement default client subnet-mask option in client conf. */ subnet_mask = scm_makfrom0str(client_conf_get_default_subnet_mask(dc->conf, dhcp_client_get_server_ip_address(dc), dhcp_client_get_server_hw_address(dc))); return subnet_mask;}/* interface-up: bring an interface up. */static SCM dhcp_scm_interface_up(SCM scm_dc, SCM scm_ip_address, SCM scm_netmask, SCM scm_mtu){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; rawnet_t *rawnet; ip_addr_t ip_address, netmask; int mtu; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-interface-up"); SCM_ASSERT(SCM_STRINGP(scm_ip_address)|SCM_INUMP(scm_ip_address), scm_ip_address, SCM_ARG2, "client-interface-up"); SCM_ASSERT(SCM_STRINGP(scm_netmask)|SCM_INUMP(scm_netmask), scm_netmask, SCM_ARG3, "client-interface-up"); SCM_ASSERT(SCM_STRINGP(scm_mtu)|SCM_INUM(scm_mtu), scm_mtu, SCM_ARG4, "client-interface-up"); /* convert to C types. */ /* interface handle. */ client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; rawnet = dc->rawnet; /* if string change to number first. */ if(SCM_STRINGP(scm_ip_address)) { ip_address = ntohl(scm_num2ulong(scm_inet_aton(scm_ip_address), 1, "client-interface-up")); } else { ip_address = scm_num2ulong(scm_ip_address, 1, "client-interface-up"); } /* if string change to number first. */ if(SCM_STRINGP(scm_netmask)) { netmask = ntohl(scm_num2ulong(scm_inet_aton(scm_netmask), 1, "client-interface-up")); } else { netmask = scm_num2ulong(scm_netmask, 1, "client-interface-up"); } /* if string change to number first. */ if(SCM_STRINGP(scm_mtu)) { mtu = scm_num2ulong(scm_mtu, 1, "client-interface-up"); } else { mtu = scm_num2int(scm_mtu, 1, "client-interface-up"); } /* don't throw an exception: return true/false based on return value. */ if(rawnet_interface_up(rawnet, ip_address, netmask, mtu, 1)) return SCM_BOOL_F; else return SCM_BOOL_T;}/* add or remove a default route depending on set_route. */static SCM dhcp_scm_client_default_route_proc(SCM scm_dc, SCM scm_default_router, SCM set_route){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; rawnet_t *rawnet; ip_addr_t default_router; struct route_entry r_entry; route_t *rt; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-set-default-route"); SCM_ASSERT(SCM_STRINGP(scm_default_router)|SCM_INUMP(scm_default_router), scm_default_router, SCM_ARG2, "client-set-default-route"); SCM_ASSERT(SCM_BOOLP(set_route), set_route, SCM_ARG3, "client-set-default-route"); /* if string change to number first. */ if(SCM_STRINGP(scm_default_router)) { default_router = ntohl(scm_num2ulong(scm_inet_aton(scm_default_router), 1, "client-set-default-route")); } else { default_router = scm_num2ulong(scm_default_router, 1, "client-set-default-route"); } /* interface handle. */ client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; rawnet = dc->rawnet; memset(&r_entry, 0, sizeof(struct route_entry)); r_entry.route_dst.addr_type = ADDR_TYPE_IP; r_entry.route_dst.addr_bits = 0; r_entry.route_dst.addr_ip = 0; r_entry.route_gw.addr_type = ADDR_TYPE_IP; r_entry.route_gw.addr_bits = 0; memcpy(&r_entry.route_gw.addr_ip, &default_router, IP_ADDR_LEN); rt = route_open(); if(rt == NULL) { ERROR_MESSAGE("unable to open routing table: %s", strerror(errno)); return SCM_BOOL_F; } if(SCM_NFALSEP(set_route)) { if(route_add(rt, &r_entry) < 0) { ERROR_MESSAGE("unable to add route: %s", strerror(errno)); route_close(rt); return SCM_BOOL_F; } } else { if(route_delete(rt, &r_entry) < 0) { ERROR_MESSAGE("unable to add remove: %s", strerror(errno)); route_close(rt); return SCM_BOOL_F; } } route_close(rt); return SCM_BOOL_T;}/* add a default route. */static SCM dhcp_scm_client_set_default_route(SCM scm_dc, SCM scm_default_router){ return dhcp_scm_client_default_route_proc(scm_dc, scm_default_router, SCM_BOOL_T);}/* remove a default route. */static SCM dhcp_scm_client_remove_default_route(SCM scm_dc, SCM scm_default_router){ return dhcp_scm_client_default_route_proc(scm_dc, scm_default_router, SCM_BOOL_F);}SCM dhcp_scm_client_shutdown(SCM scm_dc){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-shutdown"); /* client control. */ client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; client_shutdown(dc); /* never really returns but to avoid compiler warning. */ return SCM_BOOL_F;}SCM dhcp_scm_client_do_discover_icmp_latency(SCM scm_dc){ client_control_smob_t *client_control_smob; dhcp_client_control_t *dc; /* do assertions */ SCM_ASSERT(SCM_SMOB_PREDICATE(client_control_tag, scm_dc), scm_dc, SCM_ARG1, "client-do-discover-icmp-latency"); /* client control. */ client_control_smob = (client_control_smob_t *)SCM_SMOB_DATA(scm_dc); dc = client_control_smob->dc; if(client_conf_get_do_measure_router_latency_icmp(dc->conf, dhcp_client_get_server_ip_address(dc), dhcp_client_get_server_hw_address(dc))) { return SCM_BOOL_T; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -