?? dns.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) { 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 + -