---------------------[ previous ]---[ index ]---[ next ]----------------------

==============================================================================
-------------[ BFi numero 7, anno 2 - 25/12/1999 - file 9 di 22 ]-------------
==============================================================================


-[ HACKiNG ]------------------------------------------------------------------
---[ G0RK: A SiMPLE & P0WERFUL PACKET L0GGER - pIGpEN


PENSiERiNO FiL0SoFiCo: su PHRACK si legge: Live in SYN
		       in BFi il mio senso masochistico mi impone: Live TO FIN
		       E come da frase:
		       "Il mondo e' stato creato in attesa della sua fine..."
		       E come da maglietta di Barlow:
		       "No SEX, No Drugs, No Alcohol, No Tobacco,
		       No Rock Music, No Socialism, YES CAFFEINE!!!" (thx b0z0
		       per avermela fatta notare)

Ringraziamenti: raptor (thx 1000) e koba (il mangiatore di pannocchie)

			   [---> COS'E' G0RK <---]

G0RK e' prima di tutto un semplice dumper progettato per avvicinare la gente
a capire cosa passa per i loro fili :)
Ma e' soprattutto uno strumento di log che permette di monitorare quello che
entra e che esce dal vostro sistema.
Questa versione supporta la libreria pcap per dare un margine di
compatibilita' maggiore...
Mentre state leggendo e' probabile che G0RK supporti pure PF_PACKET con tipo
SOCK_RAW per i nuovi kernel di linux ed altro. Al limite se cercate una
versione piu' adatta alle vostre esigenze scrivetemi: sono disponibile a
svilupparla...

		    [---> G0RK COME STRUMENTO DI LOG <---]

       E' questa la parte piu' potente di questo tool... un esempio?

       [ Directory: /var/log/chihaosato ]

       com   edu   it   mil   fbi.gov   cammello:25   satan.was.here

       [ Arrivano i pacchetti... ]

       SYSLOG:

       messages:Aug 12 14:11:59 sp00f a.out: G0RK: My lord 666.666.666.666
		was here ... I log it

       cat /var/log/chihaosato/satan.was.here

	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 666.666.666.666
	DEST ADDR: 192.168.1.1
	SOURCE HOSTNAME: satan.was.here.hell
	DEST HOSTNAME: gateway.cameretta.pig
	TYPE: icmp echo
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 192.168.1.1
	DEST ADDR: 666.666.666.666
	SOURCE HOSTNAME: gateway.cameretta.pig
	DEST HOSTNAME: satan.was.here.hell
	TYPE: icmp echo reply
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 666.666.666.666
	DEST ADDR: 192.168.1.1
	SOURCE HOSTNAME: satan.was.here.hell
	DEST HOSTNAME: gateway.cameretta.pig
	TYPE: icmp echo
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 192.168.1.1
	DEST ADDR: 666.666.666.666
	SOURCE HOSTNAME: gateway.cameretta.pig
	DEST HOSTNAME: satan.was.here.hell
	TYPE: icmp echo reply
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 666.666.666.666
	DEST ADDR: 192.168.1.1
	SOURCE HOSTNAME: satan.was.here.hell
	DEST HOSTNAME: gateway.cameretta.pig
	TYPE: icmp echo
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 192.168.1.1
	DEST ADDR: 666.666.666.666
	SOURCE HOSTNAME: gateway.cameretta.pig
	DEST HOSTNAME: satan.was.here.hell
	TYPE: icmp echo reply
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 666.666.666.666
	DEST ADDR: 192.168.1.1
	SOURCE HOSTNAME: satan.was.here.hell
	DEST HOSTNAME: gateway.cameretta.pig
	TYPE: icmp echo
	-------------------------------------------------------------
	DATE: 14:24:10 Thu Aug 12
	SOURCE ADDR: 192.168.1.1
	DEST ADDR: 666.666.666.666
	SOURCE HOSTNAME: gateway.cameretta.pig
	DEST HOSTNAME: satan.was.here.hell
	TYPE: icmp echo reply
	-------------------------------------------------------------

Ovviamente avrete un output simile pure per TCP e UDP .
NOTA BENE: e' diverso mettere, per esempio, .com o com in gork.conf:
il primo logga il traffico su siti commerciali mentre il secondo non solo
questo, ma ad esempio anche quello su:
comitato.x.la.legalizzazione.della.pigcola.org
Questo perche' ha "com" nella parola comitato...

			   [---> COME SI CONFIGURA <---]

