7

I am using scapy 2.3.1-dev non-interactively (i.e. as a library) in a tool I am building. I would like to get a string of human-readable information about a packet, such as you get from scapy.all.Packet.show(). I have tried using all three of the methods (packet.show(), packet.show2() and packet.display()) that provide the info, but none of these return anything, instead they print out the information that I want.

Also, the information returned by packet.__repr__() is not quite enough.

Are there any functions/methods that would return the nicely-formatted text the same way that e.g. packet.show() prints them? If not is there some way of capturing/intercepting the output of show(), before it gets printed to the console?

I am aware that I can do my own string formatting, using the info from packet.fields, but I am trying to avoid having to do that.

nik
  • 726
  • 2
  • 12
  • 28

2 Answers2

16

You can use show() method by show(dump=True),then it will return string to you. Why Do I Know that,cause I read the code of show() method.

here is code:

def main():
    packet = scapy.rdpcap('1.pcap')
    for p in packet:
        a = p.show(dump=True)
        print type(a)
        print a
        exit(0)
Komal12
  • 3,340
  • 4
  • 16
  • 25
JulianZackWu
  • 161
  • 1
  • 2
8

One of the possible ways is to redirect output of the packet.show() function to the variable capture. The following code provides an example:

import sys
from StringIO import StringIO
from scapy.layers import inet
from scapy.all import *

#Create scapy packet
pack=inet.Ether()/inet.IP()/inet.TCP()

#Redirect output of print to variable 'capture'
capture = StringIO()
save_stdout = sys.stdout
sys.stdout = capture
pack.show()
sys.stdout = save_stdout

#capture.getvalue() is a string with the output of 'pack.show()' 
print capture.getvalue()

#Verify that capture.getvalue() is a string
print isinstance(capture.getvalue(), basestring)

Output of the program is:

###[ Ethernet ]###
  dst       = ff:ff:ff:ff:ff:ff
  src       = 00:00:00:00:00:00
  type      = 0x800
###[ IP ]###
     version   = 4
     ihl       = None
     tos       = 0x0
     len       = None
     id        = 1
     flags     = 
     frag      = 0
     ttl       = 64
     proto     = tcp
     chksum    = None
     src       = 127.0.0.1
     dst       = 127.0.0.1
     \options   \
###[ TCP ]###
        sport     = ftp_data
        dport     = http
        seq       = 0
        ack       = 0
        dataofs   = None
        reserved  = 0
        flags     = S
        window    = 8192
        chksum    = None
        urgptr    = 0
        options   = {}

True
Konstantin
  • 2,937
  • 10
  • 41
  • 58
  • I was hoping that there would be a more elegant way of doing it, but this will work fine. Thanks! – nik Apr 20 '15 at 22:43
  • If you are multi-threading, I'd recommend using a lock whenever trying to print anywhere in the program. That way some other text doesn't get appended to the results. – the4960 Sep 29 '18 at 01:53
  • These days, you can use show(dump=True) – Noam Rathaus Jan 22 '23 at 13:48