1 /*
2 * Copyright (c) 2017, OARC, Inc.
3 * Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
4 * All rights reserved.
5 *
6 * This file is part of PacketQ.
7 *
8 * PacketQ is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * PacketQ is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #ifndef __packetq_packet_handler_h
23 #define __packetq_packet_handler_h
24
25 #include <assert.h>
26 #include <cctype>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <string>
31 #include <vector>
32
33 #include "sql.h"
34 #include "tcp.h"
35
36 #define IPPROTO_ICMP 1
37
38 namespace packetq {
39
40 class Table;
41 class Row;
42
get_int_h(unsigned char * data)43 inline int get_int_h(unsigned char* data)
44 {
45 return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
46 }
47
get_short_h(unsigned char * data)48 inline int get_short_h(unsigned char* data)
49 {
50 return data[0] | (data[1] << 8);
51 }
52
get_int(unsigned char * data)53 inline int get_int(unsigned char* data)
54 {
55 return data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24);
56 }
57
get_short(unsigned char * data)58 inline int get_short(unsigned char* data)
59 {
60 return data[1] | (data[0] << 8);
61 }
62
63 RefCountString* v4_addr2str(in6addr_t& addr);
64 RefCountString* v6_addr2str(in6addr_t& addr);
65
66 class Payload {
67 public:
68 char m_p[0x10000];
69 int m_size;
Payload()70 Payload()
71 {
72 m_size = sizeof(m_p);
73 }
alloc(int size)74 inline char* alloc(int size)
75 {
76 if (size > m_size)
77 return 0;
78 return m_p;
79 }
80 };
81
82 class IP_header {
83 public:
IP_header()84 IP_header()
85 : s(0)
86 , us(0)
87 , ethertype(0)
88 , src_port(0)
89 , dst_port(0)
90 , proto(0)
91 , ip_ttl(0)
92 , ip_version(0)
93 , id(0)
94 , length(0)
95 , fragments(0)
96 , ident(0)
97 , offset(0)
98 {
99 memset(&src_ip, 0, sizeof(src_ip));
100 memset(&dst_ip, 0, sizeof(dst_ip));
101 }
102
103 void reset();
104 int decode(unsigned char* data, int ether_type, int id);
105 unsigned int s;
106 unsigned int us;
107 unsigned short ethertype;
108 in6addr_t src_ip;
109 in6addr_t dst_ip;
110 unsigned short src_port;
111 unsigned short dst_port;
112 unsigned short proto;
113 unsigned short ip_ttl;
114 unsigned short ip_version;
115 unsigned int id;
116 unsigned int length;
117 unsigned int fragments;
118 unsigned int ident;
119 unsigned int offset;
120 };
121
122 class Packet_handler;
123
124 class IP_header_to_table {
125 public:
126 enum {
127 COLUMN_ID,
128 COLUMN_S,
129 COLUMN_US,
130 COLUMN_ETHER_TYPE,
131 COLUMN_PROTOCOL,
132 COLUMN_IP_TTL,
133 COLUMN_IP_VERSION,
134 COLUMN_SRC_PORT,
135 COLUMN_DST_PORT,
136 COLUMN_SRC_ADDR,
137 COLUMN_DST_ADDR,
138 COLUMN_FRAGMENTS
139 };
140
141 void add_packet_columns(Packet_handler& packet_handler);
142 void on_table_created(Table* table, const std::vector<int>& columns);
143 void assign(Row* row, IP_header* head, const std::vector<int>& columns);
144
145 private:
146 Int_accessor acc_id;
147 Int_accessor acc_s;
148 Int_accessor acc_us;
149 Int_accessor acc_ether_type;
150 Int_accessor acc_protocol;
151 Int_accessor acc_ip_ttl;
152 Int_accessor acc_ip_version;
153 Int_accessor acc_src_port;
154 Int_accessor acc_dst_port;
155 Int_accessor acc_fragments;
156 Text_accessor acc_src_addr;
157 Text_accessor acc_dst_addr;
158 };
159
160 class Packet {
161 public:
162 enum ParseResult {
163 ERROR,
164 OK,
165 NOT_SAMPLED
166 };
167
Packet(unsigned char * data,int len,int s,int us,int id,int link_layer_type)168 Packet(unsigned char* data, int len, int s, int us, int id, int link_layer_type)
169 {
170 m_s = s;
171 m_us = us;
172 m_data = data;
173 m_len = len;
174 m_id = id;
175 m_link_layer_type = link_layer_type;
176 }
177
178 ParseResult parse(Packet_handler* handler, const std::vector<int>& columns, Row& destination_row, bool sample);
179 bool parse_ethernet();
180 bool parse_ip(unsigned char* data, int len, int ether_type);
181 bool parse_transport(unsigned char* data, int len);
182
183 IP_header m_ip_header;
184 unsigned char* m_data;
185 int m_len;
186 int m_s;
187 int m_us;
188 int m_id;
189 int m_link_layer_type;
190 };
191
192 struct Packet_column {
193 const char* name;
194 const char* description;
195 int id;
196 Coltype::Type type;
197 };
198
199 class Packet_handler {
200 public:
Packet_handler()201 Packet_handler()
202 : table_name(0)
203 {
204 }
~Packet_handler()205 virtual ~Packet_handler()
206 {
207 }
208
209 Table* create_table(const std::vector<int>& columns);
210
211 // for actual packet handlers to fill in
212 virtual void on_table_created(Table* table, const std::vector<int>& columns) = 0;
213 virtual Packet::ParseResult parse(Packet& packet, const std::vector<int>& columns, Row& destination_row, bool sample) = 0;
214
215 const char* table_name;
216 std::vector<Packet_column> packet_columns;
217
218 void add_packet_column(const char* name, const char* description, Coltype::Type type, int id);
219 };
220
221 void init_packet_handlers();
222 void destroy_packet_handlers();
223 Packet_handler* get_packet_handler(std::string table_name);
224
225 } // namespace packetq
226
227 #endif // __packetq_packet_handler_h
228