3

Note: While there is an accepted answer now, it is only part; check the final iptables rule below.

I'm receiving a unicast RTP stream on one interface and wish to send it out via multicast on a second interface. The system in question is an embedded processor running Linux, but I'm finding it equally difficult to set up on my Ubuntu 10.10 host. The simple, obvious answer, based on http://lists.netfilter.org/pipermail/netfilter/2002-October/038890.html and other sources, seems to be:

iptables -t nat -A PREROUTING -i [unicast-interface] -p udp --dport [unicast-incoming-port] -j DNAT --to-destination [multicast-addr]:[multicast-port]

A bit of additional research resulted in this pairing:

iptables -t nat -A PREROUTING -i [unicast-interface] -p udp --dport [unicast-incoming-port] -j DNAT --to-destination [multicast-addr]:[multicast-port]
iptables -A FORWARD -i [unicast-interface] -o [multicast-interface] -p udp --dport [unicast-incoming-port] -j ACCEPT

Though the rules show up when listed, and tcpdump shows the unicast packets coming in, Wireshark on a separate machine showed no packets coming out.

I looked at How to translate unicast to broadcast via DNAT with iptables? but that seems concerned with the specifics of the broadcast case.

Note: there are no other iptables rules that have been set. I've double-checked using iptables -L (and -t nat -L) and iptables --flush.

(I realize there are other options, like socat -- but before I switch to them I'd like to make sure I'm not missing something.)

Edit: I do have ip_forward enabled.

~ # sysctl -a 2>&1 |grep ip_forward
net.ipv4.ip_forward = 1

Edit: It looks like I'm getting increasing packet counts in my NAT table (iptables -t nat -L -v -n) but not in the main/filter table (iptables -L -v -n)

Edit: Having caught up on trying things, I have had no success. I have seen some people get a similar process to work with Cisco, such as on this site: http://www.penrod.cc/?p=527

It did seem that this worked at one point in time but I have been unable to make it work since, either on the original embedded host or on a Linux workstation.

Edit: As it turns out, this issue came up again.

Final solution that worked in full:

Get smcroute (static multicast route daemon running). If you're in an embedded system you might need to use smcroute -d

smcroute -a [unicast-interface] [source-ip] [multicast-addr] [multicast-interface]
iptables -t nat -A PREROUTING -p UDP -d [unicast-interface-ip] -j NETMAP --to [multicast-addr]

For example:

smcroute -a eth0 192.168.0.101 239.1.1.1 eth0
iptables -t nat -A PREROUTING -p UDP -d 192.168.0.1 -j NETMAP --to 239.1.1.1

Note that you might need to refine the iptables rule to ensure you don't catch packets you don't intend -- this is just a simplified example.

Arthur Shipkowski
  • 133
  • 1
  • 1
  • 6

4 Answers4

5

Do you have ip forward enabled on kernel ?

# sysctl -a 2>&1 | grep ip_forward
net.ipv4.ip_forward=1

You need it to pass traffic from one interface to another (a.k.a. the FORWARD table rules).

Edit:

There is other sysctl setting, that I suspect that will be related:

net.ipv4.conf.all.mc_forwarding

and per interface, and for ipv6.

That "mc" really sounds to multicast, but I do not have kernel docs at hand to be 100% sure.

Try setting to 1, if doesn't work always you can return to the default 0.

Edit:

from networking/ip-sysctl.txt:

conf/all/mc_forwarding must also be set to TRUE to enable multicast routing

Rafał Rawicki
  • 177
  • 1
  • 7
poisonbit
  • 797
  • 4
  • 6
  • I indeed do have ip_forward enabled -- but good thought, I should have mentioned that. – Arthur Shipkowski Apr 08 '11 at 17:02
  • 1
    Hmm, mc_forwarding is zero and refuses to go to one, so I'd better check my kernel config. – Arthur Shipkowski Apr 08 '11 at 18:02
  • Right, this is more complete than the grep: "Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE and a multicast routing daemon is required. conf/all/mc_forwarding must also be set to TRUE to enable multicast routing for the interface", in Debian It comes builtin (CONFIG_IP_MROUTE and CONFIG_IPV6_MROUTE). – poisonbit Apr 08 '11 at 18:16
  • It turns out to be set to "y" in the kernel config. Additional Googling indicates I need to install a multicast routing daemon to get it to go to "1" -- which, given the cross-compilation situation, may mean the simplest solution is to go with my alternate plan. I'll see about double-checking with a multicast routing daemon when I get the chance, and accept your answer if it works. – Arthur Shipkowski Apr 08 '11 at 18:27
  • I realized this afternoon I never got back to you. I spent some time playing with mrouted and smcroute -- neither allowed my trick as given above. – Arthur Shipkowski Oct 03 '12 at 20:55
  • This comment set me down the route of using a multicast routing daemon, so I'm accepting it. – Arthur Shipkowski Oct 24 '12 at 20:16
1

You need to manipulate the routing table so that after NAT-ing the packet, it gets sent out the correct interface.

ip route add to $MULTICAST_ADDR dev $MULTICAST_IFACE

That might cause problems if you send out multicasts through the incoming interface, so we must mark the packets

iptables -t mangle <rules to match the packets you want to multicast> -j MARK --mark <your favorite number>
ip rule add order 10 fwmark <that favorite number> lookup table <another favorite number>
ip route add to <multicast> dev <iface> table <2nd fav number>

Finally, you have to realize that conntrack will not be able to match the return packets; you have to do your own conntrack:

iptables -t nat -A POSTROUTING -d <multicast> -o <iface> -j SNAT <router's IP>:<a port>
iptables -t nat -A PREROUTING -i <router's IP> -p udp --dport <a port> -j DNAT <orig sender>:<orig port>

There, the general way to do what you want. I hope my (limited) explanation can start you on the right path.

pepoluan
  • 4,918
  • 3
  • 43
  • 71
1

It seems that you will have to use special daemon - look at igmpproxy or mrouted - as iptables will simply translate and forward incoming packet to one combination of addresses/ports in the given range.

alexm
  • 458
  • 3
  • 11
0

This kernel module creates a new netfilter hook in prerouting chain for stealing the unicast packets and sends it out as multicast packet based on the rule set by "utomu"

tor example: Incoming unicast session interface is "eth0" and outgoing multicast session interface is "eth1". Then set

echo "eth0" > /proc/sys/net/utom/in_ifname

echo "eth1" > /proc/sys/net/utom/out_ifname

suppose unicast source ip is "192.168.56.5" and want to convert it to multicast "225.1.2.3", then set the rule as

utomu -m 225.1.2.3 -a 192.168.56.5 -s 1194 -d 1194

It will changes the source port and destination port as well.

Source @ https://github.com/ravi-eticala/unicast-to-multicast

  • Welcome to Server Fault! Whilst this may theoretically answer the question, [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – vonbrand Mar 31 '13 at 21:53