00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "dhcpd.h"
00029
00030 #include <sys/time.h>
00031 #include <signal.h>
00032
00033 dhcp_context_t dhcp_gbl_ctx;
00034 int shutdown_signal = 0;
00035
00036 #if defined (NSUPDATE)
00037
00038
00039
00040
00041
00042
00043 isc_result_t
00044 dhcp_dns_client_setservers(void)
00045 {
00046 isc_result_t result;
00047 irs_resconf_t *resconf = NULL;
00048 isc_sockaddrlist_t *nameservers;
00049 isc_sockaddr_t *sa;
00050
00051 result = irs_resconf_load(dhcp_gbl_ctx.mctx, _PATH_RESOLV_CONF,
00052 &resconf);
00053 if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
00054 log_error("irs_resconf_load failed: %d.", result);
00055 return (result);
00056 }
00057
00058 nameservers = irs_resconf_getnameservers(resconf);
00059
00060
00061 for (sa = ISC_LIST_HEAD(*nameservers);
00062 sa != NULL;
00063 sa = ISC_LIST_NEXT(sa, link)) {
00064 switch (sa->type.sa.sa_family) {
00065 case AF_INET:
00066 sa->type.sin.sin_port = htons(NS_DEFAULTPORT);
00067 break;
00068 case AF_INET6:
00069 sa->type.sin6.sin6_port = htons(NS_DEFAULTPORT);
00070 break;
00071 default:
00072 break;
00073 }
00074 }
00075
00076 result = dns_client_setservers(dhcp_gbl_ctx.dnsclient,
00077 dns_rdataclass_in,
00078 NULL, nameservers);
00079 if (result != ISC_R_SUCCESS) {
00080 log_error("dns_client_setservers failed: %d.",
00081 result);
00082 }
00083 return (result);
00084 }
00085 #endif
00086
00087 void
00088 isclib_cleanup(void)
00089 {
00090 #if defined (NSUPDATE)
00091 if (dhcp_gbl_ctx.dnsclient != NULL)
00092 dns_client_destroy((dns_client_t **)&dhcp_gbl_ctx.dnsclient);
00093 #endif
00094
00095 if (dhcp_gbl_ctx.task != NULL) {
00096 isc_task_shutdown(dhcp_gbl_ctx.task);
00097 isc_task_detach(&dhcp_gbl_ctx.task);
00098 }
00099
00100 if (dhcp_gbl_ctx.timermgr != NULL)
00101 isc_timermgr_destroy(&dhcp_gbl_ctx.timermgr);
00102
00103 if (dhcp_gbl_ctx.socketmgr != NULL)
00104 isc_socketmgr_destroy(&dhcp_gbl_ctx.socketmgr);
00105
00106 if (dhcp_gbl_ctx.taskmgr != NULL)
00107 isc_taskmgr_destroy(&dhcp_gbl_ctx.taskmgr);
00108
00109 if (dhcp_gbl_ctx.actx_started != ISC_FALSE) {
00110 isc_app_ctxfinish(dhcp_gbl_ctx.actx);
00111 dhcp_gbl_ctx.actx_started = ISC_FALSE;
00112 }
00113
00114 if (dhcp_gbl_ctx.actx != NULL)
00115 isc_appctx_destroy(&dhcp_gbl_ctx.actx);
00116
00117 if (dhcp_gbl_ctx.mctx != NULL)
00118 isc_mem_detach(&dhcp_gbl_ctx.mctx);
00119
00120 return;
00121 }
00122
00123 isc_result_t
00124 dhcp_context_create(int flags,
00125 struct in_addr *local4,
00126 struct in6_addr *local6) {
00127 isc_result_t result;
00128
00129 if ((flags & DHCP_CONTEXT_PRE_DB) != 0) {
00130
00131
00132
00133
00134 result = dhcp_result_register();
00135 if (result != ISC_R_SUCCESS) {
00136 log_fatal("register_table() %s: %u", "failed", result);
00137 }
00138
00139 memset(&dhcp_gbl_ctx, 0, sizeof (dhcp_gbl_ctx));
00140
00141 isc_lib_register();
00142
00143
00144 gettimeofday(&cur_tv, (struct timezone *)0);
00145 isc_random_seed(cur_tv.tv_sec);
00146
00147 #if defined (NSUPDATE)
00148 result = dns_lib_init();
00149 if (result != ISC_R_SUCCESS)
00150 goto cleanup;
00151 #else
00152
00153
00154 result = dst_lib_init(dhcp_gbl_ctx.mctx, NULL, 0);
00155 if (result != ISC_R_SUCCESS)
00156 goto cleanup;
00157
00158 #endif
00159 result = isc_mem_create(0, 0, &dhcp_gbl_ctx.mctx);
00160 if (result != ISC_R_SUCCESS)
00161 goto cleanup;
00162
00163 result = isc_appctx_create(dhcp_gbl_ctx.mctx,
00164 &dhcp_gbl_ctx.actx);
00165 if (result != ISC_R_SUCCESS)
00166 goto cleanup;
00167
00168 result = isc_app_ctxstart(dhcp_gbl_ctx.actx);
00169 if (result != ISC_R_SUCCESS)
00170 return (result);
00171 dhcp_gbl_ctx.actx_started = ISC_TRUE;
00172
00173 result = isc_taskmgr_createinctx(dhcp_gbl_ctx.mctx,
00174 dhcp_gbl_ctx.actx,
00175 1, 0,
00176 &dhcp_gbl_ctx.taskmgr);
00177 if (result != ISC_R_SUCCESS)
00178 goto cleanup;
00179
00180 result = isc_socketmgr_createinctx(dhcp_gbl_ctx.mctx,
00181 dhcp_gbl_ctx.actx,
00182 &dhcp_gbl_ctx.socketmgr);
00183 if (result != ISC_R_SUCCESS)
00184 goto cleanup;
00185
00186 result = isc_timermgr_createinctx(dhcp_gbl_ctx.mctx,
00187 dhcp_gbl_ctx.actx,
00188 &dhcp_gbl_ctx.timermgr);
00189 if (result != ISC_R_SUCCESS)
00190 goto cleanup;
00191
00192 result = isc_task_create(dhcp_gbl_ctx.taskmgr, 0, &dhcp_gbl_ctx.task);
00193 if (result != ISC_R_SUCCESS)
00194 goto cleanup;
00195 }
00196
00197 #if defined (NSUPDATE)
00198 if ((flags & DHCP_CONTEXT_POST_DB) != 0) {
00199 isc_sockaddr_t localaddr4, *localaddr4_ptr = NULL;
00200 isc_sockaddr_t localaddr6, *localaddr6_ptr = NULL;
00201 if (local4 != NULL) {
00202 isc_sockaddr_fromin(&localaddr4, local4, 0);
00203 localaddr4_ptr = &localaddr4;
00204 }
00205 if (local6 != NULL) {
00206 isc_sockaddr_fromin6(&localaddr6, local6, 0);
00207 localaddr6_ptr = &localaddr6;
00208 }
00209
00210 result = dns_client_createx2(dhcp_gbl_ctx.mctx,
00211 dhcp_gbl_ctx.actx,
00212 dhcp_gbl_ctx.taskmgr,
00213 dhcp_gbl_ctx.socketmgr,
00214 dhcp_gbl_ctx.timermgr,
00215 0,
00216 &dhcp_gbl_ctx.dnsclient,
00217 localaddr4_ptr,
00218 localaddr6_ptr);
00219 if (result != ISC_R_SUCCESS)
00220 goto cleanup;
00221
00222 result = dhcp_dns_client_setservers();
00223 if (result != ISC_R_SUCCESS)
00224 goto cleanup;
00225 }
00226 #endif
00227
00228 return(ISC_R_SUCCESS);
00229
00230 cleanup:
00231
00232
00233
00234
00235
00236 return(result);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 isc_result_t
00249 dhcp_isc_name(unsigned char *namestr,
00250 dns_fixedname_t *namefix,
00251 dns_name_t **name)
00252 {
00253 size_t namelen;
00254 isc_buffer_t b;
00255 isc_result_t result;
00256
00257 namelen = strlen((char *)namestr);
00258 isc_buffer_init(&b, namestr, namelen);
00259 isc_buffer_add(&b, namelen);
00260 dns_fixedname_init(namefix);
00261 *name = dns_fixedname_name(namefix);
00262 result = dns_name_fromtext(*name, &b, dns_rootname, 0, NULL);
00263 isc_buffer_invalidate(&b);
00264 return(result);
00265 }
00266
00267 isc_result_t
00268 isclib_make_dst_key(char *inname,
00269 char *algorithm,
00270 unsigned char *secret,
00271 int length,
00272 dst_key_t **dstkey)
00273 {
00274 isc_result_t result;
00275 dns_name_t *name;
00276 dns_fixedname_t name0;
00277 isc_buffer_t b;
00278
00279 isc_buffer_init(&b, secret, length);
00280 isc_buffer_add(&b, length);
00281
00282
00283 if (strcasecmp(algorithm, DHCP_HMAC_MD5_NAME) != 0) {
00284 return(DHCP_R_INVALIDARG);
00285 }
00286
00287 result = dhcp_isc_name((unsigned char *)inname, &name0, &name);
00288 if (result != ISC_R_SUCCESS) {
00289 return(result);
00290 }
00291
00292 return(dst_key_frombuffer(name, DST_ALG_HMACMD5, DNS_KEYOWNER_ENTITY,
00293 DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
00294 &b, dhcp_gbl_ctx.mctx, dstkey));
00295 }
00296
00302 void dhcp_signal_handler(int signal) {
00303 isc_appctx_t *ctx = dhcp_gbl_ctx.actx;
00304 int prev = shutdown_signal;
00305
00306 if (prev != 0) {
00307
00308 return;
00309 }
00310
00311 shutdown_signal = signal;
00312
00313
00314 if (ctx && ctx->methods && ctx->methods->ctxsuspend) {
00315 (void) isc_app_ctxsuspend(ctx);
00316 }
00317 }