コード例 #1
0
ファイル: res.c プロジェクト: 12307/state-threads
static int parse_answer(querybuf_t *ans, int len, struct in_addr *addr)
{
  char buf[MAXPACKET];
  HEADER *ahp;
  u_char *cp, *eoa;
  int type, n;

  ahp = &ans->hdr;
  eoa = ans->buf + len;
  cp = ans->buf + sizeof(HEADER);

  while (ahp->qdcount > 0) {
    ahp->qdcount--;
    cp += dn_skipname(cp, eoa) + QFIXEDSZ;
  }
  while (ahp->ancount > 0 && cp < eoa) {
    ahp->ancount--;
    if ((n = dn_expand(ans->buf, eoa, cp, buf, sizeof(buf))) < 0)
      break;
    cp += n;
    type = _getshort(cp);
    cp += 8;
    n = _getshort(cp);
    cp += 2;
    if (type == T_CNAME) {
      cp += n;
      continue;
    }
    memcpy(addr, cp, n);
    return 0;
  }

  h_errno = TRY_AGAIN;
  return -1;
}
コード例 #2
0
ファイル: res_send.c プロジェクト: ya-mouse/dos-utils
/*
 * int res_queriesmatch(buf1, eom1, buf2, eom2)
 *    is there a 1:1 mapping of (name,type,Class)
 *    in (buf1,eom1) and (buf2,eom2)?
 * returns:
 *    -1 : format error
 *     0 : not a 1:1 mapping
 *    >0 : is a 1:1 mapping
 * author:
 *     paul vixie, 29may94
 */
int res_queriesmatch (const u_char *buf1, const u_char *eom1,
                      const u_char *buf2, const u_char *eom2)
{
  const u_char *cp = buf1 + HFIXEDSZ;
  int   qdcount    = ntohs (((HEADER*)buf1)->qdcount);

  if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
     return (0);

  while (qdcount-- > 0)
  {
    char tname[MAXDNAME+1];
    int n, ttype, tclass;

    n = dn_expand (buf1, eom1, cp, tname, sizeof(tname));
    if (n < 0)
       return (-1);
    cp += n;
    ttype  = _getshort (cp);
    cp    += INT16SZ;
    tclass = _getshort (cp);
    cp    += INT16SZ;
    if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
       return (0);
  }
  return (1);
}
コード例 #3
0
ファイル: res_parse.c プロジェクト: John-Chan/sipXtapi
        /*
         *  parse_question:
         *      Extract and parse a question record
         *
         *  returns a pointer to the question (or NULL on failure).
         */
s_question *
parse_question(
        char    **cpp,
        char    *msg)
{
        s_question      *ptr;

        if ((ptr = (s_question *)malloc(sizeof(s_question))) == NULL )
                return(NULL);
        if ((ptr->qname = expand_cdname(cpp,msg)) == NULL ) {
                free( ptr );
                return(NULL);
        }
        ptr->qtype = _getshort(*cpp);
        *cpp += sizeof(u_short);
        ptr->qclass = _getshort(*cpp);
        *cpp += sizeof(u_short);

        return(ptr);
}
コード例 #4
0
ファイル: res_send.c プロジェクト: ya-mouse/dos-utils
/*
 * int res_nameinquery(name, type, class, buf, eom)
 *    look for (name,type,class) in the query section of packet (buf,eom)
 * returns:
 *    -1 : format error
 *     0 : not found
 *    >0 : found
 * author:
 *     paul vixie, 29may94
 */
int res_nameinquery (const char *name, int type, int Class,
                     const u_char *buf, const u_char *eom)
{
  const u_char *cp = buf + HFIXEDSZ;
  int   qdcount    = ntohs (((HEADER*)buf)->qdcount);

  while (qdcount-- > 0)
  {
    char tname[MAXDNAME+1];
    int n, ttype, tclass;

    n = dn_expand (buf, eom, cp, tname, sizeof(tname));
    if (n < 0)
       return (-1);
    cp += n;
    ttype  = _getshort (cp);
    cp    += INT16SZ;
    tclass = _getshort (cp);
    cp    += INT16SZ;
    if (ttype == type && tclass == Class && !stricmp(tname,name))
       return (1);
  }
  return (0);
}
コード例 #5
0
ファイル: res_debug.c プロジェクト: ksherlock/gno
/*
 * Print resource record fields in human readable form.
 */
