The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/if_pppoe.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: if_pppoe.c,v 1.93.4.1 2009/02/25 03:15:32 snj Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Martin Husemann <martin@NetBSD.org>.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.93.4.1 2009/02/25 03:15:32 snj Exp $");
   34 
   35 #include "pppoe.h"
   36 #include "bpfilter.h"
   37 #include "opt_pfil_hooks.h"
   38 #include "opt_pppoe.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/kernel.h>
   43 #include <sys/callout.h>
   44 #include <sys/malloc.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/socket.h>
   47 #include <sys/proc.h>
   48 #include <sys/ioctl.h>
   49 #include <sys/kauth.h>
   50 #include <sys/intr.h>
   51 #include <sys/socketvar.h>
   52 
   53 #include <net/if.h>
   54 #include <net/if_types.h>
   55 #include <net/if_ether.h>
   56 #include <net/if_sppp.h>
   57 #include <net/if_spppvar.h>
   58 #include <net/if_pppoe.h>
   59 
   60 #if NBPFILTER > 0
   61 #include <net/bpf.h>
   62 #endif
   63 
   64 
   65 #undef PPPOE_DEBUG              /* XXX - remove this or make it an option */
   66 /* #define PPPOE_DEBUG 1 */
   67 
   68 struct pppoehdr {
   69         uint8_t vertype;
   70         uint8_t code;
   71         uint16_t session;
   72         uint16_t plen;
   73 } __packed;
   74 
   75 struct pppoetag {
   76         uint16_t tag;
   77         uint16_t len;
   78 } __packed;
   79 
   80 #define PPPOE_HEADERLEN sizeof(struct pppoehdr)
   81 #define PPPOE_OVERHEAD  (PPPOE_HEADERLEN + 2)
   82 #define PPPOE_VERTYPE   0x11    /* VER=1, TYPE = 1 */
   83 
   84 #define PPPOE_TAG_EOL           0x0000          /* end of list */
   85 #define PPPOE_TAG_SNAME         0x0101          /* service name */
   86 #define PPPOE_TAG_ACNAME        0x0102          /* access concentrator name */
   87 #define PPPOE_TAG_HUNIQUE       0x0103          /* host unique */
   88 #define PPPOE_TAG_ACCOOKIE      0x0104          /* AC cookie */
   89 #define PPPOE_TAG_VENDOR        0x0105          /* vendor specific */
   90 #define PPPOE_TAG_RELAYSID      0x0110          /* relay session id */
   91 #define PPPOE_TAG_SNAME_ERR     0x0201          /* service name error */
   92 #define PPPOE_TAG_ACSYS_ERR     0x0202          /* AC system error */
   93 #define PPPOE_TAG_GENERIC_ERR   0x0203          /* gerneric error */
   94 
   95 #define PPPOE_CODE_PADI         0x09            /* Active Discovery Initiation */
   96 #define PPPOE_CODE_PADO         0x07            /* Active Discovery Offer */
   97 #define PPPOE_CODE_PADR         0x19            /* Active Discovery Request */
   98 #define PPPOE_CODE_PADS         0x65            /* Active Discovery Session confirmation */
   99 #define PPPOE_CODE_PADT         0xA7            /* Active Discovery Terminate */
  100 
  101 /* two byte PPP protocol discriminator, then IP data */
  102 #define PPPOE_MAXMTU    (ETHERMTU - PPPOE_OVERHEAD)
  103 
  104 /* Add a 16 bit unsigned value to a buffer pointed to by PTR */
  105 #define PPPOE_ADD_16(PTR, VAL)                  \
  106                 *(PTR)++ = (VAL) / 256;         \
  107                 *(PTR)++ = (VAL) % 256
  108 
  109 /* Add a complete PPPoE header to the buffer pointed to by PTR */
  110 #define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN)  \
  111                 *(PTR)++ = PPPOE_VERTYPE;       \
  112                 *(PTR)++ = (CODE);              \
  113                 PPPOE_ADD_16(PTR, SESS);        \
  114                 PPPOE_ADD_16(PTR, LEN)
  115 
  116 #define PPPOE_DISC_TIMEOUT      (hz*5)  /* base for quick timeout calculation */
  117 #define PPPOE_SLOW_RETRY        (hz*60) /* persistent retry interval */
  118 #define PPPOE_RECON_FAST        (hz*15) /* first retry after auth failure */
  119 #define PPPOE_RECON_IMMEDIATE   (hz/10) /* "no delay" reconnect */
  120 #define PPPOE_DISC_MAXPADI      4       /* retry PADI four times (quickly) */
  121 #define PPPOE_DISC_MAXPADR      2       /* retry PADR twice */
  122 
  123 #ifdef PPPOE_SERVER
  124 /* from if_spppsubr.c */
  125 #define IFF_PASSIVE     IFF_LINK0       /* wait passively for connection */
  126 #endif
  127 
  128 struct pppoe_softc {
  129         struct sppp sc_sppp;            /* contains a struct ifnet as first element */
  130         LIST_ENTRY(pppoe_softc) sc_list;
  131         struct ifnet *sc_eth_if;        /* ethernet interface we are using */
  132 
  133         int sc_state;                   /* discovery phase or session connected */
  134         struct ether_addr sc_dest;      /* hardware address of concentrator */
  135         uint16_t sc_session;            /* PPPoE session id */
  136 
  137         char *sc_service_name;          /* if != NULL: requested name of service */
  138         char *sc_concentrator_name;     /* if != NULL: requested concentrator id */
  139         uint8_t *sc_ac_cookie;          /* content of AC cookie we must echo back */
  140         size_t sc_ac_cookie_len;        /* length of cookie data */
  141         uint8_t *sc_relay_sid;          /* content of relay SID we must echo back */
  142         size_t sc_relay_sid_len;        /* length of relay SID data */
  143 #ifdef PPPOE_SERVER
  144         uint8_t *sc_hunique;            /* content of host unique we must echo back */
  145         size_t sc_hunique_len;          /* length of host unique */
  146 #endif
  147         callout_t sc_timeout;   /* timeout while not in session state */
  148         int sc_padi_retried;            /* number of PADI retries already done */
  149         int sc_padr_retried;            /* number of PADR retries already done */
  150 };
  151 
  152 /* incoming traffic will be queued here */
  153 struct ifqueue ppoediscinq = { .ifq_maxlen = IFQ_MAXLEN };
  154 struct ifqueue ppoeinq = { .ifq_maxlen = IFQ_MAXLEN };
  155 
  156 void *pppoe_softintr = NULL;
  157 static void pppoe_softintr_handler(void *);
  158 
  159 extern int sppp_ioctl(struct ifnet *, unsigned long, void *);
  160 
  161 /* input routines */
  162 static void pppoe_input(void);
  163 static void pppoe_disc_input(struct mbuf *);
  164 static void pppoe_dispatch_disc_pkt(struct mbuf *, int);
  165 static void pppoe_data_input(struct mbuf *);
  166 
  167 /* management routines */
  168 void pppoeattach(int);
  169 static int pppoe_connect(struct pppoe_softc *);
  170 static int pppoe_disconnect(struct pppoe_softc *);
  171 static void pppoe_abort_connect(struct pppoe_softc *);
  172 static int pppoe_ioctl(struct ifnet *, unsigned long, void *);
  173 static void pppoe_tls(struct sppp *);
  174 static void pppoe_tlf(struct sppp *);
  175 static void pppoe_start(struct ifnet *);
  176 static void pppoe_clear_softc(struct pppoe_softc *, const char *);
  177 
  178 /* internal timeout handling */
  179 static void pppoe_timeout(void *);
  180 
  181 /* sending actual protocol controll packets */
  182 static int pppoe_send_padi(struct pppoe_softc *);
  183 static int pppoe_send_padr(struct pppoe_softc *);
  184 #ifdef PPPOE_SERVER
  185 static int pppoe_send_pado(struct pppoe_softc *);
  186 static int pppoe_send_pads(struct pppoe_softc *);
  187 #endif
  188 static int pppoe_send_padt(struct ifnet *, u_int, const uint8_t *);
  189 
  190 /* raw output */
  191 static int pppoe_output(struct pppoe_softc *, struct mbuf *);
  192 
  193 /* internal helper functions */
  194 static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct ifnet *);
  195 static struct pppoe_softc * pppoe_find_softc_by_hunique(uint8_t *, size_t, struct ifnet *);
  196 static struct mbuf *pppoe_get_mbuf(size_t len);
  197 
  198 #ifdef PFIL_HOOKS
  199 static int pppoe_ifattach_hook(void *, struct mbuf **, struct ifnet *, int);
  200 #endif
  201 
  202 static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
  203 
  204 static int      pppoe_clone_create(struct if_clone *, int);
  205 static int      pppoe_clone_destroy(struct ifnet *);
  206 
  207 static struct if_clone pppoe_cloner =
  208     IF_CLONE_INITIALIZER("pppoe", pppoe_clone_create, pppoe_clone_destroy);
  209 
  210 /* ARGSUSED */
  211 void
  212 pppoeattach(int count)
  213 {
  214         LIST_INIT(&pppoe_softc_list);
  215         if_clone_attach(&pppoe_cloner);
  216 
  217         pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler, NULL);
  218 }
  219 
  220 static int
  221 pppoe_clone_create(struct if_clone *ifc, int unit)
  222 {
  223         struct pppoe_softc *sc;
  224 
  225         sc = malloc(sizeof(struct pppoe_softc), M_DEVBUF, M_WAITOK|M_ZERO);
  226 
  227         if_initname(&sc->sc_sppp.pp_if, "pppoe", unit);
  228         sc->sc_sppp.pp_if.if_softc = sc;
  229         sc->sc_sppp.pp_if.if_mtu = PPPOE_MAXMTU;
  230         sc->sc_sppp.pp_if.if_flags = IFF_SIMPLEX|IFF_POINTOPOINT|IFF_MULTICAST;
  231         sc->sc_sppp.pp_if.if_type = IFT_PPP;
  232         sc->sc_sppp.pp_if.if_hdrlen = sizeof(struct ether_header) + PPPOE_HEADERLEN;
  233         sc->sc_sppp.pp_if.if_dlt = DLT_PPP_ETHER;
  234         sc->sc_sppp.pp_flags |= PP_KEEPALIVE |  /* use LCP keepalive */
  235                                 PP_NOFRAMING;   /* no serial encapsulation */
  236         sc->sc_sppp.pp_if.if_ioctl = pppoe_ioctl;
  237         IFQ_SET_MAXLEN(&sc->sc_sppp.pp_if.if_snd, IFQ_MAXLEN);
  238         IFQ_SET_READY(&sc->sc_sppp.pp_if.if_snd);
  239 
  240         /* changed to real address later */
  241         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
  242 
  243         callout_init(&sc->sc_timeout, 0);
  244 
  245         sc->sc_sppp.pp_if.if_start = pppoe_start;
  246         sc->sc_sppp.pp_tls = pppoe_tls;
  247         sc->sc_sppp.pp_tlf = pppoe_tlf;
  248         sc->sc_sppp.pp_framebytes = PPPOE_HEADERLEN;    /* framing added to ppp packets */
  249 
  250         if_attach(&sc->sc_sppp.pp_if);
  251         sppp_attach(&sc->sc_sppp.pp_if);
  252 
  253 #if NBPFILTER > 0
  254         bpfattach(&sc->sc_sppp.pp_if, DLT_PPP_ETHER, 0);
  255 #endif
  256 #ifdef PFIL_HOOKS
  257         if (LIST_EMPTY(&pppoe_softc_list))
  258                 pfil_add_hook(pppoe_ifattach_hook, NULL,
  259                     PFIL_IFNET|PFIL_WAITOK, &if_pfil);
  260 #endif
  261         LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
  262         return 0;
  263 }
  264 
  265 static int
  266 pppoe_clone_destroy(struct ifnet *ifp)
  267 {
  268         struct pppoe_softc * sc = ifp->if_softc;
  269 
  270         callout_stop(&sc->sc_timeout);
  271         LIST_REMOVE(sc, sc_list);
  272 #ifdef PFIL_HOOKS
  273         if (LIST_EMPTY(&pppoe_softc_list))
  274                 pfil_remove_hook(pppoe_ifattach_hook, NULL,
  275                     PFIL_IFNET|PFIL_WAITOK, &if_pfil);
  276 #endif
  277 #if NBPFILTER > 0
  278         bpfdetach(ifp);
  279 #endif
  280         sppp_detach(&sc->sc_sppp.pp_if);
  281         if_detach(ifp);
  282         if (sc->sc_concentrator_name)
  283                 free(sc->sc_concentrator_name, M_DEVBUF);
  284         if (sc->sc_service_name)
  285                 free(sc->sc_service_name, M_DEVBUF);
  286         if (sc->sc_ac_cookie)
  287                 free(sc->sc_ac_cookie, M_DEVBUF);
  288         if (sc->sc_relay_sid)
  289                 free(sc->sc_relay_sid, M_DEVBUF);
  290         callout_destroy(&sc->sc_timeout);
  291         free(sc, M_DEVBUF);
  292 
  293         return (0);
  294 }
  295 
  296 /*
  297  * Find the interface handling the specified session.
  298  * Note: O(number of sessions open), this is a client-side only, mean
  299  * and lean implementation, so number of open sessions typically should
  300  * be 1.
  301  */
  302 static struct pppoe_softc *
  303 pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif)
  304 {
  305         struct pppoe_softc *sc;
  306 
  307         if (session == 0)
  308                 return NULL;
  309 
  310         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  311                 if (sc->sc_state == PPPOE_STATE_SESSION
  312                     && sc->sc_session == session
  313                     && sc->sc_eth_if == rcvif)
  314                         return sc;
  315         }
  316         return NULL;
  317 }
  318 
  319 /* Check host unique token passed and return appropriate softc pointer,
  320  * or NULL if token is bogus. */
  321 static struct pppoe_softc *
  322 pppoe_find_softc_by_hunique(uint8_t *token, size_t len, struct ifnet *rcvif)
  323 {
  324         struct pppoe_softc *sc, *t;
  325 
  326         if (LIST_EMPTY(&pppoe_softc_list))
  327                 return NULL;
  328 
  329         if (len != sizeof sc)
  330                 return NULL;
  331         memcpy(&t, token, len);
  332 
  333         LIST_FOREACH(sc, &pppoe_softc_list, sc_list)
  334                 if (sc == t) break;
  335 
  336         if (sc == NULL) {
  337 #ifdef PPPOE_DEBUG
  338                 printf("pppoe: alien host unique tag, no session found\n");
  339 #endif
  340                 return NULL;
  341         }
  342 
  343         /* should be safe to access *sc now */
  344         if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) {
  345                 printf("%s: host unique tag found, but it belongs to a connection in state %d\n",
  346                         sc->sc_sppp.pp_if.if_xname, sc->sc_state);
  347                 return NULL;
  348         }
  349         if (sc->sc_eth_if != rcvif) {
  350                 printf("%s: wrong interface, not accepting host unique\n",
  351                         sc->sc_sppp.pp_if.if_xname);
  352                 return NULL;
  353         }
  354         return sc;
  355 }
  356 
  357 static void
  358 pppoe_softintr_handler(void *dummy)
  359 {
  360         /* called at splsoftnet() */
  361         mutex_enter(softnet_lock);
  362         pppoe_input();
  363         mutex_exit(softnet_lock);
  364 }
  365 
  366 /* called at appropriate protection level */
  367 static void
  368 pppoe_input(void)
  369 {
  370         struct mbuf *m;
  371         int s, disc_done, data_done;
  372 
  373         do {
  374                 disc_done = 0;
  375                 data_done = 0;
  376                 for (;;) {
  377                         s = splnet();
  378                         IF_DEQUEUE(&ppoediscinq, m);
  379                         splx(s);
  380                         if (m == NULL) break;
  381                         disc_done = 1;
  382                         pppoe_disc_input(m);
  383                 }
  384 
  385                 for (;;) {
  386                         s = splnet();
  387                         IF_DEQUEUE(&ppoeinq, m);
  388                         splx(s);
  389                         if (m == NULL) break;
  390                         data_done = 1;
  391                         pppoe_data_input(m);
  392                 }
  393         } while (disc_done || data_done);
  394 }
  395 
  396 /* analyze and handle a single received packet while not in session state */
  397 static void
  398 pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
  399 {
  400         uint16_t tag, len;
  401         uint16_t session, plen;
  402         struct pppoe_softc *sc;
  403         const char *err_msg, *devname;
  404         char *error;
  405         uint8_t *ac_cookie;
  406         size_t ac_cookie_len;
  407         uint8_t *relay_sid;
  408         size_t relay_sid_len;
  409 #ifdef PPPOE_SERVER
  410         uint8_t *hunique;
  411         size_t hunique_len;
  412 #endif
  413         struct pppoehdr *ph;
  414         struct pppoetag *pt;
  415         struct mbuf *n;
  416         int noff, err, errortag;
  417         struct ether_header *eh;
  418 
  419         devname = "pppoe";      /* as long as we don't know which instance */
  420         err_msg = NULL;
  421         errortag = 0;
  422         if (m->m_len < sizeof(*eh)) {
  423                 m = m_pullup(m, sizeof(*eh));
  424                 if (!m)
  425                         goto done;
  426         }
  427         eh = mtod(m, struct ether_header *);
  428         off += sizeof(*eh);
  429 
  430         ac_cookie = NULL;
  431         ac_cookie_len = 0;
  432         relay_sid = NULL;
  433         relay_sid_len = 0;
  434 #ifdef PPPOE_SERVER
  435         hunique = NULL;
  436         hunique_len = 0;
  437 #endif
  438         session = 0;
  439         if (m->m_pkthdr.len - off <= PPPOE_HEADERLEN) {
  440                 printf("pppoe: packet too short: %d\n", m->m_pkthdr.len);
  441                 goto done;
  442         }
  443 
  444         n = m_pulldown(m, off, sizeof(*ph), &noff);
  445         if (!n) {
  446                 printf("pppoe: could not get PPPoE header\n");
  447                 m = NULL;
  448                 goto done;
  449         }
  450         ph = (struct pppoehdr *)(mtod(n, char *) + noff);
  451         if (ph->vertype != PPPOE_VERTYPE) {
  452                 printf("pppoe: unknown version/type packet: 0x%x\n",
  453                     ph->vertype);
  454                 goto done;
  455         }
  456         session = ntohs(ph->session);
  457         plen = ntohs(ph->plen);
  458         off += sizeof(*ph);
  459 
  460         if (plen + off > m->m_pkthdr.len) {
  461                 printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n",
  462                     m->m_pkthdr.len - off, plen);
  463                 goto done;
  464         }
  465         m_adj(m, off + plen - m->m_pkthdr.len); /* ignore trailing garbage */
  466         tag = 0;
  467         len = 0;
  468         sc = NULL;
  469         while (off + sizeof(*pt) <= m->m_pkthdr.len) {
  470                 n = m_pulldown(m, off, sizeof(*pt), &noff);
  471                 if (!n) {
  472                         printf("%s: parse error\n", devname);
  473                         m = NULL;
  474                         goto done;
  475                 }
  476                 pt = (struct pppoetag *)(mtod(n, char *) + noff);
  477                 tag = ntohs(pt->tag);
  478                 len = ntohs(pt->len);
  479                 if (off + len + sizeof(*pt) > m->m_pkthdr.len) {
  480                         printf("pppoe: tag 0x%x len 0x%x is too long\n",
  481                             tag, len);
  482                         goto done;
  483                 }
  484                 switch (tag) {
  485                 case PPPOE_TAG_EOL:
  486                         goto breakbreak;
  487                 case PPPOE_TAG_SNAME:
  488                         break;  /* ignored */
  489                 case PPPOE_TAG_ACNAME:
  490                         error = NULL;
  491                         if (sc != NULL && len > 0) {
  492                                 error = malloc(len+1, M_TEMP, M_NOWAIT);
  493                                 if (error) {
  494                                         n = m_pulldown(m, off + sizeof(*pt),
  495                                             len, &noff);
  496                                         if (n) {
  497                                                 strncpy(error,
  498                                                     mtod(n, char*) + noff,
  499                                                     len);
  500                                                 error[len] = '\0';
  501                                         }
  502                                         printf("%s: connected to %s\n",
  503                                             devname, error);
  504                                         free(error, M_TEMP);
  505                                 }
  506                         }
  507                         break;  /* ignored */
  508                 case PPPOE_TAG_HUNIQUE:
  509                         if (sc != NULL)
  510                                 break;
  511                         n = m_pulldown(m, off + sizeof(*pt), len, &noff);
  512                         if (!n) {
  513                                 m = NULL;
  514                                 err_msg = "TAG HUNIQUE ERROR";
  515                                 break;
  516                         }
  517 #ifdef PPPOE_SERVER
  518                         hunique = mtod(n, uint8_t *) + noff;
  519                         hunique_len = len;
  520 #endif
  521                         sc = pppoe_find_softc_by_hunique(mtod(n, char *) + noff,
  522                             len, m->m_pkthdr.rcvif);
  523                         if (sc != NULL)
  524                                 devname = sc->sc_sppp.pp_if.if_xname;
  525                         break;
  526                 case PPPOE_TAG_ACCOOKIE:
  527                         if (ac_cookie == NULL) {
  528                                 n = m_pulldown(m, off + sizeof(*pt), len,
  529                                     &noff);
  530                                 if (!n) {
  531                                         err_msg = "TAG ACCOOKIE ERROR";
  532                                         m = NULL;
  533                                         break;
  534                                 }
  535                                 ac_cookie = mtod(n, char *) + noff;
  536                                 ac_cookie_len = len;
  537                         }
  538                         break;
  539                 case PPPOE_TAG_RELAYSID:
  540                         if (relay_sid == NULL) {
  541                                 n = m_pulldown(m, off + sizeof(*pt), len,
  542                                     &noff);
  543                                 if (!n) {
  544                                         err_msg = "TAG RELAYSID ERROR";
  545                                         m = NULL;
  546                                         break;
  547                                 }
  548                                 relay_sid = mtod(n, char *) + noff;
  549                                 relay_sid_len = len;
  550                         }
  551                         break;
  552                 case PPPOE_TAG_SNAME_ERR:
  553                         err_msg = "SERVICE NAME ERROR";
  554                         errortag = 1;
  555                         break;
  556                 case PPPOE_TAG_ACSYS_ERR:
  557                         err_msg = "AC SYSTEM ERROR";
  558                         errortag = 1;
  559                         break;
  560                 case PPPOE_TAG_GENERIC_ERR:
  561                         err_msg = "GENERIC ERROR";
  562                         errortag = 1;
  563                         break;
  564                 }
  565                 if (err_msg) {
  566                         error = NULL;
  567                         if (errortag && len) {
  568                                 error = malloc(len+1, M_TEMP, M_NOWAIT);
  569                                 n = m_pulldown(m, off + sizeof(*pt), len,
  570                                     &noff);
  571                                 if (n && error) {
  572                                         strncpy(error, 
  573                                             mtod(n, char *) + noff, len);
  574                                         error[len] = '\0';
  575                                 }
  576                         }
  577                         if (error) {
  578                                 printf("%s: %s: %s\n", devname,
  579                                     err_msg, error);
  580                                 free(error, M_TEMP);
  581                         } else
  582                                 printf("%s: %s\n", devname, err_msg);
  583                         if (errortag || m == NULL)
  584                                 goto done;
  585                 }
  586                 off += sizeof(*pt) + len;
  587         }
  588 breakbreak:;
  589         switch (ph->code) {
  590         case PPPOE_CODE_PADI:
  591 #ifdef PPPOE_SERVER
  592                 /*
  593                  * got service name, concentrator name, and/or host unique.
  594                  * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP.
  595                  */
  596                 if (LIST_EMPTY(&pppoe_softc_list))
  597                         goto done;
  598                 LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
  599                         if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP))
  600                                 continue;
  601                         if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
  602                                 continue;
  603                         if (sc->sc_state == PPPOE_STATE_INITIAL)
  604                                 break;
  605                 }
  606                 if (sc == NULL) {
  607 /*                      printf("pppoe: free passive interface is not found\n");*/
  608                         goto done;
  609                 }
  610                 if (hunique) {
  611                         if (sc->sc_hunique)
  612                                 free(sc->sc_hunique, M_DEVBUF);
  613                         sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
  614                             M_DONTWAIT);
  615                         if (sc->sc_hunique == NULL)
  616                                 goto done;
  617                         sc->sc_hunique_len = hunique_len;
  618                         memcpy(sc->sc_hunique, hunique, hunique_len);
  619                 }
  620                 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
  621                 sc->sc_state = PPPOE_STATE_PADO_SENT;
  622                 pppoe_send_pado(sc);
  623                 break;
  624 #endif /* PPPOE_SERVER */
  625         case PPPOE_CODE_PADR:
  626 #ifdef PPPOE_SERVER
  627                 /*
  628                  * get sc from ac_cookie if IFF_PASSIVE
  629                  */
  630                 if (ac_cookie == NULL) {
  631                         /* be quiet if there is not a single pppoe instance */
  632                         printf("pppoe: received PADR but not includes ac_cookie\n");
  633                         goto done;
  634                 }
  635                 sc = pppoe_find_softc_by_hunique(ac_cookie,
  636                                                  ac_cookie_len,
  637                                                  m->m_pkthdr.rcvif);
  638                 if (sc == NULL) {
  639                         /* be quiet if there is not a single pppoe instance */
  640                         if (!LIST_EMPTY(&pppoe_softc_list))
  641                                 printf("pppoe: received PADR but could not find request for it\n");
  642                         goto done;
  643                 }
  644                 if (sc->sc_state != PPPOE_STATE_PADO_SENT) {
  645                         printf("%s: received unexpected PADR\n",
  646                             sc->sc_sppp.pp_if.if_xname);
  647                         goto done;
  648                 }
  649                 if (hunique) {
  650                         if (sc->sc_hunique)
  651                                 free(sc->sc_hunique, M_DEVBUF);
  652                         sc->sc_hunique = malloc(hunique_len, M_DEVBUF,
  653                             M_DONTWAIT);
  654                         if (sc->sc_hunique == NULL)
  655                                 goto done;
  656                         sc->sc_hunique_len = hunique_len;
  657                         memcpy(sc->sc_hunique, hunique, hunique_len);
  658                 }
  659                 pppoe_send_pads(sc);
  660                 sc->sc_state = PPPOE_STATE_SESSION;
  661                 sc->sc_sppp.pp_up(&sc->sc_sppp);
  662                 break;
  663 #else
  664                 /* ignore, we are no access concentrator */
  665                 goto done;
  666 #endif /* PPPOE_SERVER */
  667         case PPPOE_CODE_PADO:
  668                 if (sc == NULL) {
  669                         /* be quiet if there is not a single pppoe instance */
  670                         if (!LIST_EMPTY(&pppoe_softc_list))
  671                                 printf("pppoe: received PADO but could not find request for it\n");
  672                         goto done;
  673                 }
  674                 if (sc->sc_state != PPPOE_STATE_PADI_SENT) {
  675                         printf("%s: received unexpected PADO\n",
  676                             sc->sc_sppp.pp_if.if_xname);
  677                         goto done;
  678                 }
  679                 if (ac_cookie) {
  680                         if (sc->sc_ac_cookie)
  681                                 free(sc->sc_ac_cookie, M_DEVBUF);
  682                         sc->sc_ac_cookie = malloc(ac_cookie_len, M_DEVBUF,
  683                             M_DONTWAIT);
  684                         if (sc->sc_ac_cookie == NULL) {
  685                                 printf("%s: FATAL: could not allocate memory "
  686                                     "for AC cookie\n",
  687                                     sc->sc_sppp.pp_if.if_xname);
  688                                 goto done;
  689                         }
  690                         sc->sc_ac_cookie_len = ac_cookie_len;
  691                         memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
  692                 }
  693                 if (relay_sid) {
  694                         if (sc->sc_relay_sid)
  695                                 free(sc->sc_relay_sid, M_DEVBUF);
  696                         sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF,
  697                             M_DONTWAIT);
  698                         if (sc->sc_relay_sid == NULL) {
  699                                 printf("%s: FATAL: could not allocate memory "
  700                                     "for relay SID\n",
  701                                     sc->sc_sppp.pp_if.if_xname);
  702                                 goto done;
  703                         }
  704                         sc->sc_relay_sid_len = relay_sid_len;
  705                         memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len);
  706                 }
  707                 memcpy(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest);
  708                 callout_stop(&sc->sc_timeout);
  709                 sc->sc_padr_retried = 0;
  710                 sc->sc_state = PPPOE_STATE_PADR_SENT;
  711                 if ((err = pppoe_send_padr(sc)) != 0) {
  712                         if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
  713                                 printf("%s: failed to send PADR, "
  714                                     "error=%d\n", sc->sc_sppp.pp_if.if_xname,
  715                                     err);
  716                 }
  717                 callout_reset(&sc->sc_timeout,
  718                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
  719                     pppoe_timeout, sc);
  720                 break;
  721         case PPPOE_CODE_PADS:
  722                 if (sc == NULL)
  723                         goto done;
  724                 sc->sc_session = session;
  725                 callout_stop(&sc->sc_timeout);
  726                 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
  727                         printf("%s: session 0x%x connected\n",
  728                             sc->sc_sppp.pp_if.if_xname, session);
  729                 sc->sc_state = PPPOE_STATE_SESSION;
  730                 sc->sc_sppp.pp_up(&sc->sc_sppp);        /* notify upper layers */
  731                 break;
  732         case PPPOE_CODE_PADT:
  733                 if (sc == NULL)
  734                         goto done;
  735                 pppoe_clear_softc(sc, "received PADT");
  736                 break;
  737         default:
  738                 printf("%s: unknown code (0x%04x) session = 0x%04x\n",
  739                     sc? sc->sc_sppp.pp_if.if_xname : "pppoe",
  740                     ph->code, session);
  741                 break;
  742         }
  743 
  744 done:
  745         if (m)
  746                 m_freem(m);
  747         return;
  748 }
  749 
  750 static void
  751 pppoe_disc_input(struct mbuf *m)
  752 {
  753 
  754         /* avoid error messages if there is not a single pppoe instance */
  755         if (!LIST_EMPTY(&pppoe_softc_list)) {
  756                 KASSERT(m->m_flags & M_PKTHDR);
  757                 pppoe_dispatch_disc_pkt(m, 0);
  758         } else
  759                 m_freem(m);
  760 }
  761 
  762 static void
  763 pppoe_data_input(struct mbuf *m)
  764 {
  765         uint16_t session, plen;
  766         struct pppoe_softc *sc;
  767         struct pppoehdr *ph;
  768 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
  769         uint8_t shost[ETHER_ADDR_LEN];
  770 #endif
  771 
  772         KASSERT(m->m_flags & M_PKTHDR);
  773 
  774 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
  775         memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN);
  776 #endif
  777         m_adj(m, sizeof(struct ether_header));
  778         if (m->m_pkthdr.len <= PPPOE_HEADERLEN) {
  779                 printf("pppoe (data): dropping too short packet: %d bytes\n",
  780                     m->m_pkthdr.len);
  781                 goto drop;
  782         }
  783 
  784         if (m->m_len < sizeof(*ph)) {
  785                 m = m_pullup(m, sizeof(*ph));
  786                 if (!m) {
  787                         printf("pppoe: could not get PPPoE header\n");
  788                         return;
  789                 }
  790         }
  791         ph = mtod(m, struct pppoehdr *);
  792 
  793         if (ph->vertype != PPPOE_VERTYPE) {
  794                 printf("pppoe (data): unknown version/type packet: 0x%x\n",
  795                     ph->vertype);
  796                 goto drop;
  797         }
  798         if (ph->code != 0)
  799                 goto drop;
  800 
  801         session = ntohs(ph->session);
  802         sc = pppoe_find_softc_by_session(session, m->m_pkthdr.rcvif);
  803         if (sc == NULL) {
  804 #ifdef PPPOE_TERM_UNKNOWN_SESSIONS
  805                 printf("pppoe: input for unknown session 0x%x, sending PADT\n",
  806                     session);
  807                 pppoe_send_padt(m->m_pkthdr.rcvif, session, shost);
  808 #endif
  809                 goto drop;
  810         }
  811 
  812         plen = ntohs(ph->plen);
  813 
  814 #if NBPFILTER > 0
  815         if(sc->sc_sppp.pp_if.if_bpf)
  816                 bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
  817 #endif
  818 
  819         m_adj(m, PPPOE_HEADERLEN);
  820 
  821 #ifdef PPPOE_DEBUG
  822         {
  823                 struct mbuf *p;
  824 
  825                 printf("%s: pkthdr.len=%d, pppoe.len=%d",
  826                         sc->sc_sppp.pp_if.if_xname,
  827                         m->m_pkthdr.len, plen);
  828                 p = m;
  829                 while (p) {
  830                         printf(" l=%d", p->m_len);
  831                         p = p->m_next;
  832                 }
  833                 printf("\n");
  834         }
  835 #endif
  836 
  837         if (m->m_pkthdr.len < plen)
  838                 goto drop;
  839 
  840         /* fix incoming interface pointer (not the raw ethernet interface anymore) */
  841         m->m_pkthdr.rcvif = &sc->sc_sppp.pp_if;
  842 
  843         /* pass packet up and account for it */
  844         sc->sc_sppp.pp_if.if_ipackets++;
  845         sppp_input(&sc->sc_sppp.pp_if, m);
  846         return;
  847 
  848 drop:
  849         m_freem(m);
  850 }
  851 
  852 static int
  853 pppoe_output(struct pppoe_softc *sc, struct mbuf *m)
  854 {
  855         struct sockaddr dst;
  856         struct ether_header *eh;
  857         uint16_t etype;
  858 
  859         if (sc->sc_eth_if == NULL) {
  860                 m_freem(m);
  861                 return EIO;
  862         }
  863 
  864         memset(&dst, 0, sizeof dst);
  865         dst.sa_family = AF_UNSPEC;
  866         eh = (struct ether_header*)&dst.sa_data;
  867         etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHERTYPE_PPPOE : ETHERTYPE_PPPOEDISC;
  868         eh->ether_type = htons(etype);
  869         memcpy(&eh->ether_dhost, &sc->sc_dest, sizeof sc->sc_dest);
  870 
  871 #ifdef PPPOE_DEBUG
  872         printf("%s (%x) state=%d, session=0x%x output -> %s, len=%d\n",
  873             sc->sc_sppp.pp_if.if_xname, etype,
  874             sc->sc_state, sc->sc_session,
  875             ether_sprintf((const unsigned char *)&sc->sc_dest), m->m_pkthdr.len);
  876 #endif
  877 
  878         m->m_flags &= ~(M_BCAST|M_MCAST);
  879         sc->sc_sppp.pp_if.if_opackets++;
  880         return sc->sc_eth_if->if_output(sc->sc_eth_if, m, &dst, NULL);
  881 }
  882 
  883 static int
  884 pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
  885 {
  886         struct lwp *l = curlwp; /* XXX */
  887         struct pppoe_softc *sc = (struct pppoe_softc*)ifp;
  888         struct ifreq *ifr = data;
  889         int error = 0;
  890 
  891         switch (cmd) {
  892         case PPPOESETPARMS:
  893         {
  894                 struct pppoediscparms *parms = (struct pppoediscparms*)data;
  895                 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE,
  896                     KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
  897                     NULL) != 0)
  898                         return (EPERM);
  899                 if (parms->eth_ifname[0] != 0) {
  900                         struct ifnet    *eth_if;
  901 
  902                         eth_if = ifunit(parms->eth_ifname);
  903                         if (eth_if == NULL || eth_if->if_dlt != DLT_EN10MB) {
  904                                 sc->sc_eth_if = NULL;
  905                                 return ENXIO;
  906                         }
  907 
  908                         if (sc->sc_sppp.pp_if.if_mtu >
  909                             eth_if->if_mtu - PPPOE_OVERHEAD) {
  910                                 sc->sc_sppp.pp_if.if_mtu = eth_if->if_mtu -
  911                                     PPPOE_OVERHEAD;
  912                         }
  913                         sc->sc_eth_if = eth_if;
  914                 }
  915                 if (parms->ac_name != NULL) {
  916                         size_t s;
  917                         char *b = malloc(parms->ac_name_len + 1, M_DEVBUF,
  918                             M_WAITOK);
  919                         if (b == NULL)
  920                                 return ENOMEM;
  921                         error = copyinstr(parms->ac_name, b,
  922                             parms->ac_name_len+1, &s);
  923                         if (error != 0) {
  924                                 free(b, M_DEVBUF);
  925                                 return error;
  926                         }
  927                         if (s != parms->ac_name_len+1) {
  928                                 free(b, M_DEVBUF);
  929                                 return EINVAL;
  930                         }
  931                         if (sc->sc_concentrator_name)
  932                                 free(sc->sc_concentrator_name, M_DEVBUF);
  933                         sc->sc_concentrator_name = b;
  934                 }
  935                 if (parms->service_name != NULL) {
  936                         size_t s;
  937                         char *b = malloc(parms->service_name_len + 1, M_DEVBUF,
  938                             M_WAITOK);
  939                         if (b == NULL)
  940                                 return ENOMEM;
  941                         error = copyinstr(parms->service_name, b,
  942                             parms->service_name_len+1, &s);
  943                         if (error != 0) {
  944                                 free(b, M_DEVBUF);
  945                                 return error;
  946                         }
  947                         if (s != parms->service_name_len+1) {
  948                                 free(b, M_DEVBUF);
  949                                 return EINVAL;
  950                         }
  951                         if (sc->sc_service_name)
  952                                 free(sc->sc_service_name, M_DEVBUF);
  953                         sc->sc_service_name = b;
  954                 }
  955                 return 0;
  956         }
  957         break;
  958         case PPPOEGETPARMS:
  959         {
  960                 struct pppoediscparms *parms = (struct pppoediscparms*)data;
  961                 memset(parms, 0, sizeof *parms);
  962                 if (sc->sc_eth_if)
  963                         strncpy(parms->ifname, sc->sc_eth_if->if_xname, IFNAMSIZ);
  964                 return 0;
  965         }
  966         break;
  967         case PPPOEGETSESSION:
  968         {
  969                 struct pppoeconnectionstate *state = (struct pppoeconnectionstate*)data;
  970                 state->state = sc->sc_state;
  971                 state->session_id = sc->sc_session;
  972                 state->padi_retry_no = sc->sc_padi_retried;
  973                 state->padr_retry_no = sc->sc_padr_retried;
  974                 return 0;
  975         }
  976         break;
  977         case SIOCSIFFLAGS:
  978                 /*
  979                  * Prevent running re-establishment timers overriding
  980                  * administrators choice.
  981                  */
  982                 if ((ifr->ifr_flags & IFF_UP) == 0
  983                      && sc->sc_state >= PPPOE_STATE_PADI_SENT
  984                      && sc->sc_state < PPPOE_STATE_SESSION) {
  985                         callout_stop(&sc->sc_timeout);
  986                         sc->sc_state = PPPOE_STATE_INITIAL;
  987                         sc->sc_padi_retried = 0;
  988                         sc->sc_padr_retried = 0;
  989                         memcpy(&sc->sc_dest, etherbroadcastaddr,
  990                             sizeof(sc->sc_dest));
  991                 }
  992                 return sppp_ioctl(ifp, cmd, data);
  993         case SIOCSIFMTU:
  994                 if (ifr->ifr_mtu > (sc->sc_eth_if == NULL ?
  995                     PPPOE_MAXMTU : (sc->sc_eth_if->if_mtu - PPPOE_OVERHEAD))) {
  996                         return EINVAL;
  997                 }
  998                 /*FALLTHROUGH*/
  999         default:
 1000                 return sppp_ioctl(ifp, cmd, data);
 1001         }
 1002         return 0;
 1003 }
 1004 
 1005 /*
 1006  * Allocate a mbuf/cluster with space to store the given data length
 1007  * of payload, leaving space for prepending an ethernet header
 1008  * in front.
 1009  */
 1010 static struct mbuf *
 1011 pppoe_get_mbuf(size_t len)
 1012 {
 1013         struct mbuf *m;
 1014 
 1015         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1016         if (m == NULL)
 1017                 return NULL;
 1018         if (len + sizeof(struct ether_header) > MHLEN) {
 1019                 MCLGET(m, M_DONTWAIT);
 1020                 if ((m->m_flags & M_EXT) == 0) {
 1021                         struct mbuf *n;
 1022                         MFREE(m, n);
 1023                         return 0;
 1024                 }
 1025         }
 1026         m->m_data += sizeof(struct ether_header);
 1027         m->m_len = len;
 1028         m->m_pkthdr.len = len;
 1029         m->m_pkthdr.rcvif = NULL;
 1030 
 1031         return m;
 1032 }
 1033 
 1034 static int
 1035 pppoe_send_padi(struct pppoe_softc *sc)
 1036 {
 1037         struct mbuf *m0;
 1038         int len, l1 = 0, l2 = 0; /* XXX: gcc */
 1039         uint8_t *p;
 1040 
 1041         if (sc->sc_state >PPPOE_STATE_PADI_SENT)
 1042                 panic("pppoe_send_padi in state %d", sc->sc_state);
 1043 
 1044         /* calculate length of frame (excluding ethernet header + pppoe header) */
 1045         len = 2 + 2 + 2 + 2 + sizeof sc;        /* service name tag is required, host unique is send too */
 1046         if (sc->sc_service_name != NULL) {
 1047                 l1 = strlen(sc->sc_service_name);
 1048                 len += l1;
 1049         }
 1050         if (sc->sc_concentrator_name != NULL) {
 1051                 l2 = strlen(sc->sc_concentrator_name);
 1052                 len += 2 + 2 + l2;
 1053         }
 1054 
 1055         /* allocate a buffer */
 1056         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);     /* header len + payload len */
 1057         if (!m0)
 1058                 return ENOBUFS;
 1059 
 1060         /* fill in pkt */
 1061         p = mtod(m0, uint8_t *);
 1062         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
 1063         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1064         if (sc->sc_service_name != NULL) {
 1065                 PPPOE_ADD_16(p, l1);
 1066                 memcpy(p, sc->sc_service_name, l1);
 1067                 p += l1;
 1068         } else {
 1069                 PPPOE_ADD_16(p, 0);
 1070         }
 1071         if (sc->sc_concentrator_name != NULL) {
 1072                 PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
 1073                 PPPOE_ADD_16(p, l2);
 1074                 memcpy(p, sc->sc_concentrator_name, l2);
 1075                 p += l2;
 1076         }
 1077         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1078         PPPOE_ADD_16(p, sizeof(sc));
 1079         memcpy(p, &sc, sizeof sc);
 1080 
 1081 #ifdef PPPOE_DEBUG
 1082         p += sizeof sc;
 1083         if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN)
 1084                 panic("pppoe_send_padi: garbled output len, should be %ld, is %ld",
 1085                     (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *)));
 1086 #endif
 1087 
 1088         /* send pkt */
 1089         return pppoe_output(sc, m0);
 1090 }
 1091 
 1092 static void
 1093 pppoe_timeout(void *arg)
 1094 {
 1095         int x, retry_wait, err;
 1096         struct pppoe_softc *sc = (struct pppoe_softc*)arg;
 1097 
 1098 #ifdef PPPOE_DEBUG
 1099         printf("%s: timeout\n", sc->sc_sppp.pp_if.if_xname);
 1100 #endif
 1101 
 1102         switch (sc->sc_state) {
 1103         case PPPOE_STATE_INITIAL:
 1104                 /* delayed connect from pppoe_tls() */
 1105                 pppoe_connect(sc);
 1106                 break;
 1107         case PPPOE_STATE_PADI_SENT:
 1108                 /*
 1109                  * We have two basic ways of retrying:
 1110                  *  - Quick retry mode: try a few times in short sequence
 1111                  *  - Slow retry mode: we already had a connection successfully
 1112                  *    established and will try infinitely (without user
 1113                  *    intervention)
 1114                  * We only enter slow retry mode if IFF_LINK1 (aka autodial)
 1115                  * is not set.
 1116                  */
 1117 
 1118                 /* initialize for quick retry mode */
 1119                 retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried);
 1120 
 1121                 x = splnet();
 1122                 sc->sc_padi_retried++;
 1123                 if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) {
 1124                         if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) {
 1125                                 /* slow retry mode */
 1126                                 retry_wait = PPPOE_SLOW_RETRY;
 1127                         } else {
 1128                                 pppoe_abort_connect(sc);
 1129                                 splx(x);
 1130                                 return;
 1131                         }
 1132                 }
 1133                 if ((err = pppoe_send_padi(sc)) != 0) {
 1134                         sc->sc_padi_retried--;
 1135                         if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
 1136                                 printf("%s: failed to transmit PADI, "
 1137                                     "error=%d\n",
 1138                                     sc->sc_sppp.pp_if.if_xname, err);
 1139                 }
 1140                 callout_reset(&sc->sc_timeout, retry_wait,
 1141                     pppoe_timeout, sc);
 1142                 splx(x);
 1143                 break;
 1144 
 1145         case PPPOE_STATE_PADR_SENT:
 1146                 x = splnet();
 1147                 sc->sc_padr_retried++;
 1148                 if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) {
 1149                         memcpy(&sc->sc_dest, etherbroadcastaddr,
 1150                             sizeof(sc->sc_dest));
 1151                         sc->sc_state = PPPOE_STATE_PADI_SENT;
 1152                         sc->sc_padr_retried = 0;
 1153                         if ((err = pppoe_send_padi(sc)) != 0) {
 1154                                 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
 1155                                         printf("%s: failed to send PADI"
 1156                                             ", error=%d\n",
 1157                                             sc->sc_sppp.pp_if.if_xname,
 1158                                             err);
 1159                         }
 1160                         callout_reset(&sc->sc_timeout,
 1161                             PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried),
 1162                             pppoe_timeout, sc);
 1163                         splx(x);
 1164                         return;
 1165                 }
 1166                 if ((err = pppoe_send_padr(sc)) != 0) {
 1167                         sc->sc_padr_retried--;
 1168                         if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
 1169                                 printf("%s: failed to send PADR, "
 1170                                     "error=%d\n", sc->sc_sppp.pp_if.if_xname,
 1171                                     err);
 1172                 }
 1173                 callout_reset(&sc->sc_timeout,
 1174                     PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried),
 1175                     pppoe_timeout, sc);
 1176                 splx(x);
 1177                 break;
 1178         case PPPOE_STATE_CLOSING:
 1179                 pppoe_disconnect(sc);
 1180                 break;
 1181         default:
 1182                 return; /* all done, work in peace */
 1183         }
 1184 }
 1185 
 1186 /* Start a connection (i.e. initiate discovery phase) */
 1187 static int
 1188 pppoe_connect(struct pppoe_softc *sc)
 1189 {
 1190         int x, err;
 1191 
 1192         if (sc->sc_state != PPPOE_STATE_INITIAL)
 1193                 return EBUSY;
 1194 
 1195 #ifdef PPPOE_SERVER
 1196         /* wait PADI if IFF_PASSIVE */
 1197         if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE))
 1198                 return 0;
 1199 #endif
 1200         x = splnet();
 1201         /* save state, in case we fail to send PADI */
 1202         sc->sc_state = PPPOE_STATE_PADI_SENT;
 1203         sc->sc_padr_retried = 0;
 1204         err = pppoe_send_padi(sc);
 1205         if (err != 0 && sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
 1206                 printf("%s: failed to send PADI, error=%d\n",
 1207                     sc->sc_sppp.pp_if.if_xname, err);
 1208         callout_reset(&sc->sc_timeout, PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
 1209         splx(x);
 1210         return err;
 1211 }
 1212 
 1213 /* disconnect */
 1214 static int
 1215 pppoe_disconnect(struct pppoe_softc *sc)
 1216 {
 1217         int err, x;
 1218 
 1219         x = splnet();
 1220 
 1221         if (sc->sc_state < PPPOE_STATE_SESSION)
 1222                 err = EBUSY;
 1223         else {
 1224                 if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
 1225                         printf("%s: disconnecting\n",
 1226                             sc->sc_sppp.pp_if.if_xname);
 1227                 err = pppoe_send_padt(sc->sc_eth_if, sc->sc_session, (const uint8_t *)&sc->sc_dest);
 1228         }
 1229 
 1230         /* cleanup softc */
 1231         sc->sc_state = PPPOE_STATE_INITIAL;
 1232         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1233         if (sc->sc_ac_cookie) {
 1234                 free(sc->sc_ac_cookie, M_DEVBUF);
 1235                 sc->sc_ac_cookie = NULL;
 1236         }
 1237         sc->sc_ac_cookie_len = 0;
 1238         if (sc->sc_relay_sid) {
 1239                 free(sc->sc_relay_sid, M_DEVBUF);
 1240                 sc->sc_relay_sid = NULL;
 1241         }
 1242         sc->sc_relay_sid_len = 0;
 1243 #ifdef PPPOE_SERVER
 1244         if (sc->sc_hunique) {
 1245                 free(sc->sc_hunique, M_DEVBUF);
 1246                 sc->sc_hunique = NULL;
 1247         }
 1248         sc->sc_hunique_len = 0;
 1249 #endif
 1250         sc->sc_session = 0;
 1251 
 1252         /* notify upper layer */
 1253         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1254 
 1255         splx(x);
 1256 
 1257         return err;
 1258 }
 1259 
 1260 /* Connection attempt aborted */
 1261 static void
 1262 pppoe_abort_connect(struct pppoe_softc *sc)
 1263 {
 1264         printf("%s: could not establish connection\n",
 1265                 sc->sc_sppp.pp_if.if_xname);
 1266         sc->sc_state = PPPOE_STATE_CLOSING;
 1267 
 1268         /* notify upper layer */
 1269         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1270 
 1271         /* clear connection state */
 1272         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1273         sc->sc_state = PPPOE_STATE_INITIAL;
 1274 }
 1275 
 1276 /* Send a PADR packet */
 1277 static int
 1278 pppoe_send_padr(struct pppoe_softc *sc)
 1279 {
 1280         struct mbuf *m0;
 1281         uint8_t *p;
 1282         size_t len, l1 = 0; /* XXX: gcc */
 1283 
 1284         if (sc->sc_state != PPPOE_STATE_PADR_SENT)
 1285                 return EIO;
 1286 
 1287         len = 2 + 2 + 2 + 2 + sizeof(sc);               /* service name, host unique */
 1288         if (sc->sc_service_name != NULL) {              /* service name tag maybe empty */
 1289                 l1 = strlen(sc->sc_service_name);
 1290                 len += l1;
 1291         }
 1292         if (sc->sc_ac_cookie_len > 0)
 1293                 len += 2 + 2 + sc->sc_ac_cookie_len;    /* AC cookie */
 1294         if (sc->sc_relay_sid_len > 0)
 1295                 len += 2 + 2 + sc->sc_relay_sid_len;    /* Relay SID */
 1296         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1297         if (!m0)
 1298                 return ENOBUFS;
 1299         p = mtod(m0, uint8_t *);
 1300         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
 1301         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1302         if (sc->sc_service_name != NULL) {
 1303                 PPPOE_ADD_16(p, l1);
 1304                 memcpy(p, sc->sc_service_name, l1);
 1305                 p += l1;
 1306         } else {
 1307                 PPPOE_ADD_16(p, 0);
 1308         }
 1309         if (sc->sc_ac_cookie_len > 0) {
 1310                 PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
 1311                 PPPOE_ADD_16(p, sc->sc_ac_cookie_len);
 1312                 memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
 1313                 p += sc->sc_ac_cookie_len;
 1314         }
 1315         if (sc->sc_relay_sid_len > 0) {
 1316                 PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID);
 1317                 PPPOE_ADD_16(p, sc->sc_relay_sid_len);
 1318                 memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len);
 1319                 p += sc->sc_relay_sid_len;
 1320         }
 1321         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1322         PPPOE_ADD_16(p, sizeof(sc));
 1323         memcpy(p, &sc, sizeof sc);
 1324 
 1325 #ifdef PPPOE_DEBUG
 1326         p += sizeof sc;
 1327         if (p - mtod(m0, uint8_t *) != len + PPPOE_HEADERLEN)
 1328                 panic("pppoe_send_padr: garbled output len, should be %ld, is %ld",
 1329                         (long)(len + PPPOE_HEADERLEN), (long)(p - mtod(m0, uint8_t *)));
 1330 #endif
 1331 
 1332         return pppoe_output(sc, m0);
 1333 }
 1334 
 1335 /* send a PADT packet */
 1336 static int
 1337 pppoe_send_padt(struct ifnet *outgoing_if, u_int session, const uint8_t *dest)
 1338 {
 1339         struct ether_header *eh;
 1340         struct sockaddr dst;
 1341         struct mbuf *m0;
 1342         uint8_t *p;
 1343 
 1344         m0 = pppoe_get_mbuf(PPPOE_HEADERLEN);
 1345         if (!m0)
 1346                 return EIO;
 1347         p = mtod(m0, uint8_t *);
 1348         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0);
 1349 
 1350         memset(&dst, 0, sizeof dst);
 1351         dst.sa_family = AF_UNSPEC;
 1352         eh = (struct ether_header*)&dst.sa_data;
 1353         eh->ether_type = htons(ETHERTYPE_PPPOEDISC);
 1354         memcpy(&eh->ether_dhost, dest, ETHER_ADDR_LEN);
 1355 
 1356         m0->m_flags &= ~(M_BCAST|M_MCAST);
 1357         return outgoing_if->if_output(outgoing_if, m0, &dst, NULL);
 1358 }
 1359 
 1360 #ifdef PPPOE_SERVER
 1361 static int
 1362 pppoe_send_pado(struct pppoe_softc *sc)
 1363 {
 1364         struct mbuf *m0;
 1365         uint8_t *p;
 1366         size_t len;
 1367 
 1368         if (sc->sc_state != PPPOE_STATE_PADO_SENT)
 1369                 return EIO;
 1370 
 1371         /* calc length */
 1372         len = 0;
 1373         /* include ac_cookie */
 1374         len += 2 + 2 + sizeof(sc);
 1375         /* include hunique */
 1376         len += 2 + 2 + sc->sc_hunique_len;
 1377         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1378         if (!m0)
 1379                 return EIO;
 1380         p = mtod(m0, uint8_t *);
 1381         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
 1382         PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
 1383         PPPOE_ADD_16(p, sizeof(sc));
 1384         memcpy(p, &sc, sizeof(sc));
 1385         p += sizeof(sc);
 1386         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1387         PPPOE_ADD_16(p, sc->sc_hunique_len);
 1388         memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 1389         return pppoe_output(sc, m0);
 1390 }
 1391 
 1392 static int
 1393 pppoe_send_pads(struct pppoe_softc *sc)
 1394 {
 1395         struct bintime bt;
 1396         struct mbuf *m0;
 1397         uint8_t *p;
 1398         size_t len, l1 = 0;     /* XXX: gcc */
 1399 
 1400         if (sc->sc_state != PPPOE_STATE_PADO_SENT)
 1401                 return EIO;
 1402 
 1403         getbinuptime(&bt);
 1404         sc->sc_session = bt.sec % 0xff + 1;
 1405         /* calc length */
 1406         len = 0;
 1407         /* include hunique */
 1408         len += 2 + 2 + 2 + 2 + sc->sc_hunique_len;      /* service name, host unique*/
 1409         if (sc->sc_service_name != NULL) {              /* service name tag maybe empty */
 1410                 l1 = strlen(sc->sc_service_name);
 1411                 len += l1;
 1412         }
 1413         m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
 1414         if (!m0)
 1415                 return ENOBUFS;
 1416         p = mtod(m0, uint8_t *);
 1417         PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
 1418         PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
 1419         if (sc->sc_service_name != NULL) {
 1420                 PPPOE_ADD_16(p, l1);
 1421                 memcpy(p, sc->sc_service_name, l1);
 1422                 p += l1;
 1423         } else {
 1424                 PPPOE_ADD_16(p, 0);
 1425         }
 1426         PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
 1427         PPPOE_ADD_16(p, sc->sc_hunique_len);
 1428         memcpy(p, sc->sc_hunique, sc->sc_hunique_len);
 1429         return pppoe_output(sc, m0);
 1430 }
 1431 #endif
 1432 
 1433 static void
 1434 pppoe_tls(struct sppp *sp)
 1435 {
 1436         struct pppoe_softc *sc = (void *)sp;
 1437         int wtime;
 1438 
 1439         if (sc->sc_state != PPPOE_STATE_INITIAL)
 1440                 return;
 1441 
 1442         if (sc->sc_sppp.pp_phase == SPPP_PHASE_ESTABLISH &&
 1443             sc->sc_sppp.pp_auth_failures > 0) {
 1444                 /*
 1445                  * Delay trying to reconnect a bit more - the peer
 1446                  * might have failed to contact it's radius server.
 1447                  */
 1448                 wtime = PPPOE_RECON_FAST * sc->sc_sppp.pp_auth_failures;
 1449                 if (wtime > PPPOE_SLOW_RETRY)
 1450                         wtime = PPPOE_SLOW_RETRY;
 1451         } else {
 1452                 wtime = PPPOE_RECON_IMMEDIATE;
 1453         }
 1454         callout_reset(&sc->sc_timeout, wtime, pppoe_timeout, sc);
 1455 }
 1456 
 1457 static void
 1458 pppoe_tlf(struct sppp *sp)
 1459 {
 1460         struct pppoe_softc *sc = (void *)sp;
 1461         if (sc->sc_state < PPPOE_STATE_SESSION)
 1462                 return;
 1463         /*
 1464          * Do not call pppoe_disconnect here, the upper layer state
 1465          * machine gets confused by this. We must return from this
 1466          * function and defer disconnecting to the timeout handler.
 1467          */
 1468         sc->sc_state = PPPOE_STATE_CLOSING;
 1469         callout_reset(&sc->sc_timeout, hz/50, pppoe_timeout, sc);
 1470 }
 1471 
 1472 static void
 1473 pppoe_start(struct ifnet *ifp)
 1474 {
 1475         struct pppoe_softc *sc = (void *)ifp;
 1476         struct mbuf *m;
 1477         uint8_t *p;
 1478         size_t len;
 1479 
 1480         if (sppp_isempty(ifp))
 1481                 return;
 1482 
 1483         /* are we ready to process data yet? */
 1484         if (sc->sc_state < PPPOE_STATE_SESSION) {
 1485                 sppp_flush(&sc->sc_sppp.pp_if);
 1486                 return;
 1487         }
 1488 
 1489         while ((m = sppp_dequeue(ifp)) != NULL) {
 1490                 len = m->m_pkthdr.len;
 1491                 M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
 1492                 if (m == NULL) {
 1493                         ifp->if_oerrors++;
 1494                         continue;
 1495                 }
 1496                 p = mtod(m, uint8_t *);
 1497                 PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
 1498 
 1499 #if NBPFILTER > 0
 1500                 if(sc->sc_sppp.pp_if.if_bpf)
 1501                         bpf_mtap(sc->sc_sppp.pp_if.if_bpf, m);
 1502 #endif
 1503 
 1504                 pppoe_output(sc, m);
 1505         }
 1506 }
 1507 
 1508 
 1509 #ifdef PFIL_HOOKS
 1510 static int
 1511 pppoe_ifattach_hook(void *arg, struct mbuf **mp, struct ifnet *ifp,
 1512     int dir)
 1513 {
 1514         struct pppoe_softc *sc;
 1515         int s;
 1516 
 1517         if (mp != (struct mbuf **)PFIL_IFNET_DETACH)
 1518                 return 0;
 1519 
 1520         s = splnet();
 1521         LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
 1522                 if (sc->sc_eth_if != ifp)
 1523                         continue;
 1524                 if (sc->sc_sppp.pp_if.if_flags & IFF_UP) {
 1525                         sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
 1526                         printf("%s: ethernet interface detached, going down\n",
 1527                             sc->sc_sppp.pp_if.if_xname);
 1528                 }
 1529                 sc->sc_eth_if = NULL;
 1530                 pppoe_clear_softc(sc, "ethernet interface detached");
 1531         }
 1532         splx(s);
 1533 
 1534         return 0;
 1535 }
 1536 #endif
 1537 
 1538 static void
 1539 pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
 1540 {
 1541         /* stop timer */
 1542         callout_stop(&sc->sc_timeout);
 1543         if (sc->sc_sppp.pp_if.if_flags & IFF_DEBUG)
 1544                 printf("%s: session 0x%x terminated, %s\n",
 1545                     sc->sc_sppp.pp_if.if_xname, sc->sc_session, message);
 1546 
 1547         /* fix our state */
 1548         sc->sc_state = PPPOE_STATE_INITIAL;
 1549 
 1550         /* signal upper layer */
 1551         sc->sc_sppp.pp_down(&sc->sc_sppp);
 1552 
 1553         /* clean up softc */
 1554         memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
 1555         if (sc->sc_ac_cookie) {
 1556                 free(sc->sc_ac_cookie, M_DEVBUF);
 1557                 sc->sc_ac_cookie = NULL;
 1558         }
 1559         if (sc->sc_relay_sid) {
 1560                 free(sc->sc_relay_sid, M_DEVBUF);
 1561                 sc->sc_relay_sid = NULL;
 1562         }
 1563         sc->sc_ac_cookie_len = 0;
 1564         sc->sc_session = 0;
 1565 }

Cache object: 53f3b55b46204c784582e11b4ec63e09


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.