1 /* $Id$ */
2 /*
3 ** Copyright (C) 2014-2021 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  */
PrintNetData(FILE * fp,const u_char * start,const int len,Packet * p)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  */
PrintCharData(FILE * fp,const char * data,int data_len)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 
PrintObfuscatedData(FILE * fp,Packet * p)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  */
PrintIPPkt(FILE * fp,int type,Packet * p)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  ***************************************************************************/
OpenAlertFile(const char * filearg)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  ***************************************************************************/
RollAlertFile(const char * filearg)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  */
AllocDumpBuf(void)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  */
ClearDumpBuf(void)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  ***************************************************************************/
NoAlert(Packet * p,char * msg,void * arg,Event * event)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  ***************************************************************************/
NoLog(Packet * p,char * msg,void * arg,Event * event)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 
Print2ndHeader(FILE * fp,Packet * p)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 
PrintTrHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintEthHeader(FILE * fp,Packet * p)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
PrintMPLSHeader(FILE * log,Packet * p)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
PrintGREHeader(FILE * log,Packet * p)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  ***************************************************************************/
PrintSLLHeader(FILE * fp,Packet * p)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 
PrintArpHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintIPHeader(FILE * fp,Packet * p)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
PrintOuterIPHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintTCPHeader(FILE * fp,Packet * p)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  */
CreateTCPFlagString(Packet * p,char * flagBuffer)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  ***************************************************************************/
PrintUDPHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintICMPHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintICMPEmbeddedIP(FILE * fp,Packet * p)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  ***************************************************************************/
PrintEmbeddedICMPHeader(FILE * fp,const ICMPHdr * icmph)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 
PrintIpOptions(FILE * fp,Packet * p)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 
PrintTcpOptions(FILE * fp,Packet * p)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  */
PrintPriorityData(FILE * fp,int do_newline)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  */
PrintXrefs(FILE * fp,int do_newline)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
SetEvent(Event * event,uint32_t generator,uint32_t id,uint32_t rev,uint32_t classification,uint32_t priority,uint32_t event_ref)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  */
PrintEapolPkt(FILE * fp,Packet * p)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  ***************************************************************************/
PrintWifiHeader(FILE * fp,Packet * p)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  */
PrintWifiPkt(FILE * fp,Packet * p)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  ***************************************************************************/
PrintEapolHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintEAPHeader(FILE * fp,Packet * p)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  ***************************************************************************/
PrintEapolKey(FILE * fp,Packet * p)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 
PrintIpAddrs(FILE * fp,Packet * p)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 
2357