static char *
p_rr(char *cp, char *msg, FILE *file)
{
int type, class, dlen, n, c;
struct in_addr inaddr;
char *cp1, *cp2;

	if ((cp = p_cdname(cp, msg, file)) == NULL)
		return (NULL);			/* compression error */
	fprintf(file,"\n\ttype = %s", __p_type(type = _getshort(cp)));
	cp += sizeof(u_short);
	fprintf(file,", class = %s", __p_class(class = _getshort(cp)));
	cp += sizeof(u_short);
	fprintf(file,", ttl = %s", __p_time(_getlong(cp)));
	cp += sizeof(u_long);
	fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
	cp += sizeof(u_short);
	cp1 = cp;
	/*
	 * Print type specific data, if appropriate
	 */
	switch (type) {
	case T_A:
		switch (class) {
		case C_IN:
		case C_HS:
			bcopy(cp, (char *)&inaddr, sizeof(inaddr));
			if (dlen == 4) {
				fprintf(file,"\tinternet address = %s\n",
					inet_ntoa(inaddr));
				cp += dlen;
			} else if (dlen == 7) {
				fprintf(file,"\tinternet address = %s",
					inet_ntoa(inaddr));
				fprintf(file,", protocol = %d", cp[4]);
				fprintf(file,", port = %d\n",
					(cp[5] << 8) + cp[6]);
				cp += dlen;
			}
			break;
		default:
			cp += dlen;
		}
		break;
	case T_CNAME:
	case T_MB:
	case T_MG:
	case T_MR:
	case T_NS:
	case T_PTR:
		fprintf(file,"\tdomain name = ");
		cp = p_cdname(cp, msg, file);
		fprintf(file,"\n");
		break;

	case T_HINFO:
		if (n = *cp++) {
			fprintf(file,"\tCPU=%.*s\n", n, cp);
			cp += n;
		}
		if (n = *cp++) {
			fprintf(file,"\tOS=%.*s\n", n, cp);
			cp += n;
		}
		break;

	case T_SOA:
		fprintf(file,"\torigin = ");
		cp = p_cdname(cp, msg, file);
		fprintf(file,"\n\tmail addr = ");
		cp = p_cdname(cp, msg, file);
		fprintf(file,"\n\tserial = %ld", _getlong(cp));
		cp += sizeof(u_long);
		fprintf(file,"\n\trefresh = %s", __p_time(_getlong(cp)));
		cp += sizeof(u_long);
		fprintf(file,"\n\tretry = %s", __p_time(_getlong(cp)));
		cp += sizeof(u_long);
		fprintf(file,"\n\texpire = %s", __p_time(_getlong(cp)));
		cp += sizeof(u_long);
		fprintf(file,"\n\tmin = %s\n", __p_time(_getlong(cp)));
		cp += sizeof(u_long);
		break;

	case T_MX:
		fprintf(file,"\tpreference = %ld,",_getshort(cp));
		cp += sizeof(u_short);
		fprintf(file," name = ");
		cp = p_cdname(cp, msg, file);
		break;

  	case T_TXT:
		(void) fputs("\t\"", file);
		cp2 = cp1 + dlen;
		while (cp < cp2) {
			if (n = (unsigned char) *cp++) {
				for (c = n; c > 0 && cp < cp2; c--)
					if (*cp == '\n') {
					    (void) putc('\\', file);
					    (void) putc(*cp++, file);
					} else
					    (void) putc(*cp++, file);
			}
		}
		(void) fputs("\"\n", file);
  		break;

	case T_MINFO:
		fprintf(file,"\trequests = ");
		cp = p_cdname(cp, msg, file);
		fprintf(file,"\n\terrors = ");
		cp = p_cdname(cp, msg, file);
		break;

	case T_UINFO:
		fprintf(file,"\t%s\n", cp);
		cp += dlen;
		break;

	case T_UID:
	case T_GID:
		if (dlen == 4) {
			fprintf(file,"\t%ld\n", _getlong(cp));
			cp += sizeof(int);
		}
		break;

	case T_WKS:
		if (dlen < sizeof(u_long) + 1)
			break;
		bcopy(cp, (char *)&inaddr, sizeof(inaddr));
		cp += sizeof(u_long);
		fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
			inet_ntoa(inaddr), *cp++);
		n = 0;
		while (cp < cp1 + dlen) {
			c = *cp++;
			do {
 				if (c & 0200)
					fprintf(file," %d", n);
 				c <<= 1;
			} while (++n & 07);
		}
		putc('\n',file);
		break;

#ifdef ALLOW_T_UNSPEC
	case T_UNSPEC:
		{
			int NumBytes = 8;
			char *DataPtr;
			int i;

			if (dlen < NumBytes) NumBytes = dlen;
			fprintf(file, "\tFirst %d bytes of hex data:",
				NumBytes);
			for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
				fprintf(file, " %x", *DataPtr);
			fputs("\n", file);
			cp += dlen;
		}
		break;
#endif /* ALLOW_T_UNSPEC */

	default:
		fprintf(file,"\t???\n");
		cp += dlen;
	}
	if (cp != cp1 + dlen) {
		fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
		cp = NULL;
	}
	fprintf(file,"\n");
	return (cp);
}
コード例 #6
0
ファイル: res_debug.c プロジェクト: ksherlock/gno
/*
 * Print the contents of a query.
 * This is intended to be primarily a debugging routine.
 */
