miniupnp.tuxfamily.org Forum Index miniupnp.tuxfamily.org
The forum about miniupnp and libnatpmp
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Several public IPs and generic redirecting engine
Goto page 1, 2  Next
 
Post new topic   Reply to topic    miniupnp.tuxfamily.org Forum Index -> NAT/UPnP
View previous topic :: View next topic  
Author Message
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Thu Jan 17, 2008 10:26 am    Post subject: Several public IPs and generic redirecting engine Reply with quote

I have two things to propose/fetaure request/collaborate on.

First, I have a network with one FreeBSD router serving a network wit some white addresses and growing network of student's home computers, with gray addresses, behind NAT. As they started to complain about sites (p2p, IRC servers etc.) with "Too many connects from your IP", I made half a dozen of white addresses which were free to act as public addresses for them. Currently I'm doing with several ng_nat's, with natd before, simply putting each block of, say, 20 IPs to one public address. You know, pf can do NATting a neetwork to a range of addresses, too.

But as I am looking to miniupnpd, which is great, I think, I couldn't find anything related to several public IPs. Moreover, as I can think about UPnP itself, it is of heavy multicast use and don't have possibilty to use several IPs (I don't know exactly, though). I was capturing my network a little and found that NAT-PMP are also very common, and NAT-PMP uses multicast only in case of changing public address, which is not actual for me :)

I am currently working on a patch to ng_nat to support it in-kernel redirect, and also thinking about writing my own custom NAT-PMP daemon, but as I'm looking of what I want, then miniupnpd come to mind. Everything already included! And functionality can be useful to someone else (if pf can do this natively without several NAT setups, which do most other NAT programs require, then it is not so uncommon).

Then we coming to second part.

As miniupnpd currently support ONLY pf, ipf and netfilter, adding one another "redirecting engine" (let it call so) is not so hard, but what about several? I currently need ng_nat on FreeBSD, someone want ipfw+natd on FreeBSD, may be in-kernel "ipfw nat" then; think about some other OS or even more fascinating things.

For example, I have an idea to write a pure non-NAT in-kernel redirecting engine (based on FreeBSD netgraph). One can also think about another userland redirector or several redirectors on different machines (again, with several public IPs). So now I have a concept of "redirecting engine" + "front-end", where engine does actulual proxying or packet-translating work, and frontend is dealing with users. An engine can be one of pf, netfilter or some userland proxying daemon, and front-end can talk with users via UPnP, NAT-PMP, SOCKS 5 or even web-interface!

Thus, we only have standard protocol between engine and front-end, then we can combine any engine with any front-end (user can easily extend system). Currently I view this as there are two daemons, say, miniupnpd and engine, connected via TCP or UNIX domain socket. Protocol is text line oriented, simple like POP3, thus allowing engine to be even a shell-script reading and writing it's stdin/stdout and executing commands to firewall. Or engine may be redirecting connections in userland itself... do not care.

So all advanced logic is in front-end (e.g. NAT-PMP timeouts) and engine is simple. It is text line-oriented to be human adjustable, e.g. it must be possible to use engine for static redirects without frontend, by doing "cat config > /tmp/socket". Both engine and frontend may be stateless to allow using more than one wth each other: several engines with different IPs and one front-end, or several front-ends to one backend (e.g. static redirects by admin and front-end for users).

Any appreciations?
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Thu Jan 17, 2008 4:05 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

Point 1
nuclight wrote:
First, I have a network with one FreeBSD router serving a network wit some white addresses and growing network of student's home computers, with gray addresses, behind NAT. As they started to complain about sites (p2p, IRC servers etc.) with "Too many connects from your IP", I made half a dozen of white addresses which were free to act as public addresses for them. Currently I'm doing with several ng_nat's, with natd before, simply putting each block of, say, 20 IPs to one public address. You know, pf can do NATting a neetwork to a range of addresses, too.

But as I am looking to miniupnpd, which is great, I think, I couldn't find anything related to several public IPs. Moreover, as I can think about UPnP itself, it is of heavy multicast use and don't have possibilty to use several IPs (I don't know exactly, though). I was capturing my network a little and found that NAT-PMP are also very common, and NAT-PMP uses multicast only in case of changing public address, which is not actual for me Smile

I am currently working on a patch to ng_nat to support it in-kernel redirect, and also thinking about writing my own custom NAT-PMP daemon, but as I'm looking of what I want, then miniupnpd come to mind. Everything already included! And functionality can be useful to someone else (if pf can do this natively without several NAT setups, which do most other NAT programs require, then it is not so uncommon).

I have never tested having several (valid) public IPs.
miniupnpd insert rules like this in pf :
Code:
rdr pass on xl1 inet proto udp from any to any port = 5150 label "DemonwarePortMapping" -> 192.168.0.132 port 5150

So the redirection should work when any public IP is used. Maybe it is not what you want and wishes a rule like :
Code:
rdr pass on xl1 inet proto udp from any to 4.3.2.1 port = 5150 label "DemonwarePortMapping" -> 192.168.0.132 port 5150
Where 4.3.2.1 is the public address associated with 192.168.0.132
Or maybe what you need is the possibility to define several "external network interface".
In any case that would need some implementation work in miniupnpd.

One thing that would work in a weird way is GetExternalIPAddress() UPnP function and Op code 0 of NAT-PMP (Public address request). But it would be easy to change in order to return the right address depending on the client LAN address.
_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Thu Jan 17, 2008 4:45 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

Point 2
nuclight wrote:
For example, I have an idea to write a pure non-NAT in-kernel redirecting engine (based on FreeBSD netgraph). One can also think about another userland redirector or several redirectors on different machines (again, with several public IPs). So now I have a concept of "redirecting engine" + "front-end", where engine does actulual proxying or packet-translating work, and frontend is dealing with users. An engine can be one of pf, netfilter or some userland proxying daemon, and front-end can talk with users via UPnP, NAT-PMP, SOCKS 5 or even web-interface!

Thus, we only have standard protocol between engine and front-end, then we can combine any engine with any front-end (user can easily extend system). Currently I view this as there are two daemons, say, miniupnpd and engine, connected via TCP or UNIX domain socket. Protocol is text line oriented, simple like POP3, thus allowing engine to be even a shell-script reading and writing it's stdin/stdout and executing commands to firewall. Or engine may be redirecting connections in userland itself... do not care.

So all advanced logic is in front-end (e.g. NAT-PMP timeouts) and engine is simple. It is text line-oriented to be human adjustable, e.g. it must be possible to use engine for static redirects without frontend, by doing "cat config > /tmp/socket". Both engine and frontend may be stateless to allow using more than one wth each other: several engines with different IPs and one front-end, or several front-ends to one backend (e.g. static redirects by admin and front-end for users).


Your idea is very interesting but it is not really in the philosophy of MiniUPnPd Wink MiniUPnPd is designed to run on low memory/low CPU power machines and has been successfully ported to some linux home routers.
One of the big advantage of miniupnpd is that it runs into only one process/one thread, and doesn't use any fork(), exec() or system() call like linux-igd does Wink
Implementing a text line oriented protocol would take some code, memory and processing time.
Anyway, existing miniupnpd code could easily be used to fork a project like "versatileUPnPd" or "UniversalNAT" Smile

Best Regards,
_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Thu Jan 17, 2008 5:14 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

miniupnp wrote:
Point 1
I have never tested having several (valid) public IPs.
miniupnpd insert rules like this in pf :
Code:
rdr pass on xl1 inet proto udp from any to any port = 5150 label "DemonwarePortMapping" -> 192.168.0.132 port 5150

So the redirection should work when any public IP is used. Maybe it is not what you want and wishes a rule like :
Code:
rdr pass on xl1 inet proto udp from any to 4.3.2.1 port = 5150 label "DemonwarePortMapping" -> 192.168.0.132 port 5150
Where 4.3.2.1 is the public address associated with 192.168.0.132


I'm not familiar with pf, so didn't test it , though perhaps it will work.

Quote:

Or maybe what you need is the possibility to define several "external network interface".
In any case that would need some implementation work in miniupnpd.

One thing that would work in a weird way is GetExternalIPAddress() UPnP function and Op code 0 of NAT-PMP (Public address request). But it would be easy to change in order to return the right address depending on the client LAN address.


The trick is that I have no of aliasing addresses on my public interface :) I have $ext_white_ip on my $ext_if and ip 82.17.64.129 on internal interface with come white addresses. In my configs I use IPs like 82.117.64.144 as aliasing addresses for gray internal clients, though that addresses are never on my router's interfaces, they are simply routed to me by my provider as this white subnet is mine.

So I actually will be happy with just specifying in miniupnpd's config something, say, like:

Code:
map_ext_ip 1.2.3.1 for 192.168.0.0/28
map_ext_ip 1.2.3.1 for 192.168.0.16/29
map_ext_ip 1.2.3.2 for 192.168.1.0/24


So that for opcode 0 in NAT-PMP each client will get appropriate public IP. I think that such specific case on other firewalls will also require manual setting in that's NAT config, thus there is no simple and clear way for miniupnpd to obtain them except it's own config ;)
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Thu Jan 17, 2008 5:56 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

miniupnp wrote:
Point 2

Your idea is very interesting but it is not really in the philosophy of MiniUPnPd ;) MiniUPnPd is designed to run on low memory/low CPU power machines and has been successfully ported to some linux home routers.
One of the big advantage of miniupnpd is that it runs into only one process/one thread, and doesn't use any fork(), exec() or system() call like linux-igd does ;)
Implementing a text line oriented protocol would take some code, memory and processing time.


No, no. Of course, it's MiniUPnPd, but, umm, not micro :) While it can run on a home router (great, really), it still can run on a usual PC, so it's useful to have feature for them also (have you *BSD in home router?). What I'm trying to say is to make another "firewall".

You already have firewall-dependent specific code in your sources - that is, "pf", "netfilter" and "ipf" subdirectories. What I suggest is to make another one, say, "generic", with this code. Only whose who really want will enable it so home routers will not be affected :)

And after all, simple line-per-request stateless text protocol is much simpler to implement than noisy XML ;) Something like that (first line is req from MiniUPnPd and second is the answer);

Code:

ADD 0.0.0.0 0 4.3.2.1 15234 192.168.0.1 1234 Rest of line is ignored but carried description
+OK 23


That was adding of redirect from any external IP/port to specific parameters, and redirecting engine will remember comment, in which we can store some our information which will be passed unchanged back when LIST comman will list active engine's redirects... And +OK 23 returned ID 23 which we can use in subsequent DELETE commands. Simple format, simple sscanf()...

