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;

Reply via email to