Skip to content
This repository was archived by the owner on Feb 4, 2026. It is now read-only.

Commit f28ef44

Browse files
authored
Merge pull request #39 from jelu/p12
Pull commits from PR #12
2 parents 1442973 + dd6ab57 commit f28ef44

File tree

6 files changed

+487
-20
lines changed

6 files changed

+487
-20
lines changed

src/packet_handler.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,15 @@ bool Packet::parse_ethernet()
284284
return false; // check for etherframe size + ipv4 header
285285

286286
int ethertype = data[13] | (data[12] << 8);
287-
data += 14;
288-
len -= 14;
287+
if (ethertype == 0x8100) {
288+
// VLAN-tagged
289+
ethertype = data[17] | (data[16] << 8);
290+
data += 18;
291+
len -= 18;
292+
} else {
293+
data += 14;
294+
len -= 14;
295+
}
289296

290297
return parse_ip(data, len, ethertype);
291298
}
@@ -312,6 +319,9 @@ bool Packet::parse_transport(unsigned char* data, int len)
312319
{
313320
// tcp/udp
314321
if (m_ip_header.proto == IPPROTO_TCP) {
322+
if (len < 14)
323+
return false;
324+
315325
m_ip_header.src_port = get_short(data);
316326
m_ip_header.dst_port = get_short(&data[2]);
317327

@@ -328,15 +338,28 @@ bool Packet::parse_transport(unsigned char* data, int len)
328338
// get the assembled TCP packet and remove the individual segments.
329339
data += dataoffs;
330340
len -= dataoffs;
341+
if (len < 0) {
342+
fprintf(stderr, "warning: Found TCP packet with bad length\n");
343+
return false;
344+
}
345+
331346
unsigned int rest = len;
332347
data = assemble_tcp(g_payload, &m_ip_header.src_ip, &m_ip_header.dst_ip, m_ip_header.src_port, m_ip_header.dst_port, &rest, seq, data, rest, syn, fin, rst, ack);
333348
len = rest;
334349
} else if (m_ip_header.proto == IPPROTO_UDP) {
350+
if (len < 4)
351+
return false;
352+
335353
m_ip_header.src_port = get_short(data);
336354
m_ip_header.dst_port = get_short(&data[2]);
337355

338356
data += 8;
339357
len -= 8;
358+
359+
if (len < 0) {
360+
fprintf(stderr, "warning: Found UDP packet with bad length\n");
361+
return false;
362+
}
340363
}
341364

342365
if (data) {

src/regression-test.sh

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,64 @@ set -e
2929
# packetq binary to packetq-before before you make a change to see the
3030
# effect on the output.
3131

32-
SQL="select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, lower_src, integer, float"
33-
34-
echo "Running packetq, output in regression-test-results"
35-
./packetq -s "$SQL" $1 > regression-test-results
36-
37-
if [ -f ./packetq-before ]
38-
then
39-
echo "Running packetq-before, output in regression-test-results-before"
40-
./packetq-before -s "$SQL" $1 > regression-test-results-before
41-
diff -u regression-test-results-before regression-test-results
42-
if [ $? = 0 ]
43-
then
44-
echo "No changes in output"
45-
fi
46-
fi
32+
#set -e
33+
DIR=/tmp/test/packetq
34+
mkdir -p $DIR
35+
typeset -i test
36+
test=0
37+
cd $(dirname $0)
38+
for SQL in \
39+
"select qname as CertainQnames, qtype as Qtype, count(1) as count from dns where (qname='localhost' or qname like '%.root-servers.net') and qr==0 group by CertainQnames,Qtype order by count desc ;" \
40+
'select qtype as Qtype, qname as Qname, count(1) as count from dns where qclass==3 and qr==0 group by Qtype,Qname order by count desc ;' \
41+
'select rcode as Rcode, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==1 group by Rcode,ClientAddr order by count desc limit 50;' \
42+
"select 'ALL' as All, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count,ClientSubnet desc limit 200;;" \
43+
"select 'ALL' as All, subnet(src_addr,24,96) as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count desc,ClientSubnet limit 200;;" \
44+
"select if(rsplit(qname,1)='de','ok','non-auth-tld') as Class, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by Class,ClientSubnet order by count,ClientSubnet,Class desc limit 200;;" \
45+
"select if(qr==1,'sent','recv') as Direction, if(protocol==6,'tcp',if(protocol==17,'udp',if(protocol==1,'icmp',if(protocol==58,'ipv6-icmp',protocol)))) as IPProto, count(1) as count from dns group by Direction,IPProto order by count,Direction desc ;" \
46+
"select if(ether_type==34525,'IPv6','IPv4') as IPVersion, qtype as Qtype, count(1) as count from dns where qr==0 group by IPVersion,Qtype order by count desc ;" \
47+
"select 'ALL' as All, do, edns0, edns_version, extended_rcode, z, if(do==1,'set','clr') as D0, count(1) as count from dns where qr==0 group by All,do,D0,edns0,edns_version,extended_rcode,z order by count desc ;" \
48+
"select 'ALL' as All, if(edns0,edns_version,'none') as EDNSVersion, count(1) as count from dns where qr==0 group by All,EDNSVersion order by count desc ;" \
49+
"select 'ALL' as All, if(qname like 'xn--%','idn','normal') as IDNQname, count(1) as count from dns where qr==0 group by All,IDNQname order by count desc ;" \
50+
"select 'ALL' as All, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qname like 'xn--%') group by All,TLD order by count,TLD desc ;" \
51+
"select 'ALL' as All, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==0 and (qtype=28 or qtype=38) and (qname like '%.root-servers.net') group by All,ClientAddr order by count desc limit 50;;" \
52+
"select 'ALL' as All, opcode as Opcode, count(1) as count from dns where qr==0 group by All,Opcode order by count desc ;" \
53+
"select 'ALL' as All, qtype as Qtype, count(1) as count from dns where qr==0 group by All,Qtype order by count desc ;" \
54+
'select qtype as Qtype, len(qname) as QnameLen, count(1) as count from dns where qr==0 group by Qtype,QnameLen order by count,QnameLen,Qtype desc ;' \
55+
'select qtype as Qtype, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qtype=1 or qtype=2 or qtype=5 or qtype=6 or qtype=12 or qtype=15 or qtype=28 or qtype=38 or qtype=255) group by Qtype,TLD order by count,TLD,Qtype desc limit 200;;' \
56+
"select 'ALL' as All, rcode as Rcode, count(1) as count from dns where qr==1 group by All,Rcode order by count desc ;" \
57+
'select rcode as Rcode, msg_size as ReplyLen, count(1) as count from dns where qr==1 group by Rcode,ReplyLen order by count desc ;' \
58+
"select 'ALL' as All, rd as RD, count(1) as count from dns where qr==0 group by All,RD order by count desc ;" \
59+
"select if(protocol==6,'tcp',if(protocol==17,'udp',protocol)) as Transport, qtype as Qtype, count(1) as count from dns where qr==0 group by Transport,Qtype order by Transport,Qtype,count desc ;" \
60+
"select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, dst_addr, lower_src, integer, float" \
61+
"select name( 'qtype' , qtype ) as qt, count(*) as count from dns group by qtype order by count desc;"\
62+
"select count(*) as count, lower(rsplit(qname,1)) as tld, istld(tld) as flag from dns group by tld order by count desc limit 50;" \
63+
;
64+
do
65+
test=$test+1
66+
new=$(./packetq --version | tr " " "_")
67+
echo ""
68+
if [ ${#SQL} -gt 200 ]; then ellipsis="..."; else ellipsis=""; fi
69+
echo "Test $test: '${SQL:0:200}$ellipsis'"
70+
t_new=$(/usr/bin/time -f "%e" ./packetq --tlds /usr/share/packetq/tlds -s "$SQL" $1 2>&1 > $DIR/$new.test$test.result)
71+
e_new=$?
72+
echo " Comparing $new against available binaries:"
73+
for prev in $(ls ../../packetq*/src/packetq); do
74+
old=$($prev --version | cut -d " " -f 2)
75+
ver=$(printf "%-20s" $old)
76+
bin=$(printf "%-48s" $prev)
77+
t_old=$(/usr/bin/time -f "%e" $prev -s "$SQL" $1 2>&1 > $DIR/$old.test$test.result)
78+
e_old=$?
79+
if [ $e_new = 0 -a $e_old = 0 -a "$t_old" != "0.00" ]; then
80+
echo -e " $bin $ver: $t_old --> $t_new ($(python -c "print '%5.2f %d%%' % ($t_new - $t_old, ($t_new-$t_old)*100/$t_old)"))"
81+
else
82+
echo -e " $bin $ver: $t_old --> $t_new ($ver Failed)"
83+
fi
84+
diff -u $DIR/$old.test$test.result $DIR/$new.test$test.result > $DIR/$new.test$test.diff
85+
if [ $? = 0 ]; then
86+
#echo "Test $test: No changes in output"
87+
true
88+
else
89+
head -n 20 $DIR/$new.test$test.diff
90+
fi
91+
done
92+
done

src/test/Makefile.am

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2121

2222
CLEANFILES = test*.log test*.trs \
23-
test1.out test2.out test3.out test4.out
23+
test1.out test2.out test3.out test4.out test5.out
2424

25-
TESTS = test1.sh test2.sh test3.sh test4.sh
25+
TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh
2626

2727
EXTRA_DIST = $(TESTS) \
28-
test1.gold test2.gold test3.gold test4.gold
28+
test1.gold test2.gold test3.gold test4.gold test5.gold \
29+
sql.txt

src/test/sql.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
select qname as CertainQnames, qtype as Qtype, count(1) as count from dns where (qname='localhost' or qname like '%.root-servers.net') and qr==0 group by CertainQnames,Qtype order by count desc;
2+
select qtype as Qtype, qname as Qname, count(1) as count from dns where qclass==3 and qr==0 group by Qtype,Qname order by count desc;
3+
select rcode as Rcode, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==1 group by Rcode,ClientAddr order by count desc limit 50;
4+
select 'ALL' as All, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count,ClientSubnet desc limit 200;
5+
#select 'ALL' as All, subnet(src_addr,24,96) as ClientSubnet, count(1) as count from dns where qr==0 group by All,ClientSubnet order by count desc,ClientSubnet limit 200;
6+
select if(rsplit(qname,1)='de','ok','non-auth-tld') as Class, if(ether_type==34525,rsplit(src_addr,7,':')||':'||rsplit(src_addr,6,':')||':'||rsplit(src_addr,5,':')||':'||rsplit(src_addr,4,':')||':'||rsplit(src_addr,3,':')||'::',rsplit(src_addr,3)||'.'||rsplit(src_addr,2)||'.'||rsplit(src_addr,1)||'.0') as ClientSubnet, count(1) as count from dns where qr==0 group by Class,ClientSubnet order by count,ClientSubnet,Class desc limit 200;
7+
select if(qr==1,'sent','recv') as Direction, if(protocol==6,'tcp',if(protocol==17,'udp',if(protocol==1,'icmp',if(protocol==58,'ipv6-icmp',protocol)))) as IPProto, count(1) as count from dns group by Direction,IPProto order by count,Direction desc;
8+
select if(ether_type==34525,'IPv6','IPv4') as IPVersion, qtype as Qtype, count(1) as count from dns where qr==0 group by IPVersion,Qtype order by count desc;
9+
select 'ALL' as All, do, edns0, edns_version, extended_rcode, z, if(do==1,'set','clr') as D0, count(1) as count from dns where qr==0 group by All,do,D0,edns0,edns_version,extended_rcode,z order by count desc;
10+
select 'ALL' as All, if(edns0,edns_version,'none') as EDNSVersion, count(1) as count from dns where qr==0 group by All,EDNSVersion order by count desc;
11+
select 'ALL' as All, if(qname like 'xn--%','idn','normal') as IDNQname, count(1) as count from dns where qr==0 group by All,IDNQname order by count desc;
12+
select 'ALL' as All, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qname like 'xn--%') group by All,TLD order by count,TLD desc;
13+
select 'ALL' as All, if(qr==1,dst_addr,src_addr) as ClientAddr, count(1) as count from dns where qr==0 and (qtype=28 or qtype=38) and (qname like '%.root-servers.net') group by All,ClientAddr order by count desc limit 50;
14+
select 'ALL' as All, opcode as Opcode, count(1) as count from dns where qr==0 group by All,Opcode order by count desc;
15+
select 'ALL' as All, qtype as Qtype, count(1) as count from dns where qr==0 group by All,Qtype order by count desc;
16+
select qtype as Qtype, len(qname) as QnameLen, count(1) as count from dns where qr==0 group by Qtype,QnameLen order by count,QnameLen,Qtype desc;
17+
select qtype as Qtype, lower(rsplit(qname,1)) as TLD, count(1) as count from dns where qr==0 and (qtype=1 or qtype=2 or qtype=5 or qtype=6 or qtype=12 or qtype=15 or qtype=28 or qtype=38 or qtype=255) group by Qtype,TLD order by count,TLD,Qtype desc limit 200;
18+
select 'ALL' as All, rcode as Rcode, count(1) as count from dns where qr==1 group by All,Rcode order by count desc;
19+
select rcode as Rcode, msg_size as ReplyLen, count(1) as count from dns where qr==1 group by Rcode,ReplyLen order by count desc;
20+
select 'ALL' as All, rd as RD, count(1) as count from dns where qr==0 group by All,RD order by count desc;
21+
select if(protocol==6,'tcp',if(protocol==17,'udp',protocol)) as Transport, qtype as Qtype, count(1) as count from dns where qr==0 group by Transport,Qtype order by Transport,Qtype,count desc;
22+
select s, dst_addr as Dst_addr, qtype as questiontype, lower(src_addr) as lower_src, if(1 and s < 1 or s <= 1 or s > 1 or s >= 1, 't', 'f'), trim(trim('foofoo' || rsplit(src_addr, 1) || 'foofoo', 'foo'), 'bar'), count(*), len(src_addr), sum(msg_size + -1 - 2 % 4 << 3 >> 2 | 3 & ~4) + 1, min(msg_size), max(msg_size), truncate(1.1) as integer, 1.1 as float, sum(src_port + 1.0 - 2.0 / 1.5 * -2.5) + 1.0, max(src_port + 1.0), min(src_port + 1.0), avg(src_port), stdev(src_port), name('rcode', 0) from dns where src_addr like '%' and (qr or not qr) group by src_addr, s having s >= 0 order by s, dst_addr, lower_src, integer, float;
23+
select name( 'qtype' , qtype ) as qt, count(*) as count from dns group by qtype order by count desc;
24+
#select count(*) as count, lower(rsplit(qname,1)) as tld, istld(tld) as flag from dns group by tld order by count desc limit 50;

0 commit comments

Comments
 (0)