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

📄 dns.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/* dns.c: *  Support a basic DNS query. *  NOT READY YET!!! * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com *  Phone:              908-582-2351 */#include "config.h"#if INCLUDE_DNSQUERY#include "endian.h"#include "genlib.h"#include "ether.h"#include "stddefs.h"#include "cli.h"char *DnsHelp[] = {    "DNS query",    "-[c:d:f:v:] {operation} [args]",    "Options...",    " -c {#}    echo count",    " -d {#}    delta (hours) relative to GMT",    " -f {x|d}  hex or decimal output (default is ascii)",    " -r        check server resolution",    " -v {var}  load result in shellvar 'var'",    "Operations...",    " time {IP}",    " echo {IP}",    "Notes...",    " If '.ns' is appended to time, then time is non-standard.",    " The 'dfrv' options are used by icmp time, option 'c' is used by echo.",    0,};intDns(int argc,char *argv[]){    int     timestamp, hour, min, sec, opt, gmt_delta, timeout, count;    char    *varname, format, *nonstandard, *operation, *ipadd;    uchar   binip[8], binenet[8], buf[32];    ushort  seqno;    gmt_delta = 0;    count = 1;    varname = (char *)0;    format = 'a';    nonstandard = "";    CheckSrvrResolution = 0;    while ((opt=getopt(argc,argv,"c:d:f:rv:")) != -1) {        switch(opt) {        case 'c':   /* count used by ping */            count = strtol(optarg,(char **)0,0);            break;        case 'd':   /* difference between this time zone and Greenwich */            gmt_delta = strtol(optarg,(char **)0,0);            break;        case 'f':            format = *optarg;            break;        case 'r':            CheckSrvrResolution = 1;            break;        case 'v':            varname = optarg;            break;        default:            return(CMD_PARAM_ERROR);        }    }    if (argc == optind)        return(-1);    operation = argv[optind];    ipadd = argv[optind+1];        /* If time or echo, do the common up-front stuff here... */    if (!strcmp(operation,"time") || !strcmp(operation,"echo")) {        if (argc != optind + 2)            return(CMD_PARAM_ERROR);        /* Convert IP address to binary: */        if (IpToBin(ipadd,binip) < 0)            return(CMD_SUCCESS);    }    if (!strcmp(operation, "time")) {        /* Get the ethernet address for the IP: */        if (!ArpEther(binip,binenet,0)) {            printf("ARP failed for %s\n",ipadd);            return(CMD_FAILURE);        }        ICMPTimeStamp = INVALID_TIMESTAMP;        SendICMPRequest(ICMP_TIMEREQUEST,binip,binenet,0,0);        /* Timeout waiting for timestamp after waiting about 2 seconds. */        timeout = LoopsPerSecond * 2;        while(timeout > 0) {            pollethernet();            timeout--;            if (ICMPTimeStamp != INVALID_TIMESTAMP)                break;        }        if (timeout == 0) {            printf("No response\n");            return(CMD_FAILURE);        }        if (ICMPTimeStamp & NONSTANDARD_TIMESTAMP) {            ICMPTimeStamp &= ~NONSTANDARD_TIMESTAMP;            nonstandard = ".ns";        }        if (format == 'a') {            timestamp = ICMPTimeStamp + (gmt_delta*MSECS_PER_HOUR);            hour = timestamp/MSECS_PER_HOUR;            timestamp -= hour*MSECS_PER_HOUR;            min = timestamp/MSECS_PER_MINUTE;            timestamp -= min*MSECS_PER_MINUTE;            sec = timestamp/MSECS_PER_SECOND;            timestamp -= sec*MSECS_PER_SECOND;            sprintf(buf,"%02d:%02d:%02d.%03d%s",hour,min,sec,timestamp,                nonstandard);        }        else if (format == 'x')            sprintf(buf,"0x%lx%s",ICMPTimeStamp,nonstandard);        else if (format == 'd')            sprintf(buf,"%ld%s",ICMPTimeStamp,nonstandard);        else            return(CMD_PARAM_ERROR);        if (varname)            setenv(varname,buf);        else if (!CheckSrvrResolution)            printf("%s\n",buf);        CheckSrvrResolution = 0;    }    else if (!strcmp(operation, "echo")) {        seqno = 0;        while (count-- > 0) {            /* Is this a self-ping? */            if (memcmp(binip,BinIpAddr,4) == 0) {                printf("Yes, I am alive!\n");                break;            }            /* Get the ethernet address for the IP: */            if (!ArpEther(binip,binenet,0)) {                printf("ARP failed for %s\n",ipadd);                continue;            }            ICMPEchoReplyId = 0;            SendICMPRequest(ICMP_ECHOREQUEST,binip,binenet,0,seqno);            /* Timeout waiting for reply after waiting about 2 secs. */            timeout = LoopsPerSecond * 2;            while(timeout > 0) {                pollethernet();                timeout--;                if (ICMPEchoReplyId == ICMP_ECHO_ID)                    break;            }            if (timeout == 0)                printf("no answer from %s\n",ipadd);            else {                printf("%s is alive",ipadd);                if (count) {                    printf(" icmp_seq=%d",ICMPSeqNoRcvd);                    timeout = LoopsPerSecond;                    while(timeout-- > 0)                        pollethernet();                    seqno++;                }                printf("\n");            }        }    }    else        printf("Unrecognized ICMP op: %s\n",operation);    return(CMD_SUCCESS);}intprocessDNS(struct ether_header *ehdr,ushort size){    struct  ip *ipp;    struct  icmp_hdr *icmpp;    int len, i;    ipp = (struct ip *)(ehdr + 1);    /* Compute size of ICMP message (IP len - size of IP header): */    len = ipp->ip_len - ((ipp->ip_vhl & 0x0f) * 4);    icmpp = (struct icmp_hdr *)((char *)ipp+IP_HLEN(ipp));    if (icmpp->type == ICMP_ECHOREQUEST) {      /* 3rdEd Comer pg 127 */        SendEchoResp(ehdr);        return(0);    }    else if (icmpp->type == ICMP_ECHOREPLY) {        struct icmp_echo_hdr *icmpecho;        icmpecho = (struct icmp_echo_hdr *)icmpp;        ICMPEchoReplyId = ecs(icmpecho->id);        ICMPSeqNoRcvd = ecs(icmpecho->seq);    }    else if (icmpp->type == ICMP_DESTUNREACHABLE) { /* 3rdEd Comer pg 129 */        if (EtherVerbose & SHOW_INCOMING) {            i = icmpp->code;            if ((i > 5) || (i < 0))                i = 6;            printf("  ICMP: %s (code=%d)\n",                IcmpDestUnreachableCode[i],icmpp->code);        }        return(0);    }    else if (icmpp->type == ICMP_TIMEREPLY) {        struct icmp_time_hdr *icmptime;        ulong orig, recv, xmit;        icmptime = (struct icmp_time_hdr *)icmpp;        memcpy((char *)&orig,(char *)&icmptime->orig,4);        memcpy((char *)&recv,(char *)&icmptime->recv,4);        memcpy((char *)&xmit,(char *)&icmptime->xmit,4);        ICMPSeqNoRcvd = icmptime->seq;        if (EtherVerbose & SHOW_INCOMING) {            printf("    ICMP_TIMEREPLY: orig=0x%lx,recv=0x%lx,xmit=0x%lx\n",                orig,recv,xmit);        }        if (CheckSrvrResolution) {            static int ICMPTimeStampTbl[20];                if (icmptime->seq < 20) {                ICMPTimeStampTbl[icmptime->seq] = xmit;                SendICMPRequest(ICMP_TIMEREQUEST,(uchar *)&ipp->ip_src,                    (uchar *)&ehdr->ether_shost,0,icmptime->seq+1);            } else {                                printf("TS00: %d\n",ICMPTimeStampTbl[0]);                for(i=1;i<20;i++) {                    printf("TS%02d: %d (dlta=%d)\n",i,                        ICMPTimeStampTbl[i],                        ICMPTimeStampTbl[i]-ICMPTimeStampTbl[i-1]);                }                ICMPTimeStamp = xmit;            }        }        else {            ICMPTimeStamp = xmit;        }    }    else {        if (EtherVerbose & SHOW_INCOMING) {            printf("    ICMPTYPE=%d\n",icmpp->type);        }        return(-1);    }    return(0);}/* SendDNSQuery(): */intSendDNSQuery(ulong addr,char *tftpsrvr,char *mode, char *hostfile,char *tfsfile,    char *tfsflags,char *tfsinfo){    int     done;    char    buf[32];    uchar   binip[8], binenet[8], *enetaddr;    setenv("TFTPGET",0);    /* Convert IP address to binary: */    if (IpToBin(tftpsrvr,binip) < 0)        return(0);    /* Get the ethernet address for the IP: */    /* Give ARP the same verbosity (if any) set up for TFTP: */    if (EtherVerbose & SHOW_TFTP)        EtherVerbose |= SHOW_ARP;    enetaddr = ArpEther(binip,binenet,0);    EtherVerbose &= ~SHOW_ARP;    if (!enetaddr) {        printf("ARP failed for %s\n",tftpsrvr);        return(0);    }    /* Initialize the retransmission delay calculator: */    RetransmitDelay(DELAY_INIT_TFTP);    printf("Retrieving %s from %s...",hostfile,tftpsrvr);    if (EtherVerbose & SHOW_TFTP)        printf("\n");    /* Send the TFTP RRQ to initiate the transfer. */    if (SendTFTPRRQ(binip,binenet,hostfile,mode,(uchar *)addr) < 0) {        printf("RRQ failed\n");        return(0);    }    /* Wait for TftpState to indicate that the transaction has completed... */    done = 0;    while(!done) {        pollethernet();        switch(TftpState) {            case TFTPIDLE:                printf(" %d bytes",TftpCount);                done = 1;                break;            case TFTPERROR:                printf(" host error: %s\n",TftpErrString);                done = 2;                break;            case TFTPTIMEOUT:                printf(" timing out (%d bytes rcvd)\n",TftpCount);                done = 2;                break;            default:                break;        }    }    if (done == 2)        return(0);    if (tfsfile) {        int err, filesize;        filesize = TftpCount - TftpChopCount;        printf("\nAdding %s (size=%d) to TFS...",tfsfile,filesize);        err = tfsadd(tfsfile,tfsinfo,tfsflags,(uchar *)addr,filesize);        if (err != TFS_OKAY)            printf("%s: %s\n",tfsfile,(char *)tfsctrl(TFS_ERRMSG,err,0));    }    printf("\n");    sprintf(buf,"%d",TftpCount);    setenv("TFTPGET",buf);    return(TftpCount);}#endif

⌨️ 快捷键说明

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