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