How to capture UDP packets with Python - python

Facts & context elements:
I need to capture data (latitude,longitude) coming out of a GPS device rework them and make them suitable for another application (QGIS). To this end I've tried to perform (What I thought at first would be a simple one) a python based module.
According to wire shark analysis.
Source Destination Protocol length info
192.168.0.1 225.2.5.1 UPD 136 source port : 1045 destination port:6495
I've tried this code found on various sources, like this one.
import socket
import os
UDP_IP = "225.2.5.1"
UDP_PORT = 6495
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(4096) # buffer size is 1024 bytes
print "received message:", data
os.system("pause")
The problem
This code doesn't work for me.The console windows whether collapse (despite the os.system("pause") or run indefinitely. As I'm not very skilled in python programming nor networking I've tested the provided code with the other IP address and port. As no result came from it I've also started to mix both of them. And finally, gave up and decided to share my issue with the community.
The aim :
I need to be able to access the data contains in this UDP frame with python 2.7 save them in a variable (data) for the next step of my programming project.
Thanks for reading and for your help

You should start your python program from the windows cmd-console or powershell, not from the explorer, then the window stays open and you see error messages. Remove the indentation error and the last line. Be sure, that your computer has the given IP-address. Bind your socket to any address:
import socket
UDP_IP = "0.0.0.0"
UDP_PORT = 6495
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(4096)
print "received message:", data

Related

In python want to read the UDP broadcast message on particular port

I am new to python programming. I have the task to read the broadcast feed on UDP port 4012.I have code of visual basic and it is working fine. The code is as follows.
#Dim receivingUdpClient As New UdpClient(4012)
#Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
#receiveBytes = receivingUdpClient.Receive(RemoteIpEndPoint)
#returnData = Encoding.ASCII.GetString(receiveBytes)
#Dim TestArray() As String = Split(returnData, ";")
I made the following program in python to read the broadcast feed on UPD port 4012, but was unable to achieve it with the following python program. The program is working and shows the cmd window message "waiting for 4012 localhost from 4012".
Can anybody help me out with this? If the code is correct then, how can i checked resolve this issue? i also want to read good material about socket programming in python specially about the UDP socket Broad Cast reading, if anybody can recommend any video or material for read.
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_host = 'localhost'
udp_port = 4012
s.connect((udp_host,udp_port))
print("waiting for 4012",udp_host, "from" ,udp_port)
data , addr= s.recvfrom(1024)
print("Received Messages: ", data ,"from", addr)
You should use broadcast IP to listen.
Currently you are listening 'localhost', but broadcast IP is usually your subnet maximum IP (for 255.255.255.0 mask it is IP with number 255 in last octet)
You need to get right IP from somewhere. Manually you can do it with ifconfig on *nix, or ipconfig on Win:
inet 192.168.100.7 netmask 0xffffff00 broadcast 192.168.100.255
so you need 192.168.100.255
Also, easy way is to listen all IP's. To listen all IP's you could bind socket to '0.0.0.0' or just ''. But in this case you'll catch both broadcast and direct packets.
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_host = ''
udp_port = 4012
s.connect((udp_host,udp_port))
print("waiting for 4012",udp_host, "from" ,udp_port)
data , addr= s.recvfrom(1024)
print("Received Messages: ", data ,"from", addr)
this snippet is something i use quite often do create basic socket server stuff...
socket_config = {
'udp_ip_address': 'your.ip.here.bla',
'udp_port_no': '6789',
'max_send_size': '1024'
}
#
# socket creation
#
serverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
serverSock.bind((socket_config['udp_ip_address'],
int(socket_config['udp_port_no'])))
def receive_loop():
# eternal loop starts here
while True:
data, addr = serverSock.recvfrom(int(socket_config['max_send_size']))
data = data.decode('utf-8')
logger.debug("Message:" + data)

Send data via UDP connection (Bridge)

I've been tasked to create a proof of concept with an Arduino Mega + Yun Shield. I've started from the Bridge sample and I can read my sensors and exposed the data through REST.
But, instead of REST, I want to send packets through UDP. I know there is samples around the web about UDP but I've have found nothing that use UDP with Bridge.
Is this feasible?
UPDATE #1
Ok, I read somewhere that is not possible. But I read also that is possible to run a Python script to send data through UDP.
I made that script:
import socket
import sys
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('192.168.1.100', 9050)
message = 'This is the message. It will be repeated.'
try:
# Send data
print >>sys.stderr, 'sending "%s"' % message
sent = sock.sendto(message, server_address)
finally:
print >>sys.stderr, 'closing socket'
sock.close()
And call it from the Arduino this way:
Process p;
p.begin("python");
p.addParameter("/test/sendUDP.py");
p.run();
The code run without errors apparently, but my UDP server receive nothing. However, it works with PuTTY.
UPDATE #2
It works! I changed this line:
p.addParameter("/root/test/sendUDP.py");
I changed this line and it works like a charm:
p.addParameter("/root/test/sendUDP.py");

