I am trying to make a TCP packet that is sent to my other computer 500 times. I have created this code:
from scapy.all import *
from scapy.utils import rdpcap
#Create your own packets
data = 'This is a test'
myPacket = Ether(src="00:E0:4C:00:02:42",dst="00:E0:4C:01:08:99")/IP(src="169.254.162.71/16",dst="169.254.208.208/16")/TCP()/Raw(load=data)
print(myPacket.show())
for i in range (0,500):
sendp(myPacket, iface="Ethernet 4") # sending packet at layer 2
The issue is that when I run this code, the computer receives packets with an incrementing Source IP and the Destination IP is wrong, for some reason:
Any help fixing this would be appreciated.
The /16 in your addresses is called a netmask in CIDR notation. It means that your adresses are subnets that include all possible addresses between 169.254.0.0 and 169.254.255.255. (Same for the source IP)
See https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing and https://en.wikipedia.org/wiki/Private_network
Scapy is going to send 256x256x256x256 (accounting for both sr and dst) packets with all possible addresses, starting as you saw with the 0.0 ones. You just need to remove the /16.
Related
While examining a sniffer code written in Python, I saw that ethernet layer information was obtained from the first 14 characters of a packet and IP layer information from the first 20 characters of the same packet that includes ethernet layer informations. So how is both IP and Ethernet information obtained from the same part of a packet?
In short:
packet = s.recvfrom(65535)
ethernet_layer = packet[:14]
ip_layer = packet[:20] # includes ethernet layer
My opinion:
packet = s.recvfrom(65535)
ethernet_layer = packet[:14]
ip_layer = packet[14:34]
Sniffer code: https://github.com/shreyasgune/Packet-Sniffer/blob/master/sniff-it.py#L47
I am trying to write a python program to parse packet capture using dpkt module. I have used it on packet captures that had Ethernet and tcpdump captures and it worked fine. However, my current packet capture is raw packet capture that directly has IP header and subsequent protocols and it seems like dpkt is not able to understand these captures. Picture of capture file is attached. enter image description here
The code I had was
f = open(ipfile, 'rb')
pcap = dpkt.pcap.Reader(f)
for ts,buf in pcap:
eth = dpkt.ethernet.Ethernet(buf) //Also tried with eth = dpkt.sll.SLL(buf), but no luck.
ip = eth.data
tcp = ip.data
Any ideas on how to parse such captures?
Thanks !!
I had the same issue with CAIDA pcap. Try
ip = dpkt.ethernet.Ethernet(buf)
I am receiving UDP packets over wifi running a simple python script on a PC. The server and the PC are in the same subnet.
The server is sending 15 uint_8 (4 bytes each) every 20 ms or so. The data received seems to be corrupted (non Hex values). Any feedback why this could be happening greatly appreciated.
For example I get something like this,
'\xb3}fC\xb7v\t>\xc8X\xd2=g\x8e1\xbf\xe6D3\xbf\x00\x00\x13\xc3\xc8g\x1b#\xc2\x12\xb2B\x01\x000=\x02\xc0~?\x01\x00\x94<\x00\x00\x00\x00\x00\x00\x00\x00\x00
#\x9c\xbe\xac\xc9V#', ('192.168.4.1', 4097))
The script is attached here.
from socket import *
import time
HOST = '192.168.4.10'
PORT = 9048
address = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_DGRAM) #Set Up the Socket
client_socket.bind((HOST, PORT))
client_socket.settimeout(5) #only wait 5 second for a response, otherwise timeout
while(1): #Main Loop
single_var = client_socket.recvfrom(1024)
print single_var #Print the response from Arduino
time.sleep(10/1000000) # sleep 10 microseconds
The print statement doesn't know that you want hex output, so it interprets hex values that have valid character representations as characters. If you want to print it as hex bytes, see the solution in Print a string as hex bytes.
i.e. do:
print ":".join("{:02x}".format(ord(c)) for c in single_var)
I'm actually trying to sniff packets with python (using pypcap and dpkt).
I tried the following :
import dpkt, pcap
pc = pcap.pcap() # construct pcap object
pc.setfilter('src host X.X.X.X or dst host X.X.X.X')
for timestamp, packet in pc:
print dpkt.ethernet.Ethernet(packet)
But nothing happens when I launch the script... Did I miss something ?
Using Python 2.7
On OS X Yosemite (10.10)
The question is old but for new people who might hit this. The github 'chains' project uses both pypcap and dpkt for exactly this kind of thing (Disclaimer: I'm involved with all three projects :) https://github.com/SuperCowPowers/chains
chains/sources/packet_streamer.py (code showing use of pypcap for 'sniffing')
chains/links/packet_meta.py (code showing use of dpkt for packet parsing)
For those that just want to use pypcap/dpkt here's a working code snippet:
import pcap
import dpkt
sniffer = pcap.pcap(name=None, promisc=True, immediate=True)
for timestamp, raw_buf in sniffer:
output = {}
# Unpack the Ethernet frame (mac src/dst, ethertype)
eth = dpkt.ethernet.Ethernet(raw_buf)
output['eth'] = {'src': eth.src, 'dst': eth.dst, 'type':eth.type}
# It this an IP packet?
if not isinstance(eth.data, dpkt.ip.IP):
print 'Non IP Packet type not supported %s\n' % eth.data.__class__.__name__
continue
# Grab ip packet
packet = eth.data
# Pull out fragment information
df = bool(packet.off & dpkt.ip.IP_DF)
mf = bool(packet.off & dpkt.ip.IP_MF)
offset = packet.off & dpkt.ip.IP_OFFMASK
# Pulling out src, dst, length, fragment info, TTL, checksum and Protocol
output['ip'] = {'src':packet.src, 'dst':packet.dst, 'p': packet.p,
'len':packet.len, 'ttl':packet.ttl,
'df':df, 'mf': mf, 'offset': offset,
'checksum': packet.sum}
print output
You should check out Scapy. Its a powerful networking tool, that can be used interactivly as well. Its written in python, hence you can use it in your scripts as well.
In scapy its as easy as (but you can easily add filters as well):
sniff(iface='eth0')
If you didn't place the path to a file in pcap.pcap(), there's no pcap for it to parse.
I ran your script with a glob of from a pcap directory I have and replaced the IP with one in my network, seemed like it worked.
You sure you installed pypcap and dpkt?
Here's exactly what I did with your script.
import dpkt, pcap, glob
for i in glob.glob("/pcap/*.pcap"):
pc = pcap.pcap(i)
pc.setfilter('src host 192.168.1.140 or dst host 192.168.1.140')
for timestamp, packet in pc:
print dpkt.ethernet.Ethernet(packet)
It printed a lot of stuff.
Nothing jumps out at the code, so I'm wondering if it is just the network.
Can you double check the IP addresses and also maybe run tcpdump as a sanity check to make sure you can see traffic?
For tcpdump something like this
$ sudo tcpdump -i en1 "src host 10.0.0.2 or dst host 10.0.0.2"
I am capturing WiFi traffic with tcpdump using the parameter -s 100 (which means I am only capturing the headers of the packets).
When I load the .pcap file and process it with Scapy I do:
pkts = rdpcap(pcapfile)
totalbytes = 0
for pkt in pkts:
totalbytes += len(pkt)
However, as I am truncating the capture, doing len(pkt) will not give me the whole packet length (frame length), it will give me the captured packet length. How can I get the real packet length?
Extra: as I have done in some occasions before, I open the pcap file in wireshark and search for the hex values of interest. But in this case (frame.len) will show the value I am looking for, but I can't find the way wireshark obtains this real packet length without having the whole packet captured.
The rdpcap function uses the PcapReader class for reading packets. Unfortunately this class discards the information you are looking for in the read_packet method, even though it is to be found in the pcap file. So you have to use the RawPcapReader directly.
totalbytes = 0
for pkt, (sec, usec, wirelen) in RawPcapReader(pcapfile):
totalbytes += wirelen
With modern Scapy versions, the proper answer would be to use pkt.wirelen. This only exists in packets read from a pcap
If for some reason you don't want to use RawPcapReader, you can use the len attribute for IPv4 packets.
real_length = pkt[IP].len
truncated_length = len(pkt)
Strangely, the IPv6 layer in Scapy doesn't have the same attribute, but it does have an attribute called plen which is the length of the payload:
payload_length = pkt[IPv6].plen
real_length = payload_length + 40
truncated_length = len(pkt)