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