Skip to content

Commit ae211e6

Browse files
committed
LINUX_SLL, netmask(), ether types
- Add support for Pcap's LINUX_SLL link layer - `packet_handler`: Clean up header parsing, size checks etc - Fix up `netmask()` code and documentation - Remove own defines of ether/proto types and don't overlap `struct in6_addr`
1 parent d847c97 commit ae211e6

File tree

13 files changed

+244
-103
lines changed

13 files changed

+244
-103
lines changed

FUNCTIONS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ Converts double precision number to integer.
4242
Evaluates `condition` and executes `false_op` if the result is 0 (false)
4343
otherwise `true_op` is executed.
4444

45-
### NETMASK (address[, v4_mask_length[, v6_mask_length]])
45+
### NETMASK(address [, v4_mask_length [, v6_mask_length]])
4646

47-
Masks the specified address using the v4 and v6 mask lengths specified in number of bits. Defaults to 24 for IPv4 and 48 for IPv6 (/24 and /48 respectively)
47+
Masks the specified address using the v4 and v6 mask lengths specified
48+
in number of bits.
49+
50+
Defaults to 24 for IPv4 and 48 for IPv6 (/24 and /48 respectively)
4851

4952
## String operations
5053

src/dns.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
#include "packet_handler.h"
3232
#include "tcp.h"
3333

