套接字 - C 中的权限被拒绝
我正在尝试从 C 中的 DNS 服务器获取 MX 记录。 我的问题是,每次我调用 sendto 或 recvfrom 时都会收到“权限被拒绝”错误。 (IDE - Xcode 4、Mac OS X Lion) 到目前为止,我还没有真正用 C 做过任何事情,但我需要这个来完成作业。 “灵感”来自 http://www. binarytides.com/blog/dns-query-code-in-c-with-linux-sockets/ 到目前为止我的代码:
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;
}
I'm trying to get an MX record from an DNS server in C.
My problem is, that everytime I call sendto or recvfrom I get a Permission denied error.
(IDE - Xcode 4, Mac OS X Lion)
Haven't really done anything in C up to this point but I need this for an assignment.
"Inspiration" from http://www.binarytides.com/blog/dns-query-code-in-c-with-linux-sockets/
My code so far:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
inet_addr 函数采用字符串形式的 IP 地址,而不是主机名。尝试将
"ns1.sil.at"
替换为其 IP 地址"213.129.232.1"
The
inet_addr
function takes an IP address in string form, not a host name. Try replacing"ns1.sil.at"
with its IP address,"213.129.232.1"
除了@joni-salonen的答案之外,您还需要绑定套接字。
使用
bind
函数调用。它需要一个 struct sockaddr_in 来标识套接字的本地端。您可以使用系列
AF_INET
、端口 0 和地址INADDR_ANY
对其进行初始化。In addition to @joni-salonen's answer, you need to bind the socket.
Use a
bind
function call.It needs a
struct sockaddr_in
, which would identify the local side of the socket. You can be initialize it with with familyAF_INET
, port 0 and addressINADDR_ANY
.