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