Malformed Packet on ICMP python - python

How i can create a frame icmp
I mark malformet packet on python
import socket, struct, uuid, subprocess, fcntl, time,random
List item
from binascii import hexlify, unhexlify from datetime import datetime
tarRed = raw_input('Ingrese nombre de Tarjeta de Red Utilizada: ')
subprocess.call(['ifconfig', tarRed, 'promisc']) pt = 0x0800 s =
socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(pt))
s.bind((tarRed, pt))
#GETCheck def getchecksum(ip_header,size): cksum = 0 pointer = 0 while size > 1: cksum += int((str("%02x" % (ip_header[pointer],))
+ str("%02x" % (ip_header[pointer+1],))), 16) size -= 2 pointer += 2 #if size: #This accounts for a situation where the header is odd
#cksum += int(ip_header[pointer]) cksum = (cksum >> 16) +
(cksum & 0xffff) cksum += (cksum >>16) return (~cksum) &
0xFFFF def _checksum(data): #calculate the header sum
ip_header_sum = sum(struct.unpack_from("6H", data)) #add the carry
ip_header_sum = (ip_header_sum & 0xFFFF) + (ip_header_sum >> 8 &
0xFFFF) ip_header_sum = ~ip_header_sum & 0xFFFF return
ip_header_sum def i_checksum(checksum_packet): total = 0 num_words
= len(checksum_packet) / 2 for chunk in struct.unpack("!%sH" % num_words, checksum_packet[0:num_words*2]): total += chunk if
len(checksum_packet) % 2: total += ord(checksum_packet[-1]) << 8
total += total >> 16 return (~total + 0xffff & 0xffff)
def checksum(source_string): sum = 0 countTo =
(len(source_string)/2)*2 count = 0 while count<countTo:
thisVal = ord(source_string[count + 1])*256 + ord(source_string[count]) sum = sum + thisVal sum = sum &
0xffffffff
count = count + 2 if countTo<len(source_string): sum = sum + ord(source_string[len(source_string) - 1]) sum = sum &
0xffffffff sum = (sum >> 16) + (sum & 0xffff) sum = sum + (sum
>> 16) answer = ~sum answer = answer & 0xffff #answer = answer >> 8 | (answer << 8 & 0xff00) return answer def
checksuma(source_string): sum = 0 countTo =
(len(source_string)/2)*2 count = 0 while count<countTo:
thisVal = ord(source_string[count + 1])*256 + ord(source_string[count]) sum = sum + thisVal sum = sum &
0xffffffff
count = count + 2 if countTo<len(source_string): sum = sum + ord(source_string[len(source_string) - 1]) sum = sum &
0xffffffff sum = (sum >> 16) + (sum & 0xffff) sum = sum + (sum
>> 16) answer = ~sum answer = answer & 0xffff answer = answer >> 8 | (answer << 8 & 0xff00) return answer def ultimo(str):
csum = 0
countTo = (len(str) / 2) * 2
count = 0
while count < countTo:
thisVal = ord(str[count+1]) * 256 + ord(str[count])
csum = csum + thisVal
csum = csum & 0xffffffff
count = count + 2
if countTo < len(str):
csum = csum + ord(str[len(str) - 1])
csum = csum & 0xffffffff
csum = (csum >> 16) + (csum & 0xffff)
csum = csum + (csum >> 16)
answer = ~csum
answer = answer & 0xffff
answer = answer >> 8 | (answer << 8 & 0xff00)
return answer
#GETCheck
#MACs adst='ffffffffffff' mac_destino = unhexlify(adst) ma = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info =
fcntl.ioctl(ma.fileno(), 0x8927, struct.pack('256s', tarRed[:15]))
asrc = ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
sd = asrc.split(':') asrc = sd[0]+sd[1]+sd[2]+sd[3]+sd[4]+sd[5]
mac_origen = unhexlify(asrc)
#MACs cabEther = struct.pack('!6s6sh',mac_destino,mac_origen,pt)
#datosIP
#version = '4'
#IHL = '5' tipoServicio = unhexlify('00') longitudT = struct.pack('!BB',00,24) identificador = struct.pack('!BB',00,01)
flag_Pos = 0x4000 tiempoVida = 05 ptIP = unhexlify('01') SCC = 0
#IPs ip = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ipO= str( socket.inet_ntoa(fcntl.ioctl(ip.fileno(),0x8915,struct.pack('256s',
tarRed[:15]))[20:24])) ipO1 = ipO.split('.') ipOr =
struct.pack("!BBBB",int(ipO1[0]),int(ipO1[1]),int(ipO1[2]),int(ipO1[3]))
ipD = raw_input('Ingrese la direccion IP destino: ') ipD1 =
ipD.split('.') ipDest =
struct.pack("!BBBB",int(ipD1[0]),int(ipD1[1]),int(ipD1[2]),int(ipD1[3]))
#IPs
#datosIP cabIP = struct.pack('!1s1s2s2shB1sH4s4s',unhexlify('45'),tipoServicio,longitudT,identificador,flag_Pos,tiempoVida,ptIP,SCC,ipOr,ipDest)
SCC = checksum(cabIP) cabIP =
struct.pack('!1s1s2s2shB1sH4s4s',unhexlify('45'),tipoServicio,longitudT,identificador,flag_Pos,tiempoVida,ptIP,socket.htons(SCC),ipOr,ipDest)
#datosIcmp tipo = 8 codigo = 0x00 check = 0x0000 identificador = int((id(1) * random.random()) % 65535) secuencia = 0x0000
#datos = 'qwertyasdfghzxcvbn0102030405060708091011121314151617181920' datos =
1 * 'Q'
#datosIcmp cabIcmp = struct.pack('!bbHHh',tipo,0,0,identificador,1) my_checksum = ultimo(cabIcmp + datos) cabIcmp =
struct.pack('!bbHHh',tipo,0,socket.htons(my_checksum),identificador,1)
cabIcmp = cabIcmp + datos tiempo = datetime.now() print tiempo for i
in range(15): s.send(cabEther + cabIP + cabIcmp,0)

