Newer
Older
#include <netdb.h>
#include <arpa/inet.h>
#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);
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));
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
}
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<const uint8_t>(*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<const uint8_t *>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: dsf: ", dsf);
// Total Length
OCTETSTRING total_length = OCTETSTRING(2, 2 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: total_length: ", total_length);
// Identification
OCTETSTRING id = OCTETSTRING(2, 4 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: id: ", id);
// Flags
OCTETSTRING flags = OCTETSTRING(2, 6 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: id: ", flags);
// TTL
OCTETSTRING ttl = OCTETSTRING(1, 8 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: ttl: ", ttl);
// Protocol
OCTETSTRING protocol = OCTETSTRING(1, 9 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: protocol: ", protocol);
// checksum
OCTETSTRING checksum = OCTETSTRING(2, 10 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: checksum: ", checksum);
// src
OCTETSTRING src = OCTETSTRING(4, 12 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: src: ", src);
// dst
OCTETSTRING dst = OCTETSTRING(4, 16 + static_cast<const uint8_t*>(p_data));
loggers::get_instance().log_msg("ip_offline_layer::receive_data: dst: ", dst);
OCTETSTRING data = OCTETSTRING(p_data.lengthof() - length, length + static_cast<const uint8_t *>(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<std::string, std::string>(params::ip_dst, std::string(static_cast<const char *>(s))));
s = oct2str(src);
p_params.insert(std::pair<std::string, std::string>(params::ip_src, std::string(static_cast<const char *>(s))));
s = oct2str(protocol);
p_params.insert(std::pair<std::string, std::string>(params::ip_proto, std::string(static_cast<const char *>(s))));
receive_to_all_layers(data, static_cast<params&>(p_params));
}
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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;