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(ldns_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         uint16_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 = (uint16_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                 if (val > 255) {
00272                         /* outside range */
00273                         return 0;
00274                 }
00275                 *q = (uint8_t) val;
00276                 return 3;
00277         } else {
00278                 s++;
00279                 if (*s == '\0' || isdigit((int) *s)) {
00280                         /* apparently the string terminator
00281                          * or a digit has been escaped...
00282                          */
00283                         return 0;
00284                 }
00285                 *q = *s;
00286                 return 1;
00287         }
00288 }
00289 
00290 /*
00291  * No special care is taken, all dots are translated into
00292  * label seperators.
00293  * Could be made more efficient....we do 3 memcpy's in total...
00294  */
00295 ldns_status
00296 ldns_str2rdf_dname(ldns_rdf **d, const char *str)
00297 {
00298         size_t len;
00299 
00300         int esc;
00301         uint8_t *s, *q, *pq, label_len;
00302         uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
00303         *d = NULL;
00304 
00305         len = strlen((char*)str);
00306         /* octet representation can make strings a lot longer than actual length */
00307         if (len > LDNS_MAX_DOMAINLEN * 4) {
00308                 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00309         }
00310         if (0 == len) {
00311                 return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
00312         }
00313 
00314         /* root label */
00315         if (1 == len && *str == '.') {
00316                 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
00317                 return LDNS_STATUS_OK;
00318         }
00319 
00320         /* get on with the rest */
00321 
00322         /* s is on the current character in the string
00323          * pq points to where the labellength is going to go
00324          * label_len keeps track of the current label's length
00325          * q builds the dname inside the buf array
00326          */
00327         len = 0;
00328         q = buf+1;
00329         pq = buf;
00330         label_len = 0;
00331         for (s = (uint8_t *)str; *s; s++, q++) {
00332                 if (q > buf + LDNS_MAX_DOMAINLEN) {
00333                         return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00334                 }
00335                 *q = 0;
00336                 switch (*s) {
00337                 case '.':
00338                         if (label_len > LDNS_MAX_LABELLEN) {
00339                                 return LDNS_STATUS_LABEL_OVERFLOW;
00340                         }
00341                         if (label_len == 0) {
00342                                 return LDNS_STATUS_EMPTY_LABEL;
00343                         }
00344                         len += label_len + 1;
00345                         *pq = label_len;
00346                         label_len = 0;
00347                         pq = q;
00348                         break;
00349                 case '\\':
00350                         /* octet value or literal char */
00351                         esc = parse_escape(s, q);
00352                         if (esc > 0) {
00353                                 s += esc;
00354                                 label_len++;
00355                         } else {
00356                                 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00357                         }
00358                         break;
00359                 default:
00360                         *q = *s;
00361                         label_len++;
00362                 }
00363         }
00364 
00365         /* add root label if last char was not '.' */
00366         if (!ldns_dname_str_absolute(str)) {
00367                 if (q > buf + LDNS_MAX_DOMAINLEN) {
00368                         return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00369                 }
00370                 if (label_len > LDNS_MAX_LABELLEN) {
00371                         return LDNS_STATUS_LABEL_OVERFLOW;
00372                 }
00373                 if (label_len == 0) { /* label_len 0 but not . at end? */
00374                         return LDNS_STATUS_EMPTY_LABEL;
00375                 }
00376                 len += label_len + 1;
00377                 *pq = label_len;
00378                 *q = 0;
00379         }
00380         len++;
00381 
00382         *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
00383         return LDNS_STATUS_OK;
00384 }
00385 
00386 ldns_status
00387 ldns_str2rdf_a(ldns_rdf **rd, const char *str)
00388 {
00389         in_addr_t address;
00390         if (inet_pton(AF_INET, (char*)str, &address) != 1) {
00391                 return LDNS_STATUS_INVALID_IP4;
00392         } else {
00393                 *rd = ldns_rdf_new_frm_data(
00394                         LDNS_RDF_TYPE_A, sizeof(address), &address);
00395         }
00396         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00397 }
00398 
00399 ldns_status
00400 ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
00401 {
00402         uint8_t address[LDNS_IP6ADDRLEN + 1];
00403 
00404         if (inet_pton(AF_INET6, (char*)str, address) != 1) {
00405                 return LDNS_STATUS_INVALID_IP6;
00406         } else {
00407                 *rd = ldns_rdf_new_frm_data(
00408                         LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
00409         }
00410         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00411 }
00412 
00413 ldns_status
00414 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
00415 {
00416         uint8_t *data;
00417         size_t i, str_i, esc_i;
00418 
00419         if (strlen(str) > 255) {
00420                 return LDNS_STATUS_INVALID_STR;
00421         }
00422 
00423         data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
00424         if(!data) return LDNS_STATUS_MEM_ERR;
00425         i = 1;
00426 
00427         for (str_i = 0; str_i < strlen(str); str_i++) {
00428                 if (str[str_i] == '\\') {
00429                         /* octet value or literal char */
00430                         esc_i = (size_t) parse_escape((uint8_t*) &str[str_i], (uint8_t*) &data[i]);
00431                         if (esc_i == 0) {
00432                                 LDNS_FREE(data);
00433                                 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00434                         }
00435                         str_i += esc_i;
00436                 } else {
00437                         data[i] = (uint8_t) str[str_i];
00438                 }
00439                 i++;
00440         }
00441         data[0] = i - 1;
00442         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR, i, data);
00443 
00444         LDNS_FREE(data);
00445         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00446 }
00447 
00448 ldns_status
00449 ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
00450 {
00451         const char *my_str = str;
00452 
00453         char *my_ip_str;
00454         size_t ip_str_len;
00455 
00456         uint16_t family;
00457         bool negation;
00458         uint8_t afdlength = 0;
00459         uint8_t *afdpart;
00460         uint8_t prefix;
00461 
00462         uint8_t *data;
00463 
00464         size_t i = 0;
00465 
00466         /* [!]afi:address/prefix */
00467         if (strlen(my_str) < 2
00468                         || strchr(my_str, ':') == NULL
00469                         || strchr(my_str, '/') == NULL
00470                         || strchr(my_str, ':') > strchr(my_str, '/')) {
00471                 return LDNS_STATUS_INVALID_STR;
00472         }
00473 
00474         if (my_str[0] == '!') {
00475                 negation = true;
00476                 my_str += 1;
00477         } else {
00478                 negation = false;
00479         }
00480 
00481         family = (uint16_t) atoi(my_str);
00482 
00483         my_str = strchr(my_str, ':') + 1;
00484 
00485         /* need ip addr and only ip addr for inet_pton */
00486         ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
00487         my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
00488         if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
00489         strncpy(my_ip_str, my_str, ip_str_len + 1);
00490         my_ip_str[ip_str_len] = '\0';
00491 
00492         if (family == 1) {
00493                 /* ipv4 */
00494                 afdpart = LDNS_XMALLOC(uint8_t, 4);
00495                 if(!afdpart) {
00496                         LDNS_FREE(my_ip_str);
00497                         return LDNS_STATUS_MEM_ERR;
00498                 }
00499                 if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
00500                         LDNS_FREE(my_ip_str);
00501                         LDNS_FREE(afdpart);
00502                         return LDNS_STATUS_INVALID_STR;
00503                 }
00504                 for (i = 0; i < 4; i++) {
00505                         if (afdpart[i] != 0) {
00506                                 afdlength = i + 1;
00507                         }
00508                 }
00509         } else if (family == 2) {
00510                 /* ipv6 */
00511                 afdpart = LDNS_XMALLOC(uint8_t, 16);
00512                 if(!afdpart) {
00513                         LDNS_FREE(my_ip_str);
00514                         return LDNS_STATUS_MEM_ERR;
00515                 }
00516                 if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
00517                         LDNS_FREE(my_ip_str);
00518                         LDNS_FREE(afdpart);
00519                         return LDNS_STATUS_INVALID_STR;
00520                 }
00521                 for (i = 0; i < 16; i++) {
00522                         if (afdpart[i] != 0) {
00523                                 afdlength = i + 1;
00524                         }
00525                 }
00526         } else {
00527                 /* unknown family */
00528                 LDNS_FREE(my_ip_str);
00529                 return LDNS_STATUS_INVALID_STR;
00530         }
00531 
00532         my_str = strchr(my_str, '/') + 1;
00533         prefix = (uint8_t) atoi(my_str);
00534 
00535         data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
00536         if(!data) {
00537                 LDNS_FREE(afdpart);
00538                 LDNS_FREE(my_ip_str);
00539                 return LDNS_STATUS_INVALID_STR;
00540         }
00541         ldns_write_uint16(data, family);
00542         data[2] = prefix;
00543         data[3] = afdlength;
00544         if (negation) {
00545                 /* set bit 1 of byte 3 */
00546                 data[3] = data[3] | 0x80;
00547         }
00548 
00549         memcpy(data + 4, afdpart, afdlength);
00550 
00551         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
00552         LDNS_FREE(afdpart);
00553         LDNS_FREE(data);
00554         LDNS_FREE(my_ip_str);
00555 
00556         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00557 }
00558 
00559 ldns_status
00560 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
00561 {
00562         uint8_t *buffer;
00563         int16_t i;
00564 
00565         buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
00566         if(!buffer) {
00567                 return LDNS_STATUS_MEM_ERR;
00568         }
00569 
00570         i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
00571                                                    ldns_b64_ntop_calculate_size(strlen(str)));
00572         if (-1 == i) {
00573                 LDNS_FREE(buffer);
00574                 return LDNS_STATUS_INVALID_B64;
00575         } else {
00576                 *rd = ldns_rdf_new_frm_data(
00577                         LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
00578         }
00579         LDNS_FREE(buffer);
00580 
00581         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00582 }
00583 
00584 ldns_status
00585 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
00586 {
00587         uint8_t *buffer;
00588         int i;
00589         /* first byte contains length of actual b32 data */
00590         uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
00591         buffer = LDNS_XMALLOC(uint8_t, len + 1);
00592         if(!buffer) {
00593                 return LDNS_STATUS_MEM_ERR;
00594         }
00595         buffer[0] = len;
00596 
00597         i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
00598                                                          ldns_b32_ntop_calculate_size(strlen(str)));
00599         if (i < 0) {
00600                 LDNS_FREE(buffer);
00601                 return LDNS_STATUS_INVALID_B32_EXT;
00602         } else {
00603                 *rd = ldns_rdf_new_frm_data(
00604                         LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
00605         }
00606         LDNS_FREE(buffer);
00607 
00608         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00609 }
00610 
00611 ldns_status
00612 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
00613 {
00614         uint8_t *t, *t_orig;
00615         int i;
00616         size_t len;
00617 
00618         len = strlen(str);
00619 
00620         if (len > LDNS_MAX_RDFLEN * 2) {
00621                 return LDNS_STATUS_LABEL_OVERFLOW;
00622         } else {
00623                 t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
00624                 if(!t) {
00625                         return LDNS_STATUS_MEM_ERR;
00626                 }
00627                 t_orig = t;
00628                 /* Now process octet by octet... */
00629                 while (*str) {
00630                         *t = 0;
00631                         if (isspace((int) *str)) {
00632                                 str++;
00633                         } else {
00634                                 for (i = 16; i >= 1; i -= 15) {
00635                                         while (*str && isspace((int) *str)) { str++; }
00636                                         if (*str) {
00637                                                 if (isxdigit((int) *str)) {
00638                                                         *t += ldns_hexdigit_to_int(*str) * i;
00639                                                 } else {
00640                                                         LDNS_FREE(t_orig);
00641                                                         return LDNS_STATUS_ERR;
00642                                                 }
00643                                                 ++str;
00644                                         }
00645                                 }
00646                                 ++t;
00647                         }
00648                 }
00649                 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
00650                                             (size_t) (t - t_orig),
00651                                             t_orig);
00652                 LDNS_FREE(t_orig);
00653         }
00654         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00655 }
00656 
00657 ldns_status
00658 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
00659 {
00660         const char *delimiters = "\n\t ";
00661         char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
00662         ldns_buffer *str_buf;
00663         ssize_t c;
00664         uint16_t cur_type;
00665         size_t type_count = 0;
00666         ldns_rr_type type_list[65536];
00667         if(!token) return LDNS_STATUS_MEM_ERR;
00668         if(rd == NULL) {
00669                 LDNS_FREE(token);
00670                 return LDNS_STATUS_NULL;
00671         }
00672 
00673         str_buf = LDNS_MALLOC(ldns_buffer);
00674         if(!str_buf) {
00675                 LDNS_FREE(token);
00676                 return LDNS_STATUS_MEM_ERR;
00677         }
00678         ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00679         if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
00680                 LDNS_FREE(str_buf);
00681                 LDNS_FREE(token);
00682                 return LDNS_STATUS_MEM_ERR;
00683         }
00684 
00685         while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
00686                 if(type_count >= sizeof(type_list)) {
00687                         LDNS_FREE(str_buf);
00688                         LDNS_FREE(token);
00689                         return LDNS_STATUS_ERR;
00690                 }
00691                 cur_type = ldns_get_rr_type_by_name(token);
00692                 type_list[type_count] = cur_type;
00693                 type_count++;
00694         }
00695 
00696         *rd = ldns_dnssec_create_nsec_bitmap(type_list,
00697                                              type_count,
00698                                              LDNS_RR_TYPE_NSEC);
00699 
00700         LDNS_FREE(token);
00701         ldns_buffer_free(str_buf);
00702         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00703 }
00704 
00705 ldns_status
00706 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
00707 {
00708         uint16_t type;
00709         type = htons(ldns_get_rr_type_by_name(str));
00710         /* ldns_rr_type is a 16 bit value */
00711         *rd = ldns_rdf_new_frm_data(
00712                 LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
00713         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00714 }
00715 
00716 ldns_status
00717 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
00718 {
00719         uint16_t klass;
00720         klass = htons(ldns_get_rr_class_by_name(str));
00721         /* class is 16 bit */
00722         *rd = ldns_rdf_new_frm_data(
00723                 LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
00724         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00725 }
00726 
00727 /* An certificate alg field can either be specified as a 8 bits number
00728  * or by its symbolic name. Handle both
00729  */
00730 ldns_status
00731 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
00732 {
00733         ldns_lookup_table *lt;
00734         ldns_status st;
00735         uint8_t idd[2];
00736         lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
00737         st = LDNS_STATUS_OK;
00738 
00739         if (lt) {
00740                 ldns_write_uint16(idd, (uint16_t) lt->id);
00741                 *rd = ldns_rdf_new_frm_data(
00742                         LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
00743                 if (!*rd) {
00744                         st = LDNS_STATUS_ERR;
00745                 }
00746         } else {
00747                 /* try as-is (a number) */
00748                 st = ldns_str2rdf_int16(rd, str);
00749                 if (st == LDNS_STATUS_OK &&
00750                     ldns_rdf2native_int16(*rd) == 0) {
00751                         st = LDNS_STATUS_CERT_BAD_ALGORITHM;
00752                 }
00753         }
00754 
00755         return st;
00756 }
00757 
00758 /* An alg field can either be specified as a 8 bits number
00759  * or by its symbolic name. Handle both
00760  */
00761 ldns_status
00762 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
00763 {
00764         ldns_lookup_table *lt;
00765         ldns_status st;
00766 
00767         lt = ldns_lookup_by_name(ldns_algorithms, str);
00768         st = LDNS_STATUS_OK;
00769 
00770         if (lt) {
00771                 /* it was given as a integer */
00772                 *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
00773                 if (!*rd) {
00774                         st = LDNS_STATUS_ERR;
00775                 }
00776         } else {
00777                 /* try as-is (a number) */
00778                 st = ldns_str2rdf_int8(rd, str);
00779         }
00780         return st;
00781 }
00782 
00783 ldns_status
00784 ldns_str2rdf_unknown( ATTR_UNUSED(ldns_rdf **rd)
00785                     , ATTR_UNUSED(const char *str)
00786                     )
00787 {
00788         /* this should be caught in an earlier time (general str2host for
00789            rr's */
00790         return LDNS_STATUS_NOT_IMPL;
00791 }
00792 
00793 ldns_status
00794 ldns_str2rdf_tsig( ATTR_UNUSED(ldns_rdf **rd)
00795                  , ATTR_UNUSED(const char *str)
00796                  )
00797 {
00798         /* there is no string representation for TSIG rrs */
00799         return LDNS_STATUS_NOT_IMPL;
00800 }
00801 
00802 ldns_status
00803 ldns_str2rdf_service( ATTR_UNUSED(ldns_rdf **rd)
00804                     , ATTR_UNUSED(const char *str)
00805                     )
00806 {
00807         /* is this used? is this actually WKS? or SRV? */
00808         return LDNS_STATUS_NOT_IMPL;
00809 }
00810 
00811 static int
00812 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
00813 {
00814         /* read <digits>[.<digits>][mM] */
00815         /* into mantissa exponent format for LOC type */
00816         uint32_t meters = 0, cm = 0, val;
00817         while (isblank(*my_str)) {
00818                 my_str++;
00819         }
00820         meters = (uint32_t)strtol(my_str, &my_str, 10);
00821         if (*my_str == '.') {
00822                 my_str++;
00823                 cm = (uint32_t)strtol(my_str, &my_str, 10);
00824         }
00825         if (meters >= 1) {
00826                 *e = 2;
00827                 val = meters;
00828         } else  {
00829                 *e = 0;
00830                 val = cm;
00831         }
00832         while(val >= 10) {
00833                 (*e)++;
00834                 val /= 10;
00835         }
00836         *m = (uint8_t)val;
00837 
00838         if (*e > 9)
00839                 return 0;
00840         if (*my_str == 'm' || *my_str == 'M') {
00841                 my_str++;
00842         }
00843         *endstr = my_str;
00844         return 1;
00845 }
00846 
00847 ldns_status
00848 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
00849 {
00850         uint32_t latitude = 0;
00851         uint32_t longitude = 0;
00852         uint32_t altitude = 0;
00853 
00854         uint8_t *data;
00855         uint32_t equator = (uint32_t) ldns_power(2, 31);
00856 
00857         uint32_t h = 0;
00858         uint32_t m = 0;
00859         uint8_t size_b = 1, size_e = 2;
00860         uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
00861         uint8_t vert_pre_b = 1, vert_pre_e = 3;
00862 
00863         double s = 0.0;
00864         bool northerness;
00865         bool easterness;
00866 
00867         char *my_str = (char *) str;
00868 
00869         /* only support version 0 */
00870         if (isdigit((int) *my_str)) {
00871                 h = (uint32_t) strtol(my_str, &my_str, 10);
00872         } else {
00873                 return LDNS_STATUS_INVALID_STR;
00874         }
00875 
00876         while (isblank((int) *my_str)) {
00877                 my_str++;
00878         }
00879 
00880         if (isdigit((int) *my_str)) {
00881                 m = (uint32_t) strtol(my_str, &my_str, 10);
00882         } else if (*my_str == 'N' || *my_str == 'S') {
00883                 goto north;
00884         } else {
00885                 return LDNS_STATUS_INVALID_STR;
00886         }
00887 
00888         while (isblank((int) *my_str)) {
00889                 my_str++;
00890         }
00891 
00892         if (isdigit((int) *my_str)) {
00893                 s = strtod(my_str, &my_str);
00894         }
00895 north:
00896         while (isblank((int) *my_str)) {
00897                 my_str++;
00898         }
00899 
00900         if (*my_str == 'N') {
00901                 northerness = true;
00902         } else if (*my_str == 'S') {
00903                 northerness = false;
00904         } else {
00905                 return LDNS_STATUS_INVALID_STR;
00906         }
00907 
00908         my_str++;
00909 
00910         /* store number */
00911         s = 1000.0 * s;
00912         /* add a little to make floor in conversion a round */
00913         s += 0.0005;
00914         latitude = (uint32_t) s;
00915         latitude += 1000 * 60 * m;
00916         latitude += 1000 * 60 * 60 * h;
00917         if (northerness) {
00918                 latitude = equator + latitude;
00919         } else {
00920                 latitude = equator - latitude;
00921         }
00922         while (isblank(*my_str)) {
00923                 my_str++;
00924         }
00925 
00926         if (isdigit((int) *my_str)) {
00927                 h = (uint32_t) strtol(my_str, &my_str, 10);
00928         } else {
00929                 return LDNS_STATUS_INVALID_STR;
00930         }
00931 
00932         while (isblank((int) *my_str)) {
00933                 my_str++;
00934         }
00935 
00936         if (isdigit((int) *my_str)) {
00937                 m = (uint32_t) strtol(my_str, &my_str, 10);
00938         } else if (*my_str == 'E' || *my_str == 'W') {
00939                 goto east;
00940         } else {
00941                 return LDNS_STATUS_INVALID_STR;
00942         }
00943 
00944         while (isblank(*my_str)) {
00945                 my_str++;
00946         }
00947 
00948         if (isdigit((int) *my_str)) {
00949                 s = strtod(my_str, &my_str);
00950         }
00951 
00952 east:
00953         while (isblank(*my_str)) {
00954                 my_str++;
00955         }
00956 
00957         if (*my_str == 'E') {
00958                 easterness = true;
00959         } else if (*my_str == 'W') {
00960                 easterness = false;
00961         } else {
00962                 return LDNS_STATUS_INVALID_STR;
00963         }
00964 
00965         my_str++;
00966 
00967         /* store number */
00968         s *= 1000.0;
00969         /* add a little to make floor in conversion a round */
00970         s += 0.0005;
00971         longitude = (uint32_t) s;
00972         longitude += 1000 * 60 * m;
00973         longitude += 1000 * 60 * 60 * h;
00974 
00975         if (easterness) {
00976                 longitude += equator;
00977         } else {
00978                 longitude = equator - longitude;
00979         }
00980 
00981         altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
00982                 10000000.0 + 0.5);
00983         if (*my_str == 'm' || *my_str == 'M') {
00984                 my_str++;
00985         }
00986 
00987         if (strlen(my_str) > 0) {
00988                 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
00989                         return LDNS_STATUS_INVALID_STR;
00990         }
00991 
00992         if (strlen(my_str) > 0) {
00993                 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
00994                         return LDNS_STATUS_INVALID_STR;
00995         }
00996 
00997         if (strlen(my_str) > 0) {
00998                 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
00999                         return LDNS_STATUS_INVALID_STR;
01000         }
01001 
01002         data = LDNS_XMALLOC(uint8_t, 16);
01003         if(!data) {
01004                 return LDNS_STATUS_MEM_ERR;
01005         }
01006         data[0] = 0;
01007         data[1] = 0;
01008         data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
01009         data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
01010         data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
01011         ldns_write_uint32(data + 4, latitude);
01012         ldns_write_uint32(data + 8, longitude);
01013         ldns_write_uint32(data + 12, altitude);
01014 
01015         *rd = ldns_rdf_new_frm_data(
01016                 LDNS_RDF_TYPE_LOC, 16, data);
01017 
01018         LDNS_FREE(data);
01019         return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
01020 }
01021 
01022 ldns_status
01023 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
01024 {
01025         uint8_t *bitmap = NULL;
01026         uint8_t *data;
01027         int bm_len = 0;
01028 
01029         struct protoent *proto = NULL;
01030         struct servent *serv = NULL;
01031         int serv_port;
01032 
01033         ldns_buffer *str_buf;
01034 
01035         char *proto_str = NULL;
01036         char *token;
01037         if(strlen(str) == 0)
01038                 token = LDNS_XMALLOC(char, 50);
01039         else    token = LDNS_XMALLOC(char, strlen(str)+2);
01040         if(!token) return LDNS_STATUS_MEM_ERR;
01041 
01042         str_buf = LDNS_MALLOC(ldns_buffer);
01043         if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01044         ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01045         if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01046                 LDNS_FREE(str_buf);
01047                 LDNS_FREE(token);
01048                 return LDNS_STATUS_MEM_ERR;
01049         }
01050 
01051         while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01052                 if (!proto_str) {
01053                         proto_str = strdup(token);
01054                         if (!proto_str) {
01055                                 LDNS_FREE(bitmap);
01056                                 LDNS_FREE(token);
01057                                 ldns_buffer_free(str_buf);
01058                                 return LDNS_STATUS_INVALID_STR;
01059                         }
01060                 } else {
01061                         serv = getservbyname(token, proto_str);
01062                         if (serv) {
01063                                 serv_port = (int) ntohs((uint16_t) serv->s_port);
01064                         } else {
01065                                 serv_port = atoi(token);
01066                         }
01067                         if (serv_port / 8 >= bm_len) {
01068                                 uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
01069                                 if(!b2) {
01070                                         LDNS_FREE(bitmap);
01071                                         LDNS_FREE(token);
01072                                         ldns_buffer_free(str_buf);
01073                                         free(proto_str);
01074                                         return LDNS_STATUS_INVALID_STR;
01075                                 }
01076                                 bitmap = b2;
01077                                 /* set to zero to be sure */
01078                                 for (; bm_len <= serv_port / 8; bm_len++) {
01079                                         bitmap[bm_len] = 0;
01080                                 }
01081                         }
01082                         ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
01083                 }
01084         }
01085 
01086         if (!proto_str || !bitmap) {
01087                 LDNS_FREE(bitmap);
01088                 LDNS_FREE(token);
01089                 ldns_buffer_free(str_buf);
01090                 free(proto_str);
01091                 return LDNS_STATUS_INVALID_STR;
01092         }
01093 
01094         data = LDNS_XMALLOC(uint8_t, bm_len + 1);
01095         if(!data) {
01096                 LDNS_FREE(token);
01097                 ldns_buffer_free(str_buf);
01098                 LDNS_FREE(bitmap);
01099                 free(proto_str);
01100                 return LDNS_STATUS_INVALID_STR;
01101         }
01102     if (proto_str)
01103                 proto = getprotobyname(proto_str);
01104         if (proto) {
01105                 data[0] = (uint8_t) proto->p_proto;
01106         } else if (proto_str) {
01107                 data[0] = (uint8_t) atoi(proto_str);
01108         }
01109         memcpy(data + 1, bitmap, (size_t) bm_len);
01110 
01111         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
01112 
01113         LDNS_FREE(data);
01114         LDNS_FREE(token);
01115         ldns_buffer_free(str_buf);
01116         LDNS_FREE(bitmap);
01117         free(proto_str);
01118 #ifdef HAVE_ENDSERVENT
01119         endservent();
01120 #endif
01121 #ifdef HAVE_ENDPROTOENT
01122         endprotoent();
01123 #endif
01124 
01125         if(!*rd) return LDNS_STATUS_MEM_ERR;
01126 
01127         return LDNS_STATUS_OK;
01128 }
01129 
01130 ldns_status
01131 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
01132 {
01133     size_t len, i;
01134     char* nsap_str = (char*) str;
01135 
01136         /* just a hex string with optional dots? */
01137         if (str[0] != '0' || str[1] != 'x') {
01138                 return LDNS_STATUS_INVALID_STR;
01139         } else {
01140                 len = strlen(str);
01141                 for (i=0; i < len; i++) {
01142                         if (nsap_str[i] == '.')
01143                                 nsap_str[i] = ' ';
01144         }
01145                 return ldns_str2rdf_hex(rd, str+2);
01146         }
01147 }
01148 
01149 ldns_status
01150 ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
01151 {
01152     size_t len, i;
01153     char* atma_str = (char*) str;
01154         ldns_status status;
01155 
01156         /* just a hex string with optional dots? */
01157         len = strlen(str);
01158         for (i=0; i < len; i++) {
01159                 if (atma_str[i] == '.')
01160                         atma_str[i] = ' ';
01161         }
01162         status = ldns_str2rdf_hex(rd, str);
01163     if (status != LDNS_STATUS_OK) {
01164                 ; /* probably in e.164 format than */
01165         }
01166         return status;
01167 }
01168 
01169 ldns_status
01170 ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
01171 {
01172         uint8_t precedence = 0;
01173         uint8_t gateway_type = 0;
01174         uint8_t algorithm = 0;
01175         char* gateway = NULL;
01176         char* publickey = NULL;
01177         uint8_t *data;
01178         ldns_buffer *str_buf;
01179         char *token;
01180         int token_count = 0;
01181         int ipseckey_len = 0;
01182         ldns_rdf* gateway_rdf = NULL;
01183         ldns_rdf* publickey_rdf = NULL;
01184         ldns_status status = LDNS_STATUS_OK;
01185         
01186         if(strlen(str) == 0)
01187                 token = LDNS_XMALLOC(char, 256);
01188         else    token = LDNS_XMALLOC(char, strlen(str)+2);
01189         if(!token) return LDNS_STATUS_MEM_ERR;
01190 
01191         str_buf = LDNS_MALLOC(ldns_buffer);
01192         if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01193         ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01194         if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01195                 LDNS_FREE(str_buf);
01196                 LDNS_FREE(token);
01197                 return LDNS_STATUS_MEM_ERR;
01198         }
01199         while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01200                 switch (token_count) {
01201                                 case 0:
01202                                         precedence = (uint8_t)atoi(token);
01203                                         break;
01204                                 case 1:
01205                                         gateway_type = (uint8_t)atoi(token);
01206                                         break;
01207                                 case 2:
01208                                         algorithm = (uint8_t)atoi(token);
01209                                         break;
01210                                 case 3:
01211                                         gateway = strdup(token);
01212                                         if (!gateway || (gateway_type == 0 &&
01213                                                         (token[0] != '.' || token[1] != '\0'))) {
01214                                                 LDNS_FREE(gateway);
01215                                                 LDNS_FREE(token);
01216                                                 ldns_buffer_free(str_buf);
01217                                                 return LDNS_STATUS_INVALID_STR;
01218                                         }
01219                                         break;
01220                                 case 4:
01221                                         publickey = strdup(token);
01222                                         break;
01223                                 default:
01224                                         LDNS_FREE(token);
01225                                         ldns_buffer_free(str_buf);
01226                                         return LDNS_STATUS_INVALID_STR;
01227                                         break;
01228                 }
01229                 token_count++;
01230         }
01231 
01232         if (!gateway || !publickey) {
01233                 if (gateway)
01234                         LDNS_FREE(gateway);
01235                 if (publickey)
01236                         LDNS_FREE(publickey);
01237                 LDNS_FREE(token);
01238                 ldns_buffer_free(str_buf);
01239                 return LDNS_STATUS_INVALID_STR;
01240         }
01241 
01242         if (gateway_type == 1) {
01243                 status = ldns_str2rdf_a(&gateway_rdf, gateway);
01244         } else if (gateway_type == 2) {
01245                 status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
01246         } else if (gateway_type == 3) {
01247                 status = ldns_str2rdf_dname(&gateway_rdf, gateway);
01248         }
01249 
01250         if (status != LDNS_STATUS_OK) {
01251                 if (gateway)
01252                         LDNS_FREE(gateway);
01253                 if (publickey)
01254                         LDNS_FREE(publickey);
01255                 LDNS_FREE(token);
01256                 ldns_buffer_free(str_buf);
01257                 return LDNS_STATUS_INVALID_STR;
01258         }
01259 
01260         status = ldns_str2rdf_b64(&publickey_rdf, publickey);
01261 
01262         if (status != LDNS_STATUS_OK) {
01263                 if (gateway)
01264                         LDNS_FREE(gateway);
01265                 if (publickey)
01266                         LDNS_FREE(publickey);
01267                 LDNS_FREE(token);
01268                 ldns_buffer_free(str_buf);
01269                 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01270                 return LDNS_STATUS_INVALID_STR;
01271         }
01272 
01273         /* now copy all into one ipseckey rdf */
01274         if (gateway_type)
01275                 ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
01276         else
01277                 ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
01278 
01279         data = LDNS_XMALLOC(uint8_t, ipseckey_len);
01280         if(!data) {
01281                 if (gateway)
01282                         LDNS_FREE(gateway);
01283                 if (publickey)
01284                         LDNS_FREE(publickey);
01285                 LDNS_FREE(token);
01286                 ldns_buffer_free(str_buf);
01287                 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01288                 if (publickey_rdf) ldns_rdf_free(publickey_rdf);
01289                 return LDNS_STATUS_MEM_ERR;
01290         }
01291 
01292         data[0] = precedence;
01293         data[1] = gateway_type;
01294         data[2] = algorithm;
01295 
01296         if (gateway_type) {
01297                 memcpy(data + 3,
01298                         ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
01299                 memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
01300                         ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01301         } else {
01302                 memcpy(data + 3,
01303                         ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01304         }
01305 
01306         *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
01307 
01308         if (gateway)
01309                 LDNS_FREE(gateway);
01310         if (publickey)
01311                 LDNS_FREE(publickey);
01312         LDNS_FREE(token);
01313         ldns_buffer_free(str_buf);
01314         ldns_rdf_free(gateway_rdf);
01315         ldns_rdf_free(publickey_rdf);
01316         LDNS_FREE(data);
01317         if(!*rd) return LDNS_STATUS_MEM_ERR;
01318         return LDNS_STATUS_OK;
01319 }

Generated on Wed Dec 19 16:56:57 2012 for ldns by  doxygen 1.4.7