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 isRunningRecver(false),
30 isRunningSender(false),
35 pthread_mutex_init(&mutex, NULL);
37 //-----------------------------------------------------------------------------
38 STG_PINGER::~STG_PINGER()
40 pthread_mutex_destroy(&mutex);
42 //-----------------------------------------------------------------------------
43 int STG_PINGER::Start()
45 struct protoent *proto = NULL;
46 proto = getprotobyname("ICMP");
47 sendSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
48 recvSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
50 pid = (int) getpid() % 65535;
51 if (sendSocket < 0 || recvSocket < 0)
53 errorStr = "Cannot create socket.";
57 if (pthread_create(&sendThread, NULL, RunSendPing, this))
59 errorStr = "Cannot create send thread.";
63 if (pthread_create(&recvThread, NULL, RunRecvPing, this))
65 errorStr = "Cannot create recv thread.";
71 //-----------------------------------------------------------------------------
72 int STG_PINGER::Stop()
78 //5 seconds to thread stops itself
80 for (i = 0; i < 25; i++)
83 SendPing(0x0100007f);//127.0.0.1
91 //after 5 seconds waiting thread still running. now killing it
94 //if (pthread_kill(recvThread, SIGINT))
96 errorStr = "Cannot kill thread.";
99 //printf("recvThread killed\n");
105 //5 seconds to thread stops itself
107 for (i = 0; i < 25; i++)
109 if (!isRunningSender)
115 //after 5 seconds waiting thread still running. now killing it
118 //if (pthread_kill(sendThread, SIGINT))
120 errorStr = "Cannot kill thread.";
123 //printf("sendThread killed\n");
130 //-----------------------------------------------------------------------------
131 void STG_PINGER::AddIP(uint32_t ip)
133 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
135 ipToAdd.push_back(ip);
137 //-----------------------------------------------------------------------------
138 void STG_PINGER::DelIP(uint32_t ip)
140 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
142 ipToDel.push_back(ip);
144 //-----------------------------------------------------------------------------
145 void STG_PINGER::RealAddIP()
147 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
149 list<uint32_t>::iterator iter;
150 iter = ipToAdd.begin();
151 while (iter != ipToAdd.end())
153 /*packets.insert(pair<RAW_PACKET, PACKET_EXTRA_DATA>(rawPacket, ed));*/
155 pingIP.insert(pair<uint32_t, time_t>(*iter, 0));
158 ipToAdd.erase(ipToAdd.begin(), ipToAdd.end());
160 //-----------------------------------------------------------------------------
161 void STG_PINGER::RealDelIP()
163 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
165 list<uint32_t>::iterator iter;
166 multimap<uint32_t, time_t>::iterator treeIter;
167 iter = ipToDel.begin();
168 while (iter != ipToDel.end())
170 treeIter = pingIP.find(*iter);
171 //printf("Found %X\n", *iter);
172 if (treeIter != pingIP.end())
173 pingIP.erase(treeIter);
177 ipToDel.erase(ipToDel.begin(), ipToDel.end());
179 //-----------------------------------------------------------------------------
180 int STG_PINGER::GetPingIPNum() const
182 return pingIP.size();
184 //-----------------------------------------------------------------------------
185 /*void STG_PINGER::GetAllIP(vector<PING_IP_TIME> *) const
187 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
189 //-----------------------------------------------------------------------------
190 void STG_PINGER::PrintAllIP()
192 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
193 multimap<uint32_t, time_t>::iterator iter;
194 iter = pingIP.begin();
195 while (iter != pingIP.end())
197 uint32_t ip = iter->first;
198 time_t t = iter->second;
201 printf("ip = %s, time = %9s\n", inet_ntostring(ip).c_str(), s.c_str());
206 //-----------------------------------------------------------------------------
207 int STG_PINGER::GetIPTime(uint32_t ip, time_t * t) const
209 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
210 multimap<uint32_t, time_t>::const_iterator treeIter;
212 treeIter = pingIP.find(ip);
213 if (treeIter == pingIP.end())
216 *t = treeIter->second;
219 //-----------------------------------------------------------------------------
220 void STG_PINGER::SetDelayTime(time_t d)
224 //-----------------------------------------------------------------------------
225 time_t STG_PINGER::GetDelayTime() const
229 //-----------------------------------------------------------------------------
230 string STG_PINGER::GetStrError() const
234 //-----------------------------------------------------------------------------
235 uint16_t STG_PINGER::PingCheckSum(void * data, int len)
237 unsigned short * buf = (unsigned short *)data;
238 unsigned int sum = 0;
239 unsigned short result;
241 for ( sum = 0; len > 1; len -= 2 )
245 sum += *(unsigned char*)buf;
247 sum = (sum >> 16) + (sum & 0xFFFF);
252 //-----------------------------------------------------------------------------
253 int STG_PINGER::SendPing(uint32_t ip)
255 struct sockaddr_in addr;
256 //printf("SendPing %X \n", ip);
257 memset(&addr, 0, sizeof(addr));
258 addr.sin_family = AF_INET;
260 addr.sin_addr.s_addr = ip;
262 memset(&pmSend, 0, sizeof(pmSend));
263 pmSend.hdr.type = ICMP_ECHO;
264 pmSend.hdr.un.echo.id = pid;
265 memcpy(pmSend.msg, &ip, sizeof(ip));
267 pmSend.hdr.checksum = PingCheckSum(&pmSend, sizeof(pmSend));
269 if (sendto(sendSocket, &pmSend, sizeof(pmSend), 0, (sockaddr *)&addr, sizeof(addr)) <= 0 )
271 errorStr = "Send ping error: " + string(strerror(errno));
278 //-----------------------------------------------------------------------------
279 uint32_t STG_PINGER::RecvPing()
281 struct sockaddr_in addr;
285 memset(buf, 0, sizeof(buf));
287 socklen_t len = sizeof(addr);
289 bytes = recvfrom(recvSocket, &buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
290 //printf("recvfrom\n");
293 struct IP_HDR * ip = (struct IP_HDR *)buf;
294 struct ICMP_HDR *icmp = (struct ICMP_HDR *)(buf + ip->ihl * 4);
296 //printf("icmp->un.echo.id=%d, pid=%d, tid: %d\n", icmp->un.echo.id, pid);
297 if (icmp->un.echo.id != pid)
300 ipAddr = *(uint32_t*)(buf + sizeof(ICMP_HDR) + ip->ihl * 4);
305 //-----------------------------------------------------------------------------
306 void * STG_PINGER::RunSendPing(void * d)
308 STG_PINGER * pinger = (STG_PINGER*)d;
310 pinger->isRunningSender = true;
312 while (pinger->nonstop)
317 multimap<uint32_t, time_t>::iterator iter;
318 iter = pinger->pingIP.begin();
319 while (iter != pinger->pingIP.end())
321 uint32_t ip = iter->first;
322 pinger->SendPing(ip);
332 currTime = lastPing = time(NULL);
335 while (currTime - lastPing < pinger->delay && pinger->nonstop)
340 currTime = time(NULL);
344 //printf("new ping cycle\n");
347 pinger->isRunningSender = false;
351 //-----------------------------------------------------------------------------
352 void * STG_PINGER::RunRecvPing(void * d)
354 STG_PINGER * pinger = (STG_PINGER*)d;
356 pinger->isRunningRecver = true;
359 multimap<uint32_t, time_t>::iterator treeIterLower;
360 multimap<uint32_t, time_t>::iterator treeIterUpper;
362 while (pinger->nonstop)
364 ip = pinger->RecvPing();
368 //printf("RecvPing %X\n", ip);
369 treeIterUpper = pinger->pingIP.upper_bound(ip);
370 treeIterLower = pinger->pingIP.lower_bound(ip);
372 while (treeIterUpper != treeIterLower)
373 //treeIterUpper = pinger->pingIP.find(ip);
374 //if (treeIterUpper != pinger->pingIP.end())
376 //printf("+++! time=%d %X i=%d !+++\n", time(NULL), ip, i);
377 //printf("--- time=%d ---\n", time(NULL));
379 treeIterLower->second = stgTime;
381 treeIterLower->second = time(NULL);
389 pinger->isRunningRecver = false;
392 //-----------------------------------------------------------------------------