G0RK e' pensato per essere il piu' semplice possibile. Basta mettere in
gork.conf gli ip oppure se preferite gli hostname da monitorare e tutto
quello che passa tra voi e ogni singola macchina della lista sara' monitorato
e salvato nel file con nome uguale all'ip o hostname che avete inserito.
G0RK puo' pure loggare direttamente tutto: basta mettere in gork.conf un "."
e l'output sara' visibile in all_g0rk.log
A parte questo sono accettati anche parte di indirizzi (per es 192.168.1
oppure .gov ).

		       [---> ALTRE OPZIONI INTERESSANTI <---]

G0RK permette inoltre di loggare solamente certe porte se invocato con
l'opzione "-p": in tal caso l'output si trovera' nei file "ip:porta" oppure
"hostname:porta".

Es.:

 [gork.conf]
 porcellino
 cammello

 cmd: g0rk -p 25

 output file: cammello:25 porcellino:25

G0RK puo' infine loggare e avvertirvi di particolari msg mandati via syslog:

 cmd: g0rk -l promiscuous

 output file: gork.syslog

 23:09:53 Sun Oct 31 --- str -> promiscuous
 192.168.1.2 -> 192.168.1.1 == <6>kernel: device eth0 entered promiscuous mode

                  [---> COME COMPILO G0RK SULLA MIA BOX <---]

E' sufficiente compilare G0RK con il cmd:

 gcc gork.c -lpcap

			   [---> QUANTO MI COSTA <---]

Uhm G0RK costa esattamente 1.000 lire per ogni pacchetto ricevuto, da pagare
con carta di credito :P Tutti i soldi verranno utilizzati per un concerto
in ricordo dei Grateful Dead ;D

G0RK e' ovviamente libero, puo' essere pubblicato e distribuito su altri siti
se lasciato nella sua forma originale... e magari con una piccola mail
inviata a pigpen@s0ftpj.org solo a titolo informativo.

			      [---> IL CODICE <---]

---------- snip ----------
/*
 * G o r k   -  U n i x   P a c k e t   L o g g e r
 * 
 * c o m p a t i b l e  v e r s i o n
 *
 *
 * Compile with: gcc gork.c -O4 -Wall -lpcap
 *
 * Tested on:
 *
 * 	Linux RedHat 6.X     ( mail.cameretta.pig )
 *	Linux Debian 2.0r3   ( porcellino.cameretta.pig ) 
 *      FreeBSD 4.0          ( sp00f.y0ur.life.cameretta.pig )
 * 
 *
 * Gork is a tcp/udp/icmp/ip dumper with options to log only packets     
 * from/to specific machine/s in a file with name = its ip/hostname  
 * This version supports pcap library                    		
 * so this code can be compiled in other boxes				       
 * How can i log?			                                       
 * For example we can use a config file [gork.conf] like this:
 * whitehouse.gov 							       
 * 192.168.1								       
 * www.dead.net		<---- great grateful stuff!!!			       
 * baubau.bau                                                                  
 *									       
 * And we see every packets from/to whitehouse.gov in whitehouse.gov file      
 * from/to 192.168.1.XXX in 192.168.1 file and so on ....                      
 * NOTE: To log all pkt use a "." in gork.conf file... Output will be in       
 * all_g0rk.log					                               
 *			                                                       
 * Gork can be used to log pkt from / to a particular port:		       
 *					                                       
 * gork -p port							               
 * or to check for a particular syslog msg                                     
 * gork -l refused							       
 * And you can see result in gork.syslog	                               
 *				                                               
 * usage: gork -h for help ...					               
 *									       
 * Greetings go to: s0ftPj, MTV (gork was created after Beavis & Butthead show)
 * b0z0/iKX, PacketStorm, all members of Metro Olografix (a cool organization),
 * dislessici, dead.net for their stuffs, Sky, Francesca & other my friends... 
 *
 *
 * pIGpEN <pigpen@s0ftpj.org>
 */

 /*  Wake of the flood, laughing water,  forty-nine. Get out the pans.
     Don't just stand the dreamin'. Get out the way. Get out the way.
             Here comes sunshine, Here comes sunshine */

// CONFIGURATION 

/*
 *
 * DONT_LOOKUP:
 * 		gork uses gethostbyaddr() function to obtain hostnames: this
 * 		can create a lot of traffic from your box to your name server
 * 		and vice versa so you can disable lookup with DONT_LOOKUP
 *		but hostnames or strings in gork.conf can't be considered
 *
 *		NOTE: gork has a little filter for this.. look for yes_lookup
 *		      flag
 * 		
 */

//#define DONT_LOOKUP	//	if you have problem with gork & your dns

