I tried to capture all the UDP packets approaching my NIC using RAW socket programming. Here I am getting a strange problem. While my program is running my socket descriptor changes itself automatically. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <arpa/inet.h>
int main () {
int sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_UDP);
if (sockfd < 0) {
perror ("socket failed");
return -1;
}
char *buf = malloc (8192);
memset (buf, 0, 8192);
if (!buf) {
perror ("calloc failed\n");
return -1;
}
int ret_recv;
i:
while ((ret_recv = recv (sockfd, buf, 8192, 0)) > -1) {
printf ("%d\n", ret_recv);
struct iphdr *iph = (struct iphdr *) buf;
//struct udphdr *udph = (struct udphdr *) (buf + sizeof (struct iphdr));
struct tcphdr *tcph = (struct tcphdr *) (buf + sizeof (struct iphdr));
char ip[4];
printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof (struct sockaddr_in)));
printf ("dest ip: %s\n", inet_ntop (AF_INET, &iph->daddr, ip, sizeof (struct sockaddr_in)));
//printf ("port: %d\n", ntohs (udph->source));
printf ("port: %d\n", ntohs (tcph->source));
}
perror ("recv failed");
//goto i;
return 0;
}
In my output, instead of a infinite loop of packet information printing, only one packet of information is being printed. So I have checked with the gdb. I used display sockfd. After socket call, the value of the sockfd was 7. Then inside the while loop, after executing the printf of dest ip, the sockfd value changed to 808988216. So the recv failed with a "bad file descriptor" error. I can't find what actually went wrong.
Thanks in advance :-)
Here's a buffer overflow:
char ip[4];
printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof (struct sockaddr_in)));
The buffer is not large enough to hold the string form of the IP address. Also, the fourth argument is lying to inet_ntop() about the available space, it should be:
char ip[INET_ADDRSTRLEN];
printf ("source ip: %s\n", inet_ntop (AF_INET, &iph->saddr, ip, sizeof ip));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With