diff options
Diffstat (limited to 'src/lbtest_icmp.cc')
-rw-r--r-- | src/lbtest_icmp.cc | 128 |
1 files changed, 49 insertions, 79 deletions
diff --git a/src/lbtest_icmp.cc b/src/lbtest_icmp.cc index c032b42..645aeed 100644 --- a/src/lbtest_icmp.cc +++ b/src/lbtest_icmp.cc @@ -11,6 +11,7 @@ #include <sys/sysinfo.h> #include <unistd.h> #include <sys/socket.h> +#include <netdb.h> #include <netinet/udp.h> #include <netinet/in.h> #include <netinet/ip.h> @@ -25,7 +26,6 @@ #include <iostream> #include <string> #include <algorithm> - #include "lbdata.hh" #include "lbtest_icmp.hh" @@ -40,52 +40,10 @@ using namespace std; void ICMPEngine::init() { - _results.erase(_results.begin(),_results.end()); - if (_initialized == true) { - return; - } - _initialized = true; if (_debug) { cout << "LBTestICMP::init(): initializing test system" << endl; } - - struct protoent *ppe = getprotobyname("icmp"); - _send_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); - if (_send_sock < 0){ - if (_debug) { - cerr << "LBTestICMP::LBTestICMP(): no send sock: " << _send_sock << endl; - } - syslog(LOG_ERR, "wan_lb: failed to acquired socket"); - _send_sock = 0; - return; - } - - //set options for broadcasting. - int val = 1; - setsockopt(_send_sock, SOL_SOCKET, SO_BROADCAST, &val, 4); - setsockopt(_send_sock, SOL_SOCKET, SO_REUSEADDR, &val, 4); - - struct sockaddr_in addr; - memset( &addr, 0, sizeof( struct sockaddr_in )); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); - addr.sin_port = 0; - - _recv_sock = socket(PF_INET, SOCK_RAW, ppe->p_proto); - if (_recv_sock < 0) { - if (_debug) { - cerr << "LBTestICMP::LBTestICMP(): no recv sock: " << _recv_sock << endl; - } - syslog(LOG_ERR, "wan_lb: failed to acquired socket"); - _recv_sock = 0; - return; - } - if (bind(_recv_sock, (struct sockaddr*)&addr, sizeof(addr))==-1) { - if (_debug) { - cerr << "failed on bind" << endl; - } - syslog(LOG_ERR, "wan_lb: failed to bind recv sock"); - } + _results.erase(_results.begin(),_results.end()); } /** @@ -114,7 +72,7 @@ ICMPEngine::process(LBHealth &health,LBTestICMP *data) cout << "LBTestICMP::start(): sending ping test for: " << health._interface << " for " << target << endl; } _packet_id = ++_packet_id % 32767; - send(health._interface, target, _packet_id); + send(data->_send_icmp_sock, health._interface, target, _packet_id); _results.insert(pair<int,PktData>(_packet_id,PktData(health._interface,-1))); } @@ -127,6 +85,10 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data) { struct timeval send_time; gettimeofday(&send_time,NULL); + + if (_results.empty() == true) { + return -1; + } //use gettimeofday to calculate time to millisecond //then iterate over recv socket and receive and record @@ -137,10 +99,11 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data) unsigned long timeout = si.uptime + 5; //seconds unsigned long cur_time = si.uptime; while (cur_time < timeout) { - int id = receive(); + int id = receive(data->_recv_icmp_sock); if (_debug) { cout << "LBTestICMP::start(): " << id << endl; } + //update current time for comparison struct sysinfo si; sysinfo(&si); @@ -162,9 +125,11 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data) //time in milliseconds below int rtt = abs(msecs) / 1000 + 1000 * secs; if (rtt < data->_resp_time) { - return rtt; + data->_state = LBTest::K_SUCCESS; + return rtt; } else { + data->_state = LBTest::K_FAILURE; return -1; } _results.erase(r_iter); @@ -174,20 +139,16 @@ ICMPEngine::recv(LBHealth &health,LBTestICMP *data) if (_debug) { cout << "LBTestICMP::start(): finished heath test" << endl; } + data->_state = LBTest::K_FAILURE; return -1; } - - - - - /** * * **/ void -ICMPEngine::send(const string &iface, const string &target_addr, int packet_id) +ICMPEngine::send(int send_sock, const string &iface, const string &target_addr, int packet_id) { int err; sockaddr_in taddr; @@ -200,12 +161,6 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id) return; } - // bind a socket to a device name (might not work on all systems): - if (setsockopt(_send_sock, SOL_SOCKET, SO_BINDTODEVICE, iface.c_str(), iface.size()) != 0) { - syslog(LOG_ERR, "wan_lb: failure to bind to interface: %s", iface.c_str()); - return; //will allow the test to time out then - } - //convert target_addr to ip addr struct hostent *h = gethostbyname(target_addr.c_str()); if (h == NULL) { @@ -216,6 +171,12 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id) return; } + // bind a socket to a device name (might not work on all systems): + if (setsockopt(send_sock, SOL_SOCKET, SO_BINDTODEVICE, iface.c_str(), iface.size()) != 0) { + syslog(LOG_ERR, "wan_lb: failure to bind to interface: %s", iface.c_str()); + return; //will allow the test to time out then + } + icmp_hdr = (struct icmphdr *)buffer; icmp_hdr->type = ICMP_ECHO; icmp_hdr->code = 0; @@ -250,12 +211,11 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id) bzero(&(taddr.sin_zero), 8); //need to direct this packet out a specific interface!!!!!!!!!!!!! - err = sendto(_send_sock, buffer, icmp_pktsize, 0, (struct sockaddr*)&taddr, sizeof(taddr)); + err = sendto(send_sock, buffer, icmp_pktsize, 0, (struct sockaddr*)&taddr, sizeof(taddr)); if (_debug) { cout << "LBTestICMP::send(): sendto: " << err << ", packet id: " << packet_id << endl; } - if(err < 0) - { + if(err < 0) { if (_debug) { if (errno == EBADF) cout << "EBADF" << endl; @@ -293,7 +253,7 @@ ICMPEngine::send(const string &iface, const string &target_addr, int packet_id) * **/ int -ICMPEngine::receive() +ICMPEngine::receive(int recv_sock) { int icmp_pktsize = 40; char resp_buf[icmp_pktsize]; @@ -303,7 +263,7 @@ ICMPEngine::receive() int ret; FD_ZERO(&readfs); - FD_SET(_recv_sock, &readfs); + FD_SET(recv_sock, &readfs); wait_time.tv_usec = 0; wait_time.tv_sec = 3; //3 second timeout @@ -312,27 +272,25 @@ ICMPEngine::receive() cout << "LBTestICMP::receive(): start" << endl; } - while (select(_recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0) + while (select(recv_sock+1, &readfs, NULL, NULL, &wait_time) != 0) { - ret = ::recv(_recv_sock, &resp_buf, icmp_pktsize, 0); - if (ret != -1) - { + ret = ::recv(recv_sock, &resp_buf, icmp_pktsize, 0); + if (ret != -1) { if (_debug) { cout << "LBTestICMP::receive(): recv: " << ret << endl; } - + icmp_hdr = (struct icmphdr *)(resp_buf + sizeof(iphdr)); - if (icmp_hdr->type == ICMP_ECHOREPLY) - { + if (icmp_hdr->type == ICMP_ECHOREPLY) { + //process packet data + char* data; + int id = 0; + data = (char*)(&resp_buf) + 36; + memcpy(&id, data, sizeof(unsigned short)); if (_debug) { - cout << "LBTestICMP::receive(): " << endl; + cout << "LBTestICMP::receive(): " << id << endl; } - //process packet data - char* data; - int id = 0; - data = (char*)(&resp_buf) + 36; - memcpy(&id, data, sizeof(unsigned short)); - return id; + return id; } } } @@ -347,10 +305,22 @@ unsigned short ICMPEngine::in_checksum(const unsigned short *buffer, int length) const { unsigned long sum; - for (sum=0; length>0; length--) + for (sum=0; length>0; length--) { sum += *buffer++; + } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return ~sum; } +/** + * + * + **/ +string +LBTestICMP::dump() +{ + char buf[20]; + sprintf(buf,"%u",_resp_time); + return (string("target: ") + _target + ", resp_time: " + buf); +} |