/*
 * PROMISC:
 * 	       value:   0    --> NO PROMISC 
 * 	                         (you see only packets from/to your box)
 * 	       		1    --> PROMISC MODE
 * 	       		         (you see all your network packets)  
 */

#define PROMISC  1  

/*
 * SYSTEM LOG:
 * 		gork can send msg via syslog... This isn't a good thing if
 * 		you send syslog msg to another host... and can also gives
 * 		you problem with console output
 */

//#define SYSTEM_LOG
 
/* 
 *
 * G 0 R K  a porting of Timothy Leary on your Box ... ;)
 * 
 */
 
#include 		<stdio.h>
#include 		<netdb.h>
#include 		<string.h>
#include 		<stdlib.h>
#include 		<unistd.h>
#include 		<arpa/nameser.h>
#include 		<sys/ioctl.h>
#include 		<sys/types.h>
#include 		<sys/time.h>
#include 		<sys/signal.h>
#include 		<sys/socket.h>
#include 		<net/bpf.h>
#include		<netinet/in_systm.h>
#include 		<netinet/in.h>
#include 		<pcap.h>		
#if (linux)
#define __FAVOR_BSD
#endif
#include		<netinet/ip.h>
#include		<netinet/ip_icmp.h>
#include		<netinet/udp.h>
 
#define			CONF		"gork.conf"
#define			LOG_TYPE	4	//syslog

#define			SYSLOG_PORT	514
#define			MTU		1500
#define			URG		32
#define			ACK_PSH		24
#define			SYN_ACK		18
#define			FIN_ACK		17
#define			ACK		16
#define                 PSH             8
#define                 RST             4
#define                 SYN             2
#define         	FIN             1


#define			WHITE		printf("\033[0;29m")
#define                 RED             printf("\033[1;31m")
#define         	GREEN           printf("\033[1;32m")
#define		        YELLOW          printf("\033[1;33m")
#define			BLUE		printf("\033[1;34m")
#define			MAGENTA		printf("\033[1;35m")
#define         	CYAN            printf("\033[1;36m")
#define			RETURN		printf("\n")
#define			CLEAR		printf("\033[2J\033[1;1H")
#define			LINE		printf("<\033[1;32m-----\033[1;34m>\n");

#define 		ADDR_DIM	300
#define			LOG_ALL		"all_g0rk.log"
#define			LOG_SL		"gork.syslog"

unsigned char 		s_addr[ADDR_DIM];
unsigned char   	d_addr[ADDR_DIM];
char 			*hst_saddr=NULL;
char 			*hst_daddr=NULL;
time_t 			now;
char 			date[60];
int 			port=0;
char			*syslog_string;

extern char 		*optarg;

pcap_t 		        *pcap_global_descriptor;
char           		*deviceglobal=NULL;
int            		offset;

/* Line up a longshot, maybe try it two times, maybe more.
   Good to know you got shoes to wear,
   when you find the floor. Why hold out for more? 
   		Here comes sunshine, here comes sunshine!! */

struct packet_info{
	unsigned char ttl, protocol, version;
	unsigned char *saddr, *daddr;
	unsigned long seq, ack_seq;
	unsigned short source, dest, type, id, flags, window;
	char dataload[2000];
};

struct DNSpkt {
 HEADER head;
 char query[255];
};

struct TCPhdr {
 u_short source, dest;
 u_int32_t seq, ack_seq;
 u_short offset_flag, window, checksum, urgent;
};

// think different not so much ...

int 		main 			__P((int, char **));
unsigned long 	in_aton 		__P((const char *));
void 		usage 			__P((char *));
void 		scan 			__P((struct packet_info));
void 		fuckin_about_all_day 	__P((void));
void 		print_addr 		__P((struct packet_info));
void 		pcap_device_on 		__P((void));
void 		sniff_pk 		__P((struct packet_info *));
void 		ethclose 		__P(());
void 		dump_tcp 		__P((struct packet_info, int));
void 		dump_udp 		__P((struct packet_info));
void 		dump_icmp 		__P((struct packet_info));

#ifndef DONT_LOOKUP

char 		*hostLookup 		__P((unsigned long));

char *hostLookup(unsigned long in)
{
 struct in_addr addr;
 struct hostent *hostEnt;

 addr.s_addr = in;
 hostEnt = gethostbyaddr((char *)&addr, sizeof(struct in_addr),AF_INET);

 if(!hostEnt) return NULL;
 	      return (hostEnt->h_name);
}

#endif

