2012-01-16 43 views
1

我試圖從C中的DNS服務器獲取MX記錄。 我的問題是,每當我調用sendto或recvfrom時,我都會收到Permission denied錯誤。 (IDE - Xcode 4,Mac OS X Lion) 到目前爲止還沒有真正在C做過任何事情,但我需要這個來完成任務。 「靈感」,從http://www.binarytides.com/blog/dns-query-code-in-c-with-linux-sockets/ 到目前爲止我的代碼:套接字 - 在C中拒絕的權限

struct QUESTION 
{ 
unsigned short qtype; 
unsigned short qclass; 
}; 

typedef struct 
{ 
unsigned char *name; 
struct QUESTION *ques; 
} QUERY; 

typedef struct 
{ 
unsigned short type; 
unsigned short _class; 
unsigned int ttl; 
unsigned short data_len; 
} R_DATA; 



int main(int argc, char *argv[]) 
{ 



int sockfd, i; 
unsigned char buf[65536],*qname; 
struct QUESTION *qinfo = NULL; 

struct sockaddr_in dest; 

struct dnsheader *dns = NULL; 

sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 


dest.sin_family=AF_INET; 
dest.sin_port=htons(53); 
dest.sin_addr.s_addr= inet_addr("ns1.sil.at"); 


srand((unsigned)time(NULL)); 
int16_t rand_number = (rand()%1000+1); 
printf("generated random number : %i \n", rand_number); 


dns = (struct dnsheader *)&buf; 
dns->flags = STANDARD_QUERY_FLAGS; 
dns->question_count = 1; 
dns->transaction_id = rand_number; 
dns->answer_rr_count = 0; 
dns->additional_rr_count = 0; 
dns->nameserver_rr_count = 0; 


qname =(unsigned char*)&buf[sizeof(struct dnsheader)]; 


qinfo =(struct QUESTION*)&buf[sizeof(struct dnsheader) + (strlen((const char*)qname) + 1)]; //fill it 

qinfo->qtype = htons(15); // MX = 15 
qinfo->qclass = htons(1); 

printf("\nSending Packet..."); 
if(sendto(sockfd,(char*)buf,sizeof(struct dnsheader) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest)) < 0){ 
    perror("\nsendto failed"); 
} 
printf("\nDone\n"); 


i = sizeof dest; 
printf("\nReceiving answer..."); 
if(recvfrom (sockfd,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , (socklen_t*)&i) < 0){ 
    perror("recvfrom failed"); 
} 
printf("Done"); 

dns = (struct dnsheader*) buf; 

print_dns_answers(buf, sizeof((char*)buf)); 




close(sockfd); 


return 0; 
} 
+0

你的代碼不能編譯。但是,根據經驗,您是否檢查過防火牆?目的地是否可達? – cateof 2012-01-16 13:32:35

回答

5

inet_addr功能以字符串形式,而不是一個主機名需要一個IP地址。試着用它的IP地址替換"ns1.sil.at""213.129.232.1"

+1

這可能意味着inet_addr()返回-1,將被解釋爲IP地址255.255.255.255,並且可能OSX拒絕正常用戶發送到廣播地址(或者至少需要您先設置SO_BROADCAST套接字選項) – nos 2012-01-16 13:56:24

+1

Trying使用主機名稱而不是IP,無論如何都沒有意義。即使它確實起作用,這也意味着DNS客戶端依靠DNS來使查詢正常工作。 – ugoren 2012-01-16 14:01:47

0

除了@喬尼 - 薩洛寧的答案,你需要綁定套接字。
使用bind函數調用。
它需要一個struct sockaddr_in,它將識別套接字的本地側。您可以使用系列AF_INET,端口0和地址INADDR_ANY對其進行初始化。

相關問題