DNS 协议运行在 UDP 协议上面,是一个 UDP 的“回显”程序,使用 53 号端口








- #include
/* See NOTES */ - #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- int sock;
- struct sockaddr_in sa;
-
- /*
- generate_question:解析域名数据
- */
- void generate_question(char*dns_name,char*buf,int*len)
- {
- char*pos = dns_name;//指向域名当前位置
- char*ptr = buf;
- int n = 0;
- *len = 0;
- while(1)
- {
- n = strlen(pos) - (strstr(pos , ".") ? strlen(strstr(pos , ".")) : 0);//在 pos 中查找"."子串
- //返回"."在 pos 中第一次出现的地址,若没有找到返回 NULL
- printf("%d\n", n);
- *ptr++ = (unsigned char)n;
- memcpy(ptr,pos,n);
- printf("%lu\n",strlen(ptr));
- printf("%s\n", ptr);
- *len += n + 1;
- ptr += n;
- if(!strstr(pos , "."))
- {
- *ptr = (unsigned char)0;
- ptr ++;
- *len += 1;
- break;
- }
- pos += n + 1;
- printf("%s\n", pos);
- }
- }
-
- /*
- send_dns_request:解析域名数据,并发送数据包
- */
- void send_dns_request(char * dns_name)
- {
- unsigned char request[256] = {0}; //保存整个请求报文
- unsigned char *ptr = request;
- unsigned char question[128];//存储域名解析数据
- int question_len;
- //产生请求(把字符串表示的域名转换成 DNS 要求的格式)
- generate_question(dns_name , question ,&question_len);
- printf("%s\n", question);
- printf("%d\n", question_len);
- *((unsigned short*)ptr) = 1; //会话标识 ID
- ptr += 2;
- *((unsigned short*)ptr) = htons(0x0100); //flags
- ptr += 2;
- *((unsigned short*)ptr) = htons(1); //Quetions 问题数,通常为 1
- ptr += 2;
- *((unsigned short*)ptr) = 0;
- ptr += 2;
- *((unsigned short*)ptr) = 0;
- ptr += 2;
- *((unsigned short*)ptr) = 0;
- ptr += 2;
- //把域名(www.baidu.com)装换为相应的问题格式保存在此处,以\0 结尾
- memcpy(ptr , question , question_len);
- ptr += question_len;
- *((unsigned short*)ptr) = htons(1); //获取 IPV4 地址,查询类型
- ptr += 2;
- *((unsigned short*)ptr) = htons(1); //指互联网地址,查询类,一般为 1,表明是 Internet 数据
- int re = sendto(sock, request,question_len+16 ,0, (structsockaddr*)&sa, sizeof(sa));
- printf("re = %d\n",re);
- int i;
- for(i=0;i
//以 16 进制格式打印出来 - {
- printf("%02X ",(unsigned char)request[i]);
- }
- printf("===================\n");
- }
-
- /*
- recv_dns_response:获取域名所对应的 IP 地址,并打印
- */
- void recv_dns_response()
- {
- struct sockaddr_in src_addr;
- socklen_t addrlen = sizeof(src_addr);
- char buf[255] = {0};
- int r = recvfrom(sock, buf, 255, 0, (struct sockaddr*)&src_addr,&addrlen);
- printf("r == %d\n", r);
- if(r > 0)//收到大于 0 的数据
- {
- int i;
- for(i=r-4;i
//以 16 进制格式打印出来 - {
- if(i != r-1)
- printf("%d.",(unsigned char)buf[i]);
- else
- printf("%d\n",(unsigned char)buf[i]);
- }
- }
- }
-
- //例./main www.baidu.com
- int main(int argc, char *argv[])
- {
- if(argc != 2)
- {
- printf("Usage : %s
\n" ,argv[0]); - return -1;
- }
- //step 1: 创建一个套接字
- sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sock == -1)
- {
- perror("socket error:");
- return -1;
- }
-
- //step 2: 绑定一个地址(ip+端口号)
- memset(&sa, 0,sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(53); //按"网络字节序"来保存一个整数
- sa.sin_addr.s_addr = inet_addr("114.114.114.114");
- //发送解析请求
- send_dns_request(argv[1]);
- //接收分析结果
- recv_dns_response();
- close(sock);
- return 0;
- }

- #include
- #include
- extern int h_errno;
struct hostent *gethostbyname(const char *name);
- struct hostent
- {
- char *h_name; /* 主机正式名称 */
- char **h_aliases; /* 别名列表。 */
- int h_addrtype; /* 主机地址类型。*/
- int h_length; /* 地址的长度。 */
- char **h_addr_list; /*来自名称服务器的地址列表。 */
- #ifdef __USE_MISC
- # define h_addr h_addr_list[0] /* 地址,用于向后兼容。*/
- #endif
- };
- #include
- #include
- #include
- #include
- extern int h_errno;
-
- int main(int argc, char **argv)
- {
- if (argc != 2) {
- printf("Use example: %s www.google.com\n", *argv);
- return -1;
- }
- char *name = argv[1];
- struct hostent *hptr;
- hptr = gethostbyname(name);
- if (hptr == NULL) {
- printf("gethostbyname error for host: %s: %s\n", name,
- hstrerror(h_errno));
- return -1;
- }
- //输出主机的规范名
- printf("\tofficial: %s\n", hptr->h_name);
- //输出主机的别名
- char **pptr;
- char str[INET_ADDRSTRLEN];
- for (pptr=hptr->h_aliases; *pptr!=NULL; pptr++) {
- printf("\ttalias: %s\n", *pptr);
- }
- //输出 ip 地址
- switch (hptr->h_addrtype) {
- case AF_INET:
- pptr = hptr->h_addr_list;
- for (; *pptr!=NULL; pptr++) {
- printf("\taddress: %s\n",inet_ntop(hptr->h_addrtype, hptr->h_addr, str, sizeof(str)));
- }
- break;
- default:
- printf("unknown address type\n");
- break;
- }
- return 0;
- }

#include
int gethostname(char *name, size_t len);
- char buf[256] = {0};
- int t = gethostname(buf,256);
- if(t == 0)
- {
- printf("%s\n",buf);
- }
