📄 dhclient.c
字号:
/* Allocate space for options. */ option_state_allocate (op, MDL); /* Send the server identifier if provided. */ if (sid) save_option (&dhcp_universe, *op, sid); oc = (struct option_cache *)0; /* Send the requested address if provided. */ if (rip) { client -> requested_address = *rip; if (!(make_const_option_cache (&oc, (struct buffer **)0, rip -> iabuf, rip -> len, &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL))) log_error ("can't make requested address cache."); else { save_option (&dhcp_universe, *op, oc); option_cache_dereference (&oc, MDL); } } else { client -> requested_address.len = 0; } if (!(make_const_option_cache (&oc, (struct buffer **)0, type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL))) log_error ("can't make message type."); else { save_option (&dhcp_universe, *op, oc); option_cache_dereference (&oc, MDL); } if (prl) { /* Figure out how many parameters were requested. */ for (i = 0; prl [i]; i++) ; if (!buffer_allocate (&bp, i, MDL)) log_error ("can't make parameter list buffer."); else { for (i = 0; prl [i]; i++) bp -> data [i] = prl [i]; if (!(make_const_option_cache (&oc, &bp, (u_int8_t *)0, i, &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST], MDL))) log_error ("can't make option cache"); else { save_option (&dhcp_universe, *op, oc); option_cache_dereference (&oc, MDL); } } } /* Run statements that need to be run on transmission. */ if (client -> config -> on_transmission) execute_statements_in_scope ((struct binding_value **)0, (struct packet *)0, (struct lease *)0, client, (lease ? lease -> options : (struct option_state *)0), *op, &global_scope, client -> config -> on_transmission, (struct group *)0);}void make_discover (client, lease) struct client_state *client; struct client_lease *lease;{ unsigned char discover = DHCPDISCOVER; int i; struct option_state *options = (struct option_state *)0; memset (&client -> packet, 0, sizeof (client -> packet)); make_client_options (client, lease, &discover, (struct option_cache *)0, lease ? &lease -> address : (struct iaddr *)0, client -> config -> requested_options, &options); /* Set up the option buffer... */ client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, /* maximum packet size */1500, (struct option_state *)0, options, /* scope */ &global_scope, /* overload */ 0, /* terminate */0, /* bootpp */0, (struct data_string *)0, client -> config -> vendor_space_name); option_state_dereference (&options, MDL); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = random (); client -> packet.secs = 0; /* filled in by send_discover. */ if (can_receive_unicast_unconfigured (client -> interface)) client -> packet.flags = 0; else client -> packet.flags = htons (BOOTP_BROADCAST); memset (&(client -> packet.ciaddr), 0, sizeof client -> packet.ciaddr); memset (&(client -> packet.yiaddr), 0, sizeof client -> packet.yiaddr); memset (&(client -> packet.siaddr), 0, sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; if (client -> interface -> hw_address.hlen > 0) memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], (unsigned)(client -> interface -> hw_address.hlen - 1));#ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length);#endif}void make_request (client, lease) struct client_state *client; struct client_lease *lease;{ unsigned char request = DHCPREQUEST; int i, j; unsigned char *tmp, *digest; unsigned char *old_digest_loc; struct option_cache *oc; memset (&client -> packet, 0, sizeof (client -> packet)); if (client -> state == S_REQUESTING) oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_SERVER_IDENTIFIER); else oc = (struct option_cache *)0; make_client_options (client, lease, &request, oc, ((client -> state == S_REQUESTING || client -> state == S_REBOOTING) ? &lease -> address : (struct iaddr *)0), client -> config -> requested_options, &client -> sent_options); /* Set up the option buffer... */ client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, /* maximum packet size */1500, (struct option_state *)0, client -> sent_options, /* scope */ &global_scope, /* overload */ 0, /* terminate */0, /* bootpp */0, (struct data_string *)0, client -> config -> vendor_space_name); option_state_dereference (&client -> sent_options, MDL); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = client -> xid; client -> packet.secs = 0; /* Filled in by send_request. */ /* If we own the address we're requesting, put it in ciaddr; otherwise set ciaddr to zero. */ if (client -> state == S_BOUND || client -> state == S_RENEWING || client -> state == S_REBINDING) { memcpy (&client -> packet.ciaddr, lease -> address.iabuf, lease -> address.len); client -> packet.flags = 0; } else { memset (&client -> packet.ciaddr, 0, sizeof client -> packet.ciaddr); if (can_receive_unicast_unconfigured (client -> interface)) client -> packet.flags = 0; else client -> packet.flags = htons (BOOTP_BROADCAST); } memset (&client -> packet.yiaddr, 0, sizeof client -> packet.yiaddr); memset (&client -> packet.siaddr, 0, sizeof client -> packet.siaddr); if (client -> state != S_BOUND && client -> state != S_RENEWING) client -> packet.giaddr = giaddr; else memset (&client -> packet.giaddr, 0, sizeof client -> packet.giaddr); if (client -> interface -> hw_address.hlen > 0) memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], (unsigned)(client -> interface -> hw_address.hlen - 1));#ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length);#endif}void make_decline (client, lease) struct client_state *client; struct client_lease *lease;{ unsigned char decline = DHCPDECLINE; int i; struct option_cache *oc; struct option_state *options = (struct option_state *)0; oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_SERVER_IDENTIFIER); make_client_options (client, lease, &decline, oc, &lease -> address, (u_int32_t *)0, &options); /* Set up the option buffer... */ memset (&client -> packet, 0, sizeof (client -> packet)); client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, 0, (struct option_state *)0, options, &global_scope, 0, 0, 0, (struct data_string *)0, client -> config -> vendor_space_name); option_state_dereference (&options, MDL); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; option_state_dereference (&options, MDL); client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = client -> xid; client -> packet.secs = 0; /* Filled in by send_request. */ if (can_receive_unicast_unconfigured (client -> interface)) client -> packet.flags = 0; else client -> packet.flags = htons (BOOTP_BROADCAST); /* ciaddr must always be zero. */ memset (&client -> packet.ciaddr, 0, sizeof client -> packet.ciaddr); memset (&client -> packet.yiaddr, 0, sizeof client -> packet.yiaddr); memset (&client -> packet.siaddr, 0, sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], client -> interface -> hw_address.hlen);#ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length);#endif}void make_release (client, lease) struct client_state *client; struct client_lease *lease;{ unsigned char request = DHCPRELEASE; int i; struct option_cache *oc; struct option_state *options = (struct option_state *)0; memset (&client -> packet, 0, sizeof (client -> packet)); oc = lookup_option (&dhcp_universe, lease -> options, DHO_DHCP_SERVER_IDENTIFIER); make_client_options (client, lease, &request, oc, (struct iaddr *)0, (u_int32_t *)0, &options); /* Set up the option buffer... */ client -> packet_length = cons_options ((struct packet *)0, &client -> packet, (struct lease *)0, client, /* maximum packet size */1500, (struct option_state *)0, options, /* scope */ &global_scope, /* overload */ 0, /* terminate */0, /* bootpp */0, (struct data_string *)0, client -> config -> vendor_space_name); if (client -> packet_length < BOOTP_MIN_LEN) client -> packet_length = BOOTP_MIN_LEN; option_state_dereference (&options, MDL); client -> packet.op = BOOTREQUEST; client -> packet.htype = client -> interface -> hw_address.hbuf [0]; client -> packet.hlen = client -> interface -> hw_address.hlen - 1; client -> packet.hops = 0; client -> packet.xid = random (); client -> packet.secs = 0; client -> packet.flags = 0; memcpy (&client -> packet.ciaddr, lease -> address.iabuf, lease -> address.len); memset (&client -> packet.yiaddr, 0, sizeof client -> packet.yiaddr); memset (&client -> packet.siaddr, 0, sizeof client -> packet.siaddr); client -> packet.giaddr = giaddr; memcpy (client -> packet.chaddr, &client -> interface -> hw_address.hbuf [1], client -> interface -> hw_address.hlen);#ifdef DEBUG_PACKET dump_raw ((unsigned char *)&client -> packet, client -> packet_length);#endif}void destroy_client_lease (lease) struct client_lease *lease;{ int i; if (lease -> server_name) dfree (lease -> server_name, MDL); if (lease -> filename) dfree (lease -> filename, MDL); option_state_dereference (&lease -> options, MDL); free_client_lease (lease, MDL);}FILE *leaseFile;void rewrite_client_leases (){ struct interface_info *ip; struct client_state *client; struct client_lease *lp; if (leaseFile) fclose (leaseFile); leaseFile = fopen (path_dhclient_db, "w"); if (!leaseFile) { log_error ("can't create %s: %m", path_dhclient_db); return; } /* Write out all the leases attached to configured interfaces that we know about. */ for (ip = interfaces; ip; ip = ip -> next) { for (client = ip -> client; client; client = client -> next) { for (lp = client -> leases; lp; lp = lp -> next) { write_client_lease (client, lp, 1, 0); } if (client -> active) write_client_lease (client, client -> active, 1, 0); } } /* Write out any leases that are attached to interfaces that aren't currently configured. */ for (ip = dummy_interfaces; ip; ip = ip -> next) { for (client = ip -> client; client; client = client -> next) { for (lp = client -> leases; lp; lp = lp -> next) { write_client_lease (client, lp, 1, 0); } if (client -> active) write_client_lease (client, client -> active, 1, 0); } } fflush (leaseFile);}void write_lease_option (struct option_cache *oc, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct universe *u, void *stuff){ const char *name, *dot; struct data_string ds; int status; struct client_state *client; memset (&ds, 0, sizeof ds); if (u != &dhcp_universe) { name = u -> name; dot = "."; } else { name = ""; dot = ""; } if (evaluate_option_cache (&ds, packet, lease, client_state, in_options, cfg_options, scope, oc, MDL)) { fprintf (leaseFile, " option %s%s%s %s;\n", name, dot, oc -> option -> name, pretty_print_option (oc -> option, ds.data, ds.len, 1, 1)); data_string_forget (&ds, MDL); }}int write_client_lease (client, lease, rewrite, makesure) struct client_state *client; struct client_lease *lease; int rewrite; int makesure;{ int i; struct tm *t; static int leases_written; struct option_cache *oc; struct data_string ds; pair *hash; int errors = 0; char *s; if (!rewrite) { if (leases_written++ > 20) { rewrite_client_leases (); leases_written = 0; } } /* If the lease came from the config file, we don't need to stash a copy in the lease
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -