python构造icmp echo请求和实现网络探测器功能代码分享

python发送icmp echo requesy请求

代码如下:

import socket
import struct

def checksum(source_string):
    sum = 0
    countTo = (len(source_string)/2)*2
    count = 0
    while count<countTo:
        thisVal = ord(source_string[count + 1])*256 + ord(source_string[count])
        sum = sum + thisVal
        sum = sum & 0xffffffff
        count = count + 2
    if countTo<len(source_string):
        sum = sum + ord(source_string[len(source_string) - 1])
        sum = sum & 0xffffffff
    sum = (sum >> 16)  +  (sum & 0xffff)
    sum = sum + (sum >> 16)
    answer = ~sum
    answer = answer & 0xffff
    answer = answer >> 8 | (answer << 8 & 0xff00)
    return answer

def ping(ip):
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, 1)
    packet = struct.pack(
            "!BBHHH", 8, 0, 0, 0, 0
    )
    chksum=checksum(packet)
    packet = struct.pack(
            "!BBHHH", 8, 0, chksum, 0, 0
    )
    s.sendto(packet, (ip, 1))

if __name__=='__main__':
    ping('192.168.41.56')

扫描探测网络功能(网络探测器)

代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'''
探测网络主机存活。
'''

import os
import struct
import array
import time
import socket
import IPy
import threading

class SendPingThr(threading.Thread):
    '''
    发送ICMP请求报文的线程。

参数:
        ipPool      -- 可迭代的IP地址池
        icmpPacket  -- 构造的icmp报文
        icmpSocket  -- icmp套字接
        timeout     -- 设置发送超时
    '''
    def __init__(self, ipPool, icmpPacket, icmpSocket, timeout=3):
        threading.Thread.__init__(self)
        self.Sock = icmpSocket
        self.ipPool = ipPool
        self.packet = icmpPacket
        self.timeout = timeout
        self.Sock.settimeout( timeout + 3 )

def run(self):
        time.sleep(0.01)  #等待接收线程启动
        for ip in self.ipPool:
            try:
                self.Sock.sendto(self.packet, (ip, 0))
            except socket.timeout:
                break
        time.sleep(self.timeout)

class Nscan:
    '''
    参数:
        timeout    -- Socket超时,默认3秒
        IPv6       -- 是否是IPv6,默认为False
    '''
    def __init__(self, timeout=3, IPv6=False):
        self.timeout = timeout
        self.IPv6 = IPv6

self.__data = struct.pack('d', time.time())   #用于ICMP报文的负荷字节(8bit)
        self.__id = os.getpid()   #构造ICMP报文的ID字段,无实际意义

@property   #属性装饰器
    def __icmpSocket(self):
        '''创建ICMP Socket'''
        if not self.IPv6:
            Sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp"))
        else:
            Sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.getprotobyname("ipv6-icmp"))
        return Sock

def __inCksum(self, packet):
        '''ICMP 报文效验和计算方法'''
        if len(packet) & 1:
            packet = packet + '\0'
        words = array.array('h', packet)
        sum = 0
        for word in words:
            sum += (word & 0xffff)
        sum = (sum >> 16) + (sum & 0xffff)
        sum = sum + (sum >> 16)

return (~sum) & 0xffff

@property
    def __icmpPacket(self):
        '''构造 ICMP 报文'''
        if not self.IPv6:
            header = struct.pack('bbHHh', 8, 0, 0, self.__id, 0) # TYPE、CODE、CHKSUM、ID、SEQ
        else:
            header = struct.pack('BbHHh', 128, 0, 0, self.__id, 0)

packet = header + self.__data     # packet without checksum
        chkSum = self.__inCksum(packet) # make checksum

if not self.IPv6:
            header = struct.pack('bbHHh', 8, 0, chkSum, self.__id, 0)
        else:
            header = struct.pack('BbHHh', 128, 0, chkSum, self.__id, 0)

return header + self.__data   # packet *with* checksum

def isUnIP(self, IP):
        '''判断IP是否是一个合法的单播地址'''
        IP = [int(x) for x in IP.split('.') if x.isdigit()]
        if len(IP) == 4:
            if (0 < IP[0] < 223 and IP[0] != 127 and IP[1] < 256 and IP[2] < 256 and 0 < IP[3] < 255):
                return True
        return False

def makeIpPool(self, startIP, lastIP):
        '''生产 IP 地址池'''
        IPver = 6 if self.IPv6 else 4
        intIP = lambda ip: IPy.IP(ip).int()
        ipPool = {IPy.intToIp(ip, IPver) for ip in range(intIP(startIP), intIP(lastIP)+1)}

return {ip for ip in ipPool if self.isUnIP(ip)}

def mPing(self, ipPool):
        '''利用ICMP报文探测网络主机存活

参数:
            ipPool  -- 可迭代的IP地址池
        '''
        Sock = self.__icmpSocket
        Sock.settimeout(self.timeout)
        packet = self.__icmpPacket
        recvFroms = set()   #接收线程的来源IP地址容器

sendThr = SendPingThr(ipPool, packet, Sock, self.timeout)
        sendThr.start()

while True:
            try:
                recvFroms.add(Sock.recvfrom(1024)[1][0])
            except Exception:
                pass
            finally:
                if not sendThr.isAlive():
                    break
        return recvFroms & ipPool

if __name__=='__main__':
    s = Nscan()
    ipPool = s.makeIpPool('192.168.0.1', '192.168.0.254')
    print( s.mPing(ipPool) )

(0)

相关推荐

  • python socket网络编程步骤详解(socket套接字使用)

    一.套接字套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象.它们允许程序接受并进行连接,如发送和接受数据.为了建立通信通道,网络通信的每个端点拥有一个套接字对象极为重要.套接字为BSD UNIX系统核心的一部分,而且他们也被许多其他类似UNIX的操作系统包括Linux所采纳.许多非BSD UNIX系统(如ms-dos,windows,os/2,mac os及大部分主机环境)都以库形式提供对套接字的支持.三种最流行的套接

  • python网络编程学习笔记(一)

    学习用书:<python 网络编程基础>作者John Goerzen 第一部分底层网络学习 Python提供了访问底层操作系统Socket接口的全部方法,需要的时候这些接口可以提供灵活而强有力的功能. (1)基本客户端操作 在<python 网络编程基础>一书中,作者列出了一个简单的Python客户端程序,具体如下: 复制代码 代码如下: import socket,sysport =70host=sys.argv[1] filename=sys.argv[2] s=socket.

  • python如何查看系统网络流量的信息

    前言 流量信息可以直接在/proc/net/dev中进行查看,笔者实现的程序使用命令: python net.py interface 其中interface为网卡名称,使用什么网卡,电脑有哪些网卡,可以使用 sudo ifconfig 进行查看. Python实现的程序如下: # coding:utf-8 import sys, time, os ''' Inter-| Receive | Transmit face |bytes packets errs drop fifo frame co

  • 以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法

    在这篇文章中,我们将分析一个网络爬虫. 网络爬虫是一个扫描网络内容并记录其有用信息的工具.它能打开一大堆网页,分析每个页面的内容以便寻找所有感兴趣的数据,并将这些数据存储在一个数据库中,然后对其他网页进行同样的操作. 如果爬虫正在分析的网页中有一些链接,那么爬虫将会根据这些链接分析更多的页面. 搜索引擎就是基于这样的原理实现的. 这篇文章中,我特别选了一个稳定的."年轻"的开源项目pyspider,它是由 binux 编码实现的. 注:据认为pyspider持续监控网络,它假定网页在一

  • Python 网络编程起步(Socket发送消息)

    一.服务端(Server.py)    服务端要做的事情是:    1. 创建一个Socket对象 Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->import sockets = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    2. 绑定一个端口 Code highlighting pro

  • Python 网络编程说明第1/2页

    一.网络知识的一些介绍 socket 是网络连接端点.例如当你的Web浏览器请求www.jb51.net上的主页时,你的Web浏览器创建一个socket并命令它去连接 www.jb51.net的Web服务器主机,Web服务器也对来自的请求在一个socket上进行监听.两端使用各自的socket来发送和 接收信息. 在使用的时候,每个socket都被绑定到一个特定的IP地址和端口.IP地址是一个由4个数组成的序列,这4个数均是范围 0~255中的值(例如,220,176,36,76):端口数值的取

  • 使用Python编写简单网络爬虫抓取视频下载资源

    我第一次接触爬虫这东西是在今年的5月份,当时写了一个博客搜索引擎,所用到的爬虫也挺智能的,起码比电影来了这个站用到的爬虫水平高多了! 回到用Python写爬虫的话题. Python一直是我主要使用的脚本语言,没有之一.Python的语言简洁灵活,标准库功能强大,平常可以用作计算器,文本编码转换,图片处理,批量下载,批量处理文本等.总之我很喜欢,也越用越上手,这么好用的一个工具,一般人我不告诉他... 因为其强大的字符串处理能力,以及urllib2,cookielib,re,threading这些

  • Python使用urllib2获取网络资源实例讲解

    这是具有利用不同协议获取URLs的能力,他同样提供了一个比较复杂的接口来处理一般情况,例如:基础验证,cookies,代理和其他.它们通过handlers和openers的对象提供.urllib2支持获取不同格式的URLs(在URL的":"前定义的字串,例如:"ftp"是"ftp:python.ort/"的前缀),它们利用它们相关网络协议(例如FTP,HTTP)进行获取.这篇教程关注最广泛的应用--HTTP.对于简单的应用,urlopen是非常容

  • python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)

    UDP广泛应用于需要相互传输数据的网络应用中,如QQ使用的就是UDP协议.在网络质量不好的情况下,使用UDP协议时丢包现象十分严重,但UDP占用资源少,处理速度快,UDP依然是传输数据时常用的协议. 下面是用python实现UDP服务器的代码: 复制代码 代码如下: #!/usr/bin/env pythonimport socketaddress=('127.0.0.1',10000)s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)s.bind

  • python网络编程学习笔记(三):socket网络服务器

    1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象  建立socket对象 第二步 调用connect()建立一个和服务器的连接 设置socket选项(可选) 第三步 无 绑定到一个端口(也可以是一个指定的网卡) 第四步 无 侦听连接 下面具体来讲这四步的建立方法: 第一步,建立socket对象:这里与客户端一样,依然是: s=socket.socket(socket.

随机推荐