IP Dump is a simple network traffic dump program for Linux 2.x; although it is similar to tcpdump, it does not require the libpcap library.
09c37ddf38e986cf8e349fd6aa6ae935e9d36b782f35bb44f9f9a8cad1818ba9
/*
* IPv4 packet sniffer for Linux 2.x
*
* Copyright (C) 2002 Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <netpacket/packet.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#define ETH_P_ALL 0x0003
#define ETH_P_IP 0x0800
int main( int argc, char *argv[] )
{
unsigned char buffer[4096];
unsigned short sport, dport;
int raw_sock, buflen, fromlen;
struct sockaddr_ll sll, from;
struct packet_mreq mr;
struct ifreq ifr;
struct in_addr src, dst;
struct icmphdr *icmp;
struct udphdr *udp;
struct tcphdr *tcp;
struct iphdr *ip;
struct tm *lt;
time_t tt;
/* check the argument */
if( argc != 2 )
{
printf( "usage: %s <interface>\n", argv[0] );
return( 1 );
}
/* create the raw socket */
if( ( raw_sock = socket( PF_PACKET, SOCK_DGRAM,
htons( ETH_P_ALL ) ) ) == -1 )
{
perror( "socket" );
return( 1 );
}
/* find the interface index */
memset( &ifr, 0, sizeof( ifr ) );
strncpy( ifr.ifr_name, argv[1], sizeof( ifr.ifr_name ) );
if( ioctl( raw_sock, SIOCGIFINDEX, &ifr ) == -1 )
{
perror( "ioctl(SIOCGIFINDEX)" );
return( 1 );
}
/* this raw socket will receive all ethernet packets */
memset( &sll, 0, sizeof( sll ) );
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons( ETH_P_ALL );
/* bind the raw socket to the interface */
if( bind( raw_sock, (struct sockaddr *) &sll, sizeof( sll ) ) == -1 )
{
perror( "bind" );
return( 1 );
}
/* enable promiscuous mode */
memset( &mr, 0, sizeof( mr ) );
mr.mr_ifindex = ifr.ifr_ifindex;
mr.mr_type = PACKET_MR_PROMISC;
if( setsockopt( raw_sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&mr, sizeof( mr ) ) == -1 )
{
perror( "setsockopt" );
return( 1 );
}
while( 1 )
{
/* wait for packets */
fromlen = sizeof( from );
if( ( buflen = recvfrom( raw_sock, buffer, 4096, 0,
(struct sockaddr *) &from, &fromlen ) ) == -1 )
{
perror( "recvfrom" );
return( 1 );
}
/* skip duplicate packets on the loopback interface */
if( ! strcmp( argv[1], "lo" ) && from.sll_pkttype == PACKET_OUTGOING )
{
continue;
}
/* verify the socket family */
if( from.sll_family != AF_PACKET )
{
printf( "socket family is %d, should be %d (AF_PACKET)\n",
from.sll_protocol, AF_PACKET );
continue;
}
/* we're only interested in standard IPv4 packets */
if( ntohs( from.sll_protocol ) != ETH_P_IP )
{
continue;
}
/* have a look inside the IP header */
ip = (struct iphdr *) buffer;
src.s_addr = ip->saddr;
dst.s_addr = ip->daddr;
/* print the local time */
tt = time( 0 );
lt = localtime( &tt );
printf( "%02d-%02d %02d:%02d:%02d ", lt->tm_mon, lt->tm_mday,
lt->tm_hour, lt->tm_min, lt->tm_sec );
switch( ip->protocol )
{
case SOL_TCP:
printf( " TCP: " );
tcp = (struct tcphdr *) \
( (void *) ip + sizeof( struct iphdr ) );
/* grab source and destination port */
sport = htons( tcp->source );
dport = htons( tcp->dest );
common:
/* and print the most interesting informations */
printf( "%15s : %-5d", inet_ntoa( src ), sport );
printf( " -> " );
printf( "%15s : %-5d", inet_ntoa( dst ), dport );
printf( " %4d\n", buflen );
break;
case SOL_UDP:
udp = (struct udphdr *) \
( (void *) ip + sizeof( struct iphdr ) );
printf( " UDP: " );
sport = htons( udp->source );
dport = htons( udp->dest );
goto common;
case 1: /* SOL_ICMP */
icmp = (struct icmphdr *) \
( (void *) ip + sizeof( struct iphdr ) );
printf( "ICMP: " );
sport = icmp->type;
dport = icmp->code;
goto common;
default :
printf( "unsupported IP protocol %d\n", ip->protocol );
break;
}
}
return( 0 );
}