34-
#define IPPROTO_ICMP 1
35-
3634
namespace packetq {
3735

3836
extern char visible_char_map[256];

src/packet_handler.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ Packet::ParseResult Packet::parse(Packet_handler* handler, const std::vector<int
277277
bool base_layers_parsed;
278278
if (m_link_layer_type == 1)
279279
base_layers_parsed = parse_ethernet();
280+
else if (m_link_layer_type == 113)
281+
base_layers_parsed = parse_sll();
280282
else
281283
base_layers_parsed = parse_ip(m_data, m_len, 0);
282284

@@ -291,12 +293,13 @@ bool Packet::parse_ethernet()
291293
{
292294
unsigned char* data = m_data;
293295
int len = m_len;
294-
if (len < 14 + 5 * 4)
295-
return false; // check for etherframe size + ipv4 header
296+
if (len < 14)
297+
return false; // check for etherframe size
296298

297299
int ethertype = data[13] | (data[12] << 8);
298300
if (ethertype == 0x8100) {
299-
// VLAN-tagged
301+
if (len < 18)
302+
return false; // check for etherframe size + VLAN tag
300303
ethertype = data[17] | (data[16] << 8);
301304
data += 18;
302305
len -= 18;
@@ -308,6 +311,28 @@ bool Packet::parse_ethernet()
308311
return parse_ip(data, len, ethertype);
309312
}
310313

314+
bool Packet::parse_sll()
315+
{
316+
unsigned char* data = m_data;
317+
int len = m_len;
318+
if (len < 16)
319+
return false; // check for LINUX_SLL size
320+
321+
int ethertype = data[15] | (data[14] << 8);
322+
if (ethertype == 0x8100) {
323+
if (len < 20)
324+
return false; // check for etherframe size + VLAN tag
325+
ethertype = data[19] | (data[18] << 8);
326+
data += 20;
327+
len -= 20;
328+
} else {
329+
data += 16;
330+
len -= 16;
331+
}
332+
333+
return parse_ip(data, len, ethertype);
334+
}
335+
311336
bool Packet::parse_ip(unsigned char* data, int len, int ethertype)
312337
{
313338
if (len < 5 * 4)

src/packet_handler.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@
3333
#include "sql.h"
3434
#include "tcp.h"
3535

36-
#ifndef IPPROTO_ICMP
37-
#define IPPROTO_ICMP 1
38-
#endif
39-
4036
namespace packetq {
4137

4238
class Table;
@@ -179,6 +175,7 @@ class Packet {
179175

180176
ParseResult parse(Packet_handler* handler, const std::vector<int>& columns, Row& destination_row, bool sample);
181177
bool parse_ethernet();
178+
bool parse_sll();
182179
bool parse_ip(unsigned char* data, int len, int ether_type);
183180
bool parse_transport(unsigned char* data, int len);
184181

src/pcap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ bool Pcap_file::get_header()
6161
m_snapshot_length = get_int32();
6262
// check for ethernet packets
6363
m_link_layer_type = get_int32();
64-
if (m_link_layer_type != 1 && m_link_layer_type != 101) {
64+
if (m_link_layer_type != 1 && m_link_layer_type != 101 && m_link_layer_type != 113) {
6565
fprintf(stderr, "PCAP file unsupported linklayer (%d)\n", m_link_layer_type);
6666
return false;
6767
}

src/sql.cpp

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
*/
2121

2222
#include "sql.h"
23-
#include <arpa/inet.h>
2423
#include "output.h"
2524
#include "packet_handler.h"
2625
#include "packetq.h"
@@ -39,79 +38,6 @@ bool verbose = false;
3938

4039
int g_allocs = 0;
4140

42-
class Netmask_func : public OP {
43-
public:
44-
Netmask_func (const OP& op) : OP(op) {}
45-
void evaluate (Row **rows, Variant& v) {
46-
Variant orig_ip;
47-
struct in_addr a4;
48-
struct in6_addr a6;
49-
int ret = 0, isv4 = 1;
50-
51-
m_param[0]->evaluate (rows, orig_ip);
52-
if (!valid_masks) set_masks (rows);
53-
54-
RefCountStringHandle src(orig_ip.get_text());
55-
RefCountStringHandle dest(RefCountString::allocate(INET6_ADDRSTRLEN));
56-
57-
ret = inet_pton (AF_INET, (*src)->data, (void *)&a4);
58-
if (ret == 0) {
59-
isv4 = 0;
60-
ret = inet_pton (AF_INET6, (*src)->data, (void *)&a6);
61-
}
62-
if (ret != 1) {
63-
// Operation on non-IP address text
64-
RefCountStringHandle empty(RefCountString::construct(""));
65-
v = *empty;
66-
return;
67-
}
68-
if (isv4) {
69-
uint32_t *_x = (uint32_t *)&a4;
70-
*_x = *_x & v4_mask;
71-
(void) inet_ntop (AF_INET, (void *)&a4, (*dest)->data, INET6_ADDRSTRLEN);
72-
} else {
73-
uint32_t *_x = (uint32_t *)&a6;
74-
for (int i=0; i < 4; i++)
75-
_x[i] = _x[i] & v6_mask[i];
76-
(void) inet_ntop (AF_INET6, (void *)&a6, (*dest)->data, INET6_ADDRSTRLEN);
77-
}
78-
v = *dest;
79-
return;
80-
}
81-
private :
82-
void set_masks (Row **rows) {
83-
int v4size = 24;
84-
int v6size = 48;
85-
if (m_param[1] != NULL) {
86-
Variant v4cidr;
87-
m_param[1]->evaluate(rows, v4cidr);
88-
v4size = v4cidr.get_int();
89-
if (m_param[2] != NULL) {
90-
Variant v6cidr;
91-
m_param[2]->evaluate(rows, v6cidr);
92-
v6size = v6cidr.get_int();
93-
}
94-
}
95-
if (v4size > 0)
96-
v4_mask = htonl ((int32_t) 0x80000000 >> (v4size - 1));
97-
if (v6size > 0) {
98-
for (int i = 0; i < 4; i++) {
99-
if (v6size >= 32)
100-
v6_mask[i] = 0xffffffff;
101-
else
102-
v6_mask[i] = htonl ((int32_t)0x80000000 >> (v6size - 1));
103-
v6size -= 32;
104-
if (v6size <= 0) break;
105-
}
106-
}
107-
valid_masks = true;
108-
return;
109-
}
110-
uint32_t v4_mask = 0;
111-
uint32_t v6_mask[4] = {0,0,0,0};
112-
bool valid_masks = false;
113-
};
114-
11541
Column* Table::add_column(const char* name, const char* type, int id, bool hidden)
11642
{
11743
if (!type)

src/sql.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838
#include <string>
3939
#include <sys/types.h>
4040
#include <vector>
41+
#include <arpa/inet.h>
42+
#include <netinet/in.h>
43+
#ifndef s6_addr32 // For *BSD
44+
#define s6_addr32 __u6_addr.__u6_addr32
45+
#endif
46+
#include <sys/socket.h>
4147

4248
#include "refcountstring.h"
4349
#include "variant.h"
@@ -796,6 +802,89 @@ class Static_text : public OP {
796802
};
797803

798804
///////////////// Functions
805+
806+
class Netmask_func : public OP {
807+
public:
808+
Netmask_func(const OP& op)
809+
: OP(op)
810+
{
811+
}
812+
void evaluate(Row** rows, Variant& v)
813+
{
814+
Variant orig_ip;
815+
m_param[0]->evaluate(rows, orig_ip);
816+
817+
if (!valid_masks)
818+
set_masks(rows);
819+
820+
RefCountStringHandle src(orig_ip.get_text());
821+
RefCountStringHandle dest(RefCountString::allocate(INET6_ADDRSTRLEN + 1));
822+
823+
if (strchr((*src)->data, ':')) {
824+
struct in6_addr a6;
825+
if (inet_pton(AF_INET6, (*src)->data, &a6) == 1) {
826+
a6.s6_addr32[0] &= v6_mask[0];
827+
a6.s6_addr32[1] &= v6_mask[1];
828+
a6.s6_addr32[2] &= v6_mask[2];
829+
a6.s6_addr32[3] &= v6_mask[3];
830+
if (inet_ntop(AF_INET6, &a6, (*dest)->data, INET6_ADDRSTRLEN)) {
831+
v = *dest;
832+
return;
833+
}
834+
}
835+
} else {
836+
struct in_addr a4;
837+
if (inet_pton(AF_INET, (*src)->data, &a4) == 1) {
838+
a4.s_addr &= v4_mask;
839+
if (inet_ntop(AF_INET, &a4, (*dest)->data, INET6_ADDRSTRLEN)) {
840+
v = *dest;
841+
return;
842+
}
843+
}
844+
}
845+
846+
// Operation on non-IP address text
847+
RefCountStringHandle empty(RefCountString::construct(""));
848+
v = *empty;
849+
}
850+
851+
private:
852+
void set_masks(Row** rows)
853+
{
854+
if (m_param[1]) {
855+
Variant v4cidr;
856+
m_param[1]->evaluate(rows, v4cidr);
857+
int v4size = v4cidr.get_int();
858+
if (v4size > -1 && v4size < 33) {
859+
v4_mask = htonl(0xffffffff << (32 - v4size));
860+
}
861+
}
862+
if (m_param[2]) {
863+
Variant v6cidr;
864+
m_param[2]->evaluate(rows, v6cidr);
865+
int v6size = v6cidr.get_int();
866+
if (v6size > -1 && v6size < 129) {
867+
for (int i = 0; i < 4; i++) {
868+
if (v6size >= 32) {
869+
v6_mask[i] = 0xffffffff;
870+
v6size -= 32;
871+
} else if (v6size) {
872+
v6_mask[i] = htonl(0xffffffff << (32 - v6size));
873+
v6size = 0;
874+
} else {
875+
v6_mask[i] = 0;
876+
}
877+
}
878+
}
879+
}
880+
valid_masks = true;
881+
}
882+
883+
uint32_t v4_mask = htonl(0xffffff00);
884+
uint32_t v6_mask[4] = { 0xffffffff, htonl(0xffff0000), 0, 0 };
885+
bool valid_masks = false;
886+
};
887+
799888
class Truncate_func : public OP {
800889
public:
801890
Truncate_func(const OP& op)

src/tcp.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,19 @@
2323
#define __packetq_tcp_h
2424

2525
#include <stdio.h>
26-
27-
// Hack for Linux which does not include this in ethernet.h/ethertypes.h
28-
#ifndef ETHERTYPE_IPV6
29-
#define ETHERTYPE_IPV6 0x86dd
30-
#endif
31-
#ifndef IPPROTO_TCP
32-
#define IPPROTO_TCP 6
33-
#endif
34-
#ifndef IPPROTO_UDP
35-
#define IPPROTO_UDP 17
36-
#endif
26+
#include <stdint.h>
3727

3828
namespace packetq {
3929

40-
struct in6_addr {
30+
struct _in6_addr {
4131
union {
42-
unsigned char __u6_addr8[16];
43-
unsigned short __u6_addr16[8];
44-
unsigned int __u6_addr32[4];
32+
uint8_t __u6_addr8[16];
33+
uint16_t __u6_addr16[8];
34+
uint32_t __u6_addr32[4];
4535
} __in6_u; /* 128-bit IP6 address */
4636
};
4737

48-
typedef struct in6_addr in6addr_t;
38+
typedef struct _in6_addr in6addr_t;
4939

5040
class Payload;
5141

src/test/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test7.sh \
2828

2929
EXTRA_DIST = $(TESTS) \
3030
test1.gold test2.gold test3.gold test4.gold test5.gold test6.gold \
31-
test7.gold sql.txt test8.gold
31+
test7.gold sql.txt test8.gold \
32+
dns.pcap dns6.pcap

src/test/dns.pcap

19.8 KB
Binary file not shown.

src/test/dns6.pcap

274 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)