Subject: bin/8591: pppd doesn't support ms-dns (RFC1877) as a client (ms-get-dns)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <mike@pelley.com>
List: netbsd-bugs
Date: 10/09/1999 10:36:58
>Number:         8591
>Category:       bin
>Synopsis:       pppd doesn't support ms-dns (RFC1877) as a client (ms-get-dns)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Oct  9 10:36:00 1999
>Last-Modified:
>Originator:     Mike Pelley
>Organization:
	Foundation
>Release:        <NetBSD-current source date>
>Environment:
	
System: NetBSD rossem.worldmap.net 1.4 NetBSD 1.4 (ROSSEM) #1: Wed Jul 14 23:17:19 EDT 1999 mike@rossem.worldmap.net:/usr/src/src-1.4/sys/arch/i386/compile/ROSSEM i386


>Description:
PPPD will serve dns to clients that connect with an option called ms-dns, but it will not retrieve the dns servers from the other end (i.e. when it is the client).  Apparently, the folks who take care of PPPD have no interest in supporting this feature as it is "a horrible protocol layering violation".  However, it can be quite useful when connecting via dialup (and especially when connecting to a corporate intranet via RAS that has an internal DNS server).

>How-To-Repeat:
to repeat:
N/A - missing feature.

>Fix:
The following patch adds the functionality to pppd (version 2.3.5).  I applied it to 1.4 sources and aside from minor line number differences it worked well and my new pppd gives me the DNS info (as environment variables to ip-up).  It also patches the man page, which is nice ;o)   I got it from ftp://ftp.wcl.bham.ac.uk/pub/bam/patches/pppd-2.3.5-get-ms-dns.diff.


diff --recursive -u ppp-2.3.5/pppd/ipcp.c ppp-2.3.5+get-ms-dns/pppd/ipcp.c
--- ppp-2.3.5/pppd/ipcp.c	Wed Apr 29 00:38:10 1998
+++ ppp-2.3.5+get-ms-dns/pppd/ipcp.c	Tue Dec 29 12:24:03 1998
@@ -327,7 +327,11 @@
     }
 
     return (LENCIADDR(go->neg_addr, go->old_addrs) +
-	    LENCIVJ(go->neg_vj, go->old_vj));
+	    LENCIVJ(go->neg_vj, go->old_vj) +
+	    LENCIADDR(go->neg_dns1, 0) +
+	    LENCIADDR(go->neg_dns2, 0) +
+	    LENCIADDR(go->neg_wins1, 0) +
+	    LENCIADDR(go->neg_wins2, 0));
 }
 
 
@@ -383,6 +387,14 @@
     ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
 	    go->maxslotindex, go->cflag);
 
+    ADDCIADDR(CI_MS_DNS1, go->neg_dns1, 0, go->dnsaddr[0], 0);
+
+    ADDCIADDR(CI_MS_DNS2, go->neg_dns2, 0, go->dnsaddr[1], 0);
+
+    ADDCIADDR(CI_MS_WINS1, go->neg_wins1, 0, go->winsaddr[0], 0);
+
+    ADDCIADDR(CI_MS_WINS2, go->neg_wins2, 0, go->winsaddr[1], 0);
+
     *lenp -= len;
 }
 
@@ -463,6 +475,14 @@
     ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
 	    go->maxslotindex, go->cflag);
 
+    ACKCIADDR(CI_MS_DNS1, go->neg_dns1, 0, go->dnsaddr[0], 0);
+
+    ACKCIADDR(CI_MS_DNS2, go->neg_dns2, 0, go->dnsaddr[1], 0);
+
+    ACKCIADDR(CI_MS_WINS1, go->neg_wins1, 0, go->winsaddr[0], 0);
+
+    ACKCIADDR(CI_MS_WINS2, go->neg_wins2, 0, go->winsaddr[1], 0);
+
     /*
      * If there are any remaining CIs, then this packet is bad.
      */
@@ -583,6 +603,16 @@
 	    }
 	    );
 
+
+    NAKCIADDR(CI_MS_DNS1, neg_dns1, 0, try.dnsaddr[0]=ciaddr1; );
+
+    NAKCIADDR(CI_MS_DNS2, neg_dns2, 0, try.dnsaddr[1]=ciaddr1; );
+
+    NAKCIADDR(CI_MS_WINS1, neg_wins1, 0, try.winsaddr[0]=ciaddr1; );
+
+    NAKCIADDR(CI_MS_WINS2, neg_wins2, 0, try.winsaddr[1]=ciaddr1; );
+
+
     /*
      * There may be remaining CIs, if the peer is requesting negotiation
      * on an option that we didn't include in our request packet.
@@ -725,6 +755,14 @@
     REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
 	    go->maxslotindex, go->cflag);
 
+    REJCIADDR(CI_MS_DNS1, neg_dns1, 0, go->dnsaddr[0], 0);
+
+    REJCIADDR(CI_MS_DNS2, neg_dns2, 0, go->dnsaddr[1], 0);
+
+    REJCIADDR(CI_MS_WINS1, neg_wins1, 0, go->winsaddr[0], 0);
+
+    REJCIADDR(CI_MS_WINS2, neg_wins2, 0, go->winsaddr[1], 0);
+
     /*
      * If there are any remaining CIs, then this packet is bad.
      */
@@ -1159,6 +1197,18 @@
     }
     script_setenv("IPLOCAL", ip_ntoa(go->ouraddr));
     script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr));
+
+    if ( go->dnsaddr[0] )
+      script_setenv("MS_DNS1", ip_ntoa(go->dnsaddr[0]));
+
+    if ( go->dnsaddr[1] )
+      script_setenv("MS_DNS2", ip_ntoa(go->dnsaddr[1]));
+
+    if ( go->winsaddr[0] )
+      script_setenv("MS_WINS1", ip_ntoa(go->winsaddr[0]));
+
+    if ( go->winsaddr[1] )
+      script_setenv("MS_WINS2", ip_ntoa(go->winsaddr[1]));
 
     /*
      * Check that the peer is allowed to use the IP address it wants.
diff --recursive -u ppp-2.3.5/pppd/ipcp.h ppp-2.3.5+get-ms-dns/pppd/ipcp.h
--- ppp-2.3.5/pppd/ipcp.h	Wed Apr 29 00:38:11 1998
+++ ppp-2.3.5+get-ms-dns/pppd/ipcp.h	Tue Dec 29 12:24:03 1998
@@ -52,6 +52,10 @@
     int old_vj : 1;		/* use old (short) form of VJ option? */
     int accept_local : 1;	/* accept peer's value for ouraddr */
     int accept_remote : 1;	/* accept peer's value for hisaddr */
+    int neg_dns1 : 1;           /* Negotiate MS DNS entries */
+    int neg_dns2 : 1;           /* Negotiate MS DNS entries */
+    int neg_wins1 : 1;          /* Negotiate MS WINS entries */
+    int neg_wins2 : 1;          /* Negotiate MS WINS entries */
     u_short vj_protocol;	/* protocol value to use in VJ option */
     u_char maxslotindex, cflag;	/* values for RFC1332 VJ compression neg. */
     u_int32_t ouraddr, hisaddr;	/* Addresses in NETWORK BYTE ORDER */
diff --recursive -u ppp-2.3.5/pppd/options.c ppp-2.3.5+get-ms-dns/pppd/options.c
--- ppp-2.3.5/pppd/options.c	Thu Mar 26 04:46:07 1998
+++ ppp-2.3.5+get-ms-dns/pppd/options.c	Tue Dec 29 12:24:03 1998
@@ -225,8 +225,10 @@
 static int setidle __P((char **));
 static int setholdoff __P((char **));
 static int setdnsaddr __P((char **));
+static int setgetdnsaddr __P((char **));
 static int resetipxproto __P((char **));
 static int setwinsaddr __P((char **));
+static int setgetwinsaddr __P((char **));
 static int showversion __P((char **));
 static int showhelp __P((char **));
 
@@ -381,6 +383,8 @@
     {"holdoff", 1, setholdoff},		/* set holdoff time (seconds) */
     {"ms-dns", 1, setdnsaddr},		/* DNS address for the peer's use */
     {"ms-wins", 1, setwinsaddr},	/* Nameserver for SMB over TCP/IP for peer */
+    {"ms-get-dns", 0, setgetdnsaddr},	/* DNS address for the my use */
+    {"ms-get-wins", 0, setgetwinsaddr},	/* Nameserver for SMB over TCP/IP for me */
     {"noipx",  0, resetipxproto},	/* Disable IPXCP (and IPX) */
     {"-ipx",   0, resetipxproto},	/* Disable IPXCP (and IPX) */
     {"--version", 0, showversion},	/* Show version number */
@@ -2381,6 +2385,31 @@
     ipcp_allowoptions[0].winsaddr[1] = wins;
 
     return (1);
+}
+
+/*
+ * setgetdnsaddr - ask peer's idea of DNS server's address
+ */
+static int
+setgetdnsaddr(argv)
+    char **argv;
+{
+    ipcp_wantoptions[0].neg_dns1 = 1;
+    ipcp_wantoptions[0].neg_dns2 = 1;
+    return 1;
+}
+
+/*
+ * setgetwinsaddr - ask peer's idea of WINS server's address
+ */
+
+static int
+setgetwinsaddr(argv)
+    char **argv;
+{
+    ipcp_wantoptions[0].neg_wins1 = 1;
+    ipcp_wantoptions[0].neg_wins2 = 1;
+    return 1;
 }
 
 #ifdef IPX_CHANGE
diff --recursive -u ppp-2.3.5/pppd/pppd.8 ppp-2.3.5+get-ms-dns/pppd/pppd.8
--- ppp-2.3.5/pppd/pppd.8	Tue Mar 31 05:30:58 1998
+++ ppp-2.3.5+get-ms-dns/pppd/pppd.8	Tue Dec 29 12:37:14 1998
@@ -418,13 +418,29 @@
 control, as for the \fIcrtscts\fR option.
 .TP
 .B ms-dns \fI<addr>
-If pppd is acting as a server for Microsoft Windows clients, this
+If pppd is acting as a server for clients using RFC1877 such as
+Microsoft Windows or or pppd with the get-ms-dns option, this
 option allows pppd to supply one or two DNS (Domain Name Server)
 addresses to the clients.  The first instance of this option specifies
 the primary DNS address; the second instance (if given) specifies the
 secondary DNS address.  (This option was present in some older
 versions of pppd under the name \fBdns-addr\fR.)
 .TP
+.B ms-get-dns
+Implement the client side of RFC1877.  If pppd is acting as a client
+to a server that implements RFC1877 such as one intended to be used
+with Microsoft Windows clients, this option allows pppd to obtain one
+or two DNS (Domain Name Server) addresses from the server.  It does
+not do anything with these addresses except put them in the
+environment that is passed to scripts.  The /etc/ppp/ip-up script
+should use this information to perform whatever adjustment is
+necessary.  Note: RFC1877 is a horrible protocol layering violation,
+the correct approach would be to use DHCP after the IPCP phase.
+.TP
+.B ms-get-wins
+As ms-get-dns but for WINS (Windows Internet Name Services) server
+addresses.
+.TP
 .B ms-wins \fI<addr>
 If pppd is acting as a server for Microsoft Windows or "Samba"
 clients, this option allows pppd to supply one or two WINS (Windows
@@ -977,6 +993,13 @@
 .B IPREMOTE
 The IP address for the remote end of the link.  This is only set when
 IPCP has come up.
+.TP
+.B MS_DNS1 MS_DNS2 MS_WINS1 MS_WINS2
+The first and second DNS and WINS server IP address supplied by the
+peer (server) using RFC1877.  This is only set IPCP has come up and
+then only if we asked for and received this information.  If there is
+only one address then it may appear in the first variable, the second
+or both depending on the server.
 .TP
 .B PEERNAME
 The authenticated name of the peer.  This is only set if the peer
>Audit-Trail:
>Unformatted: