IPL4_example: First working version for full 3-way UDP handshake
This commit is contained in:
parent
71d0e6e661
commit
fb87aa4f11
|
@ -1,5 +1,6 @@
|
||||||
module IPL4_example {
|
module IPL4_example {
|
||||||
|
|
||||||
|
import from CommonIP all;
|
||||||
import from TunDevice_PortType all;
|
import from TunDevice_PortType all;
|
||||||
import from TunDevice_Types all;
|
import from TunDevice_Types all;
|
||||||
import from NetfilterConntrack_Functions all;
|
import from NetfilterConntrack_Functions all;
|
||||||
|
@ -18,41 +19,218 @@ module IPL4_example {
|
||||||
type component dummy_CT {
|
type component dummy_CT {
|
||||||
port TunDevice_PT TUN;
|
port TunDevice_PT TUN;
|
||||||
port TunDevice_PT TUN2;
|
port TunDevice_PT TUN2;
|
||||||
|
var boolean initialized := false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) Tun_send tunmsg(octetstring p_data) := { msg := p_data };
|
||||||
|
|
||||||
|
import from UsefulTtcn3Types all;
|
||||||
|
|
||||||
|
type enumerated nfct_direction { DIR_ORIG, DIR_REPLY };
|
||||||
|
|
||||||
|
type record flow_info {
|
||||||
|
unsignedbyte l3_protocol,
|
||||||
|
charstring src_ip,
|
||||||
|
charstring dst_ip,
|
||||||
|
unsignedbyte l4_protocol,
|
||||||
|
unsignedshort src_port,
|
||||||
|
unsignedshort dst_port
|
||||||
|
}
|
||||||
|
|
||||||
|
template flow_info flow_info_udp := {
|
||||||
|
l4_protocol := tsc_IP_Protocol_UDP
|
||||||
|
}
|
||||||
|
|
||||||
|
template flow_info flow_info_tcp := {
|
||||||
|
l4_protocol := tsc_IP_Protocol_TCP
|
||||||
|
}
|
||||||
|
|
||||||
|
type record pkt_info {
|
||||||
|
nfct_direction direction,
|
||||||
|
octetstring payload optional
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate a flow_info using pre-defined default addresses + * incremented port */
|
||||||
|
function flow_gen(integer port_delta, unsignedbyte l4_prot := tsc_IP_Protocol_UDP) return flow_info {
|
||||||
|
var flow_info flowi := {
|
||||||
|
l3_protocol := 2,
|
||||||
|
src_ip := "1.1.1.200",
|
||||||
|
dst_ip := "2.2.2.200",
|
||||||
|
l4_protocol := l4_prot,
|
||||||
|
src_port := 1000 + port_delta,
|
||||||
|
dst_port := 2000 + port_delta
|
||||||
|
}
|
||||||
|
return flowi
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate a packet according to the input flow + pkt information */
|
||||||
|
function flow_gen_pkt(flow_info flowi, pkt_info pkti) return octetstring {
|
||||||
|
var octetstring ret;
|
||||||
|
var unsignedshort src_port, dst_port;
|
||||||
|
var charstring src_ip, dst_ip;
|
||||||
|
if (pkti.direction == DIR_ORIG) {
|
||||||
|
src_ip := flowi.src_ip
|
||||||
|
src_port := flowi.src_port
|
||||||
|
dst_ip := flowi.dst_ip
|
||||||
|
dst_port := flowi.dst_port
|
||||||
|
} else {
|
||||||
|
src_ip := flowi.dst_ip
|
||||||
|
src_port := flowi.dst_port
|
||||||
|
dst_ip := flowi.src_ip
|
||||||
|
dst_port := flowi.src_port
|
||||||
|
}
|
||||||
|
if (flowi.l4_protocol == tsc_IP_Protocol_UDP) {
|
||||||
|
ret := f_IPv4IPv6_AnyUdpPacket(src_ip, dst_ip, src_port, dst_port);
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reverse the L3 portion */
|
||||||
|
private function f_nfct_l3_reverse(template Layer3_type input) return template Layer3_type {
|
||||||
|
return {
|
||||||
|
protoname := input.protoname,
|
||||||
|
protonum := input.protonum,
|
||||||
|
src := input.dst,
|
||||||
|
dst := input.src
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reverse the L4 portion */
|
||||||
|
private function f_nfct_l4_reverse(template Layer4_type input) return template Layer4_type {
|
||||||
|
return { protoname := input.protoname,
|
||||||
|
protonum := input.protonum,
|
||||||
|
sport := input.dport,
|
||||||
|
dport := input.sport }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reverse an Orig_repl_group template */
|
||||||
|
private function f_nfct_orig_repl_reverse(template Orig_repl_group input) return template Orig_repl_group {
|
||||||
|
var template Orig_repl_group output
|
||||||
|
|
||||||
|
output.layer3 := f_nfct_l3_reverse(input.layer3)
|
||||||
|
output.layer4 := f_nfct_l4_reverse(input.layer4)
|
||||||
|
output.zone := input.zone
|
||||||
|
/* we cannot assume inverse direction counters have any relation to the forward direction */
|
||||||
|
output.counters := *
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
/* construct a template that can be used to match nf-conntrack XML */
|
||||||
|
function f_nfct_templ_from_flow(flow_info flowi) return template Flow {
|
||||||
|
/* construct original tuple from flow */
|
||||||
|
var template Orig_repl_group orig := {
|
||||||
|
layer3 := {
|
||||||
|
protoname := *,
|
||||||
|
protonum := int2str(flowi.l3_protocol),
|
||||||
|
src := flowi.src_ip,
|
||||||
|
dst := flowi.dst_ip
|
||||||
|
},
|
||||||
|
layer4 := {
|
||||||
|
protoname := *,
|
||||||
|
protonum := int2str(flowi.l4_protocol),
|
||||||
|
sport := flowi.src_port,
|
||||||
|
dport := flowi.dst_port
|
||||||
|
},
|
||||||
|
zone := *,
|
||||||
|
counters := *
|
||||||
|
}
|
||||||
|
/* create the inverse of the original tuple */
|
||||||
|
var template Orig_repl_group repl := f_nfct_orig_repl_reverse(orig)
|
||||||
|
|
||||||
|
return {
|
||||||
|
meta := { direction := "original", choice := { orig_repl_group := orig } },
|
||||||
|
meta_1 := { direction := "reply", choice := { orig_repl_group := repl } },
|
||||||
|
meta_2 := ?,
|
||||||
|
when := * }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a single conntrack entry derived from the specified flow_info */
|
||||||
|
function f_get_conntrack(flow_info flowi) return Flow {
|
||||||
|
var charstring xml := f_get_conntrack_xml(flowi.src_ip, flowi.dst_ip, flowi.l4_protocol, flowi.src_port, flowi.dst_port)
|
||||||
|
var Flows flows := dec_Flows(unichar2oct(xml));
|
||||||
|
return flows.flow_list[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function flow_send_pkt_tun1(flow_info flowi, pkt_info pkti) runs on dummy_CT {
|
||||||
|
var octetstring pkt := flow_gen_pkt(flowi, pkti);
|
||||||
|
TUN.send(tunmsg(pkt));
|
||||||
|
}
|
||||||
|
|
||||||
|
function flow_send_pkt_tun2(flow_info flowi, pkt_info pkti) runs on dummy_CT {
|
||||||
|
var octetstring pkt := flow_gen_pkt(flowi, pkti);
|
||||||
|
TUN2.send(tunmsg(pkt));
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() runs on dummy_CT {
|
||||||
|
if (initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map(self:TUN, system:TUN);
|
||||||
|
map(self:TUN2, system:TUN);
|
||||||
|
initialized := true;
|
||||||
}
|
}
|
||||||
|
|
||||||
testcase TC_xml() runs on dummy_CT {
|
testcase TC_xml() runs on dummy_CT {
|
||||||
var charstring xml;
|
var charstring xml;
|
||||||
|
init();
|
||||||
xml := f_get_conntracks_xml()
|
xml := f_get_conntracks_xml()
|
||||||
log(xml)
|
log(xml)
|
||||||
log(dec_Flows(unichar2oct(xml)))
|
log(dec_Flows(unichar2oct(xml)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
var Result result;
|
|
||||||
result := IPL4asp_PortType.f_IPL4_listen(IPL4, "127.0.0.1", 2342, {udp := {}})
|
|
||||||
if (ispresent(result.errorCode)) {
|
|
||||||
setverdict(fail);
|
|
||||||
stop;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
testcase TC_dummy() runs on dummy_CT {
|
testcase TC_dummy() runs on dummy_CT {
|
||||||
map(self:TUN, system:TUN);
|
var octetstring msg := unichar2oct("foo")
|
||||||
map(self:TUN2, system:TUN);
|
init();
|
||||||
|
TUN.send(tunmsg(msg))
|
||||||
|
|
||||||
var Tun_send s
|
msg := unichar2oct("bar")
|
||||||
|
TUN2.send(tunmsg(msg))
|
||||||
s.msg := unichar2oct("foo")
|
|
||||||
TUN.send(s);
|
|
||||||
|
|
||||||
s.msg := unichar2oct("bar")
|
|
||||||
TUN2.send(s);
|
|
||||||
|
|
||||||
setverdict(pass);
|
setverdict(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_nfct_and_match(flow_info flowi, template Flow t_flow) return boolean {
|
||||||
|
var Flow ct := f_get_conntrack(flowi);
|
||||||
|
return match(ct, t_flow);
|
||||||
|
}
|
||||||
|
|
||||||
|
testcase TC_udp1() runs on dummy_CT {
|
||||||
|
var flow_info flowi := flow_gen(1);
|
||||||
|
var Flow ct;
|
||||||
|
var template Flow t_flow;
|
||||||
|
init();
|
||||||
|
|
||||||
|
flow_send_pkt_tun1(flowi, { direction := DIR_ORIG, payload := ''O })
|
||||||
|
//{ meta := { direction := "original", choice := { orig_repl_group := { layer3 := { protoname := "ipv4", protonum := "2", src := "1.1.1.200", dst := "2.2.2.200" }, layer4 := { protoname := "udp", protonum := "17", sport := 1001, dport := 2001 }, zone := omit, counters := omit } } }, meta_1 := { direction := "reply", choice := { orig_repl_group := { layer3 := { protoname := "ipv4", protonum := "2", src := "2.2.2.200", dst := "1.1.1.200" }, layer4 := { protoname := "udp", protonum := "17", sport := 2001, dport := 1001 }, zone := omit, counters := omit } } }, meta_2 := { direction := "independent", choice := { indep_group := { state := omit, timeout_ := 30, mark := 0, secmark := omit, zone := omit, use := 2, id := 2741869312, assured := omit, unreplied := { }, timestamp := omit, deltatime := omit } } }, when := omit }
|
||||||
|
t_flow := f_nfct_templ_from_flow(flowi)
|
||||||
|
t_flow.meta_2.choice.indep_group.unreplied := {}
|
||||||
|
t_flow.meta_2.choice.indep_group.timeout_ := ( 29 .. 30 )
|
||||||
|
if (not get_nfct_and_match(flowi, t_flow)) {
|
||||||
|
setverdict(fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
flow_send_pkt_tun2(flowi, { direction := DIR_REPLY, payload := ''O })
|
||||||
|
//{ meta := { direction := "original", choice := { orig_repl_group := { layer3 := { protoname := "ipv4", protonum := "2", src := "1.1.1.200", dst := "2.2.2.200" }, layer4 := { protoname := "udp", protonum := "17", sport := 1001, dport := 2001 }, zone := omit, counters := omit } } }, meta_1 := { direction := "reply", choice := { orig_repl_group := { layer3 := { protoname := "ipv4", protonum := "2", src := "2.2.2.200", dst := "1.1.1.200" }, layer4 := { protoname := "udp", protonum := "17", sport := 2001, dport := 1001 }, zone := omit, counters := omit } } }, meta_2 := { direction := "independent", choice := { indep_group := { state := omit, timeout_ := 30, mark := 0, secmark := omit, zone := omit, use := 2, id := 2741869312, assured := omit, unreplied := omit, timestamp := omit, deltatime := omit } } }, when := omit }
|
||||||
|
t_flow := f_nfct_templ_from_flow(flowi)
|
||||||
|
t_flow.meta_2.choice.indep_group.timeout_ := ( 29 .. 30 )
|
||||||
|
if (not get_nfct_and_match(flowi, t_flow)) {
|
||||||
|
setverdict(fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
flow_send_pkt_tun1(flowi, { direction := DIR_ORIG, payload := ''O })
|
||||||
|
t_flow := f_nfct_templ_from_flow(flowi);
|
||||||
|
t_flow.meta_2.choice.indep_group.assured := {};
|
||||||
|
t_flow.meta_2.choice.indep_group.timeout_ := ( 179 .. 180 );
|
||||||
|
if (not get_nfct_and_match(flowi, t_flow)) {
|
||||||
|
setverdict(fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
setverdict(pass)
|
||||||
|
}
|
||||||
|
|
||||||
control {
|
control {
|
||||||
execute(TC_xml());
|
execute(TC_xml());
|
||||||
execute(TC_dummy());
|
//execute(TC_dummy());
|
||||||
|
execute(TC_udp1());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue