I use the following code to create a raw socket : http://pastebin.com/pmg9iKgG
As you can see, i want :
all TCP received packet send from port 5555 of a server to my PC,
all TCP send packets from my PC to port 5555 of a server.
The problem is : i'm only able to see incoming packets, not outgoing packets. This is quite annoying for a sniffer...
Could you help me with this?
I'm using Anaconda as python distro (3.6, x64), on windows 10. wireless (intel) or ethernet (through USB adapter cause slim laptop).
I've search the internet and i haven't seen any problem like that. Moreover, MSDN says that it should work in both way (outgoing and incoming) : https://msdn.microsoft.com/en-us/library/windows/desktop/ms740548%28v=vs.85%29.aspx
One common use of raw sockets are troubleshooting applications that need to examine IP packets and headers in detail. For example, a raw socket can be used with the SIO_RCVALL IOCTL to enable a socket to receive all IPv4 or IPv6 packets passing through a network interface. For more information, see the SIO_RCVALL reference.
I would appreciate any help with this )))
Just on thing :
i bypass this line of code :
host = socket.gethostbyname(socket.gethostname())
by :
host = "192.168.0.29"
cause it's not the right value (but that's not the problem, moreover the methode socket.getfqdn() does the job, but i didn't updated my script)
EDIT : it was the windows FW that caused this strange behaviour, by deactivating some filter, i was able to see all incoming and outgoing packets.
Related
I'm trying to setup a network to simulate an Edge computing scenario with LTE. But the question here is more pertaining to IP tables and raw sockets on the server.
I have the following setup:
PC-A is the Tower, PC-C is the LTE Core, PC-B is acting as intermediary and routing data using proxy ARPs
Cell phone wants to connect to a TCP server on PC-B(IP: 172.17.1.3)
Cell phone(IP:192.172.0.2) sends packets to PC-A(IP: 172.17.1.1)
The data from PC-A(172.17.1.1) generally has to reach LTE-EPC on 172.17.1.4 which is connected via PC-B(172.17.1.2 - 172.17.1.3 with proxy ARPs). And the data comes in the form of UDP packets to PC-B(IP: 172.17.1.2)
I use NAT table and python script with raw sockets to send all of these UDP packets to a local port, do some filtering, decapsulate the GTP headers and send the TCP/IP packet to the TCP server on PC-B interface(172.17.1.3). I use the below iptables settings to do this
iptables -t nat -A PREROUTING -p udp -d 172.17.1.4 --dport 2152 -j DNAT --to-destination 172.17.1.2:7000
Until here everything works, the extracted TCP/IP packet also reaches the TCP server on 172.17.1.3. The server responds to these packets. For example, for the SYN packet from the cell phone, the server now sends out SYN, ACK. However, the server responds to the original source address 192.172.0.2.
I want to catch these response TCP/IP packets from the TCP server 172.17.1.3 to 192.172.0.2 and do some GTP encapsulation before sending them back to PC-A.
Can anyone tell me how I can use the iptables to tell the kernel to stop dropping these martian packets with destination address 192.172.0.2, but instead forward to a local ip and port, so I can read the same.
I can see the SYN, ACK responses from the server on wireshark. But I assume that these are dropped as I already tried to route it to local ip:port using a similar iptables rule from above.
Any help is much appreciated, Thank you.
It sounds like a tun/tap interface could be useful here. Here's the official Linux kernel documentation.
Both these interface types allow a program to create a virtual network interface. This is designed for tunnels and VPNs and it seems like that is exactly what you are creating.
According to the linked documentation, you may create an interface by opening /dev/net/tun (O_RDWR) and issuing this ioctl to initialize it:
struct ifreq req;
memset(&req, 0, sizeof(req));
req.ifr_flags = IFF_TUN; // or IFF_TAP
strncpy(req.ifr_name, "tunnel%d", IFNAMSIZ); // optional; leave it blank to get a default name; you don't have to have a %d
ioctl(fd, TUNSETIFF, &req); // error check omitted for demonstration
// req.ifr_name now contains the name that was actually selected
After the ioctl you have a virtual network interface in your system. You can configure IP addresses, routes, whatever.
Any time the kernel sends a packet out through your interface it will go into a queue and you'll be able to read it. Any time you write to the interface the kernel will process it as if it's a real packet that just arrived.
You will need to configure networking like it's a real interface. Set up a static route so that 192.172.0.0/16 (or whatever your subnet is) is reached through the tunnel interface. I'm not sure if Linux will let you do this without giving it an address; you might have to give it a dummy address like 192.172.255.254. Or a completely unrelated address like 1.2.3.4 and then let Linux think there's another router in front of your cellphone subnet. Or maybe it will just work without an address - not sure.
The difference between "tun" and "tap" is whether Ethernet processing happens or not (IP tunnel vs Ethernet tap). I expect tun is right for your application. If you choose tap then Linux will also use ARP and so on, and the interface will certainly need an address.
You might find it convenient to use the tunnel interface in both directions, or just one. IP packets aren't required to take the same route in both directions. This is the "correct" way to implement a tunnel, so you might find that a lot of mysterious bugs go away by using it.
I need my own IP in a small script and in order not to hardcode it, I`ve found a piece of code from here(stackoverflow) that works.
This--
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
--
What is not clear for me is why it only works on UDP and not TCP? It has something to do with the google dns server? Thanks in advance.
This has nothing to do with Google and nothing to do with DNS.
All what this code does is to "connect" a UDP socket to an external IP, so that the OS kernel figures out which local IP address it needs to use in order to reach this external system. This is no real connection, i.e. there is no traffic involved but the OS kernel is only checking routing tables and local interfaces in order to decide which IP address to use as source in case one would actually use the socket to send data.
One could do the same with TCP. But in this case a real TCP connection would be established which means that actual traffic would be exchanged and that the connect would fail if the external system would not be reachable on this port (i.e. no listener, firewall in between etc).
With UDP instead connect will not produce any traffic and would fail only if no route to the destination IP address could be determined. This also means that an arbitrary external IP address and port could be used, i.e. ('1.1.1.1',11) would work the same as ('8.8.8.8',80).
My goal is to have remote control of a device on a WLAN. This device has software that enables me to configure this wireless network (IP, mask, gateway, dns). I can successfully connect this device, and my computer to a common network. Since both machines share the same network, I made the assumption that I would be able to open up a socket between them. Knowing the IP and port of the device that I am attempting to control remotely I used the following code, only to receive a timeout:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.xxx.xxx', XXXX))
(I am using python 2.7 on mac OS 10.11.6)
The network that I am connected to is on a different subnet that the IP that I assigned to my device. I also tried this having an IP on the same subnet as my network. There could be a number of things keeping me from opening a socket. That's not really what I'm after. The heart of my question is whether or not I can use python's 'socket' module to connect to a device wirelessly.
Yes you can.
So you get a timeout when you try to connect to a wireless device. There are several steps you can take in order to troubleshoot this.
Make sure your device has a program running that is listening to the port you want to connect to. Identify if the device can answer ICMP packets in general and can be pinged in particular. Try to ping the device. If ping succeeds, it means that basic connectivity is established and the problem is somewhere higher in the OSI stack.
- I can ping the device - great, it means that the problem is somewhere in TCP or Application Layer of the TCP/IP stack. Make sure the computer, the device, and intermediate networking equipment allow for TCP connections to the particular host and port. Then proceed to your application and the device software. Add some code to the question, post the stack trace you get or ask another one on SO.
- I can't ping the device - great. There's no connectivity between the devices and you're to identify the reason.
I) Draw a network diagram. How many intermediate network devices are placed in between the computer and the device? What are they, routers, switches? (Just in case, home grade wifi modem is a router.) Get an idea of how IP datagrams should travel across the net.
II) You said that the device can be used to configure an IP network. At least for troubleshooting purposes I would ignore this option and rely on a static IP or your router's DHCP server. Using an existing DHCP will ensure there's no IP misconfigurations.
III) Review routing tables of all the devices you have. Do they have an appropriate default gateway? Does a router knows how to pass the packets to the device. You're probably in trouble if the computer and the device are in the same subnet but attached to different network interfaces. Split the network in two subnets if needed and set up static routes between them on the router.
You can also use wireshark to see if data you send leaves the computer or is dropped right there by some nasty firewall.
There's a lot of caveats in getting a LAN working. You may want to ask questions on networking.stackexchange if these simple steps doesn't help you or if you have major troubles following them. Or just leave a comment here, I'd be happy to help.
I need to transfer data via pyzmq through two computers connected by an ethernet cable. I have already set up a script that runs on the same computer correctly, but I need to find the tcp address of the other computer in order to communicate. They both run Ubuntu 14.04. One of them should be a server processing requests while the other sends requests. How do I transfer data over tcp through ethernet? I simply need a way to find the address.
EDIT: (Clarification) I am running a behavioural study. I have a program called OpenSesame which runs in python and takes python scripts. I need a participant to be able to sit at a computer and be able to ask another person questions (specifically for help in a task). I need a server (using pyzmq preferably) to be connected by ethernet and communicate with that computer. It wrote a script. It works on the same computer, but not over ethernet. I need to find the address
Tcp is a protocol that uses an internet connection to Transfer data, through an IP address and specific port, you have to ensure that those ip directions are in the same range and uses the same port. For example: one pc 192.168.1.50 and another pc 192.168.1.60 in 502 port. The easiest way is using a Modem and set an statical address for each pc.
In the following link, you can find easily in which ip direction is connected your Computer. http://www.howtogeek.com/howto/17012/how-to-find-your-ip-address-in-ubuntu/
Maybe you could periodically send datagram message containing peer's ip address (or some other useful information) to broadcast address, to allow other peers to discover it. And after peer's address is dicovered you can estabish connection via ZeroMQ or other kind... connection. :)
I am trying to implement a python traceroute that sends UDP messages and receives the ICMP responses via raw sockets. I've run into an issue where the ICMP packets seem to avoid capture at all cost. The ICMP responses show up in wireshark as exactly what I'd expect, but the socket never receives any data to read. Another complication is that I am running the code on VirtualBox running Ubuntu, as the sendto() would not get the packets on the wire in Windows 7. (I'm running wireshark in windows to capture the packets). The strange thing is that wireshark will capture the ICMP messages when I run the python script from the virtual machine. However, when I try to run the script on windows, the ICMP messages don't show up in wireshark. (The UDP packets have magically started working on windows)
I've played around with all sorts of different versions of setting up the socket from online examples, and played around with using bind() and not using it, but no configuration seems to produce a socket that reads. It will just time out waiting to read the ICMP message.
It should also be noted that if I try to read my udp sending socket, it successfully reads the udp packets. As soon as I set IPPROTO_ICMP the read times out.
receive_response method:
def receive_response(rec_socket, packetid, tsend, timeout):
remain = timeout
print packetid
while remain > 0:
ready = select.select([rec_socket], [], [], remain)
if ready[0] == []:
return
print 'got something'
setting up the socket:
rec_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, ICMP_CODE)
rec_socket.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
rec_socket.bind(("",0)) #played with using this statement and skipping it
call to receive is simply:
reached = receive_response(rec_socket, packetid, time.time(), timeout)
It looks like the problem is VirtualBox will default to using NAT to connect to the network. This means that the virtual machine won't receive the ICMP messages by virtue of them being ICMP messages. It seems like the solution to this is to configure VirtualBox networking to use "Bridged networking" mode. Unfortunately I cannot confirm this as I can't set up the virtual machine on my university's network within bridged mode. As for the reason they didn't work in windows, it must be related to windows' lack of support for raw sockets.