How to forward a port from one machine to another?

Yes, this is called GatewayPorts in SSH. An excerpt from ssh_config(5):

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

And you can use localhost instead of M in the forwarding, as you're forwarding to the same machine as you're SSH-ing to -- if I understand your question correctly.

So, the command will become this:

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

and will look like this in netstat -nltp:

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

Now anyone accessing this machine at port 2222 TCP will actually talk to localhost:8888 as seen in machine M. Note that this is not the same as plain forwarding to port 8888 of M.


There is another way. You may set up port forwarding from S:2222 to W:8888 with iptables. Single command:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

where 1.2.3.4 is M's IP address. It is called NAT (Network Address Translation).


More alternatives: netcat (traditional) or socat

On the server (S):

socat tcp-listen:2222,reuseaddr,fork tcp:M:8888

or

nc -l -p 2222 -c 'nc M 8888'

Details see in: Simple way to create a tunnel from one local port to another?