"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/log_text.c" (16 Oct 2020, 54573 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "log_text.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /* $Id$ */
    2 /*
    3 ** Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    4 ** Copyright (C) 2002-2013 Sourcefire, Inc.
    5 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
    6 **
    7 ** This program is free software; you can redistribute it and/or modify
    8 ** it under the terms of the GNU General Public License Version 2 as
    9 ** published by the Free Software Foundation.  You may not use, modify or
   10 ** distribute this program under any other version of the GNU General
   11 ** Public License.
   12 **
   13 ** This program is distributed in the hope that it will be useful,
   14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16 ** GNU General Public License for more details.
   17 **
   18 ** You should have received a copy of the GNU General Public License
   19 ** along with this program; if not, write to the Free Software
   20 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   21 */
   22 
   23 // @file    log_text.c
   24 // @author  Russ Combs <rcombs@sourcefire.com>
   25 
   26 #ifdef HAVE_CONFIG_H
   27 #include "config.h"
   28 #endif
   29 
   30 #include <sys/types.h>
   31 #include <stdlib.h>
   32 #include <string.h>
   33 
   34 #ifdef HAVE_STRINGS_H
   35 #include <strings.h>
   36 #endif
   37 
   38 #ifndef WIN32
   39 #include <sys/socket.h>
   40 #include <netinet/in.h>
   41 #include <arpa/inet.h>
   42 #endif /* !WIN32 */
   43 #include <errno.h>
   44 #include <signal.h>
   45 
   46 #include "log.h"
   47 #include "rules.h"
   48 #include "treenodes.h"
   49 #include "util.h"
   50 #include "snort_debug.h"
   51 #include "signature.h"
   52 #include "util_net.h"
   53 
   54 #include "snort.h"
   55 #include "log_text.h"
   56 #include "sfutil/sf_textlog.h"
   57 #include "snort_bounds.h"
   58 #include "obfuscation.h"
   59 #include "detection_util.h"
   60 
   61 #include "sfutil/sf_ip.h"
   62 
   63 extern OptTreeNode *otn_tmp;    /* global ptr to current rule data */
   64 
   65 extern int IsGzipData(void *);
   66 extern int IsJSNormData(void *);
   67 
   68 /*--------------------------------------------------------------------
   69  * utility functions
   70  *--------------------------------------------------------------------
   71  */
   72 void LogTimeStamp(TextLog* log, Packet* p)
   73 {
   74     char timestamp[TIMEBUF_SIZE];
   75     ts_print((struct timeval*)&p->pkth->ts, timestamp);
   76     TextLog_Puts(log, timestamp);
   77 }
   78 
   79 /*--------------------------------------------------------------------
   80  * alert stuff cloned from log.c
   81  *--------------------------------------------------------------------
   82  */
   83 /*--------------------------------------------------------------------
   84  * Function: LogPriorityData()
   85  *
   86  * Purpose: Prints out priority data associated with an alert
   87  *
   88  * Arguments: log => pointer to TextLog to write the data to
   89  *            doNewLine => tack a \n to the end of the line or not (bool)
   90  *
   91  * Returns: void function
   92  *--------------------------------------------------------------------
   93  */
   94 void LogPriorityData(TextLog* log, bool doNewLine)
   95 {
   96     if (otn_tmp == NULL)
   97         return;
   98 
   99     if ((otn_tmp->sigInfo.classType != NULL)
  100             && (otn_tmp->sigInfo.classType->name != NULL))
  101     {
  102         TextLog_Print(log, "[Classification: %s] ",
  103                 otn_tmp->sigInfo.classType->name);
  104     }
  105 
  106     TextLog_Print(log, "[Priority: %d] ", otn_tmp->sigInfo.priority);
  107 
  108     if (doNewLine)
  109         TextLog_NewLine(log);
  110 }
  111 
  112 #if defined(FEAT_OPEN_APPID)
  113 /*--------------------------------------------------------------------
  114  * Function: LogAppID()
  115  *
  116  * Purpose: Prints out AppID data associated with an alert
  117  *
  118  * Arguments: log => pointer to TextLog to write the data to
  119  *            appName => name of app ID detected (if any)
  120  *            doNewLine => tack a \n to the end of the line or not (bool)
  121  *
  122  * Returns: void function
  123  *--------------------------------------------------------------------
  124  */
  125 void LogAppID(TextLog* log, const char* appName, bool doNewLine)
  126 {
  127     if (!appName || !appName[0])
  128         return;
  129 
  130     TextLog_Print(log, "[AppID: %s] ", appName);
  131 
  132     if (doNewLine)
  133         TextLog_NewLine(log);
  134 }
  135 #endif
  136 
  137 /*--------------------------------------------------------------------
  138  * Layer 2 header stuff cloned from log.c
  139  *--------------------------------------------------------------------
  140  */
  141 #ifndef NO_NON_ETHER_DECODER
  142 /*--------------------------------------------------------------------
  143  * Function: LogTrHeader(TextLog*, Packet*)
  144  *
  145  * Purpose: Print the packet TokenRing header to the given TextLog
  146  *
  147  * Arguments: log => pointer to TextLog to print to
  148  *
  149  * Returns: void function
  150  *--------------------------------------------------------------------
  151  */
  152 
  153 void LogTrHeader(TextLog* log, Packet* p)
  154 {
  155 
  156     TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0],
  157             p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3],
  158             p->trh->saddr[4], p->trh->saddr[5]);
  159     TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0],
  160             p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3],
  161             p->trh->daddr[4], p->trh->daddr[5]);
  162 
  163     TextLog_Print(log, "access control:0x%X frame control:0x%X\n", p->trh->ac,
  164             p->trh->fc);
  165     if(!p->trhllc)
  166         return;
  167     TextLog_Print(log, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n",
  168             p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0],
  169             p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype);
  170     if(p->trhmr)
  171     {
  172         TextLog_Print(log, "RIF structure is present:\n");
  173         TextLog_Print(log, "bcast: 0x%X length: 0x%X direction: 0x%X largest"
  174                 "fr. size: 0x%X res: 0x%X\n",
  175                 TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr),
  176         TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr),
  177                 TRH_MR_RES(p->trhmr));
  178         TextLog_Print(log, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n",
  179                 p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2],
  180                 p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5],
  181                 p->trhmr->rseg[6], p->trhmr->rseg[7]);
  182     }
  183 }
  184 #endif  // NO_NON_ETHER_DECODER
  185 
  186 /*--------------------------------------------------------------------
  187  * Function: LogEthHeader()
  188  *
  189  * Purpose: Print the packet Ethernet header to the given TextLog
  190  *
  191  * Arguments: log => pointer to TextLog to print to
  192  *
  193  * Returns: void function
  194  *--------------------------------------------------------------------
  195  */
  196 static void LogEthHeader(TextLog* log, Packet* p)
  197 {
  198     /* src addr */
  199     TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X -> ", p->eh->ether_src[0],
  200         p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3],
  201         p->eh->ether_src[4], p->eh->ether_src[5]);
  202 
  203     /* dest addr */
  204     TextLog_Print(log, "%02X:%02X:%02X:%02X:%02X:%02X ", p->eh->ether_dst[0],
  205         p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3],
  206         p->eh->ether_dst[4], p->eh->ether_dst[5]);
  207 
  208     /* protocol and pkt size */
  209     TextLog_Print(log, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type),
  210         p->pkth->pktlen);
  211 }
  212 
  213 #ifdef MPLS
  214 static void LogMPLSHeader(TextLog* log, Packet* p)
  215 {
  216 
  217     TextLog_Print(log,"label:0x%05X exp:0x%X bos:0x%X ttl:0x%X\n",
  218         p->mplsHdr.label, p->mplsHdr.exp, p->mplsHdr.bos, p->mplsHdr.ttl);
  219 }
  220 #endif
  221 
  222 #ifdef GRE
  223 static void LogGREHeader(TextLog *log, Packet *p)
  224 {
  225     if (p->greh == NULL)
  226         return;
  227 
  228     TextLog_Print(log, "GRE version:%u flags:0x%02X ether-type:0x%04X\n",
  229             GRE_VERSION(p->greh), p->greh->flags, GRE_PROTO(p->greh));
  230 }
  231 #endif
  232 
  233 #ifndef NO_NON_ETHER_DECODER
  234 /*--------------------------------------------------------------------
  235  * Function: LogSLLHeader(TextLog* )
  236  *
  237  * Purpose: Print the packet SLL (fake) header to the given TextLog
  238  * (piece partly is borrowed from tcpdump :))
  239  *
  240  * Arguments: log => pointer to TextLog to print to
  241  *
  242  * Returns: void function
  243  *--------------------------------------------------------------------
  244  */
  245 #ifdef DLT_LINUX_SLL
  246 static void LogSLLHeader(TextLog* log, Packet* p)
  247 {
  248     switch (ntohs(p->sllh->sll_pkttype)) {
  249         case LINUX_SLL_HOST:
  250             TextLog_Puts(log, "< ");
  251             break;
  252         case LINUX_SLL_BROADCAST:
  253             TextLog_Puts(log, "B ");
  254             break;
  255         case LINUX_SLL_MULTICAST:
  256             TextLog_Puts(log, "M ");
  257             break;
  258         case LINUX_SLL_OTHERHOST:
  259             TextLog_Puts(log, "P ");
  260             break;
  261         case LINUX_SLL_OUTGOING:
  262             TextLog_Puts(log, "> ");
  263             break;
  264         default:
  265             TextLog_Puts(log, "? ");
  266             break;
  267         }
  268 
  269     /* mac addr */
  270     TextLog_Print(log, "l/l len: %i l/l type: 0x%X %02X:%02X:%02X:%02X:%02X:%02X\n",
  271         htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype),
  272         p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2],
  273         p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]);
  274 
  275     /* protocol and pkt size */
  276     TextLog_Print(log, "pkt type:0x%X proto: 0x%X len:0x%X\n",
  277         ntohs(p->sllh->sll_pkttype),
  278         ntohs(p->sllh->sll_protocol), p->pkth->pktlen);
  279 }
  280 #endif
  281 
  282 /*--------------------------------------------------------------------
  283  * Function: LogWifiHeader(TextLog* )
  284  *
  285  * Purpose: Print the packet 802.11 header to the given TextLog
  286  *
  287  * Arguments: log => pointer to TextLog to print to
  288  *
  289  * Returns: void function
  290  *--------------------------------------------------------------------
  291  */
  292 static void LogWifiHeader(TextLog* log, Packet * p)
  293 {
  294   /* This assumes we are printing a data packet, could be changed
  295      to print other types as well */
  296   const u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL,
  297     *ta = NULL;
  298   /* per table 4, IEEE802.11 section 7.2.2 */
  299   if ((p->wifih->frame_control & WLAN_FLAG_TODS) &&
  300       (p->wifih->frame_control & WLAN_FLAG_FROMDS)) {
  301     ra = p->wifih->addr1;
  302     ta = p->wifih->addr2;
  303     da = p->wifih->addr3;
  304     sa = p->wifih->addr4;
  305   }
  306   else if (p->wifih->frame_control & WLAN_FLAG_TODS) {
  307     bssid = p->wifih->addr1;
  308     sa = p->wifih->addr2;
  309     da = p->wifih->addr3;
  310   }
  311   else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) {
  312     da = p->wifih->addr1;
  313     bssid = p->wifih->addr2;
  314     sa = p->wifih->addr3;
  315   }
  316   else {
  317     da = p->wifih->addr1;
  318     sa = p->wifih->addr2;
  319     bssid = p->wifih->addr3;
  320   }
  321 
  322   /* DO this switch to provide additional info on the type */
  323   switch(p->wifih->frame_control & 0x00ff)
  324   {
  325   case WLAN_TYPE_MGMT_BEACON:
  326     TextLog_Puts(log, "Beacon ");
  327     break;
  328     /* management frames */
  329   case WLAN_TYPE_MGMT_ASREQ:
  330     TextLog_Puts(log, "Assoc. Req. ");
  331     break;
  332   case WLAN_TYPE_MGMT_ASRES:
  333     TextLog_Puts(log, "Assoc. Resp. ");
  334     break;
  335   case WLAN_TYPE_MGMT_REREQ:
  336     TextLog_Puts(log, "Reassoc. Req. ");
  337     break;
  338   case WLAN_TYPE_MGMT_RERES:
  339     TextLog_Puts(log, "Reassoc. Resp. ");
  340     break;
  341   case WLAN_TYPE_MGMT_PRREQ:
  342     TextLog_Puts(log, "Probe Req. ");
  343     break;
  344   case WLAN_TYPE_MGMT_PRRES:
  345     TextLog_Puts(log, "Probe Resp. ");
  346     break;
  347   case WLAN_TYPE_MGMT_ATIM:
  348     TextLog_Puts(log, "ATIM ");
  349     break;
  350   case WLAN_TYPE_MGMT_DIS:
  351     TextLog_Puts(log, "Dissassoc. ");
  352     break;
  353   case WLAN_TYPE_MGMT_AUTH:
  354     TextLog_Puts(log, "Authent. ");
  355     break;
  356   case WLAN_TYPE_MGMT_DEAUTH:
  357     TextLog_Puts(log, "Deauthent. ");
  358     break;
  359 
  360     /* Control frames */
  361   case WLAN_TYPE_CONT_PS:
  362   case WLAN_TYPE_CONT_RTS:
  363   case WLAN_TYPE_CONT_CTS:
  364   case WLAN_TYPE_CONT_ACK:
  365   case WLAN_TYPE_CONT_CFE:
  366   case WLAN_TYPE_CONT_CFACK:
  367     TextLog_Puts(log, "Control ");
  368     break;
  369   }
  370 
  371   if (sa != NULL) {
  372     TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", sa[0],
  373         sa[1], sa[2], sa[3], sa[4], sa[5]);
  374   }
  375   else if (ta != NULL) {
  376     TextLog_Print(log, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0],
  377         ta[1], ta[2], ta[3], ta[4], ta[5]);
  378   }
  379 
  380   TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", da[0],
  381       da[1], da[2], da[3], da[4], da[5]);
  382 
  383   if (bssid != NULL)
  384   {
  385       TextLog_Print(log, "bssid: %X:%X:%X:%X:%X:%X", bssid[0],
  386               bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
  387   }
  388 
  389   if (ra != NULL) {
  390     TextLog_Print(log, " ra: %X:%X:%X:%X:%X:%X", ra[0],
  391         ra[1], ra[2], ra[3], ra[4], ra[5]);
  392   }
  393   TextLog_Puts(log, " Flags:");
  394   if (p->wifih->frame_control & WLAN_FLAG_TODS)    TextLog_Puts(log," ToDs");
  395   if (p->wifih->frame_control & WLAN_FLAG_TODS)    TextLog_Puts(log," FrDs");
  396   if (p->wifih->frame_control & WLAN_FLAG_FRAG)    TextLog_Puts(log," Frag");
  397   if (p->wifih->frame_control & WLAN_FLAG_RETRY)   TextLog_Puts(log," Re");
  398   if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) TextLog_Puts(log," Pwr");
  399   if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) TextLog_Puts(log," MD");
  400   if (p->wifih->frame_control & WLAN_FLAG_WEP)     TextLog_Puts(log," Wep");
  401   if (p->wifih->frame_control & WLAN_FLAG_ORDER)   TextLog_Puts(log," Ord");
  402   TextLog_NewLine(log);
  403 }
  404 #endif  // NO_NON_ETHER_DECODER
  405 
  406 /*--------------------------------------------------------------------
  407  * Function: Log2ndHeader(TextLog* , Packet p)
  408  *
  409  * Purpose: Log2ndHeader -- prints second layber  header info.
  410  *
  411  * Arguments: log => pointer to TextLog to print to
  412  *
  413  * Returns: void function
  414  *--------------------------------------------------------------------
  415  */
  416 void Log2ndHeader(TextLog* log, Packet* p)
  417 {
  418 
  419     switch(DAQ_GetBaseProtocol())
  420     {
  421         case DLT_EN10MB:        /* Ethernet */
  422             if(p && p->eh)
  423                 LogEthHeader(log, p);
  424             break;
  425 #ifndef NO_NON_ETHER_DECODER
  426 #ifdef DLT_IEEE802_11
  427         case DLT_IEEE802_11:
  428             if(p && p->wifih)
  429                 LogWifiHeader(log, p);
  430             break;
  431 #endif
  432         case DLT_IEEE802:                /* Token Ring */
  433             if(p && p->trh)
  434                 LogTrHeader(log, p);
  435             break;
  436 #ifdef DLT_LINUX_SLL
  437         case DLT_LINUX_SLL:
  438             if (p && p->sllh)
  439                 LogSLLHeader(log, p);  /* Linux cooked sockets */
  440             break;
  441 #endif
  442 #endif  // NO_NON_ETHER_DECODER
  443         default:
  444             if (ScLogVerbose())
  445             {
  446                 // FIXTHIS should only be output once!
  447                 ErrorMessage("Datalink %i type 2nd layer display is not "
  448                              "supported\n", DAQ_GetBaseProtocol());
  449             }
  450     }
  451 }
  452 
  453 /*-------------------------------------------------------------------
  454  * IP stuff cloned from log.c
  455  *-------------------------------------------------------------------
  456  */
  457 static void LogIpOptions(TextLog*  log, Packet * p)
  458 {
  459     int i;
  460     int j;
  461     u_long init_offset;
  462     u_long print_offset;
  463 
  464     init_offset = TextLog_Tell(log);
  465 
  466     if(!p->ip_option_count || p->ip_option_count > 40)
  467         return;
  468 
  469     TextLog_Print(log, "IP Options (%d) => ", p->ip_option_count);
  470 
  471     for(i = 0; i < (int) p->ip_option_count; i++)
  472     {
  473         print_offset = TextLog_Tell(log);
  474 
  475         if((print_offset - init_offset) > 60)
  476         {
  477             TextLog_Puts(log, "\nIP Options => ");
  478             init_offset = TextLog_Tell(log);
  479         }
  480 
  481         switch(p->ip_options[i].code)
  482         {
  483             case IPOPT_RR:
  484                 TextLog_Puts(log, "RR ");
  485                 break;
  486 
  487             case IPOPT_EOL:
  488                 TextLog_Puts(log, "EOL ");
  489                 break;
  490 
  491             case IPOPT_NOP:
  492                 TextLog_Puts(log, "NOP ");
  493                 break;
  494 
  495             case IPOPT_TS:
  496                 TextLog_Puts(log, "TS ");
  497                 break;
  498 
  499             case IPOPT_ESEC:
  500                 TextLog_Puts(log, "ESEC ");
  501                 break;
  502 
  503             case IPOPT_SECURITY:
  504                 TextLog_Puts(log, "SEC ");
  505                 break;
  506 
  507             case IPOPT_LSRR:
  508             case IPOPT_LSRR_E:
  509                 TextLog_Puts(log, "LSRR ");
  510                 break;
  511 
  512             case IPOPT_SATID:
  513                 TextLog_Puts(log, "SID ");
  514                 break;
  515 
  516             case IPOPT_SSRR:
  517                 TextLog_Puts(log, "SSRR ");
  518                 break;
  519 
  520             case IPOPT_RTRALT:
  521                 TextLog_Puts(log, "RTRALT ");
  522                 break;
  523 
  524             default:
  525                 TextLog_Print(log, "Opt %d: ", p->ip_options[i].code);
  526 
  527                 if(p->ip_options[i].len)
  528                 {
  529                     for(j = 0; j < p->ip_options[i].len; j++)
  530                     {
  531                         if (p->ip_options[i].data)
  532                             TextLog_Print(log, "%02X", p->ip_options[i].data[j]);
  533                         else
  534                             TextLog_Print(log, "%02X", 0);
  535 
  536                         if((j % 2) == 0)
  537                             TextLog_Putc(log, ' ');
  538                     }
  539                 }
  540                 break;
  541         }
  542     }
  543     TextLog_NewLine(log);
  544 }
  545 
  546 /*--------------------------------------------------------------------
  547  * Function: LogIPAddrs(TextLog* )
  548  *
  549  * Purpose: Dump the IP addresses to the given TextLog
  550  *          Handles obfuscation
  551  *
  552  * Arguments: log => TextLog to print to
  553  *            p => packet structure
  554  *
  555  * Returns: void function
  556  *--------------------------------------------------------------------
  557  */
  558 void LogIpAddrs(TextLog *log, Packet *p)
  559 {
  560     if (!IPH_IS_VALID(p))
  561         return;
  562 
  563     if (p->frag_flag
  564             || ((GET_IPH_PROTO(p) != IPPROTO_TCP)
  565                 && (GET_IPH_PROTO(p) != IPPROTO_UDP)))
  566     {
  567         char *ip_fmt = "%s -> %s";
  568 
  569         if (ScObfuscate())
  570         {
  571             TextLog_Print(log, ip_fmt,
  572                     ObfuscateIpToText(GET_SRC_ADDR(p)),
  573                     ObfuscateIpToText(GET_DST_ADDR(p)));
  574         }
  575         else
  576         {
  577             TextLog_Print(log, ip_fmt,
  578                     inet_ntoax(GET_SRC_ADDR(p)),
  579                     inet_ntoax(GET_DST_ADDR(p)));
  580         }
  581     }
  582     else
  583     {
  584         char *ip_fmt = "%s:%d -> %s:%d";
  585 
  586         if (ScObfuscate())
  587         {
  588             TextLog_Print(log, ip_fmt,
  589                     ObfuscateIpToText(GET_SRC_ADDR(p)), p->sp,
  590                     ObfuscateIpToText(GET_DST_ADDR(p)), p->dp);
  591         }
  592         else
  593         {
  594             TextLog_Print(log, ip_fmt,
  595                     inet_ntoax(GET_SRC_ADDR(p)), p->sp,
  596                     inet_ntoax(GET_DST_ADDR(p)), p->dp);
  597         }
  598     }
  599 }
  600 
  601 /*--------------------------------------------------------------------
  602  * Function: LogIPHeader(TextLog* )
  603  *
  604  * Purpose: Dump the IP header info to the given TextLog
  605  *
  606  * Arguments: log => TextLog to print to
  607  *
  608  * Returns: void function
  609  *--------------------------------------------------------------------
  610  */
  611 void LogIPHeader(TextLog*  log, Packet * p)
  612 {
  613     if(!IPH_IS_VALID(p))
  614     {
  615         TextLog_Print(log, "IP header truncated\n");
  616         return;
  617     }
  618 
  619     LogIpAddrs(log, p);
  620 
  621     if(!ScOutputDataLink())
  622     {
  623         TextLog_NewLine(log);
  624     }
  625     else
  626     {
  627         TextLog_Putc(log, ' ');
  628     }
  629 
  630     TextLog_Print(log, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u",
  631             protocol_names[GET_IPH_PROTO(p)],
  632             GET_IPH_TTL(p),
  633             GET_IPH_TOS(p),
  634             IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)),
  635             GET_IPH_HLEN(p) << 2,
  636             GET_IP_DGMLEN(p));
  637 
  638     /* print the reserved bit if it's set */
  639     if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1)
  640         TextLog_Puts(log, " RB");
  641 
  642     /* printf more frags/don't frag bits */
  643     if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1)
  644         TextLog_Puts(log, " DF");
  645 
  646     if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1)
  647         TextLog_Puts(log, " MF");
  648 
  649     TextLog_NewLine(log);
  650 
  651     /* print IP options */
  652     if(p->ip_option_count != 0)
  653     {
  654         LogIpOptions(log, p);
  655     }
  656 
  657     /* print fragment info if necessary */
  658     if(p->frag_flag)
  659     {
  660         TextLog_Print(log, "Frag Offset: 0x%04X   Frag Size: 0x%04X\n",
  661                 (p->frag_offset & 0x1FFF),
  662                 GET_IP_PAYLEN(p));
  663     }
  664 }
  665 
  666 #ifdef GRE
  667 static void LogOuterIPHeader(TextLog *log, Packet *p)
  668 {
  669     int save_family = p->family;
  670     IPH_API *save_api = p->iph_api;
  671     const IPHdr *save_iph = p->iph;
  672     uint8_t save_ip_option_count = p->ip_option_count;
  673     IP4Hdr *save_ip4h = p->ip4h;
  674     IP6Hdr *save_ip6h = p->ip6h;
  675     uint8_t save_frag_flag = p->frag_flag;
  676     uint16_t save_sp = 0, save_dp = 0;
  677 
  678     p->family = p->outer_family;
  679     p->iph_api = p->outer_iph_api;
  680     p->iph = p->outer_iph;
  681     p->ip_option_count = 0;
  682     p->ip4h = &p->outer_ip4h;
  683     p->ip6h = &p->outer_ip6h;
  684     p->frag_flag = 0;
  685 
  686     if (p->proto_bits & PROTO_BIT__TEREDO)
  687     {
  688         save_sp = p->sp;
  689         save_dp = p->dp;
  690 
  691         if (p->outer_udph)
  692         {
  693             p->sp = ntohs(p->outer_udph->uh_sport);
  694             p->dp = ntohs(p->outer_udph->uh_dport);
  695         }
  696         else
  697         {
  698             p->sp = ntohs(p->udph->uh_sport);
  699             p->dp = ntohs(p->udph->uh_dport);
  700         }
  701     }
  702 
  703     LogIPHeader(log, p);
  704 
  705     p->family = save_family;
  706     p->iph_api = save_api;
  707     p->iph = save_iph;
  708     p->ip_option_count = save_ip_option_count;
  709     p->ip4h = save_ip4h;
  710     p->ip6h = save_ip6h;
  711     p->frag_flag = save_frag_flag;
  712 
  713     if (p->proto_bits & PROTO_BIT__TEREDO)
  714     {
  715         p->sp = save_sp;
  716         p->dp = save_dp;
  717     }
  718 }
  719 #endif
  720 
  721 /*-------------------------------------------------------------------
  722  * TCP stuff cloned from log.c
  723  *-------------------------------------------------------------------
  724  */
  725 static void LogTcpOptions(TextLog*  log, Packet * p)
  726 {
  727     int i;
  728     int j;
  729     u_char tmp[5];
  730 #if 0
  731     u_long init_offset;
  732     u_long print_offset;
  733 
  734     init_offset = TextLog_Tell(log);
  735 #endif
  736 
  737     TextLog_Print(log, "TCP Options (%d) => ", p->tcp_option_count);
  738 
  739     if(p->tcp_option_count > 40 || !p->tcp_option_count)
  740         return;
  741 
  742     for(i = 0; i < (int) p->tcp_option_count; i++)
  743     {
  744 #if 0
  745         print_offset = TextLog_Tell(log);
  746 
  747         if((print_offset - init_offset) > 60)
  748         {
  749             TextLog_Puts(log, "\nTCP Options => ");
  750             init_offset = TextLog_Tell(log);
  751         }
  752 #endif
  753         switch(p->tcp_options[i].code)
  754         {
  755             case TCPOPT_MAXSEG:
  756                 memset((char*)tmp, 0, sizeof(tmp));
  757                 TextLog_Puts(log, "MSS: ");
  758                 if (p->tcp_options[i].data)
  759                     memcpy(tmp, p->tcp_options[i].data, 2);
  760                 TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp));
  761                 break;
  762 
  763             case TCPOPT_EOL:
  764                 TextLog_Puts(log, "EOL ");
  765                 break;
  766 
  767             case TCPOPT_TFO:
  768                 TextLog_Puts(log, "TFO ");
  769                 break;
  770 
  771             case TCPOPT_NOP:
  772                 TextLog_Puts(log, "NOP ");
  773                 break;
  774 
  775             case TCPOPT_WSCALE:
  776                 if (p->tcp_options[i].data)
  777                     TextLog_Print(log, "WS: %u ", p->tcp_options[i].data[0]);
  778                 else
  779                     TextLog_Print(log, "WS: %u ", 0);
  780                 break;
  781             case TCPOPT_SACK:
  782                 memset((char*)tmp, 0, sizeof(tmp));
  783                 if (p->tcp_options[i].data && (p->tcp_options[i].len >= 2))
  784                     memcpy(tmp, p->tcp_options[i].data, 2);
  785                 TextLog_Print(log, "Sack: %u@", EXTRACT_16BITS(tmp));
  786                 memset((char*)tmp, 0, sizeof(tmp));
  787                 if (p->tcp_options[i].data && (p->tcp_options[i].len >= 4))
  788                     memcpy(tmp, (p->tcp_options[i].data) + 2, 2);
  789                 TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp));
  790                 break;
  791 
  792             case TCPOPT_SACKOK:
  793                 TextLog_Puts(log, "SackOK ");
  794                 break;
  795 
  796             case TCPOPT_ECHO:
  797                 memset((char*)tmp, 0, sizeof(tmp));
  798                 if (p->tcp_options[i].data)
  799                     memcpy(tmp, p->tcp_options[i].data, 4);
  800                 TextLog_Print(log, "Echo: %u ", EXTRACT_32BITS(tmp));
  801                 break;
  802 
  803             case TCPOPT_ECHOREPLY:
  804                 memset((char*)tmp, 0, sizeof(tmp));
  805                 if (p->tcp_options[i].data)
  806                     memcpy(tmp, p->tcp_options[i].data, 4);
  807                 TextLog_Print(log, "Echo Rep: %u ", EXTRACT_32BITS(tmp));
  808                 break;
  809 
  810             case TCPOPT_TIMESTAMP:
  811                 memset((char*)tmp, 0, sizeof(tmp));
  812                 if (p->tcp_options[i].data)
  813                     memcpy(tmp, p->tcp_options[i].data, 4);
  814                 TextLog_Print(log, "TS: %u ", EXTRACT_32BITS(tmp));
  815                 memset((char*)tmp, 0, sizeof(tmp));
  816                 if (p->tcp_options[i].data)
  817                     memcpy(tmp, (p->tcp_options[i].data) + 4, 4);
  818                 TextLog_Print(log, "%u ", EXTRACT_32BITS(tmp));
  819                 break;
  820 
  821             case TCPOPT_CC:
  822                 memset((char*)tmp, 0, sizeof(tmp));
  823                 if (p->tcp_options[i].data)
  824                     memcpy(tmp, p->tcp_options[i].data, 4);
  825                 TextLog_Print(log, "CC %u ", EXTRACT_32BITS(tmp));
  826                 break;
  827 
  828             case TCPOPT_CCNEW:
  829                 memset((char*)tmp, 0, sizeof(tmp));
  830                 if (p->tcp_options[i].data)
  831                     memcpy(tmp, p->tcp_options[i].data, 4);
  832                 TextLog_Print(log, "CCNEW: %u ", EXTRACT_32BITS(tmp));
  833                 break;
  834 
  835             case TCPOPT_CCECHO:
  836                 memset((char*)tmp, 0, sizeof(tmp));
  837                 if (p->tcp_options[i].data)
  838                     memcpy(tmp, p->tcp_options[i].data, 4);
  839                 TextLog_Print(log, "CCECHO: %u ", EXTRACT_32BITS(tmp));
  840                 break;
  841 
  842             default:
  843                 if(p->tcp_options[i].len)
  844                 {
  845                     TextLog_Print(log, "Opt %d (%d): ", p->tcp_options[i].code,
  846                             (int) p->tcp_options[i].len);
  847 
  848                     for(j = 0; j < p->tcp_options[i].len; j++)
  849                     {
  850                         if (p->tcp_options[i].data)
  851                             TextLog_Print(log, "%02X", p->tcp_options[i].data[j]);
  852                         else
  853                             TextLog_Print(log, "%02X", 0);
  854 
  855                         if ((j + 1) % 2 == 0)
  856                             TextLog_Putc(log, ' ');
  857                     }
  858 
  859                     TextLog_Putc(log, ' ');
  860                 }
  861                 else
  862                 {
  863                     TextLog_Print(log, "Opt %d ", p->tcp_options[i].code);
  864                 }
  865                 break;
  866         }
  867     }
  868 
  869     TextLog_NewLine(log);
  870 }
  871 
  872 /*--------------------------------------------------------------------
  873  * Function: LogTCPHeader(TextLog* )
  874  *
  875  * Purpose: Dump the TCP header info to the given TextLog
  876  *
  877  * Arguments: log => pointer to TextLog to print data to
  878  *
  879  * Returns: void function
  880  *--------------------------------------------------------------------
  881  */
  882 void LogTCPHeader(TextLog*  log, Packet * p)
  883 {
  884     char tcpFlags[9];
  885 
  886     if(p->tcph == NULL)
  887     {
  888         TextLog_Print(log, "TCP header truncated\n");
  889         return;
  890     }
  891     /* print TCP flags */
  892     CreateTCPFlagString(p, tcpFlags);
  893     TextLog_Puts(log, tcpFlags); /* We don't care about the NULL */
  894 
  895     /* print other TCP info */
  896     TextLog_Print(log, " Seq: 0x%lX  Ack: 0x%lX  Win: 0x%X  TcpLen: %d",
  897             (u_long) ntohl(p->tcph->th_seq),
  898             (u_long) ntohl(p->tcph->th_ack),
  899             ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2);
  900 
  901     if((p->tcph->th_flags & TH_URG) != 0)
  902     {
  903         TextLog_Print(log, "  UrgPtr: 0x%X\n", (uint16_t) ntohs(p->tcph->th_urp));
  904     }
  905     else
  906     {
  907         TextLog_NewLine(log);
  908     }
  909 
  910     /* dump the TCP options */
  911     if(p->tcp_option_count != 0)
  912     {
  913         LogTcpOptions(log, p);
  914     }
  915 }
  916 
  917 /*-------------------------------------------------------------------
  918  * UDP stuff cloned from log.c
  919  *-------------------------------------------------------------------
  920  */
  921 /*--------------------------------------------------------------------
  922  * Function: LogUDPHeader(TextLog* )
  923  *
  924  * Purpose: Dump the UDP header to the given TextLog
  925  *
  926  * Arguments: log => pointer to TextLog
  927  *
  928  * Returns: void function
  929  *--------------------------------------------------------------------
  930  */
  931 void LogUDPHeader(TextLog* log, Packet* p)
  932 {
  933 
  934     if(p->udph == NULL)
  935     {
  936         TextLog_Print(log, "UDP header truncated\n");
  937         return;
  938     }
  939     /* not much to do here... */
  940     TextLog_Print(log, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN);
  941 }
  942 
  943 /*--------------------------------------------------------------------
  944  * ICMP stuff cloned from log.c
  945  *--------------------------------------------------------------------
  946  */
  947 /*--------------------------------------------------------------------
  948  * Function: LogEmbeddedICMPHeader(TextLog* , ICMPHdr *)
  949  *
  950  * Purpose: Prints the 64 bits of the original IP payload in an ICMP packet
  951  *          that requires it
  952  *
  953  * Arguments: log => pointer to TextLog
  954  *            icmph  => ICMPHdr struct pointing to original ICMP
  955  *
  956  * Returns: void function
  957  *--------------------------------------------------------------------
  958  */
  959 static void LogEmbeddedICMPHeader(TextLog* log, const ICMPHdr *icmph)
  960 {
  961     if (log == NULL || icmph == NULL)
  962         return;
  963 
  964     TextLog_Print(log, "Type: %d  Code: %d  Csum: %u",
  965             icmph->type, icmph->code, ntohs(icmph->csum));
  966 
  967     switch (icmph->type)
  968     {
  969         case ICMP_DEST_UNREACH:
  970         case ICMP_TIME_EXCEEDED:
  971         case ICMP_SOURCE_QUENCH:
  972             break;
  973 
  974         case ICMP_PARAMETERPROB:
  975             if (icmph->code == 0)
  976                 TextLog_Print(log, "  Ptr: %u", icmph->s_icmp_pptr);
  977             break;
  978 
  979         case ICMP_REDIRECT:
  980 // XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing"
  981             break;
  982 
  983         case ICMP_ECHO:
  984         case ICMP_ECHOREPLY:
  985         case ICMP_TIMESTAMP:
  986         case ICMP_TIMESTAMPREPLY:
  987         case ICMP_INFO_REQUEST:
  988         case ICMP_INFO_REPLY:
  989         case ICMP_ADDRESS:
  990         case ICMP_ADDRESSREPLY:
  991             TextLog_Print(log, "  Id: %u  SeqNo: %u",
  992                     ntohs(icmph->s_icmp_id), ntohs(icmph->s_icmp_seq));
  993             break;
  994 
  995         case ICMP_ROUTER_ADVERTISE:
  996             TextLog_Print(log, "  Addrs: %u  Size: %u  Lifetime: %u",
  997                     icmph->s_icmp_num_addrs, icmph->s_icmp_wpa,
  998                     ntohs(icmph->s_icmp_lifetime));
  999             break;
 1000 
 1001         default:
 1002             break;
 1003     }
 1004 
 1005     TextLog_NewLine(log);
 1006 
 1007     return;
 1008 }
 1009 
 1010 /*--------------------------------------------------------------------
 1011  * Function: LogICMPEmbeddedIP(TextLog* , Packet *)
 1012  *
 1013  * Purpose: Prints the original/encapsulated IP header + 64 bits of the
 1014  *          original IP payload in an ICMP packet
 1015  *
 1016  * Arguments: log => pointer to TextLog
 1017  *            p  => packet struct
 1018  *
 1019  * Returns: void function
 1020  *--------------------------------------------------------------------
 1021  */
 1022 static void LogICMPEmbeddedIP(TextLog* log, Packet *p)
 1023 {
 1024     Packet op;
 1025     Packet *orig_p;
 1026     uint32_t orig_ip_hlen;
 1027 
 1028     if (log == NULL || p == NULL)
 1029         return;
 1030 
 1031     memset((char*)&op, 0, sizeof(op));
 1032     orig_p = &op;
 1033 
 1034     orig_p->iph = p->orig_iph;
 1035     orig_p->tcph = p->orig_tcph;
 1036     orig_p->udph = p->orig_udph;
 1037     orig_p->sp = p->orig_sp;
 1038     orig_p->dp = p->orig_dp;
 1039     orig_p->icmph = p->orig_icmph;
 1040     orig_p->iph_api = p->orig_iph_api;
 1041     orig_p->ip4h = p->orig_ip4h;
 1042     orig_p->ip6h = p->orig_ip6h;
 1043     orig_p->family = p->orig_family;
 1044 
 1045     if(orig_p->iph != NULL)
 1046     {
 1047         TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
 1048         LogIPHeader(log, orig_p);
 1049         orig_ip_hlen = IP_HLEN(p->orig_iph) << 2;
 1050 
 1051         switch(GET_IPH_PROTO(orig_p))
 1052         {
 1053             case IPPROTO_TCP:
 1054                 if(orig_p->tcph != NULL)
 1055                     TextLog_Print(log, "Seq: 0x%lX\n",
 1056                             (u_long)ntohl(orig_p->tcph->th_seq));
 1057                 break;
 1058 
 1059             case IPPROTO_UDP:
 1060                 if(orig_p->udph != NULL)
 1061                     TextLog_Print(log, "Len: %d  Csum: %d\n",
 1062                             ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN,
 1063                             ntohs(orig_p->udph->uh_chk));
 1064                 break;
 1065 
 1066             case IPPROTO_ICMP:
 1067                 if(orig_p->icmph != NULL)
 1068                     LogEmbeddedICMPHeader(log, orig_p->icmph);
 1069                 break;
 1070 
 1071             default:
 1072                 TextLog_Print(log, "Protocol: 0x%X (unknown or "
 1073                         "header truncated)", GET_IPH_PROTO(orig_p));
 1074                 break;
 1075         }       /* switch */
 1076 
 1077         /* if more than 8 bytes of original IP payload sent */
 1078         if (p->dsize - orig_ip_hlen > 8)
 1079         {
 1080             TextLog_Print(log, "(%d more bytes of original packet)\n",
 1081                     p->dsize - orig_ip_hlen - 8);
 1082         }
 1083 
 1084         TextLog_Puts(log, "** END OF DUMP");
 1085     }
 1086     else
 1087     {
 1088         TextLog_Puts(log, "\nORIGINAL DATAGRAM TRUNCATED");
 1089     }
 1090 }
 1091 
 1092 /*--------------------------------------------------------------------
 1093  * Function: LogICMPHeader(TextLog* )
 1094  *
 1095  * Purpose: Print ICMP header
 1096  *
 1097  * Arguments: log => pointer to TextLog
 1098  *
 1099  * Returns: void function
 1100  *--------------------------------------------------------------------
 1101  */
 1102 void LogICMPHeader(TextLog*  log, Packet * p)
 1103 {
 1104     /* 32 digits plus 7 colons and a NULL byte */
 1105     char buf[8*4 + 7 + 1];
 1106 
 1107     if(p->icmph == NULL)
 1108     {
 1109         TextLog_Puts(log, "ICMP header truncated\n");
 1110         return;
 1111     }
 1112 
 1113     TextLog_Print(log, "Type:%d  Code:%d  ", p->icmph->type, p->icmph->code);
 1114 
 1115     switch(p->icmph->type)
 1116     {
 1117         case ICMP_ECHOREPLY:
 1118             TextLog_Print(log, "ID:%d  Seq:%d  ", ntohs(p->icmph->s_icmp_id),
 1119                     ntohs(p->icmph->s_icmp_seq));
 1120             TextLog_Puts(log, "ECHO REPLY");
 1121             break;
 1122 
 1123         case ICMP_DEST_UNREACH:
 1124             TextLog_Puts(log, "DESTINATION UNREACHABLE: ");
 1125             switch(p->icmph->code)
 1126             {
 1127                 case ICMP_NET_UNREACH:
 1128                     TextLog_Puts(log, "NET UNREACHABLE");
 1129                     break;
 1130 
 1131                 case ICMP_HOST_UNREACH:
 1132                     TextLog_Puts(log, "HOST UNREACHABLE");
 1133                     break;
 1134 
 1135                 case ICMP_PROT_UNREACH:
 1136                     TextLog_Puts(log, "PROTOCOL UNREACHABLE");
 1137                     break;
 1138 
 1139                 case ICMP_PORT_UNREACH:
 1140                     TextLog_Puts(log, "PORT UNREACHABLE");
 1141                     break;
 1142 
 1143                 case ICMP_FRAG_NEEDED:
 1144                     TextLog_Print(log, "FRAGMENTATION NEEDED, DF SET\n"
 1145                             "NEXT LINK MTU: %u",
 1146                             ntohs(p->icmph->s_icmp_nextmtu));
 1147                     break;
 1148 
 1149                 case ICMP_SR_FAILED:
 1150                     TextLog_Puts(log, "SOURCE ROUTE FAILED");
 1151                     break;
 1152 
 1153                 case ICMP_NET_UNKNOWN:
 1154                     TextLog_Puts(log, "NET UNKNOWN");
 1155                     break;
 1156 
 1157                 case ICMP_HOST_UNKNOWN:
 1158                     TextLog_Puts(log, "HOST UNKNOWN");
 1159                     break;
 1160 
 1161                 case ICMP_HOST_ISOLATED:
 1162                     TextLog_Puts(log, "HOST ISOLATED");
 1163                     break;
 1164 
 1165                 case ICMP_PKT_FILTERED_NET:
 1166                     TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED NETWORK FILTERED");
 1167                     break;
 1168 
 1169                 case ICMP_PKT_FILTERED_HOST:
 1170                     TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED HOST FILTERED");
 1171                     break;
 1172 
 1173                 case ICMP_NET_UNR_TOS:
 1174                     TextLog_Puts(log, "NET UNREACHABLE FOR TOS");
 1175                     break;
 1176 
 1177                 case ICMP_HOST_UNR_TOS:
 1178                     TextLog_Puts(log, "HOST UNREACHABLE FOR TOS");
 1179                     break;
 1180 
 1181                 case ICMP_PKT_FILTERED:
 1182                     TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED");
 1183                     break;
 1184 
 1185                 case ICMP_PREC_VIOLATION:
 1186                     TextLog_Puts(log, "PREC VIOLATION");
 1187                     break;
 1188 
 1189                 case ICMP_PREC_CUTOFF:
 1190                     TextLog_Puts(log, "PREC CUTOFF");
 1191                     break;
 1192 
 1193                 default:
 1194                     TextLog_Puts(log, "UNKNOWN");
 1195                     break;
 1196 
 1197             }
 1198 
 1199 
 1200             LogICMPEmbeddedIP(log, p);
 1201 
 1202             break;
 1203 
 1204         case ICMP_SOURCE_QUENCH:
 1205             TextLog_Puts(log, "SOURCE QUENCH");
 1206 
 1207             LogICMPEmbeddedIP(log, p);
 1208 
 1209             break;
 1210 
 1211         case ICMP_REDIRECT:
 1212             TextLog_Puts(log, "REDIRECT");
 1213             switch(p->icmph->code)
 1214             {
 1215                 case ICMP_REDIR_NET:
 1216                     TextLog_Puts(log, " NET");
 1217                     break;
 1218 
 1219                 case ICMP_REDIR_HOST:
 1220                     TextLog_Puts(log, " HOST");
 1221                     break;
 1222 
 1223                 case ICMP_REDIR_TOS_NET:
 1224                     TextLog_Puts(log, " TOS NET");
 1225                     break;
 1226 
 1227                 case ICMP_REDIR_TOS_HOST:
 1228                     TextLog_Puts(log, " TOS HOST");
 1229                     break;
 1230             }
 1231 
 1232 /* written this way since inet_ntoa was typedef'ed to use sfip_ntoa
 1233  * which requires sfcidr_t instead of inaddr's.  This call to inet_ntoa
 1234  * is a rare case that doesn't use sfcidr_t's. */
 1235 
 1236 // XXX-IPv6 NOT YET IMPLEMENTED - IPV6 addresses technically not supported - need to change ICMP
 1237 
 1238             /* no inet_ntop in Windows */
 1239             sfip_raw_ntop(AF_INET, (const void *)(&p->icmph->s_icmp_gwaddr.s_addr),
 1240                           buf, sizeof(buf));
 1241             TextLog_Print(log, " NEW GW: %s", buf);
 1242 
 1243             LogICMPEmbeddedIP(log, p);
 1244 
 1245             break;
 1246 
 1247         case ICMP_ECHO:
 1248             TextLog_Print(log, "ID:%d   Seq:%d  ", ntohs(p->icmph->s_icmp_id),
 1249                     ntohs(p->icmph->s_icmp_seq));
 1250             TextLog_Puts(log, "ECHO");
 1251             break;
 1252 
 1253         case ICMP_ROUTER_ADVERTISE:
 1254             TextLog_Print(log, "ROUTER ADVERTISMENT: "
 1255                     "Num addrs: %d Addr entry size: %d Lifetime: %u",
 1256                     p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa,
 1257                     ntohs(p->icmph->s_icmp_lifetime));
 1258             break;
 1259 
 1260         case ICMP_ROUTER_SOLICIT:
 1261             TextLog_Puts(log, "ROUTER SOLICITATION");
 1262             break;
 1263 
 1264         case ICMP_TIME_EXCEEDED:
 1265             TextLog_Puts(log, "TTL EXCEEDED");
 1266             switch(p->icmph->code)
 1267             {
 1268                 case ICMP_TIMEOUT_TRANSIT:
 1269                     TextLog_Puts(log, " IN TRANSIT");
 1270                     break;
 1271 
 1272                 case ICMP_TIMEOUT_REASSY:
 1273                     TextLog_Puts(log, " TIME EXCEEDED IN FRAG REASSEMBLY");
 1274                     break;
 1275             }
 1276 
 1277             LogICMPEmbeddedIP(log, p);
 1278 
 1279             break;
 1280 
 1281         case ICMP_PARAMETERPROB:
 1282             TextLog_Puts(log, "PARAMETER PROBLEM");
 1283             switch(p->icmph->code)
 1284             {
 1285                 case ICMP_PARAM_BADIPHDR:
 1286                     TextLog_Print(log, ": BAD IP HEADER BYTE %u",
 1287                             p->icmph->s_icmp_pptr);
 1288                     break;
 1289 
 1290                 case ICMP_PARAM_OPTMISSING:
 1291                     TextLog_Puts(log, ": OPTION MISSING");
 1292                     break;
 1293 
 1294                 case ICMP_PARAM_BAD_LENGTH:
 1295                     TextLog_Puts(log, ": BAD LENGTH");
 1296                     break;
 1297             }
 1298 
 1299             LogICMPEmbeddedIP(log, p);
 1300 
 1301             break;
 1302 
 1303         case ICMP_TIMESTAMP:
 1304             TextLog_Print(log, "ID: %u  Seq: %u  TIMESTAMP REQUEST",
 1305                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1306             break;
 1307 
 1308         case ICMP_TIMESTAMPREPLY:
 1309             TextLog_Print(log, "ID: %u  Seq: %u  TIMESTAMP REPLY:\n"
 1310                     "Orig: %u Rtime: %u  Ttime: %u",
 1311                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
 1312                     p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime,
 1313                     p->icmph->s_icmp_ttime);
 1314             break;
 1315 
 1316         case ICMP_INFO_REQUEST:
 1317             TextLog_Print(log, "ID: %u  Seq: %u  INFO REQUEST",
 1318                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1319             break;
 1320 
 1321         case ICMP_INFO_REPLY:
 1322             TextLog_Print(log, "ID: %u  Seq: %u  INFO REPLY",
 1323                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1324             break;
 1325 
 1326         case ICMP_ADDRESS:
 1327             TextLog_Print(log, "ID: %u  Seq: %u  ADDRESS REQUEST",
 1328                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
 1329             break;
 1330 
 1331         case ICMP_ADDRESSREPLY:
 1332             TextLog_Print(log, "ID: %u  Seq: %u  ADDRESS REPLY: 0x%08X",
 1333                     ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
 1334                     (u_int) ntohl(p->icmph->s_icmp_mask));
 1335             break;
 1336 
 1337         default:
 1338             TextLog_Puts(log, "UNKNOWN");
 1339 
 1340             break;
 1341     }
 1342 
 1343     TextLog_NewLine(log);
 1344 
 1345 }
 1346 
 1347 /*--------------------------------------------------------------------
 1348  * reference stuff cloned from signature.c
 1349  *--------------------------------------------------------------------
 1350  */
 1351 /* print a reference node */
 1352 static void LogReference(TextLog* log, ReferenceNode *refNode)
 1353 {
 1354     if(refNode)
 1355     {
 1356         if(refNode->system)
 1357         {
 1358             if(refNode->system->url)
 1359                 TextLog_Print(log, "[Xref => %s%s]", refNode->system->url,
 1360                         refNode->id);
 1361             else
 1362                 TextLog_Print(log, "[Xref => %s %s]", refNode->system->name,
 1363                         refNode->id);
 1364         }
 1365         else
 1366         {
 1367             TextLog_Print(log, "[Xref => %s]", refNode->id);
 1368         }
 1369     }
 1370     return;
 1371 }
 1372 
 1373 /*
 1374  * Function: LogXrefs(TextLog* )
 1375  *
 1376  * Purpose: Prints out cross reference data associated with an alert
 1377  *
 1378  * Arguments: log => pointer to TextLog to write the data to
 1379  *            doNewLine => tack a \n to the end of the line or not (bool)
 1380  *
 1381  * Returns: void function
 1382  */
 1383 void LogXrefs(TextLog* log, bool doNewLine)
 1384 {
 1385     ReferenceNode *refNode = NULL;
 1386 
 1387     if(otn_tmp)
 1388     {
 1389         refNode = otn_tmp->sigInfo.refs;
 1390 
 1391         while(refNode  != NULL)
 1392         {
 1393             LogReference(log, refNode);
 1394             refNode = refNode->next;
 1395 
 1396             /* on the last loop through, print a newline in
 1397                Full mode */
 1398             if(doNewLine && (refNode == NULL))
 1399                 TextLog_NewLine(log);
 1400         }
 1401     }
 1402 }
 1403 
 1404 /*--------------------------------------------------------------------
 1405  * payload stuff cloned from log.c
 1406  *--------------------------------------------------------------------
 1407  */
 1408 /*--------------------------------------------------------------------
 1409  * Function: ScOutputCharData(TextLog*, char*, int)
 1410  *
 1411  * Purpose: Dump the printable ASCII data from a packet
 1412  *
 1413  * Arguments: log => ptr to TextLog to print to
 1414  *            data => pointer to buffer data
 1415  *            len => length of data buffer
 1416  *
 1417  * Returns: void function
 1418  *--------------------------------------------------------------------
 1419  */
 1420 static void LogCharData(TextLog* log, const char *data, int len)
 1421 {
 1422     const char* pb = data;
 1423     const char* end = data + len;
 1424     int lineCount = 0;
 1425 
 1426     if ( !data )
 1427     {
 1428         return;
 1429     }
 1430 
 1431     while ( pb < end )
 1432     {
 1433         if ( *pb > 0x1F && *pb < 0x7F)
 1434         {   /* printable */
 1435             TextLog_Putc(log, *pb);
 1436         }
 1437         else
 1438         {   /* not printable */
 1439             TextLog_Putc(log, '.');
 1440         }
 1441 
 1442         if ( ++lineCount == 64 )
 1443         {
 1444             TextLog_Putc(log, ' ');
 1445             TextLog_NewLine(log);
 1446             lineCount = 0;
 1447         }
 1448         pb++;
 1449     }
 1450     /* slam a \n on the back */
 1451     TextLog_Putc(log, ' ');
 1452     TextLog_NewLine(log);
 1453     TextLog_Putc(log, ' ');
 1454 }
 1455 
 1456 /*
 1457  * Function: LogNetData(TextLog*, u_char *,int, Packet *)
 1458  *
 1459  * Purpose: Do a side by side dump of a buffer, hex on
 1460  *          the left, decoded ASCII on the right.
 1461  *
 1462  * Arguments: log => ptr to TextLog to print to
 1463  *            data => pointer to buffer data
 1464  *            len => length of data buffer
 1465  *
 1466  * Returns: void function
 1467  */
 1468 #define BYTES_PER_FRAME 16
 1469 /* middle of packet:"41 02 43 04 45 06 47 08 49 0A 4B 0C 4D 0E 4F 0F  A.C.E.G.I.K.M.O."*/
 1470 /* at end of packet:"41 02 43 04 45 06 47 08                          A.C.E.G."*/
 1471 static char* pad3 = "                                                 ";
 1472 
 1473 static void LogNetData (TextLog* log, const u_char* data, const int len, Packet *p)
 1474 {
 1475     const u_char* pb = data;
 1476     const u_char* end = data + len;
 1477 
 1478     int offset = 0;
 1479     char conv[] = "0123456789ABCDEF";   /* xlation lookup table */
 1480     int next_layer, ip_start, ip_ob_start, ip_ob_end, byte_pos, char_pos;
 1481     int i;
 1482 
 1483     next_layer = ip_start = byte_pos = char_pos = 0;
 1484 
 1485     ip_ob_start = ip_ob_end = -1;
 1486 
 1487     if ( !len )
 1488     {
 1489         TextLog_NewLine(log);
 1490         return;
 1491     }
 1492     if ( !data )
 1493     {
 1494         TextLog_Print(log, "Got NULL ptr in LogNetData()\n");
 1495         return;
 1496     }
 1497 
 1498     if ( len > IP_MAXPACKET )
 1499     {
 1500         if (ScLogVerbose())
 1501         {
 1502             TextLog_Print(
 1503                 log, "Got bogus buffer length (%d) for LogNetData, "
 1504                 "defaulting to %d bytes!\n", len, BYTES_PER_FRAME
 1505             );
 1506         }
 1507         end = data + BYTES_PER_FRAME;
 1508     }
 1509 
 1510     if(p && ScObfuscate() )
 1511     {
 1512         next_layer =  p->next_layer;
 1513         for ( i = 0; i < next_layer; i++ )
 1514         {
 1515             if ( p->layers[i].proto == PROTO_IP4
 1516                   || p->layers[i].proto == PROTO_IP6
 1517                 )
 1518             {
 1519                 if(p->layers[i].length && p->layers[i].start)
 1520                 break;
 1521             }
 1522         }
 1523 
 1524         ip_start = p->layers[i].start - data;
 1525 
 1526         if(ip_start > 0 )
 1527         {
 1528             ip_ob_start = ip_start + 10;
 1529             if(p->layers[i].proto == PROTO_IP4)
 1530                 ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in_addr));
 1531             else
 1532                 ip_ob_end = ip_ob_start + 2 + 2*(sizeof(struct in6_addr));
 1533 
 1534         }
 1535 
 1536     }
 1537 
 1538     /* loop thru the whole buffer */
 1539     while ( pb < end )
 1540     {
 1541         i = 0;
 1542 
 1543         if (ScVerboseByteDump())
 1544         {
 1545             TextLog_Print(log, "0x%04X: ", offset);
 1546             offset += BYTES_PER_FRAME;
 1547         }
 1548         /* process one frame */
 1549         /* first print the binary as ascii hex */
 1550         for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++, byte_pos++)
 1551         {
 1552             if(ScObfuscate() && ((byte_pos >= ip_ob_start) && (byte_pos < ip_ob_end)))
 1553             {
 1554                 TextLog_Putc(log, 'X');
 1555                 TextLog_Putc(log, 'X');
 1556                 TextLog_Putc(log, ' ');
 1557             }
 1558             else
 1559             {
 1560                 char b = pb[i];
 1561                 TextLog_Putc(log, conv[(b & 0xFF) >> 4]);
 1562                 TextLog_Putc(log, conv[(b & 0xFF) & 0x0F]);
 1563                 TextLog_Putc(log, ' ');
 1564             }
 1565         }
 1566         /* print ' ' past end of packet and before ascii */
 1567         TextLog_Puts(log, pad3+(3*i));
 1568 
 1569         /* then print the actual ascii chars */
 1570         /* or a '.' for control chars */
 1571         for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++, char_pos++)
 1572         {
 1573             if(ScObfuscate() && ((char_pos >= ip_ob_start) && (char_pos < ip_ob_end)))
 1574             {
 1575                 TextLog_Putc(log, 'X');
 1576             }
 1577             else
 1578             {
 1579                 char b = pb[i];
 1580 
 1581                 if ( b > 0x1F && b < 0x7F)
 1582                     TextLog_Putc(log, (char)(b & 0xFF));
 1583                 else
 1584                     TextLog_Putc(log, '.');
 1585             }
 1586         }
 1587         pb += BYTES_PER_FRAME;
 1588         TextLog_NewLine(log);
 1589     }
 1590     TextLog_NewLine(log);
 1591 }
 1592 
 1593 #define SEPARATOR \
 1594     "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
 1595 
 1596 static int LogObfuscatedData(TextLog* log, Packet *p)
 1597 {
 1598     uint8_t *payload = NULL;
 1599     uint16_t payload_len = 0;
 1600 
 1601     if (obApi->getObfuscatedPayload(p, &payload,
 1602                 (uint16_t *)&payload_len) != OB_RET_SUCCESS)
 1603     {
 1604         return -1;
 1605     }
 1606 
 1607     /* dump the application layer data */
 1608     if (ScOutputAppData() && !ScVerboseByteDump())
 1609     {
 1610         if (ScOutputCharData())
 1611             LogCharData(log, (char *)payload, payload_len);
 1612         else
 1613             LogNetData(log, payload, payload_len, NULL);
 1614     }
 1615     else if (ScVerboseByteDump())
 1616     {
 1617         uint8_t buf[UINT16_MAX];
 1618         uint16_t dlen = p->data - p->pkt;
 1619         int ret;
 1620 
 1621         ret = SafeMemcpy(buf, p->pkt, dlen, buf, buf + sizeof(buf));
 1622         if (ret != SAFEMEM_SUCCESS)
 1623         {
 1624             DEBUG_WRAP(DebugMessage(DEBUG_LOG,
 1625                     "%s: SafeMemcpy() Failed !!!",  __FUNCTION__);)
 1626             free(payload);
 1627             return -1;
 1628         }
 1629 
 1630         ret = SafeMemcpy(buf + dlen, payload, payload_len,
 1631                 buf, buf + sizeof(buf));
 1632         if (ret != SAFEMEM_SUCCESS)
 1633         {
 1634             DEBUG_WRAP(DebugMessage(DEBUG_LOG,
 1635                     "%s: SafeMemcpy() Failed !!!",  __FUNCTION__);)
 1636             free(payload);
 1637             return -1;
 1638         }
 1639 
 1640         LogNetData(log, buf, dlen + payload_len, NULL);
 1641     }
 1642 
 1643     TextLog_Print(log, "%s\n\n", SEPARATOR);
 1644 
 1645     free(payload);
 1646 
 1647     return 0;
 1648 }
 1649 
 1650 /*--------------------------------------------------------------------
 1651  * Function: LogIPPkt(TextLog*, int, Packet *)
 1652  *
 1653  * Purpose: Dump the packet to the given TextLog
 1654  *
 1655  * Arguments: log => pointer to print data to
 1656  *            type => packet protocol
 1657  *            p => pointer to decoded packet struct
 1658  *
 1659  * Returns: void function
 1660  *--------------------------------------------------------------------
 1661  */
 1662 
 1663 #define DATA_PTR(p) \
 1664     ((u_char*)p->iph + (GET_IPH_HLEN(p) << 2))
 1665 #define DATA_LEN(p) \
 1666     (p->actual_ip_len - (GET_IPH_HLEN(p) << 2))
 1667 
 1668 void LogIPPkt(TextLog* log, int type, Packet * p)
 1669 {
 1670     DEBUG_WRAP(DebugMessage(DEBUG_LOG, "LogIPPkt type = %d\n", type););
 1671 
 1672     /* dump the timestamp */
 1673     LogTimeStamp(log, p);
 1674 
 1675     /* dump the ethernet header if we're doing that sort of thing */
 1676     if ( ScOutputDataLink() )
 1677     {
 1678         Log2ndHeader(log, p);
 1679 
 1680 #ifdef MPLS
 1681         if ( p->mpls )
 1682         {
 1683             LogMPLSHeader(log, p);
 1684         }
 1685 #endif
 1686 
 1687 #ifdef GRE
 1688         if ( p->outer_iph )
 1689         {
 1690             LogOuterIPHeader(log, p);
 1691             if ( p->greh )
 1692                 LogGREHeader(log, p);
 1693         }
 1694 #endif
 1695     }
 1696 
 1697     LogIPHeader(log, p);
 1698 
 1699     /* if this isn't a fragment, print the other header info */
 1700     if ( !p->frag_flag )
 1701     {
 1702         switch (GET_IPH_PROTO(p))
 1703         {
 1704             case IPPROTO_TCP:
 1705                 if ( p->tcph != NULL )
 1706 
 1707                 {
 1708                     LogTCPHeader(log, p);
 1709                 }
 1710                 else
 1711                 {
 1712                     LogNetData(log, DATA_PTR(p), DATA_LEN(p), NULL);
 1713                 }
 1714                 break;
 1715 
 1716             case IPPROTO_UDP:
 1717                 if ( p->udph != NULL )
 1718                 {
 1719                     LogUDPHeader(log, p);
 1720                 }
 1721                 else
 1722                 {
 1723                     LogNetData(log, DATA_PTR(p), DATA_LEN(p), NULL);
 1724                 }
 1725 
 1726                 break;
 1727 
 1728             case IPPROTO_ICMP:
 1729                 if ( p->icmph != NULL )
 1730                 {
 1731                     LogICMPHeader(log, p);
 1732                 }
 1733                 else
 1734                 {
 1735                     LogNetData(log, DATA_PTR(p), GET_IP_PAYLEN(p), NULL);
 1736                 }
 1737                 break;
 1738 
 1739             default:
 1740                 break;
 1741         }
 1742     }
 1743 
 1744     if ((p->dsize > 0) && obApi->payloadObfuscationRequired(p)
 1745             && (LogObfuscatedData(log, p) == 0))
 1746     {
 1747         return;
 1748     }
 1749 
 1750     /* dump the application layer data */
 1751     if (ScOutputAppData() && !ScVerboseByteDump())
 1752     {
 1753         if (ScOutputCharData())
 1754         {
 1755             LogCharData(log, (char *)p->data, p->dsize);
 1756             if(!IsJSNormData(p->ssnptr))
 1757             {
 1758                 TextLog_Print(log, "%s\n", "Normalized JavaScript for this packet");
 1759                 LogCharData(log, (const char*)file_data_ptr.data, file_data_ptr.len);
 1760             }
 1761             else if(!IsGzipData(p->ssnptr))
 1762             {
 1763                 TextLog_Print(log, "%s\n", "Decompressed Data for this packet");
 1764                 LogCharData(log, (const char *)file_data_ptr.data, file_data_ptr.len);
 1765             }
 1766         }
 1767         else
 1768         {
 1769             LogNetData(log, p->data, p->dsize, NULL);
 1770             if(!IsJSNormData(p->ssnptr))
 1771             {
 1772                 TextLog_Print(log, "%s\n", "Normalized JavaScript for this packet");
 1773                 LogNetData(log, file_data_ptr.data, file_data_ptr.len, NULL);
 1774             }
 1775             else if(!IsGzipData(p->ssnptr))
 1776             {
 1777                 TextLog_Print(log, "%s\n", "Decompressed Data for this packet");
 1778                 LogNetData(log, file_data_ptr.data, file_data_ptr.len, NULL);
 1779             }
 1780         }
 1781     }
 1782     else if (ScVerboseByteDump())
 1783     {
 1784         LogNetData(log, p->pkt, p->pkth->caplen, p);
 1785     }
 1786 
 1787     TextLog_Print(log, "%s\n\n", SEPARATOR);
 1788 }
 1789 
 1790 #ifndef NO_NON_ETHER_DECODER
 1791 /*--------------------------------------------------------------------
 1792  * ARP stuff cloned from log.c
 1793  *--------------------------------------------------------------------
 1794  */
 1795 
 1796 
 1797 void LogArpHeader(TextLog* log, Packet * p)
 1798 {
 1799 // XXX-IPv6 "NOT YET IMPLEMENTED - printing ARP header"
 1800 }
 1801 #endif  // NO_NON_ETHER_DECODER
 1802 
 1803 #ifdef DUMP_BUFFER
 1804 /*--------------------------------------------------------------------
 1805  * Function to dump the buffers used by snort during packet
 1806  * processing and inspection
 1807  *--------------------------------------------------------------------
 1808  */
 1809 
 1810 void LogBuffer(TextLog *log, char *name, char *data, const int len)
 1811 {
 1812     int i = 0, j;
 1813     char conv[] = "0123456789ABCDEF";
 1814     TextLog_Print(log, "\n%s, %d\n", name, len);
 1815     while (i < len)
 1816     {
 1817         TextLog_Print(log, "\n%.8x  ",i);
 1818 
 1819         for (j = 0; j < BYTES_PER_FRAME; j++)
 1820         {
 1821             if (j == (BYTES_PER_FRAME/2))
 1822             {
 1823                  TextLog_Putc(log, ' ');
 1824             }
 1825 
 1826             if ((i+j) < len)
 1827             {
 1828             char b = data[j + i];
 1829                 TextLog_Putc(log, conv[(b & 0xFF) >> 4]);
 1830                 TextLog_Putc(log, conv[(b & 0xFF) & 0x0F]);
 1831                 TextLog_Putc(log, ' ');
 1832         }
 1833 
 1834             else
 1835             {
 1836                 TextLog_Putc(log, ' ');
 1837                 TextLog_Putc(log, ' ');
 1838                 TextLog_Putc(log, ' ');
 1839             }
 1840     }
 1841 
 1842         TextLog_Putc(log, ' ');
 1843         TextLog_Putc(log, '|');
 1844 
 1845     for (j = 0; j < BYTES_PER_FRAME; j++)
 1846         {
 1847         if ((i+j) < len)
 1848             {
 1849         char b = data[j + i];
 1850                 if ( b > 0x1F && b < 0x7F)
 1851                 {
 1852                     TextLog_Putc(log, (char)(b & 0xFF));
 1853         }
 1854                 else
 1855                 {
 1856                     TextLog_Putc(log, '.');
 1857         }
 1858         }
 1859             else
 1860             {
 1861         TextLog_Putc(log, ' ');
 1862             }
 1863     }
 1864         TextLog_Putc(log, '|');
 1865     i = i + j;
 1866     }
 1867     TextLog_Putc(log, '\n');
 1868 }
 1869 
 1870 #endif