Socket - Permission denied in C

16,432

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"

Share:
16,432
Patrick
Author by

Patrick

Updated on June 28, 2022

Comments

  • Patrick
    Patrick almost 2 years

    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; 
    } 
    
  • nos
    nos over 12 years
    Which likely means inet_addr() returns -1, which will be interpreted as the IP address 255.255.255.255 , and likely OSX denies normal users to send to the broadcast address (or atleast requires you to set the SO_BROADCAST socket option first)
  • ugoren
    ugoren over 12 years
    Trying to use the host name, rather than the IP, makes no sense anyway. Even if it did work, it would mean the DNS client relies on DNS in order queries to work...