Quote:
Anyway, existing miniupnpd code could easily be used to fork a project like "versatileUPnPd" or "UniversalNAT" :)


Fork is bad :) be that fork() or a project fork :) And I very like the idea of MiniUPnPd - NO dependencies, minimal size, speed in mind - that's optimal. It's valuable on big machines too. I'm not going to do very-very-universal thing - just make it simplier to extend. Like API for plugins :) That daemon on the other end of text protocol do not need to do system(), implementation dependent - it's up to user...
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Sat Jan 19, 2008 2:31 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

nuclight wrote:
So I actually will be happy with just specifying in miniupnpd's config something, say, like:

Code:
map_ext_ip 1.2.3.1 for 192.168.0.0/28
map_ext_ip 1.2.3.1 for 192.168.0.16/29
map_ext_ip 1.2.3.2 for 192.168.1.0/24


So that for opcode 0 in NAT-PMP each client will get appropriate public IP. I think that such specific case on other firewalls will also require manual setting in that's NAT config, thus there is no simple and clear way for miniupnpd to obtain them except it's own config Wink

I think I'll try to do something like this
_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Sat Jan 19, 2008 2:34 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

nuclight wrote:
miniupnp wrote:
Point 2

Your idea is very interesting but it is not really in the philosophy of MiniUPnPd Wink MiniUPnPd is designed to run on low memory/low CPU power machines and has been successfully ported to some linux home routers.
One of the big advantage of miniupnpd is that it runs into only one process/one thread, and doesn't use any fork(), exec() or system() call like linux-igd does Wink
Implementing a text line oriented protocol would take some code, memory and processing time.


No, no. Of course, it's MiniUPnPd, but, umm, not micro Smile While it can run on a home router (great, really), it still can run on a usual PC, so it's useful to have feature for them also (have you *BSD in home router?). What I'm trying to say is to make another "firewall".

You already have firewall-dependent specific code in your sources - that is, "pf", "netfilter" and "ipf" subdirectories. What I suggest is to make another one, say, "generic", with this code. Only whose who really want will enable it so home routers will not be affected Smile

yes you are right Smile I have currently no time to spend developing this but I would be happy to receive and integrate patches, so you can do the work ! Wink
_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Sun Jan 20, 2008 4:23 pm    Post subject: Re: Several public IPs and generic redirecting engine Reply with quote

Reply to both:

miniupnp wrote:
I think I'll try to do something like this


Oh, good, thanx. I'll test that :)

miniupnp wrote:

yes you are right :) I have currently no time to spend developing this but I would be happy to receive and integrate patches, so you can do the work ! ;)


OK, I'll do that after finishing my ng_nat patches. The only question is, what API can be relied upon? That is the question with multiple external IPs in mind - functions depend on one ext_ip. Should we change function arguments or pass IP as text string within cahr *ifname ?
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Sun Jan 27, 2008 10:50 pm    Post subject: Reply with quote

you can get and try miniupnpd-1.0.tar.gz I have added support for multiple external ips.
GetEXternalIPAddress() will answer differntly depending on the client. Adding the adress in the pf rule is not done for the moment. is it mandatory ? I dont know.

For the multiple external ip support you need to :
make config.h
edit config.h to enable MULTIPLE_EXTERNAL_IP define.
make

edit your miniupnpd.conf so the listening_ip lines look like:
Code:
listening_ip=192.168.11.1/24 1.1.1.1
listening_ip=192.168.12.1/24 1.1.1.2
listening_ip=192.168.13.1/24 1.1.1.3
listening_ip=192.168.14.1/24 1.1.1.4

_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Mon Jan 28, 2008 8:40 am    Post subject: Reply with quote

miniupnp wrote:
you can get and try miniupnpd-1.0.tar.gz I have added support for multiple external ips.
GetEXternalIPAddress() will answer differntly depending on the client. Adding the adress in the pf rule is not done for the moment. is it mandatory ? I dont know.

For the multiple external ip support you need to :
make config.h
edit config.h to enable MULTIPLE_EXTERNAL_IP define.
make

edit your miniupnpd.conf so the listening_ip lines look like:
Code:
listening_ip=192.168.11.1/24 1.1.1.1
listening_ip=192.168.12.1/24 1.1.1.2
listening_ip=192.168.13.1/24 1.1.1.3
listening_ip=192.168.14.1/24 1.1.1.4


Hmmm, sounds good, but... I looked at the code (diff to RC13 and some other parts). Not exactly my case. Sadly, I have ONE gray network, 172.18.46.0/24, with router's address .1, and divided it into several pieces of different size, but not subnets (one piece of 100 users, several about 16-20).

So, config lines above are not suitable for me as they require real different subnets with several IP addresses on a router in each. Yes, I know this configuration is worse than really different subnets/interfaces - but still real.

However, things are not so bad - as I found in the code, sockets are bound to INADDR_ANY, and the only case where different IPs for router are needed, is SSDP Notify - these sockets are explicit, and program will refuse to run if any of these fail (umm.. am I right, that's the only case?). But, I think I can live without SSDP notify to clients (or if this is impossible, even leave only NAT PMP without UPnP). May such a patch/option be done?..
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Mon Jan 28, 2008 10:20 am    Post subject: Reply with quote

hum... I'll try to do something for you...
_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Fri Mar 14, 2008 12:24 pm    Post subject: Reply with quote

I've prepared a draft for proposed Frontend-Backend protocol. Sorry if it is too long (and took too long to write) for the thing which is really simple, but I've tried to make it as full (covering all cases) and formal as possible :)

Code:
Frontend-Backend Port Redirecting Protocol (draft)

by Vadim Goncharov <vadim_nuclight@mail.ru>, 14 Mar 2008.

1. Introduction.

Network administrators in large companies, as well as owners of several
computers in small home networks, are often need to do a sharing of one or
several public IP addresses to a larger number of end users' private IP
addresses. This can be done via NAT (Network Address Translation), a SOCKS
4/5 proxy or something else. But while this always ensures traversing
connections from the private network to the Internet, connections arriving
in opposite direction can't easily determine which private IP address should
be selected, thus requiring manual port redirection setup. There are also
some protocols, e.g. NAT-PMP or SOCKS5 which allow client programs to setup
redirections automatically.

It is usually one program which does handle connections in both directions,
and it can be also of NAT-PMP or a SOCKS proxy server, but in some
configurations this is hard to achieve, as several different computers can
serve NAT, or SOCKS5 proxy protocol allows to have more then one public IP,
etc. If it could be split into two parts, a frontend conversating with users
about which ports to redirects, and a backend, let's call it "redirecting
engine" (or simply "engine"), which does actual data-passing work, then system
could be more scalable and extendable. Then the frontend can handle all the
complex logic with user authorization, different protocols, etc., while backend
could be simple and fast for bulk data. Imagine, for example, a SOCKS server
doing it's work in a software (slow) which is then upgraded to other backend
(fast in-kernel or hardware entity) without any changes in a frontend itself.

This document defines standard protocol between engine and front-end, allowing
one to combine any engine with any front-end (user can easily extend system).

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in "Key words for use in
RFCs to Indicate Requirement Levels" [RFC 2119].

2. Protocol.

Protocol is simple, stream text-based and line-oriented. Valid line separators
are both LF alone and CR LF pair, empty lines and lines beginning with "#"
character MUST be ignored. Backend acts like a server processing frontend's
requests. Backend listens on a UNIX domain socket or a TCP port. Both
connection endpoints (path to socket or a TCP address and port) are configured
on a frontend and backend, this is a responsibility of a system administrator
as well as limiting access to backend: protocol doesn't deal with security to
simplify backend implementation, security issues with end users should be
handled by frontend.

Backend is ready to operation immediately after connection was established,
no commands are needed. Backend should be able to handle several frontends
simltaneously, one per connection. There are no timeouts, connection could be
idle for any amount of time and can be terminated at any time by any of the
peers. Connection termination should not affect redirection state of backend -
frontend can reconnect any time. In other words, communication is as stateless
as possible.

Protocol commands are always lines of characters terminated with a CR-LF
(Carriage Return - Line Feed) pair (or LF alone), and these messages MUST MOT
exceed 512 characters in length, counting all characters including the trailing
CR-LF. Thus, there are 510 characters maximum allowed for the command and its
parameters. There is no provision for continuation command lines. Protocol
is case-sensitive (case MUST be preserved in both commands and description
field).

Frontend always makes one-command (one-line) requests, backend always MUST
respond with one or more lines. Protocol commands (messages) have the same
general format for both requests and replies.

2.1. Command format in 'pseudo' BNF.

The protocol commands must be extracted from the contiguous stream of octets.
For implementation simplicity, NUL characters are disallowed. Also,

The BNF representation for this is:

<message>  ::= '#' <comment> <crlf> | <command> [ <params> ] <crlf>
<command>  ::= <letter> { <letter> | <number> }
<SPACE>    ::= ' ' { ' ' }
<params>   ::= <param> { <SPACE> <param> }
<param>    ::= <Any *non-empty* sequence of octets not including SPACE
                or NUL or CR or LF>
<comment>  ::= <Any, possibly *empty* sequence of octets not including
                NUL or CR or LF>
<crlf>     ::= [ CR ] LF

Other parameters syntax are:

<identifier> ::= <letter> { <letter> | <number> | <underscore> }
<letter>     ::= 'a' ... 'z' | 'A' ... 'Z'
<number>     ::= '0' ... '9'
<underscore> ::= '_'
<port>       ::= <Sequence of 1 to 5 digits, forming number from 0 to 65535>
<ipaddr>     ::= <Usual text represenation of IPv4 address, e.g. "0.0.0.0" or
                  "123.45.67.89", each octet can range from 0 to 255>

There can be any number of SPACEs between parameters. Identifiers
MUST NOT be longer 31 characters.

2.2. Requests, replies and protocol operation.

Frontend issues requests, fronted replies. A request may be specification of
new redirect, redirect deletion or request to list existing redirects. Upon
creation of new redirect, backend assigns an identifier to it, which MUST be
unique till the backend's lifetime (e.g. until it's reboot). Then it is
returned to frontend as reply, or error can be returned, for example, if
backend is low on resources or redirects conflict occured. Redirect deletion
specifies an identifier of redirect to delete, which frontend can remember from
previous addition or obtain from a list of all currently active redirects.
Identifiers are strings opaque to frontend.

Basic protocol operation requires only the 3 requests above. As several
simultaneous frontends are supported (as well as backend may be only one of
clients of the actual redirecting engine), there may be a possibility of races
if frontend remebers own redirections - they could be removed by someone else
at any time, or new redirects can be added without frontend knowing it. Thus
in simple mode with only 3 commands, frontend should periodically refresh list.

This protocol handles only TCP and UDP protocols port redirections. Any given
redirection can be viewed as 7-tuple of protocol (TCP or UDP), IP address and
port on the client machine in the private network ("local" address and port),
IP address and port of an intermidiate machine ("public" address and port) and
an IP address and port of remote machine from which conection will be
originated. One can think that specification of "remote" address/port can be
viewed as a security measure limiting connections from specified address (and
possibly port), but it is not the only case. Backend can also be used to pass
connections from private network to Internet (e.g. normal operation of SOCKS
proxy), in which case "local" address is actually in the Internet and "remote"
machine is in the local network (somewhat reverse).

Only local address, port and public port are absolutely needed to create
redirection. One can choose to not care about remote address/port (allowing
connections from everyone) or about public IP address, allowing backend to
open port on all of backend's IP addresses (if it has multiple one) or one it
choose (randomly or configured default, this is left to implementor and system
administrator). If the address is not cared of, it MUST be specified as
0.0.0.0, if port is not cared, it MUST be specified as 0.

Redirections can be added by several frontends (and possibly manually by system
administrator), thus they have "description" field which is passed to/from
backend unchanged. Frontends can use this field to store optional info which
can be used, for example, to not touch each other redirections or to provide
human-readable descriptions. Each backend MUST support description field length
of at least 63 characters. Description field is always last, so spaces in it
are also preserved and not treated as parameter separators.

It should be noted that redirections are distinguished by their unique
identifier, not by public port (and address, if several are present). This
allows to use backends which can utilize one public port for several local
clients, e.g. by using specified remote address/port for different local
clients or doing some kind of random selection/load balancing (or such other
thing) on the same public port even if public IP, remote IP and remote port
all not given. Thus, it is responsibility of frontend to be configured to
properly select free ports to have no conflicts, etc.

One can argue that with only 3 base commands, race possibility and frontend
responsibility to do free port selection all thing is unreliable. However, this
is supposed to be cooperation of several processes under a single
administrative control, so in worst case problems can be solved by proper
configuring frontends and backends, e.g., each frontend can use it's own port
range. In best case, where backend has absolute control over the actual
redirecting engine, optional extension commands can be used to inform frontends
about all changes.

For any protocol command backend can return either a success indication or
an error report. Syntax for error reply is:

<errorreply>  ::= "ERROR" SPACE <errortype>
<errortype>   ::= "CMDSYNTAX" | "OPFAILED" | "NOTFOUND"

Error reply can be one of the three possible error cases:

   * CMDSYNTAX for syntax error in request or unsupported command;
   * OPFAILED when syntax was correct, but backend was unable to satisfy
     request due to underlying hardware or software failure (e.g. out of
     resources);
   * NOTFOUND when syntax was correct, but specified in request unique ID or
     public IP in addition request was not found in backend's internal tables
     (e.g. redirection was already deleted by other frontend).

2.3. Base protocol commands.

2.3.1. ADD.

This is main request from frontend to backend to add redirection. Syntax is:

<addrequest>  ::= "ADD" SPACE <proto> SPACE <localip> SPACE <localport> SPACE
                  <publicip> SPACE <publicport> SPACE <remoteip> SPACE
                  <remoteport> SPACE <description>
<proto>       ::= "tcp" | "udp"
<localip>     ::= <ipaddr>
<publicip>    ::= <ipaddr>
<remoteip>    ::= <ipaddr>
<localport>   ::= <port>
<publicport>  ::= <port>
<remoteport>  ::= <port>
<description> ::= <comment>

Parameters of the ADD command (distintc types of addresses and ports) were
discussed in section 2.2. Backend MUST reply with a single-line message
indicating either error condition or successful addition of redirect (in the
latter case unique identifier of newly created redirection is returned.

Syntax of successful reply to ADD command is:

<addreplyok>  ::= "ADDED" SPACE <identifier>

2.3.2. DELETE.

Request to delete redirection which was established earlier. Syntax is:

<deleterequest> ::= "DELETE" SPACE <identifier>

It takes one parameter: unique ID of redirection obtained via previous ADD or
LIST commands.

If redirection removal was successful, reply is returned:

<deletereply> ::= "DELETED" SPACE <identifier>

Here unique ID is just copied from DELETE request.

2.3.3. LIST.

This request allows to get table of all currently active backend's
redirections. It consists of the word "LIST" on the line alone without any
parameters. Backend replies with zero or more replies, one line for each
redirection, followed by a line with the word "ENDLIST" (without parameters),
indicating end of list. Syntax for one redirection-specifying line of reply is:

<listreplyentry> ::= "LIST" SPACE <identifier> SPACE <proto> SPACE
                     <localip> SPACE <localport> SPACE <publicip> SPACE
                     <publicport> SPACE <remoteip> SPACE <remoteport> SPACE
                     <description>

Meaning of the fields is the same as for ADD and DELETE requests. If list is
emty, no error is returned and reply consists of "ENDLIST" line only.

2.4. Optional commands.

Backend implementor MAY choose to support one or more optional extension
commands to make frontend implementor's life a bit easier. There is a special
command to get a list of all supported extensions, which MUST be supported by
every backend implementing extensions in addition to 3 base required commands.
This is a one-word "CAPABILITIES" request from frontend (no parameters). Simple
backend will answer "ERROR CMDSYNTAX" signalling that no extensions are
supported. More complicated backend will reply with supported command list
with a following syntax:

<capreply>    ::= "CAPABILITIES" SPACE <command> { SPACE <command> }

So this is just space-separated list of extension commands (base 3 are not
included) which backend will accept. These could be either defined in this
document commands or vendor-specific extensions. It is implied that backend
responding to CAPABILITIES request MUST support at least one extension
command (except CAPABILITIES itself), so reply MUST have at least 1 argument.

Example reply with all extensions defined in this document:

   CAPABILITIES LISTID OTHERCHANGED GETIPLIST

2.4.1. LISTID.

This is request for showing exactly one line from redirection table instead of
returning entire list as with LIST command. Syntax is:

<listidreply> ::= "LISTID" SPACE <identifier>

Here unique ID is specified as with DELETE command. If ID was found in table,
one-line reply is returned with syntax defined earlier for replies to LIST,
but without trailing "ENDLIST" line. If ID was not found, corresponding ERROR
is returned.

2.4.2. OTHERCHANGED.

This commands indicates that backend has absolute control over the actual
underlying redirecting engine and thus is able inform frontend about it's table
state changing when it occurs, e.g. after modifying by other frontend. Such
notifications, though, MUST be disabled by default, and are enabled by frontend
issuing OTHERCHANGED command, without parameters. Backend responds with the
following reply:

<otherchangedenablereply> ::= "OTHERCHANGED" SPACE <number> { <number> }

Here number in reply is total count of all currently connected frontends to
this backend. Once enabled, notifications can't be disabled, ond subsequent
OTHERCHANGED commands are useful only for statistical purposes of getting
up-to-date number of connected frontends.

Notifications, in contrast to other protocol parts, consist of gratuitous
messages from backend without any frontend commands, a kind of "reply which
is not a reply to a something", so, as mentioned before, they MUST be disabled
by default to not confuse frontends which are not prepared to receive a reply
without a command. Notifications consist of "OTHERCHANGED" command word with
parameters filled with a copy of reply to another frontend which made an
actual request, for example, it could be

   OTHERCHANGED ADDED nat1_id44

or

   OTHERCHANGED DELETED rF5_xck7

2.4.3. GETIPLIST.

This request allows frontend to retrieve list of IP addresses which can be
used as "public" in subsequent requests. It consists of the word "GETIPLIST" on
the line alone without any parameters. Backend replies with one or more
replies, one line for each IP address, followed by a line with the word
"ENDIPLIST" (without parameters), indicating end of list. Syntax for one
IP address line of reply is:

<iplistentry> ::= "IPLIST" SPACE <ipaddr>

So this will be list of all IP adresses, one per line, available to backend
engine.

3. References.

[SOCKS5] Leech, M., Ganis, M., Lee, Y., Kuris, R., Koblas, D., Jones, L.,
         "SOCKS Protocol Version 5", RFC 1928, March 1996.

[NATPMP] Cheshire, S., Krochmal, M., Sekar, K., "NAT Port Mapping Protocol
         (NAT-PMP)", Internet Draft, September 2006,
         <http://files.dns-sd.org/draft-cheshire-nat-pmp.txt>


Comments are welcome! May be some issues should be fixed for better implementation ;)
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Sat Mar 15, 2008 10:47 am    Post subject: Reply with quote

miniupnp wrote:
hum... I'll try to do something for you...


So, I've patched ng_nat, waited it to merge to FreeBSD 6.x, prepared a proto draft and looked to the miniupnpd sources more closely. So, I see that firewall-dealing code functions are not supposed to be used with several external IPs. All that they have is public port passed and interface name as char*. How can I patch miniupnpd to support several IPs there? I must patch entire tree in every place where it is called? Or, given other my network-specific conditions, should I write my own NAT-PMP daemon for this, for my sepcific site with that hacks? :)
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
miniupnp
Site Admin


Joined: 14 Apr 2007
Posts: 1442

PostPosted: Sat Mar 15, 2008 2:10 pm    Post subject: Reply with quote

nuclight wrote:
miniupnp wrote:
hum... I'll try to do something for you...


So, I've patched ng_nat, waited it to merge to FreeBSD 6.x, prepared a proto draft and looked to the miniupnpd sources more closely. So, I see that firewall-dealing code functions are not supposed to be used with several external IPs. All that they have is public port passed and interface name as char*. How can I patch miniupnpd to support several IPs there? I must patch entire tree in every place where it is called? Or, given other my network-specific conditions, should I write my own NAT-PMP daemon for this, for my sepcific site with that hacks? Smile

Indeed, UPnP IGD Spec is made for router with only One Public IP. I don't know how to make miniupnpd support several public IPs, but I guess it will need to patch things almost everywhere.
_________________
Main miniUPnP author.
http://miniupnp.tuxfamily.org/
Back to top
View user's profile Send private message Visit poster's website
nuclight



Joined: 17 Jan 2008
Posts: 23

PostPosted: Mon Mar 17, 2008 3:28 pm    Post subject: Reply with quote

miniupnp wrote:
nuclight wrote:
So, I've patched ng_nat, waited it to merge to FreeBSD 6.x, prepared a proto draft and looked to the miniupnpd sources more closely. So, I see that firewall-dealing code functions are not supposed to be used with several external IPs. All that they have is public port passed and interface name as char*. How can I patch miniupnpd to support several IPs there? I must patch entire tree in every place where it is called? Or, given other my network-specific conditions, should I write my own NAT-PMP daemon for this, for my sepcific site with that hacks? :)

Indeed, UPnP IGD Spec is made for router with only One Public IP. I don't know how to make miniupnpd support several public IPs, but I guess it will need to patch things almost everywhere.


Yes, but let me summarize some facts:

1) Networks NATting to multiple ext IPs can exists in several "gradations". First possible is: several internal NICs, with one different IP subnet on each, each subnet maps to it's own external IP independent of each other.
2) One IP subnet on one physical NIC (broadcast domain), divided somehow into individual IPs or ranges, which are mapped to several external IPs.
3) Both NAT-PMP and UPnP client requests to get his external IP can be answered with proper address for both (1) and (2), if we are not taking into account other protocols' parts.
4) NAT-PMP other protocol part instructs router to inform clients about changed ext IP (or at boot) by SINGLE the same multicast address 224.0.0.1 which is effectivelt all hosts.
5) UPnP does more complex multicasts to specific group.
6) Due to simplicity of NAT-PMP typical client will not care about destination multicast address (he don't need to care on multicast groups joining/leaving as 224.0.0.1 is equivalent to broadcast) and will accept notify from (4) in case of directed datagram to gim only.
7) This makes it possible to implement a (2) for NAT-PMP by hack at router as processing each client individually.
8) This is not suitable for UPnP which uses multicasts in both directions more heavily.
9) But, miniupnpd does not implement (4) and for NAT-PMP it works, yet for UPnP it DOES both (5), and (8) is applicable, as it is required for SSDP.

So, the valid "several ext IPs" case for protocols is (1) and my network is configured with (2) - more "hacky", though still achievable by most NATs, including pf. As we can see, neither miniupnpd nor UPnP itself can't work with (2), so I am, in my particular network, limited to NAT-PMP.

But case (1) is still valid for both, and people may have such setups, and minupnpd has some initial multi-ext-IP code for that setups. As mentioned earlier, redir functions callers should be patched in entire tree. One possible solution is add check-and-using proper external IP for into the firewall-dependent functions themselves. Is it good?

The last question is: should I, for (2), do patching miniupnpd disabling it main SSDP functions, or should I write my own custom small daemon for my net with NAT-PMP only (then provide NAT-PMP project with patches for protocol spec above, for (1) case and other firewalls) ? I guess that SSDP disabling hack will not likely to go to miniupnpd source tree? :)
_________________
WBR, Nuclear Lightning
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    miniupnp.tuxfamily.org Forum Index -> NAT/UPnP All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP
© 2007 Thomas Bernard, author of MiniUPNP.