Chinaunix首页 | 论坛 | 博客
  • 博客访问: 160337
  • 博文数量: 16
  • 博客积分: 2000
  • 博客等级: 大尉
  • 技术积分: 195
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-29 08:28
文章分类

全部博文(16)

文章存档

2015年(1)

2010年(15)

我的朋友

分类: Python/Ruby

2010-01-31 19:02:12

    以前也用过TcpDump的程序,这个可是监听程序的老祖宗,制定性也非常高,可是要想用的更个性话一点,恐怕还需要去读源代码吧,曾经我也下过决心,誓把他读懂,哎……没办到

    下面这个是用python写的监听程序,理解简单,方便修改,要是想监听特定化的数据包,还是自己写的比较放心……

#!/usr/bin/python
# -*- coding:utf-8 -*-
''
'
    IP报文格式:
    (4:版本)(4:头长)(=8:服务类型)(=========16:总长度=========)
    (=========16:标识ID=========)(3:标志)(======13:偏移量====)
    (=====8:TTL===)(=8:协议类型=)(========16:头校验和========)
    (======================32:源IP地址=======================)
    (======================32:目的IP地址=====================)

    TCP报文格式:
    (========16:源端口地址======)(=======16:目的端口地址=====)
    (========================32:序列号=======================)
    (========================32:确认号=======================)
    (4:头长)(6:reserved)(URG|ACK|PSH|RST|SYN|FIN)(16:窗口大小)
    (=========16:TCP校验和=========)(========16:紧急指针=====)

    UDP报文格式:
    (========16:源端口地址======)(=======16:目的端口地址=====)
    (========16:UDP数据长度=====)(========16:UDP校验和=======)
'
''

import pcap
import struct
import sys
import os

def ip_ntoa(c_4):
    ''
'
    传入参数:32位的ip地址的二进制形式
    返回类型:ip地址的字符串形式(点格式)
    '
''
    list = []
    for i in struct.unpack('cccc',c_4):
        list.append(str(ord(i)))
    return '.'.join(list)


def port_ntoa(c_2):
    ''
'
    传入参数:端口的二进制形式(16位)
    返回类型:int类型
    '
''
    i = (ord(c_2[0])<<8) + ord(c_2[1])
    return str(i)


def process_packet(pktlen,data,timestamp):
    # 设置偏移量指向IP报文
    offset = 14
    src_ip = ip_ntoa(data[offset+12:offset+16])
    dst_ip = ip_ntoa(data[offset+16:offset+20])
    
    # 设置偏移量指向TCP/UDP报文
    ip_len = ord(data[offset]) & 0x0f
    offset += ip_len*4
    src_port = port_ntoa(data[offset:offset+2])
    dst_port = port_ntoa(data[offset+2:offset+4])

    # 设置偏移量指向DATA数据
    tcp_len = ord(data[offset+12])>>4
    offset += tcp_len*4

    # 格式化输出
    global my_ip,f
    s = ""
    if my_ip == src_ip:
        s += ' >>' + dst_ip + ":" + dst_port
    else:
        s += '<< ' + src_ip + ":" + src_port
    s += ' \tDATA:' + str(len(data) - offset)
    s += os.linesep
    sys.stdout.write(s)
    f.write(s)

    # 在终端输出一部分数据
    for i in data[offset:offset+20]:
        sys.stdout.write(i)
    print ""

    s = ""
    for i in data[offset:]:
        s += i
    f.write(s + os.linesep)


if __name__ == "__main__":
    p = pcap.pcap()
        # 这里是你的IP地址
    my_ip = '192.168.1.50'
    # a.txt是保存的文件
    f = open('a.txt','w')
    # 在这里只接收端口为3128的数据包
    p.setfilter('port 3128')
    p.loop(process_packet,0)


阅读(2958) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~