| die letzten Änderungen * Seitenstruktur * Stichwortsuche :


logo_puschin.jpg

Startseite

Knowledge base



Kontakt

Impressum

Knowledge base - C

Knowledge base

14 Benutzer online Druckversion




zurück



C
libpcap Beispiel

Kompilieren des unten genannten Beispiels mit :

# gcc pcmon.c -o pcmon -lpthread -lpcap



pcmon.c :

#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <wait.h>
#include <fcntl.h>

/* tcpdump header (ether.h) defines ETHER_HDRLEN) */
#ifndef ETHER_HDRLEN
#define ETHER_HDRLEN 14
#endif

pthread_t p1, p2;
static int lifeline[2] = { -1, -1 };
static int fd_null = -1;
#define PATH_DEVNULL "/dev/null"

struct timeval diffPitch1;
struct timeval diffPitch2;
struct timeval diffPitch3;
struct timeval diffPitch4;
struct timeval diffPitch5;

struct timeval tv1_mem;
struct timeval tv2_mem;
struct timeval tv3_mem;
struct timeval tv4_mem;
struct timeval tv5_mem;
struct timeval tv_now;

float rate1=0;
float rate2=0;
float rate3=0;
float rate4=0;
float rate5=0;

float netio1=0;
float netio2=0;
float netio3=0;
float netio4=0;
float netio5=0;

float netio_mem1=0;
float netio_mem2=0;
float netio_mem3=0;
float netio_mem4=0;
float netio_mem5=0;

int report=1;
char buffer[200];
char html[4096];
FILE *fd;
int debug=0;

u_int16_t handle_ethernet
        (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char*
        packet);
u_char* handle_IP
        (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char*
        packet);


/*
* Structure of an internet header, naked of options.
*
* Stolen from tcpdump source (thanks tcpdump people)
*
* We declare ip_len and ip_off to be short, rather than u_short
* pragmatically since otherwise unsigned comparisons can result
* against negative integers quite easily, and fail in subtle ways.
*/
struct my_ip {
        u_int8_t        ip_vhl;         /* header length, version */
#define IP_V(ip)        (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip)       ((ip)->ip_vhl & 0x0f)
        u_int8_t        ip_tos;         /* type of service */
        u_int16_t       ip_len;         /* total length */
        u_int16_t       ip_id;          /* identification */
        u_int16_t       ip_off;         /* fragment offset field */
#define IP_DF 0x4000                    /* dont fragment flag */
#define IP_MF 0x2000                    /* more fragments flag */
#define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
        u_int8_t        ip_ttl;         /* time to live */
        u_int8_t        ip_p;           /* protocol */
        u_int16_t       ip_sum;         /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
};

/* looking at ethernet headers */
void my_callback(u_char *args,const struct pcap_pkthdr* pkthdr,const u_char*
        packet)
{
    u_int16_t type = handle_ethernet(args,pkthdr,packet);

    if(type == ETHERTYPE_IP)
    {/* handle IP packet */
        handle_IP(args,pkthdr,packet);
    }else if(type == ETHERTYPE_ARP)
    {/* handle arp packet */
    }
    else if(type == ETHERTYPE_REVARP)
    {/* handle reverse arp packet */
    }
}

u_char* handle_IP
        (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char*
        packet)
{

    const struct my_ip* ip;
    u_int length = pkthdr->len;
//printf("DEBUG : %d\n", length);
    u_int hlen,off,version;
    int i;

    int len;

    /* jump pass the ethernet header */
    ip = (struct my_ip*)(packet + sizeof(struct ether_header));
    length -= sizeof(struct ether_header);

    /* check to see we have a packet of valid length */
    if (length < sizeof(struct my_ip))
    {
        printf("truncated ip %d",length);
        return NULL;
    }

    len     = ntohs(ip->ip_len);
//printf("DEBUG : %d\n", len);
netio1+=len;
netio2+=len;
netio3+=len;
netio4+=len;
netio5+=len;

//printf("debug : %d (%d)\r", netio, ctr);
return NULL;
    hlen    = IP_HL(ip); /* header length */
    version = IP_V(ip);/* ip version */

    /* check version */
    if(version != 4)
    {
      fprintf(stdout,"Unknown version %d\n",version);
      return NULL;
    }

    /* check header length */
    if(hlen < 5 )
    {
        fprintf(stdout,"bad-hlen %d \n",hlen);
    }

    /* see if we have as much packet as we should */
    if(length < len)
        printf("\ntruncated IP - %d bytes missing\n",len - length);

    /* Check to see if we have the first fragment */
    off = ntohs(ip->ip_off);
    if((off & 0x1fff) == 0 )/* aka no 1's in first 13 bits */
    {/* print SOURCE DESTINATION hlen version len offset */
        fprintf(stdout,"IP: ");
        fprintf(stdout,"%s ",
                inet_ntoa(ip->ip_src));
        fprintf(stdout,"%s %d %d %d %d\n",
                inet_ntoa(ip->ip_dst),
                hlen,version,len,off);
    }

    return NULL;
}

