Need For Speed Underground 2, LAN game extender

Purpose:

Allow Need For Speed Underground 2 LAN games (and Need For Speed Underground 3 LAN games) to be played outside of a LAN, enabling true cross LAN and cross site multiplayer games. This has been tested to work over multiple VPNs connecting cable modems and adsl modems, with a Linux firewall on all end points. Tests have shown NFSU2 requires only the server machine to be running nfsu2relay. Tests without a VPN have been sucessful with many forwarded ports, see below. If you have machines connected via a LAN but on different subnets, that will also work - this amounths to the same situation as a VPN.

The Windows port has also been tested to work. Has been found to work even when running on the same machine as the NFSU2 game itself (ignore the recvfrom=-1 error message, it is still working). This means that the relay only requires either a VPN connecting the sites, or many ports forwarded - it no longer needs a Linux machine.

Look in the ToDo section for more Windows references.

Download:

nfsu2relay.c - the Linux/Windows source
nfsu2relay.zip - the Windows executable

Compile with:

gcc -O2 nfsu2relay.c -o nfsu2relay

Usage:

nfsu2relay <NFSU2 machine IP> <NFSU2 machine IP> [NFSU2 machine IP...]
nfsu2relay -e <your external IP> <their external IP>
-e Modify behaviour to support internet routed NFSU2 traffic.

where both IP addresses are machines running NFSU2, and nfsu2relay is running on a unix machine linked to the subnets of both machines.

More Complex usage:

In the scenario:
NFSU2 machine <---> Unix firewall <--VPN--> Unix firewall <---> NFSU2 machine

ie. Linux firewall machines connected via a VPN over the internet, and a NFSU2 machine at each site which are on the same subnet as the firewall machines. This requires nfsu2relay running on both firewall machines, in both cases they should be given the IP addresses of the NFSU2 machines, and IP traffic must be directly routeable between both machines - as nfsu2relay only helps you connect to a game, once running the clients/server talk directly without subnet limitations.

The above two scenarios have been tested to work. We can confirm that nfsu2relay must be running on all subnets where there is a NFSU2 client or server. We have yet to confirm if all the nfsu2relays need to send packets to each other (so all relays have all NFSU2 IPs on the command line), or only the server needs itself and the client IPs, and all the clients need only thier own IP and the servers IP.

General usage:

nfsu2relay needs to be running on the subnets of all NFSU2 machines, this normally means it must be connected to the same switch. Nfs2relay running on the server subnet needs to know the IP addresses of all NFSU2 clients. Nfs2relay running on client subnets needs to know only[untested] the IP address of the server.

Beware of the game filter when looking for the server. This will filter out servers of the wrong type (race type, matched/unmatched cars etc), which is fine is there are many servers and you are interested in one type of game. With this program, chances are there is only one server and you don't care what the game type is. Alas there is no way of telling NFSU2 to not filter what it sees - so just make sure they match.

nfsu2relay without a VPN

The -e switch enables the NFSU 2 broadcasts to be sent directly to a real internet address without spoofing the source address. This is part of the requirements of VPNless internet play. Ports must be forwarded from the adsl/cable modem and firewal to the server or client running NFSU2. These ports are UDP 3658, 3659, 9999 (symmetric) and TCP 9900 (server) to 3282, 3284 and 3285 (client).

For example, the machine running the server must be able to receive traffic on port 9900 TCP from outside the on the internet. For my adsl modem, that means setting up a port forward from TCP 9900 to my Linux fireware, then setting up a DNAT style port forward to forward to the NFSU2 machine. Equally, the clients need to forward TCP 3282, 3284 and 3285 from the modem, to the firewall, to the NFSU2 client. Cable modem users won't need to forward from the modem as that is transparent. nfsu2relay runs on both firewall machines as usual, but you use the -e switch and use your external IP addresses instead of the internal IP addresses of the NFSU2 machines. Note, when testing this, one game used port 3282, another game didn't and gave a warning of not being able test connection quality. So more ports would seem to be necessary. Note, games with more than two players has not been tested. Neither has hoping NAT will deal with the client side rather than have a large number of port forwards. For reference, we used these iptable rules (taken from /etc/sysconfig/iptables): *nat
-A PREROUTING -p udp -m udp --dport 3658 -i eth1 -j DNAT -d 192.168.7.130 --to 192.168.7.10
-A PREROUTING -p udp -m udp --dport 3659 -i eth1 -j DNAT -d 192.168.7.130 --to 192.168.7.10
-A PREROUTING -p udp -m udp --dport 9999 -i eth1 -j DNAT -d 192.168.7.130 --to 192.168.7.10
-A PREROUTING -p tcp -m tcp --dport 9900 -i eth1 -j DNAT -d 192.168.7.130 --to 192.168.7.10
*filter
-A INPUT -i eth1 -p udp -m udp --dport 3658 -j ACCEPT
-A INPUT -i eth1 -p udp -m udp --dport 3659 -j ACCEPT
-A INPUT -i eth1 -p udp -m udp --dport 9999 -j ACCEPT
-A INPUT -i eth1 -p tcp -m tcp --dport 9900 -j ACCEPT
-A FORWARD -i eth1 -p udp -m udp --dport 3658 -j ACCEPT
-A FORWARD -i eth1 -p udp -m udp --dport 3659 -j ACCEPT
-A FORWARD -i eth1 -p udp -m udp --dport 9999 -j ACCEPT
-A FORWARD -i eth1 -p tcp -m tcp --dport 9900 -j ACCEPT
192.168.7.10 being my NFSU2 machine, which is the server.
192.168.7.130 being my firewall, eth1 being the external interface on the firewall.