Python UDP broadcast

Ok im going to try an explain what is going on here... I have a network of multiple same type devices. I have a program that runs on any pc on the network that discovers these individual devices and categorizes them by ip, name, mac, etc.. This program allows for configuration of each device. The devices broadcast a udp packet to "255.255.255.255" with the information for discovery. I can run wireshark and intercept the packets broadcasted from the devices. I have a python program that will broadcast udp packets with data of my choosing.. Now.. This stems from me learning python and my project oriented approach.. I learn better this way :). Ok that being said.. My idea is to broadcast the exact udp packet that another device broadcasts, which in turn should land me on the discovery software as a particular network device.. By following udp stream in wireshark i can copy the data and enter it in my python program and broadcast it on the network. I can broadcast to any destination ip and see it in wireshark but when i try and send it to 255.255.255.255 it never shows up. Now i understand that routers will not forward 255x4 broadcasts pass the local network. When i run the discovery program i can see all the devices broacasting their packets to 255x4 but not the packet originating from my pc. Any ideas would be greatly appreciated.
Python Code:
import udp
import socket #for sockets
import sys #for exit
# create dgram udp socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
host = '255.255.255.255';
port = 55558;
while(1) :
msg = '''...z..
hrQT.b.......hrQT.b
.....w...NanoStation M2...N2N
..Test......"XM.ar7240.v5.6.2.27929.150716.1201........NanoStation M2'''
try :
#Set the whole string
s.sendto(msg, (host, port))
# receive data from client (data, addr)
d = s.recvfrom(1024)
reply = d[0]
addr = d[1]
print 'Server reply : ' + reply
except socket.error, msg:
print 'Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
To receive UDP packets, you need to bind the socket to the IP address and UDP port that you want to receive packets on.
1 import socket
2
3 UDP_IP = "127.0.0.1"
4 UDP_PORT = 5005
5
6 sock = socket.socket(socket.AF_INET, # Internet
7 socket.SOCK_DGRAM) # UDP
8 sock.bind((UDP_IP, UDP_PORT))
9
10 while True:
11 data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
12 print "received message:", data
I would recommend using different UDP sockets for sending and receiving packets.

How to capture the ZPL ^HV ouotput

I need help implementing the ^HV ZPL command and to capture it as the host.
I want to read the TID and encode it to the EPC using Python, i can send print and encode command to the printer but how do i read back from it ?
If I'm using the "Direct Communication" program in the Zebra Setup Utilities tool i can get the TID back in the "Data received" window.
Ive tried using TCP/IP but i dont know how to pull the info just to print
But how can i capture it using python ?
Thanks !
Communicating with a Zebra printer over TCP is the same as any other TCP connection. If the question is how to use the ^HV command, it is usually put into a stored format. The response happens when you use the format to print. Here's a snippet I modified from wiki.python.org.
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 9100
BUFFER_SIZE = 1024
FORMAT = "^XA^DFE:TEST.ZPL^FO30,30^A0N,50,50^FN1^FS^HV1,15,[,],^FS^XZ"
PRINT = "^XA^XFE:TEST.ZPL^FN1^FDHELLO WORLD^FS^XZ"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(FORMAT)
s.send(PRINT)
data = s.recv(BUFFER_SIZE)
s.close()
print "received data:", data

Python sends malformed UDP Packets

I am having trouble receiving UDP packets on an Android device, so I want to find out if I am sending them properly. Using Wireshark, everytime I try to send a UDP packet to a remote address, the following error message occurs:
232646 311.898009000 172.56.16.78 192.168.0.3 UDP 64 Source port: 31947 Destination port: 5001 [ETHERNET FRAME CHECK SEQUENCE INCORRECT]
Frame check sequence: 0xf5b6d06d [incorrect, should be 0xb0c869e3]
Does anyone know how to fix this? Would this be the cause of why I could not receive UDP packets on my Android device?
Server Code:
import http.server
import socket
import threading
import socketserver
class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
data = self.request[0].strip().decode("utf-8")
print("{} Recieved: ".format(self.client_address) + data)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
response = data.upper()
sock.sendto(bytes(response, "utf-8"), self.client_address)
print("{} Sent: {}".format(self.client_address,response))
if __name__ == "__main__":
udpserver = ThreadedUDPServer((HOST,PORT+1), ThreadedUDPRequestHandler)
udp_thread = threading.Thread(target=udpserver.serve_forever)
udp_thread.daemon = True
udp_thread.start()
print("UDP serving at port", PORT+1)
while True:
pass
udpserver.shutdown()
It seems like you're sending packets using regular userspace sockets. In that case, there's very little chance that the packets are being sent malformed since the FCS is generated physically by the network interface card.
What you're probably seeing is an FCS error due to completely different reasons, which can be safely disregarded.
I'd look for other reasons for why the other device doesn't receive the packet, like firewalls or NAT. Start by using netcat or a similar tool for sending and receiving the UDP packets between the two machines.

Categories

Resources