static int hostent_add_alias(struct hostent_ext *h, const char *name, int isdname) { char buf[MAXDNAME]; size_t i, n; for (i = 0; i < MAXALIASES; i++) if (h->aliases[i] == NULL) break; if (i == MAXALIASES) return (0); if (isdname) { _asr_strdname(name, buf, sizeof buf); buf[strlen(buf)-1] = '\0'; if (!res_hnok(buf)) return (-1); name = buf; } n = strlen(name) + 1; if (h->pos + n >= h->end) return (0); h->aliases[i] = h->pos; memmove(h->pos, name, n); h->pos += n; return (0); }
static int hostent_set_cname(struct hostent_ext *h, const char *name, int isdname) { char buf[MAXDNAME]; size_t n; if (h->h.h_name) return (-1); if (isdname) { _asr_strdname(name, buf, sizeof buf); buf[strlen(buf) - 1] = '\0'; if (!res_hnok(buf)) return (-1); name = buf; } n = strlen(name) + 1; if (h->pos + n >= h->end) return (-1); h->h.h_name = h->pos; memmove(h->pos, name, n); h->pos += n; return (0); }
static int addrinfo_from_pkt(struct asr_query *as, char *pkt, size_t pktlen) { struct asr_unpack p; struct asr_dns_header h; struct asr_dns_query q; struct asr_dns_rr rr; int i; union { struct sockaddr sa; struct sockaddr_in sain; struct sockaddr_in6 sain6; } u; char buf[MAXDNAME], *c; _asr_unpack_init(&p, pkt, pktlen); _asr_unpack_header(&p, &h); for (; h.qdcount; h.qdcount--) _asr_unpack_query(&p, &q); for (i = 0; i < h.ancount; i++) { _asr_unpack_rr(&p, &rr); if (rr.rr_type != q.q_type || rr.rr_class != q.q_class) continue; memset(&u, 0, sizeof u); if (rr.rr_type == T_A) { #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN u.sain.sin_len = sizeof u.sain; #endif u.sain.sin_family = AF_INET; u.sain.sin_addr = rr.rr.in_a.addr; u.sain.sin_port = 0; } else if (rr.rr_type == T_AAAA) { #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN u.sain6.sin6_len = sizeof u.sain6; #endif u.sain6.sin6_family = AF_INET6; u.sain6.sin6_addr = rr.rr.in_aaaa.addr6; u.sain6.sin6_port = 0; } else continue; if (as->as.ai.hints.ai_flags & AI_CANONNAME) { _asr_strdname(rr.rr_dname, buf, sizeof buf); buf[strlen(buf) - 1] = '\0'; c = res_hnok(buf) ? buf : NULL; } else if (as->as.ai.hints.ai_flags & AI_FQDN) c = as->as.ai.fqdn; else c = NULL; if (addrinfo_add(as, &u.sa, c)) return (-1); /* errno set */ } return (0); }