Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > 2c04a861c6526f67c70adfc6b88ddb28 > files > 11

dbh-devel-1.0.24-9.fc12.i686.rpm

/*
 * copyright 2002 Edscott Wilson Garcia, under GNU-GPL
 * Example program using disk based hashed for a stream
 * of data from tcpdump to do network monitoring
 * */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dbh.h>

#define LINE_MAX (256*4*16)
/*#define KEY_LEN (2+2+2+2+4+1)*/
#define KEY_LEN 13

char *trafico_raw="trafico.raw";
char whatever[256];

void update(DBHashTable *node,char *host){
   char *w,*v,t[32];
   long long int *hits;
   int i,j,withport=0;

   if (count_dots(host)>3) withport=1;
 
   
   if (!node) return;
   hits=(long long int *)(DBH_DATA(node));
   memset(DBH_KEY(node), 0,DBH_KEYLENGTH(node));

   if ((w=strtok(host,"."))==NULL) goto error_condition;
   i=atoi(w); 
   sprintf(t,"%02x",i);
   strncpy((char *)DBH_KEY(node),t,2);

   for (j=1;j<=2;j++) {
     if ((w=strtok(NULL,"."))==NULL) goto error_condition;
     i=atoi(w); 
     sprintf(t,"%02x",i);
     strncat((char *)DBH_KEY(node)+2*j,t,2);
   }
   
   if (!withport) { /* no port number */
     w=w+strlen(w)+1;	   
     i=atoi(w); 
     sprintf(t,"%02x",i);
     strncat((char *)DBH_KEY(node)+2*3,t,2);
   } else {
     if ((v=strtok(NULL,"."))==NULL) goto error_condition; 
     i=atoi(v); 
     sprintf(t,"%02x",i);
     strncat((char *)DBH_KEY(node)+2*3,t,2);
    /* port */
     w=v+strlen(v)+1;	   
     i=atoi(w); 
     sprintf(t,"%04x",i);
     strncat((char *)DBH_KEY(node)+2*4,t,4);
   }

   if (DBH_load(node)) (*hits)++;
   else *hits=1;

   /* setting the data length is necesary here because DBH_set_data() was not
    * called in this example. Instead, we are directly using the pointer to
    * the data area of the current DBHashTable record */
   DBH_set_recordsize(node,sizeof(long long int));
	   
   if (!DBH_update(node)) {
	   printf("trafico: Unable to update %s\n",DBH_PATH(node));
   }
   /*else printf("trafico: updating %s -> %d\n",(char *)node->key,*hits);*/
   return;
error_condition:
   return;
}


FILE *outfile;

void operate(DBHashTable *node){
   long long int *hits;
   char key[256], buf[16];
   int i,j[5];
   
   if (!outfile) return;
   hits=(long long int *)DBH_DATA(node);
   memset((void *)buf, 0,16);
   memset((void *)j, 0,5*sizeof(int));
   memset((void *)key, 0,256);

   for (i=0;i<4;i++){
     if ( *DBH_KEY(node)+(i*2)) {  
       strncpy(buf,(char *)DBH_KEY(node)+i*2,2);
       sscanf(buf,"%x",j+i);
     }
   }
   if ( *DBH_KEY(node)+(4*2)) { 
       strncpy(buf,(char *)DBH_KEY(node)+4*2,4);
       sscanf(buf,"%x",j+4);
   } 
   sprintf(key,"%d.%d.%d.%d:%d",j[0],j[1],j[2],j[3],j[4]);
   
   fprintf(outfile,"%-30s\t%lld\n",key,*hits);
   /*fprintf(stdout,"writing:%-30s\t%lld\n",key,*hits);*/
   
}

void create_output(DBHashTable *src_node,
		DBHashTable *tgt_node,
		DBHashTable *src_nodeS,
		DBHashTable *tgt_nodeS){
   outfile=fopen(trafico_raw,"w");
   if (!outfile) {
	   printf("trafico: cannot open file %s\n",trafico_raw);
	   return;
   }
   /* else printf("trafico: processing %s\n",trafico_raw);*/

   fprintf(outfile,"Source packets*****************************\n");
   DBH_foreach_sweep(src_node,operate);
   fprintf(outfile,"Source summary-----------------------------\n");
   DBH_foreach_sweep(src_nodeS,operate);
   fprintf(outfile,"Target packets*****************************\n");
   DBH_foreach_sweep(tgt_node,operate);
   fprintf(outfile,"Target summary-----------------------------\n");
   DBH_foreach_sweep(tgt_nodeS,operate);
   fclose(outfile);
   
     if (src_node) DBH_close(src_node);
     if (tgt_node) DBH_close(tgt_node);
     if (src_nodeS) DBH_close(src_nodeS);
     if (tgt_nodeS) DBH_close(tgt_nodeS);
   
   _exit(123);
}

int count_dots(char *addr){
	int i=0;
	char *w;
	w=addr;
	while (w){
	   w=strchr(w+1,'.');
	   if (w && w[0]==0) break;
	   if (w) i++;
	}
	/*printf("count:%s=%d\n",addr,i);*/
	return i;
}

int main(int argc,char **argv){
	/* tcpdump:
	 *  -n     Don't convert host addresses to names.  This can be
                   used to avoid DNS lookups.

            -nn    Don't  convert  protocol  and  port numbers etc. to
                   names either.
		   
            -l     Make stdout line buffered.  Useful if you  want  to
                   see the data while capturing it.  E.g.,
                   ``tcpdump  -l  |  tee  dat''  or  ``tcpdump  -l   >
                   dat  &  tail  -f  dat''.
            
	    -q     Quick (quiet?) output.  Print less protocol  inforĀ­
                   mation so output lines are shorter.

            -t     Don't print a timestamp on each dump line.

       	    -e     Print the link-level header on each dump line.
	    */


     char *cmd="/usr/sbin/tcpdump -n -nn -l -q -t";
     char buffer[256];
     char line[LINE_MAX];
     FILE *pipe;
     char *timestamp,*src="src.html",*tgt="tgt.html",*tmp;
     int linecount=0,status;
     DBHashTable *src_node,*tgt_node;
     DBHashTable *src_nodeS,*tgt_nodeS;


     if (fork()) { /* master process */
	printf("trafico: Running in background.\n");
	exit(1);
     }
   

     
     pipe=fopen("trafico.conf","r");
     if (!pipe){
        pipe=fopen("trafico.conf","w");
	printf("trafico: Creating new configuration file: trafico.conf with defaults.\n");
        if (!pipe){
	  printf("trafico: Cannot create configuration file: trafico.conf.\nUsing defaults anyway.\n");
	} else {
	  fprintf(pipe,"trafico_raw :%s\n",trafico_raw);
	  fclose(pipe);
	}
	
     } else {
       while (!feof(pipe)){
	char *word;
	fgets(line,255,pipe);
	if (line[0]=='#');
	else if (strstr(line,"trafico_raw :")){
		strtok(line,":");
		word=strtok(NULL,"\n");if (!word) break;
		
		trafico_raw=whatever;
		strcpy(whatever,word);
	}
	else {
	//	printf("trafico: Invalid configuration line:\n%s",line);
	}
       }
       fclose(pipe);
     }
     
     DBH_Size(NULL,256);

     src_node=DBH_create("src.dbh",KEY_LEN);     
     if (!src_node) {
	printf("trafico: Unable to create source host database.\n");
	exit(1);
     }
     DBH_writeheader(src_node);    

     src_nodeS=DBH_create("srcS.dbh",KEY_LEN);     
     if (!src_nodeS) {
	printf("trafico: Unable to create source summary database.\n");
	exit(1);
     }
     DBH_writeheader(src_nodeS);
     
     tgt_node=DBH_create("tgt.dbh",KEY_LEN);
     if (!tgt_node) {
	printf("trafico: Unable to create target host database.\n");
	exit(1);
     }   	
     DBH_writeheader(tgt_node);

     tgt_nodeS=DBH_create("tgtS.dbh",KEY_LEN);
     if (!tgt_nodeS) {
	printf("trafico: Unable to create target summary database.\n");
	exit(1);
     }   	
     DBH_writeheader(tgt_nodeS);
    
     pipe = popen (cmd, "r");
     if (pipe){
     //if (stdin){
      
      printf("trafico: pipe is open\n");
	     
      while (!feof(pipe)){
	char *end;
        usleep(100);
	if (!fgets(line,LINE_MAX-1,pipe)) continue; 
	line[LINE_MAX-1]=0;
#if 0
 	   printf("%s",line);
 	   //printf(".",line);fflush(NULL);
#endif
	   /* parse output */      
	   linecount++;

	   src=strtok(line," ");
	   if (!src || strcmp(src,"arp")==0) goto next;
	   tmp=strtok(NULL," ");
	   if (!tmp) goto next;
	   tgt=strtok(NULL,":");
	   if (!tgt) goto next;
	   /* update src and tgt databases */
	   strcpy(buffer,src);
	   update(src_node,buffer);
	   if ((end=strrchr(src,'.'))!=NULL) {
		   if (count_dots(src)>3) end[0]=0;
		   update(src_nodeS,src); 
	   }
	   strcpy(buffer,tgt);
	   update(tgt_node,buffer);	   
	   if ((end=strrchr(tgt,'.'))!=NULL) {
		   if (count_dots(tgt)>3) end[0]=0;
		   update(tgt_nodeS,tgt);
	   }
next:
	   if (linecount % 100 == 0) {
	     pid_t pid=0;
 	     printf("trafico: Flushing %d packets from databases.\n",linecount);
	     fflush(NULL);
             DBH_close(src_node);
             DBH_close(tgt_node);
             DBH_close(src_nodeS);
             DBH_close(tgt_nodeS);
	     pid=fork();
	     if (pid==-1) printf("Unable to fork.\n");
	     if (pid) { /* zombie control */
		     src_node=DBH_openR("src.dbh");
		     tgt_node=DBH_openR("tgt.dbh");
		     src_nodeS=DBH_openR("srcS.dbh");
		     tgt_nodeS=DBH_openR("tgtS.dbh");
		     create_output(src_node,tgt_node,src_nodeS,tgt_nodeS);
		     printf("trafico: This should never happen!\n");
	     } else {
		     src_node=DBH_open("src.dbh");
		     tgt_node=DBH_open("tgt.dbh");	
		     src_nodeS=DBH_open("srcS.dbh");
		     tgt_nodeS=DBH_open("tgtS.dbh");		     
	     }
	   }
         
      } 
      printf("trafico: closing pipe\n");
      pclose (pipe);
     }
     if (src_node) DBH_close(src_node);
     if (tgt_node) DBH_close(tgt_node);
     if (src_nodeS) DBH_close(src_nodeS);
     if (tgt_nodeS) DBH_close(tgt_nodeS);
}