"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/tools/u2streamer/Unified2File.c" (16 Oct 2020, 11371 Bytes) of package /linux/misc/snort-2.9.17.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 "Unified2File.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 
    2 /* System includes */
    3 #include <sys/types.h>
    4 #ifdef LINUX
    5 #include <stdint.h>
    6 #endif
    7 #include <stdlib.h>
    8 #include <unistd.h>
    9 #include <sys/stat.h>
   10 #include <fcntl.h>
   11 #include <unistd.h>
   12 #include <stdio.h>
   13 #include <netinet/in.h>
   14 #include <string.h>
   15 #include <errno.h>
   16 #include <fcntl.h>
   17 
   18 /* Sourcefire includes */
   19 #include <sf_error.h>
   20 #include <TimestampedFile.h>
   21 
   22 /* Local includes */
   23 #include "Unified2.h"
   24 #include "Unified2File.h"
   25 
   26 #define U2FILE_STATUS_NOT_READY                 0
   27 #define U2FILE_STATUS_HEADER_READY              1
   28 #define U2FILE_STATUS_HEADER_PARTIAL            2
   29 #define U2FILE_STATUS_EXTENDED_HEADER_READY     3
   30 #define U2FILE_STATUS_EXTENDED_HEADER_PARTIAL   4
   31 #define U2FILE_STATUS_DATA_READY                5
   32 #define U2FILE_STATUS_DATA_PARTIAL              6
   33 
   34 #ifndef MAX_U2_MESSAGE
   35 #define  MAX_U2_MESSAGE (16*1024*1024)
   36 #endif
   37 #define U2R_EXTENDED_HEADER_BIT 0x80000000
   38 
   39 
   40 /* Unified2 File API **********************************************************/
   41 int Unified2File_Open(char *filepath, Unified2File **u2_file)
   42 {
   43     Unified2File *tmp;
   44 
   45     if(!filepath || !u2_file)
   46         return SF_EINVAL;
   47 
   48     if(!(tmp = (Unified2File *)calloc(1, sizeof(Unified2File))))
   49     {
   50         fprintf(stderr, "Out of memory (wanted %zu bytes)", sizeof(Unified2File));
   51         return SF_ENOMEM;
   52     }
   53 
   54     tmp->fd = -1;
   55     tmp->read_status = U2FILE_STATUS_HEADER_READY;
   56     tmp->read_errno = 0;
   57     tmp->read_offset = 0;
   58     tmp->u2_record = NULL;
   59 
   60     if((tmp->fd = open(filepath, O_RDONLY)) == -1)
   61     {
   62         fprintf(stderr, "Unable to open file '%s': %s",
   63                 filepath, strerror(errno));
   64         free(tmp);
   65         return SF_EOPEN;  /* XXX better return code */
   66     }
   67 
   68     *u2_file = tmp;
   69 
   70     return SF_SUCCESS;
   71 }
   72 
   73 int Unified2File_Close(Unified2File *u2_file)
   74 {
   75     if(!u2_file)
   76         return SF_EINVAL;
   77 
   78     if(u2_file->u2_record)
   79         Unified2Record_Destroy(u2_file->u2_record);
   80     u2_file->u2_record = NULL;
   81 
   82     if(u2_file->fd != -1)
   83         close(u2_file->fd);
   84     u2_file->fd = -1;
   85 
   86     u2_file->read_status = 0;
   87 
   88     free(u2_file);
   89 
   90     return SF_SUCCESS;
   91 }
   92 
   93 
   94 int Unified2File_Read(Unified2File *u2_file, Unified2Record **u2_record)
   95 {
   96     ssize_t bytes_read;
   97     ssize_t bytes_wanted;
   98     int     error_count = 0;
   99 
  100     if(!u2_file || !u2_record)
  101         return SF_EINVAL;
  102 
  103     if(u2_file->read_status == U2FILE_STATUS_NOT_READY)
  104         return SF_EREAD;
  105 
  106     /* allocate a new record */
  107     if(!u2_file->u2_record)
  108     {
  109         /* XXX we should check that we are in the HEADER_READY state */
  110         if(!(u2_file->u2_record = (Unified2Record *)calloc(1,
  111                         sizeof(Unified2Record))))
  112         {
  113             fprintf(stderr, "Out of memory (wanted %zu bytes)",
  114                     sizeof(Unified2Record));
  115             return SF_ENOMEM;
  116         }
  117         u2_file->read_offset = 0;
  118         u2_file->read_status = U2FILE_STATUS_HEADER_READY;
  119     }
  120 
  121     if(u2_file->read_status == U2FILE_STATUS_HEADER_READY
  122             || u2_file->read_status == U2FILE_STATUS_HEADER_PARTIAL)
  123     {
  124 read_again:
  125         /* read the header */
  126         bytes_wanted = sizeof(Serial_Unified2_Header);
  127         bytes_read = read(u2_file->fd,
  128                 ((u_int8_t *)&u2_file->s_u2_hdr) + u2_file->read_offset,
  129                 bytes_wanted - u2_file->read_offset);
  130 
  131         /* end of file **************************/
  132         if(bytes_read == 0)
  133         {
  134             if(u2_file->read_status == U2FILE_STATUS_HEADER_PARTIAL)
  135             {
  136                 fprintf(stderr, "End of file within header");
  137 
  138                 if(errno) return SF_EREAD_TRUNCATED;
  139                 return SF_EREAD_PARTIAL;
  140             }
  141 
  142             //fprintf(stderr, "End of file on record boundary");
  143 
  144             return SF_END_OF_FILE;
  145         }
  146         /* Read error **************************/
  147         if(bytes_read == -1)
  148         {
  149             /* read error */
  150             fprintf(stderr, "Read error: %s",
  151                     strerror(errno));
  152             u2_file->read_errno = errno;
  153             u2_file->read_status = U2FILE_STATUS_NOT_READY;
  154             return SF_EREAD;
  155         }
  156 
  157         /* check for partial read *************/
  158         if(bytes_read + u2_file->read_offset < bytes_wanted)
  159         {
  160             u2_file->read_offset += bytes_read;
  161             u2_file->read_status = U2FILE_STATUS_HEADER_PARTIAL;
  162             fprintf(stderr, "Partial header read (%u of %zu bytes)",
  163                     u2_file->read_offset, bytes_wanted);
  164             return SF_EREAD_PARTIAL;
  165         }
  166 
  167         /* basic header read is complete */
  168 
  169         /* process basic header data */
  170         u2_file->u2_record->type = ntohl(u2_file->s_u2_hdr.type);
  171         u2_file->u2_record->length = ntohl(u2_file->s_u2_hdr.length);
  172         /* XXX we have enough info now to allocate storage for the data */
  173 
  174         if(!u2_file->u2_record->length || (u2_file->u2_record->length >= MAX_U2_MESSAGE))
  175         {
  176             /* Seek back to where we started, in case we want to try again */
  177             off_t rval = lseek(u2_file->fd, (0 - bytes_read), SEEK_CUR);
  178             fprintf(stderr, "Seek backwards %zu bytes, seek returns %ld", bytes_read, rval);
  179 
  180             error_count++;
  181             usleep(100);
  182             if (error_count >= 10)
  183             {
  184                 fprintf(stderr, "Unsupported length: Tried to read (%d bytes - allowed %d) at offset %ld Type %u",
  185                         u2_file->u2_record->length,
  186                         MAX_U2_MESSAGE,
  187                         rval,
  188                         u2_file->u2_record->type & ~U2R_EXTENDED_HEADER_BIT);
  189                 return SF_EBADLEN;
  190             }
  191             else
  192             {
  193                 goto read_again;
  194             }
  195         }
  196 
  197         /* check to see if we have an extended header */
  198         if(u2_file->u2_record->type & U2R_EXTENDED_HEADER_BIT)
  199         {
  200             u2_file->read_status = U2FILE_STATUS_EXTENDED_HEADER_READY;
  201             u2_file->u2_record->type &= ~U2R_EXTENDED_HEADER_BIT;
  202         }
  203         else
  204         {
  205             u2_file->u2_record->timestamp = 0;
  206             u2_file->checksum = 0;
  207             u2_file->read_status = U2FILE_STATUS_DATA_READY;
  208         }
  209 
  210         u2_file->read_offset = 0;
  211     }
  212     if(error_count > 0)
  213     {
  214         fprintf(stderr, "Bogus corrupt file, re-read %d times before file valid.", error_count);
  215     }
  216 
  217     if(u2_file->read_status == U2FILE_STATUS_EXTENDED_HEADER_READY
  218             || u2_file->read_status == U2FILE_STATUS_EXTENDED_HEADER_PARTIAL)
  219     {
  220         /* read the header extensions */
  221         bytes_wanted = sizeof(Serial_Unified2HeaderExtension);
  222         bytes_read = read(u2_file->fd,
  223                 ((u_int8_t *)&u2_file->s_u2_hdr_ext) + u2_file->read_offset,
  224                 bytes_wanted - u2_file->read_offset);
  225 
  226         /* end of file **************************/
  227         if(bytes_read == 0)
  228         {
  229             fprintf(stderr, "End of file within header");
  230 
  231             if(errno) return SF_EREAD_TRUNCATED;
  232             return SF_EREAD_PARTIAL;
  233         }
  234         /* Read error **************************/
  235         if(bytes_read == -1)
  236         {
  237             /* read error */
  238             fprintf(stderr, "Read error: %s",
  239                     strerror(errno));
  240             u2_file->read_errno = errno;
  241             u2_file->read_status = U2FILE_STATUS_NOT_READY;
  242             return SF_EREAD;
  243         }
  244 
  245         /* check for partial read *************/
  246         if(bytes_read + u2_file->read_offset < bytes_wanted)
  247         {
  248             u2_file->read_offset += bytes_read;
  249             u2_file->read_status = U2FILE_STATUS_EXTENDED_HEADER_PARTIAL;
  250             fprintf(stderr, "Partial header read (%u of %zu bytes)",
  251                     u2_file->read_offset, bytes_wanted);
  252             return SF_EREAD_PARTIAL;
  253         }
  254 
  255         /* header extension read complete */
  256         /* process header extenstion data */
  257         //VLAD we do have an extended header?
  258         u2_file->u2_record->timestamp = ntohl(u2_file->s_u2_hdr_ext.timestamp);
  259         u2_file->checksum = ntohl(u2_file->s_u2_hdr_ext.checksum);
  260 
  261         u2_file->read_status = U2FILE_STATUS_DATA_READY;
  262         u2_file->read_offset = 0;
  263     }
  264 
  265     /* we should not have any of these, but just in case */
  266     if(u2_file->u2_record->length == 0)
  267     {
  268         u2_file->read_offset = 0;
  269         u2_file->read_status = U2FILE_STATUS_HEADER_READY;
  270         *u2_record = u2_file->u2_record;
  271         u2_file->u2_record = NULL;
  272         return SF_SUCCESS;
  273     }
  274 
  275     /* XXX some other length sanity checking may be desirable */
  276 
  277     /* read the actual data ***********************/
  278     if(u2_file->read_status == U2FILE_STATUS_DATA_READY
  279             || u2_file->read_status == U2FILE_STATUS_DATA_PARTIAL)
  280     {
  281         /* allocate memory if we have not done so yet */
  282         if(!u2_file->u2_record->data)
  283         {
  284             if(!u2_file->u2_record->length || (u2_file->u2_record->length >= MAX_U2_MESSAGE))
  285             {
  286                 fprintf(stderr, "Unsupported length: Tried to read (%d bytes - allowed %d) Type %u",
  287                        u2_file->u2_record->length,
  288                        MAX_U2_MESSAGE,
  289                        u2_file->u2_record->type & ~U2R_EXTENDED_HEADER_BIT);
  290                 return SF_EBADLEN;
  291             }
  292 
  293             /* allocate the buffer (we could do this earlier) */
  294             if(!(u2_file->u2_record->data = calloc(u2_file->u2_record->length,sizeof(uint8_t))))
  295             {
  296                 fprintf(stderr,"Out of memory (wanted %u bytes)",u2_file->u2_record->length);
  297                 return SF_ENOMEM;
  298                 /* Amazingly enough, this is not a fatal error.  if the user
  299                  * frees up some memory, we can try again
  300                  */
  301             }
  302         }
  303 
  304         /* read the actual data */
  305         bytes_wanted = u2_file->u2_record->length;
  306         bytes_read = read(u2_file->fd,
  307                 ((u_int8_t *)u2_file->u2_record->data) + u2_file->read_offset,
  308                 bytes_wanted - u2_file->read_offset);
  309 
  310         /* end of file **************************/
  311         if(bytes_read == 0)
  312         {
  313             fprintf(stderr, "End of file reading data");
  314 
  315             if(errno) return SF_EREAD_TRUNCATED;
  316             return SF_EREAD_PARTIAL;
  317         }
  318         /* Read error **************************/
  319         if(bytes_read == -1)
  320         {
  321             /* read error */
  322             fprintf(stderr, "Read error: %s",
  323                     strerror(errno));
  324             u2_file->read_errno = errno;
  325             u2_file->read_status = U2FILE_STATUS_NOT_READY;
  326             return SF_EREAD;
  327         }
  328 
  329         /* check for partial read *************/
  330         if(bytes_read + u2_file->read_offset < bytes_wanted)
  331         {
  332             u2_file->read_offset += bytes_read;
  333             u2_file->read_status = U2FILE_STATUS_DATA_PARTIAL;
  334             fprintf(stderr, "Partial header read (%u of %zu bytes)",
  335                     u2_file->read_offset, bytes_wanted);
  336             return SF_EREAD_PARTIAL;
  337         }
  338 
  339         /* data read complete */
  340 
  341         if(u2_file->checksum != 0)
  342         {
  343             /* XXX validation code goes here */
  344         }
  345 
  346         u2_file->read_offset = 0;
  347         u2_file->read_status = U2FILE_STATUS_HEADER_READY;
  348         *u2_record = u2_file->u2_record;
  349         u2_file->u2_record = NULL;
  350         return SF_SUCCESS;
  351     }
  352 
  353     /* We should never get here */
  354     return SF_EINVAL;
  355 }
  356