unsigned long in_aton(const char *str) {
 unsigned long l;
 unsigned int val;
 int i;

 l = 0;
 for (i = 0; i < 4; i++) {
  l <<= 8;
  if (*str != '\0') {
   val = 0;
   while (*str != '\0' && *str != '.') {
    val *= 10;
    val += *str - '0';
    str++;
   }
   l |= val;
   if (*str != '\0')
    str++;
  }
 }
 return(htonl(l));
}

void usage(char *arg)
{
 YELLOW;
 printf("\t\t\t  pIGpEN - diGiTaL dEAdhEAd -");
 BLUE;
 printf("\n\n\nPut hostname/ip in gork.conf ... \nUse ");
 MAGENTA;
 printf("-p dest_port ");
 BLUE;
 printf("if you wanna log only packets to dest_port\n and with ip/hostname in");
 MAGENTA;
 printf(" gork.conf\n");
 BLUE;  
 printf("To log all source ip put in gork.conf: ");
 MAGENTA;
 printf(".\n");
 printf("-l string ");
 BLUE;
 printf("write in gork.syslog if <string> was found in syslog messages\n");
 printf("Other options: \n");
 printf("		-i interface\n");
 printf("		-v verbose mode for tcp\n");
 WHITE;
}

/*
	Askin' you nice now, keep the mother rollin' one more time.
	Been down before, you just don't have to go no more,
	No More.

	Here comes sunshine! Here comes sunshine! 
*/

void fuckin_about_all_day(void)
{
 CLEAR;
 fflush(stdout); sleep(1);
 printf("\033[1;35m     .g#S$'$S#n.\n");
 printf("\033[1;35m     $$$$$ $$$$'\n");
 printf("\033[1;35m     $$$$$\n");
 printf("\033[1;35m     `$$$$$$$$$n\n");
 printf("\033[1;34m           $$$$$\n");
 printf("\033[1;34m     $$$$$ $$$$$\n");
 printf("\033[1;34m     `$$$$s$$$S'\n\n");
 fflush(stdout); sleep(1);
 printf("\033[1;35m     .g#S$'$S#n.\n");
 printf("\033[1;35m     $$$$$ $$$$$\n");
 printf("\033[1;35m     $$$$$ $$$$$\n");
 printf("\033[1;35m     $$$$$ $$$$$\n");
 printf("\033[1;34m     $$$$$s$$$$'\n");
 printf("\033[1;34m     $$$$$      \n");
 printf("\033[1;34m     $$$$       \n");
 fflush(stdout); sleep(1);
 printf("\033[1;35m            S#n.\n");
 printf("\033[1;35m            $$$$\n");
 printf("\033[1;35m            $$$$\n");
 printf("\033[1;35m            $$$$\n");
 printf("\033[1;34m            $$$$\n");
 printf("\033[1;34m      $$$$$ $$$$\n");
 printf("\033[1;34m      `$$$$s$$S'\n\n");
 fflush(stdout); sleep(1);

 MAGENTA;
 printf("\033[15A\t\t\t\t     _____________________\n");
 fflush(stdout); sleep(1);
 printf("\033[01A\t\t\t\t     s o f t p r o j e c t\n\n");
 fflush(stdout); sleep(1);
 BLUE;
 printf("\t\t\t  ____________________________________________\n\n");
 fflush(stdout); sleep(1);
 printf("\t\t\t\033[02A  d i g i t a l  s e k u r i t y  f o r  y 2 k\n\n");
 fflush(stdout); sleep(1);
 printf("\t\t\t\t  ___________________________\n");
 fflush(stdout); sleep(1);
 printf("\t\t\t\t\033[01A  w w w . s 0 f t p j . o r g\n");
 fflush(stdout); sleep(1);
 sleep(3);
 CLEAR;
}

