this should help
#include <linux/socket.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/if_arp.h>
#include <linux/inet.h>
#include <linux/in.h>
int CreateSocket();
void DieWithError(char* message);
/* Set the size of buffer bigger if MTU is bigger than 1500 */
struct etherpayload
{
struct iphdr ip;
struct tcphdr tcp;
char buffer[1461];
};
int main()
{
int sock, i;
int result;
struct etherpayload rcvBuffer;
struct in_addr sourceIP;
struct in_addr destIP;
char* textSourceIP = (char *)malloc(17);
char* textDestIP = (char *)malloc(17);
sock = CreateSocket();
printf("socket: %d\n", sock);
/* Infinite loop printing out packets that we see */
for(;;)
{
/* Wait for a packet */
result = recv(sock, (void *)&rcvBuffer, 1500, 0);
/* Only try to parse the packet if it is big enough
to contain at least the IP header */
if(result > 20)
{
/* Extract the source and dest IP addresses
and convert them into readable text */
sourceIP.s_addr = (rcvBuffer.ip.saddr);
destIP.s_addr = (rcvBuffer.ip.daddr);
strcpy(textSourceIP, (char *)inet_ntoa(sourceIP));
textSourceIP[16]='\0';
strcpy(textDestIP, (char *)inet_ntoa(destIP));
textDestIP[16]='\0';
/* Print out the source and dest of the packet that we saw */
/* TODO: add reverse DNS lookup as an option */
printf("Received %d bytes from %s to %s\n",
result, textSourceIP, textDestIP);
/* Print out what the protocol inside the packet was */
printf("Protocol was %d\n", rcvBuffer.ip.protocol);
rcvBuffer.buffer[result-40]='\0';
/* If the packet was TCP, print the TCP ports and payload */
if(rcvBuffer.ip.protocol==6)
{
printf("TCP packet had source port %d and dest port %d\n",
ntohs(rcvBuffer.tcp.source), ntohs(rcvBuffer.tcp.dest));
printf("TCP data field had: \n");
for(i =0; i<result-40;i++)
{
/* Display carriage returns correctly */
if(rcvBuffer.buffer[i]==13)
{
printf("\n");
}
/* Print each individual character
assuming it is a printable character */
if(isprint(rcvBuffer.buffer[i]))
{
printf("%c", rcvBuffer.buffer[i]);
}
}
/* Print an extra carriage return after the packet */
printf("\n");
}
}
if(result <= 0)
DieWithError("Connection is dead");
}
return 0;
}
int CreateSocket()
{
int sock;
int result;
struct packet_mreq sockopt;
/* struct sockaddr_ll llopt; */
int size;
/* Structure to store socket options */
sockopt.mr_ifindex = 1;
sockopt.mr_type = PACKET_MR_PROMISC;
sockopt.mr_alen = 0;
sockopt.mr_address[0]='\0';
/* The following structure isn't needed to just listen
for packets, but it may be useful in other applications */
/*
memset((void *)&llopt, 0, sizeof(llopt));
llopt.sll_family = AF_PACKET;
llopt.sll_protocol = htons(ETH_P_IP);
llopt.sll_ifindex = 1;
llopt.sll_hatype = ARPHRD_ETHER;
llopt.sll_pkttype = PACKET_BROADCAST;
llopt.sll_halen = 6;
llopt.sll_addr[0]='\0';
*/
/* Using a SOCK_DGRAM so that we don't have to strip
out the physical layer headers ourselves */
sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
/* If we aren't root, the system won't allocate a DGRAM socket */
if(sock <= 0)
DieWithError("Couldn't open a DGRAM socket");
/* Set the socket options to put the adapter in promiscuous mode */
result = setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
(void *)&sockopt, sizeof(sockopt));
if(result < 0)
DieWithError("Couldn't set options");
return sock;
}
void DieWithError(char* message)
{
perror(message);
exit(-1);
}