#include #include #include "ip_offline_layer_factory.hh" #include "loggers.hh" ip_offline_layer::ip_offline_layer(const std::string& p_type, const std::string& p_param) : layer(p_type), _params() { loggers::get_instance().log(">>> ip_offline_layer::ip_offline_layer: '%s', %s", to_string().c_str(), p_param.c_str()); // Setup parameters params::convert(_params, p_param); } 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(); // FIXME FSCOM: To be done 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(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(ip_addr)); ip_addr = int2oct(addr, 4); // Destination address ip.put_s(ip_addr.lengthof(), static_cast(ip_addr)); OCTETSTRING ip_pdu(ip.get_read_len(), ip.get_data()); ip_pdu += p_data; send_to_all_layers(ip_pdu, static_cast(p_params)); } void ip_offline_layer::receive_data(OCTETSTRING& p_data, params& p_params) { loggers::get_instance().log_msg(">>> ip_offline_layer::receive_data: ", p_data); // Version uint8_t v = static_cast(*p_data); OCTETSTRING version = int2oct(1, v >> 4); loggers::get_instance().log_msg("ip_offline_layer::receive_data: verion: ", version); // Length in bytes uint8_t length = (v & 0x0f) * 4; loggers::get_instance().log("ip_offline_layer::receive_data: length: %d", length); // DSF OCTETSTRING dsf = OCTETSTRING(1, 1 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: dsf: ", dsf); // Total Length OCTETSTRING total_length = OCTETSTRING(2, 2 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: total_length: ", total_length); // Identification OCTETSTRING id = OCTETSTRING(2, 4 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: id: ", id); // Flags OCTETSTRING flags = OCTETSTRING(2, 6 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: id: ", flags); // TTL OCTETSTRING ttl = OCTETSTRING(1, 8 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: ttl: ", ttl); // Protocol OCTETSTRING protocol = OCTETSTRING(1, 9 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: protocol: ", protocol); // checksum OCTETSTRING checksum = OCTETSTRING(2, 10 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: checksum: ", checksum); // src OCTETSTRING src = OCTETSTRING(4, 12 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: src: ", src); // dst OCTETSTRING dst = OCTETSTRING(4, 16 + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: dst: ", dst); OCTETSTRING data = OCTETSTRING(p_data.lengthof() - length, length + static_cast(p_data)); loggers::get_instance().log_msg("ip_offline_layer::receive_data: payload for upper layer:", data); // Update params CHARSTRING s = oct2str(dst); p_params.insert(std::pair(params::ip_dst, std::string(static_cast(s)))); s = oct2str(src); p_params.insert(std::pair(params::ip_src, std::string(static_cast(s)))); s = oct2str(protocol); p_params.insert(std::pair(params::ip_proto, std::string(static_cast(s)))); receive_to_all_layers(data, static_cast(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;