decoding DHCP Giaddr, Yiaddr, Ciaddr, siaddr fields with dpkt - python issue - python-2.7

Whenever I try to load Giaddr (or YIADDR Ciaddr, siaddr ) for any DHCP packet it prints random string of numbers. ( this happens for each n every packet I load)
Am I doing something wrong or it's a bug in code?
code
dh = dpkt.dhcp.DHCP(udp.data)
print dh.giaddr
output :
182435815
I am pretty sure that my giaddr(relay ip) is 10.223.191.231 - confirmed in wireshark for this packet.

Your output is correct. You have a the integer value of the address.
To print the dotted-decimal version, you can do this:
>>> import struct
>>> socket.inet_ntoa(struct.pack(">L",x))
'10.223.191.231'

Related

How to send ascii characters through serial in python?

I want to send 3 numbers (integers) through serial port in ascii format. I use putty terminal to see the receiving data on the other end. The problem is that putty doesn't shows anything except strings. I tried to use the ord() function to get the ascii format but I cannot see anything on putty. Is it just a putty problem with ascii format, or I don't send data at all? How can I be sure that I send the data in the correct format (ascii)?
I am new to python, so sorry if this sounds trivial.
I use Ubuntu 16.04 LTS and Python 2.7.12.
Thank you in advance!
#!/opt/bin/python
import serial
import time
camera = [0, 0, 0]
ser = serial.Serial('/dev/ttyUSB0', 9600)
print (ser.name)
print ("Port Open")
time.sleep(2)
while ser.isOpen():
for i in range(1):
#ser.write(b'5')
#ser.write(chr(5))
#ser.write(5)
ser.write(ord(str(camera[0])))
#ser.write(bytes(camera))
print(camera)
time.sleep(1)
camera[1] = camera[1] + 1
ser.close()

how do i store the result of ICMP Reply Packet into variable for further use?

I am new to python. As a beginner i am facing a problem that how to store the result of ICMP reply in to variable so that it can be further used in the script in python ? i am using scapy tool along with python for packet creation.
My script is-
#!/usr/bin/python
from scapy.all import *
mac=”3c:97:0e:57:00:f1”
def build_req():
For v in range(2, 4094):
Pkt = sendp(Ether(src=”ff:ff:ff:ff:ff:ff”)/Dot1Q(vlan=v)/ARP(hwsrc=mac, psrc=”192.168.1.108”,pdst=”192.168.1.107”)/ICMP()/Padding(load=”x”*10),iface=”enp0s25”)
If response is None:
Print “vlan id is not found”
Else:
Print “vlan id found’
Sys.exit(1)
Return pkt
{ I want to store the icmp response coming from vlan id in a variable and use that response to send the packet }
You are only sending packets, but not trying to get the response. Scapy documentation tells you how to do so:
https://scapy.readthedocs.io/en/latest/usage.html#send-and-receive-packets-sr

How to use regular expressions to pull something from a terminal output?

