LCOV - code coverage report
Current view: top level - src - TCP_Rewriter.h (source / functions) Hit Total Coverage
Test: app.info Lines: 0 41 0.0 %
Date: 2010-12-13 Functions: 0 34 0.0 %
Branches: 0 10 0.0 %

           Branch data     Line data    Source code
       1                 :            : // $Id: TCP_Rewriter.h 6916 2009-09-24 20:48:36Z vern $
       2                 :            : 
       3                 :            : #ifndef tcp_rewriter_h
       4                 :            : #define tcp_rewriter_h
       5                 :            : 
       6                 :            : #include <queue>
       7                 :            : #include <set>
       8                 :            : using namespace std;
       9                 :            : 
      10                 :            : #include <pcap.h>
      11                 :            : 
      12                 :            : #include "Val.h"
      13                 :            : #include "TCP.h"
      14                 :            : #include "Anon.h"
      15                 :            : #include "Analyzer.h"
      16                 :            : 
      17                 :            : #include "PacketDumper.h"
      18                 :            : #include "Rewriter.h"
      19                 :            : 
      20                 :            : class TCP_Rewriter;
      21                 :            : 
      22                 :            : class TCP_TracePacket : public BroObj, virtual public TracePacket {
      23                 :            : public:
      24                 :            :         TCP_TracePacket(TCP_Rewriter* trace_rewriter,
      25                 :            :                         int packet_seq, double t, int is_orig,
      26                 :            :                         const struct pcap_pkthdr* hdr,
      27                 :            :                         int MTU, int initial_size);
      28                 :            :         ~TCP_TracePacket();
      29                 :            : 
      30                 :            :         int AppendLinkHeader(const u_char* chunk, int len);
      31                 :            :         int AppendIPHeader(const u_char* chunk, int len);
      32                 :            :         int AppendTCPHeader(const u_char* chunk, int len);
      33                 :            :         int AppendData(const u_char* chunk, int len);
      34                 :            : 
      35                 :            :         // Finish() is called before dumping the packet. It sets length
      36                 :            :         // fields and computes checksums in TCP/IP headers.
      37                 :            :         int Finish(struct pcap_pkthdr*& hdr, const u_char*& pkt, int& length,
      38                 :            :                    ipaddr32_t anon_src, ipaddr32_t anon_dst);
      39                 :            : 
      40                 :            :         void Reuse();
      41                 :          0 :         int IsReuse() const     { return reuse; }
      42                 :            : 
      43                 :          0 :         double TimeStamp() const        { return timestamp; }
      44                 :          0 :         int IsOrig() const      { return is_orig; }
      45                 :            : 
      46                 :            :         const struct pcap_pkthdr* Header() const        { return &pcap_hdr; }
      47                 :            : 
      48                 :            :         const u_char* Buffer() const    { return pkt; }
      49                 :            :         int Length() const      { return buffer_offset; }
      50                 :            : 
      51                 :            :         // Note that Space() does not depend on buffer_size, but depends on MTU.
      52                 :          0 :         int Space() const               { return mtu - buffer_offset; }
      53                 :          0 :         int IsEmpty() const
      54 [ #  # ][ #  # ]:          0 :                 { return SeqLength() == 0 && ! GetTCP_Flag(TH_RST); }
      55                 :            : 
      56                 :            :         uint32 GetSeq() const;
      57                 :            :         void SetSeq(uint32 seq);
      58                 :            : 
      59                 :            :         uint32 GetAck() const;
      60                 :            :         void SetAck(uint32 ack);
      61                 :            : 
      62                 :            :         int GetTCP_Flag(int which) const;
      63                 :            :         void SetTCP_Flag(int which, int value);
      64                 :            : 
      65                 :            :         int SeqLength() const;
      66                 :            :         int PayloadLength() const;
      67                 :            : 
      68                 :          0 :         int FINScheduled() const        { return FIN_scheduled; }
      69                 :          0 :         void ScheduleFIN(int fin = 1)   { FIN_scheduled = fin; }
      70                 :            : 
      71                 :          0 :         int OnHold() const      { return on_hold; }
      72                 :          0 :         void SetOnHold(int x)   { on_hold = x; }
      73                 :            : 
      74                 :          0 :         int HasReservedSlot() const     { return has_reserved_slot; }
      75                 :          0 :         void AddReservedSlot()          { ++has_reserved_slot; }
      76                 :            : 
      77                 :          0 :         int PredictedAsEmptyPlaceHolder() const
      78                 :          0 :                 { return predicted_as_empty_place_holder; }
      79                 :            :         void PredictAsEmptyPlaceHolder()
      80                 :            :                 { predicted_as_empty_place_holder = 1; }
      81                 :            : 
      82                 :            :         // Whether the ACK on this packet confirms a content gap on
      83                 :            :         // the opposite direction.
      84                 :          0 :         int SeqGap() const      { return seq_gap; }
      85                 :          0 :         void SetSeqGap(int len) { seq_gap = len; }
      86                 :            : 
      87                 :          0 :         int PacketSeq() const           { return packet_seq; }
      88                 :          0 :         TCP_Rewriter* TraceRewriter() const     { return trace_rewriter; }
      89                 :            : 
      90                 :            :         RecordVal* PacketVal();
      91                 :          0 :         void Describe(ODesc* d) const   { packet_val->Describe(d); }
      92                 :            : 
      93                 :            : protected:
      94                 :            :         int Append(const u_char* chunk, int len);
      95                 :            : 
      96                 :            :         RecordVal* packet_val;
      97                 :            :         TCP_Rewriter* trace_rewriter;
      98                 :            :         double timestamp;
      99                 :            :         int packet_seq;
     100                 :            :         int is_orig;
     101                 :            :         struct pcap_pkthdr pcap_hdr;
     102                 :            :         int mtu;
     103                 :            :         u_char* pkt;    // of maximal length MTU
     104                 :            :         int ip_offset, tcp_offset, data_offset;
     105                 :            :         int buffer_size;
     106                 :            :         int buffer_offset;
     107                 :            :         int reuse;      // whether it is an artificially replicated packet
     108                 :            :         int FIN_scheduled;
     109                 :            :         int on_hold;    // do not dump it in Flush()
     110                 :            :         int seq_gap;
     111                 :            :         int has_reserved_slot;
     112                 :            :         int predicted_as_empty_place_holder;
     113                 :            : };
     114                 :            : 
     115                 :            : // How a unidirectional flow ends.
     116                 :            : #define END_BY_FIN      1
     117                 :            : #define END_BY_RST      2
     118                 :            : #define END_BY_PEER_RST 4
     119                 :            : 
     120                 :            : class TCP_RewriterEndpoint {
     121                 :            : public:
     122                 :            :         TCP_RewriterEndpoint(TCP_Rewriter* rewriter);
     123                 :            :         ~TCP_RewriterEndpoint();
     124                 :            : 
     125                 :            :         void Init();
     126                 :            : 
     127                 :            :         // A packet that contains a TCP segment.
     128                 :            :         void NextPacket(TCP_TracePacket* p);
     129                 :            :         void WriteData(int len, const u_char* data);
     130                 :            :         void SkipGap(int len);
     131                 :            : 
     132                 :            :         void Push();
     133                 :            :         void ReqAck();
     134                 :            :         void Flush();
     135                 :            :         void Reset(int self);
     136                 :            : 
     137                 :          0 :         uint32 NextSeq() const  { return next_seq; }
     138                 :          0 :         int HasPacket() const   { return next_packet != 0; }
     139                 :            :         inline TCP_Analyzer* Analyzer() const;
     140                 :            : 
     141                 :            : protected:
     142                 :            :         TCP_Rewriter* rewriter;         // TCP rewriter for the connection
     143                 :            :         TCP_RewriterEndpoint* peer;     // the peer TCP rewriter endpoint
     144                 :            :         TCP_Endpoint* endp;             // the corresponding TCP endpoint
     145                 :            : 
     146                 :            :         TCP_TracePacket* next_packet;
     147                 :            :         std::queue<BroString*> prolog;
     148                 :            : 
     149                 :            :         double last_packet_time;
     150                 :            :         uint32 start_seq;       // start seq -- sent in SYN
     151                 :            :         uint32 next_seq;        // seq of next packet
     152                 :            :         uint32 last_ack;        // last acknowledgement seq
     153                 :            : 
     154                 :            :         int please_flush;
     155                 :            :         int flush_scheduled;
     156                 :            :         int flushed;
     157                 :            :         int established;
     158                 :            :         int end_of_data;        // is it really useful?
     159                 :            :         int there_is_a_gap;
     160                 :            : 
     161                 :            :         // Move onto the next packet header.
     162                 :            :         void SetNextPacket(TCP_TracePacket* p);
     163                 :            : 
     164                 :            :         void PurgeProlog();
     165                 :            : 
     166                 :            :         // Pour data into the current packet (next_packet).
     167                 :            :         void DoWriteData(int len, const u_char* data);
     168                 :            : 
     169                 :            :         // Push the current packet (next_packet) to dumper.
     170                 :            :         void PushPacket();
     171                 :            : 
     172                 :            :         // Please flush this endpoint after draining events.
     173                 :            :         void ScheduleFlush();
     174                 :            : 
     175                 :            :         void GenerateFIN();
     176                 :            : 
     177                 :            :         // Whether the packet is a "place holder" packet, i.e. it's
     178                 :            :         // harmless to omit the packet (except missing the timestamp
     179                 :            :         // it contains).
     180                 :            :         int IsPlaceHolderPacket(TCP_TracePacket* p);
     181                 :            : 
     182                 :            :         void Weird(const char* name) const;
     183                 :            : };
     184                 :            : 
     185                 :          0 : class TCP_RewriteSlot {
     186                 :            : public:
     187                 :            :         TCP_RewriteSlot(TCP_TracePacket* p, unsigned int slot_number);
     188                 :            : 
     189                 :            :         void WriteData(int is_orig, int len, const u_char* data);
     190                 :            : 
     191                 :            :         void Dump();
     192                 :            : 
     193                 :          0 :         unsigned int Number() const     { return slot_number; }
     194                 :          0 :         TCP_TracePacket* Packet() const { return packet; }
     195                 :            : 
     196                 :          0 :         bool isEmpty() const    { return buf.empty(); }
     197                 :            : protected:
     198                 :            :         TCP_Rewriter* rewriter;
     199                 :            :         TCP_TracePacket* packet;
     200                 :            :         unsigned int slot_number;
     201                 :            :         std::queue<BroString*> buf;
     202                 :            : };
     203                 :            : 
     204                 :            : class TCP_Rewriter : public Rewriter {
     205                 :            : public:
     206                 :            :         TCP_Rewriter(TCP_Analyzer* analyzer, PacketDumper* dumper, int MTU,
     207                 :            :                         int wait_for_commitment = 0);
     208                 :            :         virtual ~TCP_Rewriter();
     209                 :            :         virtual void Done();
     210                 :            :         void Funeral();
     211                 :            : 
     212                 :            :         // Phase 1 methods: called in packet processing.
     213                 :            : 
     214                 :            :         // A TCP/IP packet.
     215                 :            :         void NextPacket(int is_orig, double t,
     216                 :            :                         const struct pcap_pkthdr* pcap_hdr,
     217                 :            :                         const u_char* pcap_pkt, // link level header
     218                 :            :                         int hdr_size,           // link level header size
     219                 :            :                         const struct ip* ip,
     220                 :            :                         const struct tcphdr* tp);
     221                 :            :         void ContentGap(int is_orig, int len);
     222                 :            :         void ScheduleFIN(int is_orig);
     223                 :            : 
     224                 :            : 
     225                 :            :         // Phase 2 methods: called in event processing.
     226                 :            : 
     227                 :            :         void WriteData(int is_orig, int len, const u_char* data);
     228                 :          0 :         void WriteData(int is_orig, const char* data)
     229                 :          0 :                 { WriteData(is_orig, strlen(data), data); }
     230                 :          0 :         void WriteData(int is_orig, int len, const char* data)
     231                 :          0 :                 { WriteData(is_orig, len, (const u_char*) data); }
     232                 :          0 :         void WriteData(int is_orig, const BroString* str)
     233                 :          0 :                 { WriteData(is_orig, str->Len(), str->Bytes()); }
     234                 :            :         void WriteData(int is_orig, StringVal* str)
     235                 :            :                 { WriteData(is_orig, str->AsString()); }
     236                 :            :         void Push(int is_orig);
     237                 :            : 
     238                 :            :         // When wait_for_commitment = 1, packets are not dumped until
     239                 :            :         //   CommitPackets().
     240                 :            :         // When apply_to_future = 1, the same decision holds for future
     241                 :            :         //   packets as well.
     242                 :            :         //
     243                 :            :         // Regarding why AbortPackets() takes an apply_to_future flag:
     244                 :            :         //
     245                 :            :         //      The model is that there can be multiple commit/abort stages
     246                 :            :         //      during the course of a connection.  At the end of each
     247                 :            :         //      stage, a commit or abort decision is made for packets
     248                 :            :         //      generated during the stage.  A possible scenario is that
     249                 :            :         //      user may want to delete a middle part of a conversation
     250                 :            :         //      while keeping the parts before and after intact, and cannot
     251                 :            :         //      make the decision until the end of the middle part.
     252                 :            : 
     253                 :            :         void AbortPackets(int apply_to_future);
     254                 :            :         void CommitPackets(int apply_to_future);
     255                 :            : 
     256                 :            :         unsigned int ReserveSlot();
     257                 :            :         int SeekSlot(unsigned int slot);
     258                 :            :         int ReturnFromSlot();
     259                 :            :         int ReleaseSlot(unsigned int slot);
     260                 :            : 
     261                 :            :         // Do not anonymize client/server IP address
     262                 :            :         int LeaveAddrInTheClear(int is_orig);
     263                 :            : 
     264                 :            : 
     265                 :            :         // Phase 3 methods: called in flushing after events.
     266                 :            :         // (None, because flushing is done through accessing endpoints directly.)
     267                 :            : 
     268                 :            :         // Other methods.
     269                 :            : 
     270                 :            :         void DumpPacket(TCP_RewriterEndpoint* endp, TCP_TracePacket* p);
     271                 :            : 
     272                 :            :         void Weird(const char* name) const      { analyzer->Weird(name); }
     273                 :          0 :         TCP_Analyzer* Analyzer() const  { return analyzer; }
     274                 :            : 
     275                 :            :         TCP_Endpoint* GetEndpoint(TCP_RewriterEndpoint* endp);
     276                 :            :         TCP_RewriterEndpoint* GetPeer(TCP_RewriterEndpoint* endp);
     277                 :            : 
     278         [ #  # ]:          0 :         TracePacket* CurrentPacket() const      { return current_packet; }
     279         [ #  # ]:          0 :         TracePacket* RewritePacket() const      { return next_packet; }
     280                 :            : 
     281                 :            :         // Needs to be static because it's passed as a pointer-to-function
     282                 :            :         // rather than pointer-to-member-function.
     283                 :            :         static int RewriteTCPOption(unsigned int opt, unsigned int optlen,
     284                 :            :                                 const u_char* option, TCP_Analyzer* analyzer,
     285                 :            :                                 bool is_orig, void* cookie);
     286                 :            : 
     287                 :            : protected:
     288                 :            :         // Under normal circumstances, we always rewrite into the
     289                 :            :         // "current packet" of the connection. However, sometimes we'd
     290                 :            :         // want to look a few packets ahead before deciding what to
     291                 :            :         // rewrite, in which case we may use {hold,release}_packet to
     292                 :            :         // specify the packet we are writing to.
     293                 :            : 
     294                 :            :         // rewrite_packet (next_packet) always equals to
     295                 :            :         // current_packet under *normal mode*. hold_packet(p) dumps
     296                 :            :         // all packets *before* p, fixes rewrite_packet at p and turns
     297                 :            :         // the connection into *look-ahead* mode. Under look-ahead
     298                 :            :         // mode, release_packet(c) dumps all packets of on hold
     299                 :            :         // connection and makes the connection returns to normal mode
     300                 :            :         // so that rewrite_packet changes along with current_packet.
     301                 :            : 
     302                 :            :         // When a packet is held, it is illegal to write to packets on
     303                 :            :         // the other half of the connection.
     304                 :            : 
     305                 :            :         // Release next_packet
     306                 :            :         void ReleaseNextPacket();
     307                 :            : 
     308                 :            :         // Hold packet p and release all packets before p.
     309                 :            :         void HoldPacket(TCP_TracePacket* p);
     310                 :            : 
     311                 :            :         // Release all packets on hold and dump all the packets except
     312                 :            :         // the last one, which will be flushed at the end of the event.
     313                 :            :         void ReleasePacketsOnHold();
     314                 :            : 
     315                 :            :         void CleanUpEmptyPlaceHolders();
     316                 :            :         void DoWriteData(int is_orig, int len, const u_char* data);
     317                 :            : 
     318                 :          0 :         TCP_RewriterEndpoint* Endp(int is_orig) const
     319         [ #  # ]:          0 :                 { return is_orig ? orig : resp; }
     320                 :            : 
     321                 :            :         TCP_Analyzer* analyzer;
     322                 :            :         PacketDumper* dumper;
     323                 :            :         TCP_RewriterEndpoint* orig;
     324                 :            :         TCP_RewriterEndpoint* resp;
     325                 :            :         int MTU;
     326                 :            :         int wait_for_commitment;
     327                 :            :         int discard_packets;
     328                 :            :         std::queue<char*> uncommited_packet_queue;
     329                 :            :         int next_packet_seq;
     330                 :            :         int packets_rewritten;
     331                 :            :         ipaddr32_t anon_addr[2];
     332                 :            :         int pending_content_gap;
     333                 :            : 
     334                 :            :         TCP_TracePacket* current_packet;
     335                 :            :         TCP_TracePacket* next_packet;
     336                 :            :         std::deque<TCP_TracePacket*> packets_on_hold;
     337                 :            :         int holding_packets;
     338                 :            : 
     339                 :            :         TCP_RewriteSlot* current_slot;
     340                 :            :         TCP_RewriteSlot* first_slot;
     341                 :            :         TCP_RewriteSlot* last_slot;
     342                 :            :         std::deque<TCP_RewriteSlot*> slot_queue;
     343                 :            :         typedef map<unsigned int, TCP_RewriteSlot*> slot_map_t;
     344                 :            :         slot_map_t reserved_slots;
     345                 :            :         int highest_slot_number;
     346                 :            : 
     347                 :            :         TCP_RewriteSlot* add_slot();
     348                 :            :         TCP_RewriteSlot* find_slot(unsigned int slot);
     349                 :            : 
     350                 :            :         friend class TCP_RewriteSlot;
     351                 :            :         int answered[2];
     352                 :            : };
     353                 :            : 
     354                 :          0 : inline TCP_Analyzer* TCP_RewriterEndpoint::Analyzer() const
     355                 :            :         {
     356                 :          0 :         return rewriter->Analyzer();
     357                 :            :         }
     358                 :            : 
     359                 :            : // "Please flush the rewriter endpoint after event processing."
     360                 :            : extern void schedule_flush(TCP_RewriterEndpoint* endp);
     361                 :            : 
     362                 :            : // "Please call rewriter->Funeral() after event processing."
     363                 :            : extern void schedule_funeral(TCP_Rewriter* rewriter);
     364                 :            : 
     365                 :            : extern void flush_rewriter_packet();
     366                 :            : 
     367                 :            : class TCP_SourcePacket {
     368                 :            : public:
     369                 :            :         TCP_SourcePacket(const struct pcap_pkthdr* pcap_hdr, const u_char* pcap_pkt);
     370                 :            :         ~TCP_SourcePacket();
     371                 :            : 
     372                 :          0 :         int Len() const { return hdr.caplen; }
     373                 :          0 :         const u_char* Pkt() const       { return pkt; }
     374                 :          0 :         const struct pcap_pkthdr* Hdr() const   { return &hdr; }
     375                 :            : 
     376                 :            : protected:
     377                 :            :         struct pcap_pkthdr hdr;
     378                 :            :         u_char* pkt;
     379                 :            : };
     380                 :            : 
     381                 :            : // Write selected original packets to the trace
     382                 :            : class TCP_SourcePacketWriter {
     383                 :            : public:
     384                 :            :         TCP_SourcePacketWriter(TCP_Analyzer* /* analyzer */,
     385                 :            :                                 PacketDumper* arg_dumper);
     386                 :            :         ~TCP_SourcePacketWriter();
     387                 :            : 
     388                 :            :         void NextPacket(const struct pcap_pkthdr* pcap_hdr,
     389                 :            :                                 const u_char* pcap_pkt);
     390                 :            :         void Dump();
     391                 :            :         void Abort();
     392                 :            : 
     393                 :            : protected:
     394                 :            :         PacketDumper* dumper;
     395                 :            :         std::queue<TCP_SourcePacket*> source_packets;
     396                 :            :         void Purge(bool dump);
     397                 :            : };
     398                 :            : 
     399                 :            : extern TCP_SourcePacketWriter* get_src_pkt_writer(TCP_Analyzer* analyzer);
     400                 :            : 
     401                 :            : #endif

Generated by: LCOV version 1.8