LCOV - code coverage report
Current view: top level - src - UDP.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 61 91 67.0 %
Date: 2010-12-13 Functions: 9 13 69.2 %
Branches: 31 82 37.8 %

           Branch data     Line data    Source code
       1                 :            : // $Id: UDP.cc 6219 2008-10-01 05:39:07Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : #include "Net.h"
       8                 :            : #include "NetVar.h"
       9                 :            : #include "UDP.h"
      10                 :            : #include "UDP_Rewriter.h"
      11                 :            : 
      12                 :        684 : UDP_Analyzer::UDP_Analyzer(Connection* conn)
      13                 :        684 : : TransportLayerAnalyzer(AnalyzerTag::UDP, conn)
      14                 :            :         {
      15                 :        684 :         conn->EnableStatusUpdateTimer();
      16                 :        684 :         conn->SetInactivityTimeout(udp_inactivity_timeout);
      17                 :        684 :         request_len = reply_len = -1;   // -1 means "haven't seen any activity"
      18                 :        684 :         }
      19                 :            : 
      20                 :        684 : UDP_Analyzer::~UDP_Analyzer()
      21                 :            :         {
      22                 :            :         // XXX: need to implement this!
      23                 :            :         // delete src_pkt_writer;
      24 [ +  - ][ #  # ]:        684 :         }
                 [ #  # ]
      25                 :            : 
      26                 :        684 : void UDP_Analyzer::Init()
      27                 :            :         {
      28 [ -  + ][ #  # ]:        684 :         if ( transformed_pkt_dump && RewritingTrace() )
                 [ -  + ]
      29                 :            :                 SetTraceRewriter(new UDP_Rewriter(this, transformed_pkt_dump_MTU,
      30                 :          0 :                                         transformed_pkt_dump));
      31                 :        684 :         }
      32                 :            : 
      33                 :        684 : void UDP_Analyzer::Done()
      34                 :            :         {
      35                 :        684 :         Analyzer::Done();
      36                 :        684 :         }
      37                 :            : 
      38                 :            : void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
      39                 :       1683 :                                         int seq, const IP_Hdr* ip, int caplen)
      40                 :            :         {
      41         [ -  + ]:       1683 :         assert(ip);
      42                 :            : 
      43                 :       1683 :         Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
      44                 :            : 
      45                 :       1683 :         const struct udphdr* up = (const struct udphdr*) data;
      46                 :            : 
      47                 :            :         // Increment data before checksum check so that data will
      48                 :            :         // point to UDP payload even if checksum fails. Particularly,
      49                 :            :         // it allows event packet_contents to get to the data.
      50                 :       1683 :         data += sizeof(struct udphdr);
      51                 :            : 
      52                 :            :         // We need the min() here because Ethernet frame padding can lead to
      53                 :            :         // caplen > len.
      54         [ -  + ]:       1683 :         if ( packet_contents )
      55                 :          0 :                 PacketContents(data, min(len, caplen) - sizeof(struct udphdr));
      56                 :            : 
      57                 :       1683 :         int chksum = up->uh_sum;
      58                 :            : 
      59 [ +  - ][ +  - ]:       1683 :         if ( ! ignore_checksums && caplen >= len )
      60                 :            :                 {
      61                 :       1683 :                 bool bad = false;
      62                 :            : 
      63 [ +  - ][ +  - ]:       1683 :                 if ( ip->IP4_Hdr() && chksum &&
         [ -  + ][ -  + ]
      64                 :            :                      udp_checksum(ip->IP4_Hdr(), up, len) != 0xffff )
      65                 :          0 :                         bad = true;
      66                 :            : 
      67                 :            : #ifdef BROv6
      68                 :            :                 if ( ip->IP6_Hdr() && /* checksum is not optional for IPv6 */
      69                 :            :                      udp6_checksum(ip->IP6_Hdr(), up, len) != 0xffff )
      70                 :            :                         bad = true;
      71                 :            : #endif
      72                 :            : 
      73         [ -  + ]:       1683 :                 if ( bad )
      74                 :            :                         {
      75                 :          0 :                         Weird("bad_UDP_checksum");
      76                 :            : 
      77         [ #  # ]:          0 :                         if ( is_orig )
      78                 :          0 :                                 Conn()->CheckHistory(HIST_ORIG_CORRUPT_PKT, 'C');
      79                 :            :                         else
      80                 :          0 :                                 Conn()->CheckHistory(HIST_RESP_CORRUPT_PKT, 'c');
      81                 :            : 
      82                 :          0 :                         return;
      83                 :            :                         }
      84                 :            :                 }
      85                 :            : 
      86                 :       1683 :         int ulen = ntohs(up->uh_ulen);
      87         [ -  + ]:       1683 :         if ( ulen != len )
      88                 :          0 :                 Weird(fmt("UDP_datagram_length_mismatch(%d!=%d)", ulen, len));
      89                 :            : 
      90                 :       1683 :         len -= sizeof(struct udphdr);
      91                 :       1683 :         ulen -= sizeof(struct udphdr);
      92                 :       1683 :         caplen -= sizeof(struct udphdr);
      93                 :            : 
      94                 :       1683 :         Conn()->SetLastTime(current_timestamp);
      95                 :            : 
      96         [ -  + ]:       1683 :         if ( udp_contents )
      97                 :            :                 {
      98                 :          0 :                 PortVal port_val(ntohs(up->uh_dport), TRANSPORT_UDP);
      99                 :          0 :                 Val* result = 0;
     100                 :          0 :                 bool do_udp_contents = false;
     101                 :            : 
     102         [ #  # ]:          0 :                 if ( is_orig )
     103                 :            :                         {
     104                 :            :                         result = udp_content_delivery_ports_orig->Lookup(
     105                 :          0 :                                                                 &port_val);
     106   [ #  #  #  # ]:          0 :                         if ( udp_content_deliver_all_orig ||
         [ #  # ][ #  # ]
     107                 :            :                              (result && result->AsBool()) )
     108                 :          0 :                                 do_udp_contents = true;
     109                 :            :                         }
     110                 :            :                 else
     111                 :            :                         {
     112                 :            :                         result = udp_content_delivery_ports_resp->Lookup(
     113                 :          0 :                                                                 &port_val);
     114   [ #  #  #  # ]:          0 :                         if ( udp_content_deliver_all_resp ||
         [ #  # ][ #  # ]
     115                 :            :                              (result && result->AsBool()) )
     116                 :          0 :                                 do_udp_contents = true;
     117                 :            :                         }
     118                 :            : 
     119         [ #  # ]:          0 :                 if ( do_udp_contents )
     120                 :            :                         {
     121                 :          0 :                         val_list* vl = new val_list;
     122                 :          0 :                         vl->append(BuildConnVal());
     123                 :          0 :                         vl->append(new Val(is_orig, TYPE_BOOL));
     124                 :          0 :                         vl->append(new StringVal(len, (const char*) data));
     125                 :          0 :                         ConnectionEvent(udp_contents, vl);
     126                 :          0 :                         }
     127                 :            :                 }
     128                 :            : 
     129         [ +  + ]:       1683 :         if ( is_orig )
     130                 :            :                 {
     131                 :       1173 :                 Conn()->CheckHistory(HIST_ORIG_DATA_PKT, 'D');
     132                 :            : 
     133         [ +  + ]:       1173 :                 if ( request_len < 0 )
     134                 :        563 :                         request_len = ulen;
     135                 :            :                 else
     136                 :            :                         {
     137                 :        610 :                         request_len += ulen;
     138                 :            : #ifdef DEBUG
     139         [ -  + ]:        610 :                         if ( request_len < 0 )
     140                 :          0 :                                 warn("wrapping around for UDP request length");
     141                 :            : #endif
     142                 :            :                         }
     143                 :            : 
     144                 :       1173 :                 Event(udp_request);
     145                 :            :                 }
     146                 :            : 
     147                 :            :         else
     148                 :            :                 {
     149                 :        510 :                 Conn()->CheckHistory(HIST_RESP_DATA_PKT, 'd');
     150                 :            : 
     151         [ +  + ]:        510 :                 if ( reply_len < 0 )
     152                 :        399 :                         reply_len = ulen;
     153                 :            :                 else
     154                 :            :                         {
     155                 :        111 :                         reply_len += ulen;
     156                 :            : #ifdef DEBUG
     157         [ -  + ]:        111 :                         if ( reply_len < 0 )
     158                 :          0 :                                 warn("wrapping around for UDP reply length");
     159                 :            : #endif
     160                 :            :                         }
     161                 :            : 
     162                 :        510 :                 Event(udp_reply);
     163                 :            :                 }
     164                 :            : 
     165         [ +  - ]:       1683 :         if ( caplen >= len )
     166                 :       1683 :                 ForwardPacket(len, data, is_orig, seq, ip, caplen);
     167                 :            : 
     168 [ -  + ][ #  # ]:       1683 :         if ( TraceRewriter() && current_hdr )
                 [ -  + ]
     169                 :            :                 ((UDP_Rewriter*) TraceRewriter())->NextPacket(is_orig,
     170                 :            :                                         current_timestamp, current_hdr, current_pkt,
     171                 :       1683 :                                         current_hdr_size, ip->IP4_Hdr(), up);
     172                 :            : 
     173                 :            : #if 0
     174                 :            :                 // XXX: needs to be implemented fully!
     175                 :            :         if ( src_pkt_writer && current_hdr )
     176                 :            :                 src_pkt_writer->NextPacket(current_hdr, current_pkt);
     177                 :            : #endif
     178                 :            :         }
     179                 :            : 
     180                 :       2736 : void UDP_Analyzer::UpdateEndpointVal(RecordVal* endp, int is_orig)
     181                 :            :         {
     182         [ +  + ]:       2736 :         bro_int_t size = is_orig ? request_len : reply_len;
     183         [ +  + ]:       2736 :         if ( size < 0 )
     184                 :            :                 {
     185                 :       1774 :                 endp->Assign(0, new Val(0, TYPE_COUNT));
     186                 :       1774 :                 endp->Assign(1, new Val(int(UDP_INACTIVE), TYPE_COUNT));
     187                 :            :                 }
     188                 :            : 
     189                 :            :         else
     190                 :            :                 {
     191                 :        962 :                 endp->Assign(0, new Val(size, TYPE_COUNT));
     192                 :        962 :                 endp->Assign(1, new Val(int(UDP_ACTIVE), TYPE_COUNT));
     193                 :            :                 }
     194                 :       2736 :         }
     195                 :            : 
     196                 :        999 : bool UDP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
     197                 :            :         {
     198                 :        999 :         return 0;
     199                 :            :         }
     200                 :            : 
     201                 :          0 : unsigned int UDP_Analyzer::MemoryAllocation() const
     202                 :            :         {
     203                 :            :         // A rather low lower bound....
     204                 :          0 :         return Analyzer::MemoryAllocation() + padded_sizeof(*this) - 24;
     205 [ +  - ][ +  - ]:          6 :         }
     206                 :          3 : 
     207                 :            : 

Generated by: LCOV version 1.8