숙제로했던..dig..
글쓴이: 신승한 / 작성시간: 금, 2005/03/11 - 2:49오후
한번씩들봐주세요~
RFC1305 참고했습니다.
클라이언트쪽만우선...
#include "mydig.h" #define DEBUG 0 // debug flag int main(int argc, char **argv) { u_char buf[1024]={0}; // data buffer HEADER *hdr; // header structure pointer QUESTION *qst; // question structure pointer struct sockaddr_in sin; // socket address structure int sd; // socket descriptor short ret; // a variable for return value from sendto, recvfrom int pklen=0; // packet length u_char *p; // a pointer to data buffer int i = 0; char serverIP[15]; // Server's IP address char sport[5]; // Server's Port short Qtype = 0; // Query type value char *qname; // Query name value struct timeval tv, td; // timevalue structures double etime = 0; // elapsed time variable // command line argument parsing // @server port name type if(argc < 5 || (**++argv != '@')) usage(*argv); // Socket stuff setting bzero(&sin,sizeof(sin)); // structure initializing as 0 // Server address conversion strncpy(serverIP, ++(*argv), sizeof(char)*15); if(inet_pton(AF_INET, serverIP, &sin.sin_addr) <= 0) { fprintf(stderr,"Invalid server address\n"); exit(-1); } if(DEBUG) printf("\ns_addr: %s", inet_ntoa(sin.sin_addr)); // Service port conversion strncpy(sport, *++argv, sizeof(char)*5); if(atoi(sport) > 65535 || atoi(sport) < 53) { fprintf(stderr,"Invalid service port\n"); exit(-1); } sin.sin_port=htons(atoi(sport)); // Service port bit order conversion sin.sin_family=AF_INET; // Internet address family // Query type Qtype = qType(*(argv+2)); // reverse query processing from input if(Qtype == 12) { // input format check if(inet_addr(*(argv+1)) == -1) { fprintf(stderr,"Invalid query name for PTR\n"); exit(-1); } // we need space for reverse query format qname = (char *)malloc(strlen(*++argv)+13); // query format conversion make_reverse_qname(qname, *argv); } else qname = *++argv; // it's not a reverse query if(DEBUG) printf("after F:%s\n", qname); // mapping up as type of HEADER hdr = (HEADER *)buf; hdr->id=htons(rand () % 65535); // random ID hdr->qr = 0; // This is a query hdr->rd = 1; // Recursive query request hdr->opcode = htons(QUERY); // standard query hdr->qdcount = htons(1); // # of questions pklen += sizeof(HEADER); // Question setting pklen += mkQname(qname, &buf[pklen]); //Query name // mapping up as type of question qst = (QUESTION *)&buf[pklen]; qst->qtype=htons(Qtype); qst->qclass=htons(C_IN); pklen += sizeof(short) * 2; // increase packet length //create the socket, a UDP datagram socket if((sd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { fprintf(stderr,"Socket error!"); exit(-2); } if(DEBUG) printf("\nFinal pklen: %d\n",pklen); // signal handler setting for timeout if(signal(SIGALRM, sig_alarm) == SIG_ERR) { perror("Signal error"); exit(-1); } // take the start time of query gettimeofday(&tv, NULL); // send query ret = sendto(sd, buf, pklen, 0, (SA *)&sin, sizeof(sin)); if (ret < 0) { fprintf(stderr,"error: sendto error\n") ; exit(-1); } alarm(10); // set timeout 3 seconds bzero(&buf,sizeof(buf)); // structure initializing as 0 if(Qtype == 12) free(qname);// release the memory we got for reverse query // receive result if ((ret = recvfrom(sd, buf, sizeof(buf), 0, NULL, NULL)) < 0) { fprintf(stderr,"error: recvfrom error\n") ; exit(-1); } // take the end time of query gettimeofday(&td, NULL); // we got the answer, map as the HEADER structure hdr = (HEADER *)buf; // Header parsing and print out printf(";; ->>HEADER<<- opcode: %d, status: %d, id: %d\n", ntohs(hdr->opcode),ntohs(hdr->rcode), ntohs(hdr->id)); printf(";; QUERY: %d, ANSWER: %d, AUTHORITY: %d, ADDITIONAL: %d\n",ntohs(hdr->qdcount), ntohs(hdr->ancount), ntohs(hdr->nscount), ntohs(hdr->arcount)); // is the data trucated? if (hdr->tc) printf("data truncated!\n"); // forward on the size of HEADER p = buf+sizeof(HEADER); // question part parsing printf("\n;; QUESTION SECTION:\n"); for (i=ntohs(hdr->qdcount); i>0; --i) { p = toChar(buf, p); printf("\tIN\t%s\n", *(argv+1)); p += 4; // skip type(x2)/class(x2) } // answer part parsing printf("\n;; ANSWER SECTION:\n"); for (i=ntohs(hdr->ancount); i>0; --i) p = RR_parsing(buf, p); // authority part parsing printf("\n\n;; AUTHORITY SECTION:\n"); for (i=ntohs(hdr->nscount); i>0; --i) p = RR_parsing(buf, p); // additional part parsing printf("\n\n;; ADDITIONAL SECTION:\n"); for (i=ntohs(hdr->arcount); i>0; --i) p = RR_parsing(buf, p); // elapse time print out printf("\n\n;; Query time: %2.0f msec\n",df(tv,td)); printf(";; MSG SIZE rcvd: %d bytes\n", ret); printf(";; SERVER: %s#%s(%s)\n\n", *(argv-2), *(argv-1), *(argv-2)); return 0; }
#include "mydig.h" // translate string type query name into proper format int mkQname(char *host, unsigned char *qname) { char *dummy=(char *)malloc(strlen(host)+3); // temporary space for strtok int i=0; int pklen = 0; // qname index number char *p; // pointer to chunks strcpy(dummy,host); // copy the string to temp p = (char *)strtok(dummy, "."); // split the string with dot(.)s while (p != NULL) // loop til we got the end { qname[pklen++] = strlen(p); // set '\num' of characters while (i < strlen(p)) { qname[pklen++] = p[i++]; // copy the characters } i = 0 ; // need to reset this for subsequent tokens p =(char *)strtok(NULL, "."); // chop again } qname[pklen++] = '\0'; // the end of format free(dummy); // release the temp return pklen; // need to return the length of data to add to total length of the buffer } // Resource Record parsing function char* RR_parsing(char *buf, unsigned char *p) { unsigned int rttl; // for TTL unsigned short rtype; // for Resouce Type unsigned short mx_pri; // for MX priority RR *rr; // RR structure pointer // domain name variable converting from bit to chars p = toChar(buf, p); putchar('\t'); // Buf to RR mapping rr = (RR *)p; rtype = ntohs(rr->rtype); // rtype conversion rttl = ntohl(rr->rttl); // rttl conversion p += 10; // forward 10byte of RR // print the parsing results for each resource type switch (rtype) { case 1: // A (IPV4) printf("%4u IN A\t",rttl); printf("%s\n",(char *) inet_ntoa(*(SI *)p)); p+=4; break; case 2: // NS printf("%8u IN NS\t",rttl); p=toChar(buf, p); putchar('\n'); break; case 5: // CNAME : it is not requirement but, I need it for some records to display properly printf("%4u IN CNAME\t",rttl); p=toChar(buf, p); putchar('\n'); break; case 6: // SOA : again, not requirement but, UoC DNS server reply wierd sometime, so just in case printf("%4u IN SOA\t",rttl); p = toChar(buf, p); putchar(' '); // SOA domain name p = toChar(buf, p); putchar(' '); // email address of the admin p = dword(p); putchar(' '); // serial p = dword(p); putchar(' '); // refresh p = dword(p); putchar(' '); // retry p = dword(p); putchar(' '); // expire p = dword(p); // minimum break; case 12: // PTR printf("%4u IN PTR\t",rttl); p=toChar(buf, p); putchar('\n'); break; case 15: // MX mx_pri = (*p++) << 8; // MX priority conversion mx_pri |= (*p++); // two 8 bits into on short number printf("MX%4u\t", mx_pri); p = toChar(buf, p); putchar('\n'); break; default: // Why should I bother? printf("Unimplemented type:%d\n",rtype); } return p; // return the position in the buffer atfer } // convert bits pattern into characters char* toChar(unsigned char *base, unsigned char *p) { unsigned short size; unsigned short z; while ((size = *p++)) { // is message compressed? if ((size & 192) == 192) { // get offset z = (size & ~192) << 8; z |= *p++; // recursive call me toChar(base, base + z); return p; // return the pointer position } else { // no, it's just bits // then.. print out! for (; size-- > 0; ++p) putchar(*p); putchar('.'); // dot for get the DOT } } return p; // return the pointer position } // for the type of SOA, serial, refresh, retry, expire, and minimum unsigned char* dword(unsigned char *q) { unsigned long val; int i; // make 4 bytes into one value for (val=0, i=0; i < 4; i++) { val <<= 8; val |= *q++; } printf("%lu", val); // print out return q; // return the position after } // usage print function void usage(char *argv) { printf("Usage : %s @server port name type\n \ \n \ @server - IP of the DNS server you want(def: localhost)\n \ port - Service port of the @server (def: 53)\n \ name - Resource record you want\n \ type - Query type you want\n\n", argv); exit(0); } // query type converting function, from string to short short qType(char *argv) { printf("\nQTYPE: %s\n", argv); // this function convert query type from input into integer value if(strcmp(argv, "A") == 0) return T_A; else if(strcmp(argv, "MX") == 0) return T_MX; else if(strcmp(argv, "NS") == 0) return T_NS; else if(strcmp(argv, "PTR") == 0) return T_PTR; else{ fprintf(stderr,"Not supported qtype\n"); exit(-1); } } // function that makes inverse query format from IP string void make_reverse_qname(char *qname, char *argv) { int i = 0; char *idx[4],*p; idx[4] = (char *)strtok(argv, "."); // chop argv into pieces while(idx[4-i] != NULL) { i++; idx[4-i] = (char *)strtok(NULL, "."); // save the pieces in reverse order } p = qname; // set pointer to the start of target for(i = 1 ; i <= 4; i++) { sprintf(p,"%s.",idx[i]);// copy it in normal order, which is actually reverse p += strlen(p); // forward pointer by the last token length } sprintf(p,"in-addr.arpa"); // attach the last chunk } // signal handler void sig_alarm(int whocares) { fprintf(stderr,"error :timeout !!\n"); exit(-1); } // elapsed time calculating double df(struct timeval t1, struct timeval t2) { long sec, usec; // holds second, microsecond differences // compute the differences of seconds and microseconds (usec) usec = t2.tv_usec - t1.tv_usec; sec = t2.tv_sec - t1.tv_sec; // normalize if (usec < 0){ sec--; usec += 1000000; } // combine the values into a double //return(((double) sec) + ((double) usec)/1000000.0); seconds return(((double) sec) + ((double) usec)); // micro seconds }[/code]
File attachments:
첨부 | 파일 크기 |
---|---|
![]() | 7.24 KB |
Forums:
얌냠...근데 mydig.h는 어디있나요?좀 긴데, 파일첨부해주심
얌냠...근데 mydig.h는 어디있나요?
좀 긴데, 파일첨부해주심 더 죠케떠엽~^^;
--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)
[code:1]#include <arpa/nameser.h>
첨부!
더 깊이 파서 주석도~~ (퍽)
500m 파셨는데 10km 파시는 거야 뭐 힘들겠습니까? (퍼버벅)
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
Re: 첨부!
주석 잘달려 있사와요~ :roll:
댓글 달기