void print_addr(struct packet_info infoz)
{
 struct servent  *service;
 struct protoent *proto;
 int yes_lookup=0;
 
 now=time(NULL);
 strftime(date,60,"%H:%M:%S %a %h %d", localtime(&now));

 bzero(s_addr,sizeof(s_addr)); 
 bzero(d_addr,sizeof(d_addr));
 hst_daddr=hst_saddr=NULL;
 
 sprintf(s_addr,"%u.%u.%u.%u",
            	infoz.saddr[0],
                infoz.saddr[1],
                infoz.saddr[2],
                infoz.saddr[3]);

 sprintf(d_addr,"%u.%u.%u.%u",
                infoz.daddr[0],
                infoz.daddr[1],
                infoz.daddr[2],
                infoz.daddr[3]);
 
 GREEN; 	printf("%s\n",date);
 BLUE; 		printf("%s",s_addr);
 GREEN;		printf(" -> ");
 MAGENTA;	printf("%s",d_addr);

 if(infoz.protocol!=IPPROTO_ICMP) 
 {
  if((proto=getprotobynumber(infoz.protocol))) 
   {
    BLUE;	   
    if((service=getservbyport(infoz.source,proto->p_name)))
     		printf(" %s",service->s_name);
    else 	printf(" %d",infoz.source);
    YELLOW; 	printf(" / ");
    MAGENTA;
    if((service=getservbyport(infoz.dest,proto->p_name)))
     		printf("%s",service->s_name);
    else 	printf("%d",infoz.dest);
   }
 }
 
#ifndef DONT_LOOKUP 
  BLUE; 

  // limit shit for dns ... invoked with gethostbyaddr() 
  // you can change it as you want ...
  
  switch(infoz.protocol) 
   {
    case IPPROTO_TCP:
	   	      if(infoz.flags==SYN)
	               yes_lookup=1;
		      break;
    case IPPROTO_UDP:
		      if(infoz.source != NAMESERVER_PORT &&
		         infoz.dest   != NAMESERVER_PORT)
		       yes_lookup=1;
		      break;
    case IPPROTO_ICMP:
		      yes_lookup=1;
		      break;
  }		  
  
 if(yes_lookup)
 {	 
  RETURN;	
  if(!(hst_saddr=hostLookup(in_aton(s_addr))))
  		printf("none -> ");
  else
  		printf("%s -> ",hst_saddr);
 
  MAGENTA;
		   
  if(!(hst_daddr=hostLookup(in_aton(d_addr))))
  		printf("none");
  else
  		printf("%s",hst_daddr);
 }  
#endif
 MAGENTA; RETURN;
 
 scan(infoz);	
}


void scan(struct packet_info infoz)
{
 FILE *iff, *of;
 char buf[512];
 char o[400],tmp_port[10]; 
 char *flags=NULL;
 int HST_FOUND=0;

 if(!(iff=fopen(CONF,"r")))
   return;
 while(fgets(buf,512,iff))
  {
   if(buf[strlen(buf)-1]=='\n')
    buf[strlen(buf)-1]=0;

   if(infoz.version!=4)
    {
     CLEAR;
     printf("Sorry this is only a ipv4 version. write to: pigpen@s0ftpj.org\n");
     printf("if you wanna ipv6 support\n");
     exit(-1);
    } 

   if(port && infoz.dest!=port && infoz.source!=port)
    return;

   if(port && (infoz.protocol==IPPROTO_ICMP))
    return;  

   if(hst_saddr) {
    if(strstr(hst_saddr,buf)) 
     HST_FOUND=1;
   }
			
   if(hst_daddr) {	
    if(strstr(hst_daddr,buf))
     HST_FOUND=1;
   }
    
   if(  
       strstr(s_addr,buf)     ||
       strstr(d_addr,buf)     ||
       HST_FOUND==1	
     )	 
    {
#ifdef SYSTEM_LOG
      syslog(LOG_TYPE,"G0RK: My lord %s is here ... I log it", s_addr);
#endif
     if(buf[0]=='.' && buf[1]=='\0')
      of=fopen(LOG_ALL,"a");
     else
      (buf[0]=='.') ? bcopy(buf+1,o,sizeof(o)) : bcopy(buf,o,sizeof(o));
     if(port) { sprintf(tmp_port,":%d",port); strncat(o,tmp_port,sizeof(o)); }
     of=fopen(o,"a");
     if(!of)
      {
       CLEAR;
       printf("Can't open %s file\n\n\n",buf);
       exit(-1);
      }
     fprintf(of,"<--->\n");
     fprintf(of,"date: %s\n",date);
     fprintf(of,"src:%s (%s)\ndst:%s (%s)\n",s_addr,hst_saddr,d_addr,hst_daddr);
     if((infoz.protocol)!=IPPROTO_ICMP)
       fprintf(of,"port: %d:%d\n",infoz.source,infoz.dest);
     
     switch(infoz.protocol)
      {
      case IPPROTO_ICMP:
       fprintf(of,"type: ");
       switch((infoz.type)/256) {
        case 0:
         fprintf(of,"icmp echo reply\n");
         break;
        case 3:
         fprintf(of,"icmp dest_unreach\n");
         break;
        case 4:
         fprintf(of,"icmp source quench\n");
         break;
        case 5:
         fprintf(of,"icmp redirect\n");
         break;
        case 8:
         fprintf(of,"icmp echo\n");
         break;
        case 11:
         fprintf(of,"icmp time exceeded\n");
         break;
        case 12:
         fprintf(of,"icmp parameter problem\n");
         break;
        case 13:
         fprintf(of,"icmp timestamp\n");
         break;
        case 14:
         fprintf(of,"icmp timestamp reply\n");
         break;
        case 15:
         fprintf(of,"icmp information\n");
         break;
        case 16:
         fprintf(of,"icmp information reply\n");
         break;
        case 17:
         fprintf(of,"icmp address mask\n");
         break;
        case 18:
         fprintf(of,"icmp address mask reply\n");
         break;
        default:
         fprintf(of,"icmp type %i\n", infoz.type);
         break;
       }
       break;  
	
      case IPPROTO_TCP:
       fprintf(of,"seq #: %u\n",(unsigned int) infoz.seq);
       fprintf(of,"ack #: %u\n",(unsigned int) infoz.ack_seq);
       fprintf(of,"ttl: %i\n",infoz.ttl);
       fprintf(of,"win: %i\n",infoz.window);
       
       switch (infoz.flags) {
        case URG:
         flags="-----U";
         break;
        case ACK_PSH:
         flags="---PA-";
         break;
        case SYN_ACK:
         flags="-S--A-";
         break;
        case FIN_ACK:
         flags="F---A-";
         break;
        case ACK:
         flags="----A-";
         break;
        case PSH:
         flags="---P--";
         break;
        case RST:
         flags="--R---";
         break;
        case SYN:
         flags="-S----";
         break;
        case FIN:
         flags="F-----";
         break;
        default:
         break;
       }
       fprintf(of,"flags %s\n",flags);	
       break;

      case IPPROTO_UDP:
       if(infoz.dest==SYSLOG_PORT && port!=SYSLOG_PORT)
        fprintf(of,"SYSLOG DATA: %s\n",infoz.dataload); 
       break;

      default:
       break;		
      }//switch	
    
    buf[strlen(buf)+1]=0;
    buf[strlen(buf)]='\n';

    fclose(of);
   }
 }
 fclose(iff);
}


