ldns_buffer * read_hex_buffer(char *filename) { uint8_t *wire; size_t wiresize; ldns_buffer *result_buffer = NULL; wire = xmalloc(LDNS_MAX_PACKETLEN); wiresize = packetbuffromfile(filename, wire); result_buffer = LDNS_MALLOC(ldns_buffer); ldns_buffer_new_frm_data(result_buffer, wire, wiresize); ldns_buffer_set_position(result_buffer, ldns_buffer_capacity(result_buffer)); xfree(wire); return result_buffer; }
static int l_read_wire_udp(lua_State *L) { int sockfd = (int)lua_tonumber(L, 1); size_t size; uint8_t *pktbuf_raw; ldns_buffer *pktbuf; struct sockaddr_storage *from; socklen_t from_len; if (sockfd == 0) { return 0; } from = LDNS_MALLOC(struct sockaddr_storage); if (!from) { return 0; } (void)memset(from, 0, sizeof(struct sockaddr_storage)); from_len = sizeof(struct sockaddr_storage); /* set to predefined state */ pktbuf = ldns_buffer_new(LDNS_MIN_BUFLEN); /* this /should/ happen in buf_new_frm_data */ if (!pktbuf) { return 0; } pktbuf_raw = ldns_udp_read_wire(sockfd, &size, from, &from_len); if (!pktbuf_raw) { return 0; } ldns_buffer_new_frm_data(pktbuf, pktbuf_raw, size); /* push our buffer onto the stack */ /* stack func lua cal in same order buf, from */ lua_pushlightuserdata(L, pktbuf); lua_pushlightuserdata(L, from); return 2; }
ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) { ldns_resolver *r; const char *keyword[LDNS_RESOLV_KEYWORDS]; char word[LDNS_MAX_LINELEN + 1]; int8_t expect; uint8_t i; ldns_rdf *tmp; #ifdef HAVE_SSL ldns_rr *tmp_rr; #endif ssize_t gtr; ldns_buffer *b; /* do this better * expect = * 0: keyword * 1: default domain dname * 2: NS aaaa or a record */ /* recognized keywords */ keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; keyword[LDNS_RESOLV_SEARCH] = "search"; /* these two are read but not used atm TODO */ keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; keyword[LDNS_RESOLV_OPTIONS] = "options"; keyword[LDNS_RESOLV_ANCHOR] = "anchor"; expect = LDNS_RESOLV_KEYWORD; r = ldns_resolver_new(); if (!r) { return LDNS_STATUS_MEM_ERR; } gtr = 1; word[0] = 0; while (gtr > 0) { /* check comments */ if (word[0] == '#') { /* read the rest of the line, should be 1 word */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); /* prepare the next string for further parsing */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); continue; } switch(expect) { case LDNS_RESOLV_KEYWORD: /* keyword */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr != 0) { for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { if (strcasecmp(keyword[i], word) == 0) { /* chosen the keyword and * expect values carefully */ expect = i; break; } } /* no keyword recognized */ if (expect == LDNS_RESOLV_KEYWORD) { /* skip line */ /* ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_KEYWORD_ERR; */ } } break; case LDNS_RESOLV_DEFDOMAIN: /* default domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_DNAME_ERR; } /* DOn't free, because we copy the pointer */ ldns_resolver_set_domain(r, tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_NAMESERVER: /* NS aaaa or a record */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); if (!tmp) { /* try ip4 */ tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); } /* could not parse it, exit */ if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_ERR; } (void)ldns_resolver_push_nameserver(r, tmp); ldns_rdf_deep_free(tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SEARCH: /* search list domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); b = LDNS_MALLOC(ldns_buffer); ldns_buffer_new_frm_data(b, word, (size_t) gtr); gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr); while (gtr > 0) { tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_DNAME_ERR; } ldns_resolver_push_searchlist(r, tmp); ldns_rdf_deep_free(tmp); gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr); } ldns_buffer_free(b); gtr = 1; expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SORTLIST: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* sortlist not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_OPTIONS: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* options not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_ANCHOR: /* a file containing a DNSSEC trust anchor */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } #ifdef HAVE_SSL tmp_rr = ldns_read_anchor_file(word); (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); ldns_rr_free(tmp_rr); #endif expect = LDNS_RESOLV_KEYWORD; break; } } if (res) { *res = r; return LDNS_STATUS_OK; } else { return LDNS_STATUS_NULL; } }
ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) { ldns_resolver *r; const char *keyword[LDNS_RESOLV_KEYWORDS]; char word[LDNS_MAX_LINELEN + 1]; int8_t expect; uint8_t i; ldns_rdf *tmp; #ifdef HAVE_SSL ldns_rr *tmp_rr; #endif ssize_t gtr, bgtr; ldns_buffer *b; int lnr = 0, oldline; if(!line_nr) line_nr = &lnr; /* do this better * expect = * 0: keyword * 1: default domain dname * 2: NS aaaa or a record */ /* recognized keywords */ keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; keyword[LDNS_RESOLV_SEARCH] = "search"; /* these two are read but not used atm TODO */ keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; keyword[LDNS_RESOLV_OPTIONS] = "options"; keyword[LDNS_RESOLV_ANCHOR] = "anchor"; expect = LDNS_RESOLV_KEYWORD; r = ldns_resolver_new(); if (!r) { return LDNS_STATUS_MEM_ERR; } gtr = 1; word[0] = 0; oldline = *line_nr; expect = LDNS_RESOLV_KEYWORD; while (gtr > 0) { /* check comments */ if (word[0] == '#') { word[0]='x'; if(oldline == *line_nr) { /* skip until end of line */ int c; do { c = fgetc(fp); } while(c != EOF && c != '\n'); if(c=='\n' && line_nr) (*line_nr)++; } /* and read next to prepare for further parsing */ oldline = *line_nr; continue; } oldline = *line_nr; switch(expect) { case LDNS_RESOLV_KEYWORD: /* keyword */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr != 0) { if(word[0] == '#') continue; for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { if (strcasecmp(keyword[i], word) == 0) { /* chosen the keyword and * expect values carefully */ expect = i; break; } } /* no keyword recognized */ if (expect == LDNS_RESOLV_KEYWORD) { /* skip line */ /* ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_KEYWORD_ERR; */ } } break; case LDNS_RESOLV_DEFDOMAIN: /* default domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; continue; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_DNAME_ERR; } /* DOn't free, because we copy the pointer */ ldns_resolver_set_domain(r, tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_NAMESERVER: /* NS aaaa or a record */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; continue; } if(strchr(word, '%')) { /* snip off interface labels, * fe80::222:19ff:fe31:4222%eth0 */ strchr(word, '%')[0]=0; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); if (!tmp) { /* try ip4 */ tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); } /* could not parse it, exit */ if (!tmp) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_ERR; } (void)ldns_resolver_push_nameserver(r, tmp); ldns_rdf_deep_free(tmp); expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SEARCH: /* search list domain dname */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); b = LDNS_MALLOC(ldns_buffer); if(!b) { ldns_resolver_deep_free(r); return LDNS_STATUS_MEM_ERR; } ldns_buffer_new_frm_data(b, word, (size_t) gtr); if(ldns_buffer_status(b) != LDNS_STATUS_OK) { LDNS_FREE(b); ldns_resolver_deep_free(r); return LDNS_STATUS_MEM_ERR; } bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); while (bgtr > 0) { gtr -= bgtr; if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; ldns_buffer_free(b); continue; } tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); if (!tmp) { ldns_resolver_deep_free(r); ldns_buffer_free(b); return LDNS_STATUS_SYNTAX_DNAME_ERR; } ldns_resolver_push_searchlist(r, tmp); ldns_rdf_deep_free(tmp); bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); } ldns_buffer_free(b); gtr = 1; expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_SORTLIST: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* sortlist not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_OPTIONS: gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); /* options not implemented atm */ expect = LDNS_RESOLV_KEYWORD; break; case LDNS_RESOLV_ANCHOR: /* a file containing a DNSSEC trust anchor */ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); if (gtr == 0) { ldns_resolver_deep_free(r); return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; } if(word[0] == '#') { expect = LDNS_RESOLV_KEYWORD; continue; } #ifdef HAVE_SSL tmp_rr = ldns_read_anchor_file(word); (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); ldns_rr_free(tmp_rr); #endif expect = LDNS_RESOLV_KEYWORD; break; } } /* finally, add the root domain to the search list */ ldns_resolver_push_searchlist(r, ldns_dname_new_frm_str(".")); if (res) { *res = r; return LDNS_STATUS_OK; } else { ldns_resolver_deep_free(r); return LDNS_STATUS_NULL; } }
/** convert hex buffer to binary buffer */ static ldns_buffer * data_buffer2wire(ldns_buffer *data_buffer) { ldns_buffer *wire_buffer = NULL; int c; /* stat hack * 0 = normal * 1 = comment (skip to end of line) * 2 = unprintable character found, read binary data directly */ size_t data_buf_pos = 0; int state = 0; uint8_t *hexbuf; int hexbufpos = 0; size_t wirelen; uint8_t *data_wire = (uint8_t *) ldns_buffer_export(data_buffer); uint8_t *wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN); hexbuf = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN); for (data_buf_pos = 0; data_buf_pos < ldns_buffer_position(data_buffer); data_buf_pos++) { c = (int) data_wire[data_buf_pos]; if (state < 2 && !isascii(c)) { /*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/ state = 2; } switch (state) { case 0: if ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ) { hexbuf[hexbufpos] = (uint8_t) c; hexbufpos++; } else if (c == ';') { state = 1; } else if (c == ' ' || c == '\t' || c == '\n') { /* skip whitespace */ } break; case 1: if (c == '\n' || c == EOF) { state = 0; } break; case 2: hexbuf[hexbufpos] = (uint8_t) c; hexbufpos++; break; default: error("unknown state while reading"); LDNS_FREE(hexbuf); return 0; break; } } if (hexbufpos >= LDNS_MAX_PACKETLEN) { /*verbose("packet size reached\n");*/ } /* lenient mode: length must be multiple of 2 */ if (hexbufpos % 2 != 0) { hexbuf[hexbufpos] = (uint8_t) '0'; hexbufpos++; } if (state < 2) { wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, LDNS_MAX_PACKETLEN); wire_buffer = ldns_buffer_new(wirelen); ldns_buffer_new_frm_data(wire_buffer, wire, wirelen); } else { error("Incomplete hex data, not at byte boundary\n"); } LDNS_FREE(wire); LDNS_FREE(hexbuf); return wire_buffer; }