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

📄 resolv.c

📁 uc/os的网络协议栈ucIP
💻 C
📖 第 1 页 / 共 2 页
字号:
/* resolv.c: DNS Resolver * * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>, *                     The Silver Hammer Group, Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * *  5-Oct-2000 W. Greathouse  wgreathouse@smva.com *                              Fix memory leak and memory corruption. *                              -- Every name resolution resulted in *                                 a new parse of resolv.conf and new *                                 copy of nameservers allocated by *                                 strdup. *                              -- Every name resolution resulted in *                                 a new read of resolv.conf without *                                 resetting index from prior read... *                                 resulting in exceeding array bounds. * *                              Limit nameservers read from resolv.conf * *                              Add "search" domains from resolv.conf * *                              Some systems will return a security *                              signature along with query answer for *                              dynamic DNS entries. *                              -- skip/ignore this answer * *                              Include arpa/nameser.h for defines. * *                              General cleanup * 6-2-2001 Craig Graham *          - Ported to ISS OS *          - Added better answer search algorithm *          - Added support for static builtin name server list *          - Added defines to use the uC/IP UDP API directly instead of going via the *            (slightly slower) generic socket API. *          - Added uC/IP style timeouts on waiting for a response (ISS OS doesn't support signals) */#define USE_UCIP_DIRECT 1#include <config.h>#include <string.h>#include <stdio.h>#include <errno.h>#include <sys/socket.h>#if (USE_UCIP_DIRECT==0)#include <signal.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#include "netconf.h"#include "net.h"#include "netbuf.h"#include "netip.h"//#include "net_adl.h"#include "nettimer.h"#include "netudp.h"#include <stdlib.h>#include <unistd.h>//#include <cfgfile.h>#include "resolv.h"#include "nameser.h"#include <stdarg.h>#ifdef ISS_OS#include <adl.h>#include <adl_ls808.h>#else#define UNCACHED(X) (X)#endif#define MAX_RECURSE 5#define REPLY_TIMEOUT 10#define MAX_RETRIES 15#define MAX_SERVERS 3#define MAX_SEARCH 4#define L_encodeh#define L_decodeh#define L_encoded#define L_decoded#define L_lengthd#define L_encodeq#define L_decodeq#define L_lengthq#define L_encodea#define L_decodea#define L_encodep#define L_decodep#define L_formquery#define L_dnslookup#define L_resolveaddress#define L_resolvemailbox#define L_opennameservers#define L_closenameservers#define L_resolvename#define L_gethostbyname//#define L_gethostbyaddr#if 0#define RESOLVDEBUG(A) printf A#else#define RESOLVDEBUG(A)#endif/** * Switch. * 0=use /etc/resolv.conf for nameserver list, * 1=static nameserver list */#define USE_RESOLV_CONF 0#ifdef L_encodehint encode_header(struct resolv_header *h, unsigned char *dest, int maxlen){        if (maxlen < HFIXEDSZ)                return -1;        dest[0] = (h->id & 0xff00) >> 8;        dest[1] = (h->id & 0x00ff) >> 0;        dest[2] = (h->qr ? 0x80 : 0) |                ((h->opcode & 0x0f) << 3) |                (h->aa ? 0x04 : 0) | (h->tc ? 0x02 : 0) | (h->rd ? 0x01 : 0);        dest[3] = (h->ra ? 0x80 : 0) | (h->rcode & 0x0f);        dest[4] = (h->qdcount & 0xff00) >> 8;        dest[5] = (h->qdcount & 0x00ff) >> 0;        dest[6] = (h->ancount & 0xff00) >> 8;        dest[7] = (h->ancount & 0x00ff) >> 0;        dest[8] = (h->nscount & 0xff00) >> 8;        dest[9] = (h->nscount & 0x00ff) >> 0;        dest[10] = (h->arcount & 0xff00) >> 8;        dest[11] = (h->arcount & 0x00ff) >> 0;        return HFIXEDSZ;}#endif#ifdef L_decodehint decode_header(unsigned char *data, struct resolv_header *h){        h->id = (data[0] << 8) | data[1];        h->qr = (data[2] & 0x80) ? 1 : 0;        h->opcode = (data[2] >> 3) & 0x0f;        h->aa = (data[2] & 0x04) ? 1 : 0;        h->tc = (data[2] & 0x02) ? 1 : 0;        h->rd = (data[2] & 0x01) ? 1 : 0;        h->ra = (data[3] & 0x80) ? 1 : 0;        h->rcode = data[3] & 0x0f;        h->qdcount = (data[4] << 8) | data[5];        h->ancount = (data[6] << 8) | data[7];        h->nscount = (data[8] << 8) | data[9];        h->arcount = (data[10] << 8) | data[11];        return HFIXEDSZ;}#endif#ifdef L_encoded/* Encode a dotted string into nameserver transport-level encoding.   This routine is fairly dumb, and doesn't attempt to compress   the data */int encode_dotted(const char *dotted, unsigned char *dest, int maxlen){        int used = 0;        while (dotted && *dotted) {                char *c = strchr(dotted, '.');                int l = c ? c - dotted : strlen(dotted);                if (l >= (maxlen - used - 1))                        return -1;                dest[used++] = l;                memcpy(dest + used, dotted, l);                used += l;                if (c)                        dotted = c + 1;                else                        break;        }        if (maxlen < 1)                return -1;        dest[used++] = 0;        return used;}#endif#ifdef L_decoded/* Decode a dotted string from nameserver transport-level encoding.   This routine understands compressed data. */int decode_dotted(const unsigned char *data, int offset,                                  char *dest, int maxlen){        int l;        int measure = 1;        int total = 0;        int used = 0;        if (!data)                return -1;        while ((l = data[offset++])) {                if (measure && total++)                        break;                if ((l & 0xc0) == (0xc0)) {                        if (measure)                                total++;                        /* compressed item, redirect */                        offset = ((l & 0x3f) << 8) | data[offset];                        measure = 0;                        continue;                }                if ((used + l + 1) >= maxlen)                        return -1;                memcpy(dest + used, data + offset, l);                offset += l;                used += l;                if (measure)                        total += l;                if (data[offset] != 0)                        dest[used++] = '.';                else                        dest[used++] = '\0';        }        RESOLVDEBUG(("Total decode len = %d\n", total));        return total;}#endif#ifdef L_lengthdint length_dotted(const unsigned char *data, int offset){        int orig_offset = offset;        int l;        if (!data)                return -1;        while ((l = data[offset++])) {                if ((l & 0xc0) == (0xc0)) {                        offset++;                        break;                }                offset += l;        }        return offset - orig_offset;}#endif#ifdef L_encodeqint encode_question(struct resolv_question *q,                                        unsigned char *dest, int maxlen){        int i;        i = encode_dotted(q->dotted, dest, maxlen);        if (i < 0)                return i;        dest += i;        maxlen -= i;        if (maxlen < 4)                return -1;        dest[0] = (q->qtype & 0xff00) >> 8;        dest[1] = (q->qtype & 0x00ff) >> 0;        dest[2] = (q->qclass & 0xff00) >> 8;        dest[3] = (q->qclass & 0x00ff) >> 0;        return i + 4;}#endif#ifdef L_decodeqint decode_question(unsigned char *message, int offset,                                        struct resolv_question *q){        char temp[256];        int i;        i = decode_dotted(message, offset, temp, sizeof(temp));        if (i < 0)                return i;        offset += i;        q->dotted = strdup(temp);        q->qtype = (message[offset + 0] << 8) | message[offset + 1];        q->qclass = (message[offset + 2] << 8) | message[offset + 3];        return i + 4;}#endif#ifdef L_lengthqint length_question(unsigned char *message, int offset){        int i;        i = length_dotted(message, offset);        if (i < 0)                return i;        return i + 4;}#endif#ifdef L_encodeaint encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen){        int i;        i = encode_dotted(a->dotted, dest, maxlen);        if (i < 0)                return i;        dest += i;        maxlen -= i;        if (maxlen < (RRFIXEDSZ+a->rdlength))                return -1;        *dest++ = (a->atype & 0xff00) >> 8;        *dest++ = (a->atype & 0x00ff) >> 0;        *dest++ = (a->aclass & 0xff00) >> 8;        *dest++ = (a->aclass & 0x00ff) >> 0;        *dest++ = (a->ttl & 0xff000000) >> 24;        *dest++ = (a->ttl & 0x00ff0000) >> 16;        *dest++ = (a->ttl & 0x0000ff00) >> 8;        *dest++ = (a->ttl & 0x000000ff) >> 0;        *dest++ = (a->rdlength & 0xff00) >> 8;        *dest++ = (a->rdlength & 0x00ff) >> 0;        memcpy(dest, a->rdata, a->rdlength);        return i + RRFIXEDSZ + a->rdlength;}#endif#ifdef L_decodeaint decode_answer(unsigned char *message, int offset,                                  struct resolv_answer *a){        char temp[256];        int i;        i = decode_dotted(message, offset, temp, sizeof(temp));        if (i < 0)                return i;        message += offset + i;        a->dotted = strdup(temp);				printf("a->dotted=%p\n",a->dotted);        a->atype = (message[0] << 8) | message[1];        message += 2;        a->aclass = (message[0] << 8) | message[1];        message += 2;        a->ttl = (message[0] << 24) |                (message[1] << 16) | (message[2] << 8) | (message[3] << 0);        message += 4;        a->rdlength = (message[0] << 8) | message[1];        message += 2;        a->rdata = message;        a->rdoffset = offset + i + RRFIXEDSZ;        RESOLVDEBUG(("i=%d,rdlength=%d\n", i, a->rdlength));        return i + RRFIXEDSZ + a->rdlength;}#endif#ifdef L_encodepint encode_packet(struct resolv_header *h,                                  struct resolv_question **q,                                  struct resolv_answer **an,                                  struct resolv_answer **ns,                                  struct resolv_answer **ar,                                  unsigned char *dest, int maxlen){        int i, total = 0;        int j;        i = encode_header(h, dest, maxlen);        if (i < 0)                return i;        dest += i;        maxlen -= i;        total += i;        for (j = 0; j < h->qdcount; j++) {                i = encode_question(q[j], dest, maxlen);                if (i < 0)                        return i;                dest += i;                maxlen -= i;                total += i;        }        for (j = 0; j < h->ancount; j++) {                i = encode_answer(an[j], dest, maxlen);                if (i < 0)                        return i;                dest += i;                maxlen -= i;                total += i;        }        for (j = 0; j < h->nscount; j++) {                i = encode_answer(ns[j], dest, maxlen);                if (i < 0)                        return i;                dest += i;                maxlen -= i;                total += i;        }        for (j = 0; j < h->arcount; j++) {                i = encode_answer(ar[j], dest, maxlen);                if (i < 0)                        return i;                dest += i;                maxlen -= i;                total += i;        }        return total;}#endif#ifdef L_decodepint decode_packet(unsigned char *data, struct resolv_header *h){        return decode_header(data, h);}#endif#ifdef L_formqueryint form_query(int id, const char *name, int type, unsigned char *packet,                           int maxlen){        struct resolv_header h;        struct resolv_question q;        int i, j;        memset(&h, 0, sizeof(h));        h.id = id;        h.qdcount = 1;        q.dotted = (char *) name;        q.qtype = type;        q.qclass = C_IN; /* CLASS_IN */        i = encode_header(&h, packet, maxlen);        if (i < 0)                return i;        j = encode_question(&q, packet + i, maxlen - i);        if (j < 0)                return j;        return i + j;}#endif#ifdef L_dnslookupstatic volatile int dns_caught_signal = 0;#if USE_UCIP_DIRECTextern void unblock(int sockfd);static void dns_timeout(void *p){	dns_caught_signal = 1;	udpUnblockRead((int)p);}#elsevoid dns_catch_signal(int signo){        dns_caught_signal = 1;}#endifint dns_lookup(const char *name, int type, int nscount, char **nsip,                           unsigned char **outpacket, struct resolv_answer *a){	static int id = 1;	int i, j, len, fd, pos;	static int ns = 0;	struct sockaddr_in sa;#if (USE_UCIP_DIRECT==0)	int oldalarm;	__sighandler_t oldhandler;#endif	struct resolv_header h;	struct resolv_question q;	int retries = 0;	unsigned char * packet = malloc(PACKETSZ);	unsigned char * lookup = malloc(MAXDNAME);	int variant = 0;	extern int searchdomains;	extern const char * searchdomain[MAX_SEARCH];	struct resolv_answer tmpA;	fd = -1;	if (!packet || !lookup || !nscount)		goto fail;	RESOLVDEBUG(("Looking up type %d answer for '%s'\n", type, name));	ns %= nscount;	a->atype=0;	while (retries++ < MAX_RETRIES)	{		if (fd != -1)#if USE_UCIP_DIRECT			udpClose(fd);#else			close(fd);#endif#if USE_UCIP_DIRECT		fd=udpOpen();#else		fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);#endif		if (fd == -1)			goto fail;		memset(packet, 0, PACKETSZ);		memset(&h, 0, sizeof(h));		h.id = ++id;		h.qdcount = 1;		h.rd = 1;		RESOLVDEBUG(("encoding header\n", h.rd));		i = encode_header(&h, packet, PACKETSZ);		if (i < 0)			goto fail;		strncpy(lookup,name,MAXDNAME);		if (variant < searchdomains)		{			strncat(lookup,".", MAXDNAME);			strncat(lookup,searchdomain[variant], MAXDNAME);		}		RESOLVDEBUG(("lookup name: %s\n", lookup));		q.dotted = (char *)lookup;		q.qtype = type;		q.qclass = C_IN; /* CLASS_IN */		j = encode_question(&q, packet+i, PACKETSZ-i);		if (j < 0)			goto fail;		len = i + j;		RESOLVDEBUG(("On try %d, sending query to port %d of machine %s\n",										retries, NAMESERVER_PORT, nsip[ns]));		sa.sin_family = AF_INET;		sa.sin_port = htons(NAMESERVER_PORT);		sa.sin_addr.s_addr = inet_addr(nsip[ns]);#if USE_UCIP_DIRECT		if (udpConnect(fd, UNCACHED(&sa), 0) == -1)#else		if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1)#endif		{			if (errno == ENETUNREACH)			{				/* routing error, presume not transient */				goto tryall;			} else{				/* retry */				continue;			}		}		RESOLVDEBUG(("Transmitting packet of length %d, id=%d, qr=%d\n",										len, h.id, h.qr));#if USE_UCIP_DIRECT		udpWrite(fd,UNCACHED(packet),len);#else		write(fd, packet, len);#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -