I'm learning C by writing a small application that sends a DNS query to a specified server. Here is an example of the network code:
int send_query()
{
int sockfd;
struct sockaddr_in server;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("cannot create socket\n");
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(53);
inet_pton(AF_INET, "8.8.8.8", &(server.sin_addr));
sendto(sockfd, const void *buffer, size_t length, 0, (struct sockaddr *) &server, sizeof(server));
}
This works fine as the query is succesfully sent, and a reply is recieved. However, by sniffing the traffic with Wireshark I can see the message: Destination unreachable (Port unreachable)
.
I found out that I can avoid this by calling bind()
before sendto()
:
int send_query()
{
int sockfd;
struct sockaddr_in server;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
perror("cannot create socket\n");
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(53);
inet_pton(AF_INET, "8.8.8.8", &(server.sin_addr));
if(bind(sockfd, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("bind failed\n");
}
sendto(sockfd, const void *buffer, size_t length, 0, (struct sockaddr *) &server, sizeof(server));
}
Now the Destination unreachable (Port unreachable)
message is gone, but the application has to be run with root privileges as it will bind to port 53.
Is it possible to modify the code so a random non-privileged source port is used instead?
Problem solved
The problem occured because of a stupid mistake. I had simply commented out recvfrom()
. As I was sniffing the traffic while testing the application, I could see the response and error arrving at my computer, and mistakenly confused this as the application was receving. Because I don't know what the hell I'm doing, I started to mess around with bind()
etc. and this avalanche of failure started.
For brevity I did not post all the code, but the issue had probably been solved instantly if had did that instead.