6 #include <sys/socket.h>
 
   7 #include <netinet/in.h>
 
  19 #include "stg_locker.h"
 
  22 extern volatile time_t stgTime;
 
  25 //-----------------------------------------------------------------------------
 
  26 STG_PINGER::STG_PINGER(time_t d)
 
  29     pthread_mutex_init(&mutex, NULL);
 
  32 //-----------------------------------------------------------------------------
 
  33 STG_PINGER::~STG_PINGER()
 
  35     pthread_mutex_destroy(&mutex);
 
  37 //-----------------------------------------------------------------------------
 
  38 int STG_PINGER::Start()
 
  40     struct protoent *proto = NULL;
 
  41     proto = getprotobyname("ICMP");
 
  42     sendSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
 
  43     recvSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
 
  45     pid = (int) getpid() % 65535;
 
  46     if (sendSocket < 0 || recvSocket < 0)
 
  48         errorStr = "Cannot create socket.";
 
  52     if (pthread_create(&sendThread, NULL, RunSendPing, this))
 
  54         errorStr = "Cannot create send thread.";
 
  58     if (pthread_create(&recvThread, NULL, RunRecvPing, this))
 
  60         errorStr = "Cannot create recv thread.";
 
  66 //-----------------------------------------------------------------------------
 
  67 int STG_PINGER::Stop()
 
  73         //5 seconds to thread stops itself
 
  75         for (i = 0; i < 25; i++)
 
  78                 SendPing(0x0100007f);//127.0.0.1
 
  86         //after 5 seconds waiting thread still running. now killing it
 
  89             //if (pthread_kill(recvThread, SIGINT))
 
  91                 errorStr = "Cannot kill thread.";
 
  94             //printf("recvThread killed\n");
 
 100         //5 seconds to thread stops itself
 
 102         for (i = 0; i < 25; i++)
 
 104             if (!isRunningSender)
 
 110         //after 5 seconds waiting thread still running. now killing it
 
 113             //if (pthread_kill(sendThread, SIGINT))
 
 115                 errorStr = "Cannot kill thread.";
 
 118             //printf("sendThread killed\n");
 
 125 //-----------------------------------------------------------------------------
 
 126 void STG_PINGER::AddIP(uint32_t ip)
 
 128     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 130     ipToAdd.push_back(ip);
 
 132 //-----------------------------------------------------------------------------
 
 133 void STG_PINGER::DelIP(uint32_t ip)
 
 135     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 137     ipToDel.push_back(ip);
 
 139 //-----------------------------------------------------------------------------
 
 140 void STG_PINGER::RealAddIP()
 
 142     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 144     list<uint32_t>::iterator iter;
 
 145     iter = ipToAdd.begin();
 
 146     while (iter != ipToAdd.end())
 
 148         /*packets.insert(pair<RAW_PACKET, PACKET_EXTRA_DATA>(rawPacket, ed));*/
 
 150         pingIP.insert(pair<uint32_t, time_t>(*iter, 0));
 
 153     ipToAdd.erase(ipToAdd.begin(), ipToAdd.end());
 
 155 //-----------------------------------------------------------------------------
 
 156 void STG_PINGER::RealDelIP()
 
 158     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 160     list<uint32_t>::iterator iter;
 
 161     multimap<uint32_t, time_t>::iterator treeIter;
 
 162     iter = ipToDel.begin();
 
 163     while (iter != ipToDel.end())
 
 165         treeIter = pingIP.find(*iter);
 
 166         //printf("Found %X\n", *iter);
 
 167         if (treeIter != pingIP.end())
 
 168             pingIP.erase(treeIter);
 
 172     ipToDel.erase(ipToDel.begin(), ipToDel.end());
 
 174 //-----------------------------------------------------------------------------
 
 175 int STG_PINGER::GetPingIPNum()
 
 177     return pingIP.size();
 
 179 //-----------------------------------------------------------------------------
 
 180 void STG_PINGER::GetAllIP(vector<PING_IP_TIME> *)
 
 182     //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 184 //-----------------------------------------------------------------------------
 
 185 void STG_PINGER::PrintAllIP()
 
 187     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 188     multimap<uint32_t, time_t>::iterator iter;
 
 189     iter = pingIP.begin();
 
 190     while (iter != pingIP.end())
 
 192         uint32_t ip = iter->first;
 
 193         time_t t = iter->second;
 
 196         printf("ip = %s, time = %9s\n", inet_ntostring(ip).c_str(), s.c_str());
 
 201 //-----------------------------------------------------------------------------
 
 202 int STG_PINGER::GetIPTime(uint32_t ip, time_t * t)
 
 204     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 205     multimap<uint32_t, time_t>::iterator treeIter;
 
 207     treeIter = pingIP.find(ip);
 
 208     if (treeIter == pingIP.end())
 
 211     *t = treeIter->second;
 
 214 //-----------------------------------------------------------------------------
 
 215 void STG_PINGER::SetDelayTime(time_t d)
 
 219 //-----------------------------------------------------------------------------
 
 220 time_t STG_PINGER::GetDelayTime()
 
 224 //-----------------------------------------------------------------------------
 
 225 string STG_PINGER::GetStrError()
 
 229 //-----------------------------------------------------------------------------
 
 230 uint16_t STG_PINGER::PingCheckSum(void * data, int len)
 
 232     unsigned short * buf = (unsigned short *)data;
 
 233     unsigned int sum = 0;
 
 234     unsigned short result;
 
 236     for ( sum = 0; len > 1; len -= 2 )
 
 240         sum += *(unsigned char*)buf;
 
 242     sum = (sum >> 16) + (sum & 0xFFFF);
 
 247 //-----------------------------------------------------------------------------
 
 248 int STG_PINGER::SendPing(uint32_t ip)
 
 250     struct sockaddr_in addr;
 
 251     //printf("SendPing %X \n", ip);
 
 252     memset(&addr, 0, sizeof(addr));
 
 253     addr.sin_family = AF_INET;
 
 255     addr.sin_addr.s_addr = ip;
 
 257     memset(&pmSend, 0, sizeof(pmSend));
 
 258     pmSend.hdr.type = ICMP_ECHO;
 
 259     pmSend.hdr.un.echo.id = pid;
 
 260     memcpy(pmSend.msg, &ip, sizeof(ip));
 
 262     pmSend.hdr.checksum = PingCheckSum(&pmSend, sizeof(pmSend));
 
 264     if (sendto(sendSocket, &pmSend, sizeof(pmSend), 0, (sockaddr *)&addr, sizeof(addr)) <= 0 )
 
 266         errorStr = "Send ping error: " + string(strerror(errno));
 
 273 //-----------------------------------------------------------------------------
 
 274 uint32_t STG_PINGER::RecvPing()
 
 276     struct sockaddr_in addr;
 
 280     memset(buf, 0, sizeof(buf));
 
 282     socklen_t len = sizeof(addr);
 
 284     bytes = recvfrom(recvSocket, &buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
 
 285     //printf("recvfrom\n");
 
 288         struct IP_HDR * ip = (struct IP_HDR *)buf;
 
 289         struct ICMP_HDR *icmp = (struct ICMP_HDR *)(buf + ip->ihl * 4);
 
 291         //printf("icmp->un.echo.id=%d,  pid=%d, tid: %d\n", icmp->un.echo.id, pid);
 
 292         if (icmp->un.echo.id != pid)
 
 295         ipAddr = *(uint32_t*)(buf + sizeof(ICMP_HDR) + ip->ihl * 4);
 
 300 //-----------------------------------------------------------------------------
 
 301 void * STG_PINGER::RunSendPing(void * d)
 
 303     STG_PINGER * pinger = (STG_PINGER*)d;
 
 305     pinger->isRunningSender = true;
 
 307     while (pinger->nonstop)
 
 312         multimap<uint32_t, time_t>::iterator iter;
 
 313         iter = pinger->pingIP.begin();
 
 314         while (iter != pinger->pingIP.end())
 
 316             uint32_t ip = iter->first;
 
 317             pinger->SendPing(ip);
 
 327         currTime = lastPing = time(NULL);
 
 330         while (currTime - lastPing < pinger->delay && pinger->nonstop)
 
 335             currTime = time(NULL);
 
 339         //printf("new ping cycle\n");
 
 342     pinger->isRunningSender = false;
 
 346 //-----------------------------------------------------------------------------
 
 347 void * STG_PINGER::RunRecvPing(void * d)
 
 349     STG_PINGER * pinger = (STG_PINGER*)d;
 
 351     pinger->isRunningRecver = true;
 
 354     multimap<uint32_t, time_t>::iterator treeIterLower;
 
 355     multimap<uint32_t, time_t>::iterator treeIterUpper;
 
 357     while (pinger->nonstop)
 
 359         ip = pinger->RecvPing();
 
 363             //printf("RecvPing %X\n", ip);
 
 364             treeIterUpper = pinger->pingIP.upper_bound(ip);
 
 365             treeIterLower = pinger->pingIP.lower_bound(ip);
 
 367             while (treeIterUpper != treeIterLower)
 
 368             //treeIterUpper = pinger->pingIP.find(ip);
 
 369             //if (treeIterUpper != pinger->pingIP.end())
 
 371                 //printf("+++! time=%d %X i=%d !+++\n", time(NULL), ip, i);
 
 372                 //printf("--- time=%d ---\n", time(NULL));
 
 374                 treeIterLower->second = stgTime;
 
 376                 treeIterLower->second = time(NULL);
 
 384     pinger->isRunningRecver = false;
 
 387 //-----------------------------------------------------------------------------