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 //-----------------------------------------------------------------------------