Subject: kern/29757: SIOCGNATL can't do inbound lookups
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Peter Postma <peter@pointless.nl>
List: netbsd-bugs
Date: 03/21/2005 21:14:00
>Number: 29757
>Category: kern
>Synopsis: SIOCGNATL can't do inbound lookups
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Mar 21 21:14:00 +0000 2005
>Originator: Peter Postma
>Release: NetBSD 3.0_BETA
>Organization:
>Environment:
System: NetBSD mercury.pointless.nl 3.0_BETA NetBSD 3.0_BETA (mercury) #135: Thu Mar 17 16:37:29 CET 2005 peter@mercury.pointless.nl:/usr/obj/sys/arch/sparc64/compile/mercury sparc64
Architecture: sparc64
Machine: sparc64
>Description:
SIOCGNATL can do outbound lookups, it looks for the real address when
we know the destination/source addresses & ports.
But it can't do inbound lookups, to look for the source address (on the lan)
when we know the destination/real addresses & ports.
The latter would be useful when doing a lookup on the gateway for an ident
query, you'll need to find the source address then (FYI: I'm currently
working to implement this into identd(8) and it's almost finished).
>How-To-Repeat:
>Fix:
This patch add the flags IPN_IN and IPN_OUT which can be specified in the
natlook struct. If none of these flags are specified, it defaults to the
IPN_OUT lookup (which was also the previous behaviour).
Index: ip_nat.c
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_nat.c,v
retrieving revision 1.5
diff -u -r1.5 ip_nat.c
--- ip_nat.c 19 Feb 2005 21:30:25 -0000 1.5
+++ ip_nat.c 21 Mar 2005 20:29:56 -0000
@@ -3349,8 +3349,13 @@
nat_t *nat;
bzero((char *)&fi, sizeof(fi));
- fi.fin_data[0] = ntohs(np->nl_inport);
- fi.fin_data[1] = ntohs(np->nl_outport);
+ if (np->nl_flags & IPN_IN) {
+ fi.fin_data[0] = ntohs(np->nl_realport);
+ fi.fin_data[1] = ntohs(np->nl_outport);
+ } else {
+ fi.fin_data[0] = ntohs(np->nl_inport);
+ fi.fin_data[1] = ntohs(np->nl_outport);
+ }
if (np->nl_flags & IPN_TCP)
fi.fin_p = IPPROTO_TCP;
else if (np->nl_flags & IPN_UDP)
@@ -3359,14 +3364,28 @@
fi.fin_p = IPPROTO_ICMP;
/*
- * If nl_inip is non null, this is a lookup based on the real
- * ip address. Else, we use the fake.
+ * We can do two sorts of lookups:
+ * - IPN_IN: we have the `real' and `out' address, look for `in'.
+ * - IPN_OUT: we have the `in' and `out' address, look for `real'.
*/
- if ((nat = nat_outlookup(&fi, np->nl_flags, fi.fin_p, np->nl_inip,
- np->nl_outip))) {
- np->nl_realip = nat->nat_outip;
- np->nl_realport = nat->nat_outport;
+ if (np->nl_flags & IPN_IN) {
+ if ((nat = nat_inlookup(&fi, np->nl_flags, fi.fin_p,
+ np->nl_realip, np->nl_outip))) {
+ np->nl_inip = nat->nat_inip;
+ np->nl_inport = nat->nat_inport;
+ }
+ } else {
+ /*
+ * If nl_inip is non null, this is a lookup based on the real
+ * ip address. Else, we use the fake.
+ */
+ if ((nat = nat_outlookup(&fi, np->nl_flags, fi.fin_p,
+ np->nl_inip, np->nl_outip))) {
+ np->nl_realip = nat->nat_outip;
+ np->nl_realport = nat->nat_outport;
+ }
}
+
return nat;
}
Index: ip_nat.h
===================================================================
RCS file: /cvsroot/src/sys/dist/ipf/netinet/ip_nat.h,v
retrieving revision 1.4
diff -u -r1.4 ip_nat.h
--- ip_nat.h 19 Feb 2005 21:30:25 -0000 1.4
+++ ip_nat.h 21 Mar 2005 20:29:56 -0000
@@ -251,6 +251,8 @@
#define IPN_STICKY 0x80000
#define IPN_FRAG 0x100000
#define IPN_FIXEDDPORT 0x200000
+#define IPN_IN 0x400000
+#define IPN_OUT 0x800000
#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\
IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\
IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY)