玩了hostmonitor,老外写的很好。但是不符合国情,只有邮件适合发送。

今天用python 写一个自动发现ip,ping失败报警的程序。(微信和邮件报警)

以前用python写的发微信,发邮件直接导入即可。

# -*- coding: utf-8 -*-
# ping for Windows import os
import sys
import socket
import struct
import select
import time
import ConfigParser
import weixin
import mail class getcfg(object):
def __init__(self,filename):
self.filename=filename
self.cfg=ConfigParser.ConfigParser()
self.cfg.read(self.filename)
#self.allip=self.cfg.items('allip')
self.retry=self.cfg.get('rule','retry')
self.timeout=self.cfg.get('rule','timeout')
self.reload=self.cfg.get('rule','next_check')
self.scan=self.cfg.items('scan_network')
self.mailto=self.cfg.items('mail','mail_to') #发送邮件报警
def sendmessage(self,failip):
weixin.sendMessage('@all','ping %s failed.'% failip)
for key,value in self.mailto:
mail.send(value,"ping %s failed." % failip,'python ping fail') #判断要扫描ip
def scan_network(self):
self.scan.sort()
allip=self.cfg.items('allip')
i=0
while i < len(self.scan):
ipbegin=int(self.scan[i][1].split('.')[-1])
ipend=int(self.scan[i+1][1])+1
for x in range(ipbegin,ipend):
ipvalue=self.scan[i][1].split('.')[0]+'.'+self.scan[i][1].split('.')[1]+'.'+self.scan[i][1].split('.')[2]+'.'+str(x)
ip_dict=[]
for k,v in allip:
ip_dict.append(v)
if ipvalue in ip_dict:
pass
else:
#执行扫描
self.to_ping(ipvalue,int(self.timeout))
i=i+2 #执行扫描
def to_ping(self,ip_addr,timeout):
print 'scan ip ' + ip_addr,
try:
delay = ping(self.filename).ping_once(ip_addr, timeout)
if delay == None:
print 'failed. (timeout within %s second.)' % timeout
else:
print 'get reply in %0.4f ms' % (delay * 1000)
self.scan_resule(ip_addr)
except socket.gaierror, e:
print "failed. (socket error: '%s')" % e[1] #判断扫描结果,如果有新扫描到的ip则保存到配置文件
def scan_resule(self,ip_addr):
allip=self.cfg.items('allip')
ip_dict=[]
for k,v in allip:
ip_dict.append(v)
if ip_addr in ip_dict:
pass
else:
self.cfg_write(ip_addr) #保存扫描到的ip到配置文件
def cfg_write(self,ipvalue):
ipkey='auto_'+str(time.time())
self.cfg.set('allip',ipkey,ipvalue)
self.cfg.write(open('ping_monitor.txt','w')) #去执行ping类
def to_ping(self):
allip=self.cfg.items('allip')
for k,v in allip:
if len(v) >0:
ping(self.filename).icmp_ping(v,int(self.timeout),int(self.retry)) #下次执行扫描时间
def next_check(self):
while True:
self.to_ping()
print('------------------------------------------------------------')
nextcheck=0
while nextcheck < int(self.reload):
sys.stdout.write('next check %s second\r' % (int(self.reload)-nextcheck))
sys.stdout.flush()
time.sleep(1)
nextcheck=nextcheck+1
self.scan_network()
print('------------------------------------------------------------') class ping(object):
def __init__(self,filename):
self.ICMP_ECHO_REQUEST = 8
self.filename=filename def receive_ping(self,my_socket, ID, timeout):
start_time = timeout
while True:
start_select = time.clock()
what_ready = select.select([my_socket], [], [], start_time)
how_long = (time.clock() - start_select)
if what_ready[0] == []: #timeout
return time_received = time.clock()
rec_packet, addr = my_socket.recvfrom(1024)
icmp_header = rec_packet[20 : 28]
ip_type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", icmp_header)
if ip_type != 8 and packet_ID == ID: # ip_type should be 0
byte_in_double = struct.calcsize("d")
time_sent = struct.unpack("d", rec_packet[28 : 28 + byte_in_double])[0]
return time_received - time_sent start_time = start_time - how_long
if start_time <= 0:
return def get_checksum(self,source):
checksum = 0
count = (len(source) / 2) * 2
i = 0
while i < count:
temp = ord(source[i + 1]) * 256 + ord(source[i]) # 256 = 2^8
checksum = checksum + temp
checksum = checksum & 0xffffffff # 4,294,967,296 (2^32)
i = i + 2 if i < len(source):
checksum = checksum + ord(source[len(source) - 1])
checksum = checksum & 0xffffffff # 32-bit to 16-bit
checksum = (checksum >> 16) + (checksum & 0xffff)
checksum = checksum + (checksum >> 16)
answer = ~checksum
answer = answer & 0xffff # why? ans[9:16 1:8]
answer = answer >> 8 | (answer << 8 & 0xff00)
return answer def send_ping(self,my_socket, ip_addr, ID):
ip = socket.gethostbyname(ip_addr) my_checksum = 0 header = struct.pack('bbHHh', self.ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
byte_in_double = struct.calcsize("d") # C type: double
data = (192 - byte_in_double) * "P" # any char is OK, any length is OK
data = struct.pack("d", time.clock()) + data my_checksum = self.get_checksum(header + data) header = struct.pack("bbHHh", self.ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1)
packet = header + data
my_socket.sendto(packet, (ip, 80)) # it seems that 0~65535 is OK (port?) def ping_once(self,ip_addr, timeout):
icmp = socket.getprotobyname('icmp')
try:
my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
except socket.error:
raise my_ID = os.getpid() & 0xFFFF self.send_ping(my_socket, ip_addr, my_ID)
delay = self.receive_ping(my_socket, my_ID, timeout) my_socket.close()
return delay def icmp_ping(self,ip_addr,timeout,count):
number=1
for i in range(count):
print 'ping ' + ip_addr,
try:
delay = self.ping_once(ip_addr, timeout)
if delay == None:
print 'failed. (timeout within %s second.)' % timeout
if number==count:
print('The request has failed %s times,Email alerts are being sent' % count)
getcfg(self.filename).sendmessage(ip_addr)
else:
print 'get reply in %0.4f ms' % (delay * 1000)
break
except socket.gaierror, e:
print "failed. (socket error: '%s')" % e[1]
break
number=number+1 if __name__ == '__main__':
weixin=weixin.WeChat()
mail=mail.sendmail()
cfgname='ping_monitor.txt'
ping(cfgname)
pingcfg=getcfg(cfgname)
pingcfg.next_check()

 

配置文件

[rule]
retry = 4
timeout = 1
next_check = 300
#单位都是秒
[scan_network]
3paragraph_begin = 10.1.3.198
3paragraph_end = 202
2paragraph_begin = 10.1.2.1
2paragraph_end = 10 [mail]
mailto1=guoyabin@ccln.gov.cn
mailto2=lzt417@126.com [allip]
#这里会自动把扫描到的ip写入

  

 

最新文章

  1. C++ 数字转换为string类型
  2. 如何阅读android framework源码
  3. ROS机器人语音交互(一)
  4. REST 风格的api
  5. elasticsearch2.2 集群搭建各种坑
  6. POJ 1028题目描述
  7. php PDO链接SQL SERVER
  8. XML Schema使用技巧——unique
  9. Python 读取excel
  10. centos下安装图像化界面
  11. 流式计算-Jstorm提交Topology过程(上)
  12. java之jvm学习笔记三(Class文件检验器)
  13. PV操作——生产者和消费者
  14. PHP foreach 遍历数组是打印出相同的数据
  15. C#基础知识-XML介绍及基本操作(十)
  16. shell编程之文件包含
  17. iOS 检测屏幕是否锁定 &#128275; / &#128274;
  18. JAVA EE 的学习目标
  19. pytest十二:cmd命令行参数
  20. 阿里云 oss实时日志查询

热门文章

  1. test_1 计算字符串最后一个单词的长度,单词以空格隔开
  2. Android官方文档翻译 十一 2.4Overlaying the Action Bar
  3. 2021最新Termux安装Metasploit
  4. 带你玩转Flink流批一体分布式实时处理引擎
  5. 【刷题-LeetCode】154 Find Minimum in Rotated Sorted Array II
  6. 豆瓣爬虫——通过json接口获取数据
  7. VUE3 之 组件传参
  8. gin中如何记录日志和错误日志
  9. Homework_2
  10. python 小兵(3)字典