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 #include "dns.h"
00027
00028 DNS_ERROR dns_create_query( TALLOC_CTX *mem_ctx, const char *name,
00029 uint16 q_type, uint16 q_class,
00030 struct dns_request **preq )
00031 {
00032 struct dns_request *req;
00033 struct dns_question *q;
00034 DNS_ERROR err;
00035
00036 if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_request)) ||
00037 !(req->questions = TALLOC_ARRAY(req, struct dns_question *, 1)) ||
00038 !(req->questions[0] = talloc(req->questions,
00039 struct dns_question))) {
00040 TALLOC_FREE(req);
00041 return ERROR_DNS_NO_MEMORY;
00042 }
00043
00044 req->id = random();
00045
00046 req->num_questions = 1;
00047 q = req->questions[0];
00048
00049 err = dns_domain_name_from_string(q, name, &q->name);
00050 if (!ERR_DNS_IS_OK(err)) {
00051 TALLOC_FREE(req);
00052 return err;
00053 }
00054
00055 q->q_type = q_type;
00056 q->q_class = q_class;
00057
00058 *preq = req;
00059 return ERROR_DNS_SUCCESS;
00060 }
00061
00062 DNS_ERROR dns_create_update( TALLOC_CTX *mem_ctx, const char *name,
00063 struct dns_update_request **preq )
00064 {
00065 struct dns_update_request *req;
00066 struct dns_zone *z;
00067 DNS_ERROR err;
00068
00069 if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_update_request)) ||
00070 !(req->zones = TALLOC_ARRAY(req, struct dns_zone *, 1)) ||
00071 !(req->zones[0] = talloc(req->zones, struct dns_zone))) {
00072 TALLOC_FREE(req);
00073 return ERROR_DNS_NO_MEMORY;
00074 }
00075
00076 req->id = random();
00077 req->flags = 0x2800;
00078
00079 req->num_zones = 1;
00080 z = req->zones[0];
00081
00082 err = dns_domain_name_from_string(z, name, &z->name);
00083 if (!ERR_DNS_IS_OK(err)) {
00084 TALLOC_FREE(req);
00085 return err;
00086 }
00087
00088 z->z_type = QTYPE_SOA;
00089 z->z_class = DNS_CLASS_IN;
00090
00091 *preq = req;
00092 return ERROR_DNS_SUCCESS;
00093 }
00094
00095 DNS_ERROR dns_create_rrec(TALLOC_CTX *mem_ctx, const char *name,
00096 uint16 type, uint16 r_class, uint32 ttl,
00097 uint16 data_length, uint8 *data,
00098 struct dns_rrec **prec)
00099 {
00100 struct dns_rrec *rec;
00101 DNS_ERROR err;
00102
00103 if (!(rec = talloc(mem_ctx, struct dns_rrec))) {
00104 return ERROR_DNS_NO_MEMORY;
00105 }
00106
00107 err = dns_domain_name_from_string(rec, name, &rec->name);
00108 if (!(ERR_DNS_IS_OK(err))) {
00109 TALLOC_FREE(rec);
00110 return err;
00111 }
00112
00113 rec->type = type;
00114 rec->r_class = r_class;
00115 rec->ttl = ttl;
00116 rec->data_length = data_length;
00117 rec->data = talloc_move(rec, &data);
00118
00119 *prec = rec;
00120 return ERROR_DNS_SUCCESS;
00121 }
00122
00123 DNS_ERROR dns_create_a_record(TALLOC_CTX *mem_ctx, const char *host,
00124 uint32 ttl, struct in_addr ip,
00125 struct dns_rrec **prec)
00126 {
00127 uint8 *data;
00128 DNS_ERROR err;
00129
00130 if (!(data = (uint8 *)TALLOC_MEMDUP(mem_ctx, (const void *)&ip.s_addr,
00131 sizeof(ip.s_addr)))) {
00132 return ERROR_DNS_NO_MEMORY;
00133 }
00134
00135 err = dns_create_rrec(mem_ctx, host, QTYPE_A, DNS_CLASS_IN, ttl,
00136 sizeof(ip.s_addr), data, prec);
00137
00138 if (!ERR_DNS_IS_OK(err)) {
00139 TALLOC_FREE(data);
00140 }
00141
00142 return err;
00143 }
00144
00145 DNS_ERROR dns_create_name_in_use_record(TALLOC_CTX *mem_ctx,
00146 const char *name,
00147 const struct in_addr *ip,
00148 struct dns_rrec **prec)
00149 {
00150 if (ip != NULL) {
00151 return dns_create_a_record(mem_ctx, name, 0, *ip, prec);
00152 }
00153
00154 return dns_create_rrec(mem_ctx, name, QTYPE_ANY, DNS_CLASS_IN, 0, 0,
00155 NULL, prec);
00156 }
00157
00158 DNS_ERROR dns_create_name_not_in_use_record(TALLOC_CTX *mem_ctx,
00159 const char *name, uint32 type,
00160 struct dns_rrec **prec)
00161 {
00162 return dns_create_rrec(mem_ctx, name, type, DNS_CLASS_NONE, 0,
00163 0, NULL, prec);
00164 }
00165
00166 DNS_ERROR dns_create_delete_record(TALLOC_CTX *mem_ctx, const char *name,
00167 uint16 type, uint16 r_class,
00168 struct dns_rrec **prec)
00169 {
00170 return dns_create_rrec(mem_ctx, name, type, r_class, 0, 0, NULL, prec);
00171 }
00172
00173 DNS_ERROR dns_create_tkey_record(TALLOC_CTX *mem_ctx, const char *keyname,
00174 const char *algorithm_name, time_t inception,
00175 time_t expiration, uint16 mode, uint16 error,
00176 uint16 key_length, const uint8 *key,
00177 struct dns_rrec **prec)
00178 {
00179 struct dns_buffer *buf;
00180 struct dns_domain_name *algorithm;
00181 DNS_ERROR err;
00182
00183 if (!(buf = dns_create_buffer(mem_ctx))) {
00184 return ERROR_DNS_NO_MEMORY;
00185 }
00186
00187 err = dns_domain_name_from_string(buf, algorithm_name, &algorithm);
00188 if (!ERR_DNS_IS_OK(err)) goto error;
00189
00190 dns_marshall_domain_name(buf, algorithm);
00191 dns_marshall_uint32(buf, inception);
00192 dns_marshall_uint32(buf, expiration);
00193 dns_marshall_uint16(buf, mode);
00194 dns_marshall_uint16(buf, error);
00195 dns_marshall_uint16(buf, key_length);
00196 dns_marshall_buffer(buf, key, key_length);
00197 dns_marshall_uint16(buf, 0);
00198
00199 if (!ERR_DNS_IS_OK(buf->error)) {
00200 err = buf->error;
00201 goto error;
00202 }
00203
00204 err = dns_create_rrec(mem_ctx, keyname, QTYPE_TKEY, DNS_CLASS_ANY, 0,
00205 buf->offset, buf->data, prec);
00206
00207 error:
00208 TALLOC_FREE(buf);
00209 return err;
00210 }
00211
00212 DNS_ERROR dns_unmarshall_tkey_record(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
00213 struct dns_tkey_record **ptkey)
00214 {
00215 struct dns_tkey_record *tkey;
00216 struct dns_buffer buf;
00217 uint32 tmp_inception, tmp_expiration;
00218
00219 if (!(tkey = talloc(mem_ctx, struct dns_tkey_record))) {
00220 return ERROR_DNS_NO_MEMORY;
00221 }
00222
00223 buf.data = rec->data;
00224 buf.size = rec->data_length;
00225 buf.offset = 0;
00226 buf.error = ERROR_DNS_SUCCESS;
00227
00228 dns_unmarshall_domain_name(tkey, &buf, &tkey->algorithm);
00229 dns_unmarshall_uint32(&buf, &tmp_inception);
00230 dns_unmarshall_uint32(&buf, &tmp_expiration);
00231 dns_unmarshall_uint16(&buf, &tkey->mode);
00232 dns_unmarshall_uint16(&buf, &tkey->error);
00233 dns_unmarshall_uint16(&buf, &tkey->key_length);
00234
00235 if (!ERR_DNS_IS_OK(buf.error)) goto error;
00236
00237 if (tkey->key_length) {
00238 if (!(tkey->key = TALLOC_ARRAY(tkey, uint8, tkey->key_length))) {
00239 buf.error = ERROR_DNS_NO_MEMORY;
00240 goto error;
00241 }
00242 } else {
00243 tkey->key = NULL;
00244 }
00245
00246 dns_unmarshall_buffer(&buf, tkey->key, tkey->key_length);
00247 if (!ERR_DNS_IS_OK(buf.error)) goto error;
00248
00249 tkey->inception = (time_t)tmp_inception;
00250 tkey->expiration = (time_t)tmp_expiration;
00251
00252 *ptkey = tkey;
00253 return ERROR_DNS_SUCCESS;
00254
00255 error:
00256 TALLOC_FREE(tkey);
00257 return buf.error;
00258 }
00259
00260 DNS_ERROR dns_create_tsig_record(TALLOC_CTX *mem_ctx, const char *keyname,
00261 const char *algorithm_name,
00262 time_t time_signed, uint16 fudge,
00263 uint16 mac_length, const uint8 *mac,
00264 uint16 original_id, uint16 error,
00265 struct dns_rrec **prec)
00266 {
00267 struct dns_buffer *buf;
00268 struct dns_domain_name *algorithm;
00269 DNS_ERROR err;
00270
00271 if (!(buf = dns_create_buffer(mem_ctx))) {
00272 return ERROR_DNS_NO_MEMORY;
00273 }
00274
00275 err = dns_domain_name_from_string(buf, algorithm_name, &algorithm);
00276 if (!ERR_DNS_IS_OK(err)) goto error;
00277
00278 dns_marshall_domain_name(buf, algorithm);
00279 dns_marshall_uint16(buf, 0);
00280 dns_marshall_uint32(buf, time_signed);
00281 dns_marshall_uint16(buf, fudge);
00282 dns_marshall_uint16(buf, mac_length);
00283 dns_marshall_buffer(buf, mac, mac_length);
00284 dns_marshall_uint16(buf, original_id);
00285 dns_marshall_uint16(buf, error);
00286 dns_marshall_uint16(buf, 0);
00287
00288 if (!ERR_DNS_IS_OK(buf->error)) {
00289 err = buf->error;
00290 goto error;
00291 }
00292
00293 err = dns_create_rrec(mem_ctx, keyname, QTYPE_TSIG, DNS_CLASS_ANY, 0,
00294 buf->offset, buf->data, prec);
00295
00296 error:
00297 TALLOC_FREE(buf);
00298 return err;
00299 }
00300
00301 DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
00302 uint16 *num_records, struct dns_rrec ***records)
00303 {
00304 struct dns_rrec **new_records;
00305
00306 if (!(new_records = TALLOC_REALLOC_ARRAY(mem_ctx, *records,
00307 struct dns_rrec *,
00308 (*num_records)+1))) {
00309 return ERROR_DNS_NO_MEMORY;
00310 }
00311
00312 new_records[*num_records] = talloc_move(new_records, &rec);
00313
00314 *num_records += 1;
00315 *records = new_records;
00316 return ERROR_DNS_SUCCESS;
00317 }
00318
00319
00320
00321
00322
00323
00324 DNS_ERROR dns_create_probe(TALLOC_CTX *mem_ctx, const char *zone,
00325 const char *host, int num_ips,
00326 const struct in_addr *iplist,
00327 struct dns_update_request **preq)
00328 {
00329 struct dns_update_request *req;
00330 struct dns_rrec *rec;
00331 DNS_ERROR err;
00332 uint16 i;
00333
00334 err = dns_create_update(mem_ctx, zone, &req);
00335 if (!ERR_DNS_IS_OK(err)) goto error;
00336
00337 err = dns_create_name_not_in_use_record(req, host, QTYPE_CNAME, &rec);
00338 if (!ERR_DNS_IS_OK(err)) goto error;
00339
00340 err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs);
00341 if (!ERR_DNS_IS_OK(err)) goto error;
00342
00343 for (i=0; i<num_ips; i++) {
00344 err = dns_create_name_in_use_record(req, host,
00345 &iplist[i], &rec);
00346 if (!ERR_DNS_IS_OK(err)) goto error;
00347
00348 err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs);
00349 if (!ERR_DNS_IS_OK(err)) goto error;
00350 }
00351
00352 *preq = req;
00353 return ERROR_DNS_SUCCESS;
00354
00355 error:
00356 TALLOC_FREE(req);
00357 return err;
00358 }
00359
00360 DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
00361 const char *domainname,
00362 const char *hostname,
00363 const struct in_addr *ip_addrs,
00364 size_t num_addrs,
00365 struct dns_update_request **preq)
00366 {
00367 struct dns_update_request *req;
00368 struct dns_rrec *rec;
00369 DNS_ERROR err;
00370 size_t i;
00371
00372 err = dns_create_update(mem_ctx, domainname, &req);
00373 if (!ERR_DNS_IS_OK(err)) return err;
00374
00375
00376
00377
00378
00379 err = dns_create_rrec(req, domainname, QTYPE_ANY, DNS_CLASS_ANY,
00380 0, 0, NULL, &rec);
00381 if (!ERR_DNS_IS_OK(err)) goto error;
00382
00383 err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs);
00384 if (!ERR_DNS_IS_OK(err)) goto error;
00385
00386
00387
00388
00389
00390 err = dns_create_delete_record(req, hostname, QTYPE_A, DNS_CLASS_ANY,
00391 &rec);
00392 if (!ERR_DNS_IS_OK(err)) goto error;
00393
00394 err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
00395 if (!ERR_DNS_IS_OK(err)) goto error;
00396
00397
00398
00399
00400
00401 for ( i=0; i<num_addrs; i++ ) {
00402 err = dns_create_a_record(req, hostname, 3600, ip_addrs[i], &rec);
00403 if (!ERR_DNS_IS_OK(err))
00404 goto error;
00405
00406 err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
00407 if (!ERR_DNS_IS_OK(err))
00408 goto error;
00409 }
00410
00411 *preq = req;
00412 return ERROR_DNS_SUCCESS;
00413
00414 error:
00415 TALLOC_FREE(req);
00416 return err;
00417 }