"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/log.c" (16 Oct 2020, 64741 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 "log.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 /* $Id$ */
    2 /*
    3 ** Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    4 ** Copyright (C) 2002-2013 Sourcefire, Inc.
    5 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
    6 **
    7 ** This program is free software; you can redistribute it and/or modify
    8 ** it under the terms of the GNU General Public License Version 2 as
    9 ** published by the Free Software Foundation.  You may not use, modify or
   10 ** distribute this program under any other version of the GNU General
   11 ** Public License.
   12 **
   13 ** This program is distributed in the hope that it will be useful,
   14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16 ** GNU General Public License for more details.
   17 **
   18 ** You should have received a copy of the GNU General Public License
   19 ** along with this program; if not, write to the Free Software
   20 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   21 */
   22 
   23 #ifdef HAVE_CONFIG_H
   24 #include "config.h"
   25 #endif
   26 
   27 #include <sys/types.h>
   28 #include <stdlib.h>
   29 #include <string.h>
   30 
   31 #ifdef HAVE_STRINGS_H
   32 #include <strings.h>
   33 #endif
   34 
   35 #ifndef WIN32
   36 #include <sys/socket.h>
   37 #include <netinet/in.h>
   38 #include <arpa/inet.h>
   39 #endif /* !WIN32 */
   40 #include <errno.h>
   41 #include <signal.h>
   42 
   43 #include "log.h"
   44 #include "rules.h"
   45 #include "treenodes.h"
   46 #include "util.h"
   47 #include "snort_debug.h"
   48 #include "signature.h"
   49 #include "util_net.h"
   50 #include "snort_bounds.h"
   51 #include "obfuscation.h"
   52 #include "detection_util.h"
   53 #include "detect.h"
   54 
   55 #include "snort.h"
   56 
   57 extern OptTreeNode *otn_tmp;    /* global ptr to current rule data */
   58 
   59 char *data_dump_buffer;     /* printout buffer for PrintNetData */
   60 int data_dump_buffer_size = 0;/* size of printout buffer */
   61 int dump_size;              /* amount of data to print */
   62 
   63 extern int IsGzipData(void *);
   64 extern int IsJSNormData(void *);
   65 void AllocDumpBuf();
   66 
   67 
   68 /***************** LOG ASCII ROUTINES *******************/
   69 
   70 #ifndef NO_NON_ETHER_DECODER
   71 #endif
   72 
   73 /*
   74  * Function: PrintNetData(FILE *, u_char *,int, Packet *)
   75  *
   76  * Purpose: Do a side by side dump of a buffer, hex dump of buffer bytes on
   77  *          the left, decoded ASCII on the right.
   78  *
   79  * Arguments: fp => ptr to stream to print to
   80  *            start => pointer to buffer data
   81  *            len => length of data buffer
   82  *
   83  * Returns: void function
   84  */
   85 void PrintNetData(FILE * fp, const u_char * start, const int len, Packet *p)
   86 {
   87     char *end;          /* ptr to buffer end */
   88     int i;          /* counter */
   89     int j;          /* counter */
   90     int dbuf_size;      /* data buffer size */
   91     int done;           /* flag */
   92     char *data;         /* index pointer */
   93     char *frame_ptr;        /* we use 66 byte frames for a printed line */
   94     char *d_ptr;        /* data pointer into the frame */
   95     char *c_ptr;        /* char pointer into the frame */
   96     char conv[] = "0123456789ABCDEF";   /* xlation lookup table */
   97     int next_layer, ip_start, ip_ob_start, ip_ob_end, byte_pos;
   98 
   99     next_layer = ip_start = byte_pos = 0;
  100 
  101     ip_ob_start = ip_ob_end = -1;
  102 
  103     /* initialization */
  104     done = 0;
  105 
  106    /* zero, print a <CR> and get out */
  107     if(!len)
  108     {
  109         fputc('\n', fp);
  110         return;
  111     }
  112 
  113     if(start == NULL)
  114     {
  115         printf("Got NULL ptr in PrintNetData()\n");
  116         return;
  117     }
  118 
  119     end = (char*) (start + (len - 1));    /* set the end of buffer ptr */
  120 
  121     if(len > IP_MAXPACKET)
  122     {
  123         if (ScLogVerbose())
  124         {
  125             printf("Got bogus buffer length (%d) for PrintNetData, defaulting to 16 bytes!\n", len);
  126         }
  127 
  128         if (ScVerboseByteDump())
  129         {
  130             dbuf_size = (FRAME_SIZE + 8) + (FRAME_SIZE + 8) + 1;
  131         }
  132         else
  133         {
  134             dbuf_size = FRAME_SIZE + FRAME_SIZE + 1;
  135         }
  136 
  137         /* dbuf_size = 66 + 67; */
  138         end =  (char*) (start + 15);
  139     }
  140     else
  141     {
  142         if (ScVerboseByteDump())
  143         {
  144             /* figure out how big the printout data buffer has to be */
  145             dbuf_size = ((len / 16) * (FRAME_SIZE + 8)) + (FRAME_SIZE + 8) + 1;
  146         }
  147         else
  148         {
  149             /* figure out how big the printout data buffer has to be */
  150             dbuf_size = ((len / 16) * FRAME_SIZE) + FRAME_SIZE + 1;
  151         }
  152 
  153         /* dbuf_size = ((len / 16) * 66) + 67; */
  154     }
  155 
  156     /* generate the buffer */
  157     if (data_dump_buffer == NULL)
  158     {
  159         AllocDumpBuf();
  160     }
  161 
  162     if (data_dump_buffer == NULL)
  163         FatalError("Failed allocating %X bytes to data_dump_buffer!\n", data_dump_buffer_size);
  164 
  165     /* clean it out */
  166     memset(data_dump_buffer, 0x20, dbuf_size);
  167 
  168     /* set the byte buffer pointer to step thru the data buffer */
  169     data = (char*) start;
  170 
  171     /* set the frame pointer to the start of the printout buffer */
  172     frame_ptr = data_dump_buffer;
  173 
  174     /* initialize counters and frame index pointers */
  175     i = 0;
  176     j = 0;
  177 
  178     if(p && ScObfuscate() )
  179     {
  180         next_layer =  p->next_layer;
  181         for ( i = 0; i < next_layer; i++ )
  182         {
  183             if ( p->layers[i].proto == PROTO_IP4
  184                   || p->layers[i].proto == PROTO_IP6
  185               )
  186             {
  187                 if(p->layers[i].length && p->layers[i].start)
  188                     break;
  189             }
  190         }
  191         ip_start = p->layers[i].start - start;
  192 
  193         if(ip_start > 0 )
  194         {
  195             ip_ob_start = ip_start + 10;
  196             if(p->layers[i].proto == PROTO_IP4)
  197                 ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in_addr));
  198             else
  199                 ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in6_addr));
  200         }
  201 
  202 
  203         i=0;
  204     }
  205 
  206     /* loop thru the whole buffer */
  207     while(!done)
  208     {
  209         if (ScVerboseByteDump())
  210         {
  211             d_ptr = frame_ptr + 8;
  212             c_ptr = (frame_ptr + 8 + C_OFFSET);
  213             SnortSnprintf(frame_ptr,
  214                           (data_dump_buffer + data_dump_buffer_size) - frame_ptr,
  215                           "0x%04X: ", j);
  216             j += 16;
  217         }
  218         else
  219         {
  220             d_ptr = frame_ptr;
  221             c_ptr = (frame_ptr + C_OFFSET);
  222         }
  223 
  224         /* process 16 bytes per frame */
  225         for(i = 0; i < 16; i++, byte_pos++)
  226         {
  227             if(ScObfuscate() && ((byte_pos >= ip_ob_start) && (byte_pos < ip_ob_end)))
  228             {
  229                 *d_ptr = 'X';
  230                 d_ptr++;
  231                 *d_ptr = 'X';
  232                 d_ptr++;
  233 
  234                 *d_ptr = 0x20;
  235                 d_ptr++;
  236 
  237                 *c_ptr = 'X';
  238 
  239             }
  240             else
  241             {
  242 
  243                 /*
  244                  * look up the ASCII value of the first nybble of the current
  245                  * data buffer
  246                  */
  247                 *d_ptr = conv[((*data & 0xFF) >> 4)];
  248                 d_ptr++;
  249 
  250                 /* look up the second nybble */
  251                 *d_ptr = conv[((*data & 0xFF) & 0x0F)];
  252                 d_ptr++;
  253 
  254                 /* put a space in between */
  255                 *d_ptr = 0x20;
  256                 d_ptr++;
  257 
  258                 /* print out the char equivalent */
  259                 if(*data > 0x1F && *data < 0x7F)
  260                     *c_ptr = (char) (*data & 0xFF);
  261                 else
  262                     *c_ptr = 0x2E;
  263             }
  264 
  265             c_ptr++;
  266 
  267             /* increment the pointer or finish up */
  268             if(data < end)
  269                 data++;
  270             else
  271             {
  272                 *c_ptr = '\n';
  273                 c_ptr++;
  274                 *c_ptr = '\n';
  275                 c_ptr++;
  276                 *c_ptr = 0;
  277 
  278                 dump_size = (int) (c_ptr - data_dump_buffer);
  279                 fwrite(data_dump_buffer, dump_size, 1, fp);
  280 
  281                 //ClearDumpBuf();
  282                 return;
  283             }
  284         }
  285 
  286         *c_ptr = '\n';
  287         if (ScVerboseByteDump())
  288         {
  289             frame_ptr += (FRAME_SIZE + 8);
  290         }
  291         else
  292         {
  293             frame_ptr += FRAME_SIZE;
  294         }
  295     }
  296 
  297     //ClearDumpBuf();
  298 }
  299 
  300 
  301 
  302 /*
  303  * Function: PrintCharData(FILE *, char *,int)
  304  *
  305  * Purpose: Dump the ASCII data from a packet
  306  *          the left, decoded ASCII on the right.
  307  *
  308  * Arguments: fp => ptr to stream to print to
  309  *            data => pointer to buffer data
  310  *            data_len => length of data buffer
  311  *
  312  * Returns: void function
  313  */
  314 void PrintCharData(FILE * fp, const char *data, int data_len)
  315 {
  316     int bytes_processed;    /* count of bytes in the data buffer
  317                  * processed so far */
  318     int linecount = 0;      /* number of lines in this dump */
  319     const char *index;        /* index pointer into the data buffer */
  320     char *ddb_ptr;      /* index pointer into the data_dump_buffer */
  321     int size;
  322 
  323     /* if there's no data, return */
  324     if(data == NULL)
  325     {
  326         return;
  327     }
  328 
  329     /* setup the pointers and counters */
  330     bytes_processed = data_len;
  331     index = data;
  332 
  333     /* allocate a buffer to print the data to */
  334     //data_dump_buffer = (char *) calloc(data_len + (data_len >> 6) + 2, sizeof(char));
  335     if (data_dump_buffer == NULL)
  336     {
  337         AllocDumpBuf();
  338     }
  339 
  340     size = (data_len + (data_len >> 6) + 2) * sizeof(char);
  341 
  342     /* Based on data_len < 65535, this should never happen, but check just in
  343      * case sizeof(char) is big or something. */
  344     if (data_dump_buffer_size < size)
  345     {
  346         data_dump_buffer_size = size;
  347         ClearDumpBuf();
  348 
  349         /* Reallocate for a bigger size. */
  350         AllocDumpBuf();
  351     }
  352 
  353     if (data_dump_buffer == NULL)
  354         FatalError("Failed allocating %X bytes to data_dump_buffer!\n", data_dump_buffer_size);
  355 
  356     /* clean it out */
  357     memset(data_dump_buffer, 0x20, size);
  358 
  359     ddb_ptr = data_dump_buffer;
  360 
  361     /* loop thru the bytes in the data buffer */
  362     while(bytes_processed)
  363     {
  364         if(*index > 0x1F && *index < 0x7F)
  365         {
  366             *ddb_ptr = *index;
  367         }
  368         else
  369         {
  370             *ddb_ptr = '.';
  371         }
  372 
  373         if(++linecount == 64)
  374         {
  375             ddb_ptr++;
  376             *ddb_ptr = '\n';
  377             linecount = 0;
  378         }
  379         ddb_ptr++;
  380         index++;
  381         bytes_processed--;
  382     }
  383 
  384     /* slam a \n on the back */
  385     ddb_ptr++;
  386     *ddb_ptr = '\n';
  387     ddb_ptr++;
  388 
  389     /* setup the globals */
  390 
  391     dump_size = (int) (ddb_ptr - data_dump_buffer);
  392     fwrite(data_dump_buffer, dump_size, 1, fp);
  393 
  394     //ClearDumpBuf();
  395 }
  396 
  397 static int PrintObfuscatedData(FILE* fp, Packet *p)
  398 {
  399     uint8_t *payload = NULL;
  400     uint16_t payload_len = 0;
  401 
  402     if (obApi->getObfuscatedPayload(p, &payload,
  403                 (uint16_t *)&payload_len) != OB_RET_SUCCESS)
  404     {
  405         return -1;
  406     }
  407 
  408     /* dump the application layer data */
  409     if (ScOutputAppData() && !ScVerboseByteDump())
  410     {
  411         if (ScOutputCharData())
  412             PrintCharData(fp, (char *)payload, payload_len);
  413         else
  414             PrintNetData(fp, payload, payload_len, NULL);
  415     }
  416     else if (ScVerboseByteDump())
  417     {
  418         uint8_t buf[UINT16_MAX];
  419         uint16_t dlen = p->data - p->pkt;
  420         int ret;
  421 
  422         ret = SafeMemcpy(buf, p->pkt, dlen, buf, buf + sizeof(buf));
  423         if (ret != SAFEMEM_SUCCESS) 
  424         {
  425            DEBUG_WRAP(DebugMessage(DEBUG_LOG,
  426                    "%s: SafeMemcpy() Failed !!!",  __FUNCTION__);)
  427            free(payload);
  428            return -1;
  429         }
  430 
  431         ret = SafeMemcpy(buf + dlen, payload, payload_len,
  432                 buf, buf + sizeof(buf));
  433         if (ret != SAFEMEM_SUCCESS)
  434         {
  435             DEBUG_WRAP(DebugMessage(DEBUG_LOG,
  436                     "%s: SafeMemcpy() Failed !!!",  __FUNCTION__);)
  437             free(payload);
  438             return -1;
  439         }
  440 
  441         PrintNetData(fp, buf, dlen + payload_len, NULL);
  442     }
  443 
  444     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
  445             "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");
  446 
  447     p->packet_flags |= PKT_LOGGED;
  448 
  449     free(payload);
  450 
  451     return 0;
  452 }
  453 
  454 
  455 /*
  456  * Function: PrintIPPkt(FILE *, int, Packet *)
  457  *
  458  * Purpose: Dump the packet to the stream pointer
  459  *
  460  * Arguments: fp => pointer to print data to
  461  *            type => packet protocol
  462  *            p => pointer to decoded packet struct
  463  *
  464  * Returns: void function
  465  */
  466 void PrintIPPkt(FILE * fp, int type, Packet * p)
  467 {
  468     char timestamp[TIMEBUF_SIZE];
  469 
  470     if (p->packet_flags & PKT_LOGGED)
  471         return;
  472 
  473     DEBUG_WRAP(DebugMessage(DEBUG_LOG, "PrintIPPkt type = %d\n", type););
  474 
  475     memset((char *) timestamp, 0, TIMEBUF_SIZE);
  476     ts_print((struct timeval *) & p->pkth->ts, timestamp);
  477 
  478     /* dump the timestamp */
  479     fwrite(timestamp, strlen(timestamp), 1, fp);
  480 
  481     /* dump the ethernet header if we're doing that sort of thing */
  482     if(ScOutputDataLink())
  483     {
  484         Print2ndHeader(fp, p);
  485 
  486 #ifdef MPLS
  487         if(p->mpls)
  488         {
  489             PrintMPLSHeader(fp, p);
  490         }
  491 #endif
  492 
  493 #ifdef GRE
  494         if (p->outer_iph)
  495         {
  496             PrintOuterIPHeader(fp, p);
  497             if (p->greh)
  498                 PrintGREHeader(fp, p);
  499         }
  500 #endif
  501     }
  502 
  503     PrintIPHeader(fp, p);
  504 
  505     /* if this isn't a fragment, print the other header info */
  506     if(!p->frag_flag)
  507     {
  508         switch(GET_IPH_PROTO(p))
  509         {
  510             case IPPROTO_TCP:
  511                 if(p->tcph != NULL)
  512 
  513                 {
  514                     PrintTCPHeader(fp, p);
  515                 }
  516                 else
  517                 {
  518                     PrintNetData(fp, (u_char *)
  519                             (u_char *)p->iph + (GET_IPH_HLEN(p) << 2),
  520                             GET_IP_PAYLEN(p), NULL);
  521                 }
  522 
  523                 break;
  524 
  525             case IPPROTO_UDP:
  526                 if(p->udph != NULL)
  527                 {
  528                     PrintUDPHeader(fp, p);
  529                 }
  530                 else
  531                 {
  532                     PrintNetData(fp, (u_char *)
  533                             (u_char *)p->iph + (GET_IPH_HLEN(p) << 2),
  534                             GET_IP_PAYLEN(p), NULL);
  535                 }
  536 
  537                 break;
  538 
  539             case IPPROTO_ICMP:
  540                 if(p->icmph != NULL)
  541                 {
  542                     PrintICMPHeader(fp, p);
  543                 }
  544                 else
  545                 {
  546                     PrintNetData(fp, (u_char *)
  547                             ((u_char *)p->iph + (GET_IPH_HLEN(p) << 2)),
  548                             GET_IP_PAYLEN(p), NULL);
  549                 }
  550 
  551                 break;
  552 
  553             default:
  554                 break;
  555         }
  556     }
  557 
  558     if ((p->dsize > 0) && obApi->payloadObfuscationRequired(p)
  559             && (PrintObfuscatedData(fp, p) == 0))
  560     {
  561         return;
  562     }
  563 
  564     /* dump the application layer data */
  565     if (ScOutputAppData() && !ScVerboseByteDump())
  566     {
  567         if (ScOutputCharData())
  568         {
  569             PrintCharData(fp, (char*) p->data, p->dsize);
  570             if(!IsJSNormData(p->ssnptr))
  571             {
  572                 fprintf(fp, "%s\n", "Normalized JavaScript for this packet");
  573                 PrintCharData(fp, (const char*)file_data_ptr.data, file_data_ptr.len);
  574             }
  575             else if(!IsGzipData(p->ssnptr))
  576             {
  577                 fprintf(fp, "%s\n", "Decompressed Data for this packet");
  578                 PrintCharData(fp, (const char*)file_data_ptr.data, file_data_ptr.len);
  579             }
  580         }
  581         else
  582         {
  583             PrintNetData(fp, p->data, p->dsize, NULL);
  584             if(!IsJSNormData(p->ssnptr))
  585             {
  586                 fprintf(fp, "%s\n", "Normalized JavaScript for this packet");
  587                 PrintNetData(fp, file_data_ptr.data, file_data_ptr.len, NULL);
  588             }
  589             else if(!IsGzipData(p->ssnptr))
  590             {
  591                 fprintf(fp, "%s\n", "Decompressed Data for this packet");
  592                 PrintNetData(fp, file_data_ptr.data, file_data_ptr.len, NULL);
  593             }
  594         }
  595     }
  596     else if (ScVerboseByteDump())
  597     {
  598         PrintNetData(fp, p->pkt, p->pkth->caplen, p);
  599     }
  600 
  601     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
  602             "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");
  603 
  604     p->packet_flags |= PKT_LOGGED;
  605 }
  606 
  607 
  608 
  609 /****************************************************************************
  610  *
  611  * Function: OpenAlertFile(char *)
  612  *
  613  * Purpose: Set up the file pointer/file for alerting
  614  *
  615  * Arguments: filearg => the filename to open
  616  *
  617  * Returns: file handle
  618  *
  619  ***************************************************************************/
  620 FILE *OpenAlertFile(const char *filearg)
  621 {
  622     char filename[STD_BUF+1];
  623     FILE *file;
  624     char suffix[5];     /* filename suffix */
  625 #ifdef WIN32
  626     SnortStrncpy(suffix, ".ids", sizeof(suffix));
  627 #else
  628     suffix[0] = '\0';
  629 #endif
  630 
  631     if(filearg == NULL)
  632     {
  633         if (snort_conf->alert_file == NULL)
  634         {
  635             if(!ScDaemonMode())
  636                 SnortSnprintf(filename, STD_BUF, "%s/alert%s", snort_conf->log_dir, suffix);
  637             else
  638                 SnortSnprintf(filename, STD_BUF, "%s/%s", snort_conf->log_dir,
  639                         DEFAULT_DAEMON_ALERT_FILE);
  640         }
  641         else
  642         {
  643             SnortSnprintf(filename, STD_BUF, "%s/%s%s",
  644                     snort_conf->log_dir, snort_conf->alert_file, suffix);
  645         }
  646     }
  647     else
  648     {
  649         SnortSnprintf(filename, STD_BUF, "%s", filearg);
  650     }
  651 
  652     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Opening alert file: %s\n", filename););
  653 
  654     if((file = fopen(filename, "a")) == NULL)
  655     {
  656         FatalError("OpenAlertFile() => fopen() alert file %s: %s\n",
  657                    filename, strerror(errno));
  658     }
  659 #ifdef WIN32
  660     /* Do not buffer in WIN32 */
  661     setvbuf(file, (char *) NULL, _IONBF, (size_t) 0);
  662 #else
  663     setvbuf(file, (char *) NULL, _IOLBF, (size_t) 0);
  664 #endif
  665 
  666     return file;
  667 }
  668 
  669 /****************************************************************************
  670  *
  671  * Function: RollAlertFile(char *)
  672  *
  673  * Purpose: rename existing alert file with by appending time to name
  674  *
  675  * Arguments: filearg => the filename to rename (same as for OpenAlertFile())
  676  *
  677  * Returns: 0=success, else errno
  678  *
  679  ***************************************************************************/
  680 int RollAlertFile(const char *filearg)
  681 {
  682     char oldname[STD_BUF+1];
  683     char newname[STD_BUF+1];
  684     char suffix[5];     /* filename suffix */
  685     time_t now = time(NULL);
  686 
  687 #ifdef WIN32
  688     SnortStrncpy(suffix, ".ids", sizeof(suffix));
  689 #else
  690     suffix[0] = '\0';
  691 #endif
  692 
  693     if(filearg == NULL)
  694     {
  695         if(!ScDaemonMode())
  696             SnortSnprintf(oldname, STD_BUF, "%s/alert%s", snort_conf->log_dir, suffix);
  697         else
  698             SnortSnprintf(oldname, STD_BUF, "%s/%s", snort_conf->log_dir,
  699                     DEFAULT_DAEMON_ALERT_FILE);
  700     }
  701     else
  702     {
  703         SnortSnprintf(oldname, STD_BUF, "%s", filearg);
  704     }
  705     SnortSnprintf(newname, sizeof(newname)-1, "%s.%lu", oldname, (unsigned long)now);
  706     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Rolling alert file: %s\n", newname););
  707 
  708     if ( rename(oldname, newname) )
  709     {
  710         FatalError("RollAlertFile() => rename(%s, %s) = %s\n",
  711                    oldname, newname, strerror(errno));
  712     }
  713     return errno;
  714 }
  715 
  716 
  717 /*
  718  *
  719  * Function: AllocDumpBuf()
  720  *
  721  * Purpose: Allocate the buffer that PrintNetData() uses
  722  *
  723  * Arguments: None.
  724  *
  725  * Returns: void function
  726  *
  727  */
  728 void AllocDumpBuf(void)
  729 {
  730     if (data_dump_buffer_size == 0)
  731     {
  732         if (ScVerboseByteDump())
  733         {
  734             data_dump_buffer_size = (((IP_MAXPACKET+1)/16) * (FRAME_SIZE + 8)) + (FRAME_SIZE + 8) + 1;
  735         }
  736         else
  737         {
  738             data_dump_buffer_size = ((IP_MAXPACKET+1)/16) * FRAME_SIZE + FRAME_SIZE + 1;
  739         }
  740     }
  741     data_dump_buffer = (char *)calloc( 1,data_dump_buffer_size );
  742 
  743     /* make sure it got allocated properly */
  744     if(data_dump_buffer == NULL)
  745     {
  746         FatalError("AllocDumpBuf(): Failed allocating %X bytes!\n", data_dump_buffer_size);
  747     }
  748 }
  749 
  750 /*
  751  *
  752  * Function: ClearDumpBuf()
  753  *
  754  * Purpose: Clear out the buffer that PrintNetData() generates
  755  *
  756  * Arguments: None.
  757  *
  758  * Returns: void function
  759  *
  760  */
  761 void ClearDumpBuf(void)
  762 {
  763     if(data_dump_buffer)
  764         free(data_dump_buffer);
  765     else
  766         return;
  767 
  768     data_dump_buffer = NULL;
  769 
  770     dump_size  = 0;
  771 }
  772 
  773 /****************************************************************************
  774  *
  775  * Function: NoAlert(Packet *, char *)
  776  *
  777  * Purpose: Don't alert at all
  778  *
  779  * Arguments: p => pointer to the packet data struct
  780  *            msg => the message to not print in the alert
  781  *
  782  * Returns: void function
  783  *
  784  ***************************************************************************/
  785 void NoAlert(Packet * p, char *msg, void *arg, Event *event)
  786 {
  787     return;
  788 }
  789 
  790 
  791 /****************************************************************************
  792  *
  793  * Function: NoLog(Packet *)
  794  *
  795  * Purpose: Don't log anything
  796  *
  797  * Arguments: p => packet to not log
  798  *
  799  * Returns: void function
  800  *
  801  ***************************************************************************/
  802 void NoLog(Packet * p, char *msg, void *arg, Event *event)
  803 {
  804     return;
  805 }
  806 
  807 /****************************************************************************
  808  *
  809  * Function: Print2ndHeader(FILE *, Packet p)
  810  *
  811  * Purpose: Print2ndHeader -- prints second layber  header info.
  812  *
  813  * Arguments: fp => file stream to print to
  814  *
  815  * Returns: void function
  816  *
  817  ***************************************************************************/
  818 
  819 
  820 void Print2ndHeader(FILE * fp, Packet * p)
  821 {
  822 
  823     switch(DAQ_GetBaseProtocol())
  824     {
  825         case DLT_EN10MB:        /* Ethernet */
  826             if(p && p->eh)
  827                 PrintEthHeader(fp, p);
  828             break;
  829 #ifndef NO_NON_ETHER_DECODER
  830 #ifdef DLT_IEEE802_11
  831         case DLT_IEEE802_11:
  832             if(p && p->wifih)
  833                 PrintWifiHeader(fp, p);
  834             break;
  835 #endif
  836         case DLT_IEEE802:                /* Token Ring */
  837             if(p && p->trh)
  838                 PrintTrHeader(fp, p);
  839             break;
  840 #ifdef DLT_LINUX_SLL
  841         case DLT_LINUX_SLL:
  842             if (p && p->sllh)
  843                 PrintSLLHeader(fp, p);  /* Linux cooked sockets */
  844             break;
  845 #endif
  846 #endif  // NO_NON_ETHER_DECODER
  847         default:
  848             if (ScLogVerbose())
  849             {
  850                 ErrorMessage("Datalink %i type 2nd layer display is not "
  851                              "supported\n", DAQ_GetBaseProtocol());
  852             }
  853     }
  854 }
  855 
  856 
  857 
  858 #ifndef NO_NON_ETHER_DECODER
  859 /****************************************************************************
  860  *
  861  * Function: PrintTrHeader(FILE *, Packet p)
  862  &
  863  * Purpose: Print the packet TokenRing header to the specified stream
  864  *
  865  * Arguments: fp => file stream to print to
  866  *
  867  * Returns: void function
  868  ***************************************************************************/
  869 
  870 void PrintTrHeader(FILE * fp, Packet * p)
  871 {
  872 
  873     fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0],
  874             p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3],
  875             p->trh->saddr[4], p->trh->saddr[5]);
  876     fprintf(fp, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0],
  877             p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3],
  878             p->trh->daddr[4], p->trh->daddr[5]);
  879 
  880     fprintf(fp, "access control:0x%X frame control:0x%X\n", p->trh->ac,
  881             p->trh->fc);
  882     if(!p->trhllc)
  883         return;
  884     fprintf(fp, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n",
  885             p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0],
  886             p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype);
  887     if(p->trhmr)
  888     {
  889         fprintf(fp, "RIF structure is present:\n");
  890         fprintf(fp, "bcast: 0x%X length: 0x%X direction: 0x%X largest"
  891                 "fr. size: 0x%X res: 0x%X\n",
  892                 TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr),
  893         TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr),
  894                 TRH_MR_RES(p->trhmr));
  895         fprintf(fp, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n",
  896                 p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2],
  897                 p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5],
  898                 p->trhmr->rseg[6], p->trhmr->rseg[7]);
  899     }
  900 }
  901 #endif  // NO_NON_ETHER_DECODER
  902 
  903 
  904 /****************************************************************************
  905  *
  906  * Function: PrintEthHeader(FILE *)
  907  *
  908  * Purpose: Print the packet Ethernet header to the specified stream
  909  *
  910  * Arguments: fp => file stream to print to
  911  *
  912  * Returns: void function
  913  *
  914  ***************************************************************************/
  915 void PrintEthHeader(FILE * fp, Packet * p)
  916 {
  917     /* src addr */
  918     fprintf(fp, "%02X:%02X:%02X:%02X:%02X:%02X -> ", p->eh->ether_src[0],
  919             p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3],
  920             p->eh->ether_src[4], p->eh->ether_src[5]);
  921 
  922     /* dest addr */
  923     fprintf(fp, "%02X:%02X:%02X:%02X:%02X:%02X ", p->eh->ether_dst[0],
  924             p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3],
  925             p->eh->ether_dst[4], p->eh->ether_dst[5]);
  926 
  927     /* protocol and pkt size */
  928     fprintf(fp, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->pktlen);
  929 }
  930 
  931 #ifdef MPLS
  932 void PrintMPLSHeader(FILE* log, Packet* p)
  933 {
  934 
  935     fprintf(log,"label:0x%05X exp:0x%X bos:0x%X ttl:0x%X\n",
  936             p->mplsHdr.label, p->mplsHdr.exp, p->mplsHdr.bos, p->mplsHdr.ttl);
  937 }
  938 #endif
  939 
  940 #ifdef GRE
  941 void PrintGREHeader(FILE *log, Packet *p)
  942 {
  943     if (p->greh == NULL)
  944         return;
  945 
  946     fprintf(log, "GRE version:%u flags:0x%02X ether-type:0x%04X\n",
  947             GRE_VERSION(p->greh), p->greh->flags, GRE_PROTO(p->greh));
  948 }
  949 #endif
  950 
  951 #ifndef NO_NON_ETHER_DECODER
  952 /****************************************************************************
  953  *
  954  * Function: PrintSLLHeader(FILE *)
  955  *
  956  * Purpose: Print the packet SLL (fake) header to the specified stream (piece
  957  * partly is borrowed from tcpdump :))
  958  *
  959  * Arguments: fp => file stream to print to
  960  *
  961  * Returns: void function
  962  *
  963  ***************************************************************************/
  964 void PrintSLLHeader(FILE * fp, Packet * p)
  965 {
  966 
  967 
  968     switch (ntohs(p->sllh->sll_pkttype)) {
  969         case LINUX_SLL_HOST:
  970             (void)fprintf(fp, "< ");
  971             break;
  972         case LINUX_SLL_BROADCAST:
  973             (void)fprintf(fp, "B ");
  974             break;
  975         case LINUX_SLL_MULTICAST:
  976             (void)fprintf(fp, "M ");
  977             break;
  978         case LINUX_SLL_OTHERHOST:
  979             (void)fprintf(fp, "P ");
  980             break;
  981         case LINUX_SLL_OUTGOING:
  982             (void)fprintf(fp, "> ");
  983             break;
  984         default:
  985             (void)fprintf(fp, "? ");
  986             break;
  987         }
  988 
  989     /* mac addr */
  990     fprintf(fp, "l/l len: %i l/l type: 0x%X %02X:%02X:%02X:%02X:%02X:%02X\n",
  991             htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype),
  992             p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2],
  993             p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]);
  994 
  995     /* protocol and pkt size */
  996     fprintf(fp, "pkt type:0x%X proto: 0x%X len:0x%X\n",
  997                  ntohs(p->sllh->sll_pkttype),
  998                  ntohs(p->sllh->sll_protocol), p->pkth->pktlen);
  999 }
 1000 
 1001 
 1002 void PrintArpHeader(FILE * fp, Packet * p)
 1003 {
 1004 // XXX-IPv6 "NOT YET IMPLEMENTED - printing ARP header"
 1005 }
 1006 #endif  // NO_NON_ETHER_DECODER
 1007 
 1008 
 1009 /****************************************************************************
 1010  *
 1011  * Function: PrintIPHeader(FILE *)
 1012  *
 1013  * Purpose: Dump the IP header info to the specified stream
 1014  *
 1015  * Arguments: fp => stream to print to
 1016  *
 1017  * Returns: void function
 1018  *
 1019  ***************************************************************************/
 1020 void PrintIPHeader(FILE * fp, Packet * p)
 1021 {
 1022     if(!IPH_IS_VALID(p))
 1023     {
 1024         fprintf(fp, "IP header truncated\n");
 1025         return;
 1026     }
 1027 
 1028     PrintIpAddrs(fp, p);
 1029 
 1030     if (!ScOutputDataLink())
 1031     {
 1032         fputc('\n', fp);
 1033     }
 1034     else
 1035     {
 1036         fputc(' ', fp);
 1037     }
 1038 
 1039     fprintf(fp, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u",
 1040             protocol_names[GET_IPH_PROTO(p)],
 1041             GET_IPH_TTL(p),
 1042             GET_IPH_TOS(p),
 1043             IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)),
 1044             GET_IPH_HLEN(p) << 2,
 1045             GET_IP_DGMLEN(p));
 1046 
 1047     /* print the reserved bit if it's set */
 1048     if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1)
 1049         fprintf(fp, " RB");
 1050 
 1051     /* printf more frags/don't frag bits */
 1052     if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1)
 1053         fprintf(fp, " DF");
 1054 
 1055     if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1)
 1056         fprintf(fp, " MF");
 1057 
 1058     fputc('\n', fp);
 1059 
 1060     /* print IP options */
 1061     if(p->ip_option_count != 0)
 1062     {
 1063         PrintIpOptions(fp, p);
 1064     }
 1065 
 1066     /* print fragment info if necessary */
 1067     if(p->frag_flag)
 1068     {
 1069         fprintf(fp, "Frag Offset: 0x%04X   Frag Size: 0x%04X\n",
 1070                 (p->frag_offset & 0x1FFF),
 1071                 GET_IP_PAYLEN(p));
 1072     }
 1073 }
 1074 
 1075 #ifdef GRE
 1076 void PrintOuterIPHeader(FILE *fp, Packet *p)
 1077 {
 1078     int save_family = p->family;
 1079     IPH_API *save_api = p->iph_api;
 1080     const IPHdr *save_iph = p->iph;
 1081     uint8_t save_ip_option_count = p->ip_option_count;
 1082     IP4Hdr *save_ip4h = p->ip4h;
 1083     IP6Hdr *save_ip6h = p->ip6h;
 1084     uint8_t save_frag_flag = p->frag_flag;
 1085     uint16_t save_sp = p->sp, save_dp = p->dp;
 1086 
 1087     p->family = p->outer_family;
 1088     p->iph_api = p->outer_iph_api;
 1089     p->iph = p->outer_iph;
 1090     p->ip_option_count = 0;
 1091     p->ip4h = &p->outer_ip4h;
 1092     p->ip6h = &p->outer_ip6h;
 1093     p->frag_flag = 0;
 1094 
 1095     if (p->proto_bits & PROTO_BIT__TEREDO)
 1096     {
 1097         if (p->outer_udph)
 1098         {
 1099             p->sp = ntohs(p->outer_udph->uh_sport);
 1100             p->dp = ntohs(p->outer_udph->uh_dport);
 1101         }
 1102         else
 1103         {
 1104             p->sp = ntohs(p->udph->uh_sport);
 1105             p->dp = ntohs(p->udph->uh_dport);
 1106         }
 1107     }
 1108 
 1109     PrintIPHeader(fp, p);
 1110 
 1111     p->family = save_family;
 1112     p->iph_api = save_api;
 1113     p->iph = save_iph;
 1114     p->ip_option_count = save_ip_option_count;
 1115     p->ip4h = save_ip4h;
 1116     p->ip6h = save_ip6h;
 1117     p->frag_flag = save_frag_flag;
 1118 
 1119     if (p->proto_bits & PROTO_BIT__TEREDO)
 1120     {
 1121         p->sp = save_sp;
 1122         p->dp = save_dp;
 1123     }
 1124 }
 1125 #endif
 1126 
 1127 /****************************************************************************
 1128  *
 1129  * Function: PrintTCPHeader(FILE *)
 1130  *
 1131  * Purpose: Dump the TCP header info to the specified stream
 1132  *
 1133  * Arguments: fp => file stream to print data to
 1134  *
 1135  * Returns: void function
 1136  *
 1137  ***************************************************************************/
 1138 void PrintTCPHeader(FILE * fp, Packet * p)
 1139 {
 1140     char tcpFlags[9];
 1141 
 1142     if(p->tcph == NULL)
 1143     {
 1144         fprintf(fp, "TCP header truncated\n");
 1145         return;
 1146     }
 1147     /* print TCP flags */
 1148     CreateTCPFlagString(p, tcpFlags);
 1149     fwrite(tcpFlags, 8, 1, fp); /* We don't care about the NULL */
 1150 
 1151     /* print other TCP info */
 1152     fprintf(fp, " Seq: 0x%lX  Ack: 0x%lX  Win: 0x%X  TcpLen: %d",
 1153             (u_long) ntohl(p->tcph->th_seq),
 1154             (u_long) ntohl(p->tcph->th_ack),
 1155             ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2);
 1156 
 1157     if((p->tcph->th_flags & TH_URG) != 0)
 1158     {
 1159         fprintf(fp, "  UrgPtr: 0x%X\n", (uint16_t) ntohs(p->tcph->th_urp));
 1160     }
 1161     else
 1162     {
 1163         fputc((int) '\n', fp);
 1164     }
 1165 
 1166     /* dump the TCP options */
 1167     if(p->tcp_option_count != 0)
 1168     {
 1169         PrintTcpOptions(fp, p);
 1170     }
 1171 }
 1172 
 1173 /* Input is packet and an nine-byte (including NULL) character array.  Results
 1174  * are put into the character array.
 1175  */
 1176 void CreateTCPFlagString(Packet * p, char *flagBuffer)
 1177 {
 1178     /* parse TCP flags */
 1179     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RES1) ? '1' : '*');
 1180     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RES2) ? '2' : '*');
 1181     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_URG)  ? 'U' : '*');
 1182     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_ACK)  ? 'A' : '*');
 1183     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_PUSH) ? 'P' : '*');
 1184     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RST)  ? 'R' : '*');
 1185     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_SYN)  ? 'S' : '*');
 1186     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_FIN)  ? 'F' : '*');
 1187     *flagBuffer = '\0';
 1188 
 1189 }
 1190 
 1191 
 1192 /****************************************************************************
 1193  *
 1194  * Function: PrintUDPHeader(FILE *)
 1195  *
 1196  * Purpose: Dump the UDP header to the specified file stream
 1197  *
 1198  * Arguments: fp => file stream
 1199  *
 1200  * Returns: void function
 1201  *
 1202  ***************************************************************************/
 1203 void PrintUDPHeader(FILE * fp, Packet * p)
 1204 {
 1205 
 1206     if(p->udph == NULL)
 1207     {
 1208         fprintf(fp, "UDP header truncated\n");
 1209         return;
 1210     }
 1211     /* not much to do here... */
 1212     fprintf(fp, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN);
 1213 }
 1214 
 1215 
 1216 
 1217 /****************************************************************************
 1218  *
 1219  * Function: PrintICMPHeader(FILE *)
 1220  *
 1221  * Purpose: Print ICMP header
 1222  *
 1223  * Arguments: fp => file stream
 1224  *
 1225  * Returns: void function
 1226  *
 1227  ***************************************************************************/
 1228 void PrintICMPHeader(FILE * fp, Packet * p)
 1229 {
 1230     /* 32 digits plus 7 colons and a NULL byte */
 1231     char buf[8*4 + 7 + 1];
 1232 
 1233     if(p->icmph == NULL)
 1234     {
 1235         fprintf(fp, "ICMP header truncated\n");
 1236         return;
 1237     }
 1238 
 1239     fprintf(fp, "Type:%d  Code:%d  ", p->icmph->type, p->icmph->code);
 1240 
 1241     switch(p->icmph->type)
 1242     {
 1243         case ICMP_ECHOREPLY:
 1244             fprintf(fp, "ID:%d  Seq:%d  ", ntohs(p->icmph->s_icmp_id),
 1245                     ntohs(p->icmph->s_icmp_seq));
 1246             fwrite("ECHO REPLY", 10, 1, fp);
 1247             break;
 1248 
 1249         case ICMP_DEST_UNREACH:
 1250             fwrite("DESTINATION UNREACHABLE: ", 25, 1, fp);
 1251             switch(p->icmph->code)
 1252             {
 1253                 case ICMP_NET_UNREACH:
 1254                     fwrite("NET UNREACHABLE", 15, 1, fp);
 1255                     break;
 1256 
 1257                 case ICMP_HOST_UNREACH:
 1258                     fwrite("HOST UNREACHABLE", 16, 1, fp);
 1259                     break;
 1260 
 1261                 case ICMP_PROT_UNREACH:
 1262                     fwrite("PROTOCOL UNREACHABLE", 20, 1, fp);
 1263                     break;
 1264 
 1265                 case ICMP_PORT_UNREACH:
 1266                     fwrite("PORT UNREACHABLE", 16, 1, fp);
 1267                     break;
 1268 
 1269                 case ICMP_FRAG_NEEDED:
 1270                     fprintf(fp, "FRAGMENTATION NEEDED, DF SET\n"
 1271                             "NEXT LINK MTU: %u",
 1272                             ntohs(p->icmph->s_icmp_nextmtu));
 1273                     break;
 1274 
 1275                 case ICMP_SR_FAILED:
 1276                     fwrite("SOURCE ROUTE FAILED", 19, 1, fp);
 1277                     break;
 1278 
 1279                 case ICMP_NET_UNKNOWN:
 1280                     fwrite("NET UNKNOWN", 11, 1, fp);
 1281                     break;
 1282 
 1283                 case ICMP_HOST_UNKNOWN:
 1284                     fwrite("HOST UNKNOWN", 12, 1, fp);
 1285                     break;
 1286 
 1287                 case ICMP_HOST_ISOLATED:
 1288                     fwrite("HOST ISOLATED", 13, 1, fp);
 1289                     break;
 1290 
 1291                 case ICMP_PKT_FILTERED_NET:
 1292                     fwrite("ADMINISTRATIVELY PROHIBITED NETWORK FILTERED", 44,
 1293                             1, fp);
 1294                     break;
 1295 
 1296                 case ICMP_PKT_FILTERED_HOST:
 1297                     fwrite("ADMINISTRATIVELY PROHIBITED HOST FILTERED", 41,
 1298                             1, fp);
 1299                     break;
 1300 
 1301                 case ICMP_NET_UNR_TOS:
 1302                     fwrite("NET UNREACHABLE FOR TOS", 23, 1, fp);
 1303                     break;
 1304 
 1305                 case ICMP_HOST_UNR_TOS:
 1306                     fwrite("HOST UNREACHABLE FOR TOS", 24, 1, fp);
 1307                     break;
 1308 
 1309                 case ICMP_PKT_FILTERED:
 1310                     fwrite("ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED", 44,
 1311                            1, fp);
 1312                     break;
 1313 
 1314                 case ICMP_PREC_VIOLATION:
 1315                     fwrite("PREC VIOLATION", 14, 1, fp);
 1316                     break;
 1317 
 1318                 case ICMP_PREC_CUTOFF:
 1319                     fwrite("PREC CUTOFF", 12, 1, fp);
 1320                     break;
 1321 
 1322                 default:
 1323                     fwrite("UNKNOWN", 7, 1, fp);
 1324                     break;
 1325 
 1326             }
 1327 
 1328             PrintICMPEmbeddedIP(fp, p);
 1329 
 1330             break;
 1331 
 1332         case ICMP_SOURCE_QUENCH:
 1333             fwrite("SOURCE QUENCH", 13, 1, fp);
 1334 
 1335             PrintICMPEmbeddedIP(fp, p);
 1336 
 1337             break;
 1338 
 1339         case ICMP_REDIRECT:
 1340             fwrite("REDIRECT", 8, 1, fp);
 1341             switch(p->icmph->code)
 1342             {
 1343                 case ICMP_REDIR_NET:
 1344                     fwrite(" NET", 4, 1, fp);
 1345                     break;
 1346 
 1347                 case ICMP_REDIR_HOST:
 1348                     fwrite(" HOST", 5, 1, fp);
 1349                     break;
 1350 
 1351                 case ICMP_REDIR_TOS_NET:
 1352                     fwrite(" TOS NET", 8, 1, fp);
 1353                     break;
 1354 
 1355                 case ICMP_REDIR_TOS_HOST:
 1356                     fwrite(" TOS HOST", 9, 1, fp);
 1357                     break;
 1358             }
 1359 
 1360 /* written this way since inet_ntoa was typedef'ed to use sfip_ntoa
 1361  * which requires sfcidr_t instead of inaddr's.  This call to inet_ntoa
 1362  * is a rare case that doesn't use sfcidr_t's. */
 1363 
 1364 // XXX-IPv6 NOT YET IMPLEMENTED - IPV6 addresses technically not supported - need to change ICMP header
 1365 
 1366             sfip_raw_ntop(AF_INET, (void *)&p->icmph->s_icmp_gwaddr, buf, sizeof(buf));
 1367             fprintf(fp, " NEW GW: %s", buf);
 1368 
 1369             PrintICMPEmbeddedIP(fp, p);
 1370 
 1371             break;
 1372 
 1373         case ICMP_ECHO:
 1374             fprintf(fp, "ID:%d   Seq:%d  ", ntohs(p->icmph->s_icmp_id),
 1375                     ntohs(p->icmph->s_icmp_seq));
 1376             fwrite("ECHO", 4, 1, fp);
 1377             break;
 1378 
 1379         case ICMP_ROUTER_ADVERTISE:
 1380             fprintf(fp, "ROUTER ADVERTISMENT: "
 1381                     "Num addrs: %d Addr entry size: %d Lifetime: %u",
 1382                     p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa,
 1383                     ntohs(p->icmph->s_icmp_lifetime));
 1384             break;
 1385 
 1386         case ICMP_ROUTER_SOLICIT:
 1387             fwrite("ROUTER SOLICITATION", 19, 1, fp);
 1388             break;
 1389 
 1390         case ICMP_TIME_EXCEEDED:
 1391             fwrite("TTL EXCEEDED", 12, 1, fp);
 1392             switch(p->icmph->code)
 1393             {
 1394                 case ICMP_TIMEOUT_TRANSIT:
 1395                     fwrite(" IN TRANSIT", 11, 1, fp);
 1396                     break;
 1397 
 1398                 case ICMP_TIMEOUT_REASSY:
 1399                     fwrite(" TIME EXCEEDED IN FRAG REASSEMBLY", 33, 1, fp);
 1400                     break;
 1401             }
 1402 
 1403             PrintICMPEmbeddedIP(fp, p);
 1404 
 1405             break;
 1406 
 1407         case ICMP_PARAMETERPROB:
 1408             fwrite("PARAMETER PROBLEM", 17, 1, fp);
 1409             switch(p->icmph->code)
 1410             {
 1411                 case ICMP_PARAM_BADIPHDR:
 1412                     fprintf(fp, ": BAD IP HEADER BYTE %u",
 1413                             p->icmph->s_icmp_pptr);
 1414                     break;
 1415 
 1416                 case ICMP_PARAM_OPTMISSING:
 1417                     fwrite(": OPTION MISSING", 16, 1, fp);
 1418                     break;
 1419 
 1420                 case ICMP_PARAM_BAD_LENGTH:
 1421                     fwrite(": BAD LENGTH", 12, 1, fp);
 1422                     break;
 1423             }
 1424 
 1425             PrintICMPEmbeddedIP(fp, p);
 1426 
 1427             break;
 1428 
 1429         case ICMP_TIMESTAMP:
 1430             fprintf(fp, "ID: %u  Seq: %u  TIMESTAMP REQUEST",
 1431                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1432             break;
 1433 
 1434         case ICMP_TIMESTAMPREPLY:
 1435             fprintf(fp, "ID: %u  Seq: %u  TIMESTAMP REPLY:\n"
 1436                     "Orig: %u Rtime: %u  Ttime: %u",
 1437                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
 1438                     p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime,
 1439                     p->icmph->s_icmp_ttime);
 1440             break;
 1441 
 1442         case ICMP_INFO_REQUEST:
 1443             fprintf(fp, "ID: %u  Seq: %u  INFO REQUEST",
 1444                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1445             break;
 1446 
 1447         case ICMP_INFO_REPLY:
 1448             fprintf(fp, "ID: %u  Seq: %u  INFO REPLY",
 1449                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1450             break;
 1451 
 1452         case ICMP_ADDRESS:
 1453             fprintf(fp, "ID: %u  Seq: %u  ADDRESS REQUEST",
 1454                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1455             break;
 1456 
 1457         case ICMP_ADDRESSREPLY:
 1458             fprintf(fp, "ID: %u  Seq: %u  ADDRESS REPLY: 0x%08X",
 1459                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
 1460                     (u_int) ntohl(p->icmph->s_icmp_mask));
 1461             break;
 1462 
 1463         default:
 1464             fwrite("UNKNOWN", 7, 1, fp);
 1465 
 1466             break;
 1467     }
 1468 
 1469     putc('\n', fp);
 1470 
 1471 }
 1472 
 1473 /****************************************************************************
 1474  *
 1475  * Function: PrintICMPEmbeddedIP(FILE *, Packet *)
 1476  *
 1477  * Purpose: Prints the original/encapsulated IP header + 64 bits of the
 1478  *          original IP payload in an ICMP packet
 1479  *
 1480  * Arguments: fp => file stream
 1481  *            p  => packet struct
 1482  *
 1483  * Returns: void function
 1484  *
 1485  ***************************************************************************/
 1486 void PrintICMPEmbeddedIP(FILE *fp, Packet *p)
 1487 {
 1488     Packet op;
 1489     Packet *orig_p;
 1490     uint32_t orig_ip_hlen;
 1491 
 1492     if (fp == NULL || p == NULL)
 1493         return;
 1494 
 1495     memset((char *) &op, 0, sizeof(Packet));
 1496     orig_p = &op;
 1497 
 1498     orig_p->iph = p->orig_iph;
 1499     orig_p->tcph = p->orig_tcph;
 1500     orig_p->udph = p->orig_udph;
 1501     orig_p->sp = p->orig_sp;
 1502     orig_p->dp = p->orig_dp;
 1503     orig_p->icmph = p->orig_icmph;
 1504     orig_p->iph_api = p->orig_iph_api;
 1505     orig_p->ip4h = p->orig_ip4h;
 1506     orig_p->ip6h = p->orig_ip6h;
 1507     orig_p->family = p->orig_family;
 1508 
 1509     if(orig_p->iph != NULL)
 1510     {
 1511         fprintf(fp, "\n** ORIGINAL DATAGRAM DUMP:\n");
 1512         PrintIPHeader(fp, orig_p);
 1513         orig_ip_hlen = IP_HLEN(p->orig_iph) << 2;
 1514 
 1515         switch(GET_IPH_PROTO(orig_p))
 1516         {
 1517             case IPPROTO_TCP:
 1518                 if(orig_p->tcph != NULL)
 1519                     fprintf(fp, "Seq: 0x%lX\n",
 1520                             (u_long)ntohl(orig_p->tcph->th_seq));
 1521                 break;
 1522 
 1523             case IPPROTO_UDP:
 1524                 if(orig_p->udph != NULL)
 1525                     fprintf(fp, "Len: %d  Csum: %d\n",
 1526                             ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN,
 1527                             ntohs(orig_p->udph->uh_chk));
 1528                 break;
 1529 
 1530             case IPPROTO_ICMP:
 1531                 if(orig_p->icmph != NULL)
 1532                     PrintEmbeddedICMPHeader(fp, orig_p->icmph);
 1533                 break;
 1534 
 1535             default:
 1536                 fprintf(fp, "Protocol: 0x%X (unknown or "
 1537                         "header truncated)", GET_IPH_PROTO(orig_p));
 1538                 break;
 1539         }       /* switch */
 1540 
 1541         /* if more than 8 bytes of original IP payload sent */
 1542         if (p->dsize - orig_ip_hlen > 8)
 1543         {
 1544             fprintf(fp, "(%d more bytes of original packet)\n",
 1545                     p->dsize - orig_ip_hlen - 8);
 1546         }
 1547 
 1548         fprintf(fp, "** END OF DUMP");
 1549     }
 1550     else
 1551     {
 1552         fprintf(fp, "\nORIGINAL DATAGRAM TRUNCATED");
 1553     }
 1554 }
 1555 
 1556 /****************************************************************************
 1557  *
 1558  * Function: PrintEmbeddedICMPHeader(FILE *, ICMPHdr *)
 1559  *
 1560  * Purpose: Prints the 64 bits of the original IP payload in an ICMP packet
 1561  *          that requires it
 1562  *
 1563  * Arguments: fp => file stream
 1564  *            icmph  => ICMPHdr struct pointing to original ICMP
 1565  *
 1566  * Returns: void function
 1567  *
 1568  ***************************************************************************/
 1569 void PrintEmbeddedICMPHeader(FILE *fp, const ICMPHdr *icmph)
 1570 {
 1571     if (fp == NULL || icmph == NULL)
 1572         return;
 1573 
 1574     fprintf(fp, "Type: %d  Code: %d  Csum: %u",
 1575             icmph->type, icmph->code, ntohs(icmph->csum));
 1576 
 1577     switch (icmph->type)
 1578     {
 1579         case ICMP_DEST_UNREACH:
 1580         case ICMP_TIME_EXCEEDED:
 1581         case ICMP_SOURCE_QUENCH:
 1582             break;
 1583 
 1584         case ICMP_PARAMETERPROB:
 1585             if (icmph->code == 0)
 1586                 fprintf(fp, "  Ptr: %u", icmph->s_icmp_pptr);
 1587             break;
 1588 
 1589         case ICMP_REDIRECT:
 1590 // XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing"
 1591             break;
 1592 
 1593         case ICMP_ECHO:
 1594         case ICMP_ECHOREPLY:
 1595         case ICMP_TIMESTAMP:
 1596         case ICMP_TIMESTAMPREPLY:
 1597         case ICMP_INFO_REQUEST:
 1598         case ICMP_INFO_REPLY:
 1599         case ICMP_ADDRESS:
 1600         case ICMP_ADDRESSREPLY:
 1601             fprintf(fp, "  Id: %u  SeqNo: %u",
 1602                     ntohs(icmph->s_icmp_id), ntohs(icmph->s_icmp_seq));
 1603             break;
 1604 
 1605         case ICMP_ROUTER_ADVERTISE:
 1606             fprintf(fp, "  Addrs: %u  Size: %u  Lifetime: %u",
 1607                     icmph->s_icmp_num_addrs, icmph->s_icmp_wpa,
 1608                     ntohs(icmph->s_icmp_lifetime));
 1609             break;
 1610 
 1611         default:
 1612             break;
 1613     }
 1614 
 1615     fprintf(fp, "\n");
 1616 
 1617     return;
 1618 }
 1619 
 1620 void PrintIpOptions(FILE * fp, Packet * p)
 1621 {
 1622     int i;
 1623     int j;
 1624     u_long init_offset;
 1625     u_long print_offset;
 1626 
 1627     init_offset = ftell(fp);
 1628 
 1629     if(!p->ip_option_count || p->ip_option_count > 40)
 1630         return;
 1631 
 1632     fprintf(fp, "IP Options (%d) => ", p->ip_option_count);
 1633 
 1634     for(i = 0; i < (int) p->ip_option_count; i++)
 1635     {
 1636         print_offset = ftell(fp);
 1637 
 1638         if((print_offset - init_offset) > 60)
 1639         {
 1640             fwrite("\nIP Options => ", 15, 1, fp);
 1641             init_offset = ftell(fp);
 1642         }
 1643 
 1644         switch(p->ip_options[i].code)
 1645         {
 1646             case IPOPT_RR:
 1647                 fwrite("RR ", 3, 1, fp);
 1648                 break;
 1649 
 1650             case IPOPT_EOL:
 1651                 fwrite("EOL ", 4, 1, fp);
 1652                 break;
 1653 
 1654             case IPOPT_NOP:
 1655                 fwrite("NOP ", 4, 1, fp);
 1656                 break;
 1657 
 1658             case IPOPT_TS:
 1659                 fwrite("TS ", 3, 1, fp);
 1660                 break;
 1661 
 1662             case IPOPT_ESEC:
 1663                 fwrite("ESEC ", 5, 1, fp);
 1664                 break;
 1665 
 1666             case IPOPT_SECURITY:
 1667                 fwrite("SEC ", 4, 1, fp);
 1668                 break;
 1669 
 1670             case IPOPT_LSRR:
 1671             case IPOPT_LSRR_E:
 1672                 fwrite("LSRR ", 5, 1, fp);
 1673                 break;
 1674 
 1675             case IPOPT_SATID:
 1676                 fwrite("SID ", 4, 1, fp);
 1677                 break;
 1678 
 1679             case IPOPT_SSRR:
 1680                 fwrite("SSRR ", 5, 1, fp);
 1681                 break;
 1682 
 1683             case IPOPT_RTRALT:
 1684                 fwrite("RTRALT ", 7, 1, fp);
 1685                 break;
 1686 
 1687             default:
 1688                 fprintf(fp, "Opt %d: ", p->ip_options[i].code);
 1689 
 1690                 if(p->ip_options[i].len)
 1691                 {
 1692                     for(j = 0; j < p->ip_options[i].len; j++)
 1693                     {
 1694                         if (p->ip_options[i].data)
 1695                             fprintf(fp, "%02X", p->ip_options[i].data[j]);
 1696                         else
 1697                             fprintf(fp, "%02X", 0);
 1698 
 1699                         if((j % 2) == 0)
 1700                             fprintf(fp, " ");
 1701                     }
 1702                 }
 1703                 break;
 1704         }
 1705     }
 1706 
 1707     fwrite("\n", 1, 1, fp);
 1708 }
 1709 
 1710 
 1711 void PrintTcpOptions(FILE * fp, Packet * p)
 1712 {
 1713     int i;
 1714     int j;
 1715     u_char tmp[5];
 1716     u_long init_offset;
 1717     u_long print_offset;
 1718 
 1719     init_offset = ftell(fp);
 1720 
 1721     fprintf(fp, "TCP Options (%d) => ", p->tcp_option_count);
 1722 
 1723     if(p->tcp_option_count > 40 || !p->tcp_option_count)
 1724         return;
 1725 
 1726     for(i = 0; i < (int) p->tcp_option_count; i++)
 1727     {
 1728         print_offset = ftell(fp);
 1729 
 1730         if((print_offset - init_offset) > 60)
 1731         {
 1732             fwrite("\nTCP Options => ", 16, 1, fp);
 1733             init_offset = ftell(fp);
 1734         }
 1735 
 1736         switch(p->tcp_options[i].code)
 1737         {
 1738             case TCPOPT_MAXSEG:
 1739                 memset((char *) tmp, 0, 5);
 1740                 fwrite("MSS: ", 5, 1, fp);
 1741                 if (p->tcp_options[i].data)
 1742                     memcpy(tmp, p->tcp_options[i].data, 2);
 1743                 fprintf(fp, "%u ", EXTRACT_16BITS(tmp));
 1744                 break;
 1745 
 1746             case TCPOPT_EOL:
 1747                 fwrite("EOL ", 4, 1, fp);
 1748                 break;
 1749 
 1750             case TCPOPT_NOP:
 1751                 fwrite("NOP ", 4, 1, fp);
 1752                 break;
 1753 
 1754             case TCPOPT_WSCALE:
 1755                 if (p->tcp_options[i].data)
 1756                     fprintf(fp, "WS: %u ", p->tcp_options[i].data[0]);
 1757                 else
 1758                     fprintf(fp, "WS: %u ", 0);
 1759                 break;
 1760 
 1761             case TCPOPT_SACK:
 1762                 memset((char *) tmp, 0, 5);
 1763                 if (p->tcp_options[i].data && (p->tcp_options[i].len >= 2))
 1764                     memcpy(tmp, p->tcp_options[i].data, 2);
 1765                 fprintf(fp, "Sack: %u@", EXTRACT_16BITS(tmp));
 1766                 memset((char *) tmp, 0, 5);
 1767                 if (p->tcp_options[i].data && (p->tcp_options[i].len >= 4))
 1768                     memcpy(tmp, (p->tcp_options[i].data) + 2, 2);
 1769                 fprintf(fp, "%u ", EXTRACT_16BITS(tmp));
 1770                 break;
 1771 
 1772             case TCPOPT_SACKOK:
 1773                 fwrite("SackOK ", 7, 1, fp);
 1774                 break;
 1775 
 1776             case TCPOPT_TFO:
 1777                 fwrite("TFO ", 4, 1, fp);
 1778                 break; 
 1779 
 1780             case TCPOPT_ECHO:
 1781                 memset((char *) tmp, 0, 5);
 1782                 if (p->tcp_options[i].data)
 1783                     memcpy(tmp, p->tcp_options[i].data, 4);
 1784                 fprintf(fp, "Echo: %u ", EXTRACT_32BITS(tmp));
 1785                 break;
 1786 
 1787             case TCPOPT_ECHOREPLY:
 1788                 memset((char *) tmp, 0, 5);
 1789                 if (p->tcp_options[i].data)
 1790                     memcpy(tmp, p->tcp_options[i].data, 4);
 1791                 fprintf(fp, "Echo Rep: %u ", EXTRACT_32BITS(tmp));
 1792                 break;
 1793 
 1794             case TCPOPT_TIMESTAMP:
 1795                 memset((char *) tmp, 0, 5);
 1796                 if (p->tcp_options[i].data)
 1797                     memcpy(tmp, p->tcp_options[i].data, 4);
 1798                 fprintf(fp, "TS: %u ", EXTRACT_32BITS(tmp));
 1799                 memset((char *) tmp, 0, 5);
 1800                 if (p->tcp_options[i].data)
 1801                     memcpy(tmp, (p->tcp_options[i].data) + 4, 4);
 1802                 fprintf(fp, "%u ", EXTRACT_32BITS(tmp));
 1803                 break;
 1804 
 1805             case TCPOPT_CC:
 1806                 memset((char *) tmp, 0, 5);
 1807                 if (p->tcp_options[i].data)
 1808                     memcpy(tmp, p->tcp_options[i].data, 4);
 1809                 fprintf(fp, "CC %u ", EXTRACT_32BITS(tmp));
 1810                 break;
 1811 
 1812             case TCPOPT_CCNEW:
 1813                 memset((char *) tmp, 0, 5);
 1814                 if (p->tcp_options[i].data)
 1815                     memcpy(tmp, p->tcp_options[i].data, 4);
 1816                 fprintf(fp, "CCNEW: %u ", EXTRACT_32BITS(tmp));
 1817                 break;
 1818 
 1819             case TCPOPT_CCECHO:
 1820                 memset((char *) tmp, 0, 5);
 1821                 if (p->tcp_options[i].data)
 1822                     memcpy(tmp, p->tcp_options[i].data, 4);
 1823                 fprintf(fp, "CCECHO: %u ", EXTRACT_32BITS(tmp));
 1824                 break;
 1825 
 1826             default:
 1827                 if(p->tcp_options[i].len)
 1828                 {
 1829                     fprintf(fp, "Opt %d (%d): ", p->tcp_options[i].code,
 1830                             (int) p->tcp_options[i].len);
 1831 
 1832                     for(j = 0; j < p->tcp_options[i].len; j++)
 1833                     {
 1834                         if (p->tcp_options[i].data)
 1835                             fprintf(fp, "%02X", p->tcp_options[i].data[j]);
 1836                         else
 1837                             fprintf(fp, "%02X", 0);
 1838 
 1839                         if ((j + 1) % 2 == 0)
 1840                             fprintf(fp, " ");
 1841                     }
 1842 
 1843                     fprintf(fp, " ");
 1844                 }
 1845                 else
 1846                 {
 1847                     fprintf(fp, "Opt %d ", p->tcp_options[i].code);
 1848                 }
 1849                 break;
 1850         }
 1851     }
 1852 
 1853     fwrite("\n", 1, 1, fp);
 1854 }
 1855 
 1856 
 1857 /*
 1858  * Function: PrintPriorityData(FILE *)
 1859  *
 1860  * Purpose: Prints out priority data associated with an alert
 1861  *
 1862  * Arguments: fp => file descriptor to write the data to
 1863  *            do_newline => tack a \n to the end of the line or not (bool)
 1864  *
 1865  * Returns: void function
 1866  */
 1867 void PrintPriorityData(FILE *fp, int do_newline)
 1868 {
 1869     if (otn_tmp == NULL)
 1870         return;
 1871 
 1872     if ((otn_tmp->sigInfo.classType != NULL)
 1873             && (otn_tmp->sigInfo.classType->name != NULL))
 1874     {
 1875         fprintf(fp, "[Classification: %s] ",
 1876                 otn_tmp->sigInfo.classType->name);
 1877     }
 1878 
 1879     fprintf(fp, "[Priority: %d] ", otn_tmp->sigInfo.priority);
 1880 
 1881     if (do_newline)
 1882         fprintf(fp, "\n");
 1883 }
 1884 
 1885 
 1886 /*
 1887  * Function: PrintXrefs(FILE *)
 1888  *
 1889  * Purpose: Prints out cross reference data associated with an alert
 1890  *
 1891  * Arguments: fp => file descriptor to write the data to
 1892  *            do_newline => tack a \n to the end of the line or not (bool)
 1893  *
 1894  * Returns: void function
 1895  */
 1896 void PrintXrefs(FILE *fp, int do_newline)
 1897 {
 1898     ReferenceNode *refNode = NULL;
 1899 
 1900     if(otn_tmp)
 1901     {
 1902         refNode = otn_tmp->sigInfo.refs;
 1903 
 1904         while(refNode  != NULL)
 1905         {
 1906             FPrintReference(fp, refNode);
 1907             refNode = refNode->next;
 1908 
 1909             /* on the last loop through, print a newline in
 1910                Full mode */
 1911             if(do_newline && (refNode == NULL))
 1912                 fprintf(fp, "\n");
 1913         }
 1914     }
 1915 }
 1916 
 1917 
 1918 /* This function name is being altered for Win32 because it
 1919    conflicts with a Win32 SDK function name.  However calls to
 1920    this function from within Snort do not need to change because
 1921    SetEvent() is defined in log.h to evaluate to SnortSetEvent()
 1922    on Win32 compiles.
 1923  */
 1924 #ifndef WIN32
 1925 void SetEvent
 1926 #else
 1927 void SnortSetEvent
 1928 #endif
 1929        (Event *event, uint32_t generator, uint32_t id, uint32_t rev,
 1930 #if !defined(FEAT_OPEN_APPID)
 1931         uint32_t classification, uint32_t priority, uint32_t event_ref)
 1932 #else /* defined(FEAT_OPEN_APPID) */
 1933         uint32_t classification, uint32_t priority, uint32_t event_ref, char *event_appid)
 1934 #endif /* defined(FEAT_OPEN_APPID) */
 1935 {
 1936     event->sig_generator = generator;
 1937     event->sig_id = id;
 1938     event->sig_rev = rev;
 1939     event->classification = classification;
 1940     event->priority = priority;
 1941     /* this one gets set automatically */
 1942     event->event_id = ++event_id | ScEventLogId();
 1943     if(event_ref)
 1944         event->event_reference = event_ref;
 1945     else
 1946         event->event_reference = event->event_id;
 1947 #if defined(FEAT_OPEN_APPID)
 1948 
 1949     if (event_appid)
 1950         memcpy(event->app_name, event_appid, MAX_EVENT_APPNAME_LEN);
 1951     else
 1952         event->app_name[0] = 0;
 1953 #endif /* defined(FEAT_OPEN_APPID) */
 1954 
 1955     event->ref_time.tv_sec = 0;
 1956 
 1957     return;
 1958 }
 1959 
 1960 #ifndef NO_NON_ETHER_DECODER
 1961 /*
 1962  * Function: PrintEapolPkt(FILE *, Packet *)
 1963  *
 1964  * Purpose: Dump the packet to the stream pointer
 1965  *
 1966  * Arguments: fp => pointer to print data to
 1967  *            type => packet protocol
 1968  *            p => pointer to decoded packet struct
 1969  *
 1970  * Returns: void function
 1971  */
 1972 void PrintEapolPkt(FILE * fp, Packet * p)
 1973 {
 1974   char timestamp[TIMEBUF_SIZE];
 1975 
 1976 
 1977     memset((char *) timestamp, 0, TIMEBUF_SIZE);
 1978     ts_print((struct timeval *) & p->pkth->ts, timestamp);
 1979 
 1980     /* dump the timestamp */
 1981     fwrite(timestamp, strlen(timestamp), 1, fp);
 1982 
 1983     /* dump the ethernet header if we're doing that sort of thing */
 1984     if (ScOutputDataLink())
 1985     {
 1986         Print2ndHeader(fp, p);
 1987     }
 1988     PrintEapolHeader(fp, p);
 1989     if (p->eplh->eaptype == EAPOL_TYPE_EAP) {
 1990       PrintEAPHeader(fp, p);
 1991     }
 1992     else if (p->eplh->eaptype == EAPOL_TYPE_KEY) {
 1993       PrintEapolKey(fp, p);
 1994     }
 1995 
 1996     /* dump the application layer data */
 1997     if(ScOutputAppData() && !ScVerboseByteDump())
 1998     {
 1999         if (ScOutputCharData())
 2000             PrintCharData(fp, (char*) p->data, p->dsize);
 2001         else
 2002             PrintNetData(fp, p->data, p->dsize, NULL);
 2003     }
 2004     else if (ScVerboseByteDump())
 2005     {
 2006         PrintNetData(fp, p->pkt, p->pkth->caplen, p);
 2007     }
 2008 
 2009     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");
 2010 }
 2011 
 2012 /****************************************************************************
 2013  *
 2014  * Function: PrintWifiHeader(FILE *)
 2015  *
 2016  * Purpose: Print the packet 802.11 header to the specified stream
 2017  *
 2018  * Arguments: fp => file stream to print to
 2019  *
 2020  * Returns: void function
 2021  *
 2022  ***************************************************************************/
 2023 void PrintWifiHeader(FILE * fp, Packet * p)
 2024 {
 2025   /* This assumes we are printing a data packet, could be changed
 2026      to print other types as well */
 2027   const u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL,
 2028     *ta = NULL;
 2029   /* per table 4, IEEE802.11 section 7.2.2 */
 2030   if ((p->wifih->frame_control & WLAN_FLAG_TODS) &&
 2031       (p->wifih->frame_control & WLAN_FLAG_FROMDS)) {
 2032     ra = p->wifih->addr1;
 2033     ta = p->wifih->addr2;
 2034     da = p->wifih->addr3;
 2035     sa = p->wifih->addr4;
 2036   }
 2037   else if (p->wifih->frame_control & WLAN_FLAG_TODS) {
 2038     bssid = p->wifih->addr1;
 2039     sa = p->wifih->addr2;
 2040     da = p->wifih->addr3;
 2041   }
 2042   else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) {
 2043     da = p->wifih->addr1;
 2044     bssid = p->wifih->addr2;
 2045     sa = p->wifih->addr3;
 2046   }
 2047   else {
 2048     da = p->wifih->addr1;
 2049     sa = p->wifih->addr2;
 2050     bssid = p->wifih->addr3;
 2051   }
 2052 
 2053   /* DO this switch to provide additional info on the type */
 2054   switch(p->wifih->frame_control & 0x00ff)
 2055   {
 2056   case WLAN_TYPE_MGMT_BEACON:
 2057     fprintf(fp, "Beacon ");
 2058     break;
 2059     /* management frames */
 2060   case WLAN_TYPE_MGMT_ASREQ:
 2061     fprintf(fp, "Assoc. Req. ");
 2062     break;
 2063   case WLAN_TYPE_MGMT_ASRES:
 2064     fprintf(fp, "Assoc. Resp. ");
 2065     break;
 2066   case WLAN_TYPE_MGMT_REREQ:
 2067     fprintf(fp, "Reassoc. Req. ");
 2068     break;
 2069   case WLAN_TYPE_MGMT_RERES:
 2070     fprintf(fp, "Reassoc. Resp. ");
 2071     break;
 2072   case WLAN_TYPE_MGMT_PRREQ:
 2073     fprintf(fp, "Probe Req. ");
 2074     break;
 2075   case WLAN_TYPE_MGMT_PRRES:
 2076     fprintf(fp, "Probe Resp. ");
 2077     break;
 2078   case WLAN_TYPE_MGMT_ATIM:
 2079     fprintf(fp, "ATIM ");
 2080     break;
 2081   case WLAN_TYPE_MGMT_DIS:
 2082     fprintf(fp, "Dissassoc. ");
 2083     break;
 2084   case WLAN_TYPE_MGMT_AUTH:
 2085     fprintf(fp, "Authent. ");
 2086     break;
 2087   case WLAN_TYPE_MGMT_DEAUTH:
 2088     fprintf(fp, "Deauthent. ");
 2089     break;
 2090 
 2091     /* Control frames */
 2092   case WLAN_TYPE_CONT_PS:
 2093   case WLAN_TYPE_CONT_RTS:
 2094   case WLAN_TYPE_CONT_CTS:
 2095   case WLAN_TYPE_CONT_ACK:
 2096   case WLAN_TYPE_CONT_CFE:
 2097   case WLAN_TYPE_CONT_CFACK:
 2098     fprintf(fp, "Control ");
 2099     break;
 2100   }
 2101 
 2102   if (sa != NULL) {
 2103     fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", sa[0],
 2104         sa[1], sa[2], sa[3], sa[4], sa[5]);
 2105   }
 2106   else if (ta != NULL) {
 2107     fprintf(fp, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0],
 2108         ta[1], ta[2], ta[3], ta[4], ta[5]);
 2109   }
 2110 
 2111   fprintf(fp, "%X:%X:%X:%X:%X:%X\n", da[0],
 2112       da[1], da[2], da[3], da[4], da[5]);
 2113 
 2114   if (bssid != NULL)
 2115   {
 2116       fprintf(fp, "bssid: %X:%X:%X:%X:%X:%X", bssid[0],
 2117               bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
 2118   }
 2119 
 2120   if (ra != NULL) {
 2121     fprintf(fp, " ra: %X:%X:%X:%X:%X:%X", ra[0],
 2122         ra[1], ra[2], ra[3], ra[4], ra[5]);
 2123   }
 2124   fprintf(fp, " Flags:");
 2125   if (p->wifih->frame_control & WLAN_FLAG_TODS)    fprintf(fp," ToDs");
 2126   if (p->wifih->frame_control & WLAN_FLAG_TODS)    fprintf(fp," FrDs");
 2127   if (p->wifih->frame_control & WLAN_FLAG_FRAG)    fprintf(fp," Frag");
 2128   if (p->wifih->frame_control & WLAN_FLAG_RETRY)   fprintf(fp," Re");
 2129   if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) fprintf(fp," Pwr");
 2130   if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) fprintf(fp," MD");
 2131   if (p->wifih->frame_control & WLAN_FLAG_WEP)   fprintf(fp," Wep");
 2132   if (p->wifih->frame_control & WLAN_FLAG_ORDER)  fprintf(fp," Ord");
 2133   fprintf(fp, "\n");
 2134 }
 2135 
 2136 /*
 2137  * Function: PrintWifiPkt(FILE *, Packet *)
 2138  *
 2139  * Purpose: Dump the packet to the stream pointer
 2140  *
 2141  * Arguments: fp => pointer to print data to
 2142  *            p => pointer to decoded packet struct
 2143  *
 2144  * Returns: void function
 2145  */
 2146 void PrintWifiPkt(FILE * fp, Packet * p)
 2147 {
 2148     char timestamp[TIMEBUF_SIZE];
 2149 
 2150 
 2151     memset((char *) timestamp, 0, TIMEBUF_SIZE);
 2152     ts_print((struct timeval *) & p->pkth->ts, timestamp);
 2153 
 2154     /* dump the timestamp */
 2155     fwrite(timestamp, strlen(timestamp), 1, fp);
 2156 
 2157     /* dump the ethernet header if we're doing that sort of thing */
 2158     Print2ndHeader(fp, p);
 2159 
 2160     /* dump the application layer data */
 2161     if (ScOutputAppData() && !ScVerboseByteDump())
 2162     {
 2163         if (ScOutputCharData())
 2164             PrintCharData(fp, (char*) p->data, p->dsize);
 2165         else
 2166             PrintNetData(fp, p->data, p->dsize, NULL);
 2167     }
 2168     else if (ScVerboseByteDump())
 2169     {
 2170         PrintNetData(fp, p->pkt, p->pkth->caplen, p);
 2171     }
 2172 
 2173     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
 2174             "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");
 2175 }
 2176 
 2177 /****************************************************************************
 2178  *
 2179  * Function: PrintEapolHeader(FILE *, Packet *)
 2180  *
 2181  * Purpose: Dump the EAPOL header info to the specified stream
 2182  *
 2183  * Arguments: fp => stream to print to
 2184  *
 2185  * Returns: void function
 2186  *
 2187  ***************************************************************************/
 2188 void PrintEapolHeader(FILE * fp, Packet * p)
 2189 {
 2190     fprintf(fp, "EAPOL type: ");
 2191     switch(p->eplh->eaptype) {
 2192     case EAPOL_TYPE_EAP:
 2193       fprintf(fp, "EAP");
 2194       break;
 2195     case EAPOL_TYPE_START:
 2196       fprintf(fp, "Start");
 2197       break;
 2198     case EAPOL_TYPE_LOGOFF:
 2199       fprintf(fp, "Logoff");
 2200       break;
 2201     case EAPOL_TYPE_KEY:
 2202       fprintf(fp, "Key");
 2203       break;
 2204     case EAPOL_TYPE_ASF:
 2205       fprintf(fp, "ASF Alert");
 2206       break;
 2207     default:
 2208       fprintf(fp, "Unknown");
 2209     }
 2210     fprintf(fp, " Len: %d\n", ntohs(p->eplh->len));
 2211 }
 2212 
 2213 /****************************************************************************
 2214  *
 2215  * Function: PrintEAPHeader(FILE *)
 2216  *
 2217  * Purpose: Dump the EAP header to the specified file stream
 2218  *
 2219  * Arguments: fp => file stream
 2220  *
 2221  * Returns: void function
 2222  *
 2223  ***************************************************************************/
 2224 void PrintEAPHeader(FILE * fp, Packet * p)
 2225 {
 2226 
 2227     if(p->eaph == NULL)
 2228     {
 2229         fprintf(fp, "EAP header truncated\n");
 2230         return;
 2231     }
 2232     fprintf(fp, "code: ");
 2233     switch(p->eaph->code) {
 2234     case EAP_CODE_REQUEST:
 2235       fprintf(fp, "Req ");
 2236       break;
 2237     case EAP_CODE_RESPONSE:
 2238       fprintf(fp, "Resp");
 2239       break;
 2240     case EAP_CODE_SUCCESS:
 2241       fprintf(fp, "Succ");
 2242       break;
 2243     case EAP_CODE_FAILURE:
 2244       fprintf(fp, "Fail");
 2245       break;
 2246     }
 2247     fprintf(fp, " id: 0x%x len: %d", p->eaph->id, ntohs(p->eaph->len));
 2248     if (p->eaptype != NULL) {
 2249       fprintf(fp, " type: ");
 2250       switch(*(p->eaptype)) {
 2251       case EAP_TYPE_IDENTITY:
 2252     fprintf(fp, "id");
 2253     break;
 2254       case EAP_TYPE_NOTIFY:
 2255     fprintf(fp, "notify");
 2256     break;
 2257       case EAP_TYPE_NAK:
 2258     fprintf(fp, "nak");
 2259     break;
 2260       case EAP_TYPE_MD5:
 2261     fprintf(fp, "md5");
 2262     break;
 2263       case EAP_TYPE_OTP:
 2264     fprintf(fp, "otp");
 2265     break;
 2266       case EAP_TYPE_GTC:
 2267     fprintf(fp, "token");
 2268     break;
 2269       case EAP_TYPE_TLS:
 2270     fprintf(fp, "tls");
 2271     break;
 2272       default:
 2273     fprintf(fp, "undef");
 2274     break;
 2275       }
 2276     }
 2277     fprintf(fp, "\n");
 2278 }
 2279 
 2280 
 2281 /****************************************************************************
 2282  *
 2283  * Function: PrintEapolKey(FILE *)
 2284  *
 2285  * Purpose: Dump the EAP header to the specified file stream
 2286  *
 2287  * Arguments: fp => file stream
 2288  *
 2289  * Returns: void function
 2290  *
 2291  ***************************************************************************/
 2292 void PrintEapolKey(FILE * fp, Packet * p)
 2293 {
 2294     uint16_t length;
 2295 
 2296     if(p->eapolk == NULL)
 2297     {
 2298         fprintf(fp, "Eapol Key truncated\n");
 2299         return;
 2300     }
 2301     fprintf(fp, "KEY type: ");
 2302     if (p->eapolk->type == 1) {
 2303       fprintf(fp, "RC4");
 2304     }
 2305 
 2306     memcpy(&length, &p->eapolk->length, 2);
 2307     length = ntohs(length);
 2308     fprintf(fp, " len: %d", length);
 2309     fprintf(fp, " index: %d ", p->eapolk->index & 0x7F);
 2310     fprintf(fp, p->eapolk->index & 0x80 ? " unicast\n" : " broadcast\n");
 2311 }
 2312 #endif  // NO_NON_ETHER_DECODER
 2313 
 2314 void PrintIpAddrs(FILE *fp, Packet *p)
 2315 {
 2316     if (!IPH_IS_VALID(p))
 2317         return;
 2318 
 2319     if (p->frag_flag
 2320             || ((GET_IPH_PROTO(p) != IPPROTO_TCP)
 2321                 && (GET_IPH_PROTO(p) != IPPROTO_UDP)))
 2322     {
 2323         char *ip_fmt = "%s -> %s";
 2324 
 2325         if (ScObfuscate())
 2326         {
 2327             fprintf(fp, ip_fmt,
 2328                     ObfuscateIpToText(GET_SRC_ADDR(p)),
 2329                     ObfuscateIpToText(GET_DST_ADDR(p)));
 2330         }
 2331         else
 2332         {
 2333             fprintf(fp, ip_fmt,
 2334                     inet_ntoax(GET_SRC_ADDR(p)),
 2335                     inet_ntoax(GET_DST_ADDR(p)));
 2336         }
 2337     }
 2338     else
 2339     {
 2340         char *ip_fmt = "%s:%d -> %s:%d";
 2341 
 2342         if (ScObfuscate())
 2343         {
 2344             fprintf(fp, ip_fmt,
 2345                     ObfuscateIpToText(GET_SRC_ADDR(p)), p->sp,
 2346                     ObfuscateIpToText(GET_DST_ADDR(p)), p->dp);
 2347         }
 2348         else
 2349         {
 2350             fprintf(fp, ip_fmt,
 2351                     inet_ntoax(GET_SRC_ADDR(p)), p->sp,
 2352                     inet_ntoax(GET_DST_ADDR(p)), p->dp);
 2353         }
 2354     }
 2355 }
 2356