Reputation: 688
I'm trying to capture packets from a UDP client-server communication. I'm not allowed to use libpcap or tcpdump. I found a nice article about it here.
However, I'm not able to understand the program. Since, there is very less comments given.
Can someone please point me to a source of such information..? Or more precisely, i'm looking for a source which talks about packet analysis using C in linux.
Thanks in advance.
Upvotes: 2
Views: 2792
Reputation: 474
Here is something similar to what you want, you can remove the unnecessary headers. I edited the source of your code (from your link) to get your desired functionality.
Basically this guy uses RAW sockets. RAW sockets can receive any packet with all its headers attached. In a normal Socket you define the protocol that you are expecting, from which port and from which IP Source. The Linux IP Stack processes the headers and you get the application layer data only. Additionally you can get the Source and Destination IP addresses as well (from your sockaddr_in type structure).
Now in this case, you get all the headers attached, meaning you can recieve all the packets on your interface and meddle with the headers if you want. These type of sockets are very useful for packet-sniffing and creating some custom protocol, if required.
In this code, provided below, I am only sniffing UDP Packets, as per your requirement
#include<netinet/in.h>
#include<errno.h>
#include<netdb.h>
#include<stdio.h> //For standard things
#include<stdlib.h> //malloc
#include<string.h> //strlen
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h> //Provides declarations for ip header
#include<netinet/if_ether.h> //For ETH_P_ALL
#include<net/ethernet.h> //For ether_header
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#include <net/if.h> // struct ifreq
//#include <fcntl.h>
#include <linux/if_packet.h>
void ProcessPacket(unsigned char* , int);
void print_ip_header(unsigned char* , int);
void print_udp_packet(unsigned char * , int );
struct sockaddr_in source_epc,dest_epc;
//uint32_t ipSrc;
//uint16_t portSrc;
int main()
{
//struct sockaddr_ll sll;
//struct ifreq ifr;
int saddr_size , data_size;
struct sockaddr saddr;
//int udp = 0, others = 0;
unsigned char *buffer = (unsigned char *) malloc(500); //Its Big!
int sock_raw = socket( AF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
if(sock_raw < 0)
{
//Print the error with proper message
perror("Socket Error");
return 1;
}
/////////////////setsockopt(sock_raw , SOL_SOCKET , SO_BINDTODEVICE , "eth1" , strlen("eth1")+ 1 );
//memset(&sll, 0, sizeof(sll));
//memset(&ifr, 0, sizeof(ifr));
//strncpy((char *)ifr.ifr_name, "eth1", IFNAMSIZ);
/*if((ioctl(sock_raw, SIOCGIFHWADDR, &ifr)) == -1)
{
printf("Error getting Interface hw address!\n");
exit(-1);
}*/
while(1)
{
saddr_size = sizeof saddr;
//Receive a packet
//setsockopt(sock_raw , SOL_SOCKET , SO_BINDTODEVICE , "eth0" , strlen("eth0")+ 1 );
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size);
if(data_size <0 )
{
printf("Recvfrom error , failed to get packets\n");
return 1;
}
//Now process the packet
ProcessPacket(buffer , data_size);
}
close(sock_raw);
printf("Finished");
return 0;
}
void ProcessPacket(unsigned char* buffer, int size)
{
//Get the IP Header part of this packet , excluding the ethernet header
struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
//++total;
if ( iph->protocol == 17)
{
printf("UDP Packet received\n");
print_ip_header(buffer, size);
print_udp_packet(buffer , size);
}
else
{
printf("Packet received in not UDP\n");
return 1;
}
}
void print_ip_header(unsigned char* Buffer, int Size)
{
// print_ethernet_header(Buffer , Size);
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)(Buffer + sizeof(struct ethhdr) );
iphdrlen =iph->ihl*4;
memset(&source_epc, 0, sizeof(source_epc));
source_epc.sin_addr.s_addr = iph->saddr;
memset(&dest_epc, 0, sizeof(dest_epc));
dest_epc.sin_addr.s_addr = iph->daddr;
printf(" \n\n***********************IP HEADER*************************\n " );
printf(" |-IP Version : %d\n",(unsigned int)iph->version);
printf(" |-IP Header Length : %d DWORDS or %d Bytes\n",(unsigned int)iph->ihl,((unsigned int)(iph->ihl))*4);
printf(" |-Type Of Service : %d\n",(unsigned int)iph->tos);
printf(" |-IP Total Length : %d Bytes(Size of Packet)\n",ntohs(iph->tot_len));
printf(" |-Identification : %d\n",ntohs(iph->id));
//printf(" |-Reserved ZERO Field : %d\n",(unsigned int)iphdr->ip_reserved_zero);
//printf(" |-Dont Fragment Field : %d\n",(unsigned int)iphdr->ip_dont_fragment);
//printf(" |-More Fragment Field : %d\n",(unsigned int)iphdr->ip_more_fragment);
printf(" |-TTL : %d\n",(unsigned int)iph->ttl);
printf(" |-Protocol : %d\n",(unsigned int)iph->protocol);
printf(" |-Checksum : %d\n",ntohs(iph->check));
printf(" |-Source IP : %s\n",inet_ntoa(source_epc.sin_addr));
printf(" |-Destination IP : %s\n",inet_ntoa(dest_epc.sin_addr));
}
void print_udp_packet(unsigned char *Buffer , int Size)
{
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)(Buffer + sizeof(struct ethhdr));
iphdrlen = iph->ihl*4;
struct udphdr *udph = (struct udphdr*)(Buffer + iphdrlen + sizeof(struct ethhdr));
int header_size = sizeof(struct ethhdr) + iphdrlen + sizeof udph;
printf("\n\n***********************UDP Packet*************************\n");
//print_ip_header(Buffer,Size);
printf("\nUDP Header\n");
printf(" |-Source Port : %d\n" , ntohs(udph->source));
printf(" |-Destination Port : %d\n" , ntohs(udph->dest));
printf(" |-UDP Length : %d\n" , ntohs(udph->len));
printf(" |-UDP Checksum : %d\n" , ntohs(udph->check));
printf("\n");
//printf("IP Header\n");
//PrintData(Buffer , iphdrlen);
//printf("UDP Header\n");
//PrintData(Buffer+iphdrlen , sizeof udph);
//printf("Data Payload\n");
//Move the pointer ahead and reduce the size of string
//PrintData(Buffer + header_size , Size - header_size);
printf("\n###########################################################");
}
Upvotes: 1