📄 dhcpd.c
字号:
/* Default to the DHCP/BOOTP port. */ if (!local_port) { if ((s = getenv ("DHCPD_PORT"))) { local_port = htons (atoi (s)); log_debug ("binding to environment-specified port %d", ntohs (local_port)); } else { ent = getservbyname ("dhcp", "udp"); if (!ent) local_port = htons (67); else local_port = ent -> s_port;#ifndef __CYGWIN32__ /* XXX */ endservent ();#endif } } remote_port = htons (ntohs (local_port) + 1); if (server) { if (!inet_aton (server, &limited_broadcast)) { struct hostent *he; he = gethostbyname (server); if (he) { memcpy (&limited_broadcast, he -> h_addr_list [0], sizeof limited_broadcast); } else limited_broadcast.s_addr = INADDR_BROADCAST; } } else { limited_broadcast.s_addr = INADDR_BROADCAST; } /* Get the current time... */ GET_TIME (&cur_time); /* Set up the initial dhcp option universe. */ initialize_common_option_spaces (); initialize_server_option_spaces (); /* Add the ddns update style enumeration prior to parsing. */ add_enumeration (&ddns_styles); add_enumeration (&syslog_enum); if (!group_allocate (&root_group, MDL)) log_fatal ("Can't allocate root group!"); root_group -> authoritative = 0; /* Set up various hooks. */ dhcp_interface_setup_hook = dhcpd_interface_setup_hook; bootp_packet_handler = do_packet;#if defined (NSUPDATE) /* Set up the standard name service updater routine. */ parse = (struct parse *)0; status = new_parse (&parse, -1, std_nsupdate, (sizeof std_nsupdate) - 1, "standard name service update routine", 0); if (status != ISC_R_SUCCESS) log_fatal ("can't begin parsing name service updater!"); lose = 0; if (!(parse_executable_statements (&root_group -> statements, parse, &lose, context_any))) { end_parse (&parse); log_fatal ("can't parse standard name service updater!"); } end_parse (&parse);#endif /* Initialize icmp support... */ if (!cftest && !lftest) icmp_startup (1, lease_pinged);#if defined (TRACING) if (traceinfile) { if (!no_dhcpd_db) { log_error ("%s", ""); log_error ("** You must specify a lease file with -lf."); log_error (" Dhcpd will not overwrite your default"); log_fatal (" lease file when playing back a trace. **"); } trace_file_replay (traceinfile);#if defined (DEBUG_MEMORY_LEAKAGE) && \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) free_everything (); omapi_print_dmalloc_usage_by_caller (); #endif exit (0); }#endif /* Read the dhcpd.conf file... */ if (readconf () != ISC_R_SUCCESS) log_fatal ("Configuration file errors encountered -- exiting"); postconf_initialization (quiet); /* test option should cause an early exit */ if (cftest && !lftest) exit(0); group_write_hook = group_writer; /* Start up the database... */ db_startup (lftest); if (lftest) exit (0); /* Discover all the network interfaces and initialize them. */ discover_interfaces (DISCOVER_SERVER); /* Make up a seed for the random number generator from current time plus the sum of the last four bytes of each interface's hardware address interpreted as an integer. Not much entropy, but we're booting, so we're not likely to find anything better. */ seed = 0; for (ip = interfaces; ip; ip = ip -> next) { int junk; memcpy (&junk, &ip -> hw_address.hbuf [ip -> hw_address.hlen - sizeof seed], sizeof seed); seed += junk; } srandom (seed + cur_time);#if defined (TRACING) trace_seed_stash (trace_srandom, seed + cur_time);#endif postdb_startup ();#ifndef DEBUG if (daemon) { /* First part of becoming a daemon... */ if ((pid = fork ()) < 0) log_fatal ("Can't fork daemon: %m"); else if (pid) exit (0); } /* Read previous pid file. */ if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) { status = read (i, pbuf, (sizeof pbuf) - 1); close (i); pbuf [status] = 0; pid = atoi (pbuf); /* If the previous server process is not still running, write a new pid file immediately. */ if (pid && (pid == getpid() || kill (pid, 0) < 0)) { unlink (path_dhcpd_pid); if ((i = open (path_dhcpd_pid, O_WRONLY | O_CREAT, 0644)) >= 0) { sprintf (pbuf, "%d\n", (int)getpid ()); write (i, pbuf, strlen (pbuf)); close (i); pidfilewritten = 1; } } else log_fatal ("There's already a DHCP server running."); } /* If we were requested to log to stdout on the command line, keep doing so; otherwise, stop. */ if (log_perror == -1) log_perror = 1; else log_perror = 0; if (daemon) { /* Become session leader and get pid... */ close (0); close (1); close (2); pid = setsid (); } /* If we didn't write the pid file earlier because we found a process running the logged pid, but we made it to here, meaning nothing is listening on the bootp port, then write the pid file out - what's in it now is bogus anyway. */ if (!pidfilewritten) { unlink (path_dhcpd_pid); if ((i = open (path_dhcpd_pid, O_WRONLY | O_CREAT, 0644)) >= 0) { sprintf (pbuf, "%d\n", (int)getpid ()); write (i, pbuf, strlen (pbuf)); close (i); pidfilewritten = 1; } }#endif /* !DEBUG */#if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \ defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) dmalloc_cutoff_generation = dmalloc_generation; dmalloc_longterm = dmalloc_outstanding; dmalloc_outstanding = 0;#endif#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) dump_rc_history ();#endif omapi_set_int_value ((omapi_object_t *)dhcp_control_object, (omapi_object_t *)0, "state", server_running); /* Receive packets and dispatch them... */ dispatch (); /* Not reached */ return 0;}void postconf_initialization (int quiet){ struct option_state *options = (struct option_state *)0; struct data_string db; struct option_cache *oc; char *s; isc_result_t result; struct parse *parse; int tmp; /* Now try to get the lease file name. */ option_state_allocate (&options, MDL); execute_statements_in_scope ((struct binding_value **)0, (struct packet *)0, (struct lease *)0, (struct client_state *)0, (struct option_state *)0, options, &global_scope, root_group, (struct group *)0); memset (&db, 0, sizeof db); oc = lookup_option (&server_universe, options, SV_LEASE_FILE_NAME); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { s = dmalloc (db.len + 1, MDL); if (!s) log_fatal ("no memory for lease db filename."); memcpy (s, db.data, db.len); s [db.len] = 0; data_string_forget (&db, MDL); path_dhcpd_db = s; } oc = lookup_option (&server_universe, options, SV_PID_FILE_NAME); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { s = dmalloc (db.len + 1, MDL); if (!s) log_fatal ("no memory for lease db filename."); memcpy (s, db.data, db.len); s [db.len] = 0; data_string_forget (&db, MDL); path_dhcpd_pid = s; } omapi_port = -1; oc = lookup_option (&server_universe, options, SV_OMAPI_PORT); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { if (db.len == 2) { omapi_port = getUShort (db.data); } else log_fatal ("invalid omapi port data length"); data_string_forget (&db, MDL); } oc = lookup_option (&server_universe, options, SV_OMAPI_KEY); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { s = dmalloc (db.len + 1, MDL); if (!s) log_fatal ("no memory for OMAPI key filename."); memcpy (s, db.data, db.len); s [db.len] = 0; data_string_forget (&db, MDL); result = omapi_auth_key_lookup_name (&omapi_key, s); dfree (s, MDL); if (result != ISC_R_SUCCESS) log_fatal ("OMAPI key %s: %s", s, isc_result_totext (result)); } oc = lookup_option (&server_universe, options, SV_LOCAL_PORT); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { if (db.len == 2) { local_port = htons (getUShort (db.data)); } else log_fatal ("invalid local port data length"); data_string_forget (&db, MDL); } oc = lookup_option (&server_universe, options, SV_REMOTE_PORT); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { if (db.len == 2) { remote_port = htons (getUShort (db.data)); } else log_fatal ("invalid remote port data length"); data_string_forget (&db, MDL); } oc = lookup_option (&server_universe, options, SV_LIMITED_BROADCAST_ADDRESS); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { if (db.len == 4) { memcpy (&limited_broadcast, db.data, 4); } else log_fatal ("invalid remote port data length"); data_string_forget (&db, MDL); } oc = lookup_option (&server_universe, options, SV_LOCAL_ADDRESS); if (oc && evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { if (db.len == 4) { memcpy (&local_address, db.data, 4); } else log_fatal ("invalid remote port data length"); data_string_forget (&db, MDL); } oc = lookup_option (&server_universe, options, SV_DDNS_UPDATE_STYLE); if (oc) { if (evaluate_option_cache (&db, (struct packet *)0, (struct lease *)0, (struct client_state *)0, options, (struct option_state *)0, &global_scope, oc, MDL)) { if (db.len == 1) { ddns_update_style = db.data [0]; } else log_fatal ("invalid dns update type"); data_string_forget (&db, MDL); } } else { log_info ("%s", ""); log_error ("** You must add a ddns-update-style %s%s.", "statement to ", path_dhcpd_conf); log_error (" To get the same behaviour as in 3.0b2pl11 %s", "and previous"); log_error (" versions, add a line that says \"%s\"", "ddns-update-style ad-hoc;"); log_fatal (" Please read the dhcpd.conf manual page %s", "for more information. **"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -