⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns_client_resource.c

📁 DNS 的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
{    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 + -