Windows/Python UDP Broadcast Blocked No Firewall - windows

OS: Windows 10
I use an Ethernet switch to send UDP packets to two other systems (connected directly to that same switch) simultaneously via Python 3.4.4. The same code works on two other dev/testing PC's so I know it's not the Python code, but for some reason it doesn't work on the PC that I want the system to be utilized by.
When I use Wireshark to view the UDP traffic at 169.254.255.255 (the target IP for sending the UDP packets to), nothing appears. However, sending packets to 169.X.X.1 works. On the other hand, packets sent to 169.X.X.255 are sent, but I receive time-to-live exceeded messages in return. I am restricted to that target IP, so changing the IP is not a solution. I also have it sending on port 6000 (arbitrary), I have tried changing the port number to no avail. Also won't let me send to 169.254.255.1
I have the firewalls turned off.
Thanks for your help.

same problem here,
solution is bind socket to adapter which is sending multicast
example:
msg = \
'M-SEARCH * HTTP/1.1\r\n' \
'HOST:239.255.255.250:1900\r\n' \
'ST:upnp:rootdevice\r\n' \
'MX:2\r\n' \
'MAN:"ssdp:discover"\r\n' \
'USER-AGENT:Python\r\n\r\n'
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
s.bind(('ip of interface',1901))
s.settimeout(10)
print msg,len(msg)
print s.sendto(msg, ('239.255.255.250', 1900) )
resp, (addr, port) = s.recvfrom(1024)
print resp
s.close()
solution from this post Can't send multicast over non-default NIC

The strange thing about my problem, was that this exact code worked on the computer in question (and two development computers) previously, but wasn't working at the time that I posted this question.
Wireshark wasn't leading me to my answer (only showing me that the UDP packets were not sent), so I decided to ping the IP via the command prompt. I received one of two errors (destination host unreachable, or request timed out). These errors led me to adding my desired target IP (169.254.255.255) to the ARP cache, which my problem was solved.
I'd like to thank you for suggesting a possible solution.

Related

Listening for UDP response from DLNA renderer with BASH on WSL

I'm attempting to write a script to connect to a DLNA audio renderer.
There are a few articles on the web giving information on how to do this using UDP and curl, however in my particular scenario I'm having some difficulties.
The first step is to send a UDP multicast announcement over the network to discover DLNA devices on the network.
The message sent to discover devices is:
M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MX: 5
Man: "ssdp:discover"
ST: urn:schemas-upnp-org:device:MediaRenderer:1
All lines in this message sent over UDP should have crlf line endings and the last line should have an extra crlf according to this article
That all seems fine. And if the message above is in a file devicediscovery.txt supposedly it's possible to use netcat to send out this message:
cat devicediscovery.txt | nc -u -4 239.255.255.250 1900
239.255.255.250:1900 is the multicast address and port over which DLNA devices communicate.
This all seems fine too, however, as is pointed out in the linked article netcat ignores the response from the dlna media renderer because there is a mismatch in IP addresses the message is sent out over the dlna multicast address, though the response comes from the router. The article suggests using tcpdump to capture the response, however I'm on Windows and using Bash on Windows WSL so tcpdump is not available and such a technique would possibly be complicated when developing a script to automate the dlna connection.
Would it be possible to use two seperate instances of netcat? One instance sending the message over the dlna multicast address and the other listening for the response from the router?
I have tried to get this working, however I'm unsure which port netcat should be listening on to hear the incomming response. Is there a standard port that netcat should listen on?
I've tried commands such as: nc -luv 192.168.0.1, however I get an error Servname not supported for ai_socktype. I've tried to remedy this by playing around with /etc/services but had no luck.
What command can I use and how must I configure the system to listen for the response from the search for dlna devices? I'd like to parse the response in a script so that the dlna connection can be automated.
Although you mention issues with DLNA it looks that you are really asking for how to best troubleshoot this.
Network cards don't allow access to incoming traffic unless set in promiscuous mode. Netcat won't be able to do what you need because of this. But, you can use Wireshark to read the traffic on the interface. TCPdump and Wireshark have close ties and almost interchangeable.
https://www.wireshark.org/
I would recommend to use it to troubleshoot further. Ppost the capture (not just a picture) and show where it failed.

UDP Packets not Sending Possibly Due to Client Not Found?

I have an application that is very simple. It sends out UDP packets to a client somewhere else on the network.
The host computer is 192.168.11.66 (Windows 10), the client device is 192.168.11.65 (proprietary device).
The host pc cannot see the client device, however I know that it is on and listening to traffic. When I send UDP packets from the host, I use Wireshark and I do not see the packets being sent out. Instead I see messages from ARP trying to locate the client. I assume because ARP is unsuccessful, the host cancels the sending of the packets.
If I change the destination address of the packets to a broadcast address, all of the packets get sent and I see everything on Wireshark. I need to be able to specify the IP address of the client and have Windows send the packets regardless of whether or not it thinks the client device is on the network or not. The client device looks for UDP traffic specifically addressed to itself and the client device has no way of making itself visible on the network.
Does anyone know how to work around this?
Thank you #Remy: instead to create your own ARP record manually. – Remy Lebeau
I did not realize that I could create manual entries in the ARP. I need to read more about ARP. Adding a manual entry solved my issue. I found that you could do it using ASP -s, or add neighbor using NETSH .
Thanks!