I'm attempting to use the re module to look through some terminal output. When I ping a server through terminal using ping -n 1 host (I'm using Windows), it gives me much more information than I want. I want just the amount of time that it takes to get a reply from the server, which in this case is always denoted by an integer and then the letters 'ms'. The error I get explains that the output from the terminal is not a string, so I cannot use regular expressions on it.
from os import system as system_call
import re
def ping(host):
return system_call("ping -n 1 " + host) == 0
host = input("Select a host to ping: ")
regex = re.compile(r"\w\wms")
final_ping = regex.search(ping(host))
print(final_ping)
system returns 0, not anything too useful. However, if we were to do subprocess, we can get teh output, and store it to a variable, out, then we can regex search that.
import subprocess
import re
def ping(host):
ping = subprocess.Popen(["ping", "-n", "1", host], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, error = ping.communicate()
return str(out)
host = input("Select a host to ping: ")
final_ping = re.findall("\d+ms",ping(host))[0]
print(final_ping)
Output:
22ms
There are two problems with your code:
Your ping function doesn't return the terminal output. It only returns a bool that reports if the ping succeeded. The ping output is directly forwarded to the terminal that runs the Python script.
Python 3 differentiates between strings (for text, consisting of Unicode codepoints) and bytes (for any data, consisting of bytes). As Python cannot know that ping only outputs ASCII text, you will get a bytes object if you don't specify which text encoding is in use.
It would be the best to use the subprocess module instead of os.system. This is also suggested by the Python documentation.
One possible way is to use subprocess.check_output with the encoding parameter to get a string instead of bytes:
from subprocess import check_output
import sys
def ping(host):
return check_output(
"ping -n 1 " + host,
shell=True,
encoding=sys.getdefaultencoding()
)
...
EDIT: The encoding parameter is only supported since Python 3.6. If you are using an older version, try this:
from subprocess import check_output
import sys
def ping(host):
return check_output(
"ping -n 1 " + host,
shell=True
).decode()
...

How to get MAC address of connected Access point?

I am using Scapy to sniff access point(AP) beacon packets and also getting all AP beacon packets and it's MAC address nearby AP but I need exact MAC address of connected AP then How to sniff only connected AP beacon frame or How to filter connected AP beacon frame using scapy or any alternate idea.
*I am doing it in python 2.7
Assuming the beacon frame is called pkt. pkt.addr1 is the destination MAC, pkt.addr2 is the source MAC and pkt.addr3 is the MAC address of the AP. You could write something like:
from scapy.all import *
def ap_mac(pkt):
if pkt.haslayer(Dot11)
if pkt.type == 0 and pkt.subtype == 8:
print('SSID: '+%s+' MAC:'+%s)(pk.info,pkt.addr3)
else: pass
else: pass
sniff(prn=ap_mac)
to print out all the AP MACs from beacon frames. Then you could use something like:
from scapy.all import *
def sniff_ap(pkt):
if pkt.haslayer(Dot11):
if pkt.add3 == 'xx.xx.xx.xx.xx.xx': ## AP MAC
print(pkt.summary())
else: pass
else: pass
sniff(prn=sniff_ap)
Here is a good link re: beacon frames. https://www.4armed.com/blog/forging-wifi-beacon-frames-using-scapy/
I choose alternate method i.e using command in python program
Code snippet
def Check_connected_ap():
cmd =["nmcli -f BSSID,ACTIVE dev wifi list | awk '$2 ~ /yes/ {print $1}'"]
address = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(out, err) = address.communicate()
print out

Failed ping request in Python script

I have a python script that want to ping a few (quite a few!) hosts. I have set this up to read the contents of a hosts.txt file as the hosts to ping in the script. The odd thing is that I am recieving the following error, for the first few addresses (no matter what they are):
Ping request could not find host 66.211.181.182. Please check the name and try again.
I have included the address shown above at twice (within the file) and it attempts a ping. Any thoughts on what I am doing wrong - I am a python newbie, so be gentle.
Here is my script:
import subprocess
hosts_file = open("hosts.txt","r")
lines = hosts_file.readlines()
for line in lines:
ping = subprocess.Popen(
["ping", "-n", "1",line],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
out, error = ping.communicate()
print out
print error
hosts_file.close()
Here is my hosts.txt file:
66.211.181.182
178.236.5.39
173.194.67.94
66.211.181.182
And here are the results from the above test:
Ping request could not find host 66.211.181.182
. Please check the name and try again.
Ping request could not find host 178.236.5.39
. Please check the name and try again.
Ping request could not find host 173.194.67.94
. Please check the name and try again.
Pinging 66.211.181.182 with 32 bytes of data:
Request timed out.
Ping statistics for 66.211.181.182:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)
Looks like the line variable contains a linebreak at the end (except for the last line of the file). From the Python tutorial:
f.readline() reads a single line from the file; a newline character (\n) is left at the end of the string, and is only omitted on the last line of the file if the file doesn’t end in a newline.
You need to strip the \n before calling Popen: How can I remove (chomp) a newline in Python?
Few comments:
Using readlines() is highly not recommended as it will load the entire file into memory.
I suggest using Generator in order to perform rstrip on each line and then pinging the server.
No need to use file.close - you can use with statement that does it for you
Your code should look like this:
import subprocess
def PingHostName(hostname):
ping=subprocess.Popen(["ping","-n","1",hostname],stdout=subprocess.PIPE
,stderr=subprocess.PIPE)
out,err=ping.communicate();
print out
if err is not None: print err
with open('C:\\myfile.txt') as f:
striped_lines=(line.rstrip() for line in f)
for x in striped_lines: PingHostName(x)