📄 main.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 + -