LCOV - code coverage report
Current view: top level - src - Net.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 99 232 42.7 %
Date: 2010-12-13 Functions: 11 16 68.8 %
Branches: 67 186 36.0 %

           Branch data     Line data    Source code
       1                 :            : // $Id: Net.cc 6915 2009-09-22 05:04:17Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include <sys/types.h>
       8                 :            : #ifdef TIME_WITH_SYS_TIME
       9                 :            : # include <sys/time.h>
      10                 :            : # include <time.h>
      11                 :            : #else
      12                 :            : # ifdef HAVE_SYS_TIME_H
      13                 :            : #  include <sys/time.h>
      14                 :            : # else
      15                 :            : #  include <time.h>
      16                 :            : # endif
      17                 :            : #endif
      18                 :            : 
      19                 :            : #include <errno.h>
      20                 :            : #include <signal.h>
      21                 :            : #include <stdlib.h>
      22                 :            : #include <unistd.h>
      23                 :            : 
      24                 :            : #include "NetVar.h"
      25                 :            : #include "Sessions.h"
      26                 :            : #include "Event.h"
      27                 :            : #include "Timer.h"
      28                 :            : #include "Var.h"
      29                 :            : #include "Logger.h"
      30                 :            : #include "Net.h"
      31                 :            : #include "TCP_Rewriter.h"
      32                 :            : #include "Anon.h"
      33                 :            : #include "PacketSort.h"
      34                 :            : #include "Serializer.h"
      35                 :            : #include "PacketDumper.h"
      36                 :            : 
      37                 :            : extern "C" {
      38                 :            : #include "setsignal.h"
      39                 :            : };
      40                 :            : 
      41                 :            : extern "C" {
      42                 :            : extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
      43                 :            : }
      44                 :            : 
      45                 :          6 : PList(PktSrc) pkt_srcs;
      46                 :            : 
      47                 :            : // FIXME: We should really merge PktDumper and PacketDumper.
      48                 :            : // It's on my to-do [Robin].
      49                 :            : PktDumper* pkt_dumper = 0;
      50                 :            : PktDumper* pkt_transformed_dumper = 0;
      51                 :            : 
      52                 :            : // For trace of rewritten packets
      53                 :            : PacketDumper* transformed_pkt_dump = 0;
      54                 :            : // For trace of original packets from selected connections
      55                 :            : PacketDumper* source_pkt_dump = 0;
      56                 :            : int transformed_pkt_dump_MTU = 1514;
      57                 :            : 
      58                 :            : int reading_live = 0;
      59                 :            : int reading_traces = 0;
      60                 :            : int have_pending_timers = 0;
      61                 :            : double pseudo_realtime = 0.0;
      62                 :            : char* user_pcap_filter = 0;
      63                 :            : bool using_communication = false;
      64                 :            : 
      65                 :            : double network_time = 0.0;      // time according to last packet timestamp
      66                 :            :                                 // (or current time)
      67                 :            : double processing_start_time = 0.0;     // time started working on current pkt
      68                 :            : double bro_start_time = 0.0; // time Bro started.
      69                 :            : double bro_start_network_time;  // timestamp of first packet
      70                 :            : double last_watchdog_proc_time = 0.0;   // value of above during last watchdog
      71                 :            : bool terminating = false;       // whether we're done reading and finishing up
      72                 :            : 
      73                 :            : PacketSortGlobalPQ* packet_sorter = 0;
      74                 :            : 
      75                 :            : const struct pcap_pkthdr* current_hdr = 0;
      76                 :            : const u_char* current_pkt = 0;
      77                 :            : int current_dispatched = 0;
      78                 :            : int current_hdr_size = 0;
      79                 :            : double current_timestamp = 0.0;
      80                 :            : PktSrc* current_pktsrc = 0;
      81                 :            : IOSource* current_iosrc;
      82                 :            : 
      83                 :            : 
      84                 :          0 : RETSIGTYPE watchdog(int /* signo */)
      85                 :            :         {
      86         [ #  # ]:          0 :         if ( processing_start_time != 0.0 )
      87                 :            :                 {
      88                 :            :                 // The signal arrived while we're processing a packet and/or
      89                 :            :                 // its corresponding event queue.  Check whether we've been
      90                 :            :                 // spending too much time, which we take to mean we've wedged.
      91                 :            : 
      92                 :            :                 // Note that it's subtle how exactly to test this.  In
      93                 :            :                 // processing_start_time we have the timestamp of the packet
      94                 :            :                 // we're currently working on.  But that *doesn't* mean that
      95                 :            :                 // we began work on the packet at that time; we could have
      96                 :            :                 // begun at a much later time, depending on how long the
      97                 :            :                 // packet filter waited (to fill its buffer) before handing
      98                 :            :                 // up this packet.  So what we require is that the current
      99                 :            :                 // processing_start_time matches the processing_start_time we
     100                 :            :                 // observed last time the watchdog went off.  If so, then
     101                 :            :                 // we've been working on the current packet for at least
     102                 :            :                 // watchdog_interval seconds.
     103                 :            : 
     104         [ #  # ]:          0 :                 if ( processing_start_time == last_watchdog_proc_time )
     105                 :            :                         {
     106                 :            :                         // snprintf() calls alloc/free routines if you use %f!
     107                 :            :                         // We need to avoid doing that given we're in a single
     108                 :            :                         // handler and the allocation routines are not
     109                 :            :                         // reentrant.
     110                 :            : 
     111                 :          0 :                         double ct = current_time();
     112                 :            : 
     113                 :          0 :                         int int_ct = int(ct);
     114                 :          0 :                         int frac_ct = int((ct - int_ct) * 1e6);
     115                 :            : 
     116                 :          0 :                         int int_pst = int(processing_start_time);
     117                 :            :                         int frac_pst =
     118                 :          0 :                                 int((processing_start_time - int_pst) * 1e6);
     119                 :            : 
     120                 :            :                         char msg[512];
     121                 :            :                         safe_snprintf(msg, sizeof(msg),
     122                 :            :                                       "**watchdog timer expired, t = %d.%06d, start = %d.%06d, dispatched = %d",
     123                 :            :                                       int_ct, frac_ct, int_pst, frac_pst,
     124                 :          0 :                                       current_dispatched);
     125                 :            : 
     126                 :          0 :                         bro_logger->Log(msg);
     127                 :          0 :                         run_time("watchdog timer expired");
     128                 :            : 
     129         [ #  # ]:          0 :                         if ( current_hdr )
     130                 :            :                                 {
     131         [ #  # ]:          0 :                                 if ( ! pkt_dumper )
     132                 :            :                                         {
     133                 :            :                                         // We aren't dumping packets; however,
     134                 :            :                                         // saving the packet which caused the
     135                 :            :                                         // watchdog to trigger may be helpful,
     136                 :            :                                         // so we'll save that one nevertheless.
     137                 :          0 :                                         pkt_dumper = new PktDumper("watchdog-pkt.pcap");
     138         [ #  # ]:          0 :                                         if ( pkt_dumper->IsError() )
     139                 :            :                                                 {
     140                 :          0 :                                                 fprintf(stderr, "watchdog: can't open watchdog-pkt.pcap for writing\n");
     141                 :          0 :                                                 pkt_dumper = 0;
     142                 :            :                                                 }
     143                 :            :                                         }
     144                 :            : 
     145         [ #  # ]:          0 :                                 if ( pkt_dumper )
     146                 :          0 :                                         pkt_dumper->Dump(current_hdr, current_pkt);
     147                 :            :                                 }
     148                 :            : 
     149                 :          0 :                         net_get_final_stats();
     150                 :          0 :                         net_finish(0);
     151                 :            : 
     152                 :          0 :                         abort();
     153                 :            :                         exit(1);
     154                 :            :                         }
     155                 :            :                 }
     156                 :            : 
     157                 :          0 :         last_watchdog_proc_time = processing_start_time;
     158                 :            : 
     159                 :          0 :         (void) alarm(watchdog_interval);
     160                 :            :         return RETSIGVAL;
     161                 :            :         }
     162                 :            : 
     163                 :            : void net_init(name_list& interfaces, name_list& readfiles, 
     164                 :            :               name_list& netflows, name_list& flowfiles,
     165                 :            :                 const char* writefile, const char* transformed_writefile,
     166                 :            :                 const char* filter, const char* secondary_filter,
     167                 :          1 :                 int do_watchdog)
     168                 :            :         {
     169                 :          1 :         init_net_var();
     170                 :            : 
     171   [ -  +  #  # ]:          1 :         if ( readfiles.length() > 0 || flowfiles.length() > 0 )
                 [ +  - ]
     172                 :            :                 {
     173                 :          1 :                 reading_live = pseudo_realtime > 0.0;
     174                 :          1 :                 reading_traces = 1;
     175                 :            : 
     176         [ +  + ]:          2 :                 for ( int i = 0; i < readfiles.length(); ++i )
     177                 :            :                         {
     178                 :          1 :                         PktFileSrc* ps = new PktFileSrc(readfiles[i], filter);
     179                 :            : 
     180         [ -  + ]:          1 :                         if ( ! ps->IsOpen() )
     181                 :            :                                 {
     182                 :            :                                 fprintf(stderr, "%s: problem with trace file %s - %s\n",
     183                 :          0 :                                         prog, readfiles[i], ps->ErrorMsg());
     184                 :          0 :                                 exit(1);
     185                 :            :                                 }
     186                 :            :                         else
     187                 :            :                                 {
     188                 :          1 :                                 pkt_srcs.append(ps);
     189                 :          1 :                                 io_sources.Register(ps);
     190                 :            :                                 }
     191                 :            : 
     192         [ -  + ]:          1 :                         if ( secondary_filter )
     193                 :            :                                 {
     194                 :            :                                 // We use a second PktFileSrc for the
     195                 :            :                                 // secondary path.
     196                 :            :                                 PktFileSrc* ps = new PktFileSrc(readfiles[i],
     197                 :            :                                                         secondary_filter,
     198                 :          0 :                                                         TYPE_FILTER_SECONDARY);
     199                 :            : 
     200         [ #  # ]:          0 :                                 if ( ! ps->IsOpen() )
     201                 :            :                                         {
     202                 :            :                                         fprintf(stderr, "%s: problem with trace file %s - %s\n",
     203                 :            :                                                 prog, readfiles[i],
     204                 :          0 :                                                 ps->ErrorMsg());
     205                 :          0 :                                         exit(1);
     206                 :            :                                         }
     207                 :            :                                 else
     208                 :            :                                         {
     209                 :          0 :                                         pkt_srcs.append(ps);
     210                 :          0 :                                         io_sources.Register(ps);
     211                 :            :                                         }
     212                 :            : 
     213                 :          0 :                                 ps->AddSecondaryTablePrograms();
     214                 :            :                                 }
     215                 :            :                         }
     216                 :            : 
     217         [ -  + ]:          1 :                 for ( int i = 0; i < flowfiles.length(); ++i )
     218                 :            :                         {
     219                 :          0 :                         FlowFileSrc* fs = new FlowFileSrc(flowfiles[i]);
     220                 :            : 
     221         [ #  # ]:          0 :                         if ( ! fs->IsOpen() )
     222                 :            :                                 {
     223                 :            :                                 fprintf(stderr, "%s: problem with netflow file %s - %s\n",
     224                 :          0 :                                         prog, flowfiles[i], fs->ErrorMsg());
     225                 :          0 :                                 exit(1);
     226                 :            :                                 }
     227                 :            :                         else
     228                 :            :                                 {
     229                 :          0 :                                 io_sources.Register(fs);
     230                 :            :                                 }
     231                 :            :                         }
     232                 :            :                 }
     233                 :            : 
     234 [ #  # ][ #  # ]:          0 :         else if ((interfaces.length() > 0 || netflows.length() > 0))
                 [ #  # ]
     235                 :            :                 {
     236                 :          0 :                 reading_live = 1;
     237                 :          0 :                 reading_traces = 0;
     238                 :            : 
     239         [ #  # ]:          0 :                 for ( int i = 0; i < interfaces.length(); ++i )
     240                 :            :                         {
     241                 :            :                         PktSrc* ps;
     242                 :          0 :                         ps = new PktInterfaceSrc(interfaces[i], filter);
     243                 :            : 
     244         [ #  # ]:          0 :                         if ( ! ps->IsOpen() )
     245                 :            :                                 {
     246                 :            :                                 fprintf(stderr, "%s: problem with interface %s - %s\n",
     247                 :          0 :                                         prog, interfaces[i], ps->ErrorMsg());
     248                 :          0 :                                 exit(1);
     249                 :            :                                 }
     250                 :            :                         else
     251                 :            :                                 {
     252                 :          0 :                                 pkt_srcs.append(ps);
     253                 :          0 :                                 io_sources.Register(ps);
     254                 :            :                                 }
     255                 :            : 
     256         [ #  # ]:          0 :                         if ( secondary_filter )
     257                 :            :                                 {
     258                 :            :                                 PktSrc* ps;
     259                 :            :                                 ps = new PktInterfaceSrc(interfaces[i],
     260                 :          0 :                                         filter, TYPE_FILTER_SECONDARY);
     261                 :            : 
     262         [ #  # ]:          0 :                                 if ( ! ps->IsOpen() )
     263                 :            :                                         {
     264                 :            :                                         fprintf(stderr, "%s: problem with interface %s - %s\n",
     265                 :            :                                                 prog, interfaces[i],
     266                 :          0 :                                                 ps->ErrorMsg());
     267                 :          0 :                                         exit(1);
     268                 :            :                                         }
     269                 :            :                                 else
     270                 :            :                                         {
     271                 :          0 :                                         pkt_srcs.append(ps);
     272                 :          0 :                                         io_sources.Register(ps);
     273                 :            :                                         }
     274                 :            : 
     275                 :          0 :                                 ps->AddSecondaryTablePrograms();
     276                 :            :                                 }
     277                 :            :                         }
     278                 :            : 
     279         [ #  # ]:          0 :                 for ( int i = 0; i < netflows.length(); ++i )
     280                 :            :                         {
     281                 :          0 :                         FlowSocketSrc* fs = new FlowSocketSrc(netflows[i]);
     282                 :            : 
     283         [ #  # ]:          0 :                         if ( ! fs->IsOpen() )
     284                 :            :                                 {
     285                 :            :                                 fprintf(stderr, "%s: problem with netflow socket %s - %s\n",
     286                 :          0 :                                         prog, netflows[i], fs->ErrorMsg());
     287                 :          0 :                                 exit(1);
     288                 :            :                                 }
     289                 :            :                         else
     290                 :            :                                 {
     291                 :          0 :                                 io_sources.Register(fs);
     292                 :            :                                 }
     293                 :            :                         }
     294                 :            : 
     295                 :            :                 }
     296                 :            : 
     297                 :            :         else
     298                 :            :                 // have_pending_timers = 1, possibly.  We don't set
     299                 :            :                 // that here, though, because at this point we don't know
     300                 :            :                 // whether the user's bro_init() event will indeed set
     301                 :            :                 // a timer.
     302                 :          0 :                 reading_traces = reading_live = 0;
     303                 :            : 
     304         [ -  + ]:          1 :         if ( writefile )
     305                 :            :                 {
     306                 :            :                 // ### This will fail horribly if there are multiple
     307                 :            :                 // interfaces with different-lengthed media.
     308                 :          0 :                 pkt_dumper = new PktDumper(writefile);
     309         [ #  # ]:          0 :                 if ( pkt_dumper->IsError() )
     310                 :            :                         {
     311                 :            :                         fprintf(stderr, "%s: can't open write file \"%s\" - %s\n",
     312                 :          0 :                                 prog, writefile, pkt_dumper->ErrorMsg());
     313                 :          0 :                         exit(1);
     314                 :            :                         }
     315                 :            : 
     316                 :          0 :                 ID* id = global_scope()->Lookup("trace_output_file");
     317         [ #  # ]:          0 :                 if ( ! id )
     318                 :          0 :                         run_time("trace_output_file not defined in bro.init");
     319                 :            :                 else
     320                 :          0 :                         id->SetVal(new StringVal(writefile));
     321                 :            :                 }
     322                 :            : 
     323         [ -  + ]:          1 :         if ( transformed_writefile )
     324                 :            :                 {
     325                 :          0 :                 pkt_transformed_dumper = new PktDumper(transformed_writefile);
     326         [ #  # ]:          0 :                 if ( pkt_transformed_dumper->IsError() )
     327                 :            :                         {
     328                 :            :                         fprintf(stderr, "%s: can't open trace transformation write file \"%s\" - %s\n",
     329                 :            :                                 prog, writefile,
     330                 :          0 :                                 pkt_transformed_dumper->ErrorMsg());
     331                 :          0 :                         exit(1);
     332                 :            :                         }
     333                 :            : 
     334                 :            :                 transformed_pkt_dump =
     335                 :          0 :                         new PacketDumper(pkt_transformed_dumper->PcapDumper());
     336                 :            : 
     337                 :            :                 // If both -A and -w are specified, -A will be the transformed
     338                 :            :                 // trace file and -w will be the source packet trace file.
     339                 :            :                 // Otherwise the packets will go to the same file.
     340         [ #  # ]:          0 :                 if ( pkt_dumper )
     341                 :            :                         source_pkt_dump =
     342                 :          0 :                                 new PacketDumper(pkt_dumper->PcapDumper());
     343                 :            :                 }
     344                 :            : 
     345         [ -  + ]:          1 :         else if ( pkt_dumper )
     346                 :            :                 transformed_pkt_dump =
     347                 :          0 :                         new PacketDumper(pkt_dumper->PcapDumper());
     348                 :            : 
     349         [ -  + ]:          1 :         if ( anonymize_ip_addr )
     350                 :          0 :                 init_ip_addr_anonymizers();
     351                 :            :         else
     352         [ +  + ]:          6 :                 for ( int i = 0; i < NUM_ADDR_ANONYMIZATION_METHODS; ++i )
     353                 :          5 :                         ip_anonymizer[i] = 0;
     354                 :            : 
     355         [ -  + ]:          1 :         if ( packet_sort_window > 0 )
     356                 :          0 :                 packet_sorter = new PacketSortGlobalPQ();
     357                 :            : 
     358                 :          1 :         sessions = new NetSessions();
     359                 :            : 
     360         [ -  + ]:          1 :         if ( do_watchdog )
     361                 :            :                 {
     362                 :            :                 // Set up the watchdog to make sure we don't wedge.
     363                 :          0 :                 (void) setsignal(SIGALRM, watchdog);
     364                 :          0 :                 (void) alarm(watchdog_interval);
     365                 :            :                 }
     366                 :          1 :         }
     367                 :            : 
     368                 :      21347 : void expire_timers(PktSrc* src_ps)
     369                 :            :         {
     370                 :      21347 :         SegmentProfiler(segment_logger, "expiring-timers");
     371                 :            :         TimerMgr* tmgr =
     372                 :            :                 src_ps ? sessions->LookupTimerMgr(src_ps->GetCurrentTag())
     373         [ +  - ]:      21347 :                         : timer_mgr;
     374                 :            : 
     375                 :            :         current_dispatched +=
     376                 :            :                 tmgr->Advance(network_time,
     377                 :      21347 :                                 max_timer_expires - current_dispatched);
     378                 :      21347 :         }
     379                 :            : 
     380                 :            : void net_packet_dispatch(double t, const struct pcap_pkthdr* hdr,
     381                 :            :                         const u_char* pkt, int hdr_size,
     382                 :      21347 :                         PktSrc* src_ps, PacketSortElement* pkt_elem)
     383                 :            :         {
     384         [ +  + ]:      21347 :         if ( ! bro_start_network_time )
     385                 :          1 :                 bro_start_network_time = t;
     386                 :            : 
     387                 :            :         TimerMgr* tmgr =
     388                 :            :                 src_ps ? sessions->LookupTimerMgr(src_ps->GetCurrentTag())
     389         [ +  - ]:      21347 :                         : timer_mgr;
     390                 :            : 
     391                 :            :         // network_time never goes back.
     392         [ +  + ]:      21347 :         network_time = tmgr->Time() < t ? t : tmgr->Time();
     393                 :            : 
     394                 :      21347 :         current_pktsrc = src_ps;
     395                 :      21347 :         current_iosrc = src_ps;
     396                 :      21347 :         processing_start_time = t;
     397                 :            : 
     398                 :      21347 :         expire_timers(src_ps);
     399                 :            : 
     400                 :      21347 :         SegmentProfiler* sp = 0;
     401                 :            : 
     402         [ -  + ]:      21347 :         if ( load_sample )
     403                 :            :                 {
     404                 :            :                 static uint32 load_freq = 0;
     405                 :            : 
     406         [ #  # ]:          0 :                 if ( load_freq == 0 )
     407                 :          0 :                         load_freq = uint32(0xffffffff) / uint32(load_sample_freq);
     408                 :            : 
     409         [ #  # ]:          0 :                 if ( uint32(random() & 0xffffffff) < load_freq )
     410                 :            :                         {
     411                 :            :                         // Drain the queued timer events so they're not
     412                 :            :                         // charged against this sample.
     413                 :          0 :                         mgr.Drain();
     414                 :            : 
     415                 :          0 :                         sample_logger = new SampleLogger();
     416                 :          0 :                         sp = new SegmentProfiler(sample_logger, "load-samp");
     417                 :            :                         }
     418                 :            :                 }
     419                 :            : 
     420                 :      21347 :         sessions->DispatchPacket(t, hdr, pkt, hdr_size, src_ps, pkt_elem);
     421                 :      21347 :         mgr.Drain();
     422                 :            : 
     423         [ -  + ]:      21347 :         if ( sp )
     424                 :            :                 {
     425         [ #  # ]:          0 :                 delete sp;
     426         [ #  # ]:          0 :                 delete sample_logger;
     427                 :          0 :                 sample_logger = 0;
     428                 :            :                 }
     429                 :            : 
     430                 :      21347 :         processing_start_time = 0.0;    // = "we're not processing now"
     431                 :      21347 :         current_dispatched = 0;
     432                 :      21347 :         current_iosrc = 0;
     433                 :      21347 :         current_pktsrc = 0;
     434                 :      21347 :         }
     435                 :            : 
     436                 :          0 : int process_packet_sorter(double latest_packet_time)
     437                 :            :         {
     438         [ #  # ]:          0 :         if ( ! packet_sorter )
     439                 :          0 :                 return 0;
     440                 :            : 
     441                 :          0 :         double min_t = latest_packet_time - packet_sort_window;
     442                 :            : 
     443                 :          0 :         int num_pkts_dispatched = 0;
     444                 :            :         PacketSortElement* pkt_elem;
     445                 :            : 
     446                 :            :         // Dispatch packets in the packet_sorter until timestamp min_t.
     447                 :            :         // It's possible that zero or multiple packets are dispatched.
     448         [ #  # ]:          0 :         while ( (pkt_elem = packet_sorter->RemoveMin(min_t)) != 0 )
     449                 :            :                 {
     450                 :            :                 net_packet_dispatch(pkt_elem->TimeStamp(),
     451                 :            :                         pkt_elem->Hdr(), pkt_elem->Pkt(),
     452                 :            :                         pkt_elem->HdrSize(), pkt_elem->Src(),
     453                 :          0 :                         pkt_elem);
     454                 :          0 :                 ++num_pkts_dispatched;
     455         [ #  # ]:          0 :                 delete pkt_elem;
     456                 :            :                 }
     457                 :            : 
     458                 :          0 :         return num_pkts_dispatched;
     459                 :            :         }
     460                 :            : 
     461                 :            : void net_packet_arrival(double t, const struct pcap_pkthdr* hdr,
     462                 :            :                         const u_char* pkt, int hdr_size,
     463                 :      21347 :                         PktSrc* src_ps)
     464                 :            :         {
     465         [ -  + ]:      21347 :         if ( packet_sorter )
     466                 :            :                 {
     467                 :            :                 // Note that when we enable packet sorter, there will
     468                 :            :                 // be a small window between the time packet arrives
     469                 :            :                 // to Bro and when it is processed ("dispatched").  We
     470                 :            :                 // define network_time to be the latest timestamp for
     471                 :            :                 // packets *dispatched* so far (usually that's the
     472                 :            :                 // timestamp of the current packet).
     473                 :            : 
     474                 :            :                 // Add the packet to the packet_sorter.
     475                 :            :                 packet_sorter->Add(
     476                 :          0 :                         new PacketSortElement(src_ps, t, hdr, pkt, hdr_size));
     477                 :            : 
     478                 :            :                 // Do we have any packets to dispatch from packet_sorter?
     479                 :          0 :                 process_packet_sorter(t);
     480                 :            :                 }
     481                 :            :         else
     482                 :            :                 // Otherwise we dispatch the packet immediately
     483                 :      21347 :                 net_packet_dispatch(t, hdr, pkt, hdr_size, src_ps, 0);
     484                 :      21347 :         }
     485                 :            : 
     486                 :          1 : void net_run()
     487                 :            :         {
     488                 :          1 :         set_processing_status("RUNNING", "net_run");
     489                 :            : 
     490 [ +  + ][ -  + ]:      21350 :         while ( io_sources.Size() ||
         [ #  # ][ +  + ]
     491                 :            :                 (packet_sorter && ! packet_sorter->Empty()) )
     492                 :            :                 {
     493                 :            :                 double ts;
     494                 :      21349 :                 IOSource* src = io_sources.FindSoonest(&ts);
     495                 :            : 
     496                 :            : #ifdef DEBUG
     497                 :            :                 static int loop_counter = 0;
     498                 :            : 
     499                 :            :                 // If no source is ready, we log only every 100th cycle,
     500                 :            :                 // starting with the first.
     501   [ +  +  +  + ]:      21349 :                 if ( src || loop_counter++ % 100 == 0 )
                 [ +  + ]
     502                 :            :                         {
     503 [ +  + ][ +  + ]:      21348 :                         DBG_LOG(DBG_MAINLOOP, "realtime=%.6f iosrc=%s ts=%.6f",
     504                 :            :                                         current_time(), src ? src->Tag() : "<all dry>", src ? ts : -1);
     505                 :            : 
     506         [ +  + ]:      21348 :                         if ( src )
     507                 :      21347 :                                 loop_counter = 0;
     508                 :            :                         }
     509                 :            : #endif
     510                 :      21349 :                 current_iosrc = src;
     511                 :            : 
     512         [ +  + ]:      21349 :                 if ( src )
     513                 :      21347 :                         src->Process();      // which will call net_packet_arrival()
     514                 :            : 
     515 [ -  + ][ #  # ]:          2 :                 else if ( reading_live && ! pseudo_realtime)
     516                 :            :                         { // live but  no source is currently active
     517                 :          0 :                         double ct = current_time();
     518   [ #  #  #  # ]:          0 :                         if ( packet_sorter && ! packet_sorter->Empty() )
                 [ #  # ]
     519                 :          0 :                                 process_packet_sorter(ct);
     520         [ #  # ]:          0 :                         else if ( ! net_is_processing_suspended() )
     521                 :            :                                 {
     522                 :            :                                 // Take advantage of the lull to get up to
     523                 :            :                                 // date on timers and events.
     524                 :          0 :                                 network_time = ct;
     525                 :          0 :                                 expire_timers();
     526                 :            :                                 }
     527                 :            :                         }
     528                 :            : 
     529 [ -  + ][ #  # ]:          2 :                 else if ( packet_sorter && ! packet_sorter->Empty() )
                 [ -  + ]
     530                 :            :                         {
     531                 :            :                         // We are no longer reading live; done with all the
     532                 :            :                         // sources.
     533                 :            :                         // Drain packets remaining in the packet sorter.
     534                 :            :                         process_packet_sorter(
     535                 :          0 :                                 network_time + packet_sort_window + 1000000);
     536                 :            :                         }
     537                 :            : 
     538 [ +  - ][ -  + ]:          2 :                 else if ( (have_pending_timers || using_communication) &&
                 [ #  # ]
     539                 :            :                           ! pseudo_realtime )
     540                 :            :                         {
     541                 :            :                         // Take advantage of the lull to get up to
     542                 :            :                         // date on timers and events.  Because we only
     543                 :            :                         // have timers as sources, going to sleep here
     544                 :            :                         // doesn't risk blocking on other inputs.
     545                 :          0 :                         network_time = current_time();
     546                 :          0 :                         expire_timers();
     547                 :            : 
     548                 :            :                         // Avoid busy-waiting - pause for 100 ms.
     549                 :            :                         // We pick a sleep value of 100 msec that buys
     550                 :            :                         // us a lot of idle time, but doesn't delay near-term
     551                 :            :                         // timers too much.  (Delaying them somewhat is okay,
     552                 :            :                         // since Bro timers are not high-precision anyway.)
     553         [ #  # ]:          0 :                         if ( ! using_communication )
     554                 :          0 :                                 usleep(100000);
     555                 :            : 
     556                 :            :                         // Flawfinder says about usleep:
     557                 :            :                         //
     558                 :            :                         // This C routine is considered obsolete (as opposed
     559                 :            :                         // to the shell command by the same name).   The
     560                 :            :                         // interaction of this function with SIGALRM and
     561                 :            :                         // other timer functions such as sleep(), alarm(),
     562                 :            :                         // setitimer(), and nanosleep() is unspecified.
     563                 :            :                         // Use nanosleep(2) or setitimer(2) instead.
     564                 :            :                         }
     565                 :            : 
     566                 :      21349 :                 mgr.Drain();
     567                 :            : 
     568                 :      21349 :                 processing_start_time = 0.0;    // = "we're not processing now"
     569                 :      21349 :                 current_dispatched = 0;
     570                 :      21349 :                 current_iosrc = 0;
     571                 :            : 
     572                 :            :                 // Should we put the signal handling into an IOSource?
     573                 :            :                 extern void termination_signal();
     574                 :            : 
     575   [ +  -  -  + ]:      21349 :                 if ( signal_val == SIGTERM || signal_val == SIGINT )
     576                 :            :                         // We received a signal while processing the
     577                 :            :                         // current packet and its related events.
     578                 :          0 :                         termination_signal();
     579                 :            : 
     580                 :            : #ifdef DEBUG_COMMUNICATION
     581                 :            :                 if ( signal_val == SIGPROF && remote_serializer )
     582                 :            :                         remote_serializer->DumpDebugData();
     583                 :            : #endif
     584                 :            : 
     585         [ -  + ]:      21349 :                 if ( ! reading_traces )
     586                 :            :                         // Check whether we have timers scheduled for
     587                 :            :                         // the future on which we need to wait.
     588                 :          0 :                         have_pending_timers = timer_mgr->Size() > 0;
     589                 :            :                 }
     590                 :            : 
     591                 :            :         // Get the final statistics now, and not when net_finish() is
     592                 :            :         // called, since that might happen quite a bit in the future
     593                 :            :         // due to expiring pending timers, and we don't want to ding
     594                 :            :         // for any packets dropped beyond this point.
     595                 :          1 :         net_get_final_stats();
     596                 :          1 :         }
     597                 :            : 
     598                 :          1 : void net_get_final_stats()
     599                 :            :         {
     600         [ +  + ]:          2 :         loop_over_list(pkt_srcs, i)
     601                 :            :                 {
     602                 :          1 :                 PktSrc* ps = pkt_srcs[i];
     603                 :            : 
     604         [ -  + ]:          1 :                 if ( ps->IsLive() )
     605                 :            :                         {
     606                 :            :                         struct PktSrc::Stats s;
     607                 :          0 :                         ps->Statistics(&s);
     608                 :            :                         fprintf(stderr, "%d packets received on interface %s, %d dropped\n",
     609                 :          0 :                                         s.received, ps->Interface(), s.dropped);
     610                 :            :                         }
     611                 :            :                 }
     612                 :          1 :         }
     613                 :            : 
     614                 :          1 : void net_finish(int drain_events)
     615                 :            :         {
     616                 :          1 :         set_processing_status("TERMINATING", "net_finish");
     617                 :            : 
     618         [ +  - ]:          1 :         if ( drain_events )
     619                 :            :                 {
     620         [ +  - ]:          1 :                 if ( sessions )
     621                 :          1 :                         sessions->Drain();
     622                 :            : 
     623                 :          1 :                 mgr.Drain();
     624                 :            : 
     625         [ +  - ]:          1 :                 if ( sessions )
     626                 :          1 :                         sessions->Done();
     627                 :            :                 }
     628                 :            : 
     629         [ -  + ]:          1 :         delete pkt_dumper;
     630         [ -  + ]:          1 :         delete pkt_transformed_dumper;
     631                 :            : 
     632                 :            :         // fprintf(stderr, "uhash: %d/%d\n", hash_cnt_uhash, hash_cnt_all);
     633                 :            : 
     634                 :            : #ifdef DEBUG
     635                 :            :         extern int reassem_seen_bytes, reassem_copied_bytes;
     636                 :            :         // DEBUG_MSG("Reassembly (TCP and IP/Frag): %d bytes seen, %d bytes copied\n",
     637                 :            :         //      reassem_seen_bytes, reassem_copied_bytes);
     638                 :            : 
     639                 :            :         extern int num_packets_held, num_packets_cleaned;
     640                 :            :         // DEBUG_MSG("packets clean up: %d/%d\n", num_packets_cleaned, num_packets_held);
     641                 :            : #endif
     642                 :          1 :         }
     643                 :            : 
     644                 :          1 : void net_delete()
     645                 :            :         {
     646                 :          1 :         set_processing_status("TERMINATING", "net_delete");
     647                 :            : 
     648         [ +  - ]:          1 :         delete sessions;
     649         [ -  + ]:          1 :         delete packet_sorter;
     650                 :            : 
     651                 :            :         // Can't put this in net_finish() because packets might be
     652                 :            :         // dumped when connections are deleted.
     653         [ -  + ]:          1 :         if ( transformed_pkt_dump )
     654                 :          0 :                 delete transformed_pkt_dump;
     655                 :            : 
     656         [ +  + ]:          6 :         for ( int i = 0; i < NUM_ADDR_ANONYMIZATION_METHODS; ++i )
     657         [ -  + ]:          5 :                 delete ip_anonymizer[i];
     658                 :          1 :         }
     659                 :            : 
     660                 :            : // net_packet_match
     661                 :            : //
     662                 :            : // Description:
     663                 :            : //  - Checks if a packet matches a filter. It just wraps up a call to
     664                 :            : //    [pcap.h's] bpf_filter().
     665                 :            : //
     666                 :            : // Inputs:
     667                 :            : //  - fp: a BPF-compiled filter
     668                 :            : //  - pkt: a pointer to the packet
     669                 :            : //  - len: the original packet length
     670                 :            : //  - caplen: the captured packet length. This is pkt length
     671                 :            : //
     672                 :            : // Output:
     673                 :            : //  - return: 1 if the packet matches the filter, 0 otherwise
     674                 :            : 
     675                 :            : int net_packet_match(BPF_Program* fp, const u_char* pkt,
     676                 :          0 :                      u_int len, u_int caplen)
     677                 :            :         {
     678                 :            :         // NOTE: I don't like too much un-const'ing the pkt variable.
     679                 :          0 :         return bpf_filter(fp->GetProgram()->bf_insns, (u_char*) pkt, len, caplen);
     680                 :            :         }
     681                 :            : 
     682                 :            : 
     683                 :            : int _processing_suspended = 0;
     684                 :            : 
     685                 :            : static double suspend_start = 0;
     686                 :            : 
     687                 :          0 : void net_suspend_processing()
     688                 :            :         {
     689         [ #  # ]:          0 :         if ( _processing_suspended == 0 )
     690                 :          0 :                 bro_logger->Log("processing suspended");
     691                 :            : 
     692                 :          0 :         ++_processing_suspended;
     693                 :          0 :         }
     694                 :            : 
     695                 :          0 : void net_continue_processing()
     696                 :            :         {
     697         [ #  # ]:          0 :         if ( _processing_suspended == 1 )
     698                 :            :                 {
     699                 :          0 :                 bro_logger->Log("processing continued");
     700         [ #  # ]:          0 :                 loop_over_list(pkt_srcs, i)
     701                 :          0 :                         pkt_srcs[i]->ContinueAfterSuspend();
     702                 :            :                 }
     703                 :            : 
     704                 :          0 :         --_processing_suspended;
     705 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8