Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

log.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 /*
00003 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
00004 **
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023 
00024 #include <sys/types.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 
00028 #ifdef HAVE_STRINGS_H
00029 #include <strings.h>
00030 #endif
00031 
00032 #ifndef WIN32
00033 #include <sys/socket.h>
00034 #include <netinet/in.h>
00035 #include <arpa/inet.h>
00036 #endif /* !WIN32 */
00037 #include <errno.h>
00038 #include <signal.h>
00039 
00040 #include "log.h"
00041 #include "rules.h"
00042 #include "util.h"
00043 #include "debug.h"
00044 #include "signature.h"
00045 
00046 #include "snort.h"
00047 
00048 extern OptTreeNode *otn_tmp;    /* global ptr to current rule data */
00049 
00050 char *data_dump_buffer;     /* printout buffer for PrintNetData */
00051 int dump_size;          /* size of printout buffer */
00052 extern u_int16_t event_id;
00053 
00054 
00055 /***************** LOG ASCII ROUTINES *******************/
00056 
00057 static unsigned char ezero[6];  /* crap for ARP */
00058 
00059 /*
00060  * Function: PrintNetData(FILE *, u_char *,int)
00061  *
00062  * Purpose: Do a side by side dump of a buffer, hex dump of buffer bytes on
00063  *          the left, decoded ASCII on the right.
00064  *
00065  * Arguments: fp => ptr to stream to print to
00066  *            start => pointer to buffer data
00067  *            len => length of data buffer
00068  *
00069  * Returns: void function
00070  */
00071 void PrintNetData(FILE * fp, u_char * start, const int len)
00072 {
00073     char *end;          /* ptr to buffer end */
00074     int i;          /* counter */
00075     int j;          /* counter */
00076     int dbuf_size;      /* data buffer size */
00077     int done;           /* flag */
00078     char *data;         /* index pointer */
00079     char *frame_ptr;        /* we use 66 byte frames for a printed line */
00080     char *d_ptr;        /* data pointer into the frame */
00081     char *c_ptr;        /* char pointer into the frame */
00082     char conv[] = "0123456789ABCDEF";   /* xlation lookup table */
00083 
00084     /* initialization */
00085     done = 0;
00086 
00087    /* zero, print a <CR> and get out */
00088     if(!len)
00089     {
00090         fputc('\n', fp);
00091         return;
00092     }
00093 
00094     if(start == NULL)
00095     {
00096         printf("Got NULL ptr in PrintNetData()\n");
00097         return;
00098     }
00099    
00100     end = (char*) (start + (len - 1));    /* set the end of buffer ptr */
00101 
00102     if(len > 65535)
00103     {
00104         if(pv.verbose_flag)
00105         {
00106             printf("Got bogus buffer length (%d) for PrintNetData, defaulting to 16 bytes!\n", len);
00107         }
00108 
00109         if(pv.verbose_bytedump_flag == 1)
00110         {
00111             dbuf_size = (FRAME_SIZE + 8) + (FRAME_SIZE + 8) + 1;
00112         }
00113         else
00114         {
00115             dbuf_size = FRAME_SIZE + FRAME_SIZE + 1;
00116         }
00117 
00118         /* dbuf_size = 66 + 67; */
00119         end =  (char*) (start + 15);
00120     }
00121     else
00122     {
00123         if(pv.verbose_bytedump_flag == 1)
00124         {
00125             /* figure out how big the printout data buffer has to be */
00126             dbuf_size = ((len / 16) * (FRAME_SIZE + 8)) + (FRAME_SIZE + 8) + 1;
00127         }
00128         else
00129         {
00130             /* figure out how big the printout data buffer has to be */
00131             dbuf_size = ((len / 16) * FRAME_SIZE) + FRAME_SIZE + 1;
00132         }
00133 
00134         /* dbuf_size = ((len / 16) * 66) + 67; */
00135     }
00136 
00137     /* generate the buffer */
00138     data_dump_buffer = (char *) malloc(dbuf_size);
00139 
00140     /* make sure it got allocated properly */
00141     if(data_dump_buffer == NULL)
00142     {
00143         FatalError("PrintNetData(): Failed allocating %X bytes! (Length: %X)\n",
00144                    dbuf_size, len);
00145     }
00146     /* clean it out */
00147     memset(data_dump_buffer, 0x20, dbuf_size);
00148 
00149 
00150     /* set the byte buffer pointer to step thru the data buffer */
00151     data = (char*) start;
00152 
00153     /* set the frame pointer to the start of the printout buffer */
00154     frame_ptr = data_dump_buffer;
00155 
00156     /* initialize counters and frame index pointers */
00157     i = 0;
00158     j = 0;
00159 
00160     /* loop thru the whole buffer */
00161     while(!done)
00162     {
00163         if(pv.verbose_bytedump_flag == 1)
00164         {
00165             d_ptr = frame_ptr + 8;
00166             c_ptr = (frame_ptr + 8 + C_OFFSET);
00167             sprintf(frame_ptr, "0x%04X: ", j);
00168             j += 16;
00169         }
00170         else
00171         {
00172             d_ptr = frame_ptr;
00173             c_ptr = (frame_ptr + C_OFFSET);
00174         }
00175 
00176         /* process 16 bytes per frame */
00177         for(i = 0; i < 16; i++)
00178         {
00179             /*
00180              * look up the ASCII value of the first nybble of the current
00181              * data buffer
00182              */
00183             *d_ptr = conv[((*data & 0xFF) >> 4)];
00184             d_ptr++;
00185 
00186             /* look up the second nybble */
00187             *d_ptr = conv[((*data & 0xFF) & 0x0F)];
00188             d_ptr++;
00189 
00190             /* put a space in between */
00191             *d_ptr = 0x20;
00192             d_ptr++;
00193 
00194             /* print out the char equivalent */
00195             if(*data > 0x1F && *data < 0x7F)
00196                 *c_ptr = (char) (*data & 0xFF);
00197             else
00198                 *c_ptr = 0x2E;
00199 
00200             c_ptr++;
00201 
00202             /* increment the pointer or finish up */
00203             if(data < end)
00204                 data++;
00205             else
00206             {
00207                 *c_ptr = '\n';
00208                 c_ptr++;
00209                 *c_ptr = '\n';
00210                 c_ptr++;
00211                 *c_ptr = 0;
00212 
00213                 dump_size = (int) (c_ptr - data_dump_buffer);
00214                 fwrite(data_dump_buffer, dump_size, 1, fp);
00215 
00216                 return;
00217             }
00218         }
00219 
00220         *c_ptr = '\n';
00221         if(pv.verbose_bytedump_flag == 1)
00222         {
00223             frame_ptr += (FRAME_SIZE + 8);
00224         }
00225         else
00226         {
00227             frame_ptr += FRAME_SIZE;
00228         }
00229     }
00230 }
00231 
00232 
00233 
00234 /*
00235  * Function: PrintCharData(FILE *, char *,int)
00236  *
00237  * Purpose: Dump the ASCII data from a packet
00238  *          the left, decoded ASCII on the right.
00239  *
00240  * Arguments: fp => ptr to stream to print to
00241  *            data => pointer to buffer data
00242  *            data_len => length of data buffer
00243  *
00244  * Returns: void function
00245  */
00246 void PrintCharData(FILE * fp, char *data, int data_len)
00247 {
00248     int bytes_processed;    /* count of bytes in the data buffer
00249                  * processed so far */
00250     int linecount = 0;      /* number of lines in this dump */
00251     char *index;        /* index pointer into the data buffer */
00252     char *ddb_ptr;      /* index pointer into the data_dump_buffer */
00253 
00254     /* if there's no data, return */
00255     if(data == NULL)
00256     {
00257         return;
00258     }
00259 
00260     /* setup the pointers and counters */
00261     bytes_processed = data_len;
00262     index = data;
00263 
00264     /* allocate a buffer to print the data to */
00265     data_dump_buffer = (char *) calloc(data_len + (data_len >> 6) + 2, sizeof(char));
00266     ddb_ptr = data_dump_buffer;
00267 
00268     /* loop thru the bytes in the data buffer */
00269     while(bytes_processed)
00270     {
00271         if(*index > 0x1F && *index < 0x7F)
00272         {
00273             *ddb_ptr = *index;
00274         }
00275         else
00276         {
00277             *ddb_ptr = '.';
00278         }
00279 
00280         if(++linecount == 64)
00281         {
00282             ddb_ptr++;
00283             *ddb_ptr = '\n';
00284             linecount = 0;
00285         }
00286         ddb_ptr++;
00287         index++;
00288         bytes_processed--;
00289     }
00290 
00291     /* slam a \n on the back */
00292     ddb_ptr++;
00293     *ddb_ptr = '\n';
00294     ddb_ptr++;
00295 
00296     /* setup the globals */
00297 
00298     dump_size = (int) (ddb_ptr - data_dump_buffer);
00299     fwrite(data_dump_buffer, dump_size, 1, fp);
00300 }
00301 
00302 
00303 
00304 /*
00305  * Function: PrintIPPkt(FILE *, int, Packet *)
00306  *
00307  * Purpose: Dump the packet to the stream pointer
00308  *
00309  * Arguments: fp => pointer to print data to
00310  *            type => packet protocol
00311  *            p => pointer to decoded packet struct
00312  *
00313  * Returns: void function
00314  */
00315 void PrintIPPkt(FILE * fp, int type, Packet * p)
00316 {
00317     char timestamp[TIMEBUF_SIZE];
00318 
00319     DEBUG_WRAP(DebugMessage(DEBUG_LOG, "PrintIPPkt type = %d\n", type););
00320 
00321     bzero((char *) timestamp, TIMEBUF_SIZE);
00322     ts_print((struct timeval *) & p->pkth->ts, timestamp);
00323 
00324     /* dump the timestamp */
00325     fwrite(timestamp, strlen(timestamp), 1, fp);
00326 
00327     /* dump the ethernet header if we're doing that sort of thing */
00328     if(pv.show2hdr_flag)
00329     {
00330         Print2ndHeader(fp, p);
00331     }
00332 
00333     /* etc */
00334     PrintIPHeader(fp, p);
00335 
00336     /* if this isn't a fragment, print the other header info */
00337     if(!p->frag_flag)
00338     {
00339         switch(p->iph->ip_proto)
00340         {
00341             case IPPROTO_TCP:
00342                 if(p->tcph != NULL)
00343                 {
00344                     PrintTCPHeader(fp, p);
00345                 }
00346                 else
00347                 {
00348                     PrintNetData(fp, (u_char *) 
00349                                  ((u_char *)p->iph + (IP_HLEN(p->iph) << 2)), 
00350                                  (p->actual_ip_len - (IP_HLEN(p->iph) << 2)));
00351                 }
00352 
00353                 break;
00354 
00355             case IPPROTO_UDP:
00356                 if(p->udph != NULL)
00357                 {
00358                     PrintUDPHeader(fp, p);
00359                 }
00360                 else
00361                 {
00362                     PrintNetData(fp, (u_char *) 
00363                                  ((u_char *)p->iph + (IP_HLEN(p->iph) << 2)), 
00364                                  (p->actual_ip_len - (IP_HLEN(p->iph) << 2)));
00365                 }
00366 
00367                 break;
00368 
00369             case IPPROTO_ICMP:
00370                 if(p->icmph != NULL)
00371                 {
00372                     PrintICMPHeader(fp, p);
00373                 }
00374                 else
00375                 {
00376 /*
00377                    printf("p->iph: %p\n", p->iph);
00378                    printf("p->icmph: %p\n", p->icmph);
00379                    printf("p->iph->ip_hlen: %d\n", (IP_HLEN(p->iph) << 2));
00380                    printf("p->iph->ip_len: %d\n", p->iph->ip_len);
00381  */
00382                     PrintNetData(fp, (u_char *) 
00383                             ((u_char *) p->iph + (IP_HLEN(p->iph) << 2)), 
00384                             (ntohs(p->iph->ip_len) - (IP_HLEN(p->iph) << 2)));
00385                 }
00386 
00387                 break;
00388 
00389             default:
00390                 break;
00391         }
00392     }
00393     /* dump the application layer data */
00394     if(pv.data_flag && !pv.verbose_bytedump_flag)
00395     {
00396         if(pv.char_data_flag)
00397             PrintCharData(fp, (char*) p->data, p->dsize);
00398         else
00399             PrintNetData(fp, p->data, p->dsize);
00400     }
00401     else if(pv.verbose_bytedump_flag)
00402     {
00403         PrintNetData(fp, p->pkt, p->pkth->caplen);
00404     }
00405 
00406     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
00407             "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");
00408 }
00409 
00410 
00411 
00412 /****************************************************************************
00413  *
00414  * Function: OpenAlertFile(char *)
00415  *
00416  * Purpose: Set up the file pointer/file for alerting
00417  *
00418  * Arguments: filearg => the filename to open
00419  *
00420  * Returns: file handle
00421  *
00422  ***************************************************************************/
00423 FILE *OpenAlertFile(char *filearg)
00424 {
00425     char filename[STD_BUF+1];
00426     FILE *file;
00427     char suffix[5];     /* filename suffix */
00428 #ifdef WIN32
00429     strcpy(suffix,".ids");
00430 #else
00431     suffix[0] = '\0';
00432 #endif
00433 
00434     if(filearg == NULL)
00435     {
00436         if(!pv.daemon_flag)
00437             snprintf(filename, STD_BUF, "%s/alert%s", pv.log_dir, suffix);
00438         else
00439             snprintf(filename, STD_BUF, "%s/%s", pv.log_dir, 
00440                     DEFAULT_DAEMON_ALERT_FILE);
00441     }
00442     else
00443     {
00444         snprintf(filename, STD_BUF, "%s", filearg);
00445     }
00446 
00447     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Opening alert file: %s\n", filename););
00448 
00449     if((file = fopen(filename, "a")) == NULL)
00450     {
00451         FatalError("OpenAlertFile() => fopen() alert file %s: %s\n",
00452                    filename, strerror(errno));
00453     }
00454 #ifdef WIN32
00455     /* Do not buffer in WIN32 */
00456     setvbuf(file, (char *) NULL, _IONBF, (size_t) 0);
00457 #else
00458     setvbuf(file, (char *) NULL, _IOLBF, (size_t) 0);
00459 #endif
00460 
00461     return file;
00462 }
00463 
00464 
00465 
00466 /*
00467  *
00468  * Function: ClearDumpBuf()
00469  *
00470  * Purpose: Clear out the buffer that PrintNetData() generates
00471  *
00472  * Arguments: None.
00473  *
00474  * Returns: void function
00475  *
00476  */
00477 void ClearDumpBuf()
00478 {
00479     if(data_dump_buffer)
00480         free(data_dump_buffer);
00481     else
00482         return;
00483 
00484     data_dump_buffer = NULL;
00485 
00486     dump_size  = 0;
00487 }
00488 
00489 /****************************************************************************
00490  *
00491  * Function: NoAlert(Packet *, char *)
00492  *
00493  * Purpose: Don't alert at all
00494  *
00495  * Arguments: p => pointer to the packet data struct
00496  *            msg => the message to not print in the alert
00497  *
00498  * Returns: void function
00499  *
00500  ***************************************************************************/
00501 void NoAlert(Packet * p, char *msg, void *arg, Event *event)
00502 {
00503     return;
00504 }
00505 
00506 
00507 /****************************************************************************
00508  *
00509  * Function: NoLog(Packet *)
00510  *
00511  * Purpose: Don't log anything
00512  *
00513  * Arguments: p => packet to not log
00514  *
00515  * Returns: void function
00516  *
00517  ***************************************************************************/
00518 void NoLog(Packet * p, char *msg, void *arg, Event *event)
00519 {
00520     return;
00521 }
00522 
00523 /****************************************************************************
00524  *
00525  * Function: Print2ndHeader(FILE *, Packet p)
00526  *
00527  * Purpose: Print2ndHeader -- prints second layber  header info.
00528  *
00529  * Arguments: fp => file stream to print to
00530  *
00531  * Returns: void function
00532  *
00533  ***************************************************************************/
00534 
00535 
00536 void Print2ndHeader(FILE * fp, Packet * p)
00537 {
00538 
00539     switch(datalink) 
00540     {
00541         case DLT_EN10MB:        /* Ethernet */
00542             if(p && p->eh)
00543                 PrintEthHeader(fp, p);
00544             break;
00545 #ifdef DLT_IEEE802_11
00546         case DLT_IEEE802_11:
00547             if(p && p->wifih)
00548                 PrintWifiHeader(fp, p);
00549             break;
00550 #endif     
00551         case DLT_IEEE802:                /* Token Ring */
00552             if(p && p->trh)
00553                 PrintTrHeader(fp, p);
00554             break;    
00555 #ifdef DLT_LINUX_SLL        
00556         case DLT_LINUX_SLL:
00557             if (p && p->sllh)
00558                 PrintSLLHeader(fp, p);  /* Linux cooked sockets */
00559             break;
00560 #endif            
00561         default:
00562             if(pv.verbose_flag)
00563                 ErrorMessage("Datalink %i type 2nd layer display is not "
00564                         "supported\n", datalink);   
00565     }
00566 }
00567 
00568 
00569 
00570 /****************************************************************************
00571  *
00572  * Function: PrintTrHeader(FILE *, Packet p)
00573  &
00574  * Purpose: Print the packet TokenRing header to the specified stream
00575  *
00576  * Arguments: fp => file stream to print to
00577  *
00578  * Returns: void function
00579  ***************************************************************************/
00580 
00581 void PrintTrHeader(FILE * fp, Packet * p)
00582 {
00583 
00584     fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0],
00585             p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3],
00586             p->trh->saddr[4], p->trh->saddr[5]);
00587     fprintf(fp, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0],
00588             p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3],
00589             p->trh->daddr[4], p->trh->daddr[5]);
00590 
00591     fprintf(fp, "access control:0x%X frame control:0x%X\n", p->trh->ac,
00592             p->trh->fc);
00593     if(!p->trhllc)
00594         return;
00595     fprintf(fp, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n",
00596             p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0],
00597             p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype);
00598     if(p->trhmr)
00599     {
00600         fprintf(fp, "RIF structure is present:\n");
00601         fprintf(fp, "bcast: 0x%X length: 0x%X direction: 0x%X largest"
00602                 "fr. size: 0x%X res: 0x%X\n",
00603                 TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr),
00604                 TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr),
00605                 TRH_MR_RES(p->trhmr));
00606         fprintf(fp, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n",
00607                 p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2],
00608                 p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5],
00609                 p->trhmr->rseg[6], p->trhmr->rseg[7]);
00610     }
00611 }
00612 
00613 
00614 /****************************************************************************
00615  *
00616  * Function: PrintEthHeader(FILE *)
00617  *
00618  * Purpose: Print the packet Ethernet header to the specified stream
00619  *
00620  * Arguments: fp => file stream to print to
00621  *
00622  * Returns: void function
00623  *
00624  ***************************************************************************/
00625 void PrintEthHeader(FILE * fp, Packet * p)
00626 {
00627     /* src addr */
00628     fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", p->eh->ether_src[0],
00629             p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3],
00630             p->eh->ether_src[4], p->eh->ether_src[5]);
00631 
00632     /* dest addr */
00633     fprintf(fp, "%X:%X:%X:%X:%X:%X ", p->eh->ether_dst[0],
00634             p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3],
00635             p->eh->ether_dst[4], p->eh->ether_dst[5]);
00636 
00637     /* protocol and pkt size */
00638     fprintf(fp, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->len);
00639 }
00640 
00641 
00642 /****************************************************************************
00643  *
00644  * Function: PrintSLLHeader(FILE *)
00645  *
00646  * Purpose: Print the packet SLL (fake) header to the specified stream (piece
00647  * partly is borrowed from tcpdump :))
00648  *
00649  * Arguments: fp => file stream to print to
00650  *
00651  * Returns: void function
00652  *
00653  ***************************************************************************/
00654 void PrintSLLHeader(FILE * fp, Packet * p)
00655 {
00656 
00657 
00658     switch (ntohs(p->sllh->sll_pkttype)) {
00659         case LINUX_SLL_HOST:
00660             (void)fprintf(fp, "< ");
00661             break;
00662         case LINUX_SLL_BROADCAST:
00663             (void)fprintf(fp, "B ");
00664             break;
00665         case LINUX_SLL_MULTICAST:
00666             (void)fprintf(fp, "M ");
00667             break;
00668         case LINUX_SLL_OTHERHOST:
00669             (void)fprintf(fp, "P ");
00670             break;
00671         case LINUX_SLL_OUTGOING:
00672             (void)fprintf(fp, "> ");
00673             break;
00674         default:
00675             (void)fprintf(fp, "? ");
00676             break;
00677         }
00678 
00679     /* mac addr */
00680     fprintf(fp, "l/l len: %i l/l type: 0x%X %X:%X:%X:%X:%X:%X\n", 
00681             htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype),
00682             p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2],
00683             p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]);
00684 
00685     /* protocol and pkt size */
00686     fprintf(fp, "pkt type:0x%X proto: 0x%X len:0x%X\n",
00687                  ntohs(p->sllh->sll_pkttype),
00688                  ntohs(p->sllh->sll_protocol), p->pkth->len);
00689 }
00690 
00691 
00692 void PrintArpHeader(FILE * fp, Packet * p)
00693 {
00694     struct in_addr ip_addr;
00695     char timestamp[TIMEBUF_SIZE];
00696     u_int8_t *mac_src = NULL;
00697     u_int8_t *mac_dst = NULL;
00698 
00699     bzero((struct in_addr *) &ip_addr, sizeof(struct in_addr));
00700     bzero((char *) timestamp, TIMEBUF_SIZE);
00701     ts_print((struct timeval *) & p->pkth->ts, timestamp);
00702 
00703     /* determine what to use as MAC src and dst */
00704     if (p->eh != NULL) 
00705     {
00706         mac_src = p->eh->ether_src;
00707         mac_dst = p->eh->ether_dst;
00708     } /* per table 4, 802.11 section 7.2.2 */
00709     else if (p->wifih != NULL && 
00710              (p->wifih->frame_control & WLAN_FLAG_FROMDS))
00711     {
00712         mac_src = p->wifih->addr3;
00713         mac_dst = p->wifih->addr2;
00714     }
00715     else if (p->wifih != NULL &&
00716              (p->wifih->frame_control & WLAN_FLAG_TODS))
00717     {
00718         mac_src = p->wifih->addr2;
00719         mac_dst = p->wifih->addr3;
00720     }
00721     else if (p->wifih != NULL)
00722     {
00723         mac_src = p->wifih->addr2;
00724         mac_dst = p->wifih->addr1;
00725     }
00726 
00727     /* 
00728      * if these are null this function will break, exit until 
00729      * someone writes a function for it...
00730      */
00731     if(mac_src == NULL || mac_dst == NULL)
00732     {
00733         return;
00734     }
00735 
00736     /* dump the timestamp */
00737     fwrite(timestamp, strlen(timestamp), 1, fp);
00738 
00739     if(ntohs(p->ah->ea_hdr.ar_pro) != ETHERNET_TYPE_IP)
00740     {
00741         fprintf(fp, "ARP #%d for protocol #%.4X (%d) hardware #%d (%d)\n",
00742                 ntohs(p->ah->ea_hdr.ar_op), ntohs(p->ah->ea_hdr.ar_pro),
00743                 p->ah->ea_hdr.ar_pln, ntohs(p->ah->ea_hdr.ar_hrd),
00744                 p->ah->ea_hdr.ar_hln);
00745 
00746         return;
00747     }
00748 
00749     switch(ntohs(p->ah->ea_hdr.ar_op))
00750     {
00751         case ARPOP_REQUEST:
00752             bcopy((void *)p->ah->arp_tpa, (void *) &ip_addr, sizeof(ip_addr));
00753             fprintf(fp, "ARP who-has %s", inet_ntoa(ip_addr));
00754 
00755             if(memcmp((char *) ezero, (char *) p->ah->arp_tha, 6) != 0)
00756             {
00757                 fprintf(fp, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_tha[0],
00758                         p->ah->arp_tha[1], p->ah->arp_tha[2], p->ah->arp_tha[3],
00759                         p->ah->arp_tha[4], p->ah->arp_tha[5]);
00760             }
00761             bcopy((void *)p->ah->arp_spa, (void *) &ip_addr, sizeof(ip_addr));
00762 
00763             fprintf(fp, " tell %s", inet_ntoa(ip_addr));
00764 
00765             if(memcmp((char *) mac_src, (char *) p->ah->arp_sha, 6) != 0)
00766             {
00767                 fprintf(fp, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_sha[0],
00768                         p->ah->arp_sha[1], p->ah->arp_sha[2], p->ah->arp_sha[3],
00769                         p->ah->arp_sha[4], p->ah->arp_sha[5]);
00770             }
00771             break;
00772 
00773         case ARPOP_REPLY:
00774             bcopy((void *)p->ah->arp_spa, (void *) &ip_addr, sizeof(ip_addr));
00775             fprintf(fp, "ARP reply %s", inet_ntoa(ip_addr));
00776 
00777             /* print out the originating request if we're on a weirder
00778              * wireless protocol */            
00779             if(memcmp((char *) mac_src, (char *) p->ah->arp_sha, 6) != 0)
00780             {
00781                 fprintf(fp, " (%X:%X:%X:%X:%X:%X)", mac_src[0],
00782                         mac_src[1], mac_src[2], mac_src[3],
00783                         mac_src[4], mac_src[5]);
00784             }
00785             fprintf(fp, " is-at %X:%X:%X:%X:%X:%X", p->ah->arp_sha[0],
00786                     p->ah->arp_sha[1], p->ah->arp_sha[2], p->ah->arp_sha[3],
00787                     p->ah->arp_sha[4], p->ah->arp_sha[5]);
00788 
00789             if(memcmp((char *) mac_dst, (char *) p->ah->arp_tha, 6) != 0)
00790             {
00791                 fprintf(fp, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_tha[0],
00792                         p->ah->arp_tha[1], p->ah->arp_tha[2], p->ah->arp_tha[3],
00793                         p->ah->arp_tha[4], p->ah->arp_tha[5]);
00794             }
00795             break;
00796 
00797         case ARPOP_RREQUEST:
00798             fprintf(fp, "RARP who-is %X:%X:%X:%X:%X:%X tell %X:%X:%X:%X:%X:%X",
00799                     p->ah->arp_tha[0], p->ah->arp_tha[1], p->ah->arp_tha[2],
00800                     p->ah->arp_tha[3], p->ah->arp_tha[4], p->ah->arp_tha[5],
00801                     p->ah->arp_sha[0], p->ah->arp_sha[1], p->ah->arp_sha[2],
00802                     p->ah->arp_sha[3], p->ah->arp_sha[4], p->ah->arp_sha[5]);
00803 
00804             break;
00805 
00806         case ARPOP_RREPLY:
00807             bcopy((void *)p->ah->arp_tpa, (void *) &ip_addr, sizeof(ip_addr));
00808             fprintf(fp, "RARP reply %X:%X:%X:%X:%X:%X at %s",
00809                     p->ah->arp_tha[0], p->ah->arp_tha[1], p->ah->arp_tha[2],
00810                     p->ah->arp_tha[3], p->ah->arp_tha[4], p->ah->arp_tha[5],
00811                     inet_ntoa(ip_addr));
00812 
00813             break;
00814 
00815         default:
00816             fprintf(fp, "Unknown operation: %d", ntohs(p->ah->ea_hdr.ar_op));
00817             break;
00818     }
00819 
00820     fprintf(fp, "\n\n");
00821 
00822 }
00823 
00824 
00825 /****************************************************************************
00826  *
00827  * Function: PrintIPHeader(FILE *)
00828  *
00829  * Purpose: Dump the IP header info to the specified stream
00830  *
00831  * Arguments: fp => stream to print to
00832  *
00833  * Returns: void function
00834  *
00835  ***************************************************************************/
00836 void PrintIPHeader(FILE * fp, Packet * p)
00837 {
00838     if(p->iph == NULL)
00839     {
00840         fprintf(fp, "IP header truncated\n");
00841         return;
00842     }
00843     if(p->frag_flag)
00844     {
00845         /* just print the straight IP header */
00846         fputs(inet_ntoa(p->iph->ip_src), fp);
00847         fwrite(" -> ", 4, 1, fp);
00848         fputs(inet_ntoa(p->iph->ip_dst), fp);
00849     }
00850     else
00851     {
00852         if(p->iph->ip_proto != IPPROTO_TCP && p->iph->ip_proto != IPPROTO_UDP)
00853         {
00854             /* just print the straight IP header */
00855             fputs(inet_ntoa(p->iph->ip_src), fp);
00856             fwrite(" -> ", 4, 1, fp);
00857             fputs(inet_ntoa(p->iph->ip_dst), fp);
00858         }
00859         else
00860         {
00861             if(!pv.obfuscation_flag)
00862             {
00863                 /* print the header complete with port information */
00864                 fputs(inet_ntoa(p->iph->ip_src), fp);
00865                 fprintf(fp, ":%d -> ", p->sp);
00866                 fputs(inet_ntoa(p->iph->ip_dst), fp);
00867                 fprintf(fp, ":%d", p->dp);
00868             }
00869             else
00870             {
00871                 /* print the header complete with port information */
00872                 fprintf(fp, "xxx.xxx.xxx.xxx:%d -> xxx.xxx.xxx.xxx:%d", p->sp, p->dp);
00873             }
00874         }
00875     }
00876 
00877     if(!pv.show2hdr_flag)
00878     {
00879         fputc('\n', fp);
00880     }
00881     else
00882     {
00883         fputc(' ', fp);
00884     }
00885 
00886     fprintf(fp, "%s TTL:%d TOS:0x%X ID:%d IpLen:%d DgmLen:%d",
00887             protocol_names[p->iph->ip_proto],
00888             p->iph->ip_ttl,
00889             p->iph->ip_tos,
00890             ntohs(p->iph->ip_id),
00891             IP_HLEN(p->iph) << 2, ntohs(p->iph->ip_len));
00892 
00893     /* print the reserved bit if it's set */
00894     if((u_int8_t)((ntohs(p->iph->ip_off) & 0x8000) >> 15) == 1)
00895         fprintf(fp, " RB");
00896 
00897     /* printf more frags/don't frag bits */
00898     if((u_int8_t)((ntohs(p->iph->ip_off) & 0x4000) >> 14) == 1)
00899         fprintf(fp, " DF");
00900 
00901     if((u_int8_t)((ntohs(p->iph->ip_off) & 0x2000) >> 13) == 1)
00902         fprintf(fp, " MF");
00903 
00904     fputc('\n', fp);
00905 
00906     /* print IP options */
00907     if(p->ip_option_count != 0)
00908     {
00909         PrintIpOptions(fp, p);
00910     }
00911 
00912     /* print fragment info if necessary */
00913     if(p->frag_flag)
00914     {
00915         fprintf(fp, "Frag Offset: 0x%04X   Frag Size: 0x%04X\n",
00916                 (p->frag_offset & 0x1FFF),
00917                 (ntohs(p->iph->ip_len) - (IP_HLEN(p->iph) << 2)));
00918     }
00919 }
00920 
00921 
00922 
00923 /****************************************************************************
00924  *
00925  * Function: PrintTCPHeader(FILE *)
00926  *
00927  * Purpose: Dump the TCP header info to the specified stream
00928  *
00929  * Arguments: fp => file stream to print data to
00930  *
00931  * Returns: void function
00932  *
00933  ***************************************************************************/
00934 void PrintTCPHeader(FILE * fp, Packet * p)
00935 {
00936     char tcpFlags[9];
00937 
00938     if(p->tcph == NULL)
00939     {
00940         fprintf(fp, "TCP header truncated\n");
00941         return;
00942     }
00943     /* print TCP flags */
00944     CreateTCPFlagString(p, tcpFlags);
00945     fwrite(tcpFlags, 8, 1, fp); /* We don't care about the NULL */
00946 
00947     /* print other TCP info */
00948     fprintf(fp, " Seq: 0x%lX  Ack: 0x%lX  Win: 0x%X  TcpLen: %d",
00949             (u_long) ntohl(p->tcph->th_seq),
00950             (u_long) ntohl(p->tcph->th_ack),
00951             ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2);
00952 
00953     if((p->tcph->th_flags & TH_URG) != 0)
00954     {
00955         fprintf(fp, "  UrgPtr: 0x%X\n", (u_int16_t) ntohs(p->tcph->th_urp));
00956     }
00957     else
00958     {
00959         fputc((int) '\n', fp);
00960     }
00961 
00962     /* dump the TCP options */
00963     if(p->tcp_option_count != 0)
00964     {
00965         PrintTcpOptions(fp, p);
00966     }
00967 }
00968 
00969 
00970 void PrintEmbeddedTCPHeader(FILE * fp, Packet * p, int size)
00971 {
00972     char tcpFlags[9];
00973 
00974     DEBUG_WRAP(DebugMessage(DEBUG_FLOW, "size is %d\n", size););
00975 
00976     if(size >= 16)
00977     { 
00978         CreateTCPFlagString(p, tcpFlags);
00979         fwrite(tcpFlags, 8, 1, fp); 
00980         fprintf(fp, " Seq: 0x%lX  Ack: 0x%lX  Win: 0x%X  TcpLen: %d\n",
00981                 (u_long) ntohl(p->tcph->th_seq),
00982                 (u_long) ntohl(p->tcph->th_ack),
00983                 ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2);
00984     }
00985     else if(size >= 14)
00986     { 
00987         CreateTCPFlagString(p, tcpFlags);
00988         fwrite(tcpFlags, 8, 1, fp); 
00989         fprintf(fp, " Seq: 0x%lX  Ack: 0x%lX  TcpLen: %d\n",
00990                 (u_long) ntohl(p->tcph->th_seq), 
00991                 (u_long) ntohl(p->tcph->th_ack),
00992                 TCP_OFFSET(p->tcph) << 2);
00993     }
00994     else if(size >= 13)
00995     {
00996         fprintf(fp, "Seq: 0x%lX  Ack: 0x%lX  TcpLen: %d\n",
00997                 (u_long) ntohl(p->tcph->th_seq), 
00998                 (u_long) ntohl(p->tcph->th_ack), TCP_OFFSET(p->tcph) << 2);
00999     }
01000     else if(size >= 12)
01001     {
01002         fprintf(fp, "Seq: 0x%lX  Ack: 0x%lX\n",
01003                 (u_long) ntohl(p->tcph->th_seq), 
01004                 (u_long) ntohl(p->tcph->th_ack));
01005     }
01006     else if(size >= 8)
01007     {
01008 
01009         fprintf(fp, "Seq: 0x%lX\n",
01010                 (u_long) ntohl(p->tcph->th_seq));
01011     }
01012 }
01013 
01014 
01015 
01016 /* Input is packet and an nine-byte (including NULL) character array.  Results
01017  * are put into the character array.
01018  */
01019 void CreateTCPFlagString(Packet * p, char *flagBuffer)
01020 {
01021     /* parse TCP flags */
01022     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RES1) ? '1' : '*');
01023     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RES2) ? '2' : '*');
01024     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_URG)  ? 'U' : '*');
01025     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_ACK)  ? 'A' : '*');
01026     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_PUSH) ? 'P' : '*');
01027     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_RST)  ? 'R' : '*');
01028     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_SYN)  ? 'S' : '*');
01029     *flagBuffer++ = (char) ((p->tcph->th_flags & TH_FIN)  ? 'F' : '*');
01030     *flagBuffer = '\0';
01031 
01032 }
01033 
01034 
01035 /****************************************************************************
01036  *
01037  * Function: PrintUDPHeader(FILE *)
01038  *
01039  * Purpose: Dump the UDP header to the specified file stream
01040  *
01041  * Arguments: fp => file stream
01042  *
01043  * Returns: void function
01044  *
01045  ***************************************************************************/
01046 void PrintUDPHeader(FILE * fp, Packet * p)
01047 {
01048 
01049     if(p->udph == NULL)
01050     {
01051         fprintf(fp, "UDP header truncated\n");
01052         return;
01053     }
01054     /* not much to do here... */
01055     fprintf(fp, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN);
01056 }
01057 
01058 
01059 
01060 /****************************************************************************
01061  *
01062  * Function: PrintICMPHeader(FILE *)
01063  *
01064  * Purpose: Print ICMP header
01065  *
01066  * Arguments: fp => file stream
01067  *
01068  * Returns: void function
01069  *
01070  ***************************************************************************/
01071 void PrintICMPHeader(FILE * fp, Packet * p)
01072 {
01073     if(p->icmph == NULL)
01074     {
01075         fprintf(fp, "ICMP header truncated\n");
01076         return;
01077     }
01078 
01079     fprintf(fp, "Type:%d  Code:%d  ", p->icmph->type, p->icmph->code);
01080 
01081     switch(p->icmph->type)
01082     {
01083         case ICMP_ECHOREPLY:
01084             fprintf(fp, "ID:%d  Seq:%d  ", ntohs(p->icmph->s_icmp_id), 
01085                     ntohs(p->icmph->s_icmp_seq));
01086             fwrite("ECHO REPLY\n", 10, 1, fp);
01087             break;
01088 
01089         case ICMP_DEST_UNREACH:
01090             fwrite("DESTINATION UNREACHABLE: ", 25, 1, fp);
01091             switch(p->icmph->code)
01092             {
01093                 case ICMP_NET_UNREACH:
01094                     fwrite("NET UNREACHABLE", 15, 1, fp);
01095                     break;
01096 
01097                 case ICMP_HOST_UNREACH:
01098                     fwrite("HOST UNREACHABLE", 16, 1, fp);
01099                     break;
01100 
01101                 case ICMP_PROT_UNREACH:
01102                     fwrite("PROTOCOL UNREACHABLE", 20, 1, fp);
01103                     break;
01104 
01105                 case ICMP_PORT_UNREACH:
01106                     fwrite("PORT UNREACHABLE", 16, 1, fp);
01107                     break;
01108 
01109                 case ICMP_FRAG_NEEDED:
01110                     fprintf(fp, "FRAGMENTATION NEEDED, DF SET\n"
01111                             "NEXT LINK MTU: %u",
01112                             ntohs(p->icmph->s_icmp_nextmtu));
01113                     break;
01114 
01115                 case ICMP_SR_FAILED:
01116                     fwrite("SOURCE ROUTE FAILED", 19, 1, fp);
01117                     break;
01118 
01119                 case ICMP_NET_UNKNOWN:
01120                     fwrite("NET UNKNOWN", 11, 1, fp);
01121                     break;
01122 
01123                 case ICMP_HOST_UNKNOWN:
01124                     fwrite("HOST UNKNOWN", 12, 1, fp);
01125                     break;
01126 
01127                 case ICMP_HOST_ISOLATED:
01128                     fwrite("HOST ISOLATED", 13, 1, fp);
01129                     break;
01130 
01131                 case ICMP_PKT_FILTERED_NET:
01132                     fwrite("ADMINISTRATIVELY PROHIBITED NETWORK FILTERED", 44, 
01133                             1, fp);
01134                     break;
01135 
01136                 case ICMP_PKT_FILTERED_HOST:
01137                     fwrite("ADMINISTRATIVELY PROHIBITED HOST FILTERED", 41, 
01138                             1, fp);
01139                     break;
01140 
01141                 case ICMP_NET_UNR_TOS:
01142                     fwrite("NET UNREACHABLE FOR TOS", 23, 1, fp);
01143                     break;
01144 
01145                 case ICMP_HOST_UNR_TOS:
01146                     fwrite("HOST UNREACHABLE FOR TOS", 24, 1, fp);
01147                     break;
01148 
01149                 case ICMP_PKT_FILTERED:
01150                     fwrite("ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED", 44,
01151                            1, fp);
01152                     break;
01153 
01154                 case ICMP_PREC_VIOLATION:
01155                     fwrite("PREC VIOLATION", 14, 1, fp);
01156                     break;
01157 
01158                 case ICMP_PREC_CUTOFF:
01159                     fwrite("PREC CUTOFF", 12, 1, fp);
01160                     break;
01161 
01162                 default:
01163                     fwrite("UNKNOWN", 7, 1, fp);
01164                     break;
01165 
01166             }
01167             {
01168                 Packet op;
01169                 Packet *orig_p;
01170                 int orig_iph_size;
01171 
01172                 bzero((char *) &op, sizeof(Packet));
01173                 orig_p = &op;
01174                 orig_p->iph = p->orig_iph;
01175                 orig_p->tcph = p->orig_tcph;
01176                 orig_p->udph = p->orig_udph;
01177                 orig_p->sp = p->orig_sp;
01178                 orig_p->dp = p->orig_dp;
01179 
01180                 if(orig_p->iph != NULL)
01181                 {
01182                     orig_iph_size = IP_HLEN(orig_p->iph) << 2;
01183 
01184                     fprintf(fp, "\n** ORIGINAL DATAGRAM DUMP:\n");
01185                     PrintIPHeader(fp, orig_p);
01186 
01187                     switch(orig_p->iph->ip_proto)
01188                     {
01189                         case IPPROTO_TCP:
01190                             /* 
01191                              * we can only guarantee the first 8 bytes of the
01192                              * tcp header are encapsulated, so lets just print 
01193                              * them instead of freaking people out all the time
01194                              *   --MFR
01195                              */
01196                             if(orig_p->tcph != NULL)
01197                                 PrintEmbeddedTCPHeader(fp, orig_p, 
01198                                         p->dsize-orig_iph_size);
01199                             break;
01200 
01201                         case IPPROTO_UDP:
01202                             if(orig_p->udph != NULL)
01203                                 PrintUDPHeader(fp, orig_p);
01204                             break;
01205 
01206                         case IPPROTO_ICMP:
01207                             if(orig_p->icmph != NULL)
01208                                 fprintf(fp, "orig type: %d  code: %d\n", 
01209                                         orig_p->icmph->type, orig_p->icmph->code);
01210                             break;
01211 
01212                         default:
01213                             fprintf(fp, "Protocol: 0x%X (unknown or "
01214                                     "header truncated)", orig_p->iph->ip_proto);
01215                             break;
01216                     }       /* switch */
01217 
01218                     fprintf(fp, "** END OF DUMP");
01219                 }
01220                 else
01221                 {
01222                     fprintf(fp, "\nORIGINAL DATAGRAM TRUNCATED");
01223                 }
01224             }
01225             break;
01226 
01227         case ICMP_SOURCE_QUENCH:
01228             fwrite("SOURCE QUENCH", 13, 1, fp);
01229             break;
01230 
01231         case ICMP_REDIRECT:
01232             fwrite("REDIRECT", 8, 1, fp);
01233             switch(p->icmph->code)
01234             {
01235                 case ICMP_REDIR_NET:
01236                     fwrite(" NET", 4, 1, fp);
01237                     break;
01238 
01239                 case ICMP_REDIR_HOST:
01240                     fwrite(" HOST", 5, 1, fp);
01241                     break;
01242 
01243                 case ICMP_REDIR_TOS_NET:
01244                     fwrite(" TOS NET", 8, 1, fp);
01245                     break;
01246 
01247                 case ICMP_REDIR_TOS_HOST:
01248                     fwrite(" TOS HOST", 9, 1, fp);
01249                     break;
01250             }
01251              
01252             fprintf(fp, " NEW GW: %s", inet_ntoa(p->icmph->s_icmp_gwaddr));
01253 
01254             {
01255                 Packet op;
01256                 Packet *orig_p;
01257                 int orig_iph_size;
01258 
01259                 bzero((char *) &op, sizeof(Packet));
01260                 orig_p = &op;
01261 
01262                 orig_p->iph = p->orig_iph;
01263                 orig_p->tcph = p->orig_tcph;
01264                 orig_p->udph = p->orig_udph;
01265                 orig_p->sp = p->orig_sp;
01266                 orig_p->dp = p->orig_dp;
01267 
01268                 if(orig_p->iph != NULL)
01269                 {
01270                     orig_iph_size = IP_HLEN(orig_p->iph) << 2;
01271 
01272                     fprintf(fp, "\n** ORIGINAL DATAGRAM DUMP:\n");
01273                     PrintIPHeader(fp, orig_p);
01274 
01275                     switch(orig_p->iph->ip_proto)
01276                     {
01277                         case IPPROTO_TCP:
01278                             /* 
01279                              * we can only guarantee the first 8 bytes of the
01280                              * tcp header are encapsulated, so lets just print 
01281                              * them instead of freaking people out all the time
01282                              *   --MFR
01283                              */
01284                             if(orig_p->tcph != NULL)
01285                                 PrintEmbeddedTCPHeader(fp, orig_p, 
01286                                         p->dsize-orig_iph_size);
01287                             break;
01288 
01289                         case IPPROTO_UDP:
01290                             if(orig_p->udph != NULL)
01291                                 PrintUDPHeader(fp, orig_p);
01292                             break;
01293 
01294                         case IPPROTO_ICMP:
01295                             if(orig_p->icmph != NULL)
01296                                 fprintf(fp, "orig type: %d  code: %d\n", 
01297                                         orig_p->icmph->type, orig_p->icmph->code);
01298                             break;
01299 
01300                         default:
01301                             fprintf(fp, "Protocol: 0x%X (unknown or "
01302                                     "header truncated)", orig_p->iph->ip_proto);
01303                             break;
01304                     }       /* switch */
01305 
01306                     fprintf(fp, "** END OF DUMP");
01307                 }
01308                 else
01309                 {
01310                     fprintf(fp, "\nORIGINAL DATAGRAM TRUNCATED");
01311                 }
01312             }
01313                     
01314             break;
01315 
01316         case ICMP_ECHO:
01317             fprintf(fp, "ID:%d   Seq:%d  ", ntohs(p->icmph->s_icmp_id), 
01318                     ntohs(p->icmph->s_icmp_seq));
01319             fwrite("ECHO", 4, 1, fp);
01320             break;
01321 
01322         case ICMP_ROUTER_ADVERTISE:
01323             fprintf(fp, "ROUTER ADVERTISMENT: "
01324                     "Num addrs: %d Addr entry size: %d Lifetime: %u", 
01325                     p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa, 
01326                     ntohs(p->icmph->s_icmp_lifetime));
01327             break;
01328 
01329         case ICMP_ROUTER_SOLICIT:
01330             fwrite("ROUTER SOLICITATION", 19, 1, fp);
01331             break;
01332 
01333         case ICMP_TIME_EXCEEDED:
01334             fwrite("TTL EXCEEDED", 12, 1, fp);
01335             switch(p->icmph->code)
01336             {
01337                 case ICMP_TIMEOUT_TRANSIT:
01338                     fwrite(" IN TRANSIT", 11, 1, fp);
01339                     break;
01340 
01341                 case ICMP_TIMEOUT_REASSY:
01342                     fwrite(" TIME EXCEEDED IN FRAG REASSEMBLY", 33, 1, fp);
01343                     break;
01344             }
01345             break;
01346 
01347         case ICMP_PARAMETERPROB:
01348             fwrite("PARAMETER PROBLEM", 17, 1, fp);
01349             switch(p->icmph->code)
01350             {
01351                 case ICMP_PARAM_BADIPHDR:
01352                     fprintf(fp, ": BAD IP HEADER BYTE %u",
01353                             p->icmph->s_icmp_pptr);
01354                     break;
01355 
01356                 case ICMP_PARAM_OPTMISSING:
01357                     fwrite(": OPTION MISSING", 16, 1, fp);
01358                     break;
01359 
01360                 case ICMP_PARAM_BAD_LENGTH:
01361                     fwrite(": BAD LENGTH", 12, 1, fp);
01362                     break;
01363             }
01364             break;
01365 
01366         case ICMP_TIMESTAMP:
01367             fprintf(fp, "ID: %u  Seq: %u  TIMESTAMP REQUEST", 
01368                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
01369             break;
01370 
01371         case ICMP_TIMESTAMPREPLY:
01372             fprintf(fp, "ID: %u  Seq: %u  TIMESTAMP REPLY:\n"
01373                     "Orig: %u Rtime: %u  Ttime: %u", 
01374                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
01375                     p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime, 
01376                     p->icmph->s_icmp_ttime);
01377             break;
01378 
01379         case ICMP_INFO_REQUEST:
01380             fprintf(fp, "ID: %u  Seq: %u  INFO REQUEST", 
01381                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
01382             break;
01383 
01384         case ICMP_INFO_REPLY:
01385             fprintf(fp, "ID: %u  Seq: %u  INFO REPLY", 
01386                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
01387             break;
01388 
01389         case ICMP_ADDRESS:
01390             fprintf(fp, "ID: %u  Seq: %u  ADDRESS REQUEST", 
01391                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
01392             break;
01393 
01394         case ICMP_ADDRESSREPLY:
01395             fprintf(fp, "ID: %u  Seq: %u  ADDRESS REPLY: 0x%08X", 
01396                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
01397                     (u_int) ntohl(p->icmph->s_icmp_mask)); 
01398             break;
01399 
01400         default:
01401             fwrite("UNKNOWN", 7, 1, fp);
01402 
01403             break;
01404     }
01405 
01406     putc('\n', fp);
01407 
01408 }
01409 
01410 
01411 void PrintIpOptions(FILE * fp, Packet * p)
01412 {
01413     int i;
01414     int j;
01415     u_long init_offset;
01416     u_long print_offset;
01417 
01418     init_offset = ftell(fp);
01419 
01420     if(!p->ip_option_count || p->ip_option_count > 40)
01421         return;
01422 
01423     fprintf(fp, "IP Options (%d) => ", p->ip_option_count);
01424 
01425     for(i = 0; i < (int) p->ip_option_count; i++)
01426     {
01427         print_offset = ftell(fp);
01428 
01429         if((print_offset - init_offset) > 60)
01430         {
01431             fwrite("\nIP Options => ", 15, 1, fp);
01432             init_offset = ftell(fp);
01433         }
01434             
01435         switch(p->ip_options[i].code)
01436         {
01437             case IPOPT_RR:
01438                 fwrite("RR ", 3, 1, fp);
01439                 break;
01440 
01441             case IPOPT_EOL:
01442                 fwrite("EOL ", 4, 1, fp);
01443                 break;
01444 
01445             case IPOPT_NOP:
01446                 fwrite("NOP ", 4, 1, fp);
01447                 break;
01448 
01449             case IPOPT_TS:
01450                 fwrite("TS ", 3, 1, fp);
01451                 break;
01452 
01453             case IPOPT_SECURITY:
01454                 fwrite("SEC ", 4, 1, fp);
01455                 break;
01456 
01457             case IPOPT_LSRR:
01458             case IPOPT_LSRR_E:
01459                 fwrite("LSRR ", 5, 1, fp);
01460                 break;
01461 
01462             case IPOPT_SATID:
01463                 fwrite("SID ", 4, 1, fp);
01464                 break;
01465 
01466             case IPOPT_SSRR:
01467                 fwrite("SSRR ", 5, 1, fp);
01468                 break;
01469 
01470             case IPOPT_RTRALT:
01471                 fwrite("RTRALT ", 7, 1, fp);
01472                 break;    
01473 
01474             default:
01475                 fprintf(fp, "Opt %d: ", p->ip_options[i].code);
01476 
01477                 if(p->ip_options[i].len)
01478                 {
01479                     for(j = 0; j < p->ip_options[i].len; j++)
01480                     {
01481                         if (p->ip_options[i].data)
01482                             fprintf(fp, "%02X", p->ip_options[i].data[j]);
01483                         else
01484                             fprintf(fp, "%02X", 0);
01485                         
01486                         if((j % 2) == 0)
01487                             fprintf(fp, " ");
01488                     }
01489                 }
01490                 break;
01491         }
01492     }
01493 
01494     fwrite("\n", 1, 1, fp);
01495 }
01496 
01497 
01498 void PrintTcpOptions(FILE * fp, Packet * p)
01499 {
01500     int i;
01501     int j;
01502     u_char tmp[5];
01503     u_long init_offset;
01504     u_long print_offset;
01505 
01506     init_offset = ftell(fp);
01507 
01508     fprintf(fp, "TCP Options (%d) => ", p->tcp_option_count);
01509 
01510     if(p->tcp_option_count > 40 || !p->tcp_option_count)
01511         return;
01512 
01513     for(i = 0; i < (int) p->tcp_option_count; i++)
01514     {
01515         print_offset = ftell(fp);
01516 
01517         if((print_offset - init_offset) > 60)
01518         {
01519             fwrite("\nTCP Options => ", 16, 1, fp);
01520             init_offset = ftell(fp);
01521         }
01522             
01523         switch(p->tcp_options[i].code)
01524         {
01525             case TCPOPT_MAXSEG:
01526                 bzero((char *) tmp, 5);
01527                 fwrite("MSS: ", 5, 1, fp);
01528                 if (p->tcp_options[i].data)
01529                     memcpy(tmp, p->tcp_options[i].data, 2);
01530                 fprintf(fp, "%u ", EXTRACT_16BITS(tmp));
01531                 break;
01532 
01533             case TCPOPT_EOL:
01534                 fwrite("EOL ", 4, 1, fp);
01535                 break;
01536 
01537             case TCPOPT_NOP:
01538                 fwrite("NOP ", 4, 1, fp);
01539                 break;
01540 
01541             case TCPOPT_WSCALE:
01542                 if (p->tcp_options[i].data)
01543                     fprintf(fp, "WS: %u ", p->tcp_options[i].data[0]);
01544                 else
01545                     fprintf(fp, "WS: %u ", 0);
01546                 break;
01547 
01548             case TCPOPT_SACK:
01549                 bzero((char *) tmp, 5);
01550                 if (p->tcp_options[i].data)
01551                     memcpy(tmp, p->tcp_options[i].data, 2);
01552                 fprintf(fp, "Sack: %u@", EXTRACT_16BITS(tmp));
01553                 bzero((char *) tmp, 5);
01554                 if (p->tcp_options[i].data)
01555                     memcpy(tmp, (p->tcp_options[i].data) + 2, 2);
01556                 fprintf(fp, "%u ", EXTRACT_16BITS(tmp));
01557                 break;
01558 
01559             case TCPOPT_SACKOK:
01560                 fwrite("SackOK ", 7, 1, fp);
01561                 break;
01562 
01563             case TCPOPT_ECHO:
01564                 bzero((char *) tmp, 5);
01565                 if (p->tcp_options[i].data)
01566                     memcpy(tmp, p->tcp_options[i].data, 4);
01567                 fprintf(fp, "Echo: %u ", EXTRACT_32BITS(tmp));
01568                 break;
01569 
01570             case TCPOPT_ECHOREPLY:
01571                 bzero((char *) tmp, 5);
01572                 if (p->tcp_options[i].data)
01573                     memcpy(tmp, p->tcp_options[i].data, 4);
01574                 fprintf(fp, "Echo Rep: %u ", EXTRACT_32BITS(tmp));
01575                 break;
01576 
01577             case TCPOPT_TIMESTAMP:
01578                 bzero((char *) tmp, 5);
01579                 if (p->tcp_options[i].data)
01580                     memcpy(tmp, p->tcp_options[i].data, 4);
01581                 fprintf(fp, "TS: %u ", EXTRACT_32BITS(tmp));
01582                 bzero((char *) tmp, 5);
01583                 if (p->tcp_options[i].data)
01584                     memcpy(tmp, (p->tcp_options[i].data) + 4, 4);
01585                 fprintf(fp, "%u ", EXTRACT_32BITS(tmp));
01586                 break;
01587 
01588             case TCPOPT_CC:
01589                 bzero((char *) tmp, 5);
01590                 if (p->tcp_options[i].data)
01591                     memcpy(tmp, p->tcp_options[i].data, 4);
01592                 fprintf(fp, "CC %u ", EXTRACT_32BITS(tmp));
01593                 break;
01594 
01595             case TCPOPT_CCNEW:
01596                 bzero((char *) tmp, 5);
01597                 if (p->tcp_options[i].data)
01598                     memcpy(tmp, p->tcp_options[i].data, 4);
01599                 fprintf(fp, "CCNEW: %u ", EXTRACT_32BITS(tmp));
01600                 break;
01601 
01602             case TCPOPT_CCECHO:
01603                 bzero((char *) tmp, 5);
01604                 if (p->tcp_options[i].data)
01605                     memcpy(tmp, p->tcp_options[i].data, 4);
01606                 fprintf(fp, "CCECHO: %u ", EXTRACT_32BITS(tmp));
01607                 break;
01608 
01609             default:
01610                 if(p->tcp_options[i].len)
01611                 {
01612                     fprintf(fp, "Opt %d (%d): ", p->tcp_options[i].code,
01613                             (int) p->tcp_options[i].len);
01614 
01615                     for(j = 0; j < p->tcp_options[i].len; j++)
01616                     {
01617                         if (p->tcp_options[i].data)
01618                             fprintf(fp, "%02X", p->tcp_options[i].data[j]);
01619                         else
01620                             fprintf(fp, "%02X", 0);
01621                         
01622                         if((j % 2) == 0)
01623                             fprintf(fp, " ");
01624                     }
01625                 }
01626                 else
01627                 {
01628                     fprintf(fp, "Opt %d ", p->tcp_options[i].code);
01629                 }
01630                 break;
01631         }
01632     }
01633 
01634     fwrite("\n", 1, 1, fp);
01635 }
01636 
01637 
01638 /*
01639  * Function: PrintPriorityData(FILE *)
01640  *
01641  * Purpose: Prints out priority data associated with an alert
01642  *
01643  * Arguments: fp => file descriptor to write the data to
01644  *            do_newline => tack a \n to the end of the line or not (bool)
01645  *
01646  * Returns: void function
01647  */ 
01648 void PrintPriorityData(FILE *fp, int do_newline)
01649 {
01650 
01651     if(!otn_tmp)
01652         return;
01653 
01654     if(otn_tmp->sigInfo.classType)
01655     {
01656         fprintf(fp, "[Classification: %s] [Priority: %d] ", 
01657                 otn_tmp->sigInfo.classType->name, 
01658                 otn_tmp->sigInfo.priority);
01659     }
01660     else
01661     {
01662         fprintf(fp, "[Priority: %d] ", 
01663                 otn_tmp->sigInfo.priority);
01664     }
01665     if(do_newline)
01666         fprintf(fp, "\n");
01667 
01668 }
01669 
01670         
01671 /*
01672  * Function: PrintXrefs(FILE *)
01673  *
01674  * Purpose: Prints out cross reference data associated with an alert
01675  *
01676  * Arguments: fp => file descriptor to write the data to
01677  *            do_newline => tack a \n to the end of the line or not (bool)
01678  *
01679  * Returns: void function
01680  */ 
01681 void PrintXrefs(FILE *fp, int do_newline)
01682 {
01683     ReferenceNode *refNode = NULL;
01684 
01685     if(otn_tmp)
01686     {
01687         refNode = otn_tmp->sigInfo.refs;
01688 
01689         while(refNode  != NULL)
01690         {
01691             FPrintReference(fp, refNode);
01692             refNode = refNode->next;
01693 
01694             /* on the last loop through, print a newline in
01695                Full mode */
01696             if(do_newline && (refNode == NULL))
01697                 fprintf(fp, "\n");
01698         }
01699     }
01700 }
01701 
01702 
01703 /* This function name is being altered for Win32 because it
01704    conflicts with a Win32 SDK function name.  However calls to
01705    this function from within Snort do not need to change because
01706    SetEvent() is defined in log.h to evaluate to SnortSetEvent()
01707    on Win32 compiles.
01708  */
01709 #ifndef WIN32
01710 void SetEvent
01711 #else
01712 void SnortSetEvent
01713 #endif
01714        (Event *event, u_int32_t generator, u_int32_t id, u_int32_t rev, 
01715         u_int32_t classification, u_int32_t priority, u_int32_t event_ref)
01716 {
01717     event->sig_generator = generator;
01718     event->sig_id = id;
01719     event->sig_rev = rev;
01720     event->classification = classification;
01721     event->priority = priority;
01722     /* this one gets set automatically */
01723     event->event_id = ++event_id | pv.event_log_id;
01724     if(event_ref)
01725         event->event_reference = event_ref;
01726     else
01727         event->event_reference = event->event_id;
01728 
01729     event->ref_time.tv_sec = 0;
01730 
01731     return;
01732 }
01733 
01734 /*
01735  * Function: PrintEapolPkt(FILE *, Packet *)
01736  *
01737  * Purpose: Dump the packet to the stream pointer
01738  *
01739  * Arguments: fp => pointer to print data to
01740  *            type => packet protocol
01741  *            p => pointer to decoded packet struct
01742  *
01743  * Returns: void function
01744  */
01745 void PrintEapolPkt(FILE * fp, Packet * p)
01746 {
01747   char timestamp[TIMEBUF_SIZE];
01748   
01749 
01750     bzero((char *) timestamp, TIMEBUF_SIZE);
01751     ts_print((struct timeval *) & p->pkth->ts, timestamp);
01752 
01753     /* dump the timestamp */
01754     fwrite(timestamp, strlen(timestamp), 1, fp);
01755 
01756     /* dump the ethernet header if we're doing that sort of thing */
01757     if(pv.show2hdr_flag)
01758     {
01759         Print2ndHeader(fp, p);
01760     }
01761     PrintEapolHeader(fp, p);
01762     if (p->eplh->eaptype == EAPOL_TYPE_EAP) {
01763       PrintEAPHeader(fp, p);
01764     }
01765     else if (p->eplh->eaptype == EAPOL_TYPE_KEY) {
01766       PrintEapolKey(fp, p);
01767     }
01768 
01769     /* dump the application layer data */
01770     if(pv.data_flag && !pv.verbose_bytedump_flag)
01771       {
01772         if(pv.char_data_flag)
01773           PrintCharData(fp, (char*) p->data, p->dsize);
01774         else
01775           PrintNetData(fp, p->data, p->dsize);
01776       }
01777     else if(pv.verbose_bytedump_flag)
01778       {
01779         PrintNetData(fp, p->pkt, p->pkth->caplen);
01780       }
01781     
01782     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");    
01783 }
01784 
01785 /****************************************************************************
01786  *
01787  * Function: PrintWifiHeader(FILE *)
01788  *
01789  * Purpose: Print the packet 802.11 header to the specified stream
01790  *
01791  * Arguments: fp => file stream to print to
01792  *
01793  * Returns: void function
01794  *
01795  ***************************************************************************/
01796 void PrintWifiHeader(FILE * fp, Packet * p)
01797 {
01798   /* This assumes we are printing a data packet, could be changed
01799      to print other types as well */
01800   u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL,
01801     *ta = NULL;
01802   /* per table 4, IEEE802.11 section 7.2.2 */
01803   if ((p->wifih->frame_control & WLAN_FLAG_TODS) &&
01804       (p->wifih->frame_control & WLAN_FLAG_FROMDS)) {
01805     ra = p->wifih->addr1;
01806     ta = p->wifih->addr2;
01807     da = p->wifih->addr3;
01808     sa = p->wifih->addr4;
01809   }
01810   else if (p->wifih->frame_control & WLAN_FLAG_TODS) {
01811     bssid = p->wifih->addr1;
01812     sa = p->wifih->addr2;
01813     da = p->wifih->addr3;
01814   }
01815   else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) {
01816     da = p->wifih->addr1;
01817     bssid = p->wifih->addr2;
01818     sa = p->wifih->addr3;
01819   }
01820   else {
01821     da = p->wifih->addr1;
01822     sa = p->wifih->addr2;
01823     bssid = p->wifih->addr3;
01824   }
01825   
01826   /* DO this switch to provide additional info on the type */
01827   switch(p->wifih->frame_control & 0x00ff)
01828   {
01829   case WLAN_TYPE_MGMT_BEACON:
01830     fprintf(fp, "Beacon ");
01831     break;
01832     /* management frames */
01833   case WLAN_TYPE_MGMT_ASREQ:
01834     fprintf(fp, "Assoc. Req. ");
01835     break;
01836   case WLAN_TYPE_MGMT_ASRES:
01837     fprintf(fp, "Assoc. Resp. ");
01838     break;
01839   case WLAN_TYPE_MGMT_REREQ:
01840     fprintf(fp, "Reassoc. Req. ");
01841     break;
01842   case WLAN_TYPE_MGMT_RERES:
01843     fprintf(fp, "Reassoc. Resp. ");
01844     break;
01845   case WLAN_TYPE_MGMT_PRREQ:
01846     fprintf(fp, "Probe Req. ");
01847     break;
01848   case WLAN_TYPE_MGMT_PRRES:
01849     fprintf(fp, "Probe Resp. ");
01850     break;
01851   case WLAN_TYPE_MGMT_ATIM:
01852     fprintf(fp, "ATIM ");
01853     break;
01854   case WLAN_TYPE_MGMT_DIS:
01855     fprintf(fp, "Dissassoc. ");
01856     break;
01857   case WLAN_TYPE_MGMT_AUTH:
01858     fprintf(fp, "Authent. ");
01859     break;
01860   case WLAN_TYPE_MGMT_DEAUTH:
01861     fprintf(fp, "Deauthent. ");
01862     break;
01863     
01864     /* Control frames */
01865   case WLAN_TYPE_CONT_PS:
01866   case WLAN_TYPE_CONT_RTS:
01867   case WLAN_TYPE_CONT_CTS:
01868   case WLAN_TYPE_CONT_ACK:
01869   case WLAN_TYPE_CONT_CFE:
01870   case WLAN_TYPE_CONT_CFACK:
01871     fprintf(fp, "Control ");
01872     break;
01873   }  
01874   
01875   if (sa != NULL) {
01876     fprintf(fp, "%X:%X:%X:%X:%X:%X -> ", sa[0],
01877             sa[1], sa[2], sa[3], sa[4], sa[5]);
01878   }
01879   else {
01880     fprintf(fp, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0],
01881             ta[1], ta[2], ta[3], ta[4], ta[5]);
01882   } 
01883   
01884   fprintf(fp, "%X:%X:%X:%X:%X:%X\n", da[0],
01885           da[1], da[2], da[3], da[4], da[5]);
01886 
01887   if(bssid)
01888   {
01889       fprintf(fp, "bssid: %X:%X:%X:%X:%X:%X", bssid[0],
01890               bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
01891   }
01892   
01893   if (ra != NULL) {
01894     fprintf(fp, " ra: %X:%X:%X:%X:%X:%X", ra[0],
01895             ra[1], ra[2], ra[3], ra[4], ra[5]);
01896   }
01897   fprintf(fp, " Flags:");
01898   if (p->wifih->frame_control & WLAN_FLAG_TODS)    fprintf(fp," ToDs");
01899   if (p->wifih->frame_control & WLAN_FLAG_TODS)    fprintf(fp," FrDs");
01900   if (p->wifih->frame_control & WLAN_FLAG_FRAG)    fprintf(fp," Frag");
01901   if (p->wifih->frame_control & WLAN_FLAG_RETRY)   fprintf(fp," Re");
01902   if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) fprintf(fp," Pwr");
01903   if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) fprintf(fp," MD");
01904   if (p->wifih->frame_control & WLAN_FLAG_WEP)   fprintf(fp," Wep");
01905   if (p->wifih->frame_control & WLAN_FLAG_ORDER)  fprintf(fp," Ord");
01906   fprintf(fp, "\n");
01907 }
01908 
01909 /*
01910  * Function: PrintWifiPkt(FILE *, Packet *)
01911  *
01912  * Purpose: Dump the packet to the stream pointer
01913  *
01914  * Arguments: fp => pointer to print data to
01915  *            p => pointer to decoded packet struct
01916  *
01917  * Returns: void function
01918  */
01919 void PrintWifiPkt(FILE * fp, Packet * p)
01920 {
01921     char timestamp[TIMEBUF_SIZE];
01922 
01923 
01924     bzero((char *) timestamp, TIMEBUF_SIZE);
01925     ts_print((struct timeval *) & p->pkth->ts, timestamp);
01926 
01927     /* dump the timestamp */
01928     fwrite(timestamp, strlen(timestamp), 1, fp);
01929 
01930     /* dump the ethernet header if we're doing that sort of thing */
01931     Print2ndHeader(fp, p);
01932 
01933     /* dump the application layer data */
01934     if(pv.data_flag && !pv.verbose_bytedump_flag)
01935     {
01936         if(pv.char_data_flag)
01937             PrintCharData(fp, (char*) p->data, p->dsize);
01938         else
01939             PrintNetData(fp, p->data, p->dsize);
01940     }
01941     else if(pv.verbose_bytedump_flag)
01942     {
01943         PrintNetData(fp, p->pkt, p->pkth->caplen);
01944     }
01945 
01946     fprintf(fp, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
01947             "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+\n\n");
01948 }
01949 
01950 /****************************************************************************
01951  *
01952  * Function: PrintEapolHeader(FILE *, Packet *)
01953  *
01954  * Purpose: Dump the EAPOL header info to the specified stream
01955  *
01956  * Arguments: fp => stream to print to
01957  *
01958  * Returns: void function
01959  *
01960  ***************************************************************************/
01961 void PrintEapolHeader(FILE * fp, Packet * p)
01962 {
01963     fprintf(fp, "EAPOL type: ");
01964     switch(p->eplh->eaptype) {
01965     case EAPOL_TYPE_EAP:
01966       fprintf(fp, "EAP");
01967       break;
01968     case EAPOL_TYPE_START:
01969       fprintf(fp, "Start");
01970       break;
01971     case EAPOL_TYPE_LOGOFF:
01972       fprintf(fp, "Logoff");
01973       break;
01974     case EAPOL_TYPE_KEY:
01975       fprintf(fp, "Key");
01976       break;
01977     case EAPOL_TYPE_ASF:
01978       fprintf(fp, "ASF Alert");
01979       break;
01980     default:
01981       fprintf(fp, "Unknown");
01982     }
01983     fprintf(fp, " Len: %d\n", ntohs(p->eplh->len));
01984 }
01985 
01986 /****************************************************************************
01987  *
01988  * Function: PrintEAPHeader(FILE *)
01989  *
01990  * Purpose: Dump the EAP header to the specified file stream
01991  *
01992  * Arguments: fp => file stream
01993  *
01994  * Returns: void function
01995  *
01996  ***************************************************************************/
01997 void PrintEAPHeader(FILE * fp, Packet * p)
01998 {
01999 
02000     if(p->eaph == NULL)
02001     {
02002         fprintf(fp, "EAP header truncated\n");
02003         return;
02004     }
02005     fprintf(fp, "code: ");
02006     switch(p->eaph->code) {
02007     case EAP_CODE_REQUEST:
02008       fprintf(fp, "Req ");
02009       break;
02010     case EAP_CODE_RESPONSE:
02011       fprintf(fp, "Resp");
02012       break;
02013     case EAP_CODE_SUCCESS:
02014       fprintf(fp, "Succ");
02015       break;
02016     case EAP_CODE_FAILURE:
02017       fprintf(fp, "Fail");
02018       break;
02019     }
02020     fprintf(fp, " id: 0x%x len: %d", p->eaph->id, ntohs(p->eaph->len));
02021     if (p->eaptype != NULL) {
02022       fprintf(fp, " type: ");
02023       switch(*(p->eaptype)) {
02024       case EAP_TYPE_IDENTITY:
02025         fprintf(fp, "id");
02026         break;
02027       case EAP_TYPE_NOTIFY:
02028         fprintf(fp, "notify");
02029         break;
02030       case EAP_TYPE_NAK:
02031         fprintf(fp, "nak");
02032         break;
02033       case EAP_TYPE_MD5:
02034         fprintf(fp, "md5");
02035         break;
02036       case EAP_TYPE_OTP:
02037         fprintf(fp, "otp");
02038         break;
02039       case EAP_TYPE_GTC:
02040         fprintf(fp, "token");
02041         break;
02042       case EAP_TYPE_TLS:
02043         fprintf(fp, "tls");
02044         break;
02045       default:
02046         fprintf(fp, "undef");
02047         break;
02048       }
02049     }
02050     fprintf(fp, "\n");
02051 }
02052 
02053 
02054 /****************************************************************************
02055  *
02056  * Function: PrintEapolKey(FILE *)
02057  *
02058  * Purpose: Dump the EAP header to the specified file stream
02059  *
02060  * Arguments: fp => file stream
02061  *
02062  * Returns: void function
02063  *
02064  ***************************************************************************/
02065 void PrintEapolKey(FILE * fp, Packet * p)
02066 {
02067     u_int16_t length;
02068     
02069     if(p->eapolk == NULL)
02070     {
02071         fprintf(fp, "Eapol Key truncated\n");
02072         return;
02073     }
02074     fprintf(fp, "KEY type: ");
02075     if (p->eapolk->type == 1) {
02076       fprintf(fp, "RC4");
02077     }
02078 
02079     memcpy(&length, &p->eapolk->length, 2);
02080     length = ntohs(length);
02081     fprintf(fp, " len: %d", length);
02082     fprintf(fp, " index: %d ", p->eapolk->index & 0x7F);
02083     fprintf(fp, p->eapolk->index & 0x80 ? " unicast\n" : " broadcast\n");
02084     
02085 
02086 }

Generated on Sun May 14 14:51:13 2006 by  doxygen 1.4.2