void pcap_device_on(void)
{
 char            errbuf[1028];
 struct pcap_pkthdr pcap_hdr;
 int datalink;

 if (!deviceglobal || !strcmp(deviceglobal, "default")) {
  deviceglobal=pcap_lookupdev(errbuf);
  printf("Device detected ->");
  GREEN;
  printf(" %s.\n\n", deviceglobal);
 }

 if (!deviceglobal) {
  printf("Error getting device - %s\n", errbuf);
  exit(1);
 }

 pcap_global_descriptor =
  pcap_open_live(deviceglobal, 68, PROMISC, 1000, errbuf);

 if (!pcap_global_descriptor) {
  printf("error opening pcap: %s\n", errbuf);
  exit(1);
 }

 datalink = pcap_datalink(pcap_global_descriptor);
 bzero(&pcap_hdr, sizeof(struct pcap_pkthdr));

 switch (datalink) {
  case DLT_EN10MB:
                  offset = 14;
                  break;
  case DLT_NULL:
  case DLT_PPP:	
                  offset = 4;
                  break;
  case DLT_SLIP:
                  offset = 16;
                  break;
  case DLT_RAW:
		  offset = 0;
		  break;
  case DLT_SLIP_BSDOS:
  case DLT_PPP_BSDOS:
		  offset = 24;
		  break;
  default:
                  printf("unknown datalink type (%d)", datalink);
                  exit(-1); 
 }
}


void sniff_pk(struct packet_info *infoz)
{
 struct ip          *IP;
 struct TCPhdr      *TCP;
 struct udphdr      *UDP;
 struct icmp        *ICMP;
 struct pcap_pkthdr lpcap_hdr;
 char 	*sniff_buff;

 bzero(s_addr, sizeof(s_addr));
 bzero(d_addr, sizeof(d_addr));

 if((sniff_buff=(char *) pcap_next(pcap_global_descriptor, &lpcap_hdr))){
  (char *) sniff_buff+=offset;
  IP = (struct ip *) sniff_buff;
  infoz->ttl = IP->ip_ttl;
  infoz->protocol = (char)IP->ip_p;
  infoz->version  = (char)IP->ip_v;
  infoz->saddr = (unsigned char *)&(IP->ip_src.s_addr);
  infoz->daddr = (unsigned char *)&(IP->ip_dst.s_addr);

  switch (infoz->protocol) {
   case IPPROTO_TCP:
    TCP = (struct TCPhdr *)(sniff_buff+sizeof(*IP));
    infoz->seq     = ntohl(TCP->seq);
    infoz->ack_seq = ntohl(TCP->ack_seq);
    infoz->source  = ntohs(TCP->source);
    infoz->dest    = ntohs(TCP->dest);
    infoz->window  = ntohs(TCP->window);
    infoz->flags   = ntohs(TCP->offset_flag)&
     (URG|ACK|PSH|FIN|RST|SYN);
    memcpy(infoz->dataload,
           sniff_buff + sizeof(struct ip) + sizeof(struct TCPhdr),
           ntohs(IP->ip_len)-sizeof(struct ip)-sizeof(struct TCPhdr));
    break;
   case IPPROTO_UDP:
    UDP = (struct udphdr *)(sniff_buff+sizeof(*IP));
    infoz->source = ntohs(UDP->uh_sport);
    infoz->dest   = ntohs(UDP->uh_dport);
    memcpy(infoz->dataload,
           sniff_buff + sizeof(struct ip) + sizeof(struct udphdr),
           ntohs(IP->ip_len)-sizeof(struct ip)-sizeof(struct udphdr));
    break;
  case IPPROTO_ICMP:
   ICMP = (struct icmp *)(sniff_buff+sizeof(*IP));
   infoz->type = ntohs(ICMP->icmp_type);
   infoz->id   = ntohs(ICMP->icmp_seq);
   break;
  default:
   break;
  }
 }
}


