I have a small server in python that receives UDP Packets from GPS devices.
Once data is received, it is decoded and then stored in a postgresql database.
How do I monitor the UDP packets?
I think that for some reason the queue is filling up to quick and some of the information is being discarded.
For some reason if I restart the daemon, the queue gets processed as it seems there is data still there. Is there a better way to handle this?
Maybe should I run multiple servers to decrease the load?
Or is there any setting to increase the size of the queue?
I am new to socket programming so please bear with me!!
Code as follows:
#!/usr/bin/python
import sys, os, time
def main():
import socket
import struct
import sys, time
import psycopg2
import logging
try:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("myip", "udpport"))
con = psycopg2.connect("conn info")
cur = con.cursor()
while True:
data = server_socket.recv(65535)
#print data
#print sys.getsizeof(data)
logging.info(data)
if len(data) is 34:
# extract info
info = struct.unpack("<hhBBchfflccccccccccccc", data)
tid = ''.join([info[9] ,info[10] ,info[11] , info[12] , info[13] , info[14] ,info[15] , info[16] ,info[17] , info[18]])
alarm = info[4]
direction = info[5]
longt = info[6]
lat = info[7]
speed = ord(info[4])
fuel = ord(info[21])*2
datasize = sys.getsizeof(data)
messagetype = info[1]
if messagetype == 8:
dbmes = "cycle"
keystatus = int(info[2])
elif messagetype == 3:
dbmes = "alarm"
keystatus = int(info[3])
try:
# Update info on DB
cur.execute("update in database")
except Exception, e:
pass
# Commit Changes to DB
con.commit()
cur.close()
con.close()
except Exception, e:
print "\n\nNothing to do. Daemon Already Running!!!!\n"
if __name__ == "__main__":
# do the UNIX double-fork magic, see Stevens' "Advanced
# Programming in the UNIX Environment" for details (ISBN 0201563177)
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent, print eventual PID before
print "GREENCITY TANZANIA LTD GPRS SERVER PID %d" % pid
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# start the daemon main loop
main()
Related
I'm having trouble with receiving and sending data with Python's socket. In my script I need to listen to incoming data in socket and reading a FIFO file for a response and send it with socket when I find \n. I created separate thread for reading FIFO and it works but sometimes it is really slow. Is it possible to do both things in a main thread? My code:
#!/usr/bin/python
from __future__ import absolute_import, print_function, unicode_literals
from optparse import OptionParser, make_option
import os
import errno
import sys
import socket
import uuid
import dbus
import dbus.service
import dbus.mainloop.glib
import time
from threading import Thread
try:
from gi.repository import GObject
except ImportError:
import gobject as GObject
class ArduinoFifo:
fifofile = -1
OUT_PIPE_FILE = '/tmp/ble_pipe_out'
def removeFile(self, filename):
try:
os.remove(filename)
except OSError as e: # this would be "except OSError, e:" before Python 2.6
if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
print(e)
raise # re-raise exception if a different error occured
def createFifo(self):
print('removing pipe file\n')
self.removeFile(self.OUT_PIPE_FILE)
print('making pipe\n')
try:
os.mkfifo(self.OUT_PIPE_FILE, 0777)
except OSError as err:
print (err)
raise
def openFifo(self):
print('waiting to open pipe\n')
try:
self.fifofile = os.open(self.OUT_PIPE_FILE, os.O_WRONLY) # | os.O_NONBLOCK)
except OSError as err:
print (err)
def writeFifo(self, data):
try:
if (self.fifofile == -1):
openFifo(self)
os.write(self.fifofile, data)
except OSError as err:
print (err)
class FIFOReader(Thread):
def __init__(self, server_sock):
super(FIFOReader, self).__init__()
self.server_sock = server_sock
self.daemon = True
self.received_msg = ""
self.cancelled = False
print('remove in fifo')
try:
os.remove("/tmp/ble_pipe_in")
except OSError as e: # this would be "except OSError, e:" before Python 2.6
if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
print(e)
raise
print('create in fifo')
try:
os.mkfifo("/tmp/ble_pipe_in", 0777)
except OSError as err:
print (err)
raise
print('open in fifo')
try:
self.fifofile = os.open("/tmp/ble_pipe_in", os.O_RDWR)
except OSError as err:
print (err)
print('fifo in opened')
def run(self):
while not self.cancelled:
print("READING")
self.received_msg += os.read(self.fifofile, 1)
print("read: %s\n" % self.received_msg)
if "\n" in self.received_msg :
print("Sending Message...")
self.server_sock.send(self.received_msg)
self.received_msg = ""
def cancel(self):
self.cancelled = True
myfifo = ArduinoFifo()
class Profile(dbus.service.Object):
fd = -1
#dbus.service.method("org.bluez.Profile1",
in_signature="", out_signature="")
def Release(self):
print("Release")
mainloop.quit()
#dbus.service.method("org.bluez.Profile1",
in_signature="", out_signature="")
def Cancel(self):
print("Cancel")
#dbus.service.method("org.bluez.Profile1",
in_signature="oha{sv}", out_signature="")
def NewConnection(self, path, fd, properties):
global received_msg
self.fd = fd.take()
print("NewConnection(%s, %d)" % (path, self.fd))
server_sock = socket.fromfd(self.fd, socket.AF_UNIX, socket.SOCK_STREAM)
server_sock.setblocking(1)
myfifo.openFifo()
infifo = FIFOReader(server_sock)
infifo.start()
print('enter recv loop\n')
try:
while True:
data = server_sock.recv(1024)
#print("received: %s" % data)
if data:
myfifo.writeFifo(data)
#if data == "h":
#server_sock.send("Hello!\n")
except IOError as err:
print (err)
pass
server_sock.close()
print("all done")
os.kill(os.getpid(), 9)
#dbus.service.method("org.bluez.Profile1",
in_signature="o", out_signature="")
def RequestDisconnection(self, path):
print("RequestDisconnection(%s)" % (path))
if (self.fd > 0):
os.close(self.fd)
self.fd = -1
if __name__ == '__main__':
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez",
"/org/bluez"), "org.bluez.ProfileManager1")
option_list = [
make_option("-C", "--channel", action="store",
type="int", dest="channel",
default=None),
]
parser = OptionParser(option_list=option_list)
(options, args) = parser.parse_args()
options.uuid = "1101"
options.psm = "3"
options.role = "server"
options.name = "Edison SPP Loopback"
options.service = "spp char loopback"
options.path = "/foo/bar/profile"
options.auto_connect = False
options.record = ""
profile = Profile(bus, options.path)
mainloop = GObject.MainLoop()
opts = {
"AutoConnect" : options.auto_connect,
}
if (options.name):
opts["Name"] = options.name
if (options.role):
opts["Role"] = options.role
if (options.psm is not None):
opts["PSM"] = dbus.UInt16(options.psm)
if (options.channel is not None):
opts["Channel"] = dbus.UInt16(options.channel)
if (options.record):
opts["ServiceRecord"] = options.record
if (options.service):
opts["Service"] = options.service
if not options.uuid:
options.uuid = str(uuid.uuid4())
manager.RegisterProfile(options.path, options.uuid, opts)
myfifo.createFifo()
mainloop.run()
EDIT: I think the problem is in writing data to FIFO or receiving incoming data from socket because in my code in C I've got this delay when I want to read a data from the input FIFO using fgets function.
EIDT2: I use this to instantly receive a message and sends a response one after another
I doubt the issue has to do with the separate thread. "Threads" in Python aren't necessarily OS-level threads but could just be operations the main OS-level thread processes asynchronously. In cPython, which most people use, this is how they work. But I do see a couple of possible issues:
I'm not familiar with some of these libs, but os.read(self.fifofile, 1) stands out. If you use the builtin open() (not the one in os) or BufferedReader, this would be buffered and therefore ok. But os.open is a low-level call that doesn't buffer reads or writes, so you're actually reading 1 byte at a time from the file handle this way, which isn't a good idea as it can cause slowdowns for a variety of hard-to-trace reasons. You should either use a higher level library for this or do the buffering yourself.
Secondly, your +='ing of the read input to the message string repeatedly is going to be slow if your Python interpreter is creating a new string internally each time. So you could be looking at O(N^2) where N is message size time complexity for something that should be O(N). It depends on your interpreter, so to make things portable, you should be appending to a list instead.
Unrelated, but if you don't know whether your FIFO file is text, you shouldn't open it in text mode or else you'll run into errors. Strings only allow valid text bytes, UTF-8 if it's Py3 and I think ASCII if it's Py2, and you'll get an error if you receive, say, 0x00.
Hope this helps.
I have a small Python snippet that a monitoring tool that we have uses to pull information from crestron devices.
Is there a simple way to convert this small snippet into SSH.
I am not familiar with python at all so excuse me if there is an obvious answer but is this something that a free lance python programmer would be able to whip up or would this take a considerable amount of time.
Looking for any help I can get on this.
Thanks!
import time
import telnetlib
#Globals:
CACHE_DATA = {}
SNIPPET_NAME = 'Crestron: DCM Cache'
FAILED_COUNT = 0
COLLECTION_PROBLEM = False
TELNET_PORT = 23 ##Crestron only support port 23, don't use cred_port
TELNET_TIMEOUT = 2 ##default timeout in seconds, note if cred_timeout >= 2000 we will readjust later.
FAILED_ITEMS = []
self.logger.ui_debug('************** %s: Starting *******************' % (SNIPPET_NAME))
#Main:
if self.cred_details['cred_type'] == 5: ##only allow Snippet cred types...
#set global telnet timeout... if one has not been set, set it now.
if self.cred_details['cred_timeout'] >= 2000:
TELNET_TIMEOUT = int(self.cred_details['cred_timeout']/1000)
#start timer
start_time = time.time()
try:
#connect to telnet
tn = telnetlib.Telnet(self.cred_details['cred_host'], TELNET_PORT, TELNET_TIMEOUT)
#todo: add password handling.
tn.read_until(">", TELNET_TIMEOUT)
for obj_oid in result_handler.oids:
##obj_name = result_handler[obj_oid]['name']
try:
#run oid as CLI call from result_handler
tn.write(obj_oid+"\r")
rawdata = tn.read_until(">", TELNET_TIMEOUT)
if rawdata:
result_handler[obj_oid] = [(0,"Collection Ok")]
CACHE_DATA[obj_oid] = rawdata.strip()
else:
FAILED_COUNT += 1
result_handler[obj_oid] = [(0,"Failed: No data found")]
FAILED_ITEMS.append(obj_oid)
except:
FAILED_ITEMS.append(obj_oid)
result_handler[obj_oid] = [(0,'Failed: Collection: %s' % obj_oid)]
FAILED_COUNT +=1
#save job time for perf graph
CACHE_DATA['dcm_run_time'] = round(time.time() - start_time,4)
#gracefully quit the telnet session so as to not leave any defunct processes on the host device.
tn.write("bye\r")
tn.close()
if FAILED_COUNT is 0:
em7_cache_result(CACHE_DATA)
else:
COLLECTION_PROBLEM = True
PROBLEM_STR = "%s: Some Requests Failed: %s" % (SNIPPET_NAME, FAILED_ITEMS)
except:
COLLECTION_PROBLEM = True
PROBLEM_STR = "%s: Failed to Connect to Remote Device: %s: Port %s" % (SNIPPET_NAME, self.cred_details['cred_host'], TELNET_PORT)
else:
COLLECTION_PROBLEM = True
PROBLEM_STR = "%s: Wrong Credential Type Aligned to This Dynamic Application" % (SNIPPET_NAME)
You should check out paramiko.
Example for opening an SSH connection and running 'ls':
import base64
import paramiko
key = paramiko.RSAKey(data=base64.b64decode(b'AAA...'))
client = paramiko.SSHClient()
client.get_host_keys().add('ssh.example.com', 'ssh-rsa', key)
client.connect('ssh.example.com', username='strongbad', password='thecheat')
stdin, stdout, stderr = client.exec_command('ls')
for line in stdout:
print('... ' + line.strip('\n'))
client.close()
The following script is an extract from
https://github.com/RittmanMead/obi-metrics-agent/blob/master/obi-metrics-agent.py
The script is written in jython & it hits the weblogic admin console to extract metrics
The problem is it runs only once and does not loop infinitely
Here's the script that I've extracted from the original for my purpose:
import calendar, time
import sys
import getopt
print '---------------------------------------'
# Check the arguments to this script are as expected.
# argv[0] is script name.
argLen = len(sys.argv)
if argLen -1 < 2:
print "ERROR: got ", argLen -1, " args, must be at least two."
print '$FMW_HOME/oracle_common/common/bin/wlst.sh obi-metrics-agent.py <AdminUserName> <AdminPassword> [<AdminServer_t3_url>] [<Carbon|InfluxDB>] [<target host>] [<target port>] [targetDB influx db>'
exit()
outputFormat='CSV'
url='t3://localhost:7001'
targetHost='localhost'
targetDB='obi'
targetPort='8086'
try:
wls_user = sys.argv[1]
wls_pw = sys.argv[2]
url = sys.argv[3]
outputFormat=sys.argv[4]
targetHost=sys.argv[5]
targetPort=sys.argv[6]
targetDB=sys.argv[7]
except:
print ''
print wls_user, wls_pw,url, outputFormat,targetHost,targetPort,targetDB
now_epoch = calendar.timegm(time.gmtime())*1000
if outputFormat=='InfluxDB':
import httplib
influx_msgs=''
connect(wls_user,wls_pw,url)
results = displayMetricTables('Oracle_BI*','dms_cProcessInfo')
while True:
for table in results:
tableName = table.get('Table')
rows = table.get('Rows')
rowCollection = rows.values()
iter = rowCollection.iterator()
while iter.hasNext():
row = iter.next()
rowType = row.getCompositeType()
keys = rowType.keySet()
keyIter = keys.iterator()
inst_name= row.get('Name').replace(' ','-')
try:
server= row.get('Servername').replace(' ','-').replace('/','_')
except:
try:
server= row.get('ServerName').replace(' ','-').replace('/','_')
except:
server='unknown'
try:
host= row.get('Host').replace(' ','-')
except:
host=''
while keyIter.hasNext():
columnName = keyIter.next()
value = row.get(columnName )
if columnName.find('.value')>0:
metric_name=columnName.replace('.value','')
if value is not None:
if outputFormat=='InfluxDB':
influx_msg= ('%s,server=%s,host=%s,metric_group=%s,metric_instance=%s value=%s %s') % (metric_name,server,host,tableName,inst_name, value,now_epoch*1000000)
influx_msgs+='\n%s' % influx_msg
conn = httplib.HTTPConnection('%s:%s' % (targetHost,targetPort))
## TODO pretty sure should be urlencoding this ...
a=conn.request("POST", ("/write?db=%s" % targetDB), influx_msg)
r=conn.getresponse()
if r.status != 204:
print 'Failed to send to InfluxDB! Error %s Reason %s' % (r.status,r.reason)
print influx_msg
#sys.exit(2)
else:
print 'Skipping None value %s,server=%s,host=%s,metric_group=%s,metric_instance=%s value=%s %s' % (metric_name,server,host,tableName,inst_name, value,now_epoch*1000000)
I've tried to use the While loop, but that just stopped the code from exiting and not re-looping
What I want to achieve is to loop it infinitely post connection to weblogic
i.e. after this line
connect(wls_user,wls_pw,url)
and perhaps sleep for 5 seconds before re-running
Any and all help will be appreciated
Thanks
P
You can use this kind of condition for the loop :
mainLoop = 'true'
while mainLoop == 'true' :
and this for the pause between iterations :
java.lang.Thread.sleep(3 * 1000)
I've been searching a lot of examples for using GStreamer's python library on Windows but the only ones that work well are like this:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# GStreamer SDK Tutorials in Python
#
# basic-tutorial-2
#
"""
basic-tutorial-2: GStreamer concepts
http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+2%3A+GStreamer+concepts
"""
import sys
from gi.repository import Gst
Gst.init(None)
# Create the elements
source = Gst.ElementFactory.make("videotestsrc", "source")
sink = Gst.ElementFactory.make("autovideosink", "sink")
# Create the empty pipeline
pipeline = Gst.Pipeline.new("test-pipeline")
if not source or not sink or not pipeline:
print("Not all elements could be created.", file=sys.stderr)
exit(-1)
# Build the pipeline
pipeline.add(source)
pipeline.add(sink)
if not Gst.Element.link(source, sink):
print("Elements could not be linked.", file=sys.stderr)
exit(-1)
# Modify the source's properties
source.set_property("pattern", 0)
# Start playing
ret = pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
print("Unable to set the pipeline to the playing state.", file=sys.stderr)
exit(-1)
# Wait until error or EOS
bus = pipeline.get_bus()
msg = bus.timed_pop_filtered(
Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)
# Parse message
if (msg):
if msg.type == Gst.MessageType.ERROR:
err, debug = msg.parse_error()
print("Error received from element %s: %s" % (
msg.src.get_name(), err), file=sys.stderr)
print("Debugging information: %s" % debug, file=sys.stderr)
elif msg.type == Gst.MessageType.EOS:
print("End-Of-Stream reached.")
else:
print("Unexpected message received.", file=sys.stderr)
# Free resources
pipeline.set_state(Gst.State.NULL)
that is a simple test and uses just a "sink object", or the ones that stream the GStreamer example file (Sintel Movie Trailer), like this one:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# GStreamer SDK Tutorials in Python
#
# basic-tutorial-4
#
"""
basic-tutorial-4: Time management
http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+4%3A+Time+management
"""
import sys
from gi.repository import Gst
Gst.init(None)
# Python version of GST_TIME_ARGS
def convert_ns(t):
s, ns = divmod(t, 1000000000)
m, s = divmod(s, 60)
if m < 60:
return "0:%02i:%02i.%i" % (m, s, ns)
else:
h, m = divmod(m, 60)
return "%i:%02i:%02i.%i" % (h, m, s, ns)
def handle_message(data, msg):
if message.type == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print("Error received from element %s: %s" % (message.src.get_name(), err), file=sys.stderr)
print("Debugging information: %s" % debug, file=sys.stderr)
data["terminate"] = True
elif message.type == Gst.MessageType.EOS:
print("End-Of-Stream reached.")
data["terminate"] = True
elif message.type == Gst.MessageType.DURATION_CHANGED:
# The duration has changed, mark the current one as invalid
data["duration"] = Gst.CLOCK_TIME_NONE
elif message.type == Gst.MessageType.STATE_CHANGED:
if message.src == data["playbin"]:
old_state, new_state, pending_state = message.parse_state_changed()
print("Pipeline state changed from %s to %s." % (old_state.value_nick, new_state.value_nick))
data["playing"] = (new_state == Gst.State.PLAYING)
if data["playing"]:
query = Gst.Query.new_seeking(Gst.Format.TIME)
if data["playbin"].query(query):
(aux, data["seek_enabled"], start, end) = query.parse_seeking()
if data["seek_enabled"]:
print("Seeking is ENABLED from %s to %s" % (convert_ns(start), convert_ns(end)))
else:
print("Seeking is DISABLED for this stream.")
else:
print("Seeking query failed.", file=sys.stderr)
else:
print("Unexpected message received.", file=sys.stderr)
data = dict()
data["playing"] = False
data["terminate"] = False
data["seek_enabled"] = False
data["seek_done"] = False
data["duration"] = Gst.CLOCK_TIME_NONE
# Create the elements
data["playbin"] = Gst.ElementFactory.make("playbin", "playbin")
if not data["playbin"]:
print("Not all elements could be created.", file=sys.stderr)
exit(-1)
# Set the URI to play
data["playbin"].set_property(
"uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.webm")
# Start playing
ret = data["playbin"].set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
print("Unable to set the pipeline to the playing state.", file=sys.stderr)
exit(-1)
# Listen to the bus
bus = data["playbin"].get_bus()
while not data["terminate"]:
message = bus.timed_pop_filtered(100 * Gst.MSECOND,
Gst.MessageType.STATE_CHANGED |
Gst.MessageType.ERROR |
Gst.MessageType.EOS |
Gst.MessageType.DURATION_CHANGED)
# Parse message
if message:
handle_message(data, message)
else:
if data["playing"]:
fmt = Gst.Format.TIME
current = -1
# Query the current position of the stream
_, current = data['playbin'].query_position(fmt)
if not current:
print("Could not query current position", file=sys.stderr)
# If we didn't know it yet, query the stream duration
if data["duration"] == Gst.CLOCK_TIME_NONE:
_, data["duration"] = data['playbin'].query_duration(fmt)
if not data["duration"]:
print("Could not query current duration", file=sys.stderr)
print("Position %s / %s\r" % (
convert_ns(current), convert_ns(data["duration"])), end=' ')
sys.stdout.flush()
# If seeking is enabled, we have not done it yet, and the time is
# right, seek
if data["seek_enabled"] and not data["seek_done"] and current > 10 * Gst.SECOND:
print("\nReached 10s, performing seek...")
data['playbin'].seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 30 * Gst.SECOND)
data["seek_done"] = True
# Free resources
data["playbin"].set_state(Gst.State.NULL)
So, after trying to change the code I've got some questions:
Is this "file:///C:/folder/video.avi" the correct path format for GStreamer?
I know that I have to use a "playerbin" object and set its uri property but I don't know where exactly I should put that lines and how to use it properly.
Is there any problem caused by the video format?
Thank you so much for your help!
Looks right but I can't test it as I use Linux
Change the line:
data["playbin"].set_property(
"uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.webm")
to
data["playbin"].set_property("uri", "file:///C:/folder/video.avi")
No, it should be fine, playbin will run with just about anything that you throw at it.
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-playbin.html
to see the playbin properties that can be modified
How can I find with scapy wireless networks around? If I do sniff() and if pkt.haslayer(Dot11) and then if pkt.info then I collect them but very slow, for example my Android phone do it in seconds and this script in minutes or even more...
The reason for the difference is that your phone is actively looking for WiFi points by sending out requests to any access points nearby - sniff is listening for any passing traffic.
You might find is a lot quicker to:
Specifically select your network adapter - so you are not sniffing all adapters.
Do some digging to find out how to actively query for wifi networks and use sr with such packets, read the IEEE 802.11 specification to find out more, I would especially look for "Probe request frame".
The example on how to send WiFi packets from packet header may well help, (not my code and not tested by me):
#!/usr/bin/env python
"""
802.11 Scapy Packet Example
Author: Joff Thyer, 2014
"""
# if we set logging to ERROR level, it supresses the warning message
# from Scapy about ipv6 routing
# WARNING: No route found for IPv6 destination :: (no default route?)
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
class Scapy80211():
def __init__(self,intf='wlan0',ssid='test',\
source='00:00:de:ad:be:ef',\
bssid='00:11:22:33:44:55',srcip='10.10.10.10'):
self.rates = "\x03\x12\x96\x18\x24\x30\x48\x60"
self.ssid = ssid
self.source = source
self.srcip = srcip
self.bssid = bssid
self.intf = intf
self.intfmon = intf + 'mon'
# set Scapy conf.iface
conf.iface = self.intfmon
# create monitor interface using iw
cmd = '/sbin/iw dev %s interface add %s type monitor >/dev/null 2>&1' \
% (self.intf, self.intfmon)
try:
os.system(cmd)
except:
raise
def Beacon(self,count=10,ssid='',dst='ff:ff:ff:ff:ff:ff'):
if not ssid: ssid=self.ssid
beacon = Dot11Beacon(cap=0x2104)
essid = Dot11Elt(ID='SSID',info=ssid)
rates = Dot11Elt(ID='Rates',info=self.rates)
dsset = Dot11Elt(ID='DSset',info='\x01')
tim = Dot11Elt(ID='TIM',info='\x00\x01\x00\x00')
pkt = RadioTap()\
/Dot11(type=0,subtype=8,addr1=dst,addr2=self.source,addr3=self.bssid)\
/beacon/essid/rates/dsset/tim
print '[*] 802.11 Beacon: SSID=[%s], count=%d' % (ssid,count)
try:
sendp(pkt,iface=self.intfmon,count=count,inter=0.1,verbose=0)
except:
raise
def ProbeReq(self,count=10,ssid='',dst='ff:ff:ff:ff:ff:ff'):
if not ssid: ssid=self.ssid
param = Dot11ProbeReq()
essid = Dot11Elt(ID='SSID',info=ssid)
rates = Dot11Elt(ID='Rates',info=self.rates)
dsset = Dot11Elt(ID='DSset',info='\x01')
pkt = RadioTap()\
/Dot11(type=0,subtype=4,addr1=dst,addr2=self.source,addr3=self.bssid)\
/param/essid/rates/dsset
print '[*] 802.11 Probe Request: SSID=[%s], count=%d' % (ssid,count)
try:
sendp(pkt,count=count,inter=0.1,verbose=0)
except:
raise
def ARP(self,targetip,count=1,toDS=False):
if not targetip: return
arp = LLC()/SNAP()/ARP(op='who-has',psrc=self.srcip,pdst=targetip,hwsrc=self.source)
if toDS:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,FCfield='to-DS',\
addr1=self.bssid,addr2=self.source,addr3='ff:ff:ff:ff:ff:ff')\
/arp
else:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,\
addr1='ff:ff:ff:ff:ff:ff',addr2=self.source,addr3=self.bssid)\
/arp
print '[*] ARP Req: who-has %s' % (targetip)
try:
sendp(pkt,inter=0.1,verbose=0,count=count)
except:
raise
ans = sniff(lfilter = lambda x: x.haslayer(ARP) and x.op == 2,
store=1,count=1,timeout=1)
if len(ans) > 0:
return ans[0][ARP].hwsrc
else:
return None
def DNSQuery(self,query='www.google.com',qtype='A',ns=None,count=1,toDS=False):
if ns == None: return
dstmac = self.ARP(ns)
dns = LLC()/SNAP()/IP(src=self.srcip,dst=ns)/\
UDP(sport=random.randint(49152,65535),dport=53)/\
DNS(qd=DNSQR(qname=query,qtype=qtype))
if toDS:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,FCfield='to-DS',\
addr1=self.bssid,addr2=self.source,addr3=dstmac)/dns
else:
pkt = RadioTap()\
/Dot11(type=2,subtype=32,\
addr1=dstmac,addr2=self.source,addr3=self.bssid)/dns
print '[*] DNS query %s (%s) -> %s?' % (query,qtype,ns)
try:
sendp(pkt,count=count,verbose=0)
except:
raise
# main routine
if __name__ == "__main__":
print """
[*] 802.11 Scapy Packet Crafting Example
[*] Assumes 'wlan0' is your wireless NIC!
[*] Author: Joff Thyer, 2014
"""
sdot11 = Scapy80211(intf='wlan0')
sdot11.Beacon()
sdot11.ProbeReq()
sdot11.DNSQuery(ns='10.10.10.2')
I once wrote a script that could scan wireless network .
Its simple to use :
python rs.py mon0
Here mon0 is our interface. There are comments in the code to understand it properly.
#Implementation of a wireless scanner using Scapy library
#!/usr/bin/env python
# rs.py - Wireless AP scanner
#author rahil sharma
# date 15/3/2013 #rs
#usage python rs.py mon0
#where mon0 is your monitoring interface
#used this using my alfa card in bactrack
import sys, os, signal
from multiprocessing import Process
from scapy.all import *
interface='' # monitor interface
aps = {} # dictionary to store unique APs
# process unique sniffed Beacons and ProbeResponses.
#haslayer packet has Dot11 layer present
#ord() string to integer ex ord('a) will give 97
def sniffAP(p):
if ( (p.haslayer(Dot11Beacon))):
ssid = p[Dot11Elt].info
bssid = p[Dot11].addr3
channel = int( ord(p[Dot11Elt:3].info))
capability = p.sprintf("{Dot11Beacon:%Dot11Beacon.cap%}\
{Dot11ProbeResp:%Dot11ProbeResp.cap%}")
# Check for encrypted networks
#now we put Dot11Beacon.cap info in capability and using regular expression search inbuilt function in python we search for privacy if it is present then the network is encrypted
#output of the above cap file is somewhat like this short-slot+DSSS-OFDM+res15+ESS
if re.search("privacy", capability): enc = 'Y'
else: enc = 'N'
# Save discovered AP
aps[p[Dot11].addr3] = enc
# Display discovered AP
print "%02d %s %s %s" % (int(channel), enc, bssid, ssid)
# Channel hopper - we are making a channel hopper because we want to scan the whole wireless spectrum.
#first choose a random channel using randrange function
#use system to run the shell command iw dev wlan0 set channel 1
#exit when a keyboard interrupt is given CTrl+c
def channel_hopper():
while True:
try:
channel = random.randrange(1,15)
os.system("iw dev %s set channel %d" % (interface, channel))
time.sleep(1)
except KeyboardInterrupt:
break
# Capture interrupt signal and cleanup before exiting
#terminate is used to end the child process
#before exiting the program we will be displaying number of aps found etc.
#here Cntrl+c is used to
#signal_handler used to do clean up before the program exits
def signal_handler(signal, frame):
p.terminate()
p.join()
print "\n-=-=-=-=-= STATISTICS =-=-=-=-=-=-"
print "Total APs found: %d" % len(aps)
print "Encrypted APs : %d" % len([ap for ap in aps if aps[ap] =='Y'])
print "Unencrypted APs: %d" % len([ap for ap in aps if aps[ap] =='N'])
sys.exit(0)
#use this for command line variables
#for checking the number of command line variables and if they are in right order
if __name__ == "__main__":
if len(sys.argv) != 2:
print "Usage %s monitor_interface" % sys.argv[0]
sys.exit(1)
interface = sys.argv[1]
#take mon0 as interface given in the fist command line variable
# Print the program header
print "-=-=-=-=-=-= rs_scan.py =-=-=-=-=-=-"
print "CH ENC BSSID SSID"
# Start the channel hopper
#In multiprocessing, processes are spawned by creating a Process object and then calling its start() method
p = Process(target = channel_hopper)
p.start()
# Capture CTRL-C
#this will call the signal handler CTRL+C comes under the SIGINT
signal.signal(signal.SIGINT, signal_handler)
# Start the sniffer
sniff(iface=interface,prn=sniffAP)
#inbuit scapy function to start sniffing calls a function which defines the criteria and we need to give the interface`enter code here`