⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Linux系统下的简单sniffer程序代码
💻 C
字号:
/*
    This is simple TCP/UDP/ICMP sniffer.
    However it will work only (?) with Linux,
    because only Linux kernel feeds TCP and UDP packets to
    raw sockets.For example in FreeBSD you can't access TCP/UDP packets
    over raw sockets,only ICMP. 
   
    files:
       slc.c   - this file.
       defs.h  - tcp,udp and icmp packets struct's.

    License: GNU General Public license.
	
    Author:
	Povilas Daniu餴s,2002 paralax@hacker.lt
*/	
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <netinet/if_ether.h>
#include <fcntl.h>
#include <signal.h>

#include "defs.h"

#define LOGF "./log.txt"		/* log messages */

#define TCP_LOG  "./tcp.txt"		/* log all tcp sniffed packets */
#define UDP_LOG  "./udp.txt"		/* log all udp sniffed packets*/
#define ICMP_LOG "./icmp.txt"		/* & all icmp pkts */


int s_tcp,s_udp,s_icmp;
int logf;
int l_tcp,l_udp,l_icmp;
volatile int active = 1;

void sniffer(int,int,int);
void log (char *);
void sigint_h();
void usage(char *s);

int 
main(int argc,char **argv)
 {
  char c;
  int tcp_sniff = 0;
  int udp_sniff = 0;
  int icmp_sniff = 0;

 if (argc < 2) { usage(argv[0]); exit(0); }
 
 while ((c = getopt(argc,argv,"tui")) != EOF)
  switch (c)
   {
    case 't': 
     printf("TCP;"); 
     tcp_sniff = 1;
     break;
   case 'u':
     printf("UDP;"); 
     udp_sniff = 1;
     break;
   case 'i':
    printf("ICMP;");
    icmp_sniff = 1;
   break; 
  default: 
     usage(argv[0]);
     exit(0);
   break; 
  }
   printf("\n");
   sniffer(tcp_sniff,udp_sniff,icmp_sniff);     
   return 0;
 }

