Hello,

This is an old patch from Gerhard Roth, and mpf@ dating back to 2007.  Please
see:  https://marc.info/?l=openbsd-tech&m=134943767022961&w=2

I contacted Gerhard who said instead of begging for this I should make it
IPv6 capable.  So I tried and nearly flooded my ISP off the net (sorry),
it seems that there is no IPV6CP capabilities for this yet.  I googled and
found a few drafts but all said the protocol number is TBD.  Also I looked
on IANA.org https://www.iana.org/assignments/ppp-numbers/ppp-numbers.xhtml
and found no official IPV6CP specification.

I'm submitting this patch because I have a need for DNS servers as my ISP
does not give these out via official support channels.  So I'm relying on
either using a public resolver (such as 8.8.8.8) or unwind.  No offence to 
unwind but I'd rather use these ISP nameservers if I knew where to get them.
I have also made a forwarding feature on my authoritative nameserver (with
caching) and would write the code to automatically configure on startup to
automatically determined pppoe(4) nameservers.  So this is the self pitch.

Patch is below with lots of #if 0, that I'd clean up if it passes the
political hurdles.  Also I have no -current on me currently so this is all
against 6.7.  I understand there is wireguard code in ifconfig and I'd have
to bite the bullet and sysupgrade a machine here to make new new patch
fit.  I just need an OK from someone and I'll clean it up otherwise I 
won't do anymore work on this subject.  Patch after my signature:

Best Regards,
-peter


Index: ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.421
diff -u -p -u -r1.421 ifconfig.c
--- ifconfig.c  27 Feb 2020 08:28:35 -0000      1.421
+++ ifconfig.c  6 Jul 2020 17:09:49 -0000
@@ -690,6 +690,7 @@ u_int       getwpacipher(const char *);
 void   print_cipherset(u_int32_t);
 
 void   spppauthinfo(struct sauthreq *, int);
+void   spppdnsinfo(struct sdnsreq *);
 
 /* Known address families */
 const struct afswtch {
@@ -5401,6 +5402,17 @@ spppauthinfo(struct sauthreq *spa, int d
 }
 
 void
+spppdnsinfo(struct sdnsreq *spd)
+{
+       bzero(spd, sizeof(struct sdnsreq));
+       
+       ifr.ifr_data = (caddr_t)spd;
+       spd->cmd = SPPPIOGDNS;
+       if (ioctl(sock, SIOCGSPPPPARAMS, &ifr) == -1)
+               err(1, "SIOCGSPPPPARAMS(SPPPIOGDNS)");
+}
+
+void
 setspppproto(const char *val, int d)
 {
        struct sauthreq spa;
@@ -5534,6 +5546,11 @@ sppp_status(void)
 {
        struct spppreq spr;
        struct sauthreq spa;
+       struct sdnsreq spd;
+       struct sockaddr_storage *ss = NULL;
+
+       char buf[INET6_ADDRSTRLEN];
+       int i;
 
        bzero(&spr, sizeof(spr));
 
@@ -5573,6 +5590,39 @@ sppp_status(void)
        if (spa.flags & AUTHFLAG_NORECHALLENGE)
                printf("norechallenge ");
        putchar('\n');
+
+       spppdnsinfo(&spd);
+       for (i = 0; i < 2; i++) {
+               ss = (struct sockaddr_storage *)&spd.ss_dns[i];
+               if (ss->ss_family == AF_UNSPEC)
+                       continue;
+
+               switch (i) {
+               case 0:
+                       inet_ntop(AF_INET, &((struct sockaddr_in 
*)ss)->sin_addr.s_addr,
+                               buf, sizeof(buf));
+                       printf("\tipcp pri_dns: %s\n", buf);
+                       break;
+               case 1:
+                       inet_ntop(AF_INET, &((struct sockaddr_in 
*)ss)->sin_addr.s_addr,
+                               buf, sizeof(buf));
+                       printf("\tipcp sec_dns: %s\n", buf);
+               break;
+#if notyet
+               case 2:
+                       inet_ntop(AF_INET6, &((struct sockaddr_in6 
*)ss)->sin6_addr,
+                                       buf, sizeof(buf));
+                       printf("\tpri_dns6: %s\n", buf);
+                       break;
+               case 3:
+                       inet_ntop(AF_INET6, &((struct sockaddr_in6 
*)ss)->sin6_addr,
+                                       buf, sizeof(buf));
+                       printf("\tsec_dns6: %s\n", buf);
+                       break;
+#endif
+               }
+       }
+
 }
 
 void
Index: if_sppp.h
===================================================================
RCS file: /cvs/src/sys/net/if_sppp.h,v
retrieving revision 1.27
diff -u -p -u -r1.27 if_sppp.h
--- if_sppp.h   24 Jun 2019 21:36:53 -0000      1.27
+++ if_sppp.h   6 Jul 2020 17:12:27 -0000
@@ -82,12 +82,18 @@ struct spppreq {
        enum ppp_phase phase;   /* phase we're currently in */
 };
 
+struct sdnsreq {
+       int cmd;
+       struct sockaddr_storage ss_dns[4];
+};
+
 #define SPPPIOGDEFS  ((int)(('S' << 24) + (1 << 16) + sizeof(struct spppreq)))
 #define SPPPIOSDEFS  ((int)(('S' << 24) + (2 << 16) + sizeof(struct spppreq)))
 #define SPPPIOGMAUTH ((int)(('S' << 24) + (3 << 16) + sizeof(struct sauthreq)))
 #define SPPPIOSMAUTH ((int)(('S' << 24) + (4 << 16) + sizeof(struct sauthreq)))
 #define SPPPIOGHAUTH ((int)(('S' << 24) + (5 << 16) + sizeof(struct sauthreq)))
 #define SPPPIOSHAUTH ((int)(('S' << 24) + (6 << 16) + sizeof(struct sauthreq)))
+#define SPPPIOGDNS   ((int)(('S' << 24) + (7 << 16) + sizeof(struct sdnsreq)))
 
 
 #ifdef _KERNEL
@@ -165,6 +171,7 @@ struct sppp {
        time_t  pp_last_receive;        /* peer's last "sign of life" */
        time_t  pp_last_activity;       /* second of last payload data s/r */
        enum ppp_phase pp_phase;        /* phase we're currently in */
+       struct sockaddr_storage ss_dns[4]; /* IPv4  DNS servers (RFC 1877) */
        int     state[IDX_COUNT];       /* state machine */
        u_char  confid[IDX_COUNT];      /* id of last configuration request */
        int     rst_counter[IDX_COUNT]; /* restart counter */
Index: if_spppsubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.181
diff -u -p -u -r1.181 if_spppsubr.c
--- if_spppsubr.c       13 Nov 2019 10:15:10 -0000      1.181
+++ if_spppsubr.c       6 Jul 2020 17:12:27 -0000
@@ -133,6 +133,9 @@
 #define IPCP_OPT_ADDRESSES     1       /* both IP addresses; deprecated */
 #define IPCP_OPT_COMPRESSION   2       /* IP compression protocol (VJ) */
 #define IPCP_OPT_ADDRESS       3       /* local IP address */
+#define IPCP_OPT_PSEUDO_DNS    31      /* 129 and 131 don't fit */
+#define IPCP_OPT_PRIMDNS       129     /* primary remote dns address */
+#define IPCP_OPT_SECDNS                131     /* secondary remote dns address 
*/
 
 #define IPV6CP_OPT_IFID                1       /* interface identifier */
 #define IPV6CP_OPT_COMPRESSION 2       /* IPv6 compression protocol */
@@ -2261,6 +2264,8 @@ sppp_ipcp_init(struct sppp *sp)
        sp->ipcp.flags = 0;
        sp->state[IDX_IPCP] = STATE_INITIAL;
        sp->fail_counter[IDX_IPCP] = 0;
+       bzero(&sp->ss_dns[0], sizeof(sp->ss_dns[0]));
+       bzero(&sp->ss_dns[1], sizeof(sp->ss_dns[1]));
        task_set(&sp->ipcp.set_addr_task, sppp_set_ip_addrs, sp);
        task_set(&sp->ipcp.clear_addr_task, sppp_clear_ip_addrs, sp);
 }
@@ -2534,6 +2539,9 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
        struct ifnet *ifp = &sp->pp_if;
        int debug = ifp->if_flags & IFF_DEBUG;
        u_int32_t wantaddr;
+       struct sockaddr_in *sin0 = NULL, *sin1 = NULL;
+       struct sockaddr_storage ss_dns;
+       int dnsix;
 
        len -= 4;
 
@@ -2575,6 +2583,25 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
                                }
                        }
                        break;
+               case IPCP_OPT_PRIMDNS:
+               case IPCP_OPT_SECDNS:
+                       if (len >= 6 && p[1] == 6) {
+                               dnsix = (*p == IPCP_OPT_PRIMDNS) ? 0 : 1;
+                               sin0 = (struct sockaddr_in *)&ss_dns;
+                               bcopy(p + 2, &sin0->sin_addr.s_addr, 
+                                       sizeof(sin0->sin_addr.s_addr));
+                               sin0->sin_family = AF_INET;
+                               sin1 = (struct sockaddr_in *)&sp->ss_dns[dnsix];
+                               if (sin0->sin_addr.s_addr != 
sin1->sin_addr.s_addr) {
+                                       bcopy(&sin0->sin_addr.s_addr, 
+                                               &sin1->sin_addr.s_addr, 
+                                               sizeof(struct in_addr));
+
+                                       sin1->sin_family = AF_INET;
+                               }
+
+                       }
+                       break;
 #ifdef notyet
                case IPCP_OPT_COMPRESS:
                        /*
@@ -2584,6 +2611,7 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc
 #endif
                }
        }
+
        if (debug)
                addlog("\n");
 }
@@ -2656,13 +2684,16 @@ sppp_ipcp_tlf(struct sppp *sp)
        /* we no longer need LCP */
        sp->lcp.protos &= ~(1 << IDX_IPCP);
        sppp_lcp_check_and_close(sp);
+       bzero(&sp->ss_dns, sizeof(sp->ss_dns));
 }
 
 void
 sppp_ipcp_scr(struct sppp *sp)
 {
-       char opt[6 /* compression */ + 6 /* address */];
+       char opt[6 /* compression */ + 6 /* address */ + 12 /* dns addrs */];
+
        u_int32_t ouraddr;
+       struct sockaddr_in *sin = NULL;
        int i = 0;
 
 #ifdef notyet
@@ -2690,6 +2721,20 @@ sppp_ipcp_scr(struct sppp *sp)
                opt[i++] = ouraddr;
        }
 
+       sin = (struct sockaddr_in *)&sp->ss_dns[0];
+
+       opt[i++] = IPCP_OPT_PRIMDNS;
+       opt[i++] = 6;
+       bcopy(&sin->sin_addr.s_addr, &opt[i], sizeof(sin->sin_addr.s_addr));
+       i += sizeof(sin->sin_addr.s_addr);
+
+       sin = (struct sockaddr_in *)&sp->ss_dns[1];
+
+       opt[i++] = IPCP_OPT_SECDNS;
+       opt[i++] = 6;
+       bcopy(&sin->sin_addr.s_addr, &opt[i], sizeof(sin->sin_addr.s_addr));
+       i += sizeof(sin->sin_addr.s_addr);
+
        sp->confid[IDX_IPCP] = ++sp->pp_seq;
        sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, opt);
 }
@@ -2710,6 +2755,8 @@ sppp_ipv6cp_init(struct sppp *sp)
        sp->ipv6cp.flags = 0;
        sp->state[IDX_IPV6CP] = STATE_INITIAL;
        sp->fail_counter[IDX_IPV6CP] = 0;
+       bzero(&sp->ss_dns[2], sizeof(sp->ss_dns[2]));
+       bzero(&sp->ss_dns[3], sizeof(sp->ss_dns[3]));
        task_set(&sp->ipv6cp.set_addr_task, sppp_update_ip6_addr, sp);
 }
 
@@ -2985,6 +3032,12 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, str
        int debug = ifp->if_flags & IFF_DEBUG;
        struct in6_addr suggestaddr;
        char addr[INET6_ADDRSTRLEN];
+#if 0
+       /* don't enable see below */
+       struct sockaddr_storage ss_dns;
+       struct sockaddr_in6 *sin60 = NULL, *sin61 = NULL;
+       int dnsix;
+#endif
 
        len -= 4;
 
@@ -3035,6 +3088,29 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, str
                                sp->ipv6cp.flags |= IPV6CP_MYIFID_SEEN;
                        }
                        break;
+#if 0
+               /* DON'T ENABLE, I had this runnning and flooded my ISP */
+               /* DNS servers for IPV6CP have never made it out of draft */
+
+               case IPV6CP_OPT_PRIMDNS:
+               case IPV6CP_OPT_SECDNS:
+                       if (len >= 18 && p[1] == 18) {
+                               dnsix = (*p == IPCP_OPT_PRIMDNS) ? 2 : 3;
+                               sin60 = (struct sockaddr_in6 *)&ss_dns;
+                               bcopy(p + 2, &sin60->sin6_addr, 
+                                       sizeof(sin60->sin6_addr));
+                               sin60->sin6_family = AF_INET6;
+                               sin61 = (struct sockaddr_in6 
*)&sp->ss_dns[dnsix];
+                               if (bcmp(&sin60->sin6_addr, &sin61->sin6_addr, 
+                                       sizeof(sin60->sin6_addr)) != 0) {
+                                       bcopy(sin60, sin61, sizeof(struct 
sockaddr_in6));
+                                       sp->ipv6cp.opts |= (1 << 
IPV6CP_OPT_PSEUDO_DNS);
+                                       sp->ipv6cp.flags |= (1 << 
IPV6CP_OPT_PSEUDO_DNS);
+                               }
+                       }
+                               
+                       break;
+#endif
 #ifdef notyet
                case IPV6CP_OPT_COMPRESS:
                        /*
@@ -3044,6 +3120,7 @@ sppp_ipv6cp_RCN_nak(struct sppp *sp, str
 #endif
                }
        }
+
        if (debug)
                addlog("\n");
 }
@@ -3078,6 +3155,9 @@ sppp_ipv6cp_scr(struct sppp *sp)
 {
        char opt[10 /* ifid */ + 4 /* compression, minimum */];
        struct in6_addr ouraddr;
+#if 0
+       struct sockaddr_in6 *sin6 = NULL;
+#endif
        int i = 0;
 
        if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_IFID)) {
@@ -3090,6 +3170,28 @@ sppp_ipv6cp_scr(struct sppp *sp)
                bcopy(&ouraddr.s6_addr[8], &opt[i], 8);
                i += 8;
        }
+#if 0
+       if (1 || sp->ipv6cp.opts & (1 << IPV6CP_OPT_PSEUDO_DNS)) {
+               if (1 || sp->ss_dns[2].ss_family == AF_INET6) {
+                       sin6 = (struct sockaddr_in6 *)&sp->ss_dns[2];
+
+                       opt[i++] = IPV6CP_OPT_PRIMDNS;
+                       opt[i++] = 18;
+                       bcopy(&sin6->sin6_addr, &opt[i], 
+                                       sizeof(sin6->sin6_addr));
+                       i += sizeof(sin6->sin6_addr);
+               }
+               if (1 || sp->ss_dns[3].ss_family == AF_INET6) {
+                       sin6 = (struct sockaddr_in6 *)&sp->ss_dns[3];
+
+                       opt[i++] = IPV6CP_OPT_SECDNS;
+                       opt[i++] = 18;
+                       bcopy(&sin6->sin6_addr, &opt[i], 
+                                       sizeof(sin6->sin6_addr));
+                       i += sizeof(sin6->sin6_addr);
+               }
+       }
+#endif
 
 #ifdef notyet
        if (sp->ipv6cp.opts & (1 << IPV6CP_OPT_COMPRESSION)) {
@@ -4505,6 +4607,23 @@ sppp_get_params(struct sppp *sp, struct 
                free(spa, M_DEVBUF, 0);
                break;
        }
+        case SPPPIOGDNS:
+       {
+                struct sdnsreq *spd;
+
+                spd = malloc(sizeof(*spd), M_DEVBUF, M_WAITOK);
+
+               spd->cmd = cmd;
+                bcopy(sp->ss_dns, spd->ss_dns, sizeof(struct sockaddr_storage) 
* 4);
+
+               if (copyout(spd, (caddr_t)ifr->ifr_data, sizeof(*spd)) != 0) {
+                       free(spd, M_DEVBUF, 0);
+                       return EFAULT;
+               }
+
+               free(spd, M_DEVBUF, sizeof(*spd));
+               break;
+       }
        default:
                return EINVAL;
        }
@@ -4714,6 +4833,8 @@ sppp_ipcp_opt_name(u_char opt)
        case IPCP_OPT_ADDRESSES:        return "addresses";
        case IPCP_OPT_COMPRESSION:      return "compression";
        case IPCP_OPT_ADDRESS:          return "address";
+       case IPCP_OPT_PRIMDNS:          return "primarydns";
+       case IPCP_OPT_SECDNS:           return "secondarydns";
        }
        snprintf (buf, sizeof buf, "0x%x", opt);
        return buf;
@@ -4727,6 +4848,10 @@ sppp_ipv6cp_opt_name(u_char opt)
        switch (opt) {
        case IPV6CP_OPT_IFID:           return "ifid";
        case IPV6CP_OPT_COMPRESSION:    return "compression";
+#if 0
+       case IPV6CP_OPT_PRIMDNS:        return "primarydns6";
+       case IPV6CP_OPT_SECDNS:         return "secondarydns6";
+#endif
        }
        snprintf (buf, sizeof buf, "0x%x", opt);
        return buf;

Reply via email to