1 //
2 // Copyright (C) 2013 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef SHILL_SHIMS_NETFILTER_QUEUE_PROCESSOR_H_
18 #define SHILL_SHIMS_NETFILTER_QUEUE_PROCESSOR_H_
19 
20 #include <inttypes.h>
21 #include <sys/time.h>
22 
23 #include <deque>
24 #include <memory>
25 #include <string>
26 
27 #include <base/macros.h>
28 
29 struct nfgenmsg;
30 struct nfq_data;
31 struct nfq_handle;
32 struct nfq_q_handle;
33 
34 namespace shill {
35 
36 namespace shims {
37 
38 class NetfilterQueueProcessor {
39  public:
40   NetfilterQueueProcessor(int input_queue, int output_queue);
41   virtual ~NetfilterQueueProcessor();
42 
43   // Run the main loop of the processor.
44   void Run();
45 
46   // Initialize state and install the processor so it accepts messages
47   // from the kernel.
48   bool Start();
49 
50   // Uninitialize state.
51   void Stop();
52 
53  private:
54   friend class NetfilterQueueProcessorTest;
55 
56   class Packet {
57    public:
58     Packet();
59     virtual ~Packet();
60 
61     // Inputs a netfilter data packet and reads meta-information (packet id)
62     // and attempts to decode the payload as a UDP packet.  Returns true if
63     // the meta-information is decoded, regardless of whether the payload
64     // was decoded.
65     bool ParseNetfilterData(struct nfq_data* netfilter_data);
66 
67     // Getters.
in_device()68     int in_device() const { return in_device_; }
out_device()69     int out_device() const { return out_device_; }
is_udp()70     bool is_udp() const { return is_udp_; }
packet_id()71     uint32_t packet_id() const { return packet_id_; }
source_ip()72     uint32_t source_ip() const { return source_ip_; }
destination_ip()73     uint32_t destination_ip() const { return destination_ip_; }
source_port()74     uint16_t source_port() const { return source_port_; }
destination_port()75     uint16_t destination_port() const { return destination_port_; }
76 
77    private:
78     friend class NetfilterQueueProcessorTest;
79 
80     bool ParsePayloadUDPData(const unsigned char* payload, size_t payload_len);
81 
82     // Setter only used in unit tests.
83     void SetValues(int in_device,
84                    int out_device,
85                    bool is_udp,
86                    uint32_t packet_id,
87                    uint32_t source_ip,
88                    uint32_t destination_ip,
89                    uint16_t source_port,
90                    uint16_t destination_port);
91 
92     uint32_t packet_id_;
93     int in_device_;
94     int out_device_;
95     bool is_udp_;
96     uint32_t source_ip_;
97     uint32_t destination_ip_;
98     uint16_t source_port_;
99     uint16_t destination_port_;
100 
101     DISALLOW_COPY_AND_ASSIGN(Packet);
102   };
103 
104   struct ListenerEntry {
ListenerEntryListenerEntry105     ListenerEntry()
106         : last_transmission(0),
107           port(0),
108           device_index(0),
109           address(0),
110           netmask(0),
111           destination(0) {}
ListenerEntryListenerEntry112     ListenerEntry(time_t last_transmission_in,
113                   uint16_t port_in,
114                   int device_index_in,
115                   uint32_t address_in,
116                   uint32_t netmask_in,
117                   uint32_t destination_in)
118         : last_transmission(last_transmission_in),
119           port(port_in),
120           device_index(device_index_in),
121           address(address_in),
122           netmask(netmask_in),
123           destination(destination_in) {}
124     time_t last_transmission;
125     uint16_t port;
126     int device_index;
127     uint32_t address;
128     uint32_t netmask;
129     uint32_t destination;
130   };
131 
132   typedef std::shared_ptr<ListenerEntry> ListenerEntryPtr;
133 
134   // Called by the netlink_queue code when a packet arrives for the
135   // input queue.
136   static int InputQueueCallback(struct nfq_q_handle* queue_handle,
137                                 struct nfgenmsg* generic_message,
138                                 struct nfq_data* netfilter_data,
139                                 void* private_data);
140 
141   // Called by the netlink_queue code when a packet arrives for the
142   // output queue.
143   static int OutputQueueCallback(struct nfq_q_handle* queue_handle,
144                                  struct nfgenmsg* generic_message,
145                                  struct nfq_data* netfilter_data,
146                                  void* private_data);
147 
148   // Return the netmask associated with |device_index|.
149   static uint32_t GetNetmaskForDevice(int device_index);
150 
151   // Expire listener that are no longer valid |now|.
152   void ExpireListeners(time_t now);
153 
154   // Find a listener entry with port |port|, device index |device_index|
155   // and local address |address|.
156   std::deque<ListenerEntryPtr>::iterator FindListener(
157       uint16_t port, int device_index, uint32_t address);
158 
159   // Find a listener entry with port |port| and device index |device_index|
160   // which transmitted to multicast destination |destination|.
161   std::deque<ListenerEntryPtr>::iterator FindDestination(
162       uint16_t port, int device_index, uint32_t destination);
163 
164   // Returns true if incoming packet |packet| should be allowed to pass.
165   bool IsIncomingPacketAllowed(const Packet& packet, time_t now);
166 
167   // Log the transmission of an outgoing packet.
168   void LogOutgoingPacket(const Packet& packet, time_t now);
169 
170   static std::string AddressAndPortToString(uint32_t ip, uint16_t port);
171 
172   // Size of the packet buffer passed to the netlink queue library.
173   static const int kBufferSize;
174   // The number of seconds after which we should forget about a listener.
175   static const int kExpirationIntervalSeconds;
176   // Number of bytes in a single unit of IP header length.
177   static const int kIPHeaderLengthUnitBytes;
178   // The maximum expected value for the "header length" element of the IP
179   // header, in units of kIPHeaderLengthUnitBytes bytes.
180   static const int kMaxIPHeaderLength;
181   // The maximum number of listeners that we keep track of.
182   static const size_t kMaxListenerEntries;
183   // Number of bytes of the network payload we are interested in seeing.
184   static const int kPayloadCopySize;
185 
186   // Input and output queue numbers.
187   int input_queue_;
188   int output_queue_;
189 
190   // Pointer to a netfilter queue library instance.  A bare pointer is
191   // necessary since this must be freed via nfq_close().
192   struct nfq_handle* nfq_handle_;
193 
194   // Input and output queue handles.  A bare pointer is necessary since
195   // this must be freed via nfq_destroy_queue().
196   struct nfq_q_handle* input_queue_handle_;
197   struct nfq_q_handle* output_queue_handle_;
198 
199   // A list of records of listening sockets.
200   std::deque<ListenerEntryPtr> listeners_;
201 
202   DISALLOW_COPY_AND_ASSIGN(NetfilterQueueProcessor);
203 };
204 
205 }  // namespace shims
206 
207 }  // namespace shill
208 
209 #endif  // SHILL_SHIMS_NETFILTER_QUEUE_PROCESSOR_H_
210 
211