Hi, I trying to revive part of an old patch that was submitted by mpf in 2007. If adds support for DNS server negotiation to the IPCP part of sppp(4). If the PPP server provides IP addresses for DNS servers, they will appear in the ifconfig(8) output.
A simple ifstated(8) script could then be used to re-write resolv.conf, e.g. # ifconfig pppoe | sed -n 's/^[[:space:]]*dns.:/nameserver/p' Gerhard Index: sbin/ifconfig/ifconfig.c =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.257 diff -u -p -r1.257 ifconfig.c --- sbin/ifconfig/ifconfig.c 6 Sep 2012 19:41:59 -0000 1.257 +++ sbin/ifconfig/ifconfig.c 5 Oct 2012 11:19:36 -0000 @@ -4265,6 +4265,12 @@ sppp_status(void) if (spa.flags & AUTHFLAG_NORECHALLENGE) printf("norechallenge "); putchar('\n'); + if (spr.defs.dns_addrs[0] != INADDR_ANY) + printf("\tdns1: %s\n", + inet_ntoa(*(struct in_addr *)&spr.defs.dns_addrs[0])); + if (spr.defs.dns_addrs[1] != INADDR_ANY) + printf("\tdns2: %s\n", + inet_ntoa(*(struct in_addr *)&spr.defs.dns_addrs[1])); } void Index: sys/net/if_sppp.h =================================================================== RCS file: /cvs/src/sys/net/if_sppp.h,v retrieving revision 1.17 diff -u -p -r1.17 if_sppp.h --- sys/net/if_sppp.h 29 Jan 2012 10:21:54 -0000 1.17 +++ sys/net/if_sppp.h 5 Oct 2012 11:19:45 -0000 @@ -118,6 +118,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 */ + u_int32_t dns_addrs[2]; /* primary and secondary DNS server */ int state[IDX_COUNT]; /* state machine */ u_char confid[IDX_COUNT]; /* id of last configuration request */ int rst_counter[IDX_COUNT]; /* restart counter */ Index: sys/net/if_spppsubr.c =================================================================== RCS file: /cvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.98 diff -u -p -r1.98 if_spppsubr.c --- sys/net/if_spppsubr.c 24 Jul 2012 15:16:20 -0000 1.98 +++ sys/net/if_spppsubr.c 5 Oct 2012 11:19:45 -0000 @@ -167,6 +167,8 @@ #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_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 */ @@ -2687,6 +2689,7 @@ sppp_ipcp_init(struct sppp *sp) sp->ipcp.flags = 0; sp->state[IDX_IPCP] = STATE_INITIAL; sp->fail_counter[IDX_IPCP] = 0; + bzero(&sp->dns_addrs, sizeof(sp->dns_addrs)); #if defined (__FreeBSD__) callout_handle_init(&sp->ch[IDX_IPCP]); #endif @@ -2954,6 +2957,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; + u_int32_t dns; + int dnsix; + int dns_changed = 0; len -= 4; @@ -2995,6 +3001,17 @@ 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; + bcopy(p + 2, &dns, sizeof dns); + if (sp->dns_addrs[dnsix] != dns) { + sp->dns_addrs[dnsix] = dns; + dns_changed = 1; + } + } + break; #ifdef notyet case IPCP_OPT_COMPRESS: /* @@ -3004,6 +3021,8 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struc #endif } } + if ((ifp->if_flags & IFF_UP) && dns_changed) + rt_ifmsg(ifp); if (debug) addlog("\n"); } @@ -3109,12 +3128,13 @@ 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->dns_addrs, sizeof(sp->dns_addrs)); } HIDE void sppp_ipcp_scr(struct sppp *sp) { - char opt[6 /* compression */ + 6 /* address */]; + char opt[6 /* compression */ + 6 /* address */ + 12 /* dns addresses */]; u_int32_t ouraddr; int i = 0; @@ -3143,6 +3163,16 @@ sppp_ipcp_scr(struct sppp *sp) opt[i++] = ouraddr; } + opt[i++] = IPCP_OPT_PRIMDNS; + opt[i++] = 6; + bcopy(&sp->dns_addrs[0], &opt[i], sizeof sp->dns_addrs[0]); + i += sizeof sp->dns_addrs[0]; + + opt[i++] = IPCP_OPT_SECDNS; + opt[i++] = 6; + bcopy(&sp->dns_addrs[1], &opt[i], sizeof sp->dns_addrs[1]); + i += sizeof sp->dns_addrs[1]; + sp->confid[IDX_IPCP] = ++sp->pp_seq; sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, opt); } @@ -5227,6 +5257,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;