Theory of operation:

The job of nfsu2relay is to relay broadcast packets sent out by NFSU2 when looking for a game. Once the clients/server know each others IP address, there is no need for nfsu2relay as the clients/server talk directly to each other using the IP addresses obtained during the broadcast (or nfsu2relay's relayed broadcast).

As broadcast packets only spread as far as the subnet from which they originated, NFSU2 can't normally find NFSU2 servers on a nearby subnet. nfsu2relay looks for these broadcasts and sends a copy of what it receives to the IP addresses given as arguments (except for the IP the broadcast packet came from). Nfs2relay fakes the source IP addrees, so the relayed broadcast packet (which is no longer a broadcast as it is sent directly to single machines) looks like it came from the original machine, making the packet relay process transparent.

For example, if 192.168.15.51 is the NFSU2 client, 192.168.0.7 is the NFSU2 server, both machines are connected by a Linux machine on IPs 192.168.15.1 and 192.168.0.100. When told to look for LAN games, NFSU2 looks for servers by sending out a udp broadcast on port 9999:
192.168.15.51:9999 -> 255.255.255.255:9999 udp length 384 (subnet 192.168.15.0/24)
nfsu2relay receives the broadcast, and sends it to the other given IP faking the original sender IP address:
192.168.15.51:9999 -> 192.168.0.7:9999 udp 384 length (subnet 192.168.0.0/24)
NFSU2 server will receive this spoofed packet and accept this as if it was a broadcast on the same subnet by the client.
While this is happening, NFSU2 server sends out broadcasts of its own, presumably advertising itself. In this case it would look like this:
192.168.0.7:9999 -> 255.255.255.255:9999 udp 384 udp length (subnet 192.168.0.0/24)
nfsu2relay receives the broadcast, and sends it to the other given IP faking the original sender IP address:
192.168.0.7:9999 -> 192.168.15.51:9999 udp 384 udp length (subnet 192.168.15.0/24)

In either case, the receiving parties receive the correct sender address, and so can respond directly without using broadcasts. Looking at the packets generated, they also do not use port 9999.

When the clients and server are not on nearby subnets, the same idea still works but in this case multiple nfsu2relays are needed to relay the broadcasts.

To do:

Would be useful if nfsu2relay relayed real broadcasts to given subnets rather than specific IPs. Needs broadcast flag, would also need changes to check for source of packet. A quick test didnt work, so if needed this will need looking into some more. This is a low priority and would need control options.

Compile for Windows myself. DJP sent me the Windows executable, so if the source changes, the executable becomes out of date.

Related to previous, find the reason for the recvfrom=1 errors when running under Windows on the same machine as the game itself.

A friend found this: site, which is talking about this program. Athough in Russian, it does run under Windows. This exe is a self extracting archive, containing the real program.

As a more general solution, look for the Gamers Internet Tunnel. Don't know if this supports NFSU2, but it could do.

Credits:

in_cksum(), pseudohdr and udpsend() came from a German language 'hacker' howto, one of the few examples of RAW packet generation that actually generated well formed packets.

The Windows port (modified source and exe) came from DJP, dejepe at hotmail.com.

Other code and the main idea came from Richard Gregory, greg at csc.liv.ac.uk

History:

1.0 8/11/2004

Proof of concept. Took two IP address arguments and listened on port 9999 for packets to 255.255.255.255. Relayed the broadcast to the other IP address.

1.1 10/11/2004

Allow more than two IP addresses, the broadcast packets are sent to all but the source of the broadcast packet.

1.2 12/11/2004

Improved docs, added a mimimal mention on a web page. Google should find it.

1.3 17/11/2004

Modified to work without a VPN, but this broke VPN play. Added an option to pick the appropriate behaviour.

1.4 14/01/2005

Was sent a port to Windows, the source code and executable. Checked this to work as it should and so added it to the web page.