str2host.c

Go to the documentation of this file.
00001 /*
00002  * str2host.c
00003  *
00004  * conversion routines from the presentation format
00005  * to the host format
00006  *
00007  * a Net::DNS like library for C
00008  *
00009  * (c) NLnet Labs, 2004-2006
00010  *
00011  * See the file LICENSE for the license
00012  */
00013 #include <ldns/config.h>
00014 
00015 #include <ldns/ldns.h>
00016 
00017 #ifdef HAVE_SYS_SOCKET_H
00018 #include <sys/socket.h>
00019 #endif
00020 #ifdef HAVE_ARPA_INET_H
00021 #include <arpa/inet.h>
00022 #endif
00023 #include <time.h>
00024 
00025 #include <errno.h>
00026 #ifdef HAVE_NETDB_H
00027 #include <netdb.h>
00028 #endif
00029 
00030 #include <limits.h>
00031 #ifdef HAVE_SYS_PARAM_H
00032 #include <sys/param.h>
00033 #endif
00034 
00035 ldns_status
00036 ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
00037 {
00038         char *end = NULL;
00039         uint16_t *r;
00040         r = LDNS_MALLOC(uint16_t);
00041         if(!r) return LDNS_STATUS_MEM_ERR;
00042 
00043         *r = htons((uint16_t)strtol((char *)shortstr, &end, 10));
00044 
00045         if(*end != 0) {
00046                 LDNS_FREE(r);
00047                 return LDNS_STATUS_INVALID_INT;
00048         } else {
00049                 *rd = ldns_rdf_new_frm_data(
00050                         LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
00051                 LDNS_FREE(r);
00052                 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00053         }
00054 }
00055 
00056 ldns_status
00057 ldns_str2rdf_time(ldns_rdf **rd, const char *time)
00058 {
00059         /* convert a time YYYYDDMMHHMMSS to wireformat */
00060         uint16_t *r = NULL;
00061         struct tm tm;
00062         uint32_t l;
00063         char *end;
00064 
00065         /* Try to scan the time... */
00066         r = (uint16_t*)LDNS_MALLOC(uint32_t);
00067         if(!r) return LDNS_STATUS_MEM_ERR;
00068 
00069         memset(&tm, 0, sizeof(tm));
00070 
00071         if (strlen(time) == 14 &&
00072             sscanf(time, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6
00073            ) {
00074                 tm.tm_year -= 1900;
00075                 tm.tm_mon--;
00076                 /* Check values */
00077                 if (tm.tm_year < 70) {
00078                         goto bad_format;
00079                 }
00080                 if (tm.tm_mon < 0 || tm.tm_mon > 11) {
00081                         goto bad_format;
00082                 }
00083                 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
00084                         goto bad_format;
00085                 }
00086 
00087                 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
00088                         goto bad_format;
00089                 }
00090 
00091                 if (tm.tm_min < 0 || tm.tm_min > 59) {
00092                         goto bad_format;
00093                 }
00094 
00095                 if (tm.tm_sec < 0 || tm.tm_sec > 59) {
00096                         goto bad_format;
00097                 }
00098 
00099                 l = htonl(mktime_from_utc(&tm));
00100                 memcpy(r, &l, sizeof(uint32_t));
00101                 *rd = ldns_rdf_new_frm_data(
00102                         LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
00103                 LDNS_FREE(r);
00104                 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00105         } else {
00106                 /* handle it as 32 bits timestamp */
00107                 l = htonl((uint32_t)strtol((char*)time, &end, 10));
00108                 if(*end != 0) {
00109                         LDNS_FREE(r);
00110                         return LDNS_STATUS_ERR;
00111                 } else {
00112                         memcpy(r, &l, sizeof(uint32_t));
00113                         *rd = ldns_rdf_new_frm_data(
00114                                 LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
00115                         LDNS_FREE(r);
00116                         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00117                 }
00118         }
00119 
00120         bad_format:
00121         LDNS_FREE(r);
00122         return LDNS_STATUS_INVALID_TIME;
00123 }
00124 
00125 ldns_status
00126 ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
00127 {
00128         uint8_t salt_length;
00129         int c;
00130         int salt_length_str;
00131 
00132         uint8_t *salt;
00133         uint8_t *data;
00134         if(rd == NULL) {
00135                 return LDNS_STATUS_NULL;
00136         }
00137 
00138         salt_length_str = (int)strlen(salt_str);
00139         if (salt_length_str == 1 && salt_str[0] == '-') {
00140                 salt_length_str = 0;
00141         } else if (salt_length_str % 2 != 0) {
00142                 return LDNS_STATUS_INVALID_HEX;
00143         }
00144         if (salt_length_str > 512) {
00145                 return LDNS_STATUS_INVALID_HEX;
00146         }
00147 
00148         salt = LDNS_XMALLOC(uint8_t, salt_length_str / 2);
00149         if(!salt) {
00150                 return LDNS_STATUS_MEM_ERR;
00151         }
00152         for (c = 0; c < salt_length_str; c += 2) {
00153                 if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
00154                         salt[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
00155                                           ldns_hexdigit_to_int(salt_str[c+1]);
00156                 } else {
00157                         LDNS_FREE(salt);
00158                         return LDNS_STATUS_INVALID_HEX;
00159                 }
00160         }
00161         salt_length = (uint8_t) (salt_length_str / 2);
00162 
00163         data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
00164         if(!data) {
00165                 LDNS_FREE(salt);
00166                 return LDNS_STATUS_MEM_ERR;
00167         }
00168         data[0] = salt_length;
00169         memcpy(&data[1], salt, salt_length);
00170         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1 + salt_length, data);
00171         LDNS_FREE(data);
00172         LDNS_FREE(salt);
00173 
00174         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00175 }
00176 
00177 ldns_status
00178 ldns_str2rdf_period(ldns_rdf **rd,const char *period)
00179 {
00180         uint32_t p;
00181         const char *end;
00182 
00183         /* Allocate required space... */
00184         p = ldns_str2period(period, &end);
00185 
00186         if (*end != 0) {
00187                 return LDNS_STATUS_ERR;
00188         } else {
00189                 p = (uint32_t) htonl(p);
00190                 *rd = ldns_rdf_new_frm_data(
00191                         LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
00192         }
00193         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00194 }
00195 
00196 ldns_status
00197 ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
00198 {
00199         char *end;
00200         uint16_t *r = NULL;
00201         uint32_t l;
00202 
00203         r = (uint16_t*)LDNS_MALLOC(uint32_t);
00204         if(!r) return LDNS_STATUS_MEM_ERR;
00205         errno = 0; /* must set to zero before call,
00206                         note race condition on errno */
00207         if(*longstr == '-')
00208                 l = htonl((uint32_t)strtol((char*)longstr, &end, 10));
00209         else    l = htonl((uint32_t)strtoul((char*)longstr, &end, 10));
00210 
00211         if(*end != 0) {
00212                 LDNS_FREE(r);
00213                 return LDNS_STATUS_ERR;
00214      } else {
00215                 if (errno == ERANGE) {
00216                         LDNS_FREE(r);
00217                         return LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW;
00218                 }
00219                 memcpy(r, &l, sizeof(uint32_t));
00220                 *rd = ldns_rdf_new_frm_data(
00221                         LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
00222                 LDNS_FREE(r);
00223                 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00224         }
00225 }
00226 
00227 ldns_status
00228 ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
00229 {
00230         char *end;
00231         uint8_t *r = NULL;
00232 
00233         r = LDNS_MALLOC(uint8_t);
00234         if(!r) return LDNS_STATUS_MEM_ERR;
00235 
00236         *r = (uint8_t)strtol((char*)bytestr, &end, 10);
00237 
00238         if(*end != 0) {
00239                 LDNS_FREE(r);
00240                 return LDNS_STATUS_ERR;
00241         } else {
00242                 *rd = ldns_rdf_new_frm_data(
00243                         LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
00244                 LDNS_FREE(r);
00245                 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00246         }
00247 }
00248 
00249 
00250 /*
00251  * Checks whether the escaped value at **s is an octal value or
00252  * a 'normally' escaped character (and not eos)
00253  *
00254  * The string pointer at *s is increased by either 0 (on error), 1 (on
00255  * normal escapes), or 3 (on octals)
00256  *
00257  * Returns the number of bytes read from the escaped string, or
00258  * 0 on error
00259  */
00260 static int
00261 parse_escape(uint8_t *s, uint8_t *q) {
00262         uint8_t val;
00263         if (strlen((char *)s) > 3 &&
00264             isdigit((int) s[1]) &&
00265             isdigit((int) s[2]) &&
00266             isdigit((int) s[3])) {
00267                 /* cast this so it fits */
00268                 val = (uint8_t) ldns_hexdigit_to_int((char) s[1]) * 100 +
00269                                 ldns_hexdigit_to_int((char) s[2]) * 10 +
00270                                 ldns_hexdigit_to_int((char) s[3]);
00271                 *q = val;
00272                 return 3;
00273         } else {
00274                 s++;
00275                 if (*s == '\0' || isdigit((int) *s)) {
00276                         /* apparently the string terminator
00277                          * or a digit has been escaped...
00278                          */
00279                         return 0;
00280                 }
00281                 *q = *s;
00282                 return 1;
00283         }
00284 }
00285 
00286 /*
00287  * No special care is taken, all dots are translated into
00288  * label seperators.
00289  * Could be made more efficient....we do 3 memcpy's in total...
00290  */
00291 ldns_status
00292 ldns_str2rdf_dname(ldns_rdf **d, const char *str)
00293 {
00294         size_t len;
00295 
00296         int esc;
00297         uint8_t *s, *q, *pq, label_len;
00298         uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
00299         *d = NULL;
00300 
00301         len = strlen((char*)str);
00302         /* octet representation can make strings a lot longer than actual length */
00303         if (len > LDNS_MAX_DOMAINLEN * 4) {
00304                 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00305         }
00306         if (0 == len) {
00307                 return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
00308         }
00309 
00310         /* root label */
00311         if (1 == len && *str == '.') {
00312                 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
00313                 return LDNS_STATUS_OK;
00314         }
00315 
00316         /* get on with the rest */
00317 
00318         /* s is on the current character in the string
00319          * pq points to where the labellength is going to go
00320          * label_len keeps track of the current label's length
00321          * q builds the dname inside the buf array
00322          */
00323         len = 0;
00324         q = buf+1;
00325         pq = buf;
00326         label_len = 0;
00327         for (s = (uint8_t *)str; *s; s++, q++) {
00328                 if (q > buf + LDNS_MAX_DOMAINLEN) {
00329                         return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00330                 }
00331                 *q = 0;
00332                 switch (*s) {
00333                 case '.':
00334                         if (label_len > LDNS_MAX_LABELLEN) {
00335                                 return LDNS_STATUS_LABEL_OVERFLOW;
00336                         }
00337                         if (label_len == 0) {
00338                                 return LDNS_STATUS_EMPTY_LABEL;
00339                         }
00340                         len += label_len + 1;
00341                         *pq = label_len;
00342                         label_len = 0;
00343                         pq = q;
00344                         break;
00345                 case '\\':
00346                         /* octet value or literal char */
00347                         esc = parse_escape(s, q);
00348                         if (esc > 0) {
00349                                 s += esc;
00350                                 label_len++;
00351                         } else {
00352                                 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00353                         }
00354                         break;
00355                 default:
00356                         *q = *s;
00357                         label_len++;
00358                 }
00359         }
00360 
00361         /* add root label if last char was not '.' */
00362         if (!ldns_dname_str_absolute(str)) {
00363                 if (q > buf + LDNS_MAX_DOMAINLEN) {
00364                         return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00365                 }
00366                 if (label_len > LDNS_MAX_LABELLEN) {
00367                         return LDNS_STATUS_LABEL_OVERFLOW;
00368                 }
00369                 if (label_len == 0) { /* label_len 0 but not . at end? */
00370                         return LDNS_STATUS_EMPTY_LABEL;
00371                 }
00372                 len += label_len + 1;
00373                 *pq = label_len;
00374                 *q = 0;
00375         }
00376         len++;
00377 
00378         *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
00379         return LDNS_STATUS_OK;
00380 }
00381 
00382 ldns_status
00383 ldns_str2rdf_a(ldns_rdf **rd, const char *str)
00384 {
00385         in_addr_t address;
00386         if (inet_pton(AF_INET, (char*)str, &address) != 1) {
00387                 return LDNS_STATUS_INVALID_IP4;
00388         } else {
00389                 *rd = ldns_rdf_new_frm_data(
00390                         LDNS_RDF_TYPE_A, sizeof(address), &address);
00391         }
00392         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00393 }
00394 
00395 ldns_status
00396 ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
00397 {
00398         uint8_t address[LDNS_IP6ADDRLEN + 1];
00399 
00400         if (inet_pton(AF_INET6, (char*)str, address) != 1) {
00401                 return LDNS_STATUS_INVALID_IP6;
00402         } else {
00403                 *rd = ldns_rdf_new_frm_data(
00404                         LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
00405         }
00406         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00407 }
00408 
00409 ldns_status
00410 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
00411 {
00412         uint8_t *data;
00413         size_t i, str_i, esc_i;
00414 
00415         if (strlen(str) > 255) {
00416                 return LDNS_STATUS_INVALID_STR;
00417         }
00418 
00419         data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
00420         if(!data) return LDNS_STATUS_MEM_ERR;
00421         i = 1;
00422 
00423         for (str_i = 0; str_i < strlen(str); str_i++) {
00424                 if (str[str_i] == '\\') {
00425                         /* octet value or literal char */
00426                         esc_i = (size_t) parse_escape((uint8_t*) &str[str_i], (uint8_t*) &data[i]);
00427                         if (esc_i == 0) {
00428                                 LDNS_FREE(data);
00429                                 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00430                         }
00431                         str_i += esc_i;
00432                 } else {
00433                         data[i] = (uint8_t) str[str_i];
00434                 }
00435                 i++;
00436         }
00437         data[0] = i - 1;
00438         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR, i, data);
00439 
00440         LDNS_FREE(data);
00441         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00442 }
00443 
00444 ldns_status
00445 ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
00446 {
00447         const char *my_str = str;
00448 
00449         char *my_ip_str;
00450         size_t ip_str_len;
00451 
00452         uint16_t family;
00453         bool negation;
00454         uint8_t afdlength = 0;
00455         uint8_t *afdpart;
00456         uint8_t prefix;
00457 
00458         uint8_t *data;
00459 
00460         size_t i = 0;
00461 
00462         /* [!]afi:address/prefix */
00463         if (strlen(my_str) < 2
00464                         || strchr(my_str, ':') == NULL
00465                         || strchr(my_str, '/') == NULL
00466                         || strchr(my_str, ':') > strchr(my_str, '/')) {
00467                 return LDNS_STATUS_INVALID_STR;
00468         }
00469 
00470         if (my_str[0] == '!') {
00471                 negation = true;
00472                 my_str += 1;
00473         } else {
00474                 negation = false;
00475         }
00476 
00477         family = (uint16_t) atoi(my_str);
00478 
00479         my_str = strchr(my_str, ':') + 1;
00480 
00481         /* need ip addr and only ip addr for inet_pton */
00482         ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
00483         my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
00484         if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
00485         strncpy(my_ip_str, my_str, ip_str_len + 1);
00486         my_ip_str[ip_str_len] = '\0';
00487 
00488         if (family == 1) {
00489                 /* ipv4 */
00490                 afdpart = LDNS_XMALLOC(uint8_t, 4);
00491                 if(!afdpart) {
00492                         LDNS_FREE(my_ip_str);
00493                         return LDNS_STATUS_MEM_ERR;
00494                 }
00495                 if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
00496                         LDNS_FREE(my_ip_str);
00497                         LDNS_FREE(afdpart);
00498                         return LDNS_STATUS_INVALID_STR;
00499                 }
00500                 for (i = 0; i < 4; i++) {
00501                         if (afdpart[i] != 0) {
00502                                 afdlength = i + 1;
00503                         }
00504                 }
00505         } else if (family == 2) {
00506                 /* ipv6 */
00507                 afdpart = LDNS_XMALLOC(uint8_t, 16);
00508                 if(!afdpart) {
00509                         LDNS_FREE(my_ip_str);
00510                         return LDNS_STATUS_MEM_ERR;
00511                 }
00512                 if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
00513                         LDNS_FREE(my_ip_str);
00514                         LDNS_FREE(afdpart);
00515                         return LDNS_STATUS_INVALID_STR;
00516                 }
00517                 for (i = 0; i < 16; i++) {
00518                         if (afdpart[i] != 0) {
00519                                 afdlength = i + 1;
00520                         }
00521                 }
00522         } else {
00523                 /* unknown family */
00524                 LDNS_FREE(my_ip_str);
00525                 return LDNS_STATUS_INVALID_STR;
00526         }
00527 
00528         my_str = strchr(my_str, '/') + 1;
00529         prefix = (uint8_t) atoi(my_str);
00530 
00531         data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
00532         if(!data) {
00533                 LDNS_FREE(my_ip_str);
00534                 return LDNS_STATUS_INVALID_STR;
00535         }
00536         ldns_write_uint16(data, family);
00537         data[2] = prefix;
00538         data[3] = afdlength;
00539         if (negation) {
00540                 /* set bit 1 of byte 3 */
00541                 data[3] = data[3] | 0x80;
00542         }
00543 
00544         memcpy(data + 4, afdpart, afdlength);
00545 
00546         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
00547         LDNS_FREE(afdpart);
00548         LDNS_FREE(data);
00549         LDNS_FREE(my_ip_str);
00550 
00551         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00552 }
00553 
00554 ldns_status
00555 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
00556 {
00557         uint8_t *buffer;
00558         int16_t i;
00559 
00560         buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
00561         if(!buffer) {
00562                 return LDNS_STATUS_MEM_ERR;
00563         }
00564 
00565         i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
00566                                                    ldns_b64_ntop_calculate_size(strlen(str)));
00567         if (-1 == i) {
00568                 LDNS_FREE(buffer);
00569                 return LDNS_STATUS_INVALID_B64;
00570         } else {
00571                 *rd = ldns_rdf_new_frm_data(
00572                         LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
00573         }
00574         LDNS_FREE(buffer);
00575 
00576         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00577 }
00578 
00579 ldns_status
00580 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
00581 {
00582         uint8_t *buffer;
00583         int i;
00584         /* first byte contains length of actual b32 data */
00585         uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
00586         buffer = LDNS_XMALLOC(uint8_t, len + 1);
00587         if(!buffer) {
00588                 return LDNS_STATUS_MEM_ERR;
00589         }
00590         buffer[0] = len;
00591 
00592         i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
00593                                                          ldns_b32_ntop_calculate_size(strlen(str)));
00594         if (i < 0) {
00595                 LDNS_FREE(buffer);
00596                 return LDNS_STATUS_INVALID_B32_EXT;
00597         } else {
00598                 *rd = ldns_rdf_new_frm_data(
00599                         LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
00600         }
00601         LDNS_FREE(buffer);
00602 
00603         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00604 }
00605 
00606 ldns_status
00607 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
00608 {
00609         uint8_t *t, *t_orig;
00610         int i;
00611         size_t len;
00612 
00613         len = strlen(str);
00614 
00615         if (len > LDNS_MAX_RDFLEN * 2) {
00616                 return LDNS_STATUS_LABEL_OVERFLOW;
00617         } else {
00618                 t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
00619                 if(!t) {
00620                         return LDNS_STATUS_MEM_ERR;
00621                 }
00622                 t_orig = t;
00623                 /* Now process octet by octet... */
00624                 while (*str) {
00625                         *t = 0;
00626                         if (isspace((int) *str)) {
00627                                 str++;
00628                         } else {
00629                                 for (i = 16; i >= 1; i -= 15) {
00630                                         while (*str && isspace((int) *str)) { str++; }
00631                                         if (*str) {
00632                                                 if (isxdigit((int) *str)) {
00633                                                         *t += ldns_hexdigit_to_int(*str) * i;
00634                                                 } else {
00635                                                         LDNS_FREE(t_orig);
00636                                                         return LDNS_STATUS_ERR;
00637                                                 }
00638                                                 ++str;
00639                                         }
00640                                 }
00641                                 ++t;
00642                         }
00643                 }
00644                 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
00645                                             (size_t) (t - t_orig),
00646                                             t_orig);
00647                 LDNS_FREE(t_orig);
00648         }
00649         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00650 }
00651 
00652 ldns_status
00653 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
00654 {
00655         const char *delimiters = "\n\t ";
00656         char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
00657         ldns_buffer *str_buf;
00658         ssize_t c;
00659         uint16_t cur_type;
00660         size_t type_count = 0;
00661         ldns_rr_type type_list[65536];
00662         if(!token) return LDNS_STATUS_MEM_ERR;
00663         if(rd == NULL) {
00664                 LDNS_FREE(token);
00665                 return LDNS_STATUS_NULL;
00666         }
00667 
00668         str_buf = LDNS_MALLOC(ldns_buffer);
00669         if(!str_buf) {
00670                 LDNS_FREE(token);
00671                 return LDNS_STATUS_MEM_ERR;
00672         }
00673         ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00674         if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
00675                 LDNS_FREE(str_buf);
00676                 LDNS_FREE(token);
00677                 return LDNS_STATUS_MEM_ERR;
00678         }
00679 
00680         while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
00681                 if(type_count >= sizeof(type_list)) {
00682                         LDNS_FREE(str_buf);
00683                         LDNS_FREE(token);
00684                         return LDNS_STATUS_ERR;
00685                 }
00686                 cur_type = ldns_get_rr_type_by_name(token);
00687                 type_list[type_count] = cur_type;
00688                 type_count++;
00689         }
00690 
00691         *rd = ldns_dnssec_create_nsec_bitmap(type_list,
00692                                              type_count,
00693                                              LDNS_RR_TYPE_NSEC);
00694 
00695         LDNS_FREE(token);
00696         ldns_buffer_free(str_buf);
00697         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00698 }
00699 
00700 ldns_status
00701 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
00702 {
00703         uint16_t type;
00704         type = htons(ldns_get_rr_type_by_name(str));
00705         /* ldns_rr_type is a 16 bit value */
00706         *rd = ldns_rdf_new_frm_data(
00707                 LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
00708         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00709 }
00710 
00711 ldns_status
00712 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
00713 {
00714         uint16_t klass;
00715         klass = htons(ldns_get_rr_class_by_name(str));
00716         /* class is 16 bit */
00717         *rd = ldns_rdf_new_frm_data(
00718                 LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
00719         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00720 }
00721 
00722 /* An certificate alg field can either be specified as a 8 bits number
00723  * or by its symbolic name. Handle both
00724  */
00725 ldns_status
00726 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
00727 {
00728         ldns_lookup_table *lt;
00729         ldns_status st;
00730         uint8_t idd[2];
00731         lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
00732         st = LDNS_STATUS_OK;
00733 
00734         if (lt) {
00735                 ldns_write_uint16(idd, (uint16_t) lt->id);
00736                 *rd = ldns_rdf_new_frm_data(
00737                         LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
00738                 if (!*rd) {
00739                         st = LDNS_STATUS_ERR;
00740                 }
00741         } else {
00742                 /* try as-is (a number) */
00743                 st = ldns_str2rdf_int16(rd, str);
00744                 if (st == LDNS_STATUS_OK &&
00745                     ldns_rdf2native_int16(*rd) == 0) {
00746                         st = LDNS_STATUS_CERT_BAD_ALGORITHM;
00747                 }
00748         }
00749 
00750         return st;
00751 }
00752 
00753 /* An alg field can either be specified as a 8 bits number
00754  * or by its symbolic name. Handle both
00755  */
00756 ldns_status
00757 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
00758 {
00759         ldns_lookup_table *lt;
00760         ldns_status st;
00761 
00762         lt = ldns_lookup_by_name(ldns_algorithms, str);
00763         st = LDNS_STATUS_OK;
00764 
00765         if (lt) {
00766                 /* it was given as a integer */
00767                 *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
00768                 if (!*rd) {
00769                         st = LDNS_STATUS_ERR;
00770                 }
00771         } else {
00772                 /* try as-is (a number) */
00773                 st = ldns_str2rdf_int8(rd, str);
00774         }
00775         return st;
00776 }
00777 
00778 ldns_status
00779 ldns_str2rdf_unknown(ldns_rdf **rd, const char *str)
00780 {
00781         /* this should be caught in an earlier time (general str2host for
00782            rr's */
00783         rd = rd;
00784         str = str;
00785         return LDNS_STATUS_NOT_IMPL;
00786 }
00787 
00788 ldns_status
00789 ldns_str2rdf_tsig(ldns_rdf **rd, const char *str)
00790 {
00791         /* there is no strign representation for TSIG rrs */
00792         rd = rd;
00793         str = str;
00794         return LDNS_STATUS_NOT_IMPL;
00795 }
00796 
00797 ldns_status
00798 ldns_str2rdf_service(ldns_rdf **rd, const char *str)
00799 {
00800         /* is this used? is this actually WKS? or SRV? */
00801         rd = rd;
00802         str = str;
00803         return LDNS_STATUS_NOT_IMPL;
00804 }
00805 
00806 static int
00807 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
00808 {
00809         /* read <digits>[.<digits>][mM] */
00810         /* into mantissa exponent format for LOC type */
00811         uint32_t meters = 0, cm = 0, val;
00812         while (isblank(*my_str)) {
00813                 my_str++;
00814         }
00815         meters = (uint32_t)strtol(my_str, &my_str, 10);
00816         if (*my_str == '.') {
00817                 my_str++;
00818                 cm = (uint32_t)strtol(my_str, &my_str, 10);
00819         }
00820         if (meters >= 1) {
00821                 *e = 2;
00822                 val = meters;
00823         } else  {
00824                 *e = 0;
00825                 val = cm;
00826         }
00827         while(val >= 10) {
00828                 (*e)++;
00829                 val /= 10;
00830         }
00831         *m = (uint8_t)val;
00832 
00833         if (*e > 9)
00834                 return 0;
00835         if (*my_str == 'm' || *my_str == 'M') {
00836                 my_str++;
00837         }
00838         *endstr = my_str;
00839         return 1;
00840 }
00841 
00842 ldns_status
00843 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
00844 {
00845         uint32_t latitude = 0;
00846         uint32_t longitude = 0;
00847         uint32_t altitude = 0;
00848 
00849         uint8_t *data;
00850         uint32_t equator = (uint32_t) ldns_power(2, 31);
00851 
00852         uint32_t h = 0;
00853         uint32_t m = 0;
00854         uint8_t size_b = 1, size_e = 2;
00855         uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
00856         uint8_t vert_pre_b = 1, vert_pre_e = 3;
00857 
00858         double s = 0.0;
00859         bool northerness;
00860         bool easterness;
00861 
00862         char *my_str = (char *) str;
00863 
00864         /* only support version 0 */
00865         if (isdigit((int) *my_str)) {
00866                 h = (uint32_t) strtol(my_str, &my_str, 10);
00867         } else {
00868                 return LDNS_STATUS_INVALID_STR;
00869         }
00870 
00871         while (isblank((int) *my_str)) {
00872                 my_str++;
00873         }
00874 
00875         if (isdigit((int) *my_str)) {
00876                 m = (uint32_t) strtol(my_str, &my_str, 10);
00877         } else if (*my_str == 'N' || *my_str == 'S') {
00878                 goto north;
00879         } else {
00880                 return LDNS_STATUS_INVALID_STR;
00881         }
00882 
00883         while (isblank((int) *my_str)) {
00884                 my_str++;
00885         }
00886 
00887         if (isdigit((int) *my_str)) {
00888                 s = strtod(my_str, &my_str);
00889         }
00890 north:
00891         while (isblank((int) *my_str)) {
00892                 my_str++;
00893         }
00894 
00895         if (*my_str == 'N') {
00896                 northerness = true;
00897         } else if (*my_str == 'S') {
00898                 northerness = false;
00899         } else {
00900                 return LDNS_STATUS_INVALID_STR;
00901         }
00902 
00903         my_str++;
00904 
00905         /* store number */
00906         s = 1000.0 * s;
00907         /* add a little to make floor in conversion a round */
00908         s += 0.0005;
00909         latitude = (uint32_t) s;
00910         latitude += 1000 * 60 * m;
00911         latitude += 1000 * 60 * 60 * h;
00912         if (northerness) {
00913                 latitude = equator + latitude;
00914         } else {
00915                 latitude = equator - latitude;
00916         }
00917         while (isblank(*my_str)) {
00918                 my_str++;
00919         }
00920 
00921         if (isdigit((int) *my_str)) {
00922                 h = (uint32_t) strtol(my_str, &my_str, 10);
00923         } else {
00924                 return LDNS_STATUS_INVALID_STR;
00925         }
00926 
00927         while (isblank((int) *my_str)) {
00928                 my_str++;
00929         }
00930 
00931         if (isdigit((int) *my_str)) {
00932                 m = (uint32_t) strtol(my_str, &my_str, 10);
00933         } else if (*my_str == 'E' || *my_str == 'W') {
00934                 goto east;
00935         } else {
00936                 return LDNS_STATUS_INVALID_STR;
00937         }
00938 
00939         while (isblank(*my_str)) {
00940                 my_str++;
00941         }
00942 
00943         if (isdigit((int) *my_str)) {
00944                 s = strtod(my_str, &my_str);
00945         }
00946 
00947 east:
00948         while (isblank(*my_str)) {
00949                 my_str++;
00950         }
00951 
00952         if (*my_str == 'E') {
00953                 easterness = true;
00954         } else if (*my_str == 'W') {
00955                 easterness = false;
00956         } else {
00957                 return LDNS_STATUS_INVALID_STR;
00958         }
00959 
00960         my_str++;
00961 
00962         /* store number */
00963         s *= 1000.0;
00964         /* add a little to make floor in conversion a round */
00965         s += 0.0005;
00966         longitude = (uint32_t) s;
00967         longitude += 1000 * 60 * m;
00968         longitude += 1000 * 60 * 60 * h;
00969 
00970         if (easterness) {
00971                 longitude += equator;
00972         } else {
00973                 longitude = equator - longitude;
00974         }
00975 
00976         altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
00977                 10000000.0 + 0.5);
00978         if (*my_str == 'm' || *my_str == 'M') {
00979                 my_str++;
00980         }
00981 
00982         if (strlen(my_str) > 0) {
00983                 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
00984                         return LDNS_STATUS_INVALID_STR;
00985         }
00986 
00987         if (strlen(my_str) > 0) {
00988                 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
00989                         return LDNS_STATUS_INVALID_STR;
00990         }
00991 
00992         if (strlen(my_str) > 0) {
00993                 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
00994                         return LDNS_STATUS_INVALID_STR;
00995         }
00996 
00997         data = LDNS_XMALLOC(uint8_t, 16);
00998         if(!data) {
00999                 return LDNS_STATUS_MEM_ERR;
01000         }
01001         data[0] = 0;
01002         data[1] = 0;
01003         data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
01004         data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
01005         data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
01006         ldns_write_uint32(data + 4, latitude);
01007         ldns_write_uint32(data + 8, longitude);
01008         ldns_write_uint32(data + 12, altitude);
01009 
01010         *rd = ldns_rdf_new_frm_data(
01011                 LDNS_RDF_TYPE_LOC, 16, data);
01012 
01013         LDNS_FREE(data);
01014         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
01015 }
01016 
01017 ldns_status
01018 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
01019 {
01020         uint8_t *bitmap = NULL;
01021         uint8_t *data;
01022         int bm_len = 0;
01023 
01024         struct protoent *proto = NULL;
01025         struct servent *serv = NULL;
01026         int serv_port;
01027 
01028         ldns_buffer *str_buf;
01029 
01030         char *proto_str = NULL;
01031         char *token;
01032         if(strlen(str) == 0)
01033                 token = LDNS_XMALLOC(char, 50);
01034         else    token = LDNS_XMALLOC(char, strlen(str)+2);
01035         if(!token) return LDNS_STATUS_MEM_ERR;
01036 
01037         str_buf = LDNS_MALLOC(ldns_buffer);
01038         if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01039         ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01040         if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01041                 LDNS_FREE(str_buf);
01042                 LDNS_FREE(token);
01043                 return LDNS_STATUS_MEM_ERR;
01044         }
01045 
01046         while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01047                 if (!proto_str) {
01048                         proto_str = strdup(token);
01049                         if (!proto_str) {
01050                                 LDNS_FREE(bitmap);
01051                                 LDNS_FREE(token);
01052                                 ldns_buffer_free(str_buf);
01053                                 return LDNS_STATUS_INVALID_STR;
01054                         }
01055                 } else {
01056                         serv = getservbyname(token, proto_str);
01057                         if (serv) {
01058                                 serv_port = (int) ntohs((uint16_t) serv->s_port);
01059                         } else {
01060                                 serv_port = atoi(token);
01061                         }
01062                         if (serv_port / 8 >= bm_len) {
01063                                 uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
01064                                 if(!b2) {
01065                                         LDNS_FREE(bitmap);
01066                                         LDNS_FREE(token);
01067                                         ldns_buffer_free(str_buf);
01068                                         free(proto_str);
01069                                         return LDNS_STATUS_INVALID_STR;
01070                                 }
01071                                 bitmap = b2;
01072                                 /* set to zero to be sure */
01073                                 for (; bm_len <= serv_port / 8; bm_len++) {
01074                                         bitmap[bm_len] = 0;
01075                                 }
01076                         }
01077                         ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
01078                 }
01079         }
01080 
01081         if (!proto_str || !bitmap) {
01082                 LDNS_FREE(bitmap);
01083                 LDNS_FREE(token);
01084                 ldns_buffer_free(str_buf);
01085                 free(proto_str);
01086                 return LDNS_STATUS_INVALID_STR;
01087         }
01088 
01089         data = LDNS_XMALLOC(uint8_t, bm_len + 1);
01090         if(!data) {
01091                 LDNS_FREE(token);
01092                 ldns_buffer_free(str_buf);
01093                 LDNS_FREE(bitmap);
01094                 free(proto_str);
01095                 return LDNS_STATUS_INVALID_STR;
01096         }
01097     if (proto_str)
01098                 proto = getprotobyname(proto_str);
01099         if (proto) {
01100                 data[0] = (uint8_t) proto->p_proto;
01101         } else if (proto_str) {
01102                 data[0] = (uint8_t) atoi(proto_str);
01103         } else {
01104                 data[0] = 0;
01105         }
01106         memcpy(data + 1, bitmap, (size_t) bm_len);
01107 
01108         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
01109 
01110         LDNS_FREE(data);
01111         LDNS_FREE(token);
01112         ldns_buffer_free(str_buf);
01113         LDNS_FREE(bitmap);
01114         free(proto_str);
01115 #ifdef HAVE_ENDSERVENT
01116         endservent();
01117 #endif
01118 #ifdef HAVE_ENDPROTOENT
01119         endprotoent();
01120 #endif
01121 
01122         if(!*rd) return LDNS_STATUS_MEM_ERR;
01123 
01124         return LDNS_STATUS_OK;
01125 }
01126 
01127 ldns_status
01128 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
01129 {
01130     size_t len, i;
01131     char* nsap_str = (char*) str;
01132 
01133         /* just a hex string with optional dots? */
01134         if (str[0] != '0' || str[1] != 'x') {
01135                 return LDNS_STATUS_INVALID_STR;
01136         } else {
01137                 len = strlen(str);
01138                 for (i=0; i < len; i++) {
01139                         if (nsap_str[i] == '.')
01140                                 nsap_str[i] = ' ';
01141         }
01142                 return ldns_str2rdf_hex(rd, str+2);
01143         }
01144 }
01145 
01146 ldns_status
01147 ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
01148 {
01149     size_t len, i;
01150     char* atma_str = (char*) str;
01151         ldns_status status;
01152 
01153         /* just a hex string with optional dots? */
01154         len = strlen(str);
01155         for (i=0; i < len; i++) {
01156                 if (atma_str[i] == '.')
01157                         atma_str[i] = ' ';
01158         }
01159         status = ldns_str2rdf_hex(rd, str);
01160     if (status != LDNS_STATUS_OK) {
01161                 ; /* probably in e.164 format than */
01162         }
01163         return status;
01164 }
01165 
01166 ldns_status
01167 ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
01168 {
01169         uint8_t precedence = 0;
01170         uint8_t gateway_type = 0;
01171         uint8_t algorithm = 0;
01172         char* gateway = NULL;
01173         char* publickey = NULL;
01174         uint8_t *data;
01175         ldns_buffer *str_buf;
01176         char *token;
01177         int token_count = 0;
01178         int ipseckey_len = 0;
01179         ldns_rdf* gateway_rdf = NULL;
01180         ldns_rdf* publickey_rdf = NULL;
01181         ldns_status status = LDNS_STATUS_OK;
01182         
01183         if(strlen(str) == 0)
01184                 token = LDNS_XMALLOC(char, 256);
01185         else    token = LDNS_XMALLOC(char, strlen(str)+2);
01186         if(!token) return LDNS_STATUS_MEM_ERR;
01187 
01188         str_buf = LDNS_MALLOC(ldns_buffer);
01189         if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01190         ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01191         if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01192                 LDNS_FREE(str_buf);
01193                 LDNS_FREE(token);
01194                 return LDNS_STATUS_MEM_ERR;
01195         }
01196         while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01197                 switch (token_count) {
01198                                 case 0:
01199                                         precedence = (uint8_t)atoi(token);
01200                                         break;
01201                                 case 1:
01202                                         gateway_type = (uint8_t)atoi(token);
01203                                         break;
01204                                 case 2:
01205                                         algorithm = (uint8_t)atoi(token);
01206                                         break;
01207                                 case 3:
01208                                         gateway = strdup(token);
01209                                         if (!gateway || (gateway_type == 0 &&
01210                                                         (token[0] != '.' || token[1] != '\0'))) {
01211                                                 LDNS_FREE(gateway);
01212                                                 LDNS_FREE(token);
01213                                                 ldns_buffer_free(str_buf);
01214                                                 return LDNS_STATUS_INVALID_STR;
01215                                         }
01216                                         break;
01217                                 case 4:
01218                                         publickey = strdup(token);
01219                                         break;
01220                                 default:
01221                                         LDNS_FREE(token);
01222                                         ldns_buffer_free(str_buf);
01223                                         return LDNS_STATUS_INVALID_STR;
01224                                         break;
01225                 }
01226                 token_count++;
01227         }
01228 
01229         if (!gateway || !publickey) {
01230                 if (gateway)
01231                         LDNS_FREE(gateway);
01232                 if (publickey)
01233                         LDNS_FREE(publickey);
01234                 LDNS_FREE(token);
01235                 ldns_buffer_free(str_buf);
01236                 return LDNS_STATUS_INVALID_STR;
01237         }
01238 
01239         if (gateway_type == 1) {
01240                 status = ldns_str2rdf_a(&gateway_rdf, gateway);
01241         } else if (gateway_type == 2) {
01242                 status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
01243         } else if (gateway_type == 3) {
01244                 status = ldns_str2rdf_dname(&gateway_rdf, gateway);
01245         }
01246 
01247         if (status != LDNS_STATUS_OK) {
01248                 if (gateway)
01249                         LDNS_FREE(gateway);
01250                 if (publickey)
01251                         LDNS_FREE(publickey);
01252                 LDNS_FREE(token);
01253                 ldns_buffer_free(str_buf);
01254                 return LDNS_STATUS_INVALID_STR;
01255         }
01256 
01257         status = ldns_str2rdf_b64(&publickey_rdf, publickey);
01258 
01259         if (status != LDNS_STATUS_OK) {
01260                 if (gateway)
01261                         LDNS_FREE(gateway);
01262                 if (publickey)
01263                         LDNS_FREE(publickey);
01264                 LDNS_FREE(token);
01265                 ldns_buffer_free(str_buf);
01266                 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01267                 return LDNS_STATUS_INVALID_STR;
01268         }
01269 
01270         /* now copy all into one ipseckey rdf */
01271         if (gateway_type)
01272                 ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
01273         else
01274                 ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
01275 
01276         data = LDNS_XMALLOC(uint8_t, ipseckey_len);
01277         if(!data) {
01278                 if (gateway)
01279                         LDNS_FREE(gateway);
01280                 if (publickey)
01281                         LDNS_FREE(publickey);
01282                 LDNS_FREE(token);
01283                 ldns_buffer_free(str_buf);
01284                 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01285                 if (publickey_rdf) ldns_rdf_free(publickey_rdf);
01286                 return LDNS_STATUS_MEM_ERR;
01287         }
01288 
01289         data[0] = precedence;
01290         data[1] = gateway_type;
01291         data[2] = algorithm;
01292 
01293         if (gateway_type) {
01294                 memcpy(data + 3,
01295                         ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
01296                 memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
01297                         ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01298         } else {
01299                 memcpy(data + 3,
01300                         ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01301         }
01302 
01303         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
01304 
01305         if (gateway)
01306                 LDNS_FREE(gateway);
01307         if (publickey)
01308                 LDNS_FREE(publickey);
01309         LDNS_FREE(token);
01310         ldns_buffer_free(str_buf);
01311         ldns_rdf_free(gateway_rdf);
01312         ldns_rdf_free(publickey_rdf);
01313         LDNS_FREE(data);
01314         if(!*rd) return LDNS_STATUS_MEM_ERR;
01315         return LDNS_STATUS_OK;
01316 }

Generated on Thu Apr 5 23:03:55 2012 for ldns by  doxygen 1.4.7