void
__fp_query(char *msg, FILE *file)
{
register char *cp;
register HEADER *hp;
register int n;

	/*
	 * Print header fields.
	 */
	hp = (HEADER *)msg;
	cp = msg + sizeof(HEADER);
	fprintf(file,"HEADER:\n");
	fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
	fprintf(file,", id = %d", ntohs(hp->id));
	fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
	fprintf(file,"\theader flags: ");
	if (hp->qr)
		fprintf(file," qr");
	if (hp->aa)
		fprintf(file," aa");
	if (hp->tc)
		fprintf(file," tc");
	if (hp->rd)
		fprintf(file," rd");
	if (hp->ra)
		fprintf(file," ra");
	if (hp->pr)
		fprintf(file," pr");
	fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
	fprintf(file,", ancount = %d", ntohs(hp->ancount));
	fprintf(file,", nscount = %d", ntohs(hp->nscount));
	fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
	/*
	 * Print question records.
	 */
	if (n = ntohs(hp->qdcount)) {
		fprintf(file,"QUESTIONS:\n");
		while (--n >= 0) {
			fprintf(file,"\t");
			cp = p_cdname(cp, msg, file);
			if (cp == NULL)
				return;
			fprintf(file,", type = %s", __p_type(_getshort(cp)));
			cp += sizeof(u_short);
			fprintf(file,
			    ", class = %s\n\n", __p_class(_getshort(cp)));
			cp += sizeof(u_short);
		}
	}
	/*
	 * Print authoritative answer records
	 */
	if (n = ntohs(hp->ancount)) {
		fprintf(file,"ANSWERS:\n");
		while (--n >= 0) {
			fprintf(file,"\t");
			cp = p_rr(cp, msg, file);
			if (cp == NULL)
				return;
		}
	}
	/*
	 * print name server records
	 */
	if (n = ntohs(hp->nscount)) {
		fprintf(file,"NAME SERVERS:\n");
		while (--n >= 0) {
			fprintf(file,"\t");
			cp = p_rr(cp, msg, file);
			if (cp == NULL)
				return;
		}
	}
	/*
	 * print additional records
	 */
	if (n = ntohs(hp->arcount)) {
		fprintf(file,"ADDITIONAL RECORDS:\n");
		while (--n >= 0) {
			fprintf(file,"\t");
			cp = p_rr(cp, msg, file);
			if (cp == NULL)
				return;
		}
	}
}
コード例 #7
0
ファイル: dns.c プロジェクト: einyx/arpwatch
int
gethinfo(register char *hostname, register char *cpu, register int cpulen,
    register char *os, register int oslen)
{
#ifdef HAVE_DN_SKIPNAME
	register querybuf *qb;
	register u_char *cp, *eom;
	register char *bp;
	register int n;
	register HEADER *hp;
	register int type, class, buflen, ancount, qdcount;
	querybuf qbuf;

	qb = &qbuf;
	n = res_query(hostname, C_IN, T_HINFO, qb->buf, sizeof(qb->buf));
	if (n < 0)
		return (0);

	eom = qb->buf + n;
	/*
	 * find first satisfactory answer
	 */
	hp = &qb->hdr;
	ancount = ntohs(hp->ancount);
	qdcount = ntohs(hp->qdcount);
	bp = hostbuf;
	buflen = sizeof(hostbuf);
	cp = qb->buf + sizeof(HEADER);
	if (qdcount) {
		cp += dn_skipname(cp, eom) + QFIXEDSZ;
		while (--qdcount > 0)
			cp += dn_skipname(cp, eom) + QFIXEDSZ;
	}
	while (--ancount >= 0 && cp < eom) {
		if ((n = dn_expand((u_char *)qb->buf, (u_char *)eom,
		    (u_char *)cp, (u_char *)bp, buflen)) < 0)
			break;
		cp += n;
		type = _getshort(cp);
 		cp += sizeof(u_short);
		class = _getshort(cp);
 		cp += sizeof(u_short) + sizeof(u_int32_t);
		n = _getshort(cp);
		cp += sizeof(u_short);
		if (type == T_HINFO) {
			/* Unpack */
			n = *cp++;
			if (n > cpulen - 1)
				return (0);
			BCOPY(cp, cpu, n);
			cp += n;
			cpu[n] = '\0';
			n = *cp++;
			if (n > oslen - 1)
				return (0);
			BCOPY(cp, os, n);
			os[n] = '\0';
			return (1);
		}
		/* Skip unexpected junk */
		cp += n;
	}
#endif
	return (0);
}
コード例 #8
0
ファイル: res_send.c プロジェクト: ya-mouse/dos-utils
static int name_server_send (int ns, struct sockaddr_in *nsap)
{
  int resplen = 0;

  if (badns & (1 << ns))  /* this NameServer already marked bad */
  {
    resolve_close();
    return (NEXT_NS);
  }

  if (Qhook)
  {
    int done = 0;
    int loops = 0;
    do
    {
      res_sendhookact act = (*Qhook) (&nsap, (const u_char**)&ns_buf,
                                      &ns_buflen, ns_ans, ns_anssiz,
                                      &resplen);
      switch (act)
      {
        case res_goahead:
             done = 1;
             break;
        case res_nextns:
             resolve_close();
             return (NEXT_NS);
        case res_done:
             return (resplen);
        case res_modified:
             /* give the hook another try */
             if (++loops < 42)
                break;
             /* fallthrough */
        case res_error:
             /* fallthrough */
        default:
             return (-1);
      }
    }
    while (!done);
  }

  Dprint (_res.options & RES_DEBUG,
          (";; Querying server (# %d) address = %s\n",
           ns + 1, inet_ntoa(nsap->sin_addr)));

  if (v_circuit)  /* i.e. TCP */
  {
    int     truncated;
    u_short len;
    u_char *cp;

    /* Use virtual circuit; at most one attempt per server.
     */
    Try = _res.retry;
    truncated = 0;
    if (!sock || !vc)
    {
      DWORD his_ip   = ntohl (nsap->sin_addr.s_addr);
      WORD  his_port = ntohs (nsap->sin_port);

      if (sock)
         resolve_close();

      sock = (sock_type*) calloc (sizeof(_tcp_Socket), 1);
      if (!sock)
      {
        Perror ("calloc(vc)", "no memory");
        return (-1);
      }

      if (!tcp_open(&sock->tcp,0,his_ip,his_port,NULL) ||
          !tcp_conn(&sock->tcp,&errno,dns_timeout))
      {
        Aerror ("tcp_open/vc", "failed/timeout", *nsap);
        badns |= (1 << ns);
        resolve_close();
        return (NEXT_NS);
      }
      vc = 1;
    }

    /* Send length & message
     */
    {
      int   send_len = INT16SZ + ns_buflen;
      BYTE *send_buf = (BYTE*) alloca (send_len);

      PUTSHORT (ns_buflen, send_buf);
      memcpy (send_buf + INT16SZ, ns_buf, ns_buflen);
      if (sock_write(sock,send_buf,send_len) != send_len)
      {
        Perror ("sock_write() failed", sockerr(sock));
        badns |= (1 << ns);
        resolve_close();
        return (NEXT_NS);
      }
    }

    /* Receive length & response
     */
    cp  = ns_ans;
    len = INT16SZ;
    while ((n = tcp_read(&sock->tcp,cp,len,&errno,dns_timeout)) > 0)
    {
      cp  += n;
      len -= n;
      if ((signed)len <= 0)
         break;
    }
    if (n <= 0)
    {
      Perror ("tcp_read() failed", sockerr(sock));
      resolve_close();
      return (NEXT_NS);
    }
    resplen = _getshort (ns_ans);
    if (resplen > ns_anssiz)
    {
      Dprint (_res.options & RES_DEBUG,(";; response truncated\n"));
      truncated = 1;
      len = ns_anssiz;
    }
    else
      len = resplen;

    cp = ns_ans;
    while (len && (n = tcp_read(&sock->tcp,cp,len,&errno,dns_timeout)) > 0)
    {
      cp  += n;
      len -= n;
    }
    if (n <= 0)
    {
      Perror ("tcp_read(vc)",sockerr(sock));
      resolve_close();
      return (NEXT_NS);
    }
    if (truncated)
    {
      /* Flush rest of answer so connection stays in synch.
       */
      anhp->tc = 1;
      len = resplen - ns_anssiz;
      while (len)
      {
        u_char junk[PACKETSZ];

        n = (len > sizeof(junk) ? sizeof(junk) : len);
        n = tcp_read (&sock->tcp,junk,n,&errno,dns_timeout);
        if (n > 0)
             len -= n;
        else break;
      }
    }
  }
  else  /* !v_circuit, i.e. UDP */
  {
    DWORD timeout;

    if (!sock || vc)
    {
      if (vc)
         resolve_close();

      sock = (sock_type*) calloc (sizeof(_udp_Socket), 1);
      if (!sock)
      {
        Perror ("calloc(dg)", "no memory");
        return (-1);
      }
      connected = 0;
    }

    /* Connect only if we are sure we won't
     * receive a response from another server.
     */
    if (!connected)
    {
      DWORD his_ip   = ntohl (nsap->sin_addr.s_addr);
      WORD  his_port = ntohs (nsap->sin_port);

      if (!udp_open(&sock->udp,0,his_ip,his_port,NULL))
      {
        Aerror ("connect/dg", "ARP failed", *nsap);
        badns |= (1 << ns);
        resolve_close();
        return (NEXT_NS);
      }
      connected = 1;
    }
    if (sock_write(sock,(const BYTE*)ns_buf,ns_buflen) != ns_buflen)
    {
      Perror ("sock_write() failed", "");
      badns |= (1 << ns);
      resolve_close();
      return (NEXT_NS);
    }

    /* Wait for reply
     */
    timeout = (unsigned)_res.retrans << Try;
    if (Try > 0)
       timeout /= _res.nscount;
    if ((long)timeout <= 0)
       timeout = 1;

  wait:

    n = udp_read (&sock->udp, ns_ans, ns_anssiz, &errno, timeout);
    if (n == 0)
    {
      Dprint (_res.options & RES_DEBUG, (";; timeout\n"));
      gotsomewhere = 1;
      resolve_close();
      return (NEXT_NS);
    }
    gotsomewhere = 1;
    if (hp->id != anhp->id)
    {
      /* response from old query, ignore it.
       * XXX - potential security hazard could be detected here.
       */
      DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY),
               (";; old answer:\n"), ns_ans, resplen);
      goto wait;
    }

    if (!(_res.options & RES_INSECURE2) &&
        !res_queriesmatch(ns_buf, ns_buf+ns_buflen, ns_ans, ns_ans+ns_anssiz))
    {
      /* response contains wrong query? ignore it.
       * XXX - potential security hazard could be detected here.
       */
      DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY),
               (";; wrong query name:\n"), ns_ans, resplen);
      goto wait;
    }
    if (anhp->rcode == SERVFAIL ||
        anhp->rcode == NOTIMP   ||
        anhp->rcode == REFUSED)
    {
      DprintQ (_res.options & RES_DEBUG,("server rejected query:\n"),
               ns_ans,resplen);
      badns |= (1 << ns);
      resolve_close();

      /* don't retry if called from dig */
      if (!_res.pfcode)
         return (NEXT_NS);
    }
    if (!(_res.options & RES_IGNTC) && anhp->tc)
    {
      /* get rest of answer; use TCP with same server.
       */
      Dprint (_res.options & RES_DEBUG, (";; truncated answer\n"));
      v_circuit = 1;
      resolve_close();
      return (SAME_NS);
    }
  } /* if vcicuit / dg */

  Dprint ((_res.options & RES_DEBUG) ||
          ((_res.pfcode & RES_PRF_REPLY) && (_res.pfcode & RES_PRF_HEAD1)),
          (";; got answer:\n"));

  DprintQ ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_REPLY),
           (" \b"), ns_ans, resplen);

  /*
   * If using virtual circuits (TCP), we assume that the first server
   * is preferred over the rest (i.e. it is on the local machine) and
   * only keep that one open. If we have temporarily opened a virtual
   * circuit, or if we haven't been asked to keep a socket open,
   * close the socket.
   */
  if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
      !(_res.options & RES_STAYOPEN))
     resolve_close();

  if (Rhook)
  {
    int done = 0, loops = 0;

    do
    {
      res_sendhookact act = (*Rhook) (nsap, ns_buf, ns_buflen,
                                      ns_ans, ns_anssiz, &resplen);
      switch (act)
      {
        case res_goahead:
        case res_done:
             done = 1;
             break;
        case res_nextns:
             resolve_close();
             return (NEXT_NS);
        case res_modified:
             /* give the hook another try */
             if (++loops < 42)
                break;
             /* fallthrough */
        case res_error:
             /* fallthrough */
        default:
             return (-1);
      }
    }
    while (!done);
  }
  return (resplen);
}
コード例 #9
0
ファイル: dnsmx.cpp プロジェクト: chengn/TortoiseGit
BOOL GetMX (
			char *pszQuery,
			char *pszServer,
			OUT t_Ary_MXHostInfos &Ary_MXHostInfos
			)
{
	SOCKET                  hSocket;
	SOCKADDR_IN             stSockAddr;                     // socket address structures
	int                             nAddrLen = sizeof( SOCKADDR_IN );

	HOSTENT                 *pHostEnt;

	char                            achBufOut[ BUFSIZE ] = { 0 };
	char                            achBufIn[ BUFSIZE ] = { 0 };
	int                             nQueryLen = 0;
	int                             nRC;

	char *p, *np, name[128], *eom;
	int count, j, i, n;

	memset( &stSockAddr, ASCII_NULL, sizeof( stSockAddr ) );

	stSockAddr.sin_family      = AF_INET;
	stSockAddr.sin_port             = htons( 53);
	stSockAddr.sin_addr.s_addr = inet_addr( pszServer );
	if ( stSockAddr.sin_addr.s_addr == INADDR_NONE )
	{
		pHostEnt = gethostbyname( pszServer );
		if ( pHostEnt )
		{
			stSockAddr.sin_addr.s_addr = *((ULONG *)pHostEnt->h_addr_list[0]);
		}
		else
		{
			return FALSE;
		} // end if
	} // end if


	  /*------------------------------------------------------------
	  *  Get a DGRAM socket
	*/

	hSocket = socket( AF_INET, SOCK_DGRAM, 0 );

	if ( hSocket == INVALID_SOCKET )
	{
		return FALSE;
	} // end if

	  /*-----------------------------------------------------------
	  * Format DNS Query
	*/

	pDNShdr = (PDNS_HDR)&( achBufOut[ 0 ] );
	pDNShdr->dns_id         = htons( 0xDEAD );
	pDNShdr->dns_flags      = htons( DNS_FLAG_RD ); // do recurse
	pDNShdr->dns_q_count    = htons( 1 );           // one query
	pDNShdr->dns_rr_count   = 0;                  // none in query
	pDNShdr->dns_auth_count = 0;                  // none in query
	pDNShdr->dns_add_count  = 0;                  // none in query

	nQueryLen = PutQName( pszQuery, &(achBufOut[ DNS_HDR_LEN ] ) );
	nQueryLen += DNS_HDR_LEN;

	achBufOut[ nQueryLen++ ]        = 0;
	achBufOut[ nQueryLen++ ]        = 0;
	achBufOut[ nQueryLen ]          = DNS_RRTYPE_MX;
	achBufOut[ nQueryLen + 1 ]      = 0;
	achBufOut[ nQueryLen + 2 ]      = DNS_RRCLASS_IN;
	achBufOut[ nQueryLen + 3 ]      = 0;

	nQueryLen += 4;

	/*-----------------------------------------------------------
	* Send DNS Query to server
	*/

	nRC = sendto( hSocket,
		achBufOut,
		nQueryLen,
		0,
		(LPSOCKADDR)&stSockAddr,
		sizeof( SOCKADDR_IN ) );

	if ( nRC == SOCKET_ERROR )
	{

		closesocket( hSocket );
		return FALSE;
	}
	else
	{

	}

//	VERIFY ( SetBlockingMode ( hSocket, TRUE ) );

	// 用 select 模型实现连接超时
	struct timeval timeout;
	fd_set r;
	FD_ZERO(&r);
	FD_SET(hSocket, &r);
	timeout.tv_sec = 5; //连接超时秒
	timeout.tv_usec =0;
	int ret = select(0, &r, 0, 0, &timeout);
	if ( ret == SOCKET_ERROR )
	{
		::closesocket(hSocket);
		hSocket = SOCKET_ERROR;
		return FALSE;
	}

	// 得到可读的数据长度
	long cmd = FIONREAD;
	u_long argp = 0;
	BOOL err = ioctlsocket ( hSocket, cmd, (u_long*)&argp );
	if ( err || argp < 1 )
	{
		::closesocket(hSocket);
		hSocket = SOCKET_ERROR;
		return FALSE;
	}

	nRC = recvfrom( hSocket,
		achBufIn,
		BUFSIZE,
		0,
		(LPSOCKADDR)&stSockAddr,
		&nAddrLen );

	if ( nRC == SOCKET_ERROR )
	{
		int nWSAErr = WSAGetLastError();

		if ( nWSAErr != WSAETIMEDOUT )
		{

			closesocket( hSocket );
			return FALSE;
		}
		else
		{

			closesocket( hSocket );
			return FALSE;
		}
	}
	else
	{
		pDNShdr = (PDNS_HDR)&( achBufIn[ 0 ] );
		p = (char *)&pDNShdr[0];
		p+=12;
		count = (int)*p;

		// Parse the Question...
		for (i = 0; i< ntohs(pDNShdr->dns_q_count); i++)
		{
			np = name;
			eom = (char *)pDNShdr+nRC;

			if ( (n = dn_expand((char *)pDNShdr, eom, p, name, 127)) < 0 )
			{
				return FALSE;

			}
			p += n + QFIXEDSZ;
		}

		for (i = 0; i< ntohs(pDNShdr->dns_rr_count); i++)
		{

			// The Question Name appears Again...
			if ((n = dn_expand((char *)pDNShdr, eom, p, name, 127)) < 0)
			{
				return FALSE;
			}
			p+=n;


			j =  _getshort(p);;  //TYPE
			p+=2;
			//printf("%s\tType:%d", name, j);

			j = _getshort(p);  //CLASS
			p+=2;
			//	printf("\tClass:%d", j);

			j = _getlong(p);  //TTL
			p+=4;
			//	printf("\tTTL:%d", j);

			j = _getshort(p);  //RDLENGTH
			p+=2;
			//	printf("\tRDLENGTH:%d", j);

			j = _getshort(p);  //N??
			p+=2;

			// This should be an MX Name...
			if ( (n = dn_expand((char *)pDNShdr, eom, p, name, 127)) < 0 )
			{
				return FALSE;
			}

			t_MXHostInfo tMXHostInfo = {0};
			strncpy ( (char*)tMXHostInfo.szMXHost, name, _countof(tMXHostInfo.szMXHost));
			tMXHostInfo.N = j;
			Ary_MXHostInfos.Add ( tMXHostInfo );
			TRACE ( _T("%s\t%d\r\n"), name, j );
			p += n;
		}
		return TRUE;


	}


	closesocket( hSocket );
	return FALSE;
}
コード例 #10
0
ファイル: res_parse.c プロジェクト: John-Chan/sipXtapi
        /*
         *  parse_rr:
         *      Extract and parse a resource record
         *
         *  returns a pointer to the RR (or NULL on failure).
         */
