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

📄 udp_dom.c

📁 dos下开发TCP网络的库文件部分
💻 C
📖 第 1 页 / 共 2 页
字号:
    nans = intel16(qp->h.ancount);		/* number of answers */
    rcode = DRCODE & intel16(qp->h.flags);	/* return code for this message*/
    if (rcode > 0)
	return(rcode);

    if (nans > 0 &&								/* at least one answer */
    (intel16(qp->h.flags) & DQR)) {			/* response flag is set */
    p = (byte *)&qp->x;                 /* where question starts */
	i = unpackdom((char*)space,(char*)p,(char*)qp);    /* unpack question name */
	/*  spec defines name then  QTYPE + QCLASS = 4 bytes */
	p += i+4;
/*
 *  at this point, there may be several answers.  We will take the first
 *  one which has an IP number.  There may be other types of answers that
 *  we want to support later.
 */
	while (nans-- > 0) {					/* look at each answer */
	    i = unpackdom((char*)space,(char*)p,(char*)qp);	/* answer name to unpack */
	    /*			n_puts(space);*/
	    p += i;								/* account for string */
	    rrp = (struct rrpart *)p;			/* resource record here */
 /*
  *  check things which might not align on 68000 chip one byte at a time
  */
	    if (!*p && *(p+1) == dtype && 		/* correct type and class */
	    !*(p+2) && *(p+3) == DIN) {
		unpacker(data,rrp,qp);     /* get data we're looking for */
		return(0);						/* successful return */
	    }
	    movmem(&rrp->rdlength,&j,2);	/* 68000 alignment */
	    p += 10+intel16(j);				/* length of rest of RR */
	}
    }

    return(-1);						/* generic failed to parse */
}

/*********************************************************************/
/*  getdomain
*   Look at the results to see if our DOMAIN request is ready.
*   It may be a timeout, which requires another query.
*/

static int udpdom( byte dtype, unpacker_funct unpacker, void *data )
{
    int i,uret;

    uret = sock_fastread((sock_type*)dom_sock, (byte*)question, sizeof(struct useek ));
    /* this does not happen */
    if (uret < 0) {
	/*		netputevent(USERCLASS,DOMFAIL,-1);  */
   return(0);  /* ?? why'd I change this? -md */
//	return(-1);
    }

 /* num = intel16(question->h.ident); */     /* get machine number */
/*
 *  check to see if the necessary information was in the UDP response
 */

    i = (int) ddextract(question, dtype, unpacker, data);
    switch (i) {
        case 0: return(1); /* we got a response */
        case 3:	return(0);		/* name does not exist */
        case -1:return( 0 );		/* strange return code from ddextract */
	default:return( 0 );            /* dunno */
    }
}


/**************************************************************************/
/*  Sdomain
*   DOMAIN based name lookup
*   query a domain name server to get resource record data
*	Returns the data on a machine from a particular RR type.
*   Events generated will have this number tagged with them.
*   Returns various negative numbers on error conditions.
*
*   if adddom is nonzero, add default domain
*
*   Returns true if we got data, false otherwise.
*/
static int Sdomain( char *mname, byte dtype, unpacker_funct unpacker,
	    void *data, int adddom, longword nameserver, byte *timedout,
	    sockfunct_t fn ) 		// S. Lawson
/* int *timedout; set to 1 on timeout */
{
    char namebuff[512];
/*    int domainsremaining; */
    int /*status,*/ i;
    int result;
    int fnbroke;		// S. Lawson

    result = 0;
    fnbroke = 0;		// S. Lawson
    *timedout = 1;

    if (!nameserver) {	/* no nameserver, give up now */
	outs("No nameserver defined!\n\r");
	return(0);
    }

    while (*mname && *mname < 33) mname ++;   /* kill leading spaces */

    if (!(*mname))
	return(0);

    qinit();				/* initialize some flag fields */

    strcpy( namebuff, mname );

    if ( adddom ) {
	if(namebuff[strlen(namebuff)-1] != '.') {       /* if no trailing dot */
	    if(loc_domain) {             /* there is a search list */
//		domainsremaining = countpaths( loc_domain );    // why this here? -md

		strcat(namebuff,".");
		strcat(namebuff,getpath(loc_domain,1));
	    }
	} else
	    namebuff[ strlen(namebuff)-1] = 0;	/* kill trailing dot */
    }
    /*
     * This is not terribly good, but it attempts to use a binary
     * exponentially increasing delays.
     */

     for ( i = 2; i < 17; i *= 2) {
	sendom(namebuff,nameserver, 0xf001, dtype);	/* try UDP */

	ip_timer_init( dom_sock, i );
	do {
	    kbhit();
	    tcp_tick( dom_sock );
	    if (ip_timer_expired( dom_sock )) break;
	    if ( watcbroke ) {
		break;
	    }
	    if (chk_timeout( timeoutwhen ))
		break;

	    // S. Lawson - call the idle/break function
	    if (fn && fn(NULL)!=0) {
	       result=fnbroke=-1;
	       *timedout=1;
	       break;
	    }

	    if ( sock_dataready( dom_sock )) *timedout = 0;
	} while ( *timedout );

	if ( !*timedout ) break;	/* got an answer */
    }

    if ( !*timedout && !fnbroke)	// S. Lawson
	result = udpdom(dtype, unpacker, data);	/* process the received data */

    sock_close( dom_sock );
    return( result );
}

/*
 * nextdomain - given domain and count = 0,1,2,..., return next larger
 *		domain or NULL when no more are available
 */
