Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы / 2 / lab.04.by mice / hail / cdm_hailer
.cpp/*******************************************************************************
* file: cdm_hailer.h *
* version: 0.9.0 *
* author: d-evil [tmd] (mailto:d-evil.tmd@mail.ru) *
* description: not available *
*******************************************************************************/
#include "cdm_hailer.h"
////////////////////////////////////////////////////////////////////////////////
// cdm_hailer public definition
cdm_hailer::cdm_hailer() {
_init();
}
cdm_hailer::~cdm_hailer() {
_free();
}
int cdm_hailer::target(const char *const host, const int pckt_sz) {
if (0 != _iaddr.set_host(host)) return -1;
if (NULL == _iaddr.info()) return -1;
_iaddr.set_port(0);
if (0 >= pckt_sz) return -1;
_pckt_sz = pckt_sz;
return 0;
}
int cdm_hailer::link() {
if (INVALID_SOCKET == _sock) closesocket(_sock);
_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (INVALID_SOCKET == _sock) return -1;
if (0 != connect(_sock, _iaddr.info()->ai_addr, (int)_iaddr.info()->ai_addrlen)) return -1;
return 0;
}
int cdm_hailer::can_read(const int timeout_ms) {
fd_set set;
set.fd_count = 1;
set.fd_array[0] = _sock;
timeval to;
to.tv_sec = 0;
to.tv_usec = timeout_ms * 1000;
int rev = select(0, &set, NULL, NULL, &to);
switch (rev) {
case SOCKET_ERROR: return -1;
case 0: return 0;
default: return 1;
}
return -1; // dummy return
}
int cdm_hailer::hail_it(const int num) {
memset(_snd_buf, 0, MX_BUF_SZ);
icmp_h *h = (icmp_h *)_snd_buf;
h->type = ICMP_ECHO;
h->code = 0;
h->num = num;
h->id = _id;
int len = _pckt_sz + sizeof(icmp_h);
char *data = _snd_buf + sizeof(icmp_h);
*(clock_t *)data = clock();
h->check_sum = in_cksum((unsigned short *)_snd_buf, len);
int ds = send(_sock, _snd_buf, len, 0);
if (ds != len) return -1;
return 0;
}
int cdm_hailer::listen_it(const int timeout) {
if (0 >= can_read(timeout)) return -1;
int dr = recv(_sock, _rcv_buf, MX_BUF_SZ, 0);
if (0 > dr) return -1;
ip_h *hip = (ip_h *)_rcv_buf;
icmp_h *h = (icmp_h *)(_rcv_buf + sizeof(ip_h));
if (h->id != _id) return -1;
if (NULL == _hail_res) _hail_res = new sdm_hail_res;
_hail_res->ttl = ((ip_h *)_rcv_buf)->ttl;
clock_t st = *(clock_t *)(_rcv_buf + sizeof(ip_h) + sizeof(icmp_h));
_hail_res->rtime = clock() - st;
_hail_res->num = h->num;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// cdm_hailer protected definition
int cdm_hailer::_init() {
_sock = INVALID_SOCKET;
_hail_res = NULL;
_pckt_sz = DEF_PCKT_SZ;
_id = (unsigned short)GetProcessId(GetCurrentProcess());
_snd_buf = (char *)malloc(MX_BUF_SZ);
_rcv_buf = (char *)malloc(MX_BUF_SZ);
if (NULL == _snd_buf || NULL == _rcv_buf) return -1;
return 0;
}
int cdm_hailer::_free() {
if (INVALID_SOCKET != _sock) closesocket(_sock);
if (NULL != _hail_res) delete _hail_res;
free(_snd_buf);
free(_rcv_buf);
return 0;
}
Соседние файлы в папке hail