I have no idea what seems to be the problem, but it can be resolved in the following manner:
wireshark(pkt for pkt in pkts) # don't supply a list but rather a generator
This also outputs the following message:
WARNING: PcapWriter: unknown LL type for generator. Using type 1 (Ethernet)
Apparently, the wireshark
function doesn’t handle a Linux cooked-mode capture that well. This odd situation might have something to do with the following excerpt from scapy
‘s wiki:
Please remember that Wireshark works with Layer 2 packets (usually called “frames”). So we had to add an
Ether()
header to our ICMP packets. Passing just IP packets (layer 3) to Wireshark will give strange results.
We can also circumvent this issue by creating a dummy Ethernet layer, if we don’t really care about the layer 2 frame:
pkts = [Ether(src=pkt[0].src)/pkt[1:] for pkt in pkts]
EDIT – upon further research, and analyzing scapy’s source code, I figured out why passing a generator object seems to solve this issue.
The wireshark
function creates a temporary file containing the packets and launches Wireshark with that file. The link type to be specified in the header of that file is extracted in the following manner:
if self.linktype == None:
if type(pkt) is list or type(pkt) is tuple or isinstance(pkt,BasePacketList):
pkt = pkt[0]
try:
self.linktype = conf.l2types[pkt.__class__]
except KeyError:
warning("PcapWriter: unknown LL type for %s. Using type 1 (Ethernet)" % pkt.__class__.__name__)
self.linktype = 1
When passing a generator object, the first if
statement evaluates to False
(which is obviously a bug) and an exception is raised when attempting to access conf.l2types[pkt.__class__]
since pkt.__class__
is <type 'generator'>
. Therefore, the except clause of the try-except
code block is executed and the link type is specified as 1.
However, when passing a real list, the first if
statement evaluates to True
and the first packet of the list is extracted and used to access conf.l2types
, which is:
In [2]: conf.l2types
Out[2]:
0x1 <- Dot3 (802.3)
0x1 <-> Ether (Ethernet)
0xc -> IP (IP)
0x17 -> Ether (Ethernet)
0x1f <-> IPv6 (IPv6)
0x65 <-> IP (IP)
0x69 <-> Dot11 (802.11)
0x71 -> CookedLinux (cooked linux)
0x77 <-> PrismHeader (Prism header)
0x7f <-> RadioTap (RadioTap dummy)
0x90 <-> CookedLinux (cooked linux)
0xc0 <-> PPI (Per-Packet Information header (partial))
0x304 -> Ether (Ethernet)
0x321 -> Dot11 (802.11)
0x322 -> PrismHeader (Prism header)
0x323 -> RadioTap (RadioTap dummy)
Since pkts[0].__class__
is scapy.layers.l2.CookedLinux
, the link type is set to 0x90
rather than to 0x71
(seems like yet another bug), which results in Wireshark failing to parse the file.
Therefore, I think that the best approach would be to copycat scapy’s wireshark
function, with the subtle change of allowing the user to explicitly specify the link type:
def wireshark(*args, **kwargs):
"""Run wireshark on a list of packets"""
f = scapy.all.get_temp_file()
scapy.all.wrpcap(f, *args, **kwargs)
subprocess.Popen([scapy.all.conf.prog.wireshark, "-r", f])
wireshark(pkts, linktype=0x71)
EDIT – I’ve now noticed that the link type mapping issue was already reported and fixed by secdev. However, it hasn’t reached python-scapy
just yet. I’ve also created a new issue on the invalid handling of a generator object in PcapWriter
.
Я сделал несколько захватов пакетов на своем коммутаторе, а затем скопировал pcap на свой MAC-адрес ноутбука. Когда я пытаюсь открыть pcap на wireshark, я получаю сообщение об ошибке:
The capture file appears to be damaged or corrupt.
(stanag4607: File has 976433722d-byte packet, bigger than maximum of 262144)
Файлы pcaps не повреждены, они имеют размер 14 КБ. Я не могу уменьшить размер своего файла, так как в нем есть важные снимки. Какие-либо предложения?
Я открыл pcap размером более 10 КБ в wirehark, но не знаю, почему на этот раз я не могу их открыть. Я пытался искать в Интернете, но ответы в Интернете не решили проблему.
1 ответ
Ваша проблема не в размере всего файла с захваченными данными, а в том, что файл содержит как минимум один чрезвычайно длинный пакет, превышающий все мыслимые границы. Его нельзя распарсить и поэтому загрузка файла в Wireshark останавливается и завершается с ошибкой.
Обычный предельный размер данных одного IP-пакета составляет 1500 байт. Ограничение размера большого пакета составляет 9000 байт и, возможно, 64 000 байт в особых случаях. Но никогда не приближайтесь к 10e^10 B (т.е. 10000 миллионов байтов), как в вашем случае!
Один пакет в вашем случае во много раз больше, чем весь набор захваченных данных. Это ошибка данных в файле, с которой Wireshark не может справиться. Вероятная причина заключается в том, что захват сетевых данных на коммутаторе либо неправильный, либо в формате, отличном от того, который может загрузить Wireshark. Границы пакетов или размеры пакетов оцениваются неправильно.
Решения для будущих захваченных данных
- Проверьте и отрегулируйте настройки переключателя.
- Используйте зеркалирование портов вместо прямого захвата данных на коммутаторе. Сохраните данные с порта вывода зеркала, используя Wireshark на своем компьютере.
Решение для настоящего сбойного файла
- Попробуйте получить захваченные данные в других форматах или с помощью другого приложения.
0
DigiBat
6 Янв 2023 в 18:11
Вопрос:
Вот простой пример:
from scapy.all import *
pkts = rdpcap('/tmp/sample.pcap')
wireshark(pkts)
Тогда wirehark дает эту ошибку:
The capture file appears to be damaged or corrupt.
(libpcap: IrDA capture has a packet with an invalid sll_protocol field)
Я использую wirehark 1.8, python 2.7.3 и scapy 2.2.0.
ПРИМЕЧАНИЕ. Я могу открыть файл smaple.pcap напрямую с помощью wirehark.
Что я могу сделать, чтобы файлы pcap, созданные с помощью scapy, открывались в wirehark?
EDIT: Я пробовал другие файлы pcap (из образцов захвата проводов), и это сработало. Кажется, проблема в моих пакетах. Вот первый пакет (который также не работает):
###[ cooked linux ]###
pkttype = unicast
lladdrtype= 0x1
lladdrlen = 6
src = 'x00x04xedxcbx9b0'
proto = 0x800
###[ IP ]###
version = 4L
ihl = 5L
tos = 0xb8
len = 165
id = 47433
flags =
frag = 0L
ttl = 49
proto = udp
chksum = 0x50c9
src = 22.31.32.55
dst = 192.168.1.102
options
###[ UDP ]###
sport = 4566
dport = 4566
len = 145
chksum = 0x0
###[ Raw ]###
load = 'Hx84x80x80x80x80x80x8cx80x80x86x81x8bx82x80x82x81x98xb1xb9xb2xaexb1xb6xb8xaexb1xaexb2xb5xadxb0xb1xb2xb2xb6xb6xb5xb7xb4xb9xb4xadx81xcax82x89xb9xb9xb5xb0xb6xb1xb0xb3xb3xa6x81x80xa7x81x80xa8x82x80x80x84x89xb9xb9xb5xb0xb6xb1xb0xb3xb3x8ax82xe5xeex86x88xe3xe3xecxe9xe5xeexf4xb2x89x84x80x80x81x80xb8x89x80x80x80x80x80x80x80x81x80x88x84x80x80x81x80xb7x89x80x80x80x80x80x80x80x81x80x8cx82x80x82x9fx84x9exa7 xe2xb6x80'
Примечание: изменены IP-адреса, поэтому контрольная сумма может быть неправильной.
Лучший ответ:
Я понятия не имею, какая проблема, но ее можно решить следующим образом:
wireshark(pkt for pkt in pkts) # don't supply a list but rather a generator
Это также выводит следующее сообщение:
ПРЕДУПРЕЖДЕНИЕ: PcapWriter: неизвестный тип LL для генератора. Использование типа 1 (Ethernet)
По-видимому, функция wireshark
не очень хорошо справляется с захватом в режиме готовности в Linux. Эта странная ситуация может иметь какое-то отношение к следующей выдержке из scapy
wiki:
Помните, что Wireshark работает с пакетами уровня 2 (обычно называемыми “фреймами”). Поэтому нам пришлось добавить заголовок
Ether()
в наши ICMP-пакеты. Передача только IP-пакетов (уровень 3) в Wireshark даст странные результаты.
Мы также можем обойти эту проблему, создав фиктивный Ethernet-уровень, если мы не заботимся о кадре уровня 2:
pkts = [Ether(src=pkt[0].src)/pkt[1:] for pkt in pkts]
EDIT – после дальнейших исследований и анализа исходного кода scapy я понял, почему передача объекта-генератора, похоже, решает эту проблему.
Функция wireshark
создает временный файл, содержащий пакеты, и запускает Wireshark с этим файлом. Тип ссылки, который будет указан в заголовке этого файла, будет извлекаться следующим образом:
if self.linktype == None:
if type(pkt) is list or type(pkt) is tuple or isinstance(pkt,BasePacketList):
pkt = pkt[0]
try:
self.linktype = conf.l2types[pkt.__class__]
except KeyError:
warning("PcapWriter: unknown LL type for %s. Using type 1 (Ethernet)" % pkt.__class__.__name__)
self.linktype = 1
При передаче объекта-генератора первый оператор if
оценивает значение False
(что, очевидно, является ошибкой), и возникает исключение при попытке получить доступ к conf.l2types[pkt.__class__]
поскольку pkt.__class__
is <type 'generator'>
. Следовательно, выполняется условие try-except
блока try-except
code и тип ссылки указывается как 1.
Однако при передаче реального списка первый оператор if
принимает значение True
и первый пакет списка извлекается и используется для доступа к conf.l2types
, который:
In [2]: conf.l2types
Out[2]:
0x1 <- Dot3 (802.3)
0x1 <-> Ether (Ethernet)
0xc -> IP (IP)
0x17 -> Ether (Ethernet)
0x1f <-> IPv6 (IPv6)
0x65 <-> IP (IP)
0x69 <-> Dot11 (802.11)
0x71 -> CookedLinux (cooked linux)
0x77 <-> PrismHeader (Prism header)
0x7f <-> RadioTap (RadioTap dummy)
0x90 <-> CookedLinux (cooked linux)
0xc0 <-> PPI (Per-Packet Information header (partial))
0x304 -> Ether (Ethernet)
0x321 -> Dot11 (802.11)
0x322 -> PrismHeader (Prism header)
0x323 -> RadioTap (RadioTap dummy)
Так как pkts[0].__class__
– scapy.layers.l2.CookedLinux
, тип ссылки устанавливается 0x90
а не 0x71
(кажется еще одной ошибкой), что приводит к тому, что Wireshark не может проанализировать файл.
Поэтому я считаю, что наилучшим подходом было бы подражание scapy wireshark
, с тонким изменением, позволяющим пользователю явно указывать тип ссылки:
def wireshark(*args, **kwargs):
"""Run wireshark on a list of packets"""
f = scapy.all.get_temp_file()
scapy.all.wrpcap(f, *args, **kwargs)
subprocess.Popen([scapy.all.conf.prog.wireshark, "-r", f])
wireshark(pkts, linktype=0x71)
EDIT – теперь я заметил, что проблема сопоставления типов ссылок уже была указана и исправлена с помощью secdev. Тем не менее, он еще не достиг python-scapy
. Я также создал новую проблему с недопустимой обработкой объекта-генератора в PcapWriter
.
Ответ №1
(libpcap: захват IrDA имеет пакет с недопустимым полем sll_protocol)
Linux IrDA использует что-то вроде заголовка готового режима Linux, но это не то же самое:
- Заголовок в режиме готового режима Linux с типом заголовка link-layer 113;
- Linux IrDA, с заголовком типа link-layer 144.
Я не знаю, почему ваша программа выбрала 144, а не 113; был ли ваш входной файл файлом IrDA Linux, а не файлом захваченного Linux файла?
Topic: Corrupt cap files (Read 4334 times)
Hi,
Whenever I leave an interface capture running for any amount of time, Wireshark reports the following when I open the file:
“The capture file appears to be damaged or corrupt.
(pcap: File has 992550946-byte packet, bigger than maximum of 262144)”
Is this because I’m leaving the capture running for a long time, or something else?
Looking around Google a lot of people mention it could be to do with the transfer method, but I just downloaded the file via the GUI.
Thanks.
« Last Edit: September 16, 2019, 08:14:39 pm by dave »
Logged
This means that a packet has a broken header.
Logged
It certainly looks like something’s happening here.
No matter the size or duration of the capture, when transferred via SSH everything’s fine; when downloaded via the GUI things end up broken.
« Last Edit: September 16, 2019, 08:14:05 pm by dave »
Logged
Logged
I cannot stress enough how vital feedback is in order to be able to ship tested patches.
Cheers,
Franco
Logged
Logged
So, does it work or same error?
Logged
Logged
Having applied the patch the GUI download never starts, but can still be transfered fine via scp.
Applied the patch again to remove it and the GUI download started working again.
Tested with a ~300MB capture.
Seams to have generated a bug report too:
[30-Sep-2019 21:58:07 Europe/London] PHP Fatal error: Allowed memory size of 402653184 bytes exhausted (tried to allocate 344058472 bytes) in /usr/local/www/diag_packet_capture.php on line 165
[30-Sep-2019 21:58:07 Europe/London] PHP Fatal error: Unknown: Cannot use output buffering in output buffering display handlers in Unknown on line 0
[30-Sep-2019 21:58:40 Europe/London] PHP Fatal error: Allowed memory size of 402653184 bytes exhausted (tried to allocate 344058472 bytes) in /usr/local/www/diag_packet_capture.php on line 165
[30-Sep-2019 21:58:40 Europe/London] PHP Fatal error: Unknown: Cannot use output buffering in output buffering display handlers in Unknown on line 0
« Last Edit: September 30, 2019, 11:04:27 pm by dave »
Logged
background
Process the data packet through the libpcap library, extract part of the content in the offline pcap file and save it as a new pcap file, use the function:pcap_open_offline( );pcap_loop( )Wait.
error
The capture file appears to be damaged or corrupt.
(pcap: File has 2944323888-byte packet, bigger than maximum of 262144)
the reason
The pcap header in the original pcap packet (structurestruct The caplen value in pcap_pkthdr) is wrong or too large.
solve
Re-assign the pcap header before writing the new pcap file
pkthdr.caplen=packetlen=eth_len+ip_total_len