/* handle ethernet packets, much of this code gleaned from
* print-ether.c from tcpdump source
*/
u_int16_t handle_ethernet
        (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char*
        packet)
{
    u_int caplen = pkthdr->caplen;
    u_int length = pkthdr->len;
//printf("DEBUG : %d\n", length);
    struct ether_header *eptr;  /* net/ethernet.h */
    u_short ether_type;

    if (caplen < ETHER_HDRLEN)
    {
        fprintf(stdout,"Packet length less than ethernet header length\n");
        return -1;
    }

    /* lets start with the ether header... */
    eptr = (struct ether_header *) packet;
    ether_type = ntohs(eptr->ether_type);

    /* Lets print SOURCE DEST TYPE LENGTH */
/*
    fprintf(stdout,"ETH: ");
    fprintf(stdout,"%s "
            ,ether_ntoa((struct ether_addr*)eptr->ether_shost));
    fprintf(stdout,"%s "
            ,ether_ntoa((struct ether_addr*)eptr->ether_dhost));
*/
    /* check to see if we have an ip packet */
/*
    if (ether_type == ETHERTYPE_IP)
    {
        fprintf(stdout,"(IP)");
    }else  if (ether_type == ETHERTYPE_ARP)
    {
        fprintf(stdout,"(ARP)");
    }else  if (eptr->ether_type == ETHERTYPE_REVARP)
    {
        fprintf(stdout,"(RARP)");
    }else {
        fprintf(stdout,"(?)");
    }
    fprintf(stdout," %d\n",length);
*/

    return ether_type;
}

void *print_char (void *ch)
{
  for (;;) {
    gettimeofday(&tv_now, NULL);

    diffPitch1.tv_sec=tv_now.tv_sec-tv1_mem.tv_sec;
    diffPitch2.tv_sec=tv_now.tv_sec-tv2_mem.tv_sec;
    diffPitch3.tv_sec=tv_now.tv_sec-tv3_mem.tv_sec;
    diffPitch4.tv_sec=tv_now.tv_sec-tv4_mem.tv_sec;
    diffPitch5.tv_sec=tv_now.tv_sec-tv5_mem.tv_sec;

    // Wenn mehr als eine Sekunde vergangen, dann rate1 berechnen
    if (diffPitch1.tv_sec>5) {
                rate1=netio1/diffPitch1.tv_sec/1024;
                if (debug==1) { printf("=> %f / %d / 1024 = %f\n", netio1, diffPitch1.tv_sec, rate1); }
                netio_mem1=netio1;
                netio1=0;
                report=1;
                gettimeofday(&tv1_mem, NULL);
    }

    if (diffPitch2.tv_sec>60) {
                rate2=netio2/diffPitch2.tv_sec/1024;
                if (debug==1) { printf("=> %f / %d / 1024 = %f\n", netio2, diffPitch2.tv_sec, rate2); }
                netio_mem2=netio2;
                netio2=0;
                report=1;
                gettimeofday(&tv2_mem, NULL);
    }


    if (diffPitch3.tv_sec>300) {
                rate3=netio3/diffPitch3.tv_sec/1024;
                if (debug==1) { printf("=> %f / %d / 1024 = %f\n", netio3, diffPitch3.tv_sec, rate3); }
                netio_mem3=netio3;
                netio3=0;
                report=1;
                gettimeofday(&tv3_mem, NULL);
    }

    if (diffPitch4.tv_sec>3600) {
                rate4=netio4/diffPitch4.tv_sec/1024;
                if (debug==1) { printf("=> %f / %d / 1024 = %f\n", netio4, diffPitch4.tv_sec, rate4); }
                netio_mem4=netio4;
                netio4=0;
                report=1;
                gettimeofday(&tv4_mem, NULL);
    }

    if (diffPitch5.tv_sec>86400) {
                rate5=netio5/diffPitch5.tv_sec/1024;
                if (debug==1) { printf("=> %f / %d / 1024 = %f\n", netio5, diffPitch5.tv_sec, rate5); }
                netio_mem5=netio5;
                netio5=0;
                report=1;
                gettimeofday(&tv5_mem, NULL);
    }

    if (report==1) {
        sprintf(html, "<table cellspacing=10>\n\
<tr><td><b>Zeitraum</td><td><b>kbyte/s</td><td><b>Pakete</td></tr>\n \
<tr><td>5 Sekunden&nbsp;&nbsp;</td><td>%f kbytes/s</td><td>%d</td></tr>\n \
<tr><td>1 Minute</td><td>%f kbytes/s</td><td>%d</td></tr>\n \
<tr><td>5 Minuten</td><td>%f kbytes/s</td><td>%d</td></tr>\n \
<tr><td>1 Stunde</td><td>%f kbytes/s</td><td>%d</td></tr>\n \
<tr><td>1 Tag</td><td>%f kbytes/s</td><td>%d</td></tr>\n \
</table>\n", rate1, (int)netio_mem1, rate2, (int)netio_mem2, rate3, (int)netio_mem3, rate4, (int)netio_mem4, rate5, (int)netio_mem5);

        fd=fopen("pcmon.html", "w");
        fwrite(html, strlen(html), 1, fd);
        fclose(fd);

        report=0;
    }
    usleep(500000);
  }
}

void
daemonize_start(void)
{
   pid_t f, w;

   if (pipe(lifeline) == -1)
      err(1, "pipe(lifeline)");

   fd_null = open(PATH_DEVNULL, O_RDWR, 0);
   if (fd_null == -1)
      err(1, "open(" PATH_DEVNULL ")");

   f = fork();
   if (f == -1)
      err(1, "fork");
   else if (f != 0) {
      /* parent: wait for child */
      char tmp[1];
      int status;

      printf("=> parent waiting\n");
      if (close(lifeline[1]) == -1)
         printf("! close lifeline in parent\n");
      read(lifeline[0], tmp, sizeof(tmp));
      printf("=> parent done reading, calling waitpid\n");
      w = waitpid(f, &status, WNOHANG);
      printf("=> waitpid ret %d, status is %d\n", w, status);
      if (w == -1)
         err(1, "waitpid");
      else if (w == 0)
         /* child is running happily */
         exit(EXIT_SUCCESS);
      else
         /* child init failed, pass on its exit status */
         exit(WEXITSTATUS(status));
   }
   /* else we are the child: continue initializing */
}

void
daemonize_finish(void)
{
   if (fd_null == -1)
      return; /* didn't daemonize_start(), i.e. we're not daemonizing */

   if (setsid() == -1)
      err(1, "setsid");
   if (close(lifeline[0]) == -1)
      warn("close read end of lifeline in child");
   if (close(lifeline[1]) == -1)
      warn("couldn't cut the lifeline");

   /* close all our std fds */
   if (dup2(fd_null, STDIN_FILENO) == -1)
      warn("dup2(stdin)");
   if (dup2(fd_null, STDOUT_FILENO) == -1)
      warn("dup2(stdout)");
   if (dup2(fd_null, STDERR_FILENO) == -1)
      warn("dup2(stderr)");
   if (fd_null > 2)
      close(fd_null);
}

int main(int argc,char **argv)
{
    char *dev;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    struct bpf_program fp;      /* hold compiled program     */
    bpf_u_int32 maskp;          /* subnet mask               */
    bpf_u_int32 netp;           /* ip                        */
    u_char* args = NULL;

        printf("============================================\n");
        printf("pcmon - Traffic Monitor Plugin for darkstat3\n");
        printf("              27.01.2007 -  fp\n");
        printf("============================================\n");


    /* Options must be passed in as a string because I am lazy */
    if(argc < 2){
        fprintf(stdout,"Usage: %s interface [\"options\"] [debug]\n",argv[0]);
        return 0;
    }

    /* grab a device to peak into... */
    dev = pcap_lookupdev(errbuf);
    sprintf(dev,argv[1]);
    if(dev == NULL)
    { printf("%s\n",errbuf); exit(1); }

  /* print out device name */
    /* ask pcap for the network address and mask of the device */
    //pcap_lookupnet(dev,&netp,&maskp,errbuf);

    /* open device for reading. NOTE: defaulting to
     * promiscuous mode*/
    descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
    if(descr == NULL)
    { printf("pcap_open_live(): %s\n",errbuf); exit(1); }

    if(argc > 2)
    {
        /* Lets try and compile the program.. non-optimized */
        if(pcap_compile(descr,&fp,argv[2],0,netp) == -1)
        { fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }

        /* set the compiled program as the filter */
        if(pcap_setfilter(descr,&fp) == -1)
        { fprintf(stderr,"Error setting filter\n"); exit(1); }
    }

    if (argc>3) {
        if (strncmp(argv[3],"debug",5)==0) {
                debug=1;
        }
    }

    if (debug==0) { daemonize_start(); }

    /* ... and loop */
    //pcap_loop(descr,atoi(argv[2]),my_callback,args);
    gettimeofday(&tv1_mem, NULL);
    gettimeofday(&tv2_mem, NULL);
    gettimeofday(&tv3_mem, NULL);
    gettimeofday(&tv4_mem, NULL);
    gettimeofday(&tv5_mem, NULL);

    char ch1='-';
    pthread_create (&p1, NULL, print_char, &ch1);

    daemonize_finish();

    pcap_loop(descr,-1,my_callback,args);

    return 0;
}


zurück



Knowledge base wurde zuletzt bearbeitet am 12.07.13 durch Frank

www.puschin.de
login

<body bgcolor='#FFFFFF' link='#000000' vlink='#000000' alink='#000000' text='#000000'><font face='Verdana' size='2'><strong>www.puschin.de</strong><br>Die Webseite http://www.puschin.de bietet eine interessante Webseite zu vielen Themen aus dem Bereich Linux und Windows. Man findet hier Tipps und Tricks zu cms php apache postfix openxchange tomcat windows linux firewall <br><br><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=191'>Startseite</a><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=63'>Knowledge base</a><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=57'>Kontakt</a><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=9'>Impressum</a></body>