diff --git a/ccsrc/Protocols/IP/ip_offline_layer.cc b/ccsrc/Protocols/IP/ip_offline_layer.cc index 30702104f344830766148413541a706ed4f58bb0..2a66d0fee582a29326bd7f74f3e8509c37c9b305 100644 --- a/ccsrc/Protocols/IP/ip_offline_layer.cc +++ b/ccsrc/Protocols/IP/ip_offline_layer.cc @@ -1,3 +1,6 @@ +#include <netdb.h> +#include <arpa/inet.h> + #include "ip_offline_layer_factory.hh" #include "loggers.hh" @@ -10,12 +13,33 @@ ip_offline_layer::ip_offline_layer(const std::string& p_type, const std::string void ip_offline_layer::send_data(OCTETSTRING& p_data, params& p_params) { loggers::get_instance().log_msg(">>> ip_offline_layer::send_data: ", p_data); + p_params.log(); - //OCTETSTRING ip; // FIXME FSCOM: To be done - loggers::get_instance().error("ip_offline_layer::send_data: Not implemented. On;ly for offline mode"); - //ip += p_data; - //send_to_all_layers(ip, static_cast<params&>(p_params)); + loggers::get_instance().warning("ip_offline_layer::send_data: Not implemented. Only for offline mode"); + TTCN_Buffer ip; + ip.put_c(0x45); // Protocol version + ip.put_c(0x02); // Flags + unsigned short l = p_data.lengthof(); + ip.put_c(l >> 8 & 0xFF); // Data length + ip.put_c(l & 0xFF); // Data length + ip.put_c(0x00); ip.put_c(0x00); // Identification + ip.put_c(0x40); ip.put_c(0x00); // Flags (Don't fragment) + ip.put_c(0x40); // TTL + ip.put_c(132); // Protocol is SCTP + OCTETSTRING checksum = int2oct(0, 2); // Checksum + ip.put_s(checksum.lengthof(), static_cast<const unsigned char*>(checksum)); + + int addr = htonl(get_host_id("localhost"/*_params["dst_ip"]*/)); + OCTETSTRING ip_addr = int2oct(addr, 4); // Source address + ip.put_s(ip_addr.lengthof(), static_cast<const unsigned char*>(ip_addr)); + ip_addr = int2oct(addr, 4); // Destination address + ip.put_s(ip_addr.lengthof(), static_cast<const unsigned char*>(ip_addr)); + + OCTETSTRING ip_pdu(ip.get_read_len(), ip.get_data()); + ip_pdu += p_data; + + send_to_all_layers(ip_pdu, static_cast<params&>(p_params)); } void ip_offline_layer::receive_data(OCTETSTRING& p_data, params& p_params) { @@ -70,4 +94,34 @@ void ip_offline_layer::receive_data(OCTETSTRING& p_data, params& p_params) { receive_to_all_layers(data, static_cast<params&>(p_params)); } +unsigned long ip_offline_layer::get_host_id(const std::string& p_host_name) { + loggers::get_instance().log(">>> ip_offline_layer::get_host_id"); + + if (p_host_name.empty()) { + loggers::get_instance().warning("ip_offline_layer::get_host_id: Wrong parameter"); + return INADDR_ANY; + } + + unsigned long ip_addr = 0; + if (p_host_name.compare("255.255.255.255") == 0) { + loggers::get_instance().warning("ip_offline_layer::get_host_id: Host ip is 255.255.255.255"); + ip_addr = 0xffffffff; + } else { + in_addr_t addr = ::inet_addr(p_host_name.c_str()); + if (addr != (in_addr_t)-1) { // host name in XX:XX:XX:XX form + ip_addr = addr; + } else { // host name in domain.com form + struct hostent *hptr; + if ((hptr = ::gethostbyname(p_host_name.c_str())) == 0) { + loggers::get_instance().error("ip_offline_layer::get_host_id: Invalid host name: '%s'", p_host_name.c_str()); + } + ip_addr = *((unsigned long *)hptr->h_addr_list[0]); + } + } + + loggers::get_instance().log("ip_offline_layer::get_host_id: Host name: '%s', Host address: %u", p_host_name.c_str(), ip_addr); + + return htonl(ip_addr); +} + ip_offline_layer_factory ip_offline_layer_factory::_f; diff --git a/ccsrc/Protocols/IP/ip_offline_layer.hh b/ccsrc/Protocols/IP/ip_offline_layer.hh index 3b31a80e65ead80e68f0e39c78835cc775dacde8..352ddbc871f5f3997346fc5d3f85f44b9319eb0d 100644 --- a/ccsrc/Protocols/IP/ip_offline_layer.hh +++ b/ccsrc/Protocols/IP/ip_offline_layer.hh @@ -16,6 +16,9 @@ class ip_offline_layer : public layer { params _params; //! Layer parameters +private: //! \privatesection + unsigned long get_host_id(const std::string& p_host_name); + public: //! \publicsection /*! * \brief Specialised constructor diff --git a/ccsrc/Protocols/Sctp/sctp_offline_layer.cc b/ccsrc/Protocols/Sctp/sctp_offline_layer.cc index c6dbccb7d22bfdf598e312093ab9751e4f3f3d7d..051bdcfa7fe34f503bfbe3b45a778dc51e0c29d7 100644 --- a/ccsrc/Protocols/Sctp/sctp_offline_layer.cc +++ b/ccsrc/Protocols/Sctp/sctp_offline_layer.cc @@ -24,12 +24,44 @@ sctp_offline_layer::~sctp_offline_layer() { void sctp_offline_layer::send_data(OCTETSTRING &p_data, params &p_params) { loggers::get_instance().log_msg(">>> sctp_offline_layer::send_data: ", p_data); + p_params.log(); - //OCTETSTRING sctp; // FIXME FSCOM: To be done - loggers::get_instance().error("sctp_offline_layer::send_data: Not implemented. On;ly for offline mode"); - //sctp += p_data; - //send_to_all_layers(sctp, static_cast<params&>(p_params)); + loggers::get_instance().warning("sctp_offline_layer::send_data: Not implemented. Only for offline mode"); + TTCN_Buffer chunk; + chunk.put_c(0x00); // DATA chunk + chunk.put_c(0x03); // Flags + unsigned short l = p_data.lengthof(); + chunk.put_c(l >> 8 & 0xFF); // Data length + chunk.put_c(l & 0xFF); // Data length + OCTETSTRING tsn = int2oct(0, 4); // Transmission sequence number + chunk.put_s(tsn.lengthof(), static_cast<const unsigned char*>(tsn)); + l = 7; // Stream sequence identifier + chunk.put_c(l >> 8 & 0xFF); // Stream sequence identifier + chunk.put_c(l & 0xFF); // Stream sequence identifier + chunk.put_c(0x00); // Stream sequence number + chunk.put_c(0x00); // Stream sequence number + OCTETSTRING protocol = int2oct(60, 4); // Protocol is NGAP + chunk.put_s(protocol.lengthof(), static_cast<const unsigned char*>(protocol)); + chunk.put_s(p_data.lengthof(), static_cast<const unsigned char*>(p_data)); + // FIXME FSCOM: Add padding + + TTCN_Buffer sctp; + l = 12345; // SCTP Source port + sctp.put_c(l >> 8 & 0xFF); // Stream sequence identifier + sctp.put_c(l & 0xFF); // Stream sequence identifier + l = 12345; // SCTP Destination port + sctp.put_c(l >> 8 & 0xFF); // Stream sequence identifier + sctp.put_c(l & 0xFF); // Stream sequence identifier + OCTETSTRING vt = int2oct(0, 4); // Verification tag + sctp.put_s(vt.lengthof(), static_cast<const unsigned char*>(vt)); + OCTETSTRING checksum = int2oct(0, 4); // Checksum + sctp.put_s(checksum.lengthof(), static_cast<const unsigned char*>(checksum)); + + OCTETSTRING sctp_pdu(sctp.get_read_len(), sctp.get_data()); + sctp_pdu += OCTETSTRING(chunk.get_read_len(), chunk.get_data()); + + send_to_all_layers(sctp_pdu, static_cast<params&>(p_params)); } void sctp_offline_layer::receive_data(OCTETSTRING &p_data, params &p_params) { @@ -104,6 +136,12 @@ void sctp_offline_layer::process_chunk(const OCTETSTRING& p_chunk, params &p_par break; case 0x02: // INIT_ACK chunk break; + case 0x03: // SACK + break; + case 0x04: // HEARTBEAT + break; + case 0x05: // HEARTBEAT_ACK + break; case 0x0a: // COOKIE_ECHO chunk break; case 0x0b: // COOKIE_ACK chunk