For my larger project i need to start with creating a IPv4 network packet ( for simulation )
for the same I need to write a function that creates a header out of the passed data which has the source ip , dest ip and all the necessary fields
def convertIpv4( data ):
pass
For this I need you to guide me in the right direction.
Firstly I need to store the IP in 32 bits so for that if I have a string "192.168.2.1" what is the most efficient way to convert it into bytes and that too a size of 32 ??
Also if I create first a normal class with stuff like version = 4 and sourceip and dest ip then is there a way to convert it directly into a byte array with the position of objects just like the following header
Please tell how should i proceed....
Scapy can create IP headers easily.
Here they have an example on creating IP header.
Have a look at the PyIP module.
Related
I have managed to compile two lists of IP addresses. used and unused ips as such
unused_ips = ['172.16.100.0/32', '172.16.100.1/32', '172.16.100.2/32', '172.16.100.3/32', '172.16.100.4/32', '172.16.100.5/32', '172.16.100.6/32', '172.16.100.7/32', '172.16.100.8/32', '172.16.100.9/32'...]
used_ips = ['172.16.100.1/32','172.16.100.33/32']
what I want to be able to do now is compare these lists and return the next free IP. in the above example the next ip would be 172.16.100.2/32, until it handed out all of those from 1 to 32 then it would hand out 34.
im not sure where to begin with this, I can convert these to IPv4Network objects if there is something built in for this but I couldn't find anything in documentation
Thanks
I'd keep a set of ipaddress objects and manipulate them to allocate and de-allocate the addresses, like so:
import ipaddress
def massage_ip_lists():
global unused_ips, used_ips
unused_ips = set(ipaddress.ip_address(ip.replace('/32', ''))
for ip in unused_ips)
used_ips = set(ipaddress.ip_address(ip.replace('/32', ''))
for ip in used_ips)
def allocate_next_ip():
new_ip = min(unused_ips - used_ips)
used_ips.add(new_ip)
return new_ip
unused_ips = [
'172.16.100.0/32',
'172.16.100.1/32',
'172.16.100.2/32',
'172.16.100.3/32',
'172.16.100.4/32',
'172.16.100.5/32',
'172.16.100.6/32',
'172.16.100.7/32',
'172.16.100.8/32',
'172.16.100.9/32']
used_ips = ['172.16.100.1/32', '172.16.100.33/32']
massage_ip_lists()
print(allocate_next_ip())
print(allocate_next_ip())
Note:
/32 is a nomenclature for IP networks, not IP hosts.
ipaddress objects are comparable, so functions like min() work on them.
172.16.100.0 is a perfectly valid IP address, depending upon the netmask. If you don't want to allocate it, either keep it out of unused_ips, or make the program aware of the netmask in use.
You want ips that are in unused but not used:
available_ips = [ip for ip in unused_ips if ip not in used_ips]
You want to sort them to get the one that's closest to zero. Naive sorting will not work as you have strings; 172.16.xxx.xxx is sorted higher than 172.100.xxx.xxx for example. You can convert the IPs into lists of numbers to sort them correctly.
import re
available_ips = sorted(available_ips, key=lambda ip: (int(n) for n in re.split(r'[./]', ip)))
If you're just trying to iterate through a list of the available ips, you could do something like this:
# Filter unavailable ips from the list of all ips
available_ips = set(unused_ips) - set(used_ips)
# Iterate through list of available ips
for ip in available_ips:
print(ip) # Or whatever you want to do with the next available ip
I want to write a short script using python that read my ip address conversely , so when I write 127.0.0.1 I should find as a result 1.0.0.127.
any help please
Try this
ip = '127.0.0.1'
ip = ip.split('.')
ip.reverse()
print('.'.join(ip))
If you want to preserve the original ip. it's very easy since strings are immutable in python assign it to a new variable and just call reversed on it instead of calling the list's reverse() so you don't alter the list also (if you want that)
ip = '127.0.0.1'
new = ip.split('.')
new = reversed(new)
print('.'.join(new))
print(ip)
You can use this :
def reverseIP(ip):
ip = ip.split(".")
ip.reverse()
return '.'.join(ip)
Example :
print(reverseIP("127.0.0.1")) # Prints 1.0.0.127
i am new to python. I have some experience with Pascal and a little bit with C++.
At the moment i have to program some code for a research project demonstrator.
The setup is as follows:
We have a 868MHz radio master device. i can communicate with this device via a USB port (COM4 at the moment but may change in the future).
The 868MHz master communicates with a slave unit. The slave unit replies with a message that i can read from the USB port.
Until this point everything works good. I request data packages and also receive them.
From the moment of receiving the data packages i have a propblem i seem not
able to solve on myself.
I use Anaconda 32 bit with the Spyder editor
# -*- coding: utf-8 -*-
"""
Created on Thu May 7 13:35:59 2015
#author: roland
"""
import serial
portnr = 3 #Serial Port Number 0=Com1, 3=Com4
portbaud = 38400 #Baud rate
tiout = 0.1 #Timout in seconds
i = 1
wrword = ([0x02,0x04,0x00,0x00,0x00,0x02,0x71,0xF8])
try:
ser = serial.Serial(portnr, portbaud, timeout=tiout) # open port
except:
ser.close() # close port
ser = serial.Serial(portnr, portbaud, timeout=tiout) # open port
print(ser.name) # check which port was really used
while (i < 100):
ser.write(wrword)
seread = ser.readline()
print(seread)
i = i+1
sere = seread.split()
try:
readdat = str(sere[0])
except:
print("Index Error")
retlen = len(readdat)
print(retlen)
readdat = readdat[2:retlen-1]
print(readdat)
ser.close() # close port
The variable wrword is my request to the 868MHz radio master.
The Format is as follows:
0x02 Address of the unit
0x04 Command to send information from a certain register range
0x00 0x00 Address of first Register (Start address 0 is valid!)
0x00 0x02 Information how much registers are to be sent (in this case Registers 0 and 1 shall be transmitted to the Radio master)
0x71 0xF8 Checksum of the command sentence.
The program sends the command sequence successful to the master unit and the slave unit answers. Each time the command is send an answer is expected. Nevertheless it may happen that now correct answer is given thats why the
try command is in use.
I know i use ser.readline() but this is sufficient for the application.
I receive a list as answer from the USB Port.
The data look as follows:
b'\x02\x04\x04\x12\xb6\x12\xa5\xe0\xc1' (This is the Output from print(seread) )
For clarification this answer is correct and must be read as follows:
\x02 Address of the answering unit
\x04 Function that was executed (Read from certain register area)
\x04 Number of Bytes of the answer
\x12 \xb6 Value of first register (2 Byte)
\x12 \xa5 Value of second register (2 Byte)
\xe0 \xc1 Checksum of answer
If the data from the com port had all this Format i might be able to get the data values from the both Registers. But unfortunately the data format is not always the same.
Sometimes i receive answers in the following style:
b'\x02\x04\x04\x12\x8e\x12{\xe1T'
The answer is similar to the example above (different values in the Registers and different checksum) but the Format i receive has changed.
If i use the hex ASCII codes for the symbols obviously not hex values i find a valid answer telegram.
b'\x02\x04\x04\x12\x8e\x12{\xe1T'
becomes
b'\x02\x04\x04\x12\x8e\x12\x7b\xe1\x54'
when i Exchange the ASCII symbols by their hex code by Hand.
So my questions are:
Is it possible to force Python to give me the answer in a defined Format?
If not is it possible to handle the list or the string i can derive from the list in such a way that i get my values in the required format?
Does somebody can give me a hint how to extract my register values from the list and convert the two hex numbers of each register into one integer value for each register (the first value is the high byte, the second the low byte)?
Thanks in advance for your answer(s)
sincerely
Roland
I found a solution.
During a small testpiece of program i stumbled upon the fact that the variable seread contains already the data in a suitable and usable format for me.
I assume that the Spyder Editor causes the format change when displaying byte type objects.
If i Access the single Bytes using seread[i] while i is in range 0 to len(seread)-1 i receive the correct values for the single bytes.
So i can acess my data and calculate my measurement values as required.
Nevertheless thanks to keety for reading my question.
I found this code to detect the length of encrypted data in the frame :
header = self.request.recv(5)
if header == '':
#print 'client disconnected'
running = False
break
(content_type, version, length) = struct.unpack('>BHH', header)
data = self.request.recv(length)
Souce :
https://github.com/EiNSTeiN-/poodle/blob/master/samples/poodle-sample-1.py
https://gist.github.com/takeshixx/10107280
https://gist.github.com/ixs/10116537
This code, listen the connection between a client and a server. When the client talk to the server, self.request.recv(5) can get you the length of the header in the frame. Then we use that length to take the data.
If we print the exchange between the client and the server :
Client --> [proxy] -----> Server
length : 24 #why 24 ?
Client --> [proxy] -----> Server
length: 80 #length of the data
Client <-- [proxy] <----- Server
We can see that the client will send two packet to the server.
If i change
data = self.request.recv(length)
to
data = self.request.recv(4096)
Only one exchange is made.
Client --> [proxy] -----> Server
length: 109 #length of the data + the header
Client <-- [proxy] <----- Server
My question is why we only need to take a size of 5 to get the lenght, content_type informations ? Is there an understandable doc about this ?
Why there is two request: one with 24 and another with the lenght of our data ?
why we only need to take a size of 5 to get the lenght, content_type
informations ?
Because obviously that's the way the protocol was designed.
Binary streams only guarantee that when some bytes are put into one end of the stream, they arrive in the same order on the other end of the stream. For message transmission through binary streams the obvious problem is: where are the message boundaries? The classical solution to this problem is to add a prefix to messages, a so-called header. This header has a fixed size, known to both communication partners. That way, the recipient can safely read header, message, header, message (I guess you grasp the concept, it is an alternating fashion). As you see, the header does not contain message data -- it is just communication "overhead". This overhead should be kept small. The most efficient (space-wise) way to store such information is in binary form, using some kind of code that must, again, be known to both sides of the communication. Indeed, 5 bytes of information is quite a lot.
The '>BHH' format string indicates that this 5 byte header is built up like this:
unsigned char (1 Byte)
unsigned short (2 Bytes)
unsigned short (2 Bytes)
Plenty of room for storing information such as length and content type, don't you think? This header can encode 256 different content types, 65536 different versions, and a message length between 0 and 65535 bytes.
Why there is two request: one with 24 and another with the lenght of
our data ?
If your network forensics / traffic analysis does not correspond to what you have inferred from code, one of both types of analyses is wrong/incomplete. In this case, I guess that your traffic analysis is correct, but that you have not understood all relevant code for this kind of communication. Note that I did not look at the source code you linked to.
I would like to parse the first two bytes of a packets payload using Scapy. What would be the best way to accomplish this? Are offset calculations required?
First the payload needs to be parsed though the following will parse the whole PCAP file, is there a more efficient way to obtain the first two bytes of every payload? link:
>>> fp = open("payloads.dat","wb")
>>> def handler(packet):
... fp.write(str(packet.payload.payload.payload))
...
>>> sniff(offline="capture1.dump",prn=handler,filter="tcp or udp")
I see. That looks pretty efficient from here.
You might try fp.write(str(packet.payload.payload.payload)[:2]) to get just the first 2 bytes.
You could also do fp.write(str(packet[TCP].payload)[:2]) to skip past all those payloads.
Alternately, you could define an SSL Packet object, bind it to the appropriate port, then print the SSL layer.
class SSL(Packet):
name = "SSL" fields_desc = [ ShortField("firstBytes", None) ]
bind_layers( TCP, SSL, sport=443 )
bind_layers( TCP, SSL, dport=443 )
def handler(packet):
... fp.write(str(packet[SSL]))
...but this seems like overkill.