"Fossies" - the Fresh Open Source Software Archive

Member "ettercap-0.8.3.1/utils/etterlog/el_log.c" (1 Aug 2020, 11722 Bytes) of package /linux/privat/ettercap-0.8.3.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 "el_log.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.8.3_vs_0.8.3.1.

    1 /*
    2     etterlog -- read the logfile
    3 
    4     Copyright (C) ALoR & NaGA
    5 
    6     This program is free software; you can redistribute it and/or modify
    7     it under the terms of the GNU General Public License as published by
    8     the Free Software Foundation; either version 2 of the License, or
    9     (at your option) any later version.
   10 
   11     This program is distributed in the hope that it will be useful,
   12     but WITHOUT ANY WARRANTY; without even the implied warranty of
   13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14     GNU General Public License for more details.
   15 
   16     You should have received a copy of the GNU General Public License
   17     along with this program; if not, write to the Free Software
   18     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   19 
   20 */
   21 
   22 #include <el.h>
   23 #include <ec_log.h>
   24 
   25 void open_log(char *file);
   26 int get_header(struct log_global_header *hdr);
   27 int get_packet(struct log_header_packet *pck, u_char **buf);
   28 int get_info(struct log_header_info *inf, struct dissector_info *buf);
   29 static int put_header(gzFile fd, struct log_global_header *hdr);
   30 static int put_packet(gzFile fd, struct log_header_packet *pck, u_char *buf);
   31 static int put_info(gzFile fd, struct log_header_info *inf, struct dissector_info *buf);
   32 void concatenate(int argc, char **argv);
   33 static void dump_file(gzFile fd, struct log_global_header *hdr);
   34 
   35 /*******************************************/
   36 
   37 /* 
   38  * open the logfile, then drop the privs
   39  */
   40 
   41 void open_log(char *file)
   42 {
   43    int zerr;
   44    
   45    EL_GBL_LOGFILE = strdup(file);
   46    EL_GBL_LOG_FD = gzopen(file, "rb");
   47    if(EL_GBL_LOG_FD == Z_NULL)
   48       FATAL_ERROR("Cannot read the log file, please ensure you have enough permissions to read %s: error %s", file, gzerror(EL_GBL_LOG_FD, &zerr));
   49 }
   50 
   51 /*
   52  * returns the global header 
   53  */
   54 
   55 int get_header(struct log_global_header *hdr)
   56 {
   57    int c;
   58 
   59    c = gzread(EL_GBL_LOG_FD, hdr, sizeof(struct log_global_header));
   60 
   61    if (c != sizeof(struct log_global_header))
   62       return -E_INVALID;
   63    
   64    /* convert to host order */
   65    
   66    hdr->magic = ntohs(hdr->magic);
   67    
   68    if (hdr->magic != EC_LOG_MAGIC)
   69       return -E_INVALID;
   70    
   71    hdr->first_header = ntohs(hdr->first_header);
   72    gzseek(EL_GBL_LOG_FD, hdr->first_header, SEEK_SET);
   73   
   74    /* adjust the timestamp */
   75    hdr->tv.tv_sec = ntohl(hdr->tv.tv_sec);
   76    hdr->tv.tv_usec = ntohl(hdr->tv.tv_usec);
   77    
   78    hdr->type = ntohl(hdr->type);
   79    
   80    return E_SUCCESS;
   81 }
   82 
   83 /*
   84  * store the header in a file
   85  */
   86 static int put_header(gzFile fd, struct log_global_header *hdr)
   87 {
   88    int c;
   89 
   90    /* convert to network order */
   91    hdr->magic = htons(hdr->magic);
   92    hdr->first_header = htons(hdr->first_header);
   93    hdr->tv.tv_sec = htonl(hdr->tv.tv_sec);
   94    hdr->tv.tv_usec = htonl(hdr->tv.tv_usec);
   95    hdr->type = htonl(hdr->type);
   96    
   97    c = gzwrite(fd, hdr, sizeof(struct log_global_header));
   98    if (c != sizeof(struct log_global_header))
   99       FATAL_ERROR("Cannot write output file");
  100    
  101    /* convert to host order */
  102    hdr->magic = ntohs(hdr->magic);
  103    hdr->first_header = ntohs(hdr->first_header);
  104    hdr->tv.tv_sec = ntohl(hdr->tv.tv_sec);
  105    hdr->tv.tv_usec = ntohl(hdr->tv.tv_usec);
  106    hdr->type = ntohl(hdr->type);
  107    
  108    return E_SUCCESS;
  109 }
  110 
  111 
  112 /*
  113  * read the header of a packet
  114  * and return the data in the buf
  115  */
  116 int get_packet(struct log_header_packet *pck, u_char **buf)
  117 {
  118    int c;
  119 
  120    c = gzread(EL_GBL_LOG_FD, pck, sizeof(struct log_header_packet));
  121 
  122    if (c != sizeof(struct log_header_packet))
  123       return -E_INVALID;
  124    
  125    pck->len = ntohl(pck->len);
  126   
  127    /* adjust the timestamp */
  128    pck->tv.tv_sec = ntohl(pck->tv.tv_sec);
  129    pck->tv.tv_usec = ntohl(pck->tv.tv_usec);
  130  
  131    /* allocate the memory for the buffer */
  132    SAFE_CALLOC(*buf, pck->len, sizeof(u_char));
  133 
  134    /* copy the data of the packet */
  135    c = gzread(EL_GBL_LOG_FD, *buf, pck->len);
  136    
  137    if ((size_t)c != pck->len)
  138       return -E_INVALID;
  139    
  140    return E_SUCCESS;
  141 }
  142 
  143 /*
  144  * store a packet into a file
  145  */
  146 static int put_packet(gzFile fd, struct log_header_packet *pck, u_char *buf)
  147 {
  148    int c;
  149    
  150    pck->len = htonl(pck->len);
  151    pck->tv.tv_sec = htonl(pck->tv.tv_sec);
  152    pck->tv.tv_usec = htonl(pck->tv.tv_usec);
  153 
  154    c = gzwrite(fd, pck, sizeof(struct log_header_packet));
  155    if (c != sizeof(struct log_header_packet))
  156       return -E_INVALID;
  157    
  158    pck->len = ntohl(pck->len);
  159    pck->tv.tv_sec = ntohl(pck->tv.tv_sec);
  160    pck->tv.tv_usec = ntohl(pck->tv.tv_usec);
  161 
  162    /* copy the data of the packet */
  163    c = gzwrite(fd, buf, pck->len);
  164    if ((size_t)c != pck->len)
  165       return -E_INVALID;
  166    
  167    return E_SUCCESS;
  168 }
  169 
  170 /*
  171  * read the header for the info and
  172  * return the user, pass ecc in buf
  173  */
  174 int get_info(struct log_header_info *inf, struct dissector_info *buf)
  175 {
  176    int c;
  177 
  178    /* get the whole header */
  179    c = gzread(EL_GBL_LOG_FD, inf, sizeof(struct log_header_info));
  180 
  181    /* truncated ? */
  182    if (c != sizeof(struct log_header_info))
  183       return -E_INVALID;
  184 
  185    /* adjust the variable lengths */
  186    inf->var.user_len = ntohs(inf->var.user_len);
  187    inf->var.pass_len = ntohs(inf->var.pass_len);
  188    inf->var.info_len = ntohs(inf->var.info_len);
  189    inf->var.banner_len = ntohs(inf->var.banner_len);
  190 
  191    /* 
  192     * get the dissectors info
  193     *
  194     * we can deal only with associated user and pass,
  195     * so there must be present all of them
  196     */
  197 
  198    if (inf->var.user_len) {
  199       SAFE_CALLOC(buf->user, inf->var.user_len + 1, sizeof(char));
  200       
  201       c = gzread(EL_GBL_LOG_FD, buf->user, inf->var.user_len);
  202       if (c != inf->var.user_len)
  203          return -E_INVALID;
  204    }
  205    
  206    if (inf->var.pass_len) {
  207       SAFE_CALLOC(buf->pass, inf->var.pass_len + 1, sizeof(char));
  208       
  209       c = gzread(EL_GBL_LOG_FD, buf->pass, inf->var.pass_len);
  210       if (c != inf->var.pass_len)
  211          return -E_INVALID;
  212    }
  213    
  214    if (inf->var.info_len) {
  215       SAFE_CALLOC(buf->info, inf->var.info_len + 1, sizeof(char));
  216       
  217       c = gzread(EL_GBL_LOG_FD, buf->info, inf->var.info_len);
  218       if (c != inf->var.info_len)
  219          return -E_INVALID;
  220    }
  221    
  222    if (inf->var.banner_len) {
  223       SAFE_CALLOC(buf->banner, inf->var.banner_len + 1, sizeof(char));
  224       
  225       c = gzread(EL_GBL_LOG_FD, buf->banner, inf->var.banner_len);
  226       if (c != inf->var.banner_len)
  227          return -E_INVALID;
  228    }
  229 
  230    /*
  231     * sanity check for ip_addr struct
  232     */
  233    switch (ntohs(inf->L3_addr.addr_type)) {
  234       case AF_INET:
  235          if (ntohs(inf->L3_addr.addr_len) != IP_ADDR_LEN)
  236             return -E_INVALID;
  237          break;
  238       case AF_INET6:
  239          if (ntohs(inf->L3_addr.addr_len) != IP6_ADDR_LEN)
  240             return -E_INVALID;
  241          break;
  242       default:
  243          return -E_INVALID;
  244    }
  245 
  246    /* if client IP address has been set otherwise skip */
  247    if (!ip_addr_is_zero(&inf->client)) {
  248       switch (ntohs(inf->client.addr_type)) {
  249          case AF_INET:
  250             if (ntohs(inf->client.addr_len) != IP_ADDR_LEN)
  251                return -E_INVALID;
  252             break;
  253          case AF_INET6:
  254             if (ntohs(inf->client.addr_len) != IP6_ADDR_LEN)
  255                return -E_INVALID;
  256             break;
  257          default:
  258             return -E_INVALID;
  259       }
  260    }
  261 
  262 
  263    return E_SUCCESS; 
  264 }
  265 
  266 /*
  267  * store a info struct into a file 
  268  */
  269 static int put_info(gzFile fd, struct log_header_info *inf, struct dissector_info *buf)
  270 {
  271    int c;
  272 
  273    /* adjust the variable lengths */
  274    inf->var.user_len = htons(inf->var.user_len);
  275    inf->var.pass_len = htons(inf->var.pass_len);
  276    inf->var.info_len = htons(inf->var.info_len);
  277    inf->var.banner_len = htons(inf->var.banner_len);
  278    
  279    /* write the header */
  280    c = gzwrite(fd, inf, sizeof(struct log_header_info));
  281    if (c != sizeof(struct log_header_info))
  282       return -E_INVALID;
  283 
  284    /* reconvert for internal use */
  285    inf->var.user_len = ntohs(inf->var.user_len);
  286    inf->var.pass_len = ntohs(inf->var.pass_len);
  287    inf->var.info_len = ntohs(inf->var.info_len);
  288    inf->var.banner_len = ntohs(inf->var.banner_len);
  289 
  290    /* write the data */
  291    if (inf->var.user_len) {
  292       c = gzwrite(fd, buf->user, inf->var.user_len);
  293       if (c != inf->var.user_len)
  294          return -E_INVALID;
  295    }
  296    
  297    if (inf->var.pass_len) {
  298       c = gzwrite(fd, buf->pass, inf->var.pass_len);
  299       if (c != inf->var.pass_len)
  300          return -E_INVALID;
  301    }
  302    
  303    if (inf->var.info_len) {
  304       c = gzwrite(fd, buf->info, inf->var.info_len);
  305       if (c != inf->var.info_len)
  306          return -E_INVALID;
  307    }
  308    
  309    if (inf->var.banner_len) {
  310       c = gzwrite(fd, buf->banner, inf->var.banner_len);
  311       if (c != inf->var.banner_len)
  312          return -E_INVALID;
  313    }
  314    
  315    return E_SUCCESS; 
  316 }
  317 
  318 /*
  319  * concatenate two (or more) files into one single file 
  320  */
  321 void concatenate(int argc, char **argv)
  322 {
  323    int zerr;
  324    gzFile fd;
  325    struct log_global_header hdr, tmp;
  326 
  327    memset(&hdr, 0, sizeof(struct log_global_header));
  328 
  329    /* open the output file for writing */
  330    fd = gzopen(EL_GBL_LOGFILE, "wb");
  331    ON_ERROR(fd, NULL, "%s", gzerror(fd, &zerr));
  332 
  333    /* 
  334     * use EL_GBL_LOG_FD here so the get_header function
  335     * will use this file 
  336     */
  337    EL_GBL_LOG_FD = gzopen(argv[argc], "rb");
  338    ON_ERROR(EL_GBL_LOG_FD, NULL, "%s", gzerror(EL_GBL_LOG_FD, &zerr));
  339    
  340    /* get the file header */
  341    if (get_header(&hdr) != E_SUCCESS)
  342       FATAL_ERROR("Invalid log file (%s)", argv[argc]);
  343 
  344    /* write the header */
  345    put_header(fd, &hdr);
  346       
  347    USER_MSG("Concatenating file [%s]", argv[argc]);
  348    
  349    /* copy the first file into the output */
  350    dump_file(fd, &hdr);
  351      
  352    /* move the pointer to the next file */
  353    argc++;
  354    
  355    /* cicle thru the file list */
  356    while(argv[argc] != NULL) {
  357    
  358       EL_GBL_LOG_FD = gzopen(argv[argc], "rb");
  359       ON_ERROR(EL_GBL_LOG_FD, NULL, "%s", gzerror(EL_GBL_LOG_FD, &zerr));
  360    
  361       /* get the file header */
  362       if (get_header(&tmp) != E_SUCCESS)
  363          FATAL_ERROR("Invalid log file (%s)", argv[argc]);
  364      
  365       /* check if the files are compatible */
  366       if (hdr.type != tmp.type)
  367          FATAL_ERROR("Cannot concatenate different type of file");
  368 
  369       USER_MSG("Concatenating file [%s]", argv[argc]);
  370       
  371       /* concatenate this file */
  372       dump_file(fd, &tmp);
  373 
  374       gzclose(EL_GBL_LOG_FD);
  375       argc++;
  376    }
  377 
  378    gzclose(fd);
  379 
  380    USER_MSG("\nAll files concatenated into: %s\n\n", EL_GBL_LOGFILE);
  381 
  382    el_exit(0);
  383 }
  384 
  385 
  386 /*
  387  * dump the file into the fd
  388  */
  389 static void dump_file(gzFile fd, struct log_global_header *hdr)
  390 {
  391    struct log_header_packet pck;
  392    struct log_header_info inf;
  393    struct dissector_info infbuf;
  394    u_char *pckbuf;
  395    int count = 0;
  396 
  397 
  398    memset(&pck,0,sizeof(struct log_header_packet));
  399    memset(&inf,0,sizeof(struct log_header_info));
  400    memset(&infbuf,0,sizeof(struct dissector_info));
  401 
  402    /* loop until EOF */
  403    LOOP {
  404       switch (hdr->type) {
  405          case LOG_INFO:
  406             if (get_info(&inf, &infbuf) != E_SUCCESS) {
  407                USER_MSG("\n");
  408                return;
  409             }
  410             /* write the info */
  411             put_info(fd, &inf, &infbuf);
  412             SAFE_FREE(infbuf.user);
  413             SAFE_FREE(infbuf.pass);
  414             SAFE_FREE(infbuf.info);
  415             SAFE_FREE(infbuf.banner);
  416 
  417             break;
  418 
  419          case LOG_PACKET:
  420             if (get_packet(&pck, &pckbuf) != E_SUCCESS) {
  421                USER_MSG("\n");
  422                return;
  423             }
  424             /* write the data */
  425             put_packet(fd, &pck, pckbuf);
  426             SAFE_FREE(pckbuf);
  427             break;
  428             
  429          default:
  430             FATAL_ERROR("Unknown log type");
  431             break;
  432       }
  433       
  434       /* a dot every 10 packets */
  435       if (count++ % 10 == 0) {
  436          USER_MSG(".");
  437          fflush(stdout);
  438       }
  439    }
  440 
  441 }
  442 
  443 
  444 /* EOF */
  445 
  446 // vim:ts=3:expandtab
  447