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
29struct nfgenmsg;
30struct nfq_data;
31struct nfq_handle;
32struct nfq_q_handle;
33
34namespace shill {
35
36namespace shims {
37
38class 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.
68    int in_device() const { return in_device_; }
69    int out_device() const { return out_device_; }
70    bool is_udp() const { return is_udp_; }
71    uint32_t packet_id() const { return packet_id_; }
72    uint32_t source_ip() const { return source_ip_; }
73    uint32_t destination_ip() const { return destination_ip_; }
74    uint16_t source_port() const { return source_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 {
105    ListenerEntry()
106        : last_transmission(0),
107          port(0),
108          device_index(0),
109          address(0),
110          netmask(0),
111          destination(0) {}
112    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