Your question is barely understandable. It appears you're asking how to create an ICMP ECHO packet since the packet you are creating in the listed code is reported as malformed by your system. I'll try to answer why your code won't work.
First, the socket type you're using is incorrect. You need type 1, not 8. This can be done easily enough with the third parameter:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
(Note you'll need root or administrator privileges to make this call.)
Second, after creating the socket, you'll need to create the ICMP header. An ICMP header consists of the following structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 | Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | REST OF HEADER |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Notice the second four bytes "REST OF HEADER". This second set of four bytes depends on the TYPE/CODE in the first two bytes. For example, if TYPE is 0 and CODE is 0, it means you're dealing with an echo reply, and as such, the second four bytes will become 2-byte Identifier and 2-byte Sequence Number fields, starting at offset 4 and ending at offset 7 as the picture shows:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 | Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 | Identifier | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 | Data ...
+-+-+-+-+-
To create this header, I'm going to use type 8, the echo request structure, as such (note that bytes 4-5 and 6-7 in this creation is just for illustration, typically this would be different values other than zero):
icmp = struct.pack(">BBHHH", 8, 0, 0, 0, 0)
On this initial creation of the header, the checksum is zero. What we now need is to actually calculate the checksum (with this zero value), and THEN recreate the header with this new checksum value:
icmp = struct.pack(">BBHHH", 8, 0, cksum(icmp), 0, 0)
But this is where your code is incorrect again. The implementation of i_checksum() is wrong. To fix, I'll leave it to you to figure it out. The checksum is called 1's complement, and there are numerous online articles about it, as well as C code on Linux systems that implement it.
Once you have the header and its correct checksum (important because your system won't send the packet if incorrect), you simply then send it somewhere:
s.sendto(icmp, (SOME_REMOTE_HOST, 0))
And then receive replies if any:
s.recvfrom(1500)
(Note I chose 1500 bytes as that is the MTU of an IP frame, and it is thus unlikely a reply will be bigger than this, though it is certainly possible.)
AND AT THIS POINT, YOUR CODE TOTALLY FAILS -- simply because you do not have code which does the last two steps, let alone additional code to handle what to do with replies and struct-parsing of the header fields.
As for the other two functions you've defined, they're odd. One of them seems to imply it is dealing with link layer fields -- which is never the case on sockets as sockets only deal in IP layer and above -- while the other seems to be an attempt at calculating a checksum...albeit incorrectly (again).
In short, as abarnert implied, please clarify (and add some more) code AND your question.

Related

How to get bit from bytearray in python?

I want to get the particular bit value from bytearray. I tried and its working fine, but let me know is there any optimize way to do this.
in_bytes = bytearray()
in_bytes .extend([5,10,15]) # output : bytearray(b'\x05\n\x0f')
tk = in_bytes [0]
bk = in_bytes [1]
sk = in_bytes [2]
print(tk, bk, sk) # 5 10 15
bk = 10 << 8
sk = 15 << 16
res = sk | bk | tk
print(res) # 985605
def get_bit_value(number, bit_position):
return (number >> bit_position) & 1
bit_value = get_bit_value(985605, 2)
print(bit_value) #
From this bytearray b'\x05\n\x0f', how can i get particular bit value?

Separate Data From Gyroscope Serial Port, Python

I have a Bluetooth gyroscope that I only want accelerometer data from. When I open the port the data will come in as a single, jumbled stream, right? How do I grab the data that I want? I want to simulate a keypress if acceleration is over a certain value, if that helps.
Since the data packet is 11 bytes, read 11 bytes at a time from the port, then parse the message. Note, you may want to read 1 byte at a time until you get a start-message byte (0x55) then read the following 10.
# data is a byte array, len = 11
def parse_packet(data):
# Verify message
if data[0] == 0x55 and data[1] == 0x51 and len(data) == 11:
# Verify checksum
if ((sum(data) - data[10]) & 0xFF) == data[10]:
g = 9.8 # Gravity
parsed = {}
parsed["Ax"] = ((data[3] << 8) | data[2]) / 32768.0 * 16 * g
parsed["Ay"] = ((data[5] << 8) | data[4]) / 32768.0 * 16 * g
parsed["Az"] = ((data[7] << 8) | data[6]) / 32768.0 * 16 * g
# Temp in in degrees celsius
parsed["Temp"] = ((data[9] << 8) | data[8]) / 340.0 + 36.53
return parsed
return None
The one thing you need to verify is the checksum calculation. I couldn't find it in the manual. The other calculations came from the manual I found here: https://www.manualslib.com/manual/1303256/Elecmaster-Jy-61-Series.html?page=9#manual

How I do circular shifting (rotation) of int in Python?

In Java right rotation is done using:
(bits >>> k) | (bits << (Integer.SIZE - k))
But how to do similar thing in Python?
I tried to do (as described here):
n = 13
d = 2
INT_BITS = 4
print(bin(n))
print(bin((n >> d)|(n << (INT_BITS - d)) & 0xFFFFFFFF))
Output:
0b1101
0b110111
But I could not interpret this as a right rotation.
Also is it possible to perform the rotation by excluding leading zeroes, for example:
rightRotation of (...0001101) = 1110 not 1000...110
It is my mistake, if you want to change INT_BITS to 4 you also need to change 0xFFFFFFFF to 0xF (one hex equals 4-bits):
n = 13
d = 2
INT_BITS = 4
print(bin(n))
print(bin((n >> d)|(n << (INT_BITS - d)) & 0xF))
will output:
0b1101
0b111

Extract bitfields from an int in Python

I have a number like 0x5423 where I want to extract 4 values:
a = 0x5 # 15 downto 12
b = 0x42 # 11 downto 3
c = 0x3 # 3 downto 2
d = 0x00 # 1 downto 0
I discovered the module bitstrings that looks great. Unfortunately, for an unknown reason, the bits are numbered from the right.
This is bad because if a add some upper bits like 0xA5423 my extraction won't work anymore:
field = bitstrings.BitArray('0x5423')
a = field[0:4].uint
b = field[4:12].uint
c = field[12:14].uint
d = field[14:16].uint
How can I properly extract my bitfields without complex arithmetic manipulations such as:
b = (a >> 4) & 0xFF
Ideally I would have:
b = field.range(11, 4)
Convert the string to 0x#### format before pass to bitstring.BitArray:
>>> n = '0xA5423'
>>> n = '0x{:04x}'.format(int(n, 16) & 0xffff) # => '0x5423'
>>> field = bitstring.BitArray(n)
>>> field[0:4].uint
5
>>> field[4:12].uint # 0x42 == 66
66
>>> field[12:14].uint
0
>>> field[14:16].uint
3
UPDATE another solution that does not depend on bitstring, and count from left(according to OP):
Convert the number into binary format:
>>> n = '0xA5423'
>>> n = format(int(n, 16), '016b')[::-1] # reversed
>>> n
'11000100001010100101'
>>> int(n[0:2][::-1], 2) # need to reverse again to get proper value
3
>>> int(n[2:4][::-1], 2)
0
>>> int(n[4:12][::-1], 2)
66
>>> int(n[12:16][::-1], 2)
5

While Loop to produce Mathematical Sequences?

I've been asked to do the following:
Using a while loop, you will write a program which will produce the following mathematical sequence:
1 * 9 + 2 = 11(you will compute this number)
12 * 9 + 3 = 111
123 * 9 + 4 = 1111
Then your program should run as far as the results contain only "1"s. You can build your numbers as string, then convert to ints before calculation. Then you can convert the result back to a string to see if it contains all "1"s.
Sample Output:
1 * 9 + 2 = 11
12 * 9 + 3 = 111
123 * 9 + 4 = 1111
1234 * 9 + 5 = 11111
Here is my code:
def main():
Current = 1
Next = 2
Addition = 2
output = funcCalculation(Current, Addition)
while (verifyAllOnes(output) == True):
print(output)
#string concat to get new current number
Current = int(str(Current) + str(Next))
Addition += 1
Next += 1
output = funcCalculation(Current, Next)
def funcCalculation(a,b):
return (a * 9 + b)
def verifyAllOnes(val):
Num_str = str(val)
for ch in Num_str:
if(str(ch)!= "1"):
return False
return True
main()
The bug is that the formula isn't printing next to the series of ones on each line. What am I doing wrong?
Pseudo-code:
a = 1
b = 2
result = a * 9 + b
while string representation of result contains only 1s:
a = concat a with the old value of b, as a number
b = b + 1
result = a * 9 + b
This can be literally converted into Python code.
Testing all ones
Well, for starters, here is one easy way to check that the value is all ones:
def only_ones(n):
n_str = str(n)
return set(n_str) == set(['1'])
You could do something more "mathy", but I'm not sure that it would be any faster. It would much more easily
generalize to other bases (than 10) if that's something you were interested in though
def only_ones(n):
return (n % 10 == 1) and (n == 1 or only_ones2(n / 10))
Uncertainty about how to generate the specific recurrence relation...
As for actually solving the problem though, it's actually not clear what the sequence should be.
What comes next?
123456
1234567
12345678
123456789
?
Is it 1234567890? Or 12345678910? Or 1234567900?
Without answering this, it's not possible to solve the problem in any general way (unless in fact the 111..s
terminate before you get to this issue).
I'm going to go with the most mathematically appealing assumption, which is that the value in question is the
sum of all the 11111... values before it (note that 12 = 11 + 1, 123 = 111 + 11 + 1, 1234 = 1111 + 111 + 11 + 1, etc...).
A solution
In this case, you could do something along these lines:
def sequence_gen():
a = 1
b = 1
i = 2
while only_ones(b):
yield b
b = a*9 + i
a += b
i += 1
Notice that I've put this in a generator in order to make it easier to only grab as many results from this
sequence as you actually want. It's entirely possible that this is an infinite sequence, so actually running
the while code by itself might take a while ;-)
s = sequence_gen()
s.next() #=> 1
s.next() #=> 11
A generator gives you a lot of flexibility for things like this. For instance, you could grab the first 10 values of the sequence using the itertools.islice
function:
import itertools as it
s = sequence_gen()
xs = [x for x in it.islice(s, 10)]
print xs

Categories