Multicast packet seen in Wireshark, but not received by user program (Windows and Linux)

I'm trying to detect a network connected device using multicast from a Ruby program. I've sniffed the network traffic from the official detection program and found that the computer sends out a packet to 225.0.0.37:12345 and the device responds on 225.0.0.38:12346. The device is connected to a local network consisting of a Netgear switch, a Windows computer and a Linux computer. I've made my program to send out an identical packet as the official program does.
The problem I have is that the response is never received, neither by my program nor the official detection program. Using Wireshark I can clearly see the device responding without fail and the packet clearly makes it to my Linux computer which I run Wireshark on, but neither the official program running on the Windows computer, nor my own Ruby program running on the Linux computer gets the response.
Both my computers have two network adapters, one connected to the same local switch and one connected to another switch which is then connected up to a large LAN with internet access. I've tried using a different brand switch between the computers, but it made no difference.
I've searched far and wide on Internet and haven't found anything to solve my issue. I appreciate any help I can get.
Here are the relevant packets captured with tcpdump, the first is sent from my program and the second is the response from the device:
13:30:25.773019 IP 192.168.0.1.12345 > 225.0.0.37.12345: UDP, length 15
13:30:25.773770 IP 192.168.0.125.39129 > 225.0.0.38.12346: UDP, length 228
Here is a (simplified) snippet from my program:
MULTICAST_SEND_ADDRESS = '225.0.0.37'
MULTICAST_SEND_PORT = 12345
MULTICAST_RESPONSE_ADDRESS = '225.0.0.38'
MULTICAST_RESPONSE_PORT = 12346
BIND_ADDRESS = '0.0.0.0'
# Transmit packet on all adapters - this part works fine
packet = [ID_STRING].pack("Z*")
addresses = Socket.ip_address_list
addresses.each do |addr|
next unless addr.pfamily == Socket::PF_INET
socket = UDPSocket.new
socket.bind(addr.ip_address, MULTICAST_SEND_PORT)
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send(packet, 0, MULTICAST_SEND_ADDRESS, MULTICAST_SEND_PORT)
socket.close
end
# Receive packet - this should work, but doesn't
membership = IPAddr.new(MULTICAST_SEND_ADDRESS).hton + IPAddr.new(BIND_ADDRESS).hton
listen_socket = UDPSocket.new
listen_socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, membership)
listen_socket.bind(BIND_ADDRESS, MULTICAST_RESPONSE_PORT)
packet, addr = listen_socket.recvfrom(1024)
# We never get to this line since there's nothing received
puts packet
I figured out the problem in the end. In spite of what all the code examples I've seen say, it seems you can't bind to address '0.0.0.0' to get all interfaces on a multihomed machine. I don't know if this used to work and has been changed or all examples I've found have only been tested on singlehomed machines, but when I bound the socket to the actual ip of the correct interface it started working.

Is there an easy way to route IP packets from a user space Windows app to the network?

I am working on a project that involves a usb device, through which we will receive ip packets from a remote pc. We assign the remote pc its IP Address. I have been experimenting with sending raw ip packets via several methods:
1 - raw sockets: ping works fine, problems sending tcp
2 - tun/tap W32: I managed to get this working enough to send pings out and get pings back to the phy ethernet device, but could not read them using ReadFile(...) on the driver guid.
3 - winpcap: ping works, out going tcp shows up on wireshark(so I assume it is leaving the pc), but i never get an ack to my syn. Im also worried that if I did get an ack the windows TCP stack would send a rst.
Our goal is to be a transparent pass through from the client pc to the network.
Client <-wrapped ip packet-> [device] <-wrapped ip packet-> WinPC <- IP -> IpNetwork
Its possible that im going about this wrong, seems like this should be easier.
I realize that windows is prob not the ideal OS for this, however I have no control over the OS.
thanks in advance
Fixed my issue with TCP Syn packets not getting acked, turns out I forgot to include the pseudo-header when calculating the TCP header checksum. Now it looks like the tcp handshake completes, so im calling this problem solved. If anyone feels like recomending a better way to accomplish this, feel free to reply. For now looks like we will use the winpcap method.
Update:
For this to work without windows constantly RST'ing tcp connections, you have to enable internet connection sharing(ICS) on the adapter you are sending packets out of. Other than that this ended up working for us.

Viewing incoming ping on windows server

I'm trying to see the results of an incoming ping on a target windows machine. This is needed to verify that the ping, which is running in a background thread, is being sent from the originator.
I have tried netstat to no avail. Are there any other approaches I could try?
Thanks.
Ping is an ICMP packet and doesn't create a TCP connection (hence you won't see it in netstat). On Linux, I'd add a rule to the firewall.
The most simple solution for your case might be to open a connection and close it. That will add it to the output of netstat with WAIT_CLOSE.
As Aaron Digulla already noted, ping is ICMP. This also means the originator even less trustable then with TCP; there's no SYN/ACK handshake. You just get an IP packet on your host, and you have to trust the header fields. Anyone can spoof those header fields, with almost no restrictions (It might be a bit challenging to get an IP claiming to come from 127.0.0.1 past a router)
Therefore, ICMP is not suitabel for verification tasks. You need a challenge/response protocol. TCP works reasoanbly well as long as you can trust the network but not necessarily all hosts on it (a reasonable assumption for the Internet. Not strong enough for financial transactions, which is why they use SSL)

Resources