Change-Id: If4a1072e75cb64f785d660e4c828c0f521d84b16changes/78/23878/2
parent
79ed4b1685
commit
c4ac9e0fe3
@ -0,0 +1,105 @@ |
||||
module OPCAP_Adapter { |
||||
|
||||
/* OPCAP Adapter layer, sitting on top of OPCAP_CodecPort. |
||||
* test suites can 'inherit' in order to have a OPCAP connection to the IUT which they're testing |
||||
* |
||||
* (C) 2021 by Harald Welte <laforge@gnumonks.org> |
||||
* All rights reserved. |
||||
* |
||||
* Released under the terms of GNU General Public License, Version 2 or |
||||
* (at your option) any later version. |
||||
*/ |
||||
|
||||
|
||||
import from Osmocom_Types all; |
||||
import from General_Types all; |
||||
import from OPCAP_Types all; |
||||
import from OPCAP_Templates all; |
||||
import from OPCAP_CodecPort all; |
||||
import from OPCAP_CodecPort_CtrlFunct all; |
||||
import from IPL4asp_Types all; |
||||
import from IPL4asp_PortType all; |
||||
import from Socket_API_Definitions all; |
||||
|
||||
const integer NUM_OPCAP := 3; |
||||
|
||||
type component OPCAP_Adapter_CT { |
||||
/* down-facing port to OPCAP Codec port */ |
||||
port OPCAP_CODEC_PT OPCAP[NUM_OPCAP]; |
||||
var IPL4asp_Types.ConnectionId g_opcap_conn_id[NUM_OPCAP] := { -1, -1, -1 }; |
||||
} |
||||
|
||||
private function f_set_tcp_segmentation(integer idx) runs on OPCAP_Adapter_CT { |
||||
/* Set function for dissecting the binary stream into packets */ |
||||
var f_IPL4_getMsgLen vl_f := refers(f_IPL4_fixedMsgLen); |
||||
/* Offset: 2, size of length: 2, delta: 4, multiplier: 1, big-endian */ |
||||
OPCAP_CodecPort_CtrlFunct.f_IPL4_setGetMsgLen(OPCAP[idx], g_opcap_conn_id[idx], vl_f, {2, 2, 4, 1, 0}); |
||||
} |
||||
|
||||
function f_connect(charstring remote_host, IPL4asp_Types.PortNumber remote_port, |
||||
charstring local_host, IPL4asp_Types.PortNumber local_port, integer idx := 0) |
||||
runs on OPCAP_Adapter_CT { |
||||
var IPL4asp_Types.Result res; |
||||
map(self:OPCAP[idx], system:OPCAP); |
||||
if (g_opcap_conn_id[idx] != -1) { |
||||
OPCAP_CodecPort_CtrlFunct.f_IPL4_close(OPCAP[idx], g_opcap_conn_id[idx], {tcp := {}}); |
||||
g_opcap_conn_id[idx] := -1; |
||||
} |
||||
res := OPCAP_CodecPort_CtrlFunct.f_IPL4_connect(OPCAP[idx], remote_host, remote_port, |
||||
local_host, local_port, 0, { tcp :={} }); |
||||
if (not ispresent(res.connId)) { |
||||
setverdict(fail, "Could not connect to OPCAP port, check your configuration ", |
||||
"{remote ", remote_host, ":", remote_port, " local ", local_host, ":", local_port, "}"); |
||||
mtc.stop; |
||||
} |
||||
g_opcap_conn_id[idx] := res.connId; |
||||
|
||||
f_set_tcp_segmentation(idx); |
||||
} |
||||
|
||||
/* Function to use to bind to a local port as IPA server, accepting remote clients */ |
||||
function f_bind(charstring local_host, IPL4asp_Types.PortNumber local_port, integer idx := 0) |
||||
runs on OPCAP_Adapter_CT { |
||||
var IPL4asp_Types.Result res; |
||||
map(self:OPCAP[idx], system:OPCAP); |
||||
if (g_opcap_conn_id[idx] != -1) { |
||||
OPCAP_CodecPort_CtrlFunct.f_IPL4_close(OPCAP[idx], g_opcap_conn_id[idx], {tcp := {}}); |
||||
g_opcap_conn_id[idx] := -1; |
||||
} |
||||
res := OPCAP_CodecPort_CtrlFunct.f_IPL4_listen(OPCAP[idx], local_host, local_port, { tcp:={} }); |
||||
if (not ispresent(res.connId)) { |
||||
setverdict(fail, "Could not bind to OPCAP port, check your configuration ", |
||||
"{local ", local_host, ":", local_port, "}"); |
||||
mtc.stop; |
||||
} |
||||
g_opcap_conn_id[idx] := res.connId; |
||||
|
||||
f_set_tcp_segmentation(idx); |
||||
} |
||||
|
||||
function f_wait_client_connect(integer idx) runs on OPCAP_Adapter_CT { |
||||
var IPL4asp_Types.PortEvent rx_event; |
||||
OPCAP[idx].receive(IPL4asp_Types.PortEvent:{connOpened:=?}) -> value rx_event { |
||||
log("Connection from ", rx_event.connOpened.remName, ":", rx_event.connOpened.remPort); |
||||
/* we want to store the client's connId, not the 'bind socket' one */ |
||||
g_opcap_conn_id[idx] := rx_event.connOpened.connId; |
||||
} |
||||
} |
||||
|
||||
function f_disconnect(integer idx) runs on OPCAP_Adapter_CT { |
||||
OPCAP_CodecPort_CtrlFunct.f_IPL4_close(OPCAP[idx], g_opcap_conn_id[idx], {tcp := {}}); |
||||
OPCAP[idx].clear; |
||||
}; |
||||
|
||||
function f_opcap_send(template (value) OPCAP_PDU pdu, integer idx := 0) runs on OPCAP_Adapter_CT { |
||||
OPCAP[idx].send(ts_OPCAP_Send(g_opcap_conn_id[idx], pdu)); |
||||
} |
||||
|
||||
function f_opcap_exp(template OPCAP_PDU exp, integer idx := 0) runs on OPCAP_Adapter_CT return OPCAP_PDU { |
||||
var OPCAP_RecvFrom rf; |
||||
OPCAP[idx].receive(tr_OPCAP_Recv(g_opcap_conn_id[idx], exp)) -> value rf; |
||||
return rf.msg; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,64 @@ |
||||
module OPCAP_CodecPort { |
||||
|
||||
/* Simple OPCAP Codec Port, translating between raw TCP octetstring payload |
||||
* towards the IPL4asp port provider, and OPCAP primitives |
||||
* which carry the decoded OPCAP data types as payload. |
||||
* |
||||
* (C) 2021 by Harald Welte <laforge@gnumonks.org> |
||||
* All rights reserved. |
||||
* |
||||
* Released under the terms of GNU General Public License, Version 2 or |
||||
* (at your option) any later version. |
||||
*/ |
||||
|
||||
|
||||
import from IPL4asp_PortType all; |
||||
import from IPL4asp_Types all; |
||||
import from OPCAP_Types all; |
||||
|
||||
type record OPCAP_RecvFrom { |
||||
ConnectionId connId, |
||||
OPCAP_PDU msg |
||||
} |
||||
|
||||
type record OPCAP_Send { |
||||
ConnectionId connId, |
||||
OPCAP_PDU msg |
||||
} |
||||
|
||||
template (value) OPCAP_Send ts_OPCAP_Send(ConnectionId conn_id, template (value) OPCAP_PDU msg) := { |
||||
connId := conn_id, |
||||
msg := msg |
||||
} |
||||
|
||||
template OPCAP_RecvFrom tr_OPCAP_Recv(template ConnectionId conn_id, template OPCAP_PDU msg) := { |
||||
connId := conn_id, |
||||
msg := msg |
||||
} |
||||
|
||||
private function IPL4_to_OPCAP_RecvFrom(in ASP_RecvFrom pin, out OPCAP_RecvFrom pout) { |
||||
pout.connId := pin.connId; |
||||
pout.msg := dec_OPCAP_PDU(pin.msg); |
||||
} with { extension "prototype(fast)" } |
||||
|
||||
private function OPCAP_to_IPL4_Send(in OPCAP_Send pin, out ASP_Send pout) { |
||||
pout.connId := pin.connId; |
||||
pout.proto := { tcp := {} }; |
||||
pout.msg := enc_OPCAP_PDU(pin.msg); |
||||
} with { extension "prototype(fast)" } |
||||
|
||||
type port OPCAP_CODEC_PT message { |
||||
out OPCAP_Send; |
||||
in OPCAP_RecvFrom, |
||||
ASP_ConnId_ReadyToRelease, |
||||
ASP_Event; |
||||
} with { extension "user IPL4asp_PT |
||||
out(OPCAP_Send -> ASP_Send: function(OPCAP_to_IPL4_Send)) |
||||
in(ASP_RecvFrom -> OPCAP_RecvFrom: function(IPL4_to_OPCAP_RecvFrom); |
||||
ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple; |
||||
ASP_Event -> ASP_Event: simple)" |
||||
} |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,52 @@ |
||||
module OPCAP_CodecPort_CtrlFunct { |
||||
|
||||
import from OPCAP_CodecPort all; |
||||
import from IPL4asp_Types all; |
||||
|
||||
external function f_IPL4_listen( |
||||
inout OPCAP_CODEC_PT portRef, |
||||
in HostName locName, |
||||
in PortNumber locPort, |
||||
in ProtoTuple proto, |
||||
in OptionList options := {} |
||||
) return Result; |
||||
|
||||
external function f_IPL4_connect( |
||||
inout OPCAP_CODEC_PT portRef, |
||||
in HostName remName, |
||||
in PortNumber remPort, |
||||
in HostName locName, |
||||
in PortNumber locPort, |
||||
in ConnectionId connId, |
||||
in ProtoTuple proto, |
||||
in OptionList options := {} |
||||
) return Result; |
||||
|
||||
external function f_IPL4_close( |
||||
inout OPCAP_CODEC_PT portRef, |
||||
in ConnectionId id, |
||||
in ProtoTuple proto := { unspecified := {} } |
||||
) return Result; |
||||
|
||||
external function f_IPL4_setUserData( |
||||
inout OPCAP_CODEC_PT portRef, |
||||
in ConnectionId id, |
||||
in UserData userData |
||||
) return Result; |
||||
|
||||
external function f_IPL4_getUserData( |
||||
inout OPCAP_CODEC_PT portRef, |
||||
in ConnectionId id, |
||||
out UserData userData |
||||
) return Result; |
||||
|
||||
external function f_IPL4_setGetMsgLen( |
||||
inout OPCAP_CODEC_PT portRef, |
||||
in ConnectionId id, |
||||
inout f_IPL4_getMsgLen f, |
||||
in ro_integer msgLenArgs |
||||
); |
||||
|
||||
|
||||
} |
||||
|
@ -0,0 +1,66 @@ |
||||
#include "IPL4asp_PortType.hh" |
||||
#include "OPCAP_CodecPort.hh" |
||||
#include "IPL4asp_PT.hh" |
||||
|
||||
namespace OPCAP__CodecPort__CtrlFunct { |
||||
|
||||
IPL4asp__Types::Result f__IPL4__listen( |
||||
OPCAP__CodecPort::OPCAP__CODEC__PT& portRef, |
||||
const IPL4asp__Types::HostName& locName, |
||||
const IPL4asp__Types::PortNumber& locPort, |
||||
const IPL4asp__Types::ProtoTuple& proto, |
||||
const IPL4asp__Types::OptionList& options) |
||||
{ |
||||
return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options); |
||||
} |
||||
|
||||
IPL4asp__Types::Result f__IPL4__connect( |
||||
OPCAP__CodecPort::OPCAP__CODEC__PT& portRef, |
||||
const IPL4asp__Types::HostName& remName, |
||||
const IPL4asp__Types::PortNumber& remPort, |
||||
const IPL4asp__Types::HostName& locName, |
||||
const IPL4asp__Types::PortNumber& locPort, |
||||
const IPL4asp__Types::ConnectionId& connId, |
||||
const IPL4asp__Types::ProtoTuple& proto, |
||||
const IPL4asp__Types::OptionList& options) |
||||
{ |
||||
return f__IPL4__PROVIDER__connect(portRef, remName, remPort, |
||||
locName, locPort, connId, proto, options); |
||||
} |
||||
|
||||
IPL4asp__Types::Result f__IPL4__close( |
||||
OPCAP__CodecPort::OPCAP__CODEC__PT& portRef,
|
||||
const IPL4asp__Types::ConnectionId& connId,
|
||||
const IPL4asp__Types::ProtoTuple& proto) |
||||
{ |
||||
return f__IPL4__PROVIDER__close(portRef, connId, proto); |
||||
} |
||||
|
||||
IPL4asp__Types::Result f__IPL4__setUserData( |
||||
OPCAP__CodecPort::OPCAP__CODEC__PT& portRef, |
||||
const IPL4asp__Types::ConnectionId& connId, |
||||
const IPL4asp__Types::UserData& userData) |
||||
{ |
||||
return f__IPL4__PROVIDER__setUserData(portRef, connId, userData); |
||||
} |
||||
|
||||
IPL4asp__Types::Result f__IPL4__getUserData( |
||||
OPCAP__CodecPort::OPCAP__CODEC__PT& portRef, |
||||
const IPL4asp__Types::ConnectionId& connId, |
||||
IPL4asp__Types::UserData& userData) |
||||
{ |
||||
return f__IPL4__PROVIDER__getUserData(portRef, connId, userData); |
||||
} |
||||
|
||||
void f__IPL4__setGetMsgLen( |
||||
OPCAP__CodecPort::OPCAP__CODEC__PT& portRef, |
||||
const IPL4asp__Types::ConnectionId& connId, |
||||
Socket__API__Definitions::f__getMsgLen& f, |
||||
const Socket__API__Definitions::ro__integer& msgLenArgs) |
||||
{ |
||||
return f__IPL4__PROVIDER__setGetMsgLen(portRef, connId, f, msgLenArgs); |
||||
} |
||||
|
||||
|
||||
} |
||||
|
@ -0,0 +1,54 @@ |
||||
module OPCAP_Templates { |
||||
|
||||
/* OPCAP_Templates, defining TTCN-3 templates for the osmo-pcap protocol. |
||||
* |
||||
* OPCAP is a non-standard protocol used between osmo-pcap-client and osmo-pcap-server. |
||||
* |
||||
* (C) 2021 by Harald Welte <laforge@gnumonks.org> |
||||
* All rights reserved. |
||||
* |
||||
* Released under the terms of GNU General Public License, Version 2 or |
||||
* (at your option) any later version. |
||||
*/ |
||||
|
||||
import from General_Types all; |
||||
import from Osmocom_Types all; |
||||
import from OPCAP_Types all; |
||||
|
||||
|
||||
template (present) OPCAP_PDU tr_OPCAP_FILE_HDR(template (present) uint32_t linktype := ?) := { |
||||
msg_type := PKT_LINK_HDR, |
||||
spare := ?, |
||||
len := 24, |
||||
u := { |
||||
file := { |
||||
magic := PCAP_MAGIC, |
||||
version_major := PCAP_VERSION_MAJOR, |
||||
version_minor := PCAP_VERSION_MINOR, |
||||
thiszone := 0, |
||||
sigfigs := 0, |
||||
snaplen := 9000, |
||||
linktype := linktype |
||||
} |
||||
} |
||||
} |
||||
|
||||
template (present) OPCAP_PDU tr_OPCAP_PKT(template (present) octetstring payload, |
||||
template (present) uint32_t caplen := ?, |
||||
template (present) uint32_t len := ?) := { |
||||
msg_type := PKT_LINK_DATA, |
||||
spare := ?, |
||||
len := ?, |
||||
u := { |
||||
packet := { |
||||
ts_sec := ?, |
||||
ts_usec := ?, |
||||
caplen := caplen, |
||||
len := len, |
||||
payload := payload |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
}; |
@ -0,0 +1,78 @@ |
||||
module OPCAP_Types { |
||||
|
||||
/* OPCAP_Types, defining abstract TTCN-3 data types for the osmo-pcap protocol. |
||||
* |
||||
* OPCAP is a non-standard protocol used between osmo-pcap-client and osmo-pcap-server. |
||||
* |
||||
* (C) 2021 by Harald Welte <laforge@gnumonks.org> |
||||
* All rights reserved. |
||||
* |
||||
* Released under the terms of GNU General Public License, Version 2 or |
||||
* (at your option) any later version. |
||||
*/ |
||||
|
||||
import from General_Types all; |
||||
import from Osmocom_Types all; |
||||
|
||||
type enumerated OpcapMsgType { |
||||
PKT_LINK_HDR (0), |
||||
PKT_LINK_DATA (1) |
||||
} with { variant "FIELDLENGTH(8)" }; |
||||
|
||||
type record OPCAP_PDU { |
||||
OpcapMsgType msg_type, |
||||
uint8_t spare, |
||||
uint16_t len, |
||||
OpcapBodyUnion u |
||||
} with { |
||||
variant (len) "LENGTHTO(u)" |
||||
variant (len) "BYTEORDER(last)" |
||||
variant (u) "CROSSTAG( |
||||
file, msg_type = PKT_LINK_HDR; |
||||
packet, msg_type = PKT_LINK_DATA; |
||||
)" |
||||
}; |
||||
|
||||
type union OpcapBodyUnion { |
||||
PcapFileHeader file, |
||||
OpcapPacket packet |
||||
}; |
||||
|
||||
/* header in front of a PKT_LINK_DATA */ |
||||
type record OpcapPacket { |
||||
uint32_t ts_sec, |
||||
uint32_t ts_usec, |
||||
uint32_t caplen, |
||||
uint32_t len, |
||||
octetstring payload |
||||
} with { |
||||
variant (caplen) "LENGTHTO(payload)" |
||||
}; |
||||
|
||||
/* below definitions are from pcap/pcap.h */ |
||||
const uint16_t PCAP_VERSION_MAJOR := 2; |
||||
const uint16_t PCAP_VERSION_MINOR := 4; |
||||
const uint32_t PCAP_MAGIC := 2712847316; //0xA1B2C3D4; |
||||
|
||||
type record PcapFileHeader { |
||||
uint32_t magic, |
||||
uint16_t version_major, |
||||
uint16_t version_minor, |
||||
uint32_t thiszone, |
||||
uint32_t sigfigs, |
||||
uint32_t snaplen, |
||||
uint32_t linktype |
||||
}; |
||||
|
||||
/* below definitions are from pcap/dlt.h */ |
||||
const uint32_t DLT_LINUX_SLL := 113; |
||||
const uint32_t DLT_EN10MB := 1; |
||||
|
||||
|
||||
external function enc_OPCAP_PDU(in OPCAP_PDU msg) return octetstring |
||||
with { extension "prototype(convert) encode(RAW)" }; |
||||
|
||||
external function dec_OPCAP_PDU(in octetstring msg) return OPCAP_PDU |
||||
with { extension "prototype(convert) decode(RAW)" }; |
||||
|
||||
} with { encode "RAW"; variant "FIELDORDER(msb)"; variant "BYTEORDER(first)" }; |
@ -0,0 +1,18 @@ |
||||
[ORDERED_INCLUDE] |
||||
# Common configuration, shared between test suites |
||||
"../Common.cfg" |
||||
# testsuite specific configuration, not expected to change |
||||
"./OPCAP_CLIENT_Tests.default" |
||||
|
||||
# Local configuration below |
||||
|
||||
[LOGGING] |
||||
|
||||
[TESTPORT_PARAMETERS] |
||||
|
||||
[MODULE_PARAMETERS] |
||||
|
||||
[MAIN_CONTROLLER] |
||||
|
||||
[EXECUTE] |
||||
OPCAP_CLIENT_Tests.control |
@ -0,0 +1,19 @@ |
||||
[LOGGING] |
||||
mtc.FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC; |
||||
|
||||
[TESTPORT_PARAMETERS] |
||||
*.VTY.CTRL_MODE := "client" |
||||
*.VTY.CTRL_HOSTNAME := "127.0.0.1" |
||||
*.VTY.CTRL_PORTNUM := "4237" |
||||
*.VTY.CTRL_LOGIN_SKIPPED := "yes" |
||||
*.VTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes" |
||||
*.VTY.CTRL_READMODE := "buffered" |
||||
*.VTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes" |
||||
*.VTY.CTRL_DETECT_CONNECTION_ESTABLISHMENT_RESULT := "yes" |
||||
*.VTY.PROMPT1 := "OsmoPCAPClient> " |
||||
*.TCP.noDelay := "yes" // turn off nagle |
||||
|
||||
[MODULE_PARAMETERS] |
||||
Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoPCAPClient" |
||||
|
||||
[EXECUTE] |
@ -0,0 +1,212 @@ |
||||
module OPCAP_CLIENT_Tests { |
||||
|
||||
import from OPCAP_Adapter all; |
||||
import from OPCAP_Types all; |
||||
import from OPCAP_Templates all; |
||||
|
||||
import from IPL4asp_Types all; |
||||
import from IPL4asp_PortType all; |
||||
import from Osmocom_Types all; |
||||
import from Osmocom_VTY_Functions all; |
||||
import from TELNETasp_PortType all; |
||||
import from Socket_API_Definitions all; |
||||
|
||||
type record IpPort { |
||||
charstring ip, |
||||
integer udp_port |
||||
}; |
||||
|
||||
modulepar { |
||||
/* local IP address listening for OPCAP connections */ |
||||
charstring mp_local_opcap_ip := "127.0.0.1"; |
||||
/* local TCP base port for inbound OPCAP connections */ |
||||
integer mp_local_opcap_port := 5000; |
||||
|
||||
/* IP + port for simulating user traffic */ |
||||
IpPort mp_traffic_a := { "127.0.0.23", 44423 }; |
||||
IpPort mp_traffic_b := { "127.0.0.42", 44442 }; |
||||
}; |
||||
|
||||
type component test_CT extends OPCAP_Adapter_CT { |
||||
timer g_Tguard := 30.0; |
||||
|
||||
port TELNETasp_PT VTY; |
||||
|
||||
/* port to generate IP traffic that may or may not be captured */ |
||||
port IPL4asp_PT IP; |
||||
var integer g_traffic_conn_id[2]; |
||||
}; |
||||
|
||||
private altstep as_Tguard() runs on test_CT { |
||||
[] g_Tguard.timeout { |
||||
setverdict(fail, "global guard timeout"); |
||||
mtc.stop; |
||||
} |
||||
} |
||||
|
||||
/* initialize one of the OPCAP servers, wait for client to connect */ |
||||
private function f_init_one_srv(integer idx, template (present) uint32_t linktype) runs on test_CT { |
||||
/* start guard timer */ |
||||
activate(as_Tguard()); |
||||
g_Tguard.start; |
||||
log("Waiting for client-", idx, " connection..."); |
||||
/* wait for connection */ |
||||
f_bind(mp_local_opcap_ip, mp_local_opcap_port+idx, idx); |
||||
f_wait_client_connect(idx); |
||||
/* wait for file header */ |
||||
f_opcap_exp(tr_OPCAP_FILE_HDR(linktype), idx); |
||||
}; |
||||
|
||||
|
||||
/* global initialization */ |
||||
private function f_init() runs on test_CT { |
||||
map(self:VTY, system:VTY); |
||||
f_vty_set_prompts(VTY); |
||||
f_vty_transceive(VTY, "enable"); |
||||
|
||||
map(self:IP, system:IP); |
||||
var IPL4asp_Types.Result res |
||||
|
||||
/* 0 -> 1 */ |
||||
res := f_IPL4_connect(IP, mp_traffic_b.ip, mp_traffic_b.udp_port, |
||||
mp_traffic_a.ip, mp_traffic_a.udp_port, -1, { udp:={} }); |
||||
g_traffic_conn_id[0] := res.connId; |
||||
|
||||
/* 1 -> 0 */ |
||||
res := f_IPL4_connect(IP, mp_traffic_a.ip, mp_traffic_a.udp_port, |
||||
mp_traffic_b.ip, mp_traffic_b.udp_port, -1, { udp:={} }); |
||||
g_traffic_conn_id[1] := res.connId; |
||||
} |
||||
|
||||
/* generate user traffic from A -> B */ |
||||
function f_trafic_pkt_ab(octetstring payload) runs on test_CT { |
||||
IP.send(ASP_Send:{g_traffic_conn_id[0], omit, payload}) |
||||
IP.receive(ASP_RecvFrom:{g_traffic_conn_id[1], ?, ?, ?, ?, { udp:={} }, ?, payload}); |
||||
} |
||||
|
||||
/* generate user traffic from B -> A */ |
||||
function f_trafic_pkt_ba(octetstring payload) runs on test_CT { |
||||
IP.send(ASP_Send:{g_traffic_conn_id[1], omit, payload}) |
||||
IP.receive(ASP_RecvFrom:{g_traffic_conn_id[0], ?, ?, ?, ?, { udp:={} }, ?, payload}); |
||||
} |
||||
|
||||
/* expect a specified UDP payload on the OPCAP connection 'idx' */ |
||||
function f_opcap_exp_udp(octetstring udp_payload, integer idx) runs on test_CT { |
||||
var octetstring rx_tail; |
||||
var integer udp_payload_len, rx_pdu_len; |
||||
var OPCAP_PDU rx_pdu; |
||||
|
||||
udp_payload_len := lengthof(udp_payload); |
||||
|
||||
/* sadly I couldn't figure out how to create an octetstring template |
||||
* for 'match an octetstring ending in 'udp_payload' */ |
||||
rx_pdu := f_opcap_exp(tr_OPCAP_PKT(?), idx); |
||||
rx_pdu_len := lengthof(rx_pdu.u.packet.payload); |
||||
rx_tail := substr(rx_pdu.u.packet.payload, rx_pdu_len - udp_payload_len, udp_payload_len); |
||||
if (rx_tail != udp_payload) { |
||||
log("captured UDP payload: ", rx_tail, " but expected: ", udp_payload); |
||||
setverdict(fail); |
||||
} else { |
||||
setverdict(pass); |
||||
} |
||||
} |
||||
|
||||
/* create an additional pcap-store-connection via the VTY */ |
||||
function f_vty_create_addl_connection(integer idx) runs on test_CT |
||||
{ |
||||
f_vty_config3(VTY, { "client", "pcap-store-connectio second-" & int2str(idx) }, |
||||
{ "server ip " & mp_local_opcap_ip, |
||||
"server port " & int2str(mp_local_opcap_port + idx), |
||||
"connect" } |
||||
); |
||||
} |
||||
|
||||
|
||||
|
||||
/* wait for inbound client connection and reception of link header */ |
||||
testcase TC_connect_rx_hdr() runs on test_CT |
||||
{ |
||||
f_init(); |
||||
f_init_one_srv(0, ?); |
||||
setverdict(pass); |
||||
} |
||||
|
||||
/* check if client connection is re-started after a close */ |
||||
testcase TC_reconnect(integer idx := 0) runs on test_CT |
||||
{ |
||||
f_init(); |
||||
f_init_one_srv(idx, ?); |
||||
f_sleep(2.0); |
||||
|
||||
log("Disconnecting client-", idx); |
||||
f_disconnect(idx); |
||||
|
||||
f_wait_client_connect(idx); |
||||
f_opcap_exp(tr_OPCAP_FILE_HDR(?), idx); |
||||
setverdict(pass); |
||||
} |
||||
|
||||
/* capture a packet that's within the filter */ |
||||
testcase TC_capture() runs on test_CT |
||||
{ |
||||
f_init(); |
||||
f_init_one_srv(0, ?); |
||||
|
||||
for (var integer i := 0; i < 10; i := i + 1) { |
||||
var octetstring udp_payload; |
||||
|
||||
/* we assume 1400 is low enough to avoid IP fragmentation */ |
||||
udp_payload := f_rnd_octstring(f_rnd_int(1400)); |
||||
f_trafic_pkt_ab(udp_payload); |
||||
|
||||
f_opcap_exp_udp(udp_payload, 0); |
||||
} |
||||
} |
||||
|
||||
/* wait for inbound client connections and reception of link header */ |
||||
testcase TC_multi_connect_rx_hdr() runs on test_CT |
||||
{ |
||||
f_init(); |
||||
f_init_one_srv(0, ?); |
||||
f_vty_create_addl_connection(1); |
||||
f_init_one_srv(1, ?); |
||||
setverdict(pass); |
||||
} |
||||
|
||||
/* ensure a packet that's within the filter is sent to secondary clients */ |
||||
testcase TC_multi_capture() runs on test_CT |
||||
{ |
||||
f_init(); |
||||
f_init_one_srv(0, ?); |
||||
f_vty_create_addl_connection(1); |
||||
f_init_one_srv(1, ?); |
||||
|
||||
for (var integer i := 0; i < 10; i := i + 1) { |
||||
var octetstring udp_payload; |
||||
|
||||
/* we assume 1400 is low enough to avoid IP fragmentation */ |
||||
udp_payload := f_rnd_octstring(f_rnd_int(1400)); |
||||
f_trafic_pkt_ab(udp_payload); |
||||
|
||||
/* expect packet to arrive on both simulated servers */ |
||||
f_opcap_exp_udp(udp_payload, 0); |
||||
f_opcap_exp_udp(udp_payload, 1); |
||||
} |
||||
} |
||||
|
||||
/* TODO: ensure a packet outside the filter is dropped */ |
||||
/* TODO: capture of truncated packet */ |
||||
/* TODO: stall the receive window */ |
||||
/* TODO: different link type (ethernet, not SLL) */ |
||||
|
||||
|
||||
control { |
||||
execute( TC_connect_rx_hdr() ); |
||||
execute( TC_reconnect() ); |
||||
execute( TC_capture() ); |
||||
execute( TC_multi_connect_rx_hdr() ); |
||||
execute( TC_multi_capture() ); |
||||
}; |
||||
|
||||
|
||||
}; |
@ -0,0 +1,31 @@ |
||||
#!/bin/bash |
||||
|
||||
BASEDIR=../deps |
||||
|
||||
. ../gen_links.sh.inc |
||||
|
||||
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src |
||||
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h" |
||||
FILES+=" TCCEncoding_Functions.ttcn TCCEncoding.cc " # GSM 7-bit coding |
||||
gen_links $DIR $FILES |
||||
|
||||
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src |
||||
FILES="Socket_API_Definitions.ttcn" |
||||
gen_links $DIR $FILES |
||||
|
||||
DIR=$BASEDIR/titan.TestPorts.IPL4asp/src |
||||
FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh" |
||||
gen_links $DIR $FILES |
||||
|
||||
DIR=$BASEDIR/titan.TestPorts.TELNETasp/src |
||||
FILES="TELNETasp_PT.cc TELNETasp_PT.hh TELNETasp_PortType.ttcn" |
||||
gen_links $DIR $FILES |
||||
|
||||
DIR=../library |
||||
FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn Native_Functions.ttcn Native_FunctionDefs.cc " |
||||
FILES+="Osmocom_VTY_Functions.ttcn " |
||||
FILES+="OPCAP_Types.ttcn OPCAP_Templates.ttcn " |
||||
FILES+="OPCAP_CodecPort.ttcn OPCAP_CodecPort_CtrlFunct.ttcn OPCAP_CodecPort_CtrlFunctdef.cc OPCAP_Adapter.ttcn " |
||||
gen_links $DIR $FILES |
||||
|
||||
ignore_pp_results |
@ -0,0 +1,14 @@ |
||||
! |
||||
! OsmoPCAPClient (UNKNOWN-dirty) configuration saved from vty |
||||
!! |
||||
! |
||||
! |
||||
line vty |
||||
no login |
||||
! |
||||
client |
||||
pcap device lo |
||||
pcap filter udp port 44423 |
||||
pcap detect-loop 0 |
||||
server ip 127.0.0.1 |
||||
server port 5000 |
@ -0,0 +1,11 @@ |
||||
#!/bin/bash |
||||
|
||||
FILES="*.ttcn TCCConversion.cc TCCInterface.cc TCCEncoding.cc IPL4asp_PT.cc IPL4asp_discovery.cc TELNETasp_PT.cc Native_FunctionDefs.cc OPCAP_CodecPort_CtrlFunctdef.cc " |
||||
#FILES+="*.ttcnpp " |
||||
#FILES+="*.asn" |
||||
|
||||
export CPPFLAGS_TTCN3="" |
||||
|
||||
../regen-makefile.sh OPCAP_CLIENT_Tests.ttcn $FILES |
||||
|
||||
#sed -i -e 's/^LINUX_LIBS = -lxml2/LINUX_LIBS = -lxml2 -lfftranscode/' Makefile |
Loading…
Reference in new issue