diff --git a/testproject/IPL4_example.ttcn b/testproject/IPL4_example.ttcn index fca9db2..08dbafc 100644 --- a/testproject/IPL4_example.ttcn +++ b/testproject/IPL4_example.ttcn @@ -1,5 +1,6 @@ module IPL4_example { + import from CommonIP all; import from TunDevice_PortType all; import from TunDevice_Types all; import from NetfilterConntrack_Functions all; @@ -18,41 +19,218 @@ module IPL4_example { type component dummy_CT { port TunDevice_PT TUN; 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 { var charstring xml; + init(); xml := f_get_conntracks_xml() log(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 { - map(self:TUN, system:TUN); - map(self:TUN2, system:TUN); + var octetstring msg := unichar2oct("foo") + init(); + TUN.send(tunmsg(msg)) - var Tun_send s - - s.msg := unichar2oct("foo") - TUN.send(s); - - s.msg := unichar2oct("bar") - TUN2.send(s); + msg := unichar2oct("bar") + TUN2.send(tunmsg(msg)) 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 { execute(TC_xml()); - execute(TC_dummy()); + //execute(TC_dummy()); + execute(TC_udp1()); } }