"Fossies" - the Fresh Open Source Software Archive

Member "tcpflow-1.6.1/src/be13_api/pcap_fake.cpp" (19 Feb 2021, 6802 Bytes) of package /linux/misc/tcpflow-1.6.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pcap_fake.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.5_vs_1.5.0.

    1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
    2 
    3 #include "config.h"
    4 
    5 #ifndef HAVE_LIBPCAP
    6 #include "pcap_fake.h"
    7 
    8 #include <fcntl.h>
    9 #include <string.h>
   10 #include <errno.h>
   11 #include <stdlib.h>
   12 #include <iostream>
   13 
   14 #ifdef WIN32
   15 #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
   16 #else
   17 #define SET_BINMODE(f) /* ignore */
   18 #endif
   19 
   20 
   21 /* pcap_fake's struct pcap just keeps track of the file that was opened and
   22  * whether or not it was byteswapped.
   23  */
   24 struct pcap {
   25     FILE *fp;                   // input file we are reading from
   26     int    swapped;                     // whether magic number was swapped?
   27     uint32_t linktype;
   28     bool   error;                       // an error occured
   29     bool   break_loop;                  // break_loop was called
   30     bool   must_close;
   31     char   err_buf[128];
   32     uint8_t *pktbuf;
   33 };
   34 
   35 char *pcap_geterr(pcap_t *p)
   36 {
   37     snprintf(p->err_buf,sizeof(p->err_buf),"not implemented in pcap_fake");
   38     return p->err_buf;
   39 }
   40 
   41 /**
   42  * pcap_open_offline()
   43  * -- "The name "-" is a synonym for stdin" (pcap manual)
   44  * -- allocate the pcap_t structure
   45  * -- open a pcap capture file.
   46  */
   47 pcap_t *pcap_open_offline(const char *fname, char *errbuf)
   48 {
   49     FILE *fp = strcmp(fname,"-")==0 ? stdin : fopen(fname,"rb");
   50     if(!fp){
   51         snprintf(errbuf,PCAP_ERRBUF_SIZE,"%s:%s",fname,strerror(errno));
   52         return 0;
   53     }
   54     pcap_t *p = pcap_fopen_offline(fp,errbuf);
   55     if(p && p->fp!=stdin) p->must_close = true;
   56     return p;
   57 }
   58 
   59 char    *pcap_lookupdev(char *) // not implemented
   60 {
   61     fprintf(stderr,"pcap_fake.cpp:pcap_lookupdev: tcpflow was compiled without LIBPCAP. Will not live capture.\n");
   62     return 0;
   63 }
   64 
   65 pcap_t  *pcap_open_live(const char *, int, int, int, char *)
   66 {
   67     fprintf(stderr,"pcap_fake.cpp:pcap_open_live: tcpflow was compiled without LIBPCAP. Will not live capture.\n");
   68     return 0;
   69 }
   70 
   71 inline uint32_t swap4(uint32_t x) 
   72 {
   73     return (
   74         ((x & 0xff000000) >> 24) |
   75         ((x & 0x00ff0000) >> 8)  |
   76         ((x & 0x0000ff00) << 8)  |
   77         ((x & 0x000000ff) << 24));
   78 }
   79 
   80 inline uint32_t swap2(uint16_t x) 
   81 {
   82     return (
   83         ((x & 0xff00) >> 8)  |
   84         ((x & 0x00ff) << 8));
   85 }
   86 
   87 pcap_t *pcap_fopen_offline(FILE *fp, char *errbuf)
   88 {
   89     SET_BINMODE(fp);
   90     bool swapped = false;
   91     struct pcap_file_header header;
   92     if(fread(&header,sizeof(header),1,fp)!=1){
   93         snprintf(errbuf,PCAP_ERRBUF_SIZE,"Cannot read pcap header");
   94         return 0; // cannot read header
   95     }
   96     if(header.magic==0xd4c3b2a1){                       // check for swap
   97         header.magic = swap4(header.magic);
   98         header.version_major = swap2(header.version_major);
   99         header.version_minor = swap2(header.version_minor);
  100         header.thiszone      = swap4(header.thiszone);
  101         header.sigfigs       = swap4(header.sigfigs);
  102         header.snaplen       = swap4(header.snaplen);
  103         header.linktype      = swap4(header.linktype);
  104         swapped = true;
  105 
  106     }
  107     if(header.magic != 0xa1b2c3d4){
  108         snprintf(errbuf,
  109                  PCAP_ERRBUF_SIZE,"Cannot decode pcap header 0x%x; swapped=%d",
  110                  header.magic,swapped);
  111         return 0;
  112     }
  113     if(header.version_major!=PCAP_VERSION_MAJOR || header.version_minor!=PCAP_VERSION_MINOR){
  114         snprintf(errbuf,
  115                  PCAP_ERRBUF_SIZE,"Cannot read pcap version %d.%d",
  116                  header.version_major,header.version_minor);
  117         return 0;
  118     }
  119 
  120     pcap_t *ret = (pcap_t *)calloc(1,sizeof(pcap_t));
  121     if(ret==0){
  122         snprintf(errbuf,
  123                  PCAP_ERRBUF_SIZE,"Cannot calloc %u bytes",(unsigned int)sizeof(pcap_t));
  124         return 0;
  125     }
  126     ret->pktbuf  = (uint8_t *)malloc(header.snaplen);
  127     if(ret->pktbuf==0) { // did we get the snaplen?
  128         std::cerr << "Couldn't get header snaplen";
  129         free(ret);                      
  130         return 0;
  131     }
  132     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.magic = %x", header.magic);
  133     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.version_major = %d", header.version_major);
  134     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.version_minor = %d", header.version_minor);
  135     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.thiszone = %d", header.thiszone);
  136     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.sigfigs = %d", header.sigfigs);
  137     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.snaplen = %d", header.snaplen);
  138     //DEBUG(100) ("pcap_fake.cpp DEBUG: header.linktype = %d",header.linktype);
  139     //DEBUG(100) ("pcap_fake.cpp DEBUG: ret->pktbuf = %s". ret->pktbuf);
  140     ret->fp      = fp;
  141     ret->swapped = swapped;
  142     ret->linktype = header.linktype;
  143     return ret;
  144 }       
  145 
  146 /*
  147  * These are not implemented in pcap_fake
  148  */
  149 
  150 int pcap_compile(pcap_t *p, struct bpf_program *program,
  151                  const char *expression, int optimize, uint32_t mask) {
  152     if(strlen(expression)==0){
  153         program->valid = true;
  154         return 0;       // we can compile the empty expression
  155     }
  156     return -1;                          // we cannot compile otherwise
  157 }
  158 
  159 int pcap_datalink(pcap_t *p) {
  160     return p->linktype;
  161 }
  162 
  163 int pcap_setfilter(pcap_t *p, struct bpf_program *prog) {
  164     if(prog->valid) return 0;
  165     return -1;
  166 }
  167 
  168 
  169 int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, uint8_t *user)
  170 {
  171     while(cnt !=0 && !feof(p->fp) && p->break_loop==false){
  172         uint32_t tv_sec;
  173         uint32_t tv_usec;
  174 
  175         struct pcap_pkthdr hdr;
  176 
  177         /* Note: struct timeval is 16 bytes on MacOS and not 8 bytes,
  178          * so we manually read and set up the structure
  179          */
  180         if(fread(&tv_sec,sizeof(uint32_t),1,p->fp)!=1) break;
  181         if(fread(&tv_usec,sizeof(uint32_t),1,p->fp)!=1) break;
  182         hdr.ts.tv_sec  = tv_sec;
  183         hdr.ts.tv_usec = tv_usec;
  184         
  185         if(fread(&hdr.caplen,sizeof(uint32_t),1,p->fp)!=1) break;
  186         if(fread(&hdr.len,sizeof(uint32_t),1,p->fp)!=1) break;
  187 
  188         /* Swap the header if necessary */
  189         if(p->swapped){
  190             hdr.ts.tv_sec = swap4(hdr.ts.tv_sec);
  191             hdr.ts.tv_usec = swap4(hdr.ts.tv_usec);
  192             hdr.caplen  = swap4(hdr.caplen);
  193             hdr.len  = swap4(hdr.len);
  194         }
  195 
  196         /* Read the packet */
  197         if(fread(p->pktbuf,hdr.caplen,1,p->fp)!=1) break; // no more to read
  198 
  199         //DEBUG(100) ("pcap_fake: read tv_sec.tv_usec=%d.%06d  caplen=%d  len=%d",
  200         // (int)hdr.ts.tv_sec,(int)hdr.ts.tv_usec,hdr.caplen,hdr.len);
  201 
  202         /* Process the packet */
  203         (*callback)(user,&hdr,p->pktbuf);
  204 
  205 
  206 
  207         /* And loop */
  208         if(cnt>0) cnt--;                // decrease the packet count
  209     }
  210     return 0;
  211 }
  212 
  213 void pcap_break_loop(pcap_t *p)
  214 {
  215     p->break_loop=true;
  216 }
  217 
  218 void    pcap_close(pcap_t *p)                     // close the file
  219 {
  220     if(p->must_close) fclose(p->fp);
  221     free(p->pktbuf);
  222     free(p);
  223 }
  224 
  225 
  226 #endif