static char *nextdomain( char *domain, int count )
{
    char *p;
    int i;

    p = domain;

// S. Lawson
#ifdef SCANDOMAIN		// scan all domain pieces
    for (i = 0; i < count; ++i) {
	p = strchr( p, '.' );
	if (!p) return( NULL );
	++p;
    }
#else                          // whole domain name only
    if (count > 0) return NULL;
#endif
    return( p );
}

/*
 * Perform a nameserver lookup of specified type using specified
 *    unpacker to extract data, if found.
 */
static int do_ns_lookup( char *name, byte dtype,
		     unpacker_funct unpacker, void *data, sockfunct_t fn )  // S. Lawson
{
/*    longword temp; */
    int result = 0;             // init to false
    int count, i;
    byte timeout[ MAX_NAMESERVERS ];
    struct useek qp;        /* temp buffer */
    udp_Socket ds;          /* temp buffer */
    word oldhndlcbrk;

    question = &qp;
    dom_sock = &ds;
    if (!name) return( 0 );
    rip( name );

    if (!_domaintimeout) _domaintimeout = sock_delay << 2;
    timeoutwhen = set_timeout( _domaintimeout );

    count = 0;
    memset( &timeout, 0, sizeof( timeout ));

    oldhndlcbrk = wathndlcbrk;
    wathndlcbrk = 1;        /* enable special interrupt mode */
    watcbroke = 0;
    do {
	if ( (loc_domain = nextdomain( def_domain, count )) == NULL )
		count = -1;	/* use default name */

	for ( i = 0; i < _last_nameserver ; ++i ) {
	    if (!timeout[i])
		if ((result = Sdomain( name, dtype, unpacker, data, count != -1 ,
			def_nameservers[i], &timeout[i], fn)) == 1)	// S. Lawson
		    break;	/* got name, bail out of loop */
		if (result==-1) break;		// S. Lawson
	}

	if (count == -1) break;
	count++;
    } while (!result);
    watcbroke = 0;          /* always clean up */
    wathndlcbrk = oldhndlcbrk;

    if (result==-1) result=0;		// S. Lawson
    return( result );
}

// S. Lawson - keep a resolve(char *) version
longword resolve( char *name )
{
    return (resolve_fn(name,NULL));
}


/*
 * resolve()
 * 	convert domain name -> address resolution.
 * 	returns 0 if name is unresolvable right now
 */
longword resolve_fn( char *name, sockfunct_t fn )	// S. Lawson
{
    longword ipaddr;
    // S. Lawson
#define DNSCACHESIZE 4			// cache up to 4 names
#define DNSCACHELENGTH 32		//   up to 32 characters
#define DNSCACHETIMEOUT 120             //     for up to 2 minutes
    static char DNScacheName[DNSCACHESIZE][DNSCACHELENGTH];
    static longword DNScacheIP[DNSCACHESIZE];
    static longword DNScacheTimeout[DNSCACHESIZE]={0,0,0,0};
    static char DNScacheNext=0;
    int DNScacheScan;

    if( !name ) return 0L;

    rip( name );			// S. Lawson - trim for cache scan
    if ( isaddr( name ))
	 return( aton( name ));

    // S. Lawson
    for (DNScacheScan=0 ; DNScacheScan<DNSCACHESIZE ; DNScacheScan++) {
       if (DNScacheTimeout[DNScacheScan]==0L) continue;
       if (chk_timeout(DNScacheTimeout[DNScacheScan])) {
	  DNScacheTimeout[DNScacheScan]=0L;
	  continue;
       }
       if(!strcmpi(DNScacheName[DNScacheScan],name))
	  return DNScacheIP[DNScacheScan];
    }

#ifdef NOTUSED	// S. Lawson
    if( do_ns_lookup(name, DTYPEA, typea_unpacker, &ipaddr) )
       return (intel(ipaddr));
    else return (0L);
#else	// S. Lawson
    if( do_ns_lookup(name, DTYPEA, typea_unpacker, &ipaddr, fn) ) {
       strncpy(DNScacheName[DNScacheNext], name, DNSCACHELENGTH);
       DNScacheName[DNScacheNext][DNSCACHELENGTH-1]='\0';
       DNScacheIP[DNScacheNext]=intel(ipaddr);
       DNScacheTimeout[DNScacheNext]=set_timeout(DNSCACHETIMEOUT);
       if (++DNScacheNext>=DNSCACHESIZE) DNScacheNext=0;
       return (intel(ipaddr));
    }
    return (0L);
#endif	// S. Lawson
}

// S. Lawson - keep version w/o fn
int reverse_addr_lookup( longword ipaddr, char *name )
{
    return(reverse_addr_lookup_fn(ipaddr, name, NULL));
}

/*
 * reverse_addr_lookup()
 *    lookup a hostname based on IP address
 *          (PTR lookups in the .in-addr.arpa domain)
 *
 * Returns true if the info was found, false otherwise.
 *
 * assumes: name buffer is big enough for the longest hostname
 */
int reverse_addr_lookup_fn( longword ipaddr, char *name, sockfunct_t fn )
{
   char revname[64];

   inet_ntoa( revname, ntohl(ipaddr) );   /* ntohl flips order */
   strcat(revname, ".IN-ADDR.ARPA.");

   return ( do_ns_lookup(revname, DTYPEPTR, typeptr_unpacker, (void*)name, fn) );   // S. Lawson
}

⌨️ 快捷键说明

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