s_rr *
parse_rr(
        char    **cpp,
        char    *msg)
{
        s_rr            *ptr;
        int             dlen;
        union u_rdata   *rd;


                /*
                 *  Set up the RR-independent information
                 */
        if ((ptr = (s_rr *)malloc(sizeof(s_rr))) == NULL )
                return(NULL);
        if ((ptr->name = expand_cdname(cpp,msg)) == NULL ) {
                free(ptr);
                return(NULL);
        }
        ptr->type = _getshort(*cpp);
        *cpp += sizeof(u_short);
        ptr->rclass = _getshort(*cpp);
        *cpp += sizeof(u_short);
        ptr->ttl = _getlong(*cpp);
        /* Size on the network is 4 bytes so use u_int not u_long as
         * u_long is architecture dependent (e.g. 8 bytes on 64 bit). */
        *cpp += sizeof(u_int);

        dlen = _getshort(*cpp);
        ptr->dlen = dlen;
        *cpp += sizeof(u_short);

        rd = &ptr->rdata;


                /*
                 *  Handle RR-specifics
                 *
                 *    (No indication of failures here is
                 *      passed back to the calling procedure)
                 */
        switch(ptr->type) {
        case T_A:                               /* Address */
                switch (ptr->rclass) {
                case C_IN:
                        memcpy((void *)&rd->address, (void *)*cpp, sizeof(struct in_addr));
                        *cpp += dlen;
                        break;

                default:
                        /* Can't really handle this - just skip it */
                        *cpp += dlen;
                }
                break;

        case T_NS:                              /* Name Server */
        case T_MD:                              /* Mail Destination (OBS) */
        case T_MF:                              /* Mail Forwarder   (OBS) */
        case T_CNAME:                           /* Canonical Name */
                rd->string = expand_cdname(cpp, msg);
                break;

        case T_SOA:                             /* Start of Authority */
                rd->soa.mname = expand_cdname(cpp, msg);
                rd->soa.rname = expand_cdname(cpp, msg);
                rd->soa.serial = _getlong(*cpp);
                *cpp += sizeof(u_long);
                rd->soa.refresh = _getlong(*cpp);
                *cpp += sizeof(u_long);
                rd->soa.retry = _getlong(*cpp);
                *cpp += sizeof(u_long);
                rd->soa.expire = _getlong(*cpp);
                *cpp += sizeof(u_long);
                rd->soa.minimum = _getlong(*cpp);
                *cpp += sizeof(u_long);
                break;

        case T_MB:                              /* Mail Box  */
        case T_MG:                              /* Mail Group */
        case T_MR:                              /* Mail Rename */
                rd->string = expand_cdname(cpp, msg);
                break;

/* Following modification taken from VxWorks --GAT */
/* 01b,29apr97,jag Changed T_NULL to T_NULL_RR to fix conflict with loadCoffLib.h */
        case T_NULL_RR:                         /* Null RR */
                if ((rd->null.anything = (char *)malloc(dlen)) != NULL )
                        memcpy((void *)rd->null.anything, (void *)*cpp, dlen);
                rd->null.length = dlen;
                *cpp += dlen;
                break;

        case T_WKS:                             /* Well Known Services */
                memcpy((void *)&rd->wks.address, (void *)*cpp, sizeof(struct in_addr));
                *cpp += sizeof(struct in_addr);
                rd->wks.protocol = **cpp;
                (*cpp)++;
                rd->wks.maplength = dlen-(sizeof(struct in_addr) +1);
                if ((rd->wks.bitmap = (char *)malloc(rd->wks.maplength)) != NULL )
                        memcpy((void *)rd->wks.bitmap, (void *)*cpp, rd->wks.maplength);
                *cpp += rd->wks.maplength;
                break;

        case T_PTR:                             /* Domain Name Pointer */
                rd->string = expand_cdname(cpp, msg);
                break;

        case T_HINFO:                           /* Host Info */
                if (( rd->hinfo.cpu = expand_charstring(cpp, msg)) == NULL ) {
                        cpp += dlen;
                        break;
                }
                if (( rd->hinfo.os = expand_charstring(cpp, msg)) == NULL ) {
                        cpp -= (strlen(rd->hinfo.cpu) +1);
                        cpp += dlen;
                        break;
                }
                break;

        case T_MINFO:                           /* Mailbox Info */
                rd->minfo.rmailbx = expand_cdname(cpp, msg);
                rd->minfo.emailbx = expand_cdname(cpp, msg);
                break;

        case T_MX:                              /* Mail Exchanger */
                rd->mx.preference = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->mx.exchange = expand_cdname(cpp, msg);
                break;

        case T_SRV:                             /* Service location */
                rd->srv.priority = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->srv.weight = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->srv.port = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->srv.target = expand_cdname(cpp, msg);
                break;

        case T_NAPTR:                           /* Naming authority pointer */
        {
                // This is copied from the other cases, but I think that
                // all cases should be setting *cpp += dlen, not
                // cpp += dlen.
                char **cpp_end = cpp + dlen;
                rd->naptr.order = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->naptr.preference = _getshort(*cpp);
                *cpp += sizeof(u_short);
                if (( rd->naptr.flags = expand_charstring(cpp, msg)) == NULL ) {
                        cpp = cpp_end;
                        break;
                }
                if (( rd->naptr.services = expand_charstring(cpp, msg)) == NULL ) {
                        cpp = cpp_end;
                        break;
                }
                if (( rd->naptr.regexp = expand_charstring(cpp, msg)) == NULL ) {
                        cpp = cpp_end;
                        break;
                }
                rd->naptr.replacement = expand_cdname(cpp, msg);
        }
                break;

        case T_TXT:                             /* Text string */
                rd->txt.len = **cpp;
                rd->txt.next = NULL;
                if ((rd->txt.text = expand_charstring(cpp, msg)) == NULL ) {
                        cpp += dlen;
                        break;
                }

                        /*
                         *  Multiple strings
                         *      add onto a linked list
                         */
                if ( rd->txt.len+1 < dlen ) {
                        struct s_TXT    *txtp;
                        char            **cpp2;
                        int             n;

                        n = rd->txt.len+1;
                        txtp = &(rd->txt);
                        cpp2 = cpp;
                        while ( n < dlen ) {
                                if ((txtp->next = (struct s_TXT *)malloc(sizeof(struct s_TXT))) == NULL ) {
                                        cpp += (dlen - rd->txt.len);
                                        break;
                                }
                                txtp = txtp->next;
                                txtp->len = **cpp2;
                                n += txtp->len+1;
                                txtp->next = NULL;
                                if ((txtp->text = expand_charstring(cpp2, msg)) == NULL ) {
                                        cpp += (dlen - rd->txt.len);
                                        break;
                                }
                        }
                }
                break;


                        /*
                         *  RFC 1183  Additional types
                         */
        case T_AFSDB:                           /* AFS Server */
                rd->afsdb.subtype = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->afsdb.hostname = expand_cdname(cpp, msg);
                break;


        case T_RP:                              /* Responsible Person */
                rd->rp.mbox_dname = expand_cdname(cpp, msg);
                rd->rp.txt_dname = expand_cdname(cpp, msg);
                break;

        case T_X25:                             /* X25 Address */
                rd->string = expand_charstring(cpp, msg);
                break;

        case T_ISDN:                            /* ISDN Address */
                if ( **cpp == dlen ) {
                        rd->isdn.address = expand_charstring(cpp, msg);
                        rd->isdn.sa = NULL;
                }
                else {
                        rd->isdn.address = expand_charstring(cpp, msg);
                        rd->isdn.sa = expand_charstring(cpp, msg);
                }
                break;

        case T_RT:                              /* Route Through */
                rd->rt.preference = _getshort(*cpp);
                *cpp += sizeof(u_short);
                rd->rt.int_host = expand_cdname(cpp, msg);
                break;

                        /*
                         *  Additional Non-standard types
                         */
        case T_UINFO:                           /* User (finger) info */
                if ((rd->string = (char *)malloc(dlen+1)) != NULL ) {
                        memcpy((void *)rd->string, (void *)*cpp, dlen);
                        rd->string[dlen] = '\0';
                }
                *cpp += dlen;
                break;

        case T_UID:                             /* User ID */
        case T_GID:                             /* Group ID */
                rd->number = _getlong(*cpp);
                *cpp += sizeof(u_long);
                break;

        case T_UNSPEC:                          /* Unspecified info */
        default:                                /* Unrecognised */
                if ((rd->string = (char *)malloc(dlen+1)) != NULL )
                        memcpy((void *)rd->string, (void *)*cpp, dlen);
                *cpp += dlen;
                break;

        }


        return(ptr);
}