dpkt Tutorial #1: ICMP Echo

本文介绍使用DPKT库创建并发送ICMP回显请求的方法。通过实例演示了如何设置ICMP回显负载的ID和序列号,并添加数据负载。此外还展示了如何构建ICMP包并将回显负载作为数据字段附加。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dpkt Tutorial #1: ICMP Echo

In this dpkt tutorial, I will demonstrate how to construct and send a simple ICMP echo packet.

dpkt is a sweet framework for creating and parsing packets.  While dpkt doesn’t have much documentation, once you get the hang of using one module, the rest fall into place fairly easily.  I’ll be doing a number of dpkt tutorials with simple tasks in hopes of providing some “documentation by example”.  If you have any tasks you’d like to see done in dpkt, drop me a line.

In this tutorial, we’ll be creating an ICMP echo packet, aka a ping.  It’s good to start off with a simple example to see how to construct a packet across multiple layers using the various modules of dpkt.  Let’s get started!

Taking a look at dpkt/icmp.py, we see the following classes for ICMP and it’s Echo payload:

class ICMP(dpkt.Packet):
    __hdr__ = (
        ('type', 'B', 8),
        ('code', 'B', 0),
        ('sum', 'H', 0)
        )
    class Echo(dpkt.Packet):
        __hdr__ = (('id', 'H', 0), ('seq', 'H', 0))

Since we’ll be sending the ICMP echo out via the standard socket interface, we don’t have to concerns ourselves with lower layers such as IP or the link-layer (we’ll save that for another tutorial).

When constructing packets with dpkt, I usually take an top-to-bottom approach, starting with the highest level structure and working our way down the layers.  For this ICMP request, we would start with contructing the Echo payload and then the ICMP base payload (and then the IP payload, the link-layer payload, and so on if we were constructing lower-level payloads).  To create the Echo payload, we simple create an instance of the Echo class:

echo = dpkt.icmp.ICMP.Echo()

The attributes for the Echo payload (listed in __hdr__) are id and seq, both of which 16-bit integers (‘H’) and default to 0.  We can easily change these attributes of the Echo payload and will randomize them for kicks:

echo.id = random.randint(0, 0xffff)
echo.seq = random.randint(0, 0xffff)

ICMP Echo requests often include a data payload that is echo’ed back by the receiver.  We will include a payload by assigning a string to the Echo data attribute.  The data attribute is special in dpkt-land and we will see its use later when linking together the Echo payload with the ICMP payload.  For now, we assign a dummy payload:

echo.data = 'hello world'

We can now pretty print, hexdump, or print the raw bytes of the Echo payload:

>>> print `echo`
Echo(id=24528, seq=11482, data='hello world')
>>> print binascii.hexlify(str(echo))
5fd02cda68656c6c6f20776f726c64
>>> print str(echo)
_?,?hello world

Next, we create the ICMP payload and assign its attributes using the constants found in dpkt/icmp.py:

icmp = dpkt.icmp.ICMP()
icmp.type = dpkt.icmp.ICMP_ECHO

To link our Echo payload to our ICMP payload, we again use the data attribute.  Since the Echo payload is a “sub-payload” of the ICMP packet, we assign it to the ICMP’s data attribute:

icmp.data = echo

Again, we can now pretty print, hexdump, or print the raw bytes of the entire ICMP/Echo packet and see how the Echo payload is nested within the ICMP payload:

>>> print `icmp`
ICMP(data=Echo(id=24528, seq=11482, data='hello world'))
>>> print binascii.hexlify(str(icmp))
0800d9865fd02cda68656c6c6f20776f726c64
>>> print str(icmp)
??_?,?hello world

Now that we have the full binary payload of our ICMP packet (str(icmp)), we can send it out via a standard ICMP socket:

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
s.connect(('74.125.67.100', 1))
s.send(str(icmp))

Success!  This completes our tutorial showing the construction of an ICMP echo request with dpkt.

The full python script for this tutorial follows:

#!/usr/bin/env python

import dpkt
import socket, random

echo = dpkt.icmp.ICMP.Echo()
echo.id = random.randint(0, 0xffff)
echo.seq = random.randint(0, 0xffff)
echo.data = 'hello world'

icmp = dpkt.icmp.ICMP()
icmp.type = dpkt.icmp.ICMP_ECHO
icmp.data = echo

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
s.connect(('74.125.67.100', 1))
sent = s.send(str(icmp))

print 'sent %d bytes' % sent

转载于:https://www.cnblogs.com/lovemo1314/archive/2011/05/05/2037335.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值