using socat to multicast an mpeg-2 stream - unix

I have a broken ts file containing some MPEG-2 stream, with occasional intentional packet errors. The idea is to analyze the stream on another application I am trying to build and detect the errors.
If I use socat as
socat -u open:test.ts udp:localhost:1234
sleep 0.001
It correctly sends the contents of the file on that socket and I can listen to that port in my client application to analyze transport stream packets. Now, I want my application to support multicast as well.For that, I use something like
socat -u open:test.ts udp:239.48.208.1:1234
sleep 0.001
and listen to that multicast address on my application. I receive nothing. Since I know that multicast address is valid within my firewall, I am assuming this is an issue of socat not sending any packets in the first place. So, I believe this is not the correct way to send file contents over network using socat.
It does not have to be an MPEG-2 stream though. I just want to know how to multicast contents of a binary file on a specific multicast address and port.

I have not tried this, but there are many detailed examples on dest-unreach.org by Gerhard Rieger, the author of socat. The first example is of a multicast client and several receiving servers on a common network 192.168.10.*. The client 192.168.10.1 sends to a multicast address, and the receiving
servers may send response packets. On any of the servers, e.g. 192.168.10.2, we have
socat UDP4-RECVFROM:6666,ip-add-membership=224.1.0.1:192.168.10.2,fork EXEC:hostname
which means receive multicasts to 224.1.0.1, and fork a process for each packet. The process (eg hostname) can send one or more reply packets back. 192.168.10.2 is the interface to receive on (so differs on each server); see the socat man page for ip-add-membership.
On the sending client we have
socat STDIO UDP4-DATAGRAM:224.1.0.1:6666,range=192.168.10.0/24
which sends data from stdin to be multicast. It will print any received replies.

Related

destination port in UDP protocol

My question is that how the destination port address in UDP is chosen/given?
I mean what matters to set a destination port in a UDP packet?
Because when we send a packet, just the destination address(ip) is important and we want to send data to our destination.
It has nothing to do with the port!
Do we assign a random port?
Typically, whatever documentation tells you what to put in the UDP datagram you're sending should also tell you what port to send it to.
For example, if you're trying to talk to an NTP server, RFC5905 tells you what to put in the UDP datagrams you send. It also tells you, on page 16, to send it to port 123.
If you're writing a DNS resolver, RFC1035 is one place you might look for the information needed to know what to put in your UDP datagrams. It also tells you, in section 4.2, to send the datagrams to port 53.
So however you're figuring out what to put in the UDP datagrams you're going to send, that's typically what tells you either what port to send them to or, in some cases, how to determine what port to send them to.
For example, a media streaming protocol might start with the information about the stream being delivered by a web server. In that case, the information delivered by the web server to the client might include the destination port to send datagrams to.
Generally, there's either a well-known port that at least one side listens for datagrams on or there's some external method using a different protocol that tells whichever end sends the first datagram what port to send it to. The other end then just replies, sending its response datagrams to whatever port that first datagram was sent from.
Generally, the sending port is chose randomly for the ephemeral ports available.
The destination port is the port to which the destination application is listening. To facilitate this, IANA maintains the Service Name and Transport Protocol Port Number Registry for standard applications and protocols.
If you create your own application or protocol, there is a range for you to use, but you should always check the registry to make sure you will not step on some other application or protocol.
When you design your listening application or protocol, you choose a port on which it listens, and the sending application will need to send to that port.

Multicast Broadcasting to self clarification

Setup:
The user has two applications - one sender one receiver - running on the same host/server. The user sets it up such that the sender sends messages to its own IP address not 127.0.0.1. Lets say its IP and port is x:y for simplicity. The user then sets up the receiver to receiver messages on x:y. Again this is on the same host/server.
Questions:
From my understanding this is not possible since the port will already be reserved. Therefore I cannot use the same port to try and send packets out to myself. Can I have a port used for a sender and receiver on the same node?
Is this resolved if I use SO_REUSEADDR or does this only resolve the IP conflict and not the port reuse?
If the program is not setup with IP_MULTICAST_LOOP the host will not multicast the message to itself, correct?
With IP_MULITCAST_LOOP set, if I only wanted to send the message to myself can I use 127.0.0.1 or must I use another address? Additionally, how do the ports get resolved?
If I am not seeing messages on the same node, would the first best guess be that IP_MULITCAST_LOOP is not set?
Let's take it step by step:
The sending port does not matter at all. So you can choose an arbitrary port for the sender, and use the specific port number for your service just for the receiver.
No, SO_REUSEADDR/PORT does not solve this problem. Even if you manage to achieve it: Do not start multiple listeners on the same port. This will cause strange effects. The main purpose of SO_REUSEADDR/PORT is to allow servers to create a TCP (not UDP) socket when the previous server process just died, without waiting for a timeout of the TCP state machine of the stale socket.
Corrects, assuming you mean multicast rather than broadcast,
Yes and no: If you only want to send messages to yourself you can send the packets to 127.0.0.1, and then you message will be a normal unicast packet and no longer a multicast packet, and IP_MULTICAST_LOOP does not matter at all. Multicast packets are normal UDP packets which have a destination address in the multicast address range (i.e. 224.0.0.0-239.255.255.255). The receiving socket cannot easily tell whether a packet was sent via unicast or multicast.
IP routing on the same host between interfaces is far from trivial. There are a lot of mechanisms and routing rules involved which are not shown in the normal routing table, which is just for outgoing traffic. It also depends on by which means you try to observe the messages. There is not a single point where you can see all messages going through a node (unfortunately). This is usually all attached to interfaces, and there also to an ingress and egress side, and the latter is usually not documented and not configurable. Monitoring local traffic can be tricky and may require virtual network interfaces. Really messy.
In summary: You are trying to send messages from one process to another process on the same host. Use unicast UDP for this and you are done. No multicast involved.

Send TCP/UDP packets from the outside to a client behind a router

I want to send packets to a client on a lan, say, the public address is:
15.15.15.15 and behind this, there are 3 machines:
192.168.0.10
192.168.0.11
192.168.0.12
How would format my packet so that, if I were to send it to this IP address, it'll be received, well, atleast redirected to say, 192.168.0.10.
I know that there's 192.168.0.10, since it's one of my machines and I was wondering if I can build a notification system for something using no sockets whatsoever, but just a client listening for these. (Using scapy to parse packets)
So, for example: I send a packet from outside saying "Alert!" to 15.15.15.15 and 192.168.0.12 picks it up. Wrote this just to provide some insight!
Made this image to portray the process:
Cheers.
You can also implement a UDP hole punching, but you need a public server with real IP address to do that.

Routing traffic with TUN/TAP interface

I am new to network programming and try to understand managing traffic via TUN/TAP interface.
Since I have almost nonexistent system programming skills, and feel confident on Java; I use OpenVPN tun/tap driver and ready made Java binding for it. It works on TAP mode.
As an example application I am trying to imitiate no encryption, no authentication client server VPN application.
I can catch Ethernet Frame packets, but for the routing part, I failed miserably. (I can modify route/arp tables.)
Do anybody know how OpenVPN send packets from client to server, and from server to target. Opening sockets from Java looks like an alternative; but I was hoping that modifying packets(change IPs and/or MAC addresses) and writing back to the virtual tap interface would be enough. Is it so?
Can I inject packets to send other locations, or by default received packet moves towards application layer?
-- Edit:
Scneario
Client Tap0 _____ Server Tap0 ______ Target
Eth0 Eth0
Target: Ping from client, move through tap interfaces, target see only server ip (anonymization)
What I achived so far.
Catch traffic at client tap0 interface.
I coulnt forward traffic at server Tap so to fasten things I used Java socket programming between client-server.
Now I read packets from socket at server, and try to OpenVPN Tap driver's write method to move forward but I am not sure where do I fail. I see packets with tcpdump at server tap0, but they do not pass to server eth0.
My most important question is if I modify packet(ip, mac address) and call write method, is it possible that packet moves forward. (Or does it move to application layer whatever you change??)
Any help would be appreciated.
1. Routing is a Layer 3 (IP) problem and handled by the OS. As for the Ethernet frames on Layer 2, you have multiple options. In any case, you'll have to parse the incoming packets' headers and extract the MAC address, and decide based on the MAC where to pass the packet: To a specific client, all clients (broadcasts) or the local tap interface.
Option 1: On each client, use a tun device, and let the server use a tap device. Assign pseudo MAC addresses to each client, respond accordingly to ARP requests from the server's OS and let the OS on the server take care of the rest. Applicationwise, you'll only have to forward all incoming packets to the tap device and all outgoing packets to the client to which you assigned this MAC.
Option 2: Let the clients choose their own MAC address and forward ARP-requests through the network. The server application has to decide for incoming packets from a client whether to forward the packet to a client, or send it to the local tap device if the address matches the local device's MAC.
In both cases, clients pass all packets from their local tun/tap device to the server and vice versa.
2. You can do almost anything. A packet is only "received" when you decide to write it to the tap device, and you can of course temper with any packets, or inject new ones, ...
As a final comment, I've found that toying with tun devices is conceptually simpler, because they work on Layer 3. You'll have to open a tun device on the server for each client, but within your application you'll have to do nothing but to forward anything coming from the device to the single client, and vice versa.

UDP packets rejected at OS-level?

Running on a Linux system, getting UDP packets from another computer address to let's say 192.168.0.2 from another address let's say 192.168.166.66, I can see the UDP packets coming in with tcpdump. However, if I use netcat I don't actually receive the packets.
If I create an interface on 192.168.166.XXX network, then netcat is able to receive the packets no problem.
What basic networking concept am I missing? Why do I need to have an interface on the network of the sending IP when I can see with tcpdump that they are being delivered correctly?
tcpdump per default puts the interface into promiscious mode, which lets you see all the packets arriving at your network interface. But, your operating system only processes packets destined for the local system, e.g. either having the local or a broadcast address as destination.
The final solution to this problem was to disable Reverse Path Forwarding (RPF) on the interface. There are security implications here, but after careful review this was the correct path forward in this particular case.
RPF was turned off by modifying /etc/sysctl.conf:
net.ipv4.conf.eth0.rp_filter=0
Some more information on RPF:
Wikipedia - Reverse path forwarding
Linux kernel rp_filter settings

Resources