Я использую scapy и хочу создать пакет и вычислить его контрольную сумму, не отправляя его. Есть ли способ сделать это?
Спасибо.
Я использую scapy и хочу создать пакет и вычислить его контрольную сумму, не отправляя его. Есть ли способ сделать это?
Спасибо.
Вам необходимо удалить значение .chksum
из пакета после его создания; затем позвоните .show2()
>>> from scapy.layers.inet import IP
>>> from scapy.layers.inet import ICMP
>>> from scapy.layers.inet import TCP
>>> target = "10.9.8.7"
>>> ttl = 64
>>> id = 32711
>>> sport = 2927
>>> dport = 80
>>> pak = IP(dst=target, src = "100.99.98.97", ttl=ttl, flags="DF", id=id, len=1200, chksum = 0)/TCP(flags="S", sport=sport, dport=int(dport), options=[('Timestamp',(0,0))], chksum = 0)
>>> del pak[IP].chksum
>>> del pak[TCP].chksum
>>> pak.show2()
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 1200
id = 32711
flags = DF
frag = 0L
ttl = 64
proto = tcp
chksum = 0x9afd
src = 100.99.98.97
dst = 10.9.8.7
\options \
###[ TCP ]###
sport = 2927
dport = www
seq = 0
ack = 0
dataofs = 8L
reserved = 0L
flags = S
window = 8192
chksum = 0x2c0e
urgptr = 0
options = [('Timestamp', (0, 0)), ('EOL', None)]
>>>
show2()
, потому что весь вывод был ненужным. Возможно, должна быть просто функция пакета recalc
.
- person Mr. Shickadance; 21.07.2011
stdout
на мгновение, переназначив его... например, stdout, null = sys.stdout, open('/dev/null', 'w'); sys.stdout = null
. Когда вы закончите, переназначьте снова с помощью sys.stdout = stdout
- person This; 21.07.2011
show2()
?
- person lordlabakdas; 29.12.2016
Я также пытался избежать show2(), потому что он печатает пакет. Я нашел в источнике лучшее решение:
del packet.chksum
packet = packet.__class__(bytes(packet))
Этот код регенерирует пакет с правильной контрольной суммой без какой-либо печати, и на самом деле это то, что show2() запускается в фоновом режиме перед печатью.
del ret_packet.chksum
и del ret_packet[UDP].chksum
для UDP.
- person Shir; 01.01.2020
Добавьте этот патч в scapy/packet.py:
+ def checksum_silent(self):
+ """
+ Internal method that recalcs checksum without the annoying prints
+ **AFTER old checksums are deleted.**
+ """
+
+ for f in self.fields_desc:
+ if isinstance(f, ConditionalField) and not f._evalcond(self):
+ continue
+ fvalue = self.getfieldval(f.name)
+ if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
+ fvalue_gen = SetGen(fvalue,_iterpacket=0)
+ for fvalue in fvalue_gen:
+ fvalue.checksum_silent()
+ if self.payload:
+ self.payload.checksum_silent()
Затем вместо вызова pkt.show2()
просто вызовите эту функцию pkt.checksum_silent()
. (Не забудьте сначала выполнить del pkt[IP].chksum
и del pkt[UDP].chksum
и т. д.), как показано в предыдущем ответе.
Эта функция должна работать быстрее и быть бесшумной. (Также могут быть дополнительные вещи, которые нужно обрезать; я взломал этот код вместе и только проверил, чтобы убедиться, что он молчит с правильной контрольной суммой.)
Действительно, функция show2()
подсчитывает за вас контрольную сумму, но также распечатывает содержимое пакета по окончании своей работы. Однако у show2()
есть небольшой полезный параметр с именем dump
. Источник описывает это так:
:param dump: определить, печатает ли он или возвращает строковое значение
Таким образом, установив dump=True
, вы можете избежать надоедливого вывода, который функция обеспечивает по умолчанию, и по-прежнему получать нужные вам вычисления.
Вы также можете использовать packet.build()
, который возвращает необработанные байты с правильной контрольной суммой. Затем преобразуйте байты в пакет.
>>> import scapy.all as sp
>>> packet = sp.IP(src='127.0.0.1', dst='8.8.8.8')
>>> packet
<IP src=127.0.0.1 dst=8.8.8.8 |>
>>> sp.IP(packet.build())
<IP version=4 ihl=5 tos=0x0 len=20 id=1 flags= frag=0 ttl=64
proto=hopopt chksum=0xebd8 src=127.0.0.1 dst=8.8.8.8 |>