如何获取DNS的数据包

oria2006 2008-04-02 11:24:25
又谁知道如何获取DNS的数据结构吗??我现在想修改DNS数据包中数据,
...全文
636 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
mezidane 2009-04-10
  • 打赏
  • 举报
回复
楼主应该是有获取和发送DNS的数据结构吧,能否发份给我?谢谢了!!
我的邮箱:mezidane@163.com
oria2006 2008-04-07
  • 打赏
  • 举报
回复
这个是发送,我想获取
不过已经给我不少帮助了 谢谢了
fallinleave 2008-04-02
  • 打赏
  • 举报
回复
引用:http://blog.csdn.net/blog51/archive/2006/04/20/670550.aspx
这几天构造一个DNS报文,查了好些资料,好象许多朋友对UDP报文的校验和老是出问题,自己试了一些例子代码,也有问题。所以花了一些时间,做了一个成功的例子,在Linux下GCC通过并验证成功。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>


unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum=0;

while (size > 1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned char *)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);

return (unsigned short)(~cksum);
}

void CalculateCheckSum(
void *iphdr,
struct udphdr *udphdr,
char *payload,
int payloadlen)
{
struct iphdr *v4hdr=NULL;
unsigned long zero=0;
char buf[1000],
*ptr=NULL;
int chksumlen=0,
i;

ptr = buf;

v4hdr = (struct iphdr *)iphdr;

// Include the source and destination IP addresses
memcpy(ptr, &v4hdr->saddr, sizeof(v4hdr->saddr));
ptr += sizeof(v4hdr->saddr);
chksumlen += sizeof(v4hdr->saddr);

memcpy(ptr, &v4hdr->daddr, sizeof(v4hdr->daddr));
ptr += sizeof(v4hdr->daddr);
chksumlen += sizeof(v4hdr->daddr);

// Include the 8 bit zero field
memcpy(ptr, &zero, 1);
ptr++;
chksumlen += 1;

// Protocol
memcpy(ptr, &v4hdr->protocol, sizeof(v4hdr->protocol));
ptr += sizeof(v4hdr->protocol);
chksumlen += sizeof(v4hdr->protocol);

// UDP length
memcpy(ptr, &udphdr->len, sizeof(udphdr->len));
ptr += sizeof(udphdr->len);
chksumlen += sizeof(udphdr->len);

// UDP source port
memcpy(ptr, &udphdr->source, sizeof(udphdr->source));
ptr += sizeof(udphdr->source);
chksumlen += sizeof(udphdr->source);

// UDP destination port
memcpy(ptr, &udphdr->dest, sizeof(udphdr->dest));
ptr += sizeof(udphdr->dest);
chksumlen += sizeof(udphdr->dest);

// UDP length again
memcpy(ptr, &udphdr->len, sizeof(udphdr->len));
ptr += sizeof(udphdr->len);
chksumlen += sizeof(udphdr->len);

// 16-bit UDP checksum, zero
memcpy(ptr, &zero, sizeof(unsigned short));
ptr += sizeof(unsigned short);
chksumlen += sizeof(unsigned short);

// payload
memcpy(ptr, payload, payloadlen);
ptr += payloadlen;
chksumlen += payloadlen;

// pad to next 16-bit boundary
for(i=0 ; i < payloadlen%2 ; i++, ptr++)
{
printf("pad one byte\n");
*ptr = 0;
ptr++;
chksumlen++;
}

// Compute the checksum and put it in the UDP header
udphdr->check = checksum((unsigned short *)buf, chksumlen);

return;
}


void main()
{

int sock;
unsigned int buffer_size = sizeof(struct iphdr) + sizeof(struct udphdr);

char DNS_Data[] = "\x71\x79\x81\x80\x00\x01"
"\x00\x02\x00\x04\x00\x04\x03\x77\x77\x77\x03\x61\x62\x63\x03\x63"
"\x6f\x6d\x00\x00\x01\x00\x01\xc0\x0c\x00\x05\x00\x01\x00\x00\x02"
"\xe8\x00\x02\xc0\x10\xc0\x10\x00\x01\x00\x01\x00\x00\x02\xe9\x00"
"\x04\x0a\xb5\x84\xfa\xc0\x10\x00\x02\x00\x01\x00\x00\xda\xeb\x00"
"\x0d\x06\x73\x65\x6e\x73\x30\x31\x03\x64\x69\x67\xc0\x14\xc0\x10"
"\x00\x02\x00\x01\x00\x00\xda\xeb\x00\x09\x06\x73\x65\x6e\x73\x30"
"\x32\xc0\x4e\xc0\x10\x00\x02\x00\x01\x00\x00\xda\xeb\x00\x09\x06"
"\x6f\x72\x6e\x73\x30\x31\xc0\x4e\xc0\x10\x00\x02\x00\x01\x00\x00"
"\xda\xeb\x00\x09\x06\x6f\x72\x6e\x73\x30\x32\xc0\x4e\xc0\x75\x00"
"\x01\x00\x01\x00\x00\x7a\x36\x00\x04\x0a\xbb\xbd\x2c\xc0\x8a\x00"
"\x01\x00\x01\x00\x00\x1b\x96\x00\x04\x0a\xbb\xbe\x2c\xc0\x47\x00"
"\x01\x00\x01\x00\x00\x92\xb1\x00\x04\x0a\xb5\x86\x10\xc0\x60\x00"
"\x01\x00\x01\x00\x00\x92\xb1\x00\x04\x0a\xb5\x87\xc7";

buffer_size += sizeof(DNS_Data);

unsigned char buffer[buffer_size];
memset (buffer, 0, buffer_size);

struct iphdr *ip = (struct iphdr *)buffer;
struct udphdr *udp = (struct udphdr *)(buffer + sizeof(struct iphdr));

if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1) {

perror("socket()");
exit(EXIT_FAILURE);
}

int o = 1;
if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&o,sizeof(o)) == -1) {

perror("setsockopt()");
exit(EXIT_FAILURE);
}

ip->version = 4;
ip->ihl = 5;
ip->id = htonl(random());
ip->saddr = inet_addr("1.0.0.1");
ip->daddr = inet_addr("10.0.0.63");
ip->ttl = 255;
ip->protocol = IPPROTO_UDP;
ip->tot_len = buffer_size;
ip->check = 0;

udp->source = htons(53);
udp->dest = htons(1234);
udp->len = htons(buffer_size - sizeof(struct iphdr));
udp->check = 0;


struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = udp->source;
addr.sin_addr.s_addr = ip->saddr;

memcpy(buffer+sizeof(struct iphdr) + sizeof(struct udphdr),DNS_Data,sizeof(DNS_Data));
CalculateCheckSum(ip,udp,DNS_Data,sizeof(DNS_Data));

if ((sendto(sock, buffer, buffer_size, 0, (struct sockaddr*)&addr,
sizeof(struct sockaddr_in))) == -1) {

perror("send()");
exit(1);
}
else
printf("OK\n");
}



上面代码构造了一个DNS应答报文。用抓包程序抓下来验证正确。

70,024

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