void
 sniffer(int tcp_sniff,int udp_sniff,int icmp_sniff)
 {
   int chpid;
   int r;
   char buff[128];
   unsigned long int tcp_sniffed = 0,udp_sniffed = 0,icmp_sniffed = 0;
    /* open raw sockets */   
    if (tcp_sniff) 
     if ((s_tcp  = socket(PF_INET,SOCK_RAW,IPPROTO_TCP)) == -1)
      {
       perror("TCP socket():");
       exit(-1);
      }
    if (udp_sniff) 
     if ((s_udp  = socket(PF_INET,SOCK_RAW,IPPROTO_UDP)) == -1)
      {
       perror("UDP socket():");
       exit(-1);
      } 
    if (icmp_sniff) 
    if ((s_icmp = socket(PF_INET,SOCK_RAW,IPPROTO_ICMP)) == -1)
     {
      perror("ICMP socket():");
      exit(-1);
     }
    /* open log files */ 
    /* don't open logs over nfs ( man open() , O_APPEND ) ! */
    if ((logf = open(LOGF,O_RDWR | O_CREAT | O_APPEND,0600)) == -1 )
     {
      perror("open()");
      exit(-1);
     } 
     if (tcp_sniff)
     if ((l_tcp = open(TCP_LOG,O_RDWR | O_CREAT | O_APPEND,0600)) == -1)
     {
      perror("open()");
      exit(-1);
     } 
    if (udp_sniff)
    if ((l_udp = open(UDP_LOG,O_RDWR | O_CREAT | O_APPEND ,0600)) == -1)
     {
      perror("open()");
      exit(-1);
     } 
    if (icmp_sniff) 
    if ((l_icmp = open(ICMP_LOG,O_RDWR | O_CREAT | O_APPEND,0600)) == -1)
     {
      perror("open()");
      exit(-1);
     } 
   /* go to background */
   if ((chpid = fork()))
    {
     printf("daemon pid = %d\n",chpid);
     exit(0);
    } 
   else if (chpid == -1)
    {
     perror("Can't start daemon -  fork() : ");
     exit(-1);
    } 
   /* sniffer stops after geting SIGINT */    
    signal(SIGINT,sigint_h);		
   
    log("Daemon started"); 
   /*switch sockets to non blocking mode */
    fcntl(s_tcp,F_SETFL,FNDELAY);
    fcntl(s_udp,F_SETFL,FNDELAY);
    fcntl(s_icmp,F_SETFL,FNDELAY);
    memset(&tcp_packet,0,sizeof(tcp_packet));
    memset(&udp_packet,0,sizeof(udp_packet));
    memset(&icmp_packet,0,sizeof(icmp_packet));
    memset(buff,0,sizeof(buff));
        while (active)
        {
	  if (
	     tcp_sniff	&&
	     ((r = read(s_tcp,(struct ip_tcp_pkt *)&tcp_packet,sizeof (tcp_packet)))>0)
	     )
	   {
	    tcp_sniffed++;
            sprintf(buff,"%s (%d bytes) -- ","TCP packet",r);
	    log(buff);
	    write(l_tcp,(struct ip_tcp_pkt *)&tcp_packet,r);
	    r = 0;
	   }    
	  if (
              udp_sniff && 
	     ((r = read(s_udp,(struct ip_udp_pkt *)&udp_packet,sizeof (udp_packet)))>0)
	     )
	   {
	    udp_sniffed++;
            sprintf(buff,"%s (%d bytes) --","UDP packet",r);
	    log(buff);
	    write(l_udp,(struct ip_udp_pkt *)&udp_packet,r);
	    r = 0;
	   }    
	  if (
	     icmp_sniff &&
	     ((r = read(s_icmp,(struct ip_icmp_pkt *)&icmp_packet,sizeof (icmp_packet)))>0)
	     )
	   {
	    icmp_sniffed++;
            sprintf(buff,"%s (%d bytes) --","ICMP packet",r);
	    log(buff);
	    write(l_icmp,(struct ip_icmp_pkt *)&icmp_packet,r);
	    r = 0;
	   }    
	  
	   memset(&tcp_packet,0,sizeof(tcp_packet));
	   memset(&udp_packet,0,sizeof(udp_packet));
	   memset(&icmp_packet,0,sizeof(icmp_packet));
        }
       memset(buff,0,sizeof(buff));       	
       sprintf(buff,"%d TCP;%d UDP;%d ICMP, total %d packets sniffed",
       tcp_sniffed,udp_sniffed,icmp_sniffed,
       tcp_sniffed + udp_sniffed + icmp_sniffed
       );		
       log(buff);
       log("Daemon stopped by SIGINT\n");
       fcntl(s_tcp,F_SETFL,0);
       fcntl(s_udp,F_SETFL,0);
       fcntl(s_icmp,F_SETFL,0);
       close(s_tcp);
       close(s_udp);
       close(s_icmp);
       close(l_tcp);
       close(l_udp);
       close(l_icmp);
       close(logf);	
 }
 
void 
 log(char *msg)
{
 time_t t = time(NULL);
 char *ct = ctime(&t);
 char message[128];										
 ct[strlen(ct)-1] = ' ';
 sprintf(message,"%d : [ %s ] %s\n",getpid(),ct,msg);
 write(logf,message,strlen(message));
} 

void 
 sigint_h()
 {
  active = 0;
 } 
 
void 
 usage(char *s)
 {
  char color[16];
  char nocolor[16];
  int  d;
  srand(time(NULL));
  d = rand() % 10;
  sprintf(color,"%c[3%dm",0x1b,d);
  sprintf(nocolor,"%c[0m",0x1b);
  printf("Linux Sniffer by %s Povilas Daniushis%s\n",color,nocolor);
  printf("		    paralax@freemail.lt \n");
  printf("usage %s [-tui] \n",s); 
  printf("where -t - for TCP\n");
  printf("	-u - for UDP\n");
  printf("	-i - for ICMP\n");
 } 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -