📄 dns_client_resource.c
字号:
{ memset(sock, 0, sizeof(struct sockaddr_storage)); ((struct sockaddr_in *)sock)->sin_family = AF_INET; *((U32 *)&((struct sockaddr_in *)sock)->sin_addr) = ip;}/* * data2sock -- * This routine converts IPv6 address into sockaddr_in6 structure. * * PARAMETERS * sock - storage for result * data - address (pointer to an in6_addr structure or an array) * * RETURNS * n/a */voiddata2sock(OUT void *sock, IN void *data){ memset(sock, 0, sizeof(struct sockaddr_storage)); ((struct sockaddr_in6 *)sock)->sin6_family = AF_INET6; memcpy(&((struct sockaddr_in6 *)sock)->sin6_addr, data, sizeof(struct in6_addr));}/* * sock2long -- * Converts a 'sockaddr_storage' structure into U32 IPv4 address. * Note, family is not checked here, it is assumed here to be AF_INET. * If the family is not AF_INET this inline routine will return * weird result * * PARAMETERS * sock - IPv4 address in sockaddr_storage form * * RETURNS * IPv4 address converted in U32 type */U32 sock2long(IN struct sockaddr_storage *sock){ return *(U32 *)&((struct sockaddr_in *)sock)->sin_addr;}/* * get_offset() * * this inline routine will strip the top two bits, (these just indicate the fact * that compression is used), and return a short that is the value of the remaining * 14 bits. that value is an offset into the DNS message, first byte is 0. */shortget_offset(char *data){ U16 offset; memcpy(&offset, data, sizeof(U16)); offset = ntohs(offset); return offset & CMPSTRIP;} /* end get_offset *//* * reverse_ip_addr() * * this routine takes an IP address as an unsigned long and will reverse it * and add on the "in-addr.arpa." so it can be used for a query. */voidreverse_ip_addr(U32 ip, char *rev){ U8 *ipaddr = (U8 *)&ip; sprintf(rev, "%u.%u.%u.%u.%s", ipaddr[3], ipaddr[2], ipaddr[1], ipaddr[0], INADDR_ARPA);} /* end reverse_ip_addr() *//* * reverse_sockaddr_int -- * This routine reverses an IPv4 or IPv6 address * and adds on the "ip6.int." (RFC 1886) or "in-addr.arpa" * so it can be used for a query. * * PARAMETERS * ip - ip address * rev - reversed IP address string * * RETURNS * n/a */voidreverse_sockaddr_int(IN struct sockaddr_storage *ip, OUT char *rev){ if (ip->__ss_family == AF_INET) { reverse_ip_addr(sock2long(ip), rev); return; } else if (ip->__ss_family == AF_INET6) { U8 *nibbles = (U8 *) &((struct sockaddr_in6 *)ip)->sin6_addr; int cnt; char *ptr = rev; for (cnt = sizeof(struct in6_addr) - 1; cnt >= 0; cnt--) { static const char *xDigits = "0123456789abcdef"; U8 l4bits, h4bits; l4bits = (nibbles[cnt] & 0x0f); h4bits = (nibbles[cnt] >> 4); *ptr++ = xDigits[l4bits]; *ptr++ = DOT; *ptr++ = xDigits[h4bits]; *ptr++ = DOT; } *ptr = '\0'; strcpy(ptr, IP6_INT); }} /* end reverse_sockaddr_int() *//* * reverse_sockaddr_arpa -- * This routine reverses an IPv4 or IPv6 address * and adds on the "ip6.arpa." (RFC 1886) or "in-addr.arpa" * so it can be used for a query. * * PARAMETERS * ip - ip address * rev - reversed IP address string * * RETURNS * n/a */voidreverse_sockaddr_arpa(IN struct sockaddr_storage *ip, OUT char *rev){ if (ip->__ss_family == AF_INET) { reverse_ip_addr(sock2long(ip), rev); return; } else if (ip->__ss_family == AF_INET6) { U8 *bytes = (U8 *) &((struct sockaddr_in6 *)ip)->sin6_addr; char *ptr = rev; int cnt; strcpy(ptr, "\\[x"); ptr += 3; for (cnt = 0; cnt < (int)sizeof(struct in6_addr); cnt++) { static const char *xDigits = "0123456789abcdef"; U8 l4bits, h4bits; l4bits = (bytes[cnt] & 0x0f); h4bits = (bytes[cnt] >> 4); *ptr++ = xDigits[h4bits]; *ptr++ = xDigits[l4bits]; } *ptr = '\0'; sprintf(ptr, "/128].%s", IP6_ARPA); }} /* end reverse_sockaddr_arpa() *//* * count_domain_parts() * * this routine will count the parts of a domain name. we look for dots * in the name and base the count on that. * * return: number of parts (parts is parts) */intcount_domain_parts(const char *name){ char *tok, *ptr; int parts = 0; ptr = (char *)name; while ((tok = strchr(ptr, DOT)) != NULL) { ptr = ++tok; parts++; } if ( *ptr != '\0' ) parts++; return parts;} /* end count_domain_parts() *//* * get_last_domain_parts() * * this routine will return a pointer to the last domain parts of a domain name. it * will return NULL if there is an error. * * name - the domain name, ex: host.virata.com * tparts - total number of parts in domain name, above ex. would be 3 * lparts - parts we're interested in, say 2 would give virata.com */const char *get_last_domain_parts(const char *name, int tparts, int lparts){ char *tok, *ptr; int i, cnt; if ( 0 == lparts ) return name; cnt = tparts - lparts; /* they want lparts, there are tparts, go past the first cnt */ ptr = (char *)name; for ( i = 0; i < cnt; i++ ) { if ((tok = strchr(ptr, DOT)) == NULL) return NULL; ptr = ++tok; } return ptr;} /* end get_last_domain_parts() *//* * find_match_rrecord() * * this routine takes a pointer to the beginning of a DnsRRec list. it goes * through the list looking for a RR that matches the correct type, given byrtype, * and the domain name, dname. it returns a pointer to that RR. * * return: pointer to the first matching RR, or * NULL if no match. */DnsRRec *find_match_rrecord(const char *dname, DnsRRec *RRlist, U16 rtype){ DnsRRec *rrec = RRlist; while ( rrec != NULL ) { if ( rrec->r_type == rtype && strcmp(dname, rrec->r_dname) == 0 ) return rrec; rrec = rrec->r_next; } return NULL;} /* end find_match_rrecord() *//* * find_num_match() * * this routine will search through the entire list of RRs and count the * number that match the type and domain name. * * return: number of matching. */intfind_num_match(const char *dname, DnsRRec *RRlist, U16 rtype){ int cnt = 0; DnsRRec *rrec = RRlist; while ( rrec != NULL ) { if ( rrec->r_type == rtype && strcmp(dname, rrec->r_dname) == 0 ) cnt++; rrec = rrec->r_next; } return cnt;} /* end find_num_match() *//* * find_num_record() * * this routine will loop through the list of RRs given and count the number * of that type, (ex. SOA). here the domain is not considered, just the record * type. * * return: number of records of the given type. */intfind_num_record(DnsRRec *rrlist, U16 rtype){ int cnt = 0; DnsRRec *rrec = rrlist; while ( rrec != NULL ) { if ( rrec->r_type == rtype ) cnt++; rrec = rrec->r_next; } return cnt;} /* end find_num_record() *//* * ip_string() * * this routine is used to construct a string to represent the IP address * in dotted decimal form from the long. */voidip_string(struct sockaddr_storage *ip, char *str, int size){ void *ptr; if (ip->__ss_family == AF_INET) { ptr = &((struct sockaddr_in *)ip)->sin_addr; } else { ptr = &((struct sockaddr_in6 *)ip)->sin6_addr; } if (inet_ntop(ip->__ss_family, ptr, str, size) == NULL) { sprintf(str, "<error>"); }} /* end ip_string() *//* * lowercase_copy() * * this routine will copy to destination from source. it converts an upper * case characters to lower case before the copy. * NOTE: can't use the following statement: *to++ = tolower(*fptr++); in the * while loop because of the tolower macro. */voidlowercase_copy(char *destination, const char *source){ char *fptr; fptr = (char *)source; while ( *fptr != '\0' ) { *destination = tolower(*fptr); destination++; fptr++; } *destination = '\0';} /* end lowercase_copy() *//* * dns_copy_question() * * this routine will copy the contents of the from question to the to question. */voiddns_copy_question(DnsQuestion *qto, DnsQuestion *qfrom){ qto->q_type = qfrom->q_type; qto->q_class = qfrom->q_class; strcpy(qto->q_name, qfrom->q_name);} /* end dns_copy_question() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -