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;