UDP DNS lookup

Hello, I'm having a little bit of trouble with my client program. It is suppose to take an address of a name server to query from and the name of the site to convert to its IP address. When I run it, it gives a segmentation fault(core dumped). I can't seem to find where it is doing that.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

#include <arpa/inet.h>
#include <sys/socket.h>
#ifndef S_SPLINT_S    // Workaround for splint.
#include <unistd.h>
#endif

unsigned char install_dname(unsigned char *p, char *dname)
{
    *p = '.';
    p++;
    strcpy((char *)p, dname);
    p--;

    while(*p != '\0')
    {
        if(*p == '.')
        {
            unsigned char *end = p + 1;
            while(!(*end == '.' || *end == '\0'))
            {
                end++;
            }
            *p = end - p - 1;
        }
        p++;
    }
    return p;
}

void sig_alarm(int signo)
{
    alarm(5);
}

int main(int argc, char **argv)
{
    int            socket_handle;
    unsigned short port = 53;
    struct sockaddr_in servaddr, cliaddr;
    int max = 512;
    unsigned char buffer[512];

    // Do we have a command line arguments?
    if (argc != 3) {
        fprintf(stderr, "usage: %s server-ipaddress domain-name\n", argv[0]);
        return EXIT_FAILURE;
    }

    // Create a socket.
    if ((socket_handle = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Unable to create socket");
        return EXIT_FAILURE;
    }

    // TODO: The bulk of the program goes here...

    //function to construct a request packet
    buffer[0] = 0x00;
    buffer[1] = 0x01;
    buffer[2] = 0x01;
    buffer[3] = 0x00;
    buffer[4] = 0x00;
    buffer[5] = 0x01;
    buffer[6] = 0x00;
    buffer[7] = 0x00;
    buffer[8] = 0x00;
    buffer[9] = 0x00;
    buffer[10] = 0x00;
    buffer[11] = 0x00;

    unsigned char *p = install_dname(&buffer[12], argv[2]);
    *p++ = 0x00;
    *p++ = 0x01;
    *p++ = 0x00;
    *p++ = 0x01;


    //function to send request
    int length = sizeof(buffer);
    if(sendto(socket_handle, buffer, length, 0, (struct sockaddr *) &servaddr,
              sizeof(servaddr)) == -1)
              {
                  perror("unable to send");
                  return -1;
              }
    //function that receives the response
    //TODO put in alarm()
    signal (SIGALRM, sig_alarm);
    alarm(5);
    int address_length = sizeof(struct sockaddr_in);
    int count;
    socklen_t clilen;
    clilen = sizeof(cliaddr);
    if((count = recvfrom(socket_handle, buffer, max, 0, (struct sockaddr *) &cliaddr,
                        &clilen)) < 0)
                        {
                            if(errno == EINTR)
                            {
                                fprintf(stderr, "socket timeout\n");
                            }
                            else
                            {
                                perror ("error during packet receive");
                                return -2;
                            }
                        }

    //function that disects the response looking for the answer
    p = buffer;
    p += 12;
    p += 2 + strlen(argv[2]) + 4;
    if((*p & 0xC0) == 0xC0)
    {
        p += 12;
    }
    else
    {
        p += 2 + strlen(argv[2]) + 10;
    }
    for(int i = p; i < count; i++)
    {
        printf("%d", buffer[i]);
    }
    printf("\n");

    // Close the socket to clean up.
    close(socket_handle);
    return EXIT_SUCCESS;
}
What is instaill_dname supposed to do? I can't follow it.

You don't appear to have initalised servaddr.
install_dname is taking the domain name and putting it into the buffer array to get it ready to be sent out to get its IP address.
install_dname is taking the domain name and putting it into the buffer array to get it ready to be sent out to get its IP address.
That may be true, but it doesn't explain what this stuff is trying to do.
1
2
3
4
5
6
            unsigned char *end = p + 1;
            while(!(*end == '.' || *end == '\0'))
            {
                end++;
            }
            *p = end - p - 1;

I'm too lazy to work thru it, I was hoping you'd explain it.

You're assuming the buffer will have a 0x0 in it somewhere, but you never initialize it.

There are a number of problems with your code, but if you don't explain your method, I can't verify/correct what you've done.
Last edited on
The function takes in the domain name without any "." or "\0" in it. Once it is done, it returns the pointer location of the end of the domain name. As for all the buffer[0] = 0x00 stuff, it is part of the RFC documents that discusses how to construct the information to be sent properly.
Topic archived. No new replies allowed.