On Wed, Nov 10, 2021 at 07:35:26AM +0100, Bjorn Ketelaars wrote:
> On Mon 08/11/2021 11:52, Bjorn Ketelaars wrote:
> > Diff below does two things:
> > 1. add PPP IPCP extensions for name server addresses (rfc1877) to
> >    sppp(4)
> > 2. propose negotiated name servers from sppp(4) to resolvd(8) using
> >    RTM_PROPOSAL_STATIC route messages.
> 
> 
> Updated diff below, based on feedback from kn@ and claudio@:
> 
> - fix forgotten parentheses with `sizeof`
> - instead of using `u_int32_t` use `struct in_addr` for holding dns
>   addresses. Makes it more clear what the data is
> - decouple `IPCP_OPT` definitions from the bitmask values to
>   enable/disable an option. Makes the code look a bit better
> - use `memcpy`
> - fit code within 80 columns
> 
> While here add RFC to sppp(4)'s STANDARDS section.
> 
> @kn, is this still OK for you?
> 
> Other OK's?
> 
> 
> diff --git share/man/man4/sppp.4 share/man/man4/sppp.4
> index 5ca10285953..bccb41eec15 100644
> --- share/man/man4/sppp.4
> +++ share/man/man4/sppp.4
> @@ -230,6 +230,13 @@ take place.
>  .Re
>  .Pp
>  .Rs
> +.%A S. Cobb
> +.%D December 1995
> +.%R RFC 1877
> +.%T PPP Internet Protocol Control Protocol Extensions for Name Server 
> Addresses
> +.Re
> +.Pp
> +.Rs
>  .%A W. Simpson
>  .%D August 1996
>  .%R RFC 1994
> diff --git sys/net/if_sppp.h sys/net/if_sppp.h
> index ff559fcc369..5850a6da963 100644
> --- sys/net/if_sppp.h
> +++ sys/net/if_sppp.h
> @@ -132,6 +132,8 @@ struct sipcp {
>                                 * original one here, in network byte order */
>       u_int32_t req_hisaddr;  /* remote address requested (IPv4) */
>       u_int32_t req_myaddr;   /* local address requested (IPv4) */
> +#define IPCP_MAX_DNSSRV      2
> +     struct in_addr dns[IPCP_MAX_DNSSRV]; /* IPv4  DNS servers (RFC 1877) */
>  #ifdef INET6
>       struct in6_aliasreq req_ifid;   /* local ifid requested (IPv6) */
>  #endif
> diff --git sys/net/if_spppsubr.c sys/net/if_spppsubr.c
> index ac1dc9a709d..e460703c089 100644
> --- sys/net/if_spppsubr.c
> +++ sys/net/if_spppsubr.c
> @@ -132,6 +132,14 @@
>  #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 SPPP_IPCP_OPT_ADDRESSES              1       /* bitmask value */
> +#define SPPP_IPCP_OPT_COMPRESSION    2       /* bitmask value */
> +#define SPPP_IPCP_OPT_ADDRESS                3       /* bitmask value */
> +#define SPPP_IPCP_OPT_PRIMDNS                4       /* bitmask value */
> +#define SPPP_IPCP_OPT_SECDNS         5       /* bitmask value */

Instead of repeating the /* bitmask value */ just add a comment at the
top. Something like "bitmask value to enable or disable individual IPCP
options"

>  
>  #define IPV6CP_OPT_IFID              1       /* interface identifier */
>  #define IPV6CP_OPT_COMPRESSION       2       /* IPv6 compression protocol */
> @@ -338,6 +346,8 @@ void sppp_update_gw(struct ifnet *ifp);
>  void sppp_set_ip_addrs(void *);
>  void sppp_clear_ip_addrs(void *);
>  void sppp_set_phase(struct sppp *sp);
> +void sppp_update_dns(struct ifnet *ifp);
> +void sppp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt);
>  
>  /* our control protocol descriptors */
>  static const struct cp lcp = {
> @@ -701,6 +711,7 @@ sppp_attach(struct ifnet *ifp)
>  
>       sp->pp_if.if_type = IFT_PPP;
>       sp->pp_if.if_output = sppp_output;
> +     sp->pp_if.if_rtrequest = sppp_rtrequest;
>       ifq_set_maxlen(&sp->pp_if.if_snd, 50);
>       mq_init(&sp->pp_cpq, 50, IPL_NET);
>       sp->pp_loopcnt = 0;
> @@ -2512,13 +2523,19 @@ sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header 
> *h, int len)
>                        * Peer doesn't grok address option.  This is
>                        * bad.  XXX  Should we better give up here?
>                        */
> -                     sp->ipcp.opts &= ~(1 << IPCP_OPT_ADDRESS);
> +                     sp->ipcp.opts &= ~(1 << SPPP_IPCP_OPT_ADDRESS);
>                       break;
>  #ifdef notyet
>               case IPCP_OPT_COMPRESS:
> -                     sp->ipcp.opts &= ~(1 << IPCP_OPT_COMPRESS);
> +                     sp->ipcp.opts &= ~(1 << SPPP_IPCP_OPT_COMPRESS);
>                       break;
>  #endif
> +             case IPCP_OPT_PRIMDNS:
> +                     sp->ipcp.opts &= ~(1 << SPPP_IPCP_OPT_PRIMDNS);
> +                     break;
> +             case IPCP_OPT_SECDNS:
> +                     sp->ipcp.opts &= ~(1 << SPPP_IPCP_OPT_SECDNS);
> +                     break;
>               }
>       }
>       if (debug)
> @@ -2559,7 +2576,7 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header 
> *h, int len)
>                       if (len >= 6 && p[1] == 6) {
>                               wantaddr = p[2] << 24 | p[3] << 16 |
>                                       p[4] << 8 | p[5];
> -                             sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
> +                             sp->ipcp.opts |= (1 << SPPP_IPCP_OPT_ADDRESS);
>                               if (debug)
>                                       addlog("[wantaddr %s] ",
>                                              sppp_dotted_quad(wantaddr));
> @@ -2584,6 +2601,16 @@ sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header 
> *h, int len)
>                        */
>                       break;
>  #endif
> +             case IPCP_OPT_PRIMDNS:
> +                     if (len >= 6 && p[1] == 6)
> +                             memcpy(&sp->ipcp.dns[0].s_addr, p + 2,
> +                                 sizeof(sp->ipcp.dns[0].s_addr));
> +                     break;
> +             case IPCP_OPT_SECDNS:
> +                     if (len >= 6 && p[1] == 6)
> +                             memcpy(&sp->ipcp.dns[1].s_addr, p + 2,
> +                                 sizeof(sp->ipcp.dns[1].s_addr));
> +                     break;
>               }
>       }
>       if (debug)
> @@ -2612,6 +2639,7 @@ sppp_ipcp_tls(struct sppp *sp)
>           IPCP_MYADDR_DYN|IPCP_HISADDR_DYN);
>       sp->ipcp.req_myaddr = 0;
>       sp->ipcp.req_hisaddr = 0;
> +     memset(&sp->ipcp.dns, 0, sizeof(sp->ipcp.dns));
>  
>       sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0);
>       /*
> @@ -2634,7 +2662,7 @@ sppp_ipcp_tls(struct sppp *sp)
>                * negotiate my address.
>                */
>               sp->ipcp.flags |= IPCP_MYADDR_DYN;
> -             sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
> +             sp->ipcp.opts |= (1 << SPPP_IPCP_OPT_ADDRESS);
>       }
>       if (hisaddr >= 1 && hisaddr <= 255) {
>               /*
> @@ -2644,6 +2672,10 @@ sppp_ipcp_tls(struct sppp *sp)
>               sp->ipcp.flags |= IPCP_HISADDR_DYN;
>       }
>  
> +     /* negotiate name server addresses */
> +     sp->ipcp.opts |= (1 << SPPP_IPCP_OPT_PRIMDNS);
> +     sp->ipcp.opts |= (1 << SPPP_IPCP_OPT_SECDNS);
> +
>       /* indicate to LCP that it must stay alive */
>       sp->lcp.protos |= (1 << IDX_IPCP);
>  }
> @@ -2663,12 +2695,13 @@ sppp_ipcp_tlf(struct sppp *sp)
>  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;
> +     size_t sz;
>       int i = 0;
>  
>  #ifdef notyet
> -     if (sp->ipcp.opts & (1 << IPCP_OPT_COMPRESSION)) {
> +     if (sp->ipcp.opts & (1 << SPPP_IPCP_OPT_COMPRESSION)) {
>               opt[i++] = IPCP_OPT_COMPRESSION;
>               opt[i++] = 6;
>               opt[i++] = 0;   /* VJ header compression */
> @@ -2678,7 +2711,7 @@ sppp_ipcp_scr(struct sppp *sp)
>       }
>  #endif
>  
> -     if (sp->ipcp.opts & (1 << IPCP_OPT_ADDRESS)) {
> +     if (sp->ipcp.opts & (1 << SPPP_IPCP_OPT_ADDRESS)) {
>               if (sp->ipcp.flags & IPCP_MYADDR_SEEN)
>                       /* not sure if this can ever happen */
>                       ouraddr = sp->ipcp.req_myaddr;
> @@ -2692,6 +2725,22 @@ sppp_ipcp_scr(struct sppp *sp)
>               opt[i++] = ouraddr;
>       }
>  
> +     if (sp->ipcp.opts & (1 << SPPP_IPCP_OPT_PRIMDNS)) {
> +             opt[i++] = IPCP_OPT_PRIMDNS;
> +             opt[i++] = 6;
> +             sz = sizeof(sp->ipcp.dns[0].s_addr);
> +             memcpy(&opt[i], &sp->ipcp.dns[0].s_addr, sz);
> +             i += sz;

I would just use sizeof(sp->ipcp.dns[0]) and also put that sizeof in the
two places instead of using the local sz variable.

                memcpy(&opt[i], &sp->ipcp.dns[0].s_addr, 
                    sizeof(sp->ipcp.dns[0]));
                i += sizeof(sp->ipcp.dns[0]);

> +     }
> +
> +     if (sp->ipcp.opts & (1 << SPPP_IPCP_OPT_SECDNS)) {
> +             opt[i++] = IPCP_OPT_SECDNS;
> +             opt[i++] = 6;
> +             sz = sizeof(sp->ipcp.dns[1].s_addr);
> +             memcpy(&opt[i], &sp->ipcp.dns[1].s_addr, sz);
> +             i += sz;

Same as above.

> +     }
> +
>       sp->confid[IDX_IPCP] = ++sp->pp_seq;
>       sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, opt);
>  }
> @@ -4242,6 +4291,7 @@ sppp_set_ip_addrs(void *arg1)
>                       goto out;
>               }
>               sppp_update_gw(ifp);
> +             sppp_update_dns(ifp);
>       }
>  out:
>       NET_UNLOCK();
> @@ -4302,6 +4352,9 @@ sppp_clear_ip_addrs(void *arg1)
>                       goto out;
>               }
>               sppp_update_gw(ifp);
> +
> +             memset(sp->ipcp.dns, 0, sizeof(sp->ipcp.dns));
> +             sppp_update_dns(ifp);
>       }
>  out:
>       NET_UNLOCK();
> @@ -4721,6 +4774,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 "primdns";
> +     case IPCP_OPT_SECDNS:           return "secdns";
>       }
>       snprintf (buf, sizeof buf, "0x%x", opt);
>       return buf;
> @@ -4851,3 +4906,43 @@ sppp_set_phase(struct sppp *sp)
>               if_link_state_change(ifp);
>       }
>  }
> +
> +void
> +sppp_update_dns(struct ifnet *ifp)
> +{
> +     struct rt_addrinfo info;
> +     struct sockaddr_rtdns rtdns;
> +     struct sppp *sp = ifp->if_softc;
> +     size_t sz = 0;
> +     int i, flag = 0;
> +
> +     memset(&rtdns, 0, sizeof(rtdns));
> +     memset(&info, 0, sizeof(info));
> +
> +     for (i = 0; i < IPCP_MAX_DNSSRV; i++) {
> +             if (sp->ipcp.dns[i].s_addr == INADDR_ANY)
> +                     break;
> +             sz = sizeof(sp->ipcp.dns[i].s_addr);

Use sizeof(sp->ipcp.dns[0])

> +             memcpy(rtdns.sr_dns + i * sz, &sp->ipcp.dns[i].s_addr, sz);
> +             flag = RTF_UP;
> +     }
> +
> +     rtdns.sr_family = AF_INET;
> +     rtdns.sr_len = 2 + i * sz;
> +     info.rti_info[RTAX_DNS] = srtdnstosa(&rtdns);
> +
> +     rtm_proposal(ifp, &info, flag, RTP_PROPOSAL_STATIC);
> +}
> +
> +void
> +sppp_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
> +{
> +     if (req == RTM_PROPOSAL) {
> +             KERNEL_LOCK();
> +             sppp_update_dns(ifp);
> +             KERNEL_UNLOCK();
> +             return;
> +     }
> +
> +     p2p_rtrequest(ifp, req, rt);
> +}
> 

I can't really test this but apart from the above cleanups ok claudio@

-- 
:wq Claudio

Reply via email to