void ethclose()
{
 if(pcap_global_descriptor) pcap_close(pcap_global_descriptor);
 MAGENTA;
 printf("I will getby ... I will survive...\n");
 WHITE;
 exit(0);
}


void dump_tcp(struct packet_info info, int data)
{
 char *flags=NULL;

 print_addr(info);
 MAGENTA;
 printf("TCP ");
 BLUE;
 printf("%u:", (unsigned int) info.seq);
 MAGENTA;
 printf("%u", (unsigned int) info.ack_seq);
 MAGENTA; printf("\tTTL: ");
 BLUE;    printf("%i ", info.ttl);
 MAGENTA; printf("\tWin: ");
 BLUE;    printf("%i", info.window);	
 
 switch (info.flags) {
  case URG:
   flags="-----\033[1;32mU\033[1;34m";
   break;
  case ACK_PSH:
   flags="---\033[1;32mPA\033[1;34m-";
   break;
  case SYN_ACK:
   flags="-\033[1;32mS\033[0;34m--\033[1;32mA\033[1;34m-";
   break;
  case FIN_ACK:
   flags="\033[1;32mF\033[1;34m---\033[1;32mA\033[1;34m-";
   break;
  case ACK:
   flags="----\033[1;32mA\033[1;34m-";
   break;
  case PSH:
   flags="---\033[1;32mP\033[1;34m--";
   break;
  case RST:
   flags="--\033[1;32mR\033[1;34m---";
   break;
  case SYN:
   flags="-\033[1;32mS\033[1;34m----";
   break;
  case FIN:
   flags="\033[1;32mF\033[1;34m-----";
   break;
  default:
   break;
 }

 MAGENTA;  printf("     FLAGS: ");
 BLUE; printf("%s\n",flags);
 if(data && (info.flags==PSH || info.flags==ACK_PSH))
  { 
   BLUE; printf("-> ");
   GREEN;  printf("%s\n",info.dataload);
  }
 LINE;
}


void dump_udp(struct packet_info info)
{
 FILE *fp_sl;
 struct DNSpkt *dns_pkt;

 print_addr(info);
 printf("UDP ");

 if(info.dest==SYSLOG_PORT && port!=SYSLOG_PORT)
  {
   GREEN; 
   printf("%s", info.dataload);
   if(syslog_string && info.dataload)
    {
     if(strstr(info.dataload,syslog_string))
      {
       RED;
       printf("\tMSG LOGGED -> %s\n",LOG_SL);
       fp_sl=fopen(LOG_SL,"a");
       now=time(NULL);
       strftime(date,60,"%H:%M:%S %a %h %d", localtime(&now));
       fprintf(fp_sl,"\n%s --- str -> %s\n",date,syslog_string); 
       fprintf(fp_sl,"%s -> %s == %s\n", 
                     s_addr,
                     d_addr,
                     info.dataload);
       fclose(fp_sl);
      }
    }
  } 

 if(info.source==NAMESERVER_PORT || info.dest==NAMESERVER_PORT) 
  {
   dns_pkt=(struct DNSpkt *) info.dataload;
 
   BLUE;    printf("\tRD: ");
   MAGENTA; printf("%d ",dns_pkt->head.rd);
   BLUE;    printf("AA: ");
   MAGENTA; printf("%d ",dns_pkt->head.aa);
   BLUE;    printf("OPCODE: ");
   MAGENTA;
   switch(dns_pkt->head.opcode)
   {
     case  QUERY: printf("QUERY ");  break;
     case IQUERY: printf("IQUERY "); break;
     case STATUS: printf("STATUS "); break;
         default: printf("%d ",dns_pkt->head.opcode);  
   }
   BLUE;        printf("QR: ");
   MAGENTA;     printf("%d ",dns_pkt->head.qr);

   BLUE; 	printf("RA: ");
   MAGENTA;	printf("%d ",dns_pkt->head.ra);
   BLUE;        printf("AD: ");
   MAGENTA;     printf("%d ",dns_pkt->head.ad);
   BLUE;        printf("CD: ");
   MAGENTA;     printf("%d",dns_pkt->head.cd);
   BLUE;        printf("\tDNSPKT ID: ");
   RED;         printf("%d",dns_pkt->head.id);
  }
 RETURN; BLUE; LINE;
}


void dump_icmp(struct packet_info info)
{
 print_addr(info);

 MAGENTA; printf("ICMP ");
 BLUE;	  printf("TYPE: ");
 RED;
 switch((info.type/256)) {
  case 0:
         printf("echo reply\t");
         break;
  case 3:
         printf("dest_unreach\t");
         break;
  case 4:
         printf("source quench\t");
         break;
  case 5:
         printf("redirect\t");
         break;
  case 8:
         printf("echo\t");
         break;
  case 11:
         printf("time exceeded\t");
         break;
  case 12:
         printf("parameter problem\t");
         break;
  case 13:
         printf("timestamp\t");
         break;
  case 14:
         printf("timestamp reply\t");
         break;
  case 15:
         printf("information\t");
         break;
  case 16:
         printf("information reply\t");
         break;
  case 17:
         printf("address mask\t");
         break;
  case 18:
         printf("address mask reply\t");
         break;
  default:
         printf("%i\t", info.type);
         break;
 }

 BLUE;
 printf("(ttl:%i id:%i)\n", info.ttl, (info.id/256));
 LINE;
}


int main(int argc, char **argv)
{
 int snoop = 0, opt;
 struct packet_info pk_info;

 signal(SIGINT,  ethclose);
 signal(SIGTERM, ethclose);
 signal(SIGKILL, ethclose);
 signal(SIGQUIT, ethclose);
 
 fuckin_about_all_day(); 

 while ((opt = getopt(argc, (char **) argv, "vhp:l:i:")) != EOF) {
  switch(opt)
   {
    case 'v':
             snoop=1;
             break;
    case 'h':
	     usage(argv[0]);
	     exit(1);
    case 'p':
             if(syslog_string)
	      {
	       printf("Can't execute gork with -l & -p\n");
	       WHITE;
	       exit(1);
	      }
	     port=atoi(optarg);
	     break;
    case 'l':
             if(port)
              {
	       printf("Can't execute gork with -p & -l\n");
	       WHITE;
	       exit(1);
	      } 
             syslog_string=optarg;
	     break;    
    case 'i':
	     deviceglobal=optarg;
	     break;
    default:
            exit(1);
   }
 }

 pcap_device_on();
 
 while(1) {
  bzero(&pk_info,sizeof(pk_info));
  sniff_pk(&pk_info);

  // add here other protocol implementations with their functions 
  
  switch(pk_info.protocol) {
   case IPPROTO_TCP:
                     dump_tcp(pk_info, snoop);
                     break;
   case IPPROTO_UDP:
                     dump_udp(pk_info);
                     break;
   case IPPROTO_ICMP:
                     dump_icmp(pk_info);
                     break;
             default:
                     break; 
  }
 }
}
---------- snip ----------

Se ti piace questo codice oppure se provi pena per uno che passa la
giornata a mettere asterischi negli headers contatta l'autore per offrirgli
una cocacola. Non accetto soldi, cacca, fanta, pannocchie, erba, giocattoli,
elettrodomestici, libri usati, frullatori, polpette, scarpe, ecc... (il kit
del barbone ce l'ho, il pizzo pure... se non barboneggio a lungo e' perche'
finisco le pile del walkman e scarico il cellulare).
Sunday, Monday Happy Day... Thrusday, Friday Hippie Day...
...uhm, ma non era proprio cosi'...

Questa non e' ancora la versione definitiva, ma e' comunque funzionante.
Nuove eventuali versioni saranno reperibili su www.s0ftpj.org .

baobab

pIGpEN


==============================================================================
---------------------------------[ EOF 9/23 ]---------------------------------
==============================================================================

---------------------[ previous ]---[ index ]---[ next ]----------------------