LCOV - code coverage report
Current view: top level - src - UDP_Rewriter.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2 179 1.1 %
Date: 2010-12-13 Functions: 2 31 6.5 %
Branches: 2 116 1.7 %

           Branch data     Line data    Source code
       1                 :            : // $Id:$
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : 
       6                 :            : #include "config.h"
       7                 :            : 
       8                 :            : #include <assert.h>
       9                 :            : #include <stdlib.h>
      10                 :            : 
      11                 :            : #include "Event.h"
      12                 :            : #include "Net.h"
      13                 :            : #include "UDP_Rewriter.h"
      14                 :            : 
      15                 :            : #define MSG_PREFIX      "UDP trace rewriter: "
      16                 :            : #define DEBUG_MSG_A(x...)
      17                 :            : // #define DEBUG_MSG_A  DEBUG_MSG
      18                 :            : 
      19                 :            : 
      20                 :            : UDP_Rewriter::UDP_Rewriter(Analyzer* arg_analyzer, int arg_MTU,
      21                 :          0 :                                 PacketDumper* arg_dumper)
      22                 :            :         {
      23                 :          0 :         analyzer = arg_analyzer;
      24                 :          0 :         MTU = arg_MTU;
      25                 :          0 :         dumper = arg_dumper;
      26                 :          0 :         packets_rewritten = 0;
      27                 :          0 :         current_packet = next_packet = 0;
      28                 :            : 
      29   [ #  #  #  # ]:          0 :         if ( anonymize_ip_addr )
      30                 :            :                 {
      31                 :            :                 anon_addr[0] = anonymize_ip(to_v4_addr(analyzer->Conn()->OrigAddr()),
      32                 :          0 :                                                 ORIG_ADDR);
      33                 :            :                 anon_addr[1] = anonymize_ip(to_v4_addr(analyzer->Conn()->RespAddr()),
      34                 :          0 :                                                 RESP_ADDR);
      35                 :            :                 }
      36                 :            :         else
      37                 :          0 :                 anon_addr[0] = anon_addr[1] = 0;
      38                 :          0 :         }
      39                 :            : 
      40                 :          0 : void UDP_Rewriter::Done()
      41                 :            :         {
      42                 :          0 :         }
      43                 :            : 
      44                 :          0 : UDP_Rewriter::~UDP_Rewriter()
      45                 :            :         {
      46 [ #  # ][ #  # ]:          0 :         delete current_packet;
                 [ #  # ]
      47 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
      48                 :            : 
      49                 :          0 : void UDP_Rewriter::WriteData(int is_orig, int len, const u_char* data)
      50                 :            :         {
      51                 :          0 :         DoWriteData(is_orig, len, data);
      52                 :          0 :         }
      53                 :            : 
      54                 :          0 : void UDP_Rewriter::DoWriteData(int is_orig, int len, const u_char* data)
      55                 :            :         {
      56                 :            :         struct pcap_pkthdr* hdr;
      57                 :          0 :         int length = len;
      58                 :          0 :         ipaddr32_t src = 0, dst = 0;
      59                 :            : 
      60                 :          0 :         current_packet->AppendData(data,len);
      61                 :            :         // Mark data to be written.
      62                 :          0 :         current_packet->SetModified();
      63                 :          0 :         }
      64                 :            : 
      65                 :            : // Compose the packet so it can be written.
      66                 :            : // Compute UDP/IP checksums, lengths, addresses.
      67                 :            : int UDP_TracePacket::BuildPacket(struct pcap_pkthdr*& hdr,
      68                 :            :                                 const u_char*& arg_pkt, int& length,
      69                 :          0 :                                 ipaddr32_t anon_src, ipaddr32_t anon_dst)
      70                 :            :         {
      71                 :          0 :         struct ip* ip = (struct ip*) (pkt + ip_offset);
      72                 :          0 :         struct udphdr* up = (struct udphdr*) (pkt + udp_offset);
      73                 :          0 :         uint32 sum = 0;
      74                 :            : 
      75                 :            :         // Fix IP addresses before computing the UDP checksum
      76         [ #  # ]:          0 :         if ( anonymize_ip_addr )
      77                 :            :                 {
      78                 :          0 :                 ip->ip_src.s_addr = anon_src;
      79                 :          0 :                 ip->ip_dst.s_addr = anon_dst;
      80                 :            :                 }
      81                 :            : 
      82                 :            :         // Create the IP header.
      83                 :          0 :         ip->ip_off = 0;
      84                 :          0 :         ip->ip_sum = 0;
      85                 :          0 :         ip->ip_hl = (udp_offset - ip_offset) >> 2;
      86                 :          0 :         ip->ip_len = htons(buffer_offset - ip_offset);
      87                 :          0 :         ip->ip_off = 0;      // DF = 0, MF = 0, offset = 0
      88                 :          0 :         ip->ip_sum = 0;
      89                 :            :         ip->ip_sum = 0xffff - ones_complement_checksum((const void*) ip,
      90                 :          0 :                                                 (udp_offset-ip_offset), sum);
      91                 :            : 
      92                 :          0 :         pcap_hdr.caplen = pcap_hdr.len = buffer_offset;
      93                 :            : 
      94                 :          0 :         hdr = &pcap_hdr;
      95                 :          0 :         arg_pkt = pkt;
      96                 :          0 :         length = buffer_offset;
      97                 :            : 
      98                 :            :         // Create the UDP header.
      99                 :          0 :         up->uh_ulen = htons(buffer_offset - udp_offset);
     100                 :          0 :         up->uh_sum = 0;
     101                 :          0 :         up->uh_sum = 0xffff - udp_checksum(ip, up, buffer_offset - udp_offset);
     102                 :            : 
     103                 :            :         // Create the pcap header.
     104                 :            :         //
     105                 :            :         // The below works around a potential type incompatibility
     106                 :            :         // on systems where pcap's timeval is different from the
     107                 :            :         // system-wide one. --cpk
     108                 :            :         //
     109                 :          0 :         timeval tv_tmp = double_to_timeval(timestamp);
     110                 :          0 :         pcap_hdr.ts.tv_sec = tv_tmp.tv_sec;
     111                 :          0 :         pcap_hdr.ts.tv_usec = tv_tmp.tv_usec;
     112                 :          0 :         pcap_hdr.caplen = pcap_hdr.len = buffer_offset;
     113                 :            : 
     114                 :          0 :         hdr = &pcap_hdr;
     115                 :          0 :         arg_pkt = pkt;
     116                 :          0 :         length = buffer_offset;
     117                 :            : 
     118                 :          0 :         return 1;
     119                 :            :         }
     120                 :            : 
     121                 :            : void UDP_Rewriter::NextPacket(int is_orig, double t,
     122                 :            :                                 const struct pcap_pkthdr* pcap_hdr,
     123                 :            :                                 const u_char* pcap_pkt, int hdr_size,
     124                 :          0 :                                 const struct ip* ip, const struct udphdr* up)
     125                 :            :         {
     126                 :          0 :         unsigned int ip_hdr_len = ip->ip_hl * 4;
     127                 :            : 
     128                 :            :         // Cache the packet ....
     129                 :            :         UDP_TracePacket* p = new UDP_TracePacket(this, t, is_orig,
     130                 :            :                                 pcap_hdr, /*MTU */ 1024,
     131                 :          0 :                                 hdr_size + ip_hdr_len + sizeof(struct udphdr));
     132                 :            : 
     133         [ #  # ]:          0 :         if ( ! p->AppendLinkHeader(pcap_pkt, hdr_size) )
     134                 :          0 :                 internal_error(MSG_PREFIX "cannot append headers -- check MTU");
     135                 :            : 
     136         [ #  # ]:          0 :         if ( ! p->AppendIPHeader((const u_char*) ip, sizeof(*ip)) )
     137                 :          0 :                 internal_error(MSG_PREFIX "cannot append headers -- check MTU");
     138                 :            : 
     139         [ #  # ]:          0 :         if ( ! p->AppendUDPHeader((const u_char*) up, sizeof(*up)) )
     140                 :          0 :                 internal_error(MSG_PREFIX "cannot append headers -- check MTU");
     141                 :            : 
     142                 :            :         // We only ever use one packet in UDP.
     143                 :            :         // ### This is potentially a leak.
     144                 :          0 :         next_packet = current_packet = p;
     145                 :          0 :         }
     146                 :            : 
     147                 :          0 : void UDP_Rewriter::Push(int)
     148                 :            :         {
     149                 :          0 :         internal_error("UDP_Rewriter::Push not implemented");
     150                 :            :         }
     151                 :            : 
     152                 :          0 : void UDP_Rewriter::AbortPackets(int)
     153                 :            :         {
     154                 :          0 :         internal_error("UDP_Rewriter::AbortPackets not implemented");
     155                 :            :         }
     156                 :            : 
     157                 :          0 : unsigned int UDP_Rewriter::ReserveSlot()
     158                 :            :         {
     159                 :          0 :         internal_error("UDP_Rewriter::ReserveSlot not implemented");
     160                 :            :         return 0;
     161                 :            :         }
     162                 :            : 
     163                 :          0 : int UDP_Rewriter::SeekSlot(unsigned int)
     164                 :            :         {
     165                 :          0 :         internal_error("UDP_Rewriter::SeekSlot not implemented");
     166                 :            :         return 0;
     167                 :            :         }
     168                 :            : 
     169                 :          0 : int UDP_Rewriter::ReturnFromSlot()
     170                 :            :         {
     171                 :          0 :         internal_error("UDP_Rewriter::ReturnFromSlot not implemented");
     172                 :            :         return 0;
     173                 :            :         }
     174                 :          0 : int UDP_Rewriter::ReleaseSlot(unsigned int)
     175                 :            :         {
     176                 :          0 :         internal_error("UDP_Rewriter::ReleaseSlot not implemented");
     177                 :            :         return 0;
     178                 :            :         }
     179                 :            : 
     180                 :          0 : int UDP_Rewriter::LeaveAddrInTheClear(int is_orig)
     181                 :            :         {
     182                 :          0 :         internal_error("UDP_Rewriter::LeaveAddrInTheClear not implemented");
     183                 :            :         return 0;
     184                 :            :         }
     185                 :            : 
     186                 :          0 : void UDP_Rewriter::CommitPackets(int commit)
     187                 :            :         {
     188 [ #  # ][ #  # ]:          0 :         if ( current_packet && current_packet->IsModified() )
                 [ #  # ]
     189                 :            :                 {
     190                 :          0 :                 ipaddr32_t anon_src = 0, anon_dst = 0;
     191                 :            : 
     192         [ #  # ]:          0 :                 if ( current_packet->IsOrig() )
     193                 :            :                         {
     194                 :          0 :                         anon_src = anon_addr[0];
     195                 :          0 :                         anon_dst = anon_addr[1];
     196                 :            :                         }
     197                 :            :                 else
     198                 :            :                         {
     199                 :          0 :                         anon_src = anon_addr[1];
     200                 :          0 :                         anon_dst = anon_addr[0];
     201                 :            :                         }
     202                 :            : 
     203                 :            :                 struct pcap_pkthdr* hdr;
     204                 :            :                 const u_char* pkt;
     205                 :            :                 int len;
     206                 :          0 :                 current_packet->BuildPacket(hdr, pkt, len, anon_src, anon_dst);
     207                 :            : 
     208                 :          0 :                 dumper->DumpPacket(hdr, pkt, hdr->caplen);
     209                 :            :                 }
     210                 :            : 
     211         [ #  # ]:          0 :         delete current_packet;
     212                 :          0 :         next_packet = current_packet = 0;
     213                 :            : 
     214                 :          0 :         ++packets_rewritten;
     215                 :          0 :         }
     216                 :            : 
     217                 :            : UDP_TracePacket::UDP_TracePacket(UDP_Rewriter* arg_trace_rewriter,
     218                 :            :                                         double t, int arg_is_orig,
     219                 :            :                                         const struct pcap_pkthdr* arg_hdr,
     220                 :          0 :                                         int MTU, int initial_size)
     221                 :            :         {
     222                 :          0 :         trace_rewriter = arg_trace_rewriter;
     223                 :          0 :         pcap_hdr = *arg_hdr;
     224                 :            :         // packet_seq = arg_packet_seq;
     225                 :          0 :         timestamp = t;
     226                 :          0 :         is_orig = arg_is_orig;
     227                 :          0 :         mtu = MTU;
     228                 :          0 :         buffer_size = initial_size;
     229                 :          0 :         buffer_offset = 0;
     230                 :            : 
     231                 :          0 :         pkt = new u_char[buffer_size];
     232                 :            : 
     233                 :          0 :         ip_offset = udp_offset = data_offset = -1;
     234                 :            : 
     235                 :          0 :         reuse = 0;
     236                 :          0 :         on_hold = 0;
     237                 :          0 :         modified = 0;
     238                 :          0 :         seq_gap = 0;
     239                 :            : 
     240                 :          0 :         packet_val = 0;
     241                 :          0 :         packet_val = PacketVal();
     242                 :          0 :         }
     243                 :            : 
     244                 :          0 : UDP_TracePacket::~UDP_TracePacket()
     245                 :            :         {
     246                 :          0 :         packet_val->SetOrigin(0);
     247                 :          0 :         Unref(packet_val);
     248   [ #  #  #  # ]:          0 :         delete [] pkt;
                 [ #  # ]
     249 [ #  # ][ #  # ]:          0 :         }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     250                 :            : 
     251                 :          0 : RecordVal* UDP_TracePacket::PacketVal()
     252                 :            :         {
     253         [ #  # ]:          0 :         if ( packet_val )
     254                 :          0 :                 Ref(packet_val);
     255                 :            :         else
     256                 :            :                 {
     257                 :          0 :                 packet_val = new RecordVal(packet_type);
     258                 :          0 :                 packet_val->Assign(0, TraceRewriter()->GetAnalyzer()->BuildConnVal());
     259                 :          0 :                 packet_val->Assign(1, new Val(IsOrig(), TYPE_BOOL));
     260                 :          0 :                 packet_val->Assign(2, new Val(TimeStamp(), TYPE_TIME));
     261                 :          0 :                 packet_val->SetOrigin(this);
     262                 :            :                 }
     263                 :            : 
     264                 :          0 :         return packet_val;
     265                 :            :         }
     266                 :            : 
     267                 :          0 : int UDP_TracePacket::AppendLinkHeader(const u_char* chunk, int len)
     268                 :            :         {
     269 [ #  # ][ #  # ]:          0 :         if ( ip_offset >= 0 && ip_offset != buffer_offset )
     270                 :          0 :                 internal_error(MSG_PREFIX "link header must be appended before IP header");
     271                 :            : 
     272         [ #  # ]:          0 :         if ( ! Append(chunk, len) )
     273                 :          0 :                 return 0;
     274                 :            : 
     275                 :          0 :         ip_offset = buffer_offset;
     276                 :          0 :         return 1;
     277                 :            :         }
     278                 :            : 
     279                 :          0 : int UDP_TracePacket::AppendIPHeader(const u_char* chunk, int len)
     280                 :            :         {
     281 [ #  # ][ #  # ]:          0 :         if ( udp_offset >= 0 && udp_offset != buffer_offset )
     282                 :          0 :                 internal_error(MSG_PREFIX "IP header must be appended before udp header");
     283                 :            : 
     284         [ #  # ]:          0 :         if ( ! Append(chunk, len) )
     285                 :          0 :                 return 0;
     286                 :            : 
     287                 :          0 :         udp_offset = buffer_offset;
     288                 :          0 :         return 1;
     289                 :            :         }
     290                 :            : 
     291                 :          0 : int UDP_TracePacket::AppendUDPHeader(const u_char* chunk, int len)
     292                 :            :         {
     293 [ #  # ][ #  # ]:          0 :         if ( data_offset >= 0 && data_offset != buffer_offset )
     294                 :          0 :                 internal_error(MSG_PREFIX "tcp header must be appended before payload");
     295                 :            : 
     296         [ #  # ]:          0 :         if ( udp_offset == buffer_offset )
     297                 :            :                 { // first UDP header chunk
     298                 :          0 :                 int extra = (udp_offset - ip_offset) % 4;
     299         [ #  # ]:          0 :                 if ( extra )
     300                 :            :                         {
     301                 :          0 :                         DEBUG_MSG(MSG_PREFIX "padding IP header");
     302         [ #  # ]:          0 :                         if ( ! AppendIPHeader(0, 4 - extra) )
     303                 :          0 :                                 return 0;
     304                 :            :                         }
     305                 :            :                 }
     306                 :            : 
     307         [ #  # ]:          0 :         if ( ! Append(chunk, len) )
     308                 :          0 :                 return 0;
     309                 :            : 
     310                 :          0 :         data_offset = buffer_offset;
     311                 :          0 :         return 1;
     312                 :            :         }
     313                 :            : 
     314                 :          0 : int UDP_TracePacket::AppendData(const u_char* chunk, int len)
     315                 :            :         {
     316                 :            :         // All headers must be appended before any data.
     317 [ #  # ][ #  # ]:          0 :         ASSERT(ip_offset >= 0 && udp_offset >= 0 && data_offset >= 0);
         [ #  # ][ #  # ]
     318                 :            : 
     319         [ #  # ]:          0 :         if ( data_offset == buffer_offset )
     320                 :            :                 { // first data chunk
     321                 :          0 :                 int extra = (data_offset - udp_offset) % 4;
     322         [ #  # ]:          0 :                 if ( extra )
     323                 :            :                         {
     324         [ #  # ]:          0 :                         if ( ! AppendUDPHeader(0, 4 - extra) )
     325                 :          0 :                                 return 0;
     326                 :            :                         }
     327                 :            :                 }
     328                 :            : 
     329         [ #  # ]:          0 :         if ( ! Append(chunk, len) )
     330                 :          0 :                 return 0;
     331                 :            : 
     332                 :          0 :         return 1;
     333                 :            :         }
     334                 :            : 
     335                 :          0 : int UDP_TracePacket::Append(const u_char* chunk, int len)
     336                 :            :         {
     337         [ #  # ]:          0 :         if ( buffer_offset + len > buffer_size )
     338                 :            :                 {
     339         [ #  # ]:          0 :                 if ( buffer_offset + len > mtu )
     340                 :          0 :                         return 0;
     341                 :            : 
     342                 :          0 :                 u_char* tmp = new u_char[mtu];
     343         [ #  # ]:          0 :                 for ( int i = 0 ; i < buffer_size; ++i )
     344                 :          0 :                         tmp[i] = pkt[i];
     345                 :            : 
     346         [ #  # ]:          0 :                 delete [] pkt;
     347                 :          0 :                 pkt = tmp;
     348                 :          0 :                 buffer_size = mtu;
     349                 :            :                 }
     350                 :            : 
     351         [ #  # ]:          0 :         ASSERT(buffer_offset + len <= buffer_size);
     352                 :            : 
     353         [ #  # ]:          0 :         if ( chunk )
     354                 :          0 :                 memcpy(pkt + buffer_offset, chunk, len);
     355                 :            :         else
     356                 :            :                 // Fill with 0.
     357                 :          0 :                 memset(pkt + buffer_offset, 0, len);
     358                 :            : 
     359                 :          0 :         buffer_offset += len;
     360                 :            : 
     361                 :          0 :         return 1;
     362 [ +  - ][ +  - ]:          6 :         